kubetpl - kubernetes 模板管理工具

简介: kubetpl - kubernetes 模板管理工具

Helm、Kustomize、Kubetpl

  • 本人实际没有使用过 Helm 和 Kustomiz 这两款工具,以下的对比,仅个人观点,仅供参考;如果有说的不对的地方,还望指点

Helm

  • 在有网络的情况下
  • Helm 可以很好的进行产品的迭代升级,只需要配置好 repo 仓库,拉取相应版本的 chart 包,修改对应的 values.yaml 文件就可以完成
  • 对于需要快速部署一些主流的中间件或者服务的时候,可以不需要去考虑自己需要准备那些对象(deployment、service、configmap等等),因为仓库里面都有现成的,不需要自己造轮子,拿来就可以用
  • 在没有网络的情况下
  • 比如一些 saas 类型的产品交付公司,在一些银行、证券类的客户现场,大多数的生产环境是不通外网的,在这些苛刻条件下,如果使用 Helm 就会需要涉及 Helm 的私仓,相对于交付来说,架构会过于庞大且麻烦

Kustomize

  • Helm 对于服务的定制仅限于预置变量,那么如果需要更多更灵活的的 YAML 定制就需要用到 Kustomize
  • Kustomize 是一套采用合并思想,对 Kubernetes 原生配置进行管理的工具,使用无模板的方案定义应用配置
  • 允许用户使用一系列的描述文件为基础,然后通过 overlay 的方式生成最终部署应用所需的描述文件

Kubetpl

  • 有点类似于 Helm 的 values.yaml 的方式配置相应的变量,通过预先配置好的 yaml 文件模板,带入变量后生成新的 yaml 文件
  • 可以定制化配置不同场景的模板,不过模板的管理会相对麻烦很多
  • 比较轻量化,不需要任何服务器组件,只是单纯的配置和管理 yaml 文件

安装 Kubetpl

curl -sSL https://github.com/shyiko/kubetpl/releases/download/0.9.0/kubetpl-0.9.0-$(
    bash -c '[[ $OSTYPE == darwin* ]] && echo darwin || echo linux'
  )-amd64 -o kubetpl && chmod a+x kubetpl && sudo mv kubetpl /usr/local/bin/

Kubetpl 命令参数

参数选项

  • completion - 命令行参数自动补齐
  • help - 命令帮助
  • render - 渲染模板
completion - 参数自动补齐
  • 可选参数:bashzsh
# bash
source <(kubetpl completion bash)
# zsh
source <(kubetpl completion zsh)
ender - 渲染模板

image.png关于模板风格:$,go-template,template-kind ,主要区别在于变量引用的方式不同

  • $-shell 的风格
  • $NAME

go-template - go 语言 template 库的风格

  • {{ .VAR }} - 获取变量名称为 VAR 的变量值
  • {{ if isset "VAR" }} ... {{ end }} - 当定义了 VAR 变量的时候才会在 }} ... {{ 中间展示变量值
  • {{ get "VAR" "default" }} - 获取 VAR 的值,如果未设置,则返回 "default"
  • {{ .VAR | quote }} - 引用 VAR 值
  • {{ .VAR | indent 4 }} - VAR 的缩进值(带 4 个空格)
  • {{ .VAR | b64enc }} - VAR 值以 base64 编码展示
  • template-kind - 没太看懂....

go-template 语法

  • 本人没有接触过 go 语言,临时找了一些资料来学习一些简单的使用
  • go 语言的变量好像是不支持 - 出现在变量名称内的,go 语言使用的是驼峰命名,不然可能会有这样的报错:
  • template: nginx-template.yaml:3: unexpected bad character U+002D '-' in range

注释

{{/* 注释 */}}

引用变量

  • 输出 hostAlias 变量的值
{{ .hostAlias }}
  • hostAlias 是匿名字段时,可以访问其内部字段或方法
{{ .hostAlias.ip }}
  • 如果需要引用外部变量,需要在前面加上 $ 符号
{{ $.hostAlias }}

在 template 中定义变量

  • 变量名称前面需要带上 $ 符号
  • 使用 := 来对变量赋值
{{ $x := "hello" }}
  • 定义变量的值引用其他变量的值
{{ $x := .hostAlias }}

条件判断

  • if 后面可以是一个条件表达式(包括管道函数表达式。pipeline 即管道)
  • 也可以是一个字符串变量布尔值变量
  • 当为字符串变量时,如为空字符串则判断为 false,否则判断为 true
{{ if .hostAlias }}
- ip: {{ .ip }}
  hostnames: {{ .hostnames }}
{{ end }}

遍历

  • 普通用法,当变量值存在时才会有后面的内容输出
{{ range $.hostAliases }}
- ip: {{ .ip }}
  hostnames: {{ .hostnames }}
{{ end }}
  • 另一种用法
{{ range $k,$v := .labels }}
{{ $k }}: {{ $v }}
{{ end }}

开始使用

简单使用

准备一个 yaml 模板
  • 这里直接从 github 上面复制过来用了,以下所有的 yaml 文件只是用来模拟 kubetpl 生成 yaml 文件使用的,不能被直接使用的

# kubetpl:syntax:go-template

  • 定义模板风格,如果不在模板文件内定义,则需要通过 --syntax 的方式申明,否则会有类似如下报错

does not appear to be a valid YAML (yaml: line 3: did not find expected key).

Did you forget to specify --syntax=<$|go-template|template-kind> / add "# kubetpl:syntax:<$|go-template|template-kind>"?

# kubetpl:syntax:go-template
apiVersion: v1
kind: Service
metadata:
  name: {{ .NAME }}-service
spec:
  selector:
    app: {{ .NAME }}
  ports:
  - protocol: TCP
    port: 80
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: {{ .NAME }}-deployment
spec:
  replicas: {{ .REPLICAS }}
  template: 
    metadata:
      labels:
        app: {{ .NAME }}
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
准备变量文件
  • 支持的格式
  • *.env - <var>=<value>
  • yaml/json 文件

*.env 的方式

cat << EOF > valus.env
NAME=sample-app
REPLICAS=2
EOF

yaml 文件 的方式

cat << EOF > env.yaml
NAME: my-nginx
REPLICAS: 3
EOF
生成新的 yaml 文件
  • 两个变量文件定义的变量值是有差异的,这个单纯就是用来比较使用的,只是选择哪种变量文件,全看各自的选择
# 使用 valus.env
kubetpl render nginx-template.yaml -i valus.env -o nginx-env.yaml
# 使用 env.yaml
kubetpl render nginx-template.yaml -i env.yaml -o nginx-yaml.yaml

稍微复杂一点的场景

  • 因为 kubetpl 是通过 -i 的方式引入的变量,所以下面的变量引用都需要加上 $ 符号表示外部引入变量,才能正常识别,不然会有类似如下的报错:
  • template: nginx-template.yaml:9:23: executing "nginx-template.yaml" at <.static.namespace>: map has no entry for key "static"
准备一个 yaml 模板
# kubetpl:syntax:go-template
{{ range $getName := .staticInfo }}
---
apiVersion: v1
kind: Service
metadata:
  name: {{ $getName.name }}-svc
  namespace: {{ $.static.namespace }}
spec:
  selector:
    app: {{ $getName.name }}
  ports:
  - protocol: TCP
    port: {{ $getName.port }}
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: {{ $getName.name }}
  namespace: {{ $.static.namespace }}
spec:
  replicas: {{ $.static.replicas }}
  template:
    metadata:
      labels:
        app: {{ $getName.name }}
    spec:
      containers:
      - name: {{ $getName.name }}
        image: {{ $.global.Image }}
        imagePullPolicy: {{ $.global.ImagePull }}
        ports:
        - containerPort: 80
{{ end }}
准备变量文件
global:
  Image: nginx:1.16
  ImagePull: IfNotPresent
static:
  namespace: web-static
  replicas: 3
staticInfo:
  - name: app-static
    port: 80
  - name: backend-static
    port: 8080
生成新的 yaml 文件
kubetpl render nginx-template.yaml -i env.yaml -o nginx.yaml
生成后的 yaml 文件
---
apiVersion: v1
kind: Service
metadata:
  name: app-static-svc
  namespace: web-static
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    app: app-static
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: app-static
  namespace: web-static
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: app-static
    spec:
      containers:
      - image: nginx:1.16
        imagePullPolicy: IfNotPresent
        name: app-static
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: backend-static-svc
  namespace: web-static
spec:
  ports:
  - port: 8080
    protocol: TCP
  selector:
    app: backend-static
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: backend-static
  namespace: web-static
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: backend-static
    spec:
      containers:
      - image: nginx:1.16
        imagePullPolicy: IfNotPresent
        name: backend-static
        ports:
        - containerPort: 80

kubetpl/data-from-file

  • 当我们需要配置 configmap 的时候,可以通过文件带入的形式来配置 yaml 文件,这样可以单独维护 configmap 给所有的 yaml 文件来使用,对于维护来说,能减轻不少的成本
准备一个 yaml 模板
# kubetpl:syntax:go-template
---
apiVersion: v1
kind: ConfigMap
kubetpl/data-from-file:
  - ./nginx.conf
metadata:
  name: {{ $.configmap.name }}
  namespace: {{ $.static.namespace }}
data:
{{ range $getName := .staticInfo }}
---
apiVersion: v1
kind: Service
metadata:
  name: {{ $getName.name }}-svc
  namespace: {{ $.static.namespace }}
spec:
  selector:
    app: {{ $getName.name }}
  ports:
  - protocol: TCP
    port: {{ $getName.port }}
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: {{ $getName.name }}
  namespace: {{ $.static.namespace }}
spec:
  replicas: {{ $.static.replicas }}
  template:
    metadata:
      labels:
        app: {{ $getName.name }}
    spec:
      containers:
      - name: {{ $getName.name }}
        image: {{ $.global.Image }}
        imagePullPolicy: {{ $.global.ImagePull }}
        ports:
        - containerPort: 80
        volumeMounts:
        - name: nginx-conf
          mountPath: /workspace/nginx/conf
    volumes:
    - name: nginx-conf
      configMap:
        name: {{ $.configmap.name }}
{{ end }}
准备变量文件
  • 对比前面的,增加了一个 configmap
global:
  Image: nginx:1.16
  ImagePull: IfNotPresent
static:
  namespace: web-static
  replicas: 3
staticInfo:
  - name: app-static
    port: 80
  - name: backend-static
    port: 8080
configmap:
  name: static-cm
准备 file 文件
  • 命名为 nginx.conf
user root;
worker_processes 4;
error_log  logs/nginx_error.log  warn;
pid  logs/nginx.pid;
worker_rlimit_nofile 51200;
events {
  use epoll;
  worker_connections 51200;
  multi_accept on;
}
http {
  include       mime.types;
  default_type  application/octet-stream;
  server_names_hash_bucket_size 128;
  client_header_buffer_size 256k;
  large_client_header_buffers 16 256k;
  client_max_body_size 1m;
  keepalive_timeout 0;
  client_body_timeout 10;
  client_header_timeout 10;
  send_timeout 5;
  sendfile on;
  tcp_nopush  on;
  tcp_nodelay on;
  gzip on;
  gzip_min_length  1k;
  gzip_buffers     4 16k;
  gzip_http_version 1.0;
  gzip_comp_level 5;
  gzip_disable "MSIE [1-6].";
  gzip_types text/plain application/x-javascript text/css text/javascript application/x-httpd-php image/jpeg image/gif image/png application/json;
  gzip_vary on;
  ssi on;
  ssi_silent_errors on;
  ssi_types text/shtml;
  proxy_temp_path proxy_temp 1 2;
  client_body_temp_path client_body_temp 1 2;
  fastcgi_temp_path fastcgi_temp 1 2;
  uwsgi_temp_path uwsgi_temp 1 2;
  scgi_temp_path scgi_temp 1 2;
  set_real_ip_from 0.0.0.0/0;
  real_ip_header  X-Forwarded-For;
  real_ip_recursive   on;
  underscores_in_headers on;
  resolver kube-dns.kube-system valid=5s;
  resolver_timeout 5s;
  access_log off;
  server {
      listen       8080;
      server_name  test.com;
      set $proto_host "${http_x_forwarded_proto}_${host}";
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
      location /static/ {
        location ~* \.(gif|jpg|jpeg|png|bmp|swf|ico)$ {
          expires      30d;
        }
        expires 1h;
      }
  }
}
生成新的 yaml 文件
  • 使用 kubetpl/data-from-file 的话,需要加上 --allow-fs-access 参数,不然会出现类似如下的报错:
  • nginx-template.yaml: access denied: nginx.conf (use --allow-fs-access and/or -c/--chroot=<root dir, e.g. '.'> to allow)
kubetpl render --allow-fs-access nginx-template.yaml -i env.yaml -o nginx.yaml
生成后的 yaml 文件
---
apiVersion: v1
data:
  nginx.conf: |
    user root;
    worker_processes 4;
    error_log  logs/nginx_error.log  warn;
    pid  logs/nginx.pid;
    worker_rlimit_nofile 51200;
    events {
      use epoll;
      worker_connections 51200;
      multi_accept on;
    }
    http {
      include       mime.types;
      default_type  application/octet-stream;
      server_names_hash_bucket_size 128;
      client_header_buffer_size 256k;
      large_client_header_buffers 16 256k;
      client_max_body_size 1m;
      keepalive_timeout 0;
      client_body_timeout 10;
      client_header_timeout 10;
      send_timeout 5;
      sendfile on;
      tcp_nopush  on;
      tcp_nodelay on;
      gzip on;
      gzip_min_length  1k;
      gzip_buffers     4 16k;
      gzip_http_version 1.0;
      gzip_comp_level 5;
      gzip_disable "MSIE [1-6].";
      gzip_types text/plain application/x-javascript text/css text/javascript application/x-httpd-php image/jpeg image/gif image/png application/json;
      gzip_vary on;
      ssi on;
      ssi_silent_errors on;
      ssi_types text/shtml;
      proxy_temp_path proxy_temp 1 2;
      client_body_temp_path client_body_temp 1 2;
      fastcgi_temp_path fastcgi_temp 1 2;
      uwsgi_temp_path uwsgi_temp 1 2;
      scgi_temp_path scgi_temp 1 2;
      set_real_ip_from 0.0.0.0/0;
      real_ip_header  X-Forwarded-For;
      real_ip_recursive   on;
      underscores_in_headers on;
      resolver kube-dns.kube-system valid=5s;
      resolver_timeout 5s;
      access_log off;
      server {
          listen       8080;
          server_name  test.com;
          set $proto_host "${http_x_forwarded_proto}_${host}";
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
          location /static/ {
            location ~* \.(gif|jpg|jpeg|png|bmp|swf|ico)$ {
              expires      30d;
            }
            expires 1h;
          }
      }
    }
kind: ConfigMap
metadata:
  name: static-cm
  namespace: web-static
---
apiVersion: v1
kind: Service
metadata:
  name: app-static-svc
  namespace: web-static
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    app: app-static
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: app-static
  namespace: web-static
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: app-static
    spec:
      containers:
      - image: nginx:1.16
        imagePullPolicy: IfNotPresent
        name: app-static
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: /workspace/nginx/conf
          name: nginx-conf
    volumes:
    - configMap:
        name: static-cm
      name: nginx-conf
---
apiVersion: v1
kind: Service
metadata:
  name: backend-static-svc
  namespace: web-static
spec:
  ports:
  - port: 8080
    protocol: TCP
  selector:
    app: backend-static
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: backend-static
  namespace: web-static
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: backend-static
    spec:
      containers:
      - image: nginx:1.16
        imagePullPolicy: IfNotPresent
        name: backend-static
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: /workspace/nginx/conf
          name: nginx-conf
    volumes:
    - configMap:
        name: static-cm
      name: nginx-conf


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
8月前
|
Kubernetes Shell Linux
K8S 实用工具之一 - 如何合并多个 kubeconfig?
K8S 实用工具之一 - 如何合并多个 kubeconfig?
|
2月前
|
Kubernetes 安全 容器
关于K8s,不错的开源工具
【10月更文挑战第12天】
|
2月前
|
Kubernetes 应用服务中间件 nginx
【赵渝强老师】Kubernetes命令行管理工具:kubectl
kubectl 是 Kubernetes 的命令行工具,用于管理和操作 Kubernetes 集群。本文通过视频讲解和具体示例,介绍了 kubectl 的常用命令,包括显示 Pod 信息、创建 Deployment 和 Service、更新和回滚 Deployment、以及删除资源等操作。
|
4月前
|
Ubuntu Linux pouch
Docker容器管理工具
文章介绍了Docker容器管理工具,以及早期使用的LXC容器管理工具,包括它们的安装、使用和相关技术特点。
90 10
Docker容器管理工具
|
8月前
|
存储 Kubernetes C++
【专栏】Kubernetes VS Docker Swarm了解两者特点,助力选取合适容器编排工具
【4月更文挑战第27天】对比Kubernetes和Docker Swarm:K8s在可扩展性和自动化方面出色,有强大社区支持;Swarm以简易用著称,适合初学者。选择取决于项目需求、团队技能和预期收益。高度复杂项目推荐Kubernetes,快速上手小项目则选Docker Swarm。了解两者特点,助力选取合适容器编排工具。
234 1
|
4月前
|
Linux pouch 容器
CentOS7部署阿里巴巴开源的pouch容器管理工具实战
关于如何在CentOS 7.6操作系统上安装和使用阿里巴巴开源的Pouch容器管理工具的实战教程。
143 2
|
5月前
|
存储 Kubernetes Cloud Native
容器管理工具Containerd
容器管理工具Containerd
|
5月前
|
Prometheus Kubernetes 监控
揭秘Kubernetes的秘密武器库:十大工具让你的容器编排如虎添翼!探索这些神秘而强大的工具,它们将如何彻底改变你的Kubernetes体验?
【8月更文挑战第19天】在容器世界里,Kubernetes是部署与管理容器化应用的首选平台。为了增强其功能,本文精选了十大必备工具:Helm简化复杂应用部署;Prometheus监控系统与应用指标;Grafana提供数据可视化;Fluentd统一日志管理;Envoy实现服务间通信与控制;Calico确保网络连接安全;CoreDNS提升DNS服务性能;Velero保障数据安全与迁移;Argo Workflows执行复杂工作流;Istio强化服务网格功能。这些工具覆盖部署、监控、日志等多个方面,助力提升Kubernetes的效率与稳定性。
95 3
|
5月前
|
Kubernetes 监控 Shell
在K8S中,我们公司用户反应pod连接数非常多,希望看一下这些连接都是什么信息?什么状态?怎么排查?容器里面没有集成bash环境、网络工具,怎么处理?
在K8S中,我们公司用户反应pod连接数非常多,希望看一下这些连接都是什么信息?什么状态?怎么排查?容器里面没有集成bash环境、网络工具,怎么处理?
|
5月前
|
Kubernetes Cloud Native 开发者
基于 K8s 做应用发布的工具选择:Tekton,一颗璀璨的CI/CD新星!
【8月更文挑战第8天】在众多Kubernetes应用发布工具中,阿里巴巴为何青睐Tekton?Tekton“以应用为中心”的设计理念与阿里巴巴的技术哲学相契合,不仅关注代码构建部署,还覆盖应用全生命周期管理,完美融入阿里巴巴业务场景。Tekton提供灵活工作流定义、多平台支持及与Kubernetes生态无缝集成等功能,满足阿里巴巴复杂业务需求的同时赋予开发者更多灵活性。作为CNCF毕业项目,Tekton拥有活跃社区和不断壮大的生态系统,为阿里巴巴技术演进提供坚实基础。综上所述,阿里巴巴选择Tekton是一个深思熟虑且具前瞻性的决策。
125 0

热门文章

最新文章