玩K8S不得不会的HELM

网友投稿 947 2022-05-30

一 基本概念

helm 类似于Linux系统下的包管理器,如yum/apt等,可以方便快捷的将之前打包好的yaml文件快速部署进kubernetes内,方便管理维护。

helm:一个命令行下客户端工具,主要用于kubernetes应用chart的创建/打包/发布已经创建和管理和远程Chart仓库。

Tiller:helm的服务端,部署于kubernetes内,Tiller接受helm的请求,并根据chart生成kubernetes部署文件(helm称为release),然后提交给 Kubernetes 创建应用。Tiller 还提供了 Release 的升级、删除、回滚等一系列功能。

Chart: helm的软件包,采用tar格式,其中包含运行一个应用所需的所有镜像/依赖/资源定义等,还可能包含kubernetes集群中服务定义

Release:在kubernetes中集群中运行的一个Chart实例,在同一个集群上,一个Chart可以安装多次,每次安装均会生成一个新的release。

Repository:用于发布和存储Chart的仓库

简单来说:

helm的作用:像centos7中的yum命令一样,管理软件包,只不过helm这儿管理的是在k8s上安装的各种容器。

tiller的作用:像centos7的软件仓库一样,简单说类似于/etc/yum.repos.d目录下的xxx.repo。

二 组件架构

三 工作原理

3.1 Chart install

helm从制定目录或tar文件解析chart结构信息

helm将制定的chart结构和value信息通过gRPC协议传递给tiller

tiller根据chart和values生成一个release

tiller通过json将release发送给kubernetes,生成release

3.2 Chart update

helm从制定的目录或tar文件解析chart结构信息

helm将制定的chart结构和value信息通过gRPC协议传给tiller

tiller生成release并更新制定名称的release的history

tiller将release信息发送给kubernetes用于更新release

3.3 Chart Rollback

helm将会滚的release名称传递给tiller

tiller根据release名称查找history

tiller从history中获取到上一个release

tiller将上一个release发送给kubernetes用于替换当前release

3.4 Chart处理依赖

Tiller 在处理 Chart 时,直接将 Chart 以及其依赖的所有 Charts 合并为一个 Release,同时传递给 Kubernetes。因此 Tiller 并不负责管理依赖之间的启动顺序。Chart 中的应用需要能够自行处理依赖关系。

四 安装部署

4.1 v2版本安装

4.1.1 安装helm

# 在helm客户端主机上,一般为master主机 wget https://get.helm.sh/helm-v2.14.2-linux-amd64.tar.gz tar xf helm-v2.14.2-linux-amd64.tar.gz mv helm /usr/local/bin/ helm version 复制代码

4.1.2 初始化tiller

初始化tiller会自动读取~/.kube目录,所以需要确保config文件存在并认证成功

tiller配置rbac,新建rabc-config.yaml并应用

# 在:https://github.com/helm/helm/blob/master/docs/rbac.md 可以找到rbac-config.yaml cat > rbac-config.yaml <

制定镜像

docker pull jessestuart/tiller:v2.14.2 yum install socat  # yum install socat docker tag jessestuart/tiller:v2.14.2 gcr.io/kubernetes-helm/tiller:v2.14.2 helm init -i gcr.io/kubernetes-helm/tiller:v2.9.0  # 需要注意点参数 –client-only:也就是不安装服务端应用,这在 CI&CD 中可能需要,因为通常你已经在 k8s 集群中安装好应用了,这时只需初始化 helm 客户端即可; –history-max:最大历史,当你用 helm 安装应用的时候,helm 会在所在的 namespace 中创建一份安装记录,随着更新次数增加,这份记录会越来越多; –tiller-namespace:默认是 kube-system,你也可以设置为其它 namespace; 复制代码

修改镜像

# 由于gfw原因,可以利用此镜像https://hub.docker.com/r/jessestuart/tiller/tags kubectl edit deployment -n kube-system tiller-deploy image: jessestuart/tiller:v2.14.0 复制代码

异常处理

Error: Looks like "https://kubernetes-charts.storage.googleapis.com" is not a valid chart repository or cannot be reached: Get https://kubernetes-charts.storage.googleapis.com/index.yaml: read tcp 10.2.8.44:49020->216.58.220.208:443: read: connection reset by peer 解决方案:更换源:helm repo add stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts 然后在helm init 注意:tiller可能运行在node节点,将tiller镜像下载到node节点并修改tag 复制代码

查看版本

[root@master ~]# helm version Client: &version.Version{SemVer:"v2.14.2", GitCommit:"a8b13cc5ab6a7dbef0a58f5061bcc7c0c61598e7", GitTreeState:"clean"} Server: &version.Version{SemVer:"v2.14.2+unreleased", GitCommit:"d953c6875cfd4b351a1e8205081ea8aabad7e7d4", GitTreeState:"dirty"} 复制代码

4.2 helm3 安装部署

由于国外很多镜像网站国内无法访问,例如gcr.io ,建议使用阿里源,developer.aliyun.com/hub。

AppHub 是一个托管在国内公有云上、全公益性的 Helm Hub “中国站”,它的后端由阿里云容器平台团队的三位工程师利用 20% 时间开发完成。

而这个站点的一个重要职责,就是把所有 Helm 官方 Hub 托管的应用自动同步到国内;同时,自动将 Charts 文件中的 gcr.io 等所有有网络访问问题的 URL 替换成为稳定的国内镜像 URL。

目前helm3已经不依赖于tiller,Release 名称可在不同 ns 间重用。

4.2.1 安装helm

Helm3 不需要安装tiller,下载到 Helm 二进制文件直接解压到 $PATH 下就可以使用了。

cd /opt && wget https://cloudnativeapphub.oss-cn-hangzhou.aliyuncs.com/helm-v3.0.0-alpha.1-linux-amd64.tar.gz tar -xvf helm-v3.0.0-alpha.1-linux-amd64.tar.gz mv linux-amd64 helm3 mv helm3/helm helm3/helm3 chown root.root helm3 -R cat > /etc/profile.d/helm3.sh << EOF export PATH=$PATH:/opt/helm3 EOF source /etc/profile.d/helm3.sh [root@master helm3]# helm3 version version.BuildInfo{Version:"v3.0.0-alpha.1", GitCommit:"b9a54967f838723fe241172a6b94d18caf8bcdca", GitTreeState:"clean"} 复制代码

4.2.2 使用helm3安装应用

helm repo add apphub https://apphub.aliyuncs.com helm search guestbook helm install guestbook apphub/guestbook 复制代码

五 使用

5.1 基础命令

http://hub.kubeapps.com/ completion  # 为指定的shell生成自动完成脚本(bash或zsh) create      # 创建一个具有给定名称的新 chart delete      # 从 Kubernetes 删除指定名称的 release dependency  # 管理 chart 的依赖关系 fetch       # 从存储库下载 chart 并(可选)将其解压缩到本地目录中 get         # 下载一个命名 release help        # 列出所有帮助信息 history     # 获取 release 历史 home        # 显示 HELM_HOME 的位置 init        # 在客户端和服务器上初始化Helm inspect     # 检查 chart 详细信息 install     # 安装 chart 存档 lint        # 对 chart 进行语法检查 list        # releases 列表 package     # 将 chart 目录打包成 chart 档案 plugin      # 添加列表或删除 helm 插件 repo        # 添加列表删除更新和索引 chart 存储库 reset       # 从集群中卸载 Tiller rollback    # 将版本回滚到以前的版本 search      # 在 chart 存储库中搜索关键字 serve       # 启动本地http网络服务器 status      # 显示指定 release 的状态 template    # 本地渲染模板 test        # 测试一个 release upgrade     # 升级一个 release verify      # 验证给定路径上的 chart 是否已签名且有效 version     # 打印客户端/服务器版本信息 dep         # 分析 Chart 并下载依赖 复制代码

指定value.yaml部署一个chart

helm install --name els1 -f values.yaml stable/elasticsearch 复制代码

升级一个chart

helm upgrade --set mysqlRootPassword=passwd db-mysql stable/mysql helm upgrade go2cloud-api-doc go2cloud-api-doc/  复制代码

回滚一个 chart

helm rollback db-mysql 1 复制代码

删除一个 release

helm delete --purge db-mysql 复制代码

只对模板进行渲染然后输出,不进行安装

helm install/upgrade xxx --dry-run --debug 复制代码

5.2 Chart文件组织

myapp/                               # Chart 目录 ├── charts                           # 这个 charts 依赖的其他 charts,始终被安装 ├── Chart.yaml                       # 描述这个 Chart 的相关信息、包括名字、描述信息、版本等 ├── templates                        # 模板目录 │   ├── deployment.yaml              # deployment 控制器的 Go 模板文件 │   ├── _helpers.tpl                 # 以 _ 开头的文件不会部署到 k8s 上,可用于定制通用信息 │   ├── ingress.yaml                 # ingress 的模板文件 │   ├── NOTES.txt                    # Chart 部署到集群后的一些信息,例如:如何使用、列出缺省值 │   ├── service.yaml                 # service 的 Go 模板文件 │   └── tests │       └── test-connection.yaml └── values.yaml                      # 模板的值文件,这些值会在安装时应用到 GO 模板生成部署文件 复制代码

5.3 新建自己的Chart

创建自己的mychart

[root@master mychart]# helm create mychart Creating mychart [root@master mychart]# ls mychart [root@master mychart]# tree mychart/ mychart/ ├── charts ├── Chart.yaml ├── templates │   ├── deployment.yaml # 部署相关资源 │   ├── _helpers.tpl # 模版助手 │   ├── ingress.yaml # ingress资源 │   ├── NOTES.txt # chart的帮助文本,运行helm install展示给用户 │   ├── service.yaml # service端点 │   └── tests │       └── test-connection.yaml └── values.yaml 3 directories, 8 files 复制代码

删除template下的所有文件,并创建configmap

rm -rf mychart/templates/* # 我们首先创建一个名为 mychart/templates/configmap.yaml: apiVersion: v1 kind: ConfigMap metadata:   name: mychart-configmap data:   myvalue: "Hello World" 复制代码

安装测试

由于创建的yaml文件在template下,tiller读取此文件,会将其发送给kubernetes。

[root@master mychart]# helm install ./mychart/ NAME:   enervated-dolphin LAST DEPLOYED: Sun Jul 21 09:29:13 2019 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/ConfigMap NAME               DATA  AGE mychart-configmap  1     0s [root@master mychart]# kubectl get cm mychart-configmap NAME                DATA   AGE mychart-configmap   1      2m6s [root@master mychart]# kubectl describe cm mychart-configmap Name:         mychart-configmap Namespace:    default Labels:        Annotations:   Data ==== myvalue: ---- this is my chart configmap Events:   [root@master mychart]# helm get manifest enervated-dolphin --- # Source: mychart/templates/configmap.yaml apiVersion: v1 kind: ConfigMap metadata:   name: mychart-configmap data:   myvalue: "this is my chart configmap" 复制代码

该 helm get manifest 命令获取 release 名称(enervated-dolphin)并打印出上传到服务器的所有 Kubernetes 资源。每个文件都以 --- 开始作为 YAML 文档的开始,然后是一个自动生成的注释行,告诉我们该模板文件生成的这个 YAML 文档。

从那里开始,我们可以看到 YAML 数据正是我们在我们的 configmap.yaml 文件中所设计的 。

现在我们可以删除我们的 release:helm delete enervated-dolphin。

[root@master mychart]# helm delete enervated-dolphin release "enervated-dolphin" deleted 复制代码

5.4 添加模版调用

硬编码 name: 成资源通常被认为是不好的做法。名称应该是唯一的一个版本。所以我们可能希望通过插入 release 名称来生成一个名称字段。

提示: name: 由于 DNS 系统的限制,该字段限制为 63 个字符。因此,release 名称限制为 53 个字符。Kubernetes 1.3 及更早版本仅限于 24 个字符(即 14 个字符名称)。

修改下之前的configmap为如下内容

apiVersion: v1 kind: ConfigMap metadata:   name: {{.Release.Name}}-configmap data:   myvalue: "Hello World" 复制代码

name: 现在这个值发生了变化成了 {{.Release.Name}}-configmap。

模板指令包含在 {{ 和 }} 块中。

模板指令 {{.Release.Name}} 将 release 名称注入模板。传递给模板的值可以认为是 namespace 对象,其中 dot(.)分隔每个 namespace 元素。

Release 前面的前一个小圆点表示我们从这个范围的最上面的 namespace 开始(我们将稍微谈一下 scope)。所以我们可以这样理解 .Release.Name:"从顶层命名空间开始,找到 Release 对象,然后在里面查找名为 Name 的对象"。

该 Release 对象是 Helm 的内置对象之一,稍后我们将更深入地介绍它。但就目前而言,这足以说明这会显示 Tiller 分配给我们发布的 release 名称。

现在,当我们安装我们的资源时,我们会立即看到使用这个模板指令的结果:

[root@master mychart]# helm install ./mychart/ NAME:   famous-peahen LAST DEPLOYED: Sun Jul 21 09:42:05 2019 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/ConfigMap NAME                    DATA  AGE famous-peahen-confgmap  1     0s [root@master mychart]# helm get manifest famous-peahen --- # Source: mychart/templates/configmap.yaml apiVersion: v1 kind: ConfigMap metadata:   name: famous-peahen-confgmap data:   myvalue: "this is my chart configmap" 复制代码

我们看过了基础的模板:YAML 文件嵌入了模板指令,通过 。在下一部分中,我们将深入研究模板。但在继续之前,有一个快速技巧可以使构建模板更快:当您想测试模板渲染,但实际上没有安装任何东西时,可以使用 helm install --debug --dry-run ./mychart。这会将 chart 发送到 Tiller 服务器,它将渲染模板。但不是安装 chart,它会将渲染模板返回,以便可以看到输出:

六 实战

6.1 制作charts

将用slate做好的go2cloud-api-doc 利用helm做成charts,方便后续部署

helm create go2cloud-api-doc [root@master go2cloud-api-doc]# tree  . ├── charts ├── Chart.yaml ├── templates │   ├── deployment.yaml │   ├── _helpers.tpl │   ├── NOTES.txt │   ├── service.yaml │   └── tests │       └── test-connection.yaml └── values.yaml 3 directories, 8 files  # 配置 deployment [root@master go2cloud_api_doc_charts]# egrep "^$|^#" -v go2cloud-api-doc/templates/deployment.yaml   apiVersion: apps/v1 kind: Deployment metadata:   name: {{ include "go2cloud-api-doc.fullname" . }}   labels: {{ include "go2cloud-api-doc.labels" . | indent 4 }} spec:   replicas: {{ .Values.replicaCount }}   selector:     matchLabels:       app.kubernetes.io/name: {{ include "go2cloud-api-doc.name" . }}       app.kubernetes.io/instance: {{ .Release.Name }}   template:     metadata:       labels:         app.kubernetes.io/name: {{ include "go2cloud-api-doc.name" . }}         app.kubernetes.io/instance: {{ .Release.Name }}     spec:       imagePullSecrets:          - name: {{ .Values.imagePullSecrets }}       containers:         - name: {{ .Chart.Name }}           image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"           imagePullPolicy: {{ .Values.image.pullPolicy }}           ports:             - name: http               containerPort: {{ .Values.service.port }}               protocol: TCP           livenessProbe:             {{- toYaml .Values.livenessProbe | nindent 12  }}           readinessProbe:             {{- toYaml .Values.readinessProbe | nindent 12  }}           resources:             {{- toYaml .Values.resources | nindent 12 }}       {{- with .Values.nodeSelector }}       nodeSelector:         {{- toYaml . | nindent 8 }}       {{- end }}     {{- with .Values.affinity }}       affinity:         {{- toYaml . | nindent 8 }}     {{- end }}     {{- with .Values.tolerations }}       tolerations:         {{- toYaml . | nindent 8 }}     {{- end }}  # 配置service [root@master go2cloud_api_doc_charts]# egrep "^$|^#" -v go2cloud-api-doc/templates/service.yaml  apiVersion: v1 kind: Service metadata:   name: {{ include "go2cloud-api-doc.fullname" . }}   labels: {{ include "go2cloud-api-doc.labels" . | indent 4 }} spec:   type: {{ .Values.service.type }}   ports:     - port: {{ .Values.service.port }}       targetPort: {{ .Values.service.port }}       protocol: TCP       name: http       nodePort: {{ .Values.service.nodePort }}         selector:     app.kubernetes.io/name: {{ include "go2cloud-api-doc.name" . }}     app.kubernetes.io/instance: {{ .Release.Name }}  # 配置values [root@master go2cloud_api_doc_charts]# egrep "^$|^#|^[[:space:]]+#" -v go2cloud-api-doc/values.yaml replicaCount: 1 image:   repository: 10.234.2.218/go2cloud/go2cloud-api-doc   tag: latest   pullPolicy: Always imagePullSecrets: registry-secret nameOverride: "" fullnameOverride: "" service:   type: NodePort   port: 4567   nodePort: 30567 ingress:   enabled: false   annotations: {}   hosts:     - host: chart-example.local       paths: []   tls: [] resources:    requests:     cpu: 1000m     memory: 1280Mi   limits:     cpu: 1000m     memory: 1280Mi livenessProbe:   tcpSocket:     port: 4567   initialDelaySeconds: 10   failureThreshold: 2    timeoutSeconds: 10 readinessProbe:   httpGet:     path: /#introduction     port: http   initialDelaySeconds: 5   failureThreshold: 2    timeoutSeconds: 30 nodeSelector: {} tolerations: [] affinity: {} [root@master go2cloud_api_doc_charts]# egrep "^$|^#|^[[:space:]]+#" -v go2cloud-api-doc/Chart.yaml  apiVersion: v1 appVersion: "1.0" description: A Helm chart for Kubernetes name: go2cloud-api-doc version: 0.1.0  # 部署 [root@master go2cloud_api_doc_charts]# helm install -n go2cloud-api-doc -f go2cloud-api-doc/values.yaml go2cloud-api-doc/                   NAME:   go2cloud-api-doc LAST DEPLOYED: Wed Jul 31 14:34:21 2019 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/Deployment NAME              READY  UP-TO-DATE  AVAILABLE  AGE go2cloud-api-doc  0/1    1           0          0s ==> v1/Pod(related) NAME                               READY  STATUS             RESTARTS  AGE go2cloud-api-doc-7cfb7bb795-clrz8  0/1    ContainerCreating  0         0s ==> v1/Service NAME              TYPE      CLUSTER-IP     EXTERNAL-IP  PORT(S)         AGE go2cloud-api-doc  NodePort  10.96.228.251         4567:30567/TCP  0s NOTES: 1. Get the application URL by running these commands:   export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services go2cloud-api-doc)   export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")   echo http://$NODE_IP:$NODE_PORT [root@master go2cloud_api_doc_charts]# helm ls go2cloud-api-doc NAME                    REVISION        UPDATED                         STATUS          CHART                   APP VERSION     NAMESPACE go2cloud-api-doc        1               Wed Jul 31 14:34:21 2019        DEPLOYED        go2cloud-api-doc-0.1.0  1.0             default   [root@master go2cloud_api_doc_charts]# kubectl get deployment go2cloud-api-doc NAME               READY   UP-TO-DATE   AVAILABLE   AGE go2cloud-api-doc   0/1     1            0           10m [root@master go2cloud_api_doc_charts]# kubectl get pods |grep go2cloud-api-doc go2cloud-api-doc-7cfb7bb795-clrz8                         0/1     CrashLoopBackOff   7          10m [root@master go2cloud_api_doc_charts]# kubectl get svc go2cloud-api-doc NAME               TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE go2cloud-api-doc   NodePort   10.96.228.251           4567:30567/TCP   10m  # 打包 [root@master go2cloud_api_doc_charts]# helm package ./go2cloud-api-doc/ Successfully packaged chart and saved it to: /data/go2cloud_api_doc_charts/go2cloud-api-doc-0.1.0.tgz [root@master go2cloud_api_doc_charts]# tree  . ├── go2cloud-api-doc │   ├── charts │   ├── Chart.yaml │   ├── templates │   │   ├── deployment.yaml │   │   ├── _helpers.tpl │   │   ├── NOTES.txt │   │   ├── service.yaml │   │   └── tests │   │       └── test-connection.yaml │   └── values.yaml └── go2cloud-api-doc-0.1.0.tgz 4 directories, 8 files  # 升级副本数量 helm upgrade go2cloud-api-doc --set replicaCount=2 go2cloud-api-doc/ 复制代码

6.2 配置minior

将制作好的charts存放到minio上,在k8s内部署minior

创建本地chart目录

玩K8S不得不会的HELM

mkdir minio-chart 复制代码

将修改好的chart文件打包

helm package redis 复制代码

将包拷贝至创建的本地chart目录中

cp redis-8.0.5.tgz /root/minio-chart/ 复制代码

更新/root/minio-chart/目录下的index索引

helm repo index minio-chart/ --url http://10.234.2.204:31311/minio/common-helm-repo/ 复制代码

将index.yaml 和chart包上传至minio

mc cp index.yaml minio/common-helm-repo/ mc cp redis-8.0.5.tgz minio/common-helm-repo/ 复制代码

将制作好的charts上传至minio

helm repo add monocular https://helm.github.io/monocular helm install -n monocular monocular/monocular mc cp go2cloud-api-doc-0.1.0.tgz minio/common-helm-repo 复制代码

可以在${HOME}/.mc/config.json中查看ak密钥信息。

验证

6.3 上传至公共的helm仓库

将制作好的charts包可以上传至helm仓库,可以放在自己的自建私有仓库,流入:kubeapps/Monocular/minior等,可以利用helm命令一键安装。

上传至公有云公共仓库,例如国内的阿里目前创建的Apphub等,在现今的云原生生态当中,已经有很多成熟的开源软件被制作成了 Helm Charts,使得用户可以非常方便地下载和使用,比如 Nginx,Apache、Elasticsearch、Redis 等等。不过,在开放云原生应用中心 App hub(Helm Charts 中国站) 发布之前,国内用户一直都很难直接下载使用这些 Charts。而现在,AppHub 不仅为国内用户实时同步了官方 Helm Hub 里的所有应用,还自动替换了这些 Charts 里所有不可访问的镜像 URL(比如 gcr.io, quay.io 等),终于使得国内开发者通过 helm install “一键安装”应用成为了可能。

具体提交自己的charts可以参考:github.com/cloudnative…

此为我上传的slate chart,Slate helps you create beautiful, intelligent, responsive API documentation.

developer.aliyun.com/hub/detail?…

欢迎。

七 相关链接

helm githab地址

helm 手册

whmzsu.github.io/helm-doc-zh…

github.com/helm/monocu…

Helm3

GitHub Kubernetes

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Excel2016表格中更换字体的方法有哪些
下一篇:滚动条网页应用技术研究
相关文章