什么是 Helm 在没使用 helm 之前,向 kubernetes 部署应用,我们要依次部署 deployment、svc 等,步骤较繁琐。况且随 着很多项目微服务化,复杂的应用在容器中部署以及管理显得较为复杂,helm 通过打包的方式,支持发布的版本 管理和控制,很大程度上简化了 Kubernetes 应用的部署和管理
Helm 本质就是让 K8s 的应用管理(Deployment,Service 等 ) 可配置,能动态生成。通过动态生成 K8s 资源清单文件(deployment.yaml,service.yaml)。然后调用 Kubectl 自动执行 K8s 资源部署
Helm 是官方提供的类似于 YUM 的包管理器,是部署环境的流程封装。Helm 有两个重要的概念:chart 和 release
chart 是创建一个应用的信息集合,包括各种 Kubernetes 对象的配置模板、参数定义、依赖关系、文档说 明等。chart 是应用部署的自包含逻辑单元。可以将 chart 想象成 apt、yum 中的软件安装包
release 是 chart 的运行实例,代表了一个正在运行的应用。当 chart 被安装到 Kubernetes 集群,就生成 一个 release。chart 能够多次安装到同一个集群,每次安装都是一个 release
Helm 包含两个组件:Helm 客户端和 Tiller 服务器,如下图所示 缺图
Helm 客户端负责 chart 和 release 的创建和管理以及和 Tiller 的交互。Tiller 服务器运行在 Kubernetes 集群 中,它会处理 Helm 客户端的请求,与 Kubernetes API Server 交互
Helm 部署 1 2 3 4 5 ntpdate ntp1.aliyun.com wget https://get.helm.sh/helm-v2.16.5-linux-amd64.tar.gz tar -zxvf helm-v2.16.5-linux-amd64.tar.gz cd linux-amd64/ cp helm /usr/local/bin/
为了安装服务端 tiller,还需要在这台机器上配置好 kubectl 工具和 kubeconfig 文件,确保 kubectl 工具可以 在这台机器上访问 apiserver 且正常使用。 这里的 node1 节点以及配置好了 kubectl
因为 Kubernetes APIServer 开启了 RBAC 访问控制,所以需要创建 tiller 使用的 service account: tiller 并分 配合适的角色给它。 详细内容可以查看helm文档中的 Role-based Access Control。 这里简单起见直接分配 cluster- admin 这个集群内置的 ClusterRole 给它。创建 rbac-config.yaml 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 cat > rbac-config.yaml <<EOF apiVersion: v1 kind: ServiceAccount metadata: name: tiller namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: tiller roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: tiller namespace: kube-system EOF
1 2 3 kubectl create -f rbac-config.yaml serviceaccount/tiller created clusterrolebinding.rbac.authorization.k8s.io/tiller created
拉取镜像
1 2 3 docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.16.6 docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.16.6 k8s.gcr.io/tiller:v2.16.6 docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.16.6
安装tiller
1 helm init --service-account tiller --history-max 200 --upgrade --tiller-image k8s.gcr.io/tiller:v2.16.6 --stable-repo-url https://cnych.github.io/kube-charts-mirror/
tiller 默认被部署在 k8s 集群中的 kube-system 这个 namespace 下
1 2 3 4 5 6 kubectl get pod -n kube-system -l app=helm NAME READY STATUS RESTARTS AGE tiller-deploy-55479b584d-4kc4b 1/1 Running 2 21h helm version Client: &version.Version{SemVer:"v2.16.9", GitCommit:"8ad7037828e5a0fca1009dabe290130da6368e39", GitTreeState:"clean"} Server: &version.Version{SemVer:"v2.16.6", GitCommit:"dd2e5695da88625b190e6b22e9542550ab503a47", GitTreeState:"clean"}
Helm 自定义模板 1 2 3 # 创建文件夹 mkdir ./hello-world cd ./hello-world
1 2 3 4 5 # 创建自描述文件 Chart.yaml , 这个文件必须有 name 和 version 定义 cat <<'EOF' > ./Chart.yaml name: hello-world version: 1.0.0 EOF
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 # 创建模板文件, 用于生成 Kubernetes 资源清单(manifests) mkdir ./templates cat <<'EOF' > ./templates/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: hello-world labels: app: hello-world spec: replicas: 3 selector: matchLabels: app: hello-world template: metadata: labels: app: hello-world spec: containers: - name: nginx image: nginx:lasest ports: - containerPort: 80 EOF cat <<'EOF' > ./templates/service.yaml apiVersion: v1 kind: Service metadata: name: hello-world spec: type: NodePort ports: - name: http protocol: TCP port: 80 selector: app: hello-world EOF
1 2 # 使用命令 helm install RELATIVE_PATH_TO_CHART 创建一次Release $ helm install .
1 2 3 4 # 查看 hello-world的部署情况 helm list NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE wistful-ferret 1 Thu Jul 2 18:42:42 2020 DEPLOYED hello-world-1.0.0 default
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # 这个文件中定义的值,在模板文件中可以通过 .VAlues对象访问到 cat <<'EOF' > ./templates/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: hello-world labels: app: hello-world spec: replicas: 3 selector: matchLabels: app: hello-world template: metadata: labels: app: hello-world spec: containers: - name: nginx image: {{ .Values.image.repository }}:{{ .Values.image.tag }} ports: - containerPort: 80 EOF
创建一个 values.yaml 定义相关值
1 2 3 4 5 6 # 配置体现在配置文件 values.yaml cat <<'EOF' > ./values.yaml image: repository: nginx tag: '1.18' EOF
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # 查看当前的版本信息 helm list NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE wistful-ferret 1 Thu Jul 2 18:42:42 2020 DEPLOYED hello-world-1.0.0 default # 升级版本 helm upgrade -f values.yaml wistful-ferret . # helm list NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE wistful-ferret 2 Fri Jul 3 15:16:24 2020 DEPLOYED hello-world-1.0.0 default # kubectl get pods hello-world-8689856fc-v9s2m -o yaml |grep "\- image: " - image: nginx:1.18
也可以通过命令行显式指定版本号
1 2 # 在 values.yaml 中的值可以被部署 release 时用到的参数 --values YAML_FILE_PATH 或 --set key1=value1, key2=value2 覆盖掉 $ helm install --set image.tag='latest' .
helm 常用命令
1 2 3 4 5 6 7 8 9 10 11 # 列出已经部署的 Release $ helm ls # 查询一个特定的 Release 的状态 $ helm status RELEASE_NAME # 移除所有与这个 Release 相关的 Kubernetes 资源 $ helm delete cautious-shrimp # helm rollback RELEASE_NAME REVISION_NUMBER $ helm rollback cautious-shrimp 1 # 使用 helm delete --purge RELEASE_NAME 移除所有与指定 Release 相关的 Kubernetes 资源和所有这个 Release 的记录 $ helm delete --purge cautious-shrimp $ helm ls --deleted
Debug
1 2 3 # 使用模板动态生成K8s资源清单,非常需要能提前预览生成的结果。 # 使用--dry-run --debug 选项来打印出生成的清单文件内容,而不执行部署 helm install . --dry-run --debug --set image.tag=latest
帮助文档 官方文档 helm 安装 dashboard ingress-nginx deploy ingress-nginx