Helm 初体验
什么是 Helm
我们在 Kubernetes 集群中一开始是使用 kubectl apply -f xxx.yaml 的方式去部署,但它有一个痛点,比如通常我们说的一个应用,可能会需要多个服务共同组成,但通过这种方式部署的服务无法有这种关联关系,特别不利于管理和维护,而 Helm 作为一个包管理工具,可以解决这个问题,不仅可以应用管理,还可以制定依赖关系和启动顺序。
如果有 Linux 使用经验,也可以简单粗暴的理解一下, CentOS/RHEL 系装软件的命令是 rpm install ,但大家都在用 yum install 来维护日常软件,Debian/Ubuntu 系简单命令是 dpkg install ,但大家使用超级牛力 apt install 管理。
什么是 Chart
chart 是 helm 的打包格式,不同于 kubectl apply 所使用的 YAML 文件不同,chart 是一些列的文件,文件数量上会让初学者产生恐惧心理。
安装 Helm
官方脚本
https://github.com/helm/helm/blob/master/scripts/get-helm-3
curl -s https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
若过程中下载 helm 很吃力,那么还是想办法把安装包下载到本地来再安装吧
https://github.com/helm/helm/releases
tar zxvf helm-v3.0.3-linux-amd64.tar.gz
mv linux-amd64/helm /usr/local/bin
rm -rf linux-amd4
尝试一下
与 yum/apt 一样,helm 也有源的概念
# text阿里的源,helm repo add <源的本地名称> <源的URL>
helm repo add alihub https://apphub.aliyuncs.com
# 查看加入的源,可以看到源已经被加入进来
helm repo list
在线安装应用
# 查找刚刚添加的源线上资源,helm search repo <chart名称的关键字>
helm search repo nginx
NAME CHART VERSION APP VERSION DESCRIPTION
alihub/nginx 5.1.4 1.16.1 Chart for the nginx server
alihub/nginx-ingress 1.30.0 0.28.0 An nginx Ingress controller that uses ConfigMap...
alihub/nginx-ingress-controller 5.3.2 0.28.0 Chart for the nginx Ingress controller
alihub/nginx-lego 0.3.1 Chart for nginx-ingress-controller and kube-lego
alihub/nginx-php 1.0.0 nginx-1.10.3_php-7.0 Chart for the nginx php server
# 安装应用,helm install <应用名称> <chart名称>
helm install my-testlink alihub/nginx
NAME: my-nginx
LAST DEPLOYED: Fri Feb 14 12:02:32 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Get the NGINX URL:
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
Watch the status with: 'kubectl get svc --namespace default -w my-nginx'
export SERVICE_IP=$(kubectl get svc --namespace default my-nginx --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}")
echo "NGINX URL: http://$SERVICE_IP/"
# 查看部署的应用, helm list
helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
my-nginx default 1 2020-02-14 12:02:32.005886038 +0800 CST deployed nginx-5.1.4 1.16.1
# 也可以用提示的命令查看
kubectl get svc --namespace default -w my-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx LoadBalancer 10.96.3.55 <pending> 80:30564/TCP,443:32235/TCP 50s
残酷的现实
本以为这样就算部署成功,可以很轻松的访问应用了,但实际上,跟平时使用 NodePort 不同,在线的这些 chart 模板都是使用 LoadBalancer 类型
kubectl get svc my-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx LoadBalancer 10.96.3.55 <pending> 80:30564/TCP,443:32235/TCP 4m
于是需要自己写个 chart 模板,可以把源上的 chart 拉下来
helm pull alihub/nginx
当前目录会生成一个 tgz 的打包压缩, tar zvxf 解压它,得到类似如下的文件结构
.
├── Chart.yaml
├── ci
│ └── values-with-ingress-metrics-and-serverblock.yaml
├── README.md
├── templates
│ ├── deployment.yaml
│ ├── _helpers.tpl
│ ├── ingress.yaml
│ ├── NOTES.txt
│ ├── server-block-configmap.yaml
│ ├── servicemonitor.yaml
│ ├── svc.yaml
│ └── tls-secrets.yaml
├── values.schema.json
└── values.yaml
每一处改动都是踩过的坑
# 修改类型为 NodePort
sed -i 's/type: LoadBalancer/type: NodePort/g' nginx/values.yaml
# 由于拉镜像不容易,所以把 Nginx 的镜像改成 daocloud.io 的
sed -i 's/registry: docker.io/registry: daocloud.io/g' nginx/values.yaml
sed -i 's/repository: bitnami\/nginx/repository: nginx/g' nginx/values.yaml
sed -i 's/tag: 1.16.1-debian-10-r0/tag: latest/g' nginx/values.yaml
# 配上 limits 和 requests
sed -i 's/limits: {}/limits:/g' nginx/values.yaml
sed -i 's/requests: {}/requests:/g' nginx/values.yaml
sed -i 's/# cpu:.*/ cpu: 100m/g' nginx/values.yaml
sed -i 's/# memory:.*/ memory: 128Mi/g' nginx/values.yaml
# 这个 chart 模板里的 Nginx 是 8080 端口,修改成 80 端口
sed -i 's/containerPort: 8080/containerPort: 80/g' nginx/templates/deployment.yaml
尝试部署本地修改过的 chart, helm install <应用名称> <chart路径>
helm install my-chart-nginx ./nginx
NAME: my-chart-nginx
LAST DEPLOYED: Fri Feb 14 14:12:47 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Get the NGINX URL:
export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services my-chart-nginx)
export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
echo "NGINX URL: http://$NODE_IP:$NODE_PORT/"
稍作等待, POD 正常启动了
kubectl get po
NAME READY STATUS RESTARTS AGE
my-chart-nginx-75f9ddc7b5-d9csc 1/1 Running 0 13s
查看一下服务
kubectl get svc my-chart-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-chart-nginx NodePort 10.96.1.83 <none> 80:30203/TCP,443:32406/TCP 1m
尝试访问集群主机 IP + NodePort, Nginx 欢迎页呈现在眼前。
curl 127.0.0.1:30203
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Helm 私有仓库
实验室环境中制作了一些 chart ,集中存在在 helm 私有仓库中,使用起来就会很方便,安装一个 helm 仓库其实也很简单,首先准备一个装有 helm 的 nginx 文件服务器,然后在服务器上做一些操作:
# 创建一个用作管理 chart 的目录
mkdir mychart
# 存一些 chart 进来,比如我直接传了一个 chart 包
mychart/
└── my-test-0.1.0.tgz
# 为 helm 仓库建立索引
helm repo index mychart
# 多了一个 index.yaml
mychart/
├── index.yaml
└── my-test-0.1.0.tgz
尝试一下我这个私有仓库
# 在集群上尝试添加私有仓库
helm repo add mychart http://192.168.111.111/dcs/mychart
"mychart" has been added to your repositories
# 查一下仓库里的 chart 包,是刚刚在仓库机器上创建的 chart 包
helm search repo mychart/
NAME CHART VERSION APP VERSION DESCRIPTION
mychart/my-test 0.1.0 1.16.0 A Helm chart for Kubernetes