有了 kubectl + yaml , 还要 helm 做什么呢?
在微服务场景中,使用同一模式开发的应用会变的很多,我们会使用相同的 docker 基础镜像进行应用打包。但对于部署场景,我们需要写很多类似的 yaml 文件,由此,我们希望将不同之处使用变量抽取出来,并与通用模板进行整合。
目前使用 kubectl + yaml 的这种方式是无法完成这一功能的。
我们可以使用 helm 来批量部署同类应用,并彻底将部署代码从程序中解耦。在同一类部署中,不同的值是:应用名称,应用当前版本,镜像地址,我们将这些参数提取出来,从命令行中指定进去。
下面我们来展示这一过程。
写在前面 - 关于腾讯云 TKE 和 helm
腾讯云的 TKE 已经安装了 helm 的 tiller 了,所以在本地使用 helm 的时候,只需要使用 helm 的命令行工具即可。 helm 默认会操作 ~/.kube/config 对应的集群。
如果要操作不同的集群,我习惯加上 --kubeconfig=xxx 来操作,建议将他做成一个别名放在你的 .bashrc 或 .zshrc 中,如:
alias helm2="helm --kubeconfig ~/.kube/config2"
创建一个 helm chart
使用命令创建一个chart
helm create chart-demo
创建出来的目录结构
./chart-demo ├── Chart.yaml ├── charts ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── deployment.yaml │ ├── hpa.yaml │ ├── ingress.yaml │ ├── service.yaml │ ├── serviceaccount.yaml │ └── tests │ └── test-connection.yaml └── values.yaml
只需将共用的基础部署脚本写在 templates 里面的文件中,把可变量写到 values.yaml 中。
开始写一个简单 Chart
使用 helm create 出来的模板文件,看起来很复杂,所以,咱们不用他的那些模板,从 kubectl 的 yaml 开始。删掉 templates 下的所有文件。用自己熟悉的方式,先创建部署,目录结构如下:
./chart-demo ├── Chart.yaml ├── templates │ └── deploy.yaml └── values.yaml
deploy.yaml
apiVersion: apps/v1beta2 kind: Deployment metadata: name: {{ .Release.Name }} labels: app: {{ .Release.Name }} spec: replicas: 2 selector: matchLabels: app: {{ .Release.Name }} strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 template: metadata: labels: app: {{ .Release.Name }} spec: containers: - name: {{ .Release.Name }} image: ccr.ccs.tencentyun.com/axlyzhang-images/xyzdemo-product:v1.10 env: - name: PATH value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin - name: LANG value: C.UTF-8 - name: JAVA_HOME value: /usr/lib/jvm/java-8-openjdk-amd64 - name: JAVA_VERSION value: 8u111 resources: limits: cpu: 500m memory: 1Gi requests: cpu: 250m memory: 256Mi
假装安装一下,看看输出的结果:
helm install --debug --dry-run xyz-product .
--- # Source: chart-demo/templates/deploy.yaml apiVersion: apps/v1beta2 kind: Deployment metadata: name: xyz-product labels: app: xyz-product spec: replicas: 2 selector: matchLabels: app: xyz-product strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 template: metadata: labels: app: xyz-product spec: containers: - name: xyz-product image: ccr.ccs.tencentyun.com/axlyzhang-images/xyzdemo-product:v1.10 env: - name: PATH value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin - name: LANG value: C.UTF-8 - name: JAVA_HOME value: /usr/lib/jvm/java-8-openjdk-amd64 - name: JAVA_VERSION value: 8u111 resources: limits: cpu: 500m memory: 1Gi requests: cpu: 250m memory: 256Mi
上面就是合成结果,我们已经放入了一个内置变量 {{ .Release.Name }}
。
很简单吧。接下来,就是要把更多的变量(appName, version)放进去。
Values
helm 支持变量,函数,模板和一些流控编程。现在我们不使用 Release 这个内置变量了,我们使用 Values 变量。Values 变量一般有 2 个来源,一个是 yaml 文件,一个是命令行参数。在 Jenkins 自动化 部署的场景,我们更希望通过命令行来把参数指定进去。
我们改写 deploy.yaml 一下:
apiVersion: apps/v1beta2 kind: Deployment metadata: name: {{ required "应用名称 appName 必须指定" .Values.appName }} namespace: {{ default "default" .Values.ns}} labels: app: {{ .Values.appName }} version: {{ required "版本号 version 必须指定" .Values.version }} spec: replicas: {{ default 2 .Values.replicas }} selector: matchLabels: app: {{ .Values.appName }} strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 template: metadata: labels: app: {{ .Values.appName }} spec: containers: - name: {{ .Values.appName }} image: ccr.ccs.tencentyun.com/axlyzhang-images/{{ .Values.appName }}:{{ .Values.version }} env: - name: PATH value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin - name: LANG value: C.UTF-8 - name: JAVA_HOME value: /usr/lib/jvm/java-8-openjdk-amd64 - name: JAVA_VERSION value: 8u111 resources: limits: cpu: 500m memory: 1Gi requests: cpu: 250m memory: 256Mi
我们通过命令行,将参数指定进去,如下:
helm install --debug --dry-run springboot-app . --set appName=xyzdemo-product --set version=v1.10
看到结果,已经按照我们想要的结果输出了。去掉 --debug --dry-run
就可以直接执行到 K8S 环境了。
上传到 Chart “私服”
有多种方法可以搭建自己的私服,如:ChartMuseum, Github Pages, JFrog Artifactory 等。目前使用 coding.net 的制品库已经可以完美支持 helm charts 。只需要创建仓库即可。
在本地设置你的仓库(下面这些命令在 coding 中会自动帮你生成):
helm plugin install https://e.coding.net/coding-public/helm-push helm repo add --username <userName> --password <pwd> charts "https://your-repo-url"
推送步骤:
- 打包:
helm package .
- 推送
helm push chart-demo-0.1.0.tgz charts
现在搜一下 coding 的 helm 仓库:
helm search repo charts
便有了你的图样。
现在远程的 repo 已经设置到本地了。可以使用远程图样,直接部署同环境的应用了。
helm install microservice1 charts/chart-demo --set appName=microservice1 --set version=1.0 helm install microservice2 charts/chart-demo --set appName=microservice2 --set version=1.1 ...
在 Jenkins 的脚本中,无法多次 install 同一个,可以使用 helm upgrade --install
。
More
到这里,我们只是应用了 helm 很少的功能,便实现了应用的批量部署。
其实,helm 的功能很强大,他的模板系统可以支持更多的变量,模板,流控,函数等,并可以支持很多部署操作命令,这些可以去他的官网研究一下。
总结
helm 可以理解为一套 YAML 的模板系统,按照 helm 特定的模板语法编写 yaml,他就可以“智能地”将这些模板合成为正确的 Yaml 部署文件,并可以通过简单的命令部署到 K8S 环境中。
当然,Helm 也可以是你的应用的“包管理系统”。
参考:
HELM 官网
CODING制品库
合智互联客户成功服务热线:400-1565-661
留言评论
暂无留言