0%

轻量级Kubernetes发行版k3s之Helm安装及应用部署

说明

helm介绍

Helm是Kubernetes生态系统中的一个软件包管理工具。

类似于Ubuntu下的ap-get或者CentOS下的yum,Helm是一个用于kubernetes的包管理器。

通过Helm可以对应用程序相关的Kubernetes资源文件进行打包,管理依赖及管理应用程序版本等功能。

helm组件
  • Helm: Kubernetes的应用打包工具,也是命令行工具客户端的名称
  • Tiller: Helm的服务端,部署在Kubernetes集群中,用于处理Helm的相关命令
  • Chart: Helm的打包格式,内部包含了一组相关的kubernetes资源
  • Release: 使用Helm install命令在Kubernetes集群中安装的Chart称为Release
  • Repoistory: Helm的软件仓库

helm客户端安装

helm使用的是和kubctl相同的配置文件,可以通过官方的说明了解:

Helm will figure out where to install Tiller by reading your Kubernetes configuration file (usually $HOME/.kube/config). This is the same file that kubectl uses.

在安装有kubectl的服务器上安装helm客户端或者将k3s的配置文件 /etc/rancher/k3s/k3s.yaml 拷贝到指定设备的 ~/.kube/config

如果是其他指定设备,需要修改配置文件 ~/.kube/config ,将其中的 https://localhost:6443 替换为k3s的master节点的IP,如 https://192.168.5.17:6443

执行如下命令,测试kubectl是否能正常管理k3s集群:

1
kubectl get nodes

Releases · helm/helm 下载 heml的客户端安装包,解压后将其中的 helm 程序移动到 /usr/local/bin 目录下。

helm客户端验证

可以通过如下命令来查看helm的信息:

1
2
3
➜ helm version
Client: &version.Version{SemVer:"v2.14.3", GitCommit:"0e7f3b6637f7af8fcfddb3d2941fcc7cbebb0085", GitTreeState:"clean"}
Error: could not find tiller

此处可能会报出 dial tcp [::1]:8080: connect: connection refused 的错误,解决方法见下面。

helm服务端安装

helm的服务端名为tiller,tiller需要部署在Kubernetes集群中并且需要设置相应的权限。

第一步:为Tiller创建一个Service Account:

1
kubectl -n kube-system create serviceaccount tiller

第二步:为Tiller赋予cluster-admin权限:

1
kubectl create clusterrolebinding tiller --clusterrole=cluster-admin --serviceaccount=kube-system:tiller

也可以直接创建下面的 tiller-rbac-config.yaml 文件来完成上面两步:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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

执行:

1
kubectl create -f tiller-rbac-config.yaml

安装Tiller:

1
helm init --service-account tiller

tiller的镜像默认会去 gcr.io 镜像仓库中获取,而该地址在国内是无法访问的。此时可以通过 --tiller-image 来指定国内的镜像仓库源:

1
2
helm init --service-account tiller \
--tiller-image registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:<tag>

详细的解决方法说明见下面。

验证Tiller

通过如下命令来验证helm服务端Tiller是否安装成功:

1
2
3
4
$ helm version

Client: &version.Version{SemVer:"v2.14.3", GitCommit:"0e7f3b6637f7af8fcfddb3d2941fcc7cbebb0085", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.14.3", GitCommit:"0e7f3b6637f7af8fcfddb3d2941fcc7cbebb0085", GitTreeState:"clean"}

如果同时显示出了helm的client和server的版本信息,则说明安装成功。

如果显示为 Error: could not find a ready tiller pod 则只需稍等一下,待tiller的Pod安装完成即可。

也可以通过 kubectl 命令来验证,执行如下命令:

1
$ kubectl get pods -n kube-system | grep tiller

如果看到一个前缀为 tiller-deploy 的Pod即说明Tiller安装成功了。

Tiller升级

通过如下命令来升级Tiller版本:

1
helm init --upgrade

Tiller卸载

由于Tiller的数据保存在ConfigMaps中,所以无需担心数据丢失的问题。卸载Tiller推荐的方式是执行如下命令:

1
2
3
kubectl delete deployment tiller-deploy --namespace kube-system

kubectl delete svc tiller-deploy --namespace kube-system

或者使用下面的命令:

1
helm reset

通过Helm Chart部署应用

这里,我通过一个简单的Chart来测试通过helm部署应用。

Chart

执行如下命令来创建一个chart:

1
➜ helm create hello-chart

查看该chart目录下的文件:

1
2
➜ ls hello-chart
charts Chart.yaml templates values.yaml

其中,Chart.yaml 文件用于描述这个chart,其中包括chart的名称、描述信息以及版本等:

1
2
3
4
5
6
➜ cat Chart.yaml
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: hello-chart
version: 0.1.0

values.yaml 用于存储templates目录中模板文件中用到的变量。模板文件就是Go模板,需要安装Go模板的规则来编写。

templates 目录下则是部署应用的相关模板文件。

部署

修改 values.yaml 文件中下面部分:

1
2
3
4
5
6
7
8
9
10
11
12
image:
repository: nginx
tag: stable
pullPolicy: IfNotPresent

imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""

service:
type: ClusterIP
port: 80

将其中的 image.tag 修改为 alpine ,将 service.type 修改为 NodePort 。即使用 nginx:alpine 镜像,并设置service类型为 NodePort,以便于访问。

修改完成后,在 hello-chart 目录同级,执行如下命令来部署helm:

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
➜ helm install ./hello-chart
NAME: truculent-wolverine
LAST DEPLOYED: Sun Sep 1 23:51:47 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
truculent-wolverine-hello-chart 0/1 0 0 0s

==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
truculent-wolverine-hello-chart-655545d645-72xg9 0/1 Pending 0 0s

==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
truculent-wolverine-hello-chart NodePort 10.43.199.183 <none> 80:31337/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 truculent-wolverine-hello-chart)
export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT

可以看到通过helm chart创建了一个随机名称的Release实例并输出了相关的 Deployment PodService 信息。而且可以看到相应的Service端口为 31337 。通过浏览器访问k3s主机IP及端口 http://192.168.5.17:31337/ 查看是否能正常访问。

此时,可以通过 helm list 命令查看安装的Release信息:

1
2
3
➜ helm list
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
truculent-wolverine 1 Sun Sep 1 23:51:47 2019 DEPLOYED hello-chart-0.1.0 1.0 default

如果需要删除Release,则可以通过指定Release的名称来实现:

1
2
➜ helm delete truculent-wolverine
release "truculent-wolverine" deleted

关于Helm的更多信息可以参照官方文档了解。

问题汇总

Install Tiller ImagePullBackOff

在执行 helm init --service-account tiller 命令时安装的Pod会一直卡在 ImagePullBackOff 阶段,这是因为Triller的镜像默认是从 gcr.io 镜像仓库中拉取的,而该镜像地址在国内是无法访问的。

1
2
3
4
5
6
7
8
9
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 68s default-scheduler Successfully assigned kube-system/tiller-deploy-7f4d76c4b6-xxlng to k3s-agent
Warning Failed 26s (x2 over 52s) kubelet, k3s-agent Failed to pull image "gcr.io/kubernetes-helm/tiller:v2.14.3": rpc error: code = Unknown desc = Error response from daemon: Get https://gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
Warning Failed 26s (x2 over 52s) kubelet, k3s-agent Error: ErrImagePull
Normal BackOff 14s (x2 over 52s) kubelet, k3s-agent Back-off pulling image "gcr.io/kubernetes-helm/tiller:v2.14.3"
Warning Failed 14s (x2 over 52s) kubelet, k3s-agent Error: ImagePullBackOff
Normal Pulling 0s (x3 over 67s) kubelet, k3s-agent Pulling image "gcr.io/kubernetes-helm/tiller:v2.14.3"

可以通过 --tiller-image 参数来指定安装的镜像仓库地址。

1
2
helm init --service-account tiller \
--tiller-image registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:<tag>

其中,Tiller 镜像版本与 helm 版本相同。

在执行该命令之前,可通过 kubectl delete deploy tiller-deploy -n kube-system 命令来删除上一步命令安装失败的Pod。


helm 报错 connection refused
1
2
3
➜ helm version
Client: &version.Version{SemVer:"v2.14.3", GitCommit:"0e7f3b6637f7af8fcfddb3d2941fcc7cbebb0085", GitTreeState:"clean"}
Error: Get http://localhost:8080/api/v1/namespaces/kube-system/pods?labelSelector=app%3Dhelm%2Cname%3Dtiller: dial tcp [::1]:8080: connect: connection refused

如果你直接在k3s的master节点上执行 helm version 命令的话,很容易会出现上面的错误信息。

这是因为helm默认会从 ~/.kube/config 中来载入kubernetes/k3s的集群信息,而k3s的默认配置文件是 /etc/rancher/k3s/k3s.yaml ,在k3s的master节点上的 ~/.kube 目录下并不存在一个 config 文件,也就导致了helm连接不上k3s集群,而获取不到集群的信息。

要解决这个问题,可以通过指定配置文件的方式,如下:

1
2
3
➜ KUBECONFIG=/etc/rancher/k3s/k3s.yaml helm version
Client: &version.Version{SemVer:"v2.14.3", GitCommit:"0e7f3b6637f7af8fcfddb3d2941fcc7cbebb0085", GitTreeState:"clean"}
Error: could not find tiller

即在 helm version 命令前指定k3s集群配置文件的地址 KUBECONFIG=/etc/rancher/k3s/k3s.yaml,这样就能正常执行了。

当然,如果觉得每条helm命令都加一个 KUBECONFIG 参数太麻烦,可以通过如下方式解决:

1
2
3
4
5
➜ export KUBECONFIG=/etc/rancher/k3s/k3s.yaml

➜ helm version
Client: &version.Version{SemVer:"v2.14.3", GitCommit:"0e7f3b6637f7af8fcfddb3d2941fcc7cbebb0085", GitTreeState:"clean"}
Error: could not find tiller

如果觉得这种方法也很麻烦,那么可以将k3s的配置文件复制一份到 ~/.kube/config 下:

1
cp /etc/rancher/k3s/k3s.yaml ~/.kube/config

相关参考

如有疑问或需要技术讨论,请留言或发邮件到 service@itfanr.cc