- Published on
Kubernetes上如何使用Helm
- Authors
- Name
- 老杨的博客
Kubernetes 上如何使用 Helm
[TOC]
1. 环境说明
操作系统:CentOS7 kubernetes:1.11
2. helm 安装
# 下载脚本并执行安装
curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get > get_helm.sh
bash get_helm.sh
# 查看Helm客户端的版本号
helm version
注意版本号,后续容器服务的版本要和这个一致, 否则会出现问题。
Client: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}
# 在 Kubernetes 群集上安装 Tiller(helm服务端),注意和上面版本号一致
helm init --upgrade -i registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.9.1 --stable-repo-url https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
说明:
helm init --upgrade
会在 Kubernetes 集群上安装配置 Tiller, 仓库默认使用https://kubernetes-charts.storage.googleapis.com 。由于国内无法访问相关域名,可以使用阿里云容器服务提供的镜像和站点。
查看容器运行情况
kubectl get pod --all-namespaces|grep tiller
kube-system tiller-deploy-b67849f44-cs4qr 1/1 Running 0 46m
从 Kubernetes 1.6 开始,API Server 启用了 RBAC 授权。而 Tiller 部署没有定义授权的 ServiceAccount,这会导致访问 API Server 时被拒绝。我们可以采用如下方法,为 Tiller 部署添加授权。
kubectl create serviceaccount --namespace kube-system tiller
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
# 查看已部署的应用
helm list
卸载 helm 服务端
helm reset
# helm reset --force
3. helm 使用
# 先移除原先的仓库
helm repo remove stable
# 添加新的仓库地址
helm repo add stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
# 更新仓库
helm repo update
4. 安装 Monocular
Monocular 基于 web 的用户界面,用于管理 Kubernetes 应用打包为 Helm Charts。它允许您从多个存储库搜索和发现可用 Chats,并安装在您的集群中,只需要鼠标点点就能完成。
准备条件 * Helm 和 Tiller 已安装 * Nginx Ingress controller 已安装 * Install with Helm: helm install stable/nginx-ingress
* Minikube/Kubeadm: helm install stable/nginx-ingress --set controller.hostNetwork=true
安装
helm repo add monocular https://helm.github.io/monocular
helm install --name monocular monocular/monocular
默认它是配置到 ingress 中的,通过 ingress 节点 IP 就能访问。
注意 安装过程中,pvc 创建提示失败,需要手动干预提供可用 pvc。
5. 安装 Kubeapps
kubeapps 是一个基于 web 的用户界面,用于部署和管理在 kubernetes 群集中的应用程序。Kubeapps 允许你: * 浏览并部署存储库中的 chats * 检查、升级和删除集群中安装的基于helm
的应用程序 * 添加自定义和私有的 chat 存储库(支持ChartMuseum and JFrog Artifactory) * 浏览并提供来自Service Catalog的外部服务和可用的服务中介 * 用服务目录绑定基于helm
的应用程序连接到外部服务 * 基于 kubernetes RBAC 的安全认证和授权
安装
kubectl create namespace kubeapps
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install --name kubeapps --namespace kubeapps bitnami/kubeapps
6. 2 个工具对比
- 在功能上,2 个基本一样;
- 用户体验上,当前 2 个的最新版本,Kubeapps(v1.0.0-alpha.6)要优于 Monocular(0.7.3),部署时 Kubeapps 能让用户直接修改一些默认参数;
- 安全上,Kubeapps 直接使用 Kubernetes 的 RBAC,和 Kubernetes 的 dashboard 的 toke 登录方式一样。Monocular 登录功能用不了;
- 对外提供访问上,Kubeapps 的
kubectl port-forward
不推荐,最好配置 ingress,而 Monocular 已自动配置 ingress;
7. chart repo
chart repo 是一个可用来存储 index.yml 与打包的 chart 文件的 HTTP server。
当要分享 chart 时,需要上传 chart 文件到 chart 仓库。任何一个能能够提供 YAML 与 tar 文件的 HTTP server 都可以当做 chart 仓库,比如 Google Cloud Storage (GCS) bucket、Amazon S3 bucket、Github Pages 或创建你自己的 web 服务器。官方 chart 仓库由 Kubernetes Charts 维护, Helm 允许我们创建私有 chart 仓库。
7.1 chart repo 结构
查看目前的 repo,helm repo list
NAME URL
stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
local http://localhost:8879/charts
monocular https://helm.github.io/monocular
bitnami https://charts.bitnami.com/bitnami
incubator http://storage.googleapis.com/kubernetes-charts-incubator
helm
执行 tiller 命令后默认会配置一个名为 l 的本地 repo。
一个 chart 仓库由一个 chart 包与index.yaml
文件组成,index.yaml
记录了 chart 仓库中全部 chart 的索引,一个本地 chart 仓库的布局例子如下:
~/.helm/
|-- cache
| `-- archive
| |-- drupal-0.9.2.tgz
| `-- mariadb-1.0.3.tgz
|-- plugins
|-- repository
| |-- cache
| | |-- fantastic-charts-index.yaml
| | |-- local-index.yaml -> /home/ts1/.helm/repository/local/index.yaml
| | |-- mariadb-1.0.3.tgz-index.yaml
| | |-- memcached-1.2.1.tgz-index.yaml
| | |-- mychart_xia-0.1.0.tgz-index.yaml
| | |-- mysql-0.2.8.tgz-index.yaml
| | |-- stable-index.yaml
| | |-- test-0.1.0.tgz-index.yaml
| | `-- test-0.1.8.tgz-index.yaml
| |-- local
| | |-- index.yaml
| | |-- mychart-0.1.0.tgz
| | |-- mychart_xia-0.1.0.tgz
| | |-- mysql-0.2.8.tgz
| | |-- mysql-6.19.centos-29.tgz
| | |-- test-0.1.0.tgz
| | |-- test-0.1.8.tgz
| | `-- test-0.1.9.tgz
| `-- repositories.yaml
`-- starters
~/.helm/repository/local/index.yaml 文件中记录了 chart 的诸如名称、url、version 等一些 metadata 信息。
7.2 启动 repo 服务
mkdir -p /data/helm/charts
cat > /data/helm/start_local_helm.sh <<EOF
#!/usr/bin/env bash
helm_path=\$(which helm)
helm_pid=\$(pidof \$helm_path)
helm_data_path="/data/helm/charts"
if [ -z "\$helm_pid" ]; then
cd \$helm_data_path
nohup \$helm_path serve --address 0.0.0.0:8879 --repo-path \$helm_data_path &
else
echo -e "helm already running."
fi
exit 0
EOF
sh /data/helm/start_local_helm.sh
helm serve --help
This command starts a local chart repository server that serves charts from a local directory.
The new server will provide HTTP access to a repository. By default, it will
scan all of the charts in '$HELM_HOME/repository/local' and serve those over
the local IPv4 TCP port (default '127.0.0.1:8879').
This command is intended to be used for educational and testing purposes only.
It is best to rely on a dedicated web server or a cloud-hosted solution like
Google Cloud Storage for production use.
See https://github.com/kubernetes/helm/blob/master/docs/chart_repository.md#hosting-chart-repositories
for more information on hosting chart repositories in a production setting.
Usage:
helm serve [flags]
Flags:
--address string address to listen on (default "127.0.0.1:8879")
--repo-path string local directory path from which to serve charts
--url string external URL of chart repository
Global Flags:
--debug enable verbose output
--home string location of your Helm config. Overrides $HELM_HOME (default "/root/.helm")
--host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system")
添加本地 repo helm repo add local http://192.168.105.92:8879/charts
7.3 向 repo 中增加软件包
上面步骤中,已经创建了一个本地的 repo,接下来讲述如何在 repo 中增加一个可用来部署的软件包 chart。chart 须遵循 SemVer 2 规则填写正确的版本格式。各种 chart 包可以在github下载。
因为官方 chart 里的 image 镜像被墙的可能和自己定制参数的设置,我们将修改过的 chart 添加到本机 chart 中。
cd /data/helm
helm fetch incubator/zookeeper --untar
helm package zookeeper
mv zookeeper-1.1.1.tgz charts/
注
helm package
的作用是在当前目录下将软件打包为 tgz,假如这个软件包中有 requirement.yaml,则打包时还需要加上--dependency-update
,用来update dependencies from "requirements.yaml" to dir "charts/" before packaging
更新 index.yaml 文件
cd /data/helm
helm repo index charts --url http://192.168.105.92:8879/charts
helm repo remove local
helm repo add local http://192.168.105.92:8879/charts
查看 chart 是否上传仓库成功: helm search zookeeper|grep local
local/zookeeper 1.1.1 3.4.10 Centralized service for maintaining configurati...
8. 应用部署和版本管理
获取 chart 获取版本为 0.3.5 的 mysql 并解压缩包:
$ helm fetch stable/mysql --version 0.3.5 --untar
$ ls mysql/
Chart.yaml README.md templates values.yaml
$ helm lint mysql
==> Linting mysql
Lint OK
1 chart(s) linted, no failures
利用 helm lint 命令检查下载的 chart 是否存在问题:
$ helm lint mysql
==> Linting mysql
Lint OK
1 chart(s) linted, no failures
创建自定义 chart helm create mychart
查看 mychart 结构:
mychart/
├── charts
├── Chart.yaml
├── templates
│ ├── deployment.yaml
│ ├── _helpers.tpl
│ ├── ingress.yaml
│ ├── NOTES.txt
│ └── service.yaml
└── values.yaml
2 directories, 7 files
生成 chart 目录里有Chart.yaml
, values.yaml
and NOTES.txt
等文件,下面分别对 chart 中几个重要文件解释: Chart.yaml
包含了 chart 的 metadata,描述了 Chart 名称、描述信息与版本。 values.yaml
:存储了模板文件变量。 templates/
:记录了全部模板文件。 charts/
:依赖 chart 存储路径。
其中mychart/templates/
的文件及其作用如下: NOTES.txt
:给出了部署 chart 后的帮助文档,例如如何使用 chart、列出默认的设置等。 deployment.yaml
:创建 Kubernetes deployment 的 yaml 文件。 service.yaml
:创建 deployment 的 service endpoint yams 文件。 _helpers.tpl
: 模板使用帮助文件。
chart 安装有以下几种方式: 指定 chart: helm install stable/mariadb
指定打包的 chart: helm install ./nginx-1.2.3.tgz
指定打包目录: helm install ./nginx
指定 chart 包 URL: helm install https://example.com/charts/nginx-1.2.3.tgz
覆盖 chart 中的默认值,通过指定配置文件方式: helm install -f myvalues.yaml ./redis
或者通过–set key=value 形式: helm install --set name=prod ./redis
安装 release 名称为 mysql 例子如下,请注意 NOTES 中对 Mysql 的使用说明:
vim mysql/values.yaml
找到 storageClass,并修改其值,这里我们使用可用的动态卷ceph-rbd
storageClass: "ceph-rbd"`
安装 release
[root@lab1 helm]# helm install -n mysql -f mysql/values.yaml --set resources.requests.memory=512Mi mysql
NAME: mysql
LAST DEPLOYED: Mon Aug 27 11:23:27 2018
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Secret
NAME TYPE DATA AGE
mysql-mysql Opaque 2 0s
==> v1/PersistentVolumeClaim
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysql-mysql Pending ceph-rbd 0s
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mysql-mysql ClusterIP 10.101.206.24 <none> 3306/TCP 0s
==> v1beta1/Deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
mysql-mysql 1 1 1 0 0s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
mysql-mysql-7f56cd565b-sfmgj 0/1 Pending 0 0s
NOTES:
MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
mysql-mysql.default.svc.cluster.local
To get your root password run:
MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace default mysql-mysql -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echo)
To connect to your database:
1. Run an Ubuntu pod that you can use as a client:
kubectl run -i --tty ubuntu --image=ubuntu:16.04 --restart=Never -- bash -il
2. Install the mysql client:
$ apt-get update && apt-get install mysql-client -y
3. Connect using the mysql cli, then provide your password:
$ mysql -h mysql-mysql -p
To connect to your database directly from outside the K8s cluster:
MYSQL_HOST=127.0.0.1
MYSQL_PORT=3306
# Execute the following commands to route the connection:
export POD_NAME=$(kubectl get pods --namespace default -l "app=mysql-mysql" -o jsonpath="{.items[0].metadata.name}")
kubectl port-forward $POD_NAME 3306:3306
mysql -h ${MYSQL_HOST} -P${MYSQL_PORT} -u root -p${MYSQL_ROOT_PASSWORD}
查看 release 状态helm status mysql
NAME: mysql
LAST DEPLOYED: Mon Aug 27 11:23:27 2018
NAMESPACE: default
STATUS: DEPLOYED
或通过 helm list -a 查看全部的 release,tag “-a”是查看全部的 release,包括已部署、部署失败、正在删除、已删除 release 等。
更新 release
helm upgrade mysql -f mysql/values.yaml --set resources.requests.memory=1024Mi mysql
查看指定 release 的历史部署版本信息:
[root@lab1 helm]# helm hist mysql
REVISION UPDATED STATUS CHART DESCRIPTION
1 Mon Aug 27 11:23:27 2018 SUPERSEDED mysql-0.3.5 Install complete
2 Mon Aug 27 11:26:09 2018 DEPLOYED mysql-0.3.5 Upgrade complete
查看指定 release 的历史版本部署时部分配置信息,以 resources.requests.memory 为例,符合查看部署符合预期:即第一次部署 resources.requests.memory 设置为 512Mi,第二次的升级 resources.requests.memory 设置为 1024Mi:
helm get --revision 1 mysql
版本回滚
回滚到第一次的版本:
[root@lab1 helm]# helm rollback --debug mysql 1
[debug] Created tunnel using local port: '44164'
[debug] SERVER: "127.0.0.1:44164"
Rollback was a success! Happy Helming!
查看 mysql release 的版本信息,当前已经回滚到 REVISION 为 1 的版本:
[root@lab1 helm]# helm hist mysql
REVISION UPDATED STATUS CHART DESCRIPTION
1 Mon Aug 27 11:23:27 2018 SUPERSEDED mysql-0.3.5 Install complete
2 Mon Aug 27 11:26:09 2018 SUPERSEDED mysql-0.3.5 Upgrade complete
3 Mon Aug 27 11:29:24 2018 SUPERSEDED mysql-0.3.5 Rollback to 1
删除 release
[root@lab1 helm]# helm delete mysql
release "mysql" deleted
确认 release 是否删除:
[root@lab1 helm]# helm ls -a mysql
NAME REVISION UPDATED STATUS CHART NAMESPACE
mysql 4 Mon Aug 27 11:29:45 2018 DELETED mysql-0.3.5 default
即使删除的 release ,其发布的历史信息还是继续被保存。
[root@lab1 helm]# helm hist mysql
REVISION UPDATED STATUS CHART DESCRIPTION
1 Mon Aug 27 11:23:27 2018 SUPERSEDED mysql-0.3.5 Install complete
2 Mon Aug 27 11:26:09 2018 SUPERSEDED mysql-0.3.5 Upgrade complete
3 Mon Aug 27 11:29:24 2018 SUPERSEDED mysql-0.3.5 Rollback to 1
4 Mon Aug 27 11:29:45 2018 DELETED mysql-0.3.5 Deletion complete
可以恢复一个已经删除的 release:
[root@lab1 helm]# helm rollback --debug mysql 2
[debug] Created tunnel using local port: '33811'
[debug] SERVER: "127.0.0.1:33811"
Error: "mysql" has no deployed releases
如果希望彻底删除一个 release,可以用如下命令:
[root@lab1 helm]# helm delete --purge mysql
release "mysql" deleted
再次查看刚被删除的 mysql release,提示已经无法找到,符合预期:
[root@lab1 helm]# helm hist mysql
Error: release: "mysql" not found
Helm 对 release 的版本管理
在上面例子中,已经展示了 Helm 对 release 的非常强大的版本管理功能,比如通过helm list -a
查看有哪些 release,通过helm hist
查看某一个具体的 release 发布过的历史版本,以及通过helm get --revision
,查看某个 release 的一次历史版本对应的具体应用配置信息等。即使已经被删除的 release 仍然有记录,并且通过 Helm 能够快速回滚到已删除 release 的某个发布过的历史版本。Helm 的这些版本管理功能,Kubernetes 原生并不支持。
参考资料:
[1] https://helm.sh/
[2] https://whmzsu.github.io/helm-doc-zh-cn/
[3] 简化 Kubernetes 应用部署工具-Helm 简介
[4] 简化 Kubernetes 应用部署工具-Helm 安装
[5] 简化 Kubernetes 应用部署工具-Helm 之应用部署
[6] 简化 Kubernetes 应用部署工具-Helm 之 Release 配置
[7] https://github.com/helm/monocular
[8] https://github.com/kubeapps/kubeapps