- 在有网络的情况下
- Helm 可以很好的进行产品的迭代升级,只需要配置好 repo 仓库,拉取相应版本的 chart 包,修改对应的 values.yaml 文件就可以完成
- 对于需要快速部署一些主流的中间件或者服务的时候,可以不需要去考虑自己需要准备那些对象(deployment、service、configmap等等),因为仓库里面都有现成的,不需要自己造轮子,拿来就可以用
- 在没有网络的情况下
- 比如一些 saas 类型的产品交付公司,在一些银行、证券类的客户现场,大多数的生产环境是不通外网的,在这些苛刻条件下,如果使用 Helm 就会需要涉及 Helm 的私仓,相对于交付来说,架构会过于庞大且麻烦
- Helm 对于服务的定制仅限于预置变量,那么如果需要更多更灵活的的 YAML 定制就需要用到 Kustomize
- Kustomize 是一套采用合并思想,对 Kubernetes 原生配置进行管理的工具,使用无模板的方案定义应用配置
- 允许用户使用一系列的描述文件为基础,然后通过 overlay 的方式生成最终部署应用所需的描述文件
- 有点类似于 Helm 的 values.yaml 的方式配置相应的变量,通过预先配置好的 yaml 文件模板,带入变量后生成新的 yaml 文件
- 可以定制化配置不同场景的模板,不过模板的管理会相对麻烦很多
- 比较轻量化,不需要任何服务器组件,只是单纯的配置和管理 yaml 文件
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/
completion
- 命令行参数自动补齐
help
- 命令帮助
render
- 渲染模板
bash
和 zsh
# bash
source <(kubetpl completion bash)# zsh
source <(kubetpl completion zsh)
参数 | 解释 |
---|---|
--allow-fs-access | --chroot= |
-c, --chroot string | kubetpl/data-from-file 允许读取的文件的路径,--chroot 以外的文件都会被拒绝访问 ;在模板文件中可以写好路径,使用 --allow-fs-access 参数也可以实现 |
-z, --freeze --freeze-list stringSlice --freeze-ref stringArray --ignore-unset | 冻结 ConfigMap/Secret
不应包含在输出中的外部 ConfigMap/Secret,但需要对其进行 --freeze 的引用 如果未设置,则保留 $VAR/${VAR}(例如,"echo 'kind:$A$B'|kubetpl r --s A=X --syntax=$ --ignore-unset" 输出:"kind:X$B" )` |
-i, --input stringArray | 指定配置文件:*.{env,yml,yaml,json} |
-o, --output string | 指定输出的文件名称 |
-s, --set stringArray | = 如果 --input 有配置则以 --input 优先 变量少的情况下,可以不写 --input,直接使用 --set 申明 |
-x, --syntax string | 定义模板风格 $,go-template,template-kind - 三个可选项 |
关于模板风格:
$,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: nginx-template.yaml:3: unexpected bad character U+002D '-' in range
{{/* 注释 */}}
hostAlias
变量的值{{ .hostAlias }}
hostAlias
是匿名字段时,可以访问其内部字段或方法{{ .hostAlias.ip }}
$
符号{{ $.hostAlias }}
$
符号:=
来对变量赋值{{ $x := "hello" }}
{{ $x := .hostAlias }}
条件表达式
(包括管道函数表达式。pipeline 即管道)字符串变量
或布尔值变量
字符串变量
时,如为空字符串则判断为 false
,否则判断为 true
{{ if .hostAlias }}
- ip: {{ .ip }}hostnames: {{ .hostnames }}
{{ end }}
{{ range $.hostAliases }}
- ip: {{ .ip }}hostnames: {{ .hostnames }}
{{ end }}
{{ range $k,$v := .labels }}
{{ $k }}: {{ $v }}
{{ end }}
# 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-templateapiVersion: v1
kind: Service
metadata:name: {{ .NAME }}-service
spec:selector:app: {{ .NAME }}ports:- protocol: TCPport: 80
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:name: {{ .NAME }}-deployment
spec:replicas: {{ .REPLICAS }}template: metadata:labels:app: {{ .NAME }}spec:containers:- name: nginximage: nginx:1.7.9ports:- containerPort: 80
支持的格式
*.env
- =
yaml/json 文件
*.env
的方式
cat << EOF > valus.env
NAME=sample-app
REPLICAS=2
EOF
yaml 文件
的方式
cat << EOF > env.yaml
NAME: my-nginx
REPLICAS: 3
EOF
# 使用 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
-i
的方式引入的变量,所以下面的变量引用都需要加上 $
符号表示外部引入变量,才能正常识别,不然会有类似如下的报错: template: nginx-template.yaml:9:23: executing "nginx-template.yaml" at <.static.namespace>: map has no entry for key "static"
# kubetpl:syntax:go-template{{ range $getName := .staticInfo }}
---
apiVersion: v1
kind: Service
metadata:name: {{ $getName.name }}-svcnamespace: {{ $.static.namespace }}
spec:selector:app: {{ $getName.name }}ports:- protocol: TCPport: {{ $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.16ImagePull: IfNotPresent
static:namespace: web-staticreplicas: 3
staticInfo:- name: app-staticport: 80- name: backend-staticport: 8080
kubetpl render nginx-template.yaml -i env.yaml -o nginx.yaml
---
apiVersion: v1
kind: Service
metadata:name: app-static-svcnamespace: web-static
spec:ports:- port: 80protocol: TCPselector:app: app-static
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:name: app-staticnamespace: web-static
spec:replicas: 3template:metadata:labels:app: app-staticspec:containers:- image: nginx:1.16imagePullPolicy: IfNotPresentname: app-staticports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: backend-static-svcnamespace: web-static
spec:ports:- port: 8080protocol: TCPselector:app: backend-static
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:name: backend-staticnamespace: web-static
spec:replicas: 3template:metadata:labels:app: backend-staticspec:containers:- image: nginx:1.16imagePullPolicy: IfNotPresentname: backend-staticports:- containerPort: 80
# kubetpl:syntax:go-template---
apiVersion: v1
kind: ConfigMap
kubetpl/data-from-file:- ./nginx.confmetadata:name: {{ $.configmap.name }}namespace: {{ $.static.namespace }}
data:{{ range $getName := .staticInfo }}
---
apiVersion: v1
kind: Service
metadata:name: {{ $getName.name }}-svcnamespace: {{ $.static.namespace }}
spec:selector:app: {{ $getName.name }}ports:- protocol: TCPport: {{ $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: 80volumeMounts:- name: nginx-confmountPath: /workspace/nginx/confvolumes:- name: nginx-confconfigMap:name: {{ $.configmap.name }}
{{ end }}
configmap
global:Image: nginx:1.16ImagePull: IfNotPresent
static:namespace: web-staticreplicas: 3
staticInfo:- name: app-staticport: 80- name: backend-staticport: 8080
configmap:name: static-cm
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;}}
}
kubetpl/data-from-file
的话,需要加上 --allow-fs-access
参数,不然会出现类似如下的报错: nginx-template.yaml: access denied: nginx.conf (use --allow-fs-access and/or -c/--chroot= to allow)
kubetpl render --allow-fs-access nginx-template.yaml -i env.yaml -o nginx.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-cmnamespace: web-static
---
apiVersion: v1
kind: Service
metadata:name: app-static-svcnamespace: web-static
spec:ports:- port: 80protocol: TCPselector:app: app-static
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:name: app-staticnamespace: web-static
spec:replicas: 3template:metadata:labels:app: app-staticspec:containers:- image: nginx:1.16imagePullPolicy: IfNotPresentname: app-staticports:- containerPort: 80volumeMounts:- mountPath: /workspace/nginx/confname: nginx-confvolumes:- configMap:name: static-cmname: nginx-conf
---
apiVersion: v1
kind: Service
metadata:name: backend-static-svcnamespace: web-static
spec:ports:- port: 8080protocol: TCPselector:app: backend-static
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:name: backend-staticnamespace: web-static
spec:replicas: 3template:metadata:labels:app: backend-staticspec:containers:- image: nginx:1.16imagePullPolicy: IfNotPresentname: backend-staticports:- containerPort: 80volumeMounts:- mountPath: /workspace/nginx/confname: nginx-confvolumes:- configMap:name: static-cmname: nginx-conf
最后推荐几在找资料的时候看到的文章和大家一起学习