前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kubernetes 中使用consul-template渲染配置

Kubernetes 中使用consul-template渲染配置

作者头像
charlieroro
发布2023-10-28 10:46:35
4520
发布2023-10-28 10:46:35
举报
文章被收录于专栏:charlieroro

Kubernetes 中使用consul-template渲染配置

当前公司使用consul来实现服务发现,如Prometheue配置中的target和alertmanager注册都采用了consul服务发现的方式,以此来灵活应对服务的变更。但对于其他服务,是否也有一个通用的方式来使用consul管理配置文件?本文中描述如何使用consul-template来渲染配置文件。

使用方式

consul-template是hashicorp开发的一个模板渲染工具,它采用了Go template语法。可以将其配置为守护进程模式,watch consul服务的变动,并将变动后的服务渲染到配置文件中。会虽然名字中带了consul,但它还可以对 VaultNomad 进行渲染。

简单使用方式如下,首先要创建一个模板in.tpl,在渲染时通过-template指定模板(in.tpl)和渲染结果(out.txt):

代码语言:javascript
复制
$ consul-template -consul-addr=<consul-address>:<consul-port> -template "in.tpl:out.txt"
SSL方式

生产环境中的consul通常会启用ssl和ACL配置,这样在连接consul的时候需要提供CA证书和token。命令行使用方式如下:

代码语言:javascript
复制
$ consul-template -log-level debug -consul-addr==<consul-address>:<consul-port> -consul-token=<token> -consul-ssl  -consul-ssl-verify=false -consul-ssl-ca-cert=<ca.crt> -template "in.tpl:out.txt"

也可以使用-consul-ssl-ca-path-consul-token-file分别指定CA证书和token文件的路径。

获取ca证书

官方提供了一个名为consul-k8s的工具来获取consul的CA证书,并提供了容器镜像,使用方式如下:

代码语言:javascript
复制
$ consul-k8s-control-plane get-consul-client-ca -output-file=/tmp/tls.crt -server-addr=<consul-address> -server-port=<consul-port> 

可以将consul-k8s配置为一个initcontainer,这样在consul-template启动之前就可以获取到ca证书:

代码语言:javascript
复制
  initContainers:
    - command:
        - /bin/sh
        - '-ec'
        - |
          consul-k8s-control-plane get-consul-client-ca \
            -output-file=/consul/tls/client/ca/tls.crt \
            -server-addr=<consul-address> \
            -server-port=<consul-port> \
      image: docker pull hashicorp/consul-k8s-control-plane:0.36.0
      imagePullPolicy: IfNotPresent
      name: get-auto-encrypt-client-ca
      resources:
        limits:
          cpu: 50m
          memory: 50Mi
        requests:
          cpu: 50m
          memory: 50Mi
      volumeMounts:
        - mountPath: /consul/tls/client/ca
          name: consul-auto-encrypt-ca-cert
 volumes:
    - emptyDir:
        medium: Memory
      name: consul-auto-encrypt-ca-cert
获取token

连接consul所使用的token可以以secret的形式部署在kubernetes集群中,可以通过vault注入等方式来避免token泄露。

整个处理方式如下图所示:

配置文件方式

上面通过命令行的方式(-template "in.tpl:out.txt")指定了模版和渲染结果,但这种方式只适用于渲染单个模板,如果需要渲染多个模板,可以采用配置文件的方式。

配置文件语法采用的是hcl,包含三部分:服务端(ConsulVaultNomad)、TemplatesModes,以及可选字段。服务端主要用于配置到服务端(Consul、Vault和Nomad)的连接;Templates可以指定多个模板(source)和渲染结果(destination);Modes用于配置consul-template的运行模式,通过once mode可以配置为非守护进程模式,通过exec mode可以启动额外的子进程。Modes字段可选,默认是守护进程模式。

配置文件的例子如下:

代码语言:javascript
复制
consul {
  address = "127.0.0.1:8500"

  auth {
    enabled = true
    username = "test"
    password = "test"
  }
}

log_level = "warn"

template {
  contents = "{{key \"hello\"}}"
  destination = "out.txt"
  exec {
    command = "cat out.txt"
  }
}

后续就可以通过consul-template -config <config>的方式运行。

编写模板

consul-template使用的Go template的语法,除此之外,它还提供了丰富的内置方法,用于支持Consul(文章中搜索关键字Query Consul )、Vault(文章中搜索关键字Query Vault )和Nomad(文章中搜索关键字Query Nomad ),以及一些公共函数(如trimregexMatchreplaceAll等)。

模板语法中比较重要的两点:

  • 在模板文本中,一切动态的内容和判断代码块均使用 {{}} 包括起来,在 {{}} 之外的文本均会被原封不动地拷贝到输出中
  • 为了方便格式化模板源代码,还额外提供了 {{--}} 两种语法,可以将代码块前或代码块后的空白字符均移除。空白字符包括空格符、换行符、回车符、水平制表符。
举例

下面是logstash的output配置,用于将logstash处理的消息发送到elasticsearch.hosts中。如果hosts中的节点发生变动(如扩缩容),此时就需要联动修改logstash的配置:

代码语言:javascript
复制
output {
    elasticsearch {
        hosts => ['dev-logging-elkclient000001.local:9200', 'dev-logging-elkclient000002.local:9200', 'elkclient000003.local:9200']
        index => "logstash-infra-%{es_index}"
        resurrect_delay => 2
        retry_max_interval => 30
        sniffing => false
        action => "create"
    }
}

为了避免上述修改,可以通过consul-template对该配置进行渲染(当然前提是hosts中的节点都已经注册到了Consul中)。

代码语言:javascript
复制
{{- $nodes := "" }}
{{ range service "elasticsearch" }} {{- $node := .Node }} {{- $port := .Port }} 
{{ if $node | regexMatch "(dev|prd)-logging-elkclient.*" }}
{{ if eq $nodes "" }}
{{$nodes = (printf "'%s:%d'" $node $port)}}
{{else}}
{{$nodes = (printf "%s,'%s:%d'" $nodes $node $port)}}
{{- end -}}
{{- end -}}
{{- end }}

output {
    elasticsearch {
        hosts => [{{$nodes}}]
        index => "logstash-%{es_index}"
        resurrect_delay => 2
        retry_max_interval => 30
        sniffing => false
        action => "create"
    }
}
  1. 首先定义一个变量$nodes,用于保存最终的结果
  2. 遍历consul的service elasticsearch,获取Node字段(如dev-logging-elkclient000001.local)和Port字段(本例中只有9200)
  3. 通过内置方法regexMatchelasticsearch的节点中过滤所需的节点
  4. 通过printf方法拼接字符串,并将结果保存到$nodes
  5. 最后在output.elasticsearch.hosts中使用上面的结果nodes即可,由于nodes是动态输出,因此需要加上双大括号{{
参考

Tips

有时候一个文件因为要经过多个服务的渲染而添加了多个模板,例如先使用vault注入secrets,再使用consul注入services。这样就会导致vault在处理时候会尝试解析consul的模板,但由于vault缺少连接consul所需的配置,会导致vault一直尝试连接consul。可以通过将其他服务的模版作为raw string的方式规避该问题,这样在vault解析模板的时候就会输出consul的模板:

代码语言:javascript
复制
{{- $consulTemplate := `
{{- $nodes := "" }}
{{ range service "elasticsearch" }} {{- $node := .Node }} {{- $port := .Port }} 
{{ if $node | regexMatch "(dev|prd)-logging-elkclient.*" }}
{{ if eq $nodes "" }}
{{$nodes = (printf "'%s:%d'" $node $port)}}
{{else}}
{{$nodes = (printf "%s,'%s:%d'" $nodes $node $port)}}
{{- end -}}
{{- end -}}
{{- end }}

output {
    elasticsearch {
        hosts => [{{$nodes}}]
        index => "logstash-%{es_index}"
        resurrect_delay => 2
        retry_max_interval => 30
        sniffing => false
        action => "create"
    }
}
` }}

{{ $consulTemplate }}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Kubernetes 中使用consul-template渲染配置
    • 使用方式
      • SSL方式
    • 编写模板
      • 举例
      • 参考
    • Tips
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档