ljzsdut
GitHubToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

00 Helm2基础使用

helm简介

类似于软件包安装使用的yum。helm是提供资源的配置清单文件集合的仓库。

核心术语:

  • Chart:一个helm程序包;
  • Repository:Charts仓库,https/http服务器;
  • Release:特定的Chart部署于目标集群上的一个实例;

Chart -> Config -> Release

程序架构:

  • helm:客户端,管理本地的Chart仓库,管理Chart, 与Tiller服务器交互,发送Chart,实现实例安装、查询、卸载等操作
  • Tiller:服务端,接收helm发来的Charts与Config,合并生成relase并进行部署;

安装Helm v2服务端Tiller:

  • 到github的release中下载编译好的helm二进制包:https://github.com/helm/helm/releases
  • 使用helm init安装Tiller,helm init时使用k8s的config文件作为配置文件连接apiserver:将~/.kube/config拷贝到helm所在主机的~/.kube/config,也可以使用–kubeconfig参数指定config文件的位置。此时helm便可以工作了
  • 如果k8s集群启用了rbac,Tiller服务器需要能获取到整个集群的管理权限来完成k8s集群的应用安装、卸载等管理操作,需要先创建基于rbac的ServiceAccount(名称为tiller):
apiVersion: v1
kind: ServiceAccount
metadata:
  name: tiller
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: tiller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: tiller
    namespace: kube-system
  • 初始化:在k8s集群上创建Tiller:

helm init使用参数:

安装指定Tiller的image:--tiller-image 
指定Tiller安装在哪一个Kubernetes集群:--kube-context 
指定Tiller安装在哪个namespace:--tiller-namespace ,默认为kube-system
[root@physerver src]# helm init --service-account tiller
Creating /root/.helm 
Creating /root/.helm/repository 
Creating /root/.helm/repository/cache 
Creating /root/.helm/repository/local 
Creating /root/.helm/plugins 
Creating /root/.helm/starters 
Creating /root/.helm/cache/archive 
Creating /root/.helm/repository/repositories.yaml 
Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com 
Adding local repo with URL: http://127.0.0.1:8879/charts 
$HELM_HOME has been configured at /root/.helm.

Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.

Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.
To prevent this, run `helm init` with the --tiller-tls-verify flag.
For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation
Happy Helming!

#验证Tiller是否安装成功
[root@physerver src]#  kubectl -n kube-system get pods|grep tiller
tiller-deploy-56c4cf647b-5jr2m         0/1       ImagePullBackOff   0          2m
#我们发现上面的命令执行失败,由于 Helm 默认会去 storage.googleapis.com 拉取镜像,如果你当前执行的机器不能访问该域名的话可以使用阿里云的镜像,使用如下命令镜像Tiller更新(注意修改Tiller版本号与helm版本号一致),--upgrade表示如果Tiller已经安装就进行更新操作:

[root@physerver src]# helm init --service-account tiller --upgrade --tiller-image registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.10.0 --stable-repo-url https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts

[root@physerver src]# kubectl -n kube-system get pods|grep tiller
tiller-deploy-56dd949bd5-m9jgh         1/1       Running   0          16s

如果上面的命令没有使用–service-account tiller参数,可以给deployment进行打补丁:

kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}' 

查看是否授权成功

$ kubectl get deploy --namespace kube-system   tiller-deploy  --output yaml|grep  serviceAccount
serviceAccount: tiller
serviceAccountName: tiller

卸载Helm v2服务器端 Tiller

如果你需要在 Kubernetes 中卸载已部署的 Tiller,可使用以下命令完成卸载。

[root@physerver src]# helm reset

helm使用

下面我们通过一个完整的示例来学习如何使用 Helm 创建、打包、分发、安装、升级及回退Kubernetes应用。

1、自定义Chart

创建一个名为 mychart 的 Chart

[root@k8smaster ~]# helm create mychart
Creating mychart

该命令创建了一个 mychart 目录,该目录结构如下所示。这里我们主要关注目录中的 Chart.yaml、values.yaml、NOTES.txt 和 Templates 目录。

[root@k8smaster ~]# tree mychart/
mychart/
├── charts
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── ingress.yaml
│   ├── NOTES.txt
│   └── service.yaml
└── values.yaml

2 directories, 7 files
  • Chart.yaml 用于描述这个 Chart的相关元信息,包括名字、描述信息以及版本等。
  • values.yaml 用于存储 templates 目录中模板文件中用到变量的默认值。
  • NOTES.txt 用于介绍 Chart 部署后的一些信息,例如:如何使用这个 Chart、列出缺省的设置等。这些信息会在helm install和helm status中显示。
  • Templates 目录下是 YAML 文件的模板,该模板文件遵循 Go template 语法。

Templates 目录下 YAML 文件模板的值默认都是在 values.yaml 里定义的,比如在 deployment.yaml 中定义的容器镜像 image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 其中的 .Values.image.repository 的值就是在 values.yaml 里定义的 nginx,.Values.image.tag 的值就是 stable。

$ cat mychart/values.yaml|grep repository
repository: nginx

$ cat mychart/values.yaml|grep tag
tag: stable

以上两个变量值是在 create chart 的时候就自动生成的默认值,你可以根据实际情况进行修改。

如果你需要了解更多关于 Go 模板的相关信息,可以查看 Hugo 的一个关于 Go 模板 的介绍。

编写应用的介绍信息

打开 Chart.yaml, 填写你部署的应用的详细信息,以 mychart 为例:

[root@k8smaster ~]# cat mychart/Chart.yaml
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: mychart
version: 0.1.0

编写应用具体部署信息

编辑 values.yaml,它默认会在 Kubernetes 部署一个 Nginx。下面是 mychart 应用的 values.yaml 文件的内容:

$ cat mychart/values.yaml
[root@k8smaster ~]# cat mychart/values.yaml
# Default values for mychart.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 1

image:
  repository: nginx
  tag: stable
  pullPolicy: IfNotPresent

nameOverride: ""
fullnameOverride: ""

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: false
  annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  path: /
  hosts:
    - chart-example.local
  tls: []
  #  - secretName: chart-example-tls
  #    hosts:
  #      - chart-example.local

resources: {}
  # We usually recommend not to specify default resources and to leave this as a conscious
  # choice for the user. This also increases chances charts run on environments with little
  # resources, such as Minikube. If you do want to specify resources, uncomment the following
  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
  # limits:
  #  cpu: 100m
  #  memory: 128Mi
  # requests:
  #  cpu: 100m
  #  memory: 128Mi

nodeSelector: {}

tolerations: []

affinity: {}# Default values for mychart.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 1

image:
repository: nginx
tag: stable
pullPolicy: IfNotPresent

service:
type: ClusterIP
port: 80

ingress:
enabled: false
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
path: /
hosts:
- chart-example.local
tls: []
#  - secretName: chart-example-tls
#    hosts:
#      - chart-example.local

resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
#  cpu: 100m
#  memory: 128Mi
# requests:
#  cpu: 100m
#  memory: 128Mi

nodeSelector: {}

tolerations: []

affinity: {}

检查依赖和模板配置是否语法正确

[root@k8smaster ~]# helm lint mychart/
==> Linting mychart/
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, no failures

如果文件格式错误,可以根据提示进行修改。

2、将应用打包

[root@k8smaster ~]# helm package mychart
Successfully packaged chart and saved it to: /root/mychart-0.1.0.tgz

mychart 目录会被打包为一个 mychart-0.1.0.tgz 格式的压缩包,该压缩包会被放到当前目录下,并同时被保存到了 Helm 的本地缺省仓库仓库目录$HOME/.helm/repository/local中,如果不想同时保存到此目录中,可以使用指定--save=false参数。

如果你想看到更详细的输出,可以加上 --debug 参数来查看打包的输出,输出内容应该类似如下:

$ helm package mychart --debug
Successfully packaged chart and saved it to: /home/k8s/mychart-0.1.0.tgz
[debug] Successfully saved /home/k8s/mychart-0.1.0.tgz to /home/k8s/.helm/repository/local

3、将应用发布到Repository

方法1:使用默认目录$HOME/.helm/repository/local作为仓库目录

我们在打包chart时,默认会拷贝一份chart压缩包拷贝到默认的$HOME/.helm/repository/local目录中,该仓库是执行 helm init 命令后默认会配置一个名为 local 的本地仓库,它只监听在127.0.0.1:8879,所以只能在本机适用,无法让其他机器来获取仓库中的chart。

[root@k8smaster ~]# helm search mychart
NAME            CHART VERSION   APP VERSION     DESCRIPTION                
local/mychart   0.1.0           1.0             A Helm chart for Kubernetes

如果想让其他机器也可以使用这个仓库,我们可以在本地启动一个 Repository Server,并将其加入到 Helm Repo 列表中。Helm Repository 必须以 Web 服务的方式提供,这里我们就使用 helm serve 命令启动一个 Repository Server(也可以使用其他http服务,如nignx),该 Server 缺省使用 $HOME/.helm/repository/local目录作为 Chart 存储,并在 8879 端口上提供服务。一个chart仓库由一系列chart压缩包与index.yaml文件组成,index.yaml记录了chart仓库中全部chart的索引信息,index.yaml信息可以使用helm repo index /path/to/repo。

[root@k8smaster ~]# helm serve --address 192.168.5.36:8879 &
Regenerating index. This may take a moment.
Now serving you on 192.168.5.36:8879
[root@k8smaster ~]# helm repo add local-repo http://192.168.5.36:8879
"local-repo" has been added to your repositories
[root@k8smaster ~]# helm repo list
NAME            URL                                                   
stable          https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
local           http://127.0.0.1:8879/charts                          
local-repo      http://192.168.5.36:8879 
[root@k8smaster ~]# helm search mychart 
NAME                    CHART VERSION   APP VERSION     DESCRIPTION                
local-repo/mychart      0.1.0           1.0             A Helm chart for Kubernetes
local/mychart           0.1.0           1.0             A Helm chart for Kubernetes

如何在其他机器上使用这个仓库:

[root@physerver manifests]# helm repo add local-repo http://192.168.5.36:8879
"local-repo" has been added to your repositories
[root@physerver manifests]# helm repo list 
NAME            URL                                             
stable          https://kubernetes-charts.storage.googleapis.com
local-repo      http://192.168.5.36:8879                        
[root@physerver manifests]# helm search mychart
NAME                    CHART VERSION   APP VERSION     DESCRIPTION                
local-repo/mychart      0.1.0           1.0             A Helm chart for Kubernetes

指定仓库目录:

如果你想使用指定目录来做为 Helm Repository 的存储目录,可以helm serve加上 --repo-path参数,还可以使用–url指定外部访问地址:

[root@k8smaster ~]# mkdir -pv /data/helm/repository/ 
mkdir: 已创建目录 "/data"
mkdir: 已创建目录 "/data/helm"
mkdir: 已创建目录 "/data/helm/repository/"
[root@k8smaster ~]# helm serve --address 0.0.0.0:8879 --repo-path /data/helm/repository/ --url http://192.168.5.36:8879/charts/ &       
Regenerating index. This may take a moment.
Now serving you on 0.0.0.0:8879
[root@k8smaster ~]# helm repo add local-1 http://192.168.5.36:8879/charts/
"local-1" has been added to your repositories
[root@k8smaster ~]# helm repo list
NAME    URL                                                   
stable  https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
local   http://127.0.0.1:8879/charts                          
local-1 http://192.168.5.36:8879/charts/
[root@k8smaster ~]# tree /data/helm/repository/
/data/helm/repository/
└── index.yaml

0 directories, 1 file
[root@k8smaster ~]# cat /data/helm/repository/index.yaml   
apiVersion: v1
entries: {}
generated: 2018-11-07T15:38:54.93430747+08:00

我们发现仓库目录下没有任何chart,而且index.yaml文件没有任何信息,我们现在手动拷贝一个chart压缩包到该目录下,然后通过 helm repo index 命令将 Chart 的 Metadata 记录更新在 index.yaml 文件中:

[root@k8smaster ~]# cp mychart-0.1.0.tgz /data/helm/repository/
[root@k8smaster ~]# helm repo index /data/helm/repository/
[root@k8smaster ~]# cat /data/helm/repository/index.yaml 
apiVersion: v1
entries:
  mychart:
  - apiVersion: v1
    appVersion: "1.0"
    created: 2018-11-07T15:47:11.393463841+08:00
    description: A Helm chart for Kubernetes
    digest: fa2b5d397c2cf666e5edb5a907ba56aaf519d183ccb249bfa02a071f51f0278b
    name: mychart
    urls:
    - mychart-0.1.0.tgz
    version: 0.1.0
generated: 2018-11-07T15:47:11.391984743+08:00
#索引信息已经跟新了
[root@k8smaster ~]# helm search mychart
NAME            CHART VERSION   APP VERSION     DESCRIPTION                
local/mychart   0.1.0           1.0             A Helm chart for Kubernetes
[root@k8smaster ~]# helm repo update  #更新仓库信息,再次查找mychart包
Hang tight while we grab the latest from your chart repositories...
...Skip local chart repository
...Successfully got an update from the "local-1" chart repository
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈ Happy Helming!⎈ 
[root@k8smaster ~]# helm search mychart
NAME            CHART VERSION   APP VERSION     DESCRIPTION                
local-1/mychart 0.1.0           1.0             A Helm chart for Kubernetes
local/mychart   0.1.0           1.0             A Helm chart for Kubernetes

上面我们向repo中增加软件包使用的是直接拷贝chart压缩包到仓库目录中,也可以拷贝chart目录到仓库目录,然后使用helm package进行打包,然后再更新index.yaml文件。

4、在 Kubernetes 中部署应用

~部署一个应用

Chart 被发布到仓储后,就可以通过 helm install 命令部署该 Chart。

  • 检查配置和模板是否有效

当使用 helm install 命令部署应用时,实际上就是将 templates 目录下的模板文件渲染成 Kubernetes 能够识别的 YAML 格式。

在部署前我们可以使用 helm install --name <release_name> --dry-run --debug <chart_name|chart_dir>命令来验证 Chart 的配置。该输出中包含了模板的变量配置与最终渲染的 YAML 文件。

[root@k8smaster ~]# helm install --name mike-test --dry-run --debug  local/mychart
[debug] Created tunnel using local port: '45676'

[debug] SERVER: "127.0.0.1:45676"

[debug] Original chart version: ""
[debug] Fetched local/mychart to /root/.helm/cache/archive/mychart-0.1.0.tgz

[debug] CHART PATH: /root/.helm/cache/archive/mychart-0.1.0.tgz

NAME:   mike-test
REVISION: 1
RELEASED: Wed Nov  7 16:10:14 2018
CHART: mychart-0.1.0
USER-SUPPLIED VALUES:
{}

COMPUTED VALUES:
affinity: {}
fullnameOverride: ""
image:
  pullPolicy: IfNotPresent
  repository: nginx
  tag: stable
ingress:
  annotations: {}
  enabled: false
  hosts:
  - chart-example.local
  path: /
  tls: []
nameOverride: ""
nodeSelector: {}
replicaCount: 1
resources: {}
service:
  port: 80
  type: ClusterIP
tolerations: []

HOOKS:
MANIFEST:

---
# Source: mychart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: mike-test-mychart
  labels:
    app: mychart
    chart: mychart-0.1.0
    release: mike-test
    heritage: Tiller
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app: mychart
    release: mike-test
---
# Source: mychart/templates/deployment.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: mike-test-mychart
  labels:
    app: mychart
    chart: mychart-0.1.0
    release: mike-test
    heritage: Tiller
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mychart
      release: mike-test
  template:
    metadata:
      labels:
        app: mychart
        release: mike-test
    spec:
      containers:
        - name: mychart
          image: "nginx:stable"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            {}

验证完成没有问题后,我们就可以使用以下命令将其部署到 Kubernetes 上了。

# 部署时需指定 Chart 名及 Release(部署的实例)名。
$ helm install local/mychart --name mike-test
NAME:   mike-test
LAST DEPLOYED: Mon Jul 23 10:41:20 2018
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Service
NAME               TYPE       CLUSTER-IP      EXTERNAL-IP  PORT(S)  AGE
mike-test-mychart  ClusterIP  10.254.120.177  <none>       80/TCP   1s

==> v1beta2/Deployment
NAME               DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
mike-test-mychart  1        0        0           0          0s

==> v1/Pod(related)
NAME                                READY  STATUS   RESTARTS  AGE
mike-test-mychart-6d56f8c8c9-d685v  0/1    Pending  0         0s

NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app=mychart,release=mike-test" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80

注:helm install 默认会用到 socat,需要在所有节点上安装 socat 软件包。

完成部署后,现在 Nginx 就已经部署到 Kubernetes 集群上。在本地主机上执行提示中的命令后,就可在本机访问到该 Nginx 实例。

$ export POD_NAME=$(kubectl get pods --namespace default -l "app=mychart,release=mike-test" -o jsonpath="{.items[0].metadata.name}")
$ echo "Visit http://127.0.0.1:8080 to use your application"
$ kubectl port-forward $POD_NAME 8080:80

在本地访问 Nginx

$ curl http://127.0.0.1:8080
.....
<title>Welcome to nginx!</title>
<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>
......

使用下面的命令列出的所有已部署的 Release 以及其对应的 Chart。

$ helm list
NAME      REVISION  UPDATED                   STATUS    CHART         NAMESPACE
mike-test 1         Mon Jul 23 10:41:20 2018  DEPLOYED  mychart-0.1.0 default

你还可以使用 helm status 查询一个特定的 Release 的状态。

$ helm status mike-test
LAST DEPLOYED: Mon Jul 23 10:41:20 2018
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Pod(related)
NAME                                READY  STATUS   RESTARTS  AGE
mike-test-mychart-6d56f8c8c9-d685v  1/1    Running  0         1m

==> v1/Service
NAME               TYPE       CLUSTER-IP      EXTERNAL-IP  PORT(S)  AGE
mike-test-mychart  ClusterIP  10.254.120.177  <none>       80/TCP   1m

==> v1beta2/Deployment
NAME               DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
mike-test-mychart  1        1        1           1          1m

NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app=mychart,release=mike-test" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80

~升级和回退一个应用

从上面 helm list 输出的结果中我们可以看到有一个 Revision(更改历史)字段,该字段用于表示某一个 Release 被更新的次数,我们可以用该特性对已部署的 Release 进行回滚。

  • 修改 Chart.yaml 文件

将版本号从 0.1.0 修改为 0.2.0, 然后使用 helm package 命令打包并发布到本地仓库。

$ cat mychart/Chart.yaml
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: mychart
version: 0.2.0

$ helm package mychart
Successfully packaged chart and saved it to: /home/k8s/mychart-0.2.0.tgz
  • 查询本地仓库中的 Chart 信息

我们可以看到在本地仓库中 mychart 有两个版本。

$ helm search mychart -l
NAME          CHART VERSION APP VERSION DESCRIPTION
local/mychart 0.2.0         1.0         A Helm chart for Kubernetes
local/mychart 0.1.0         1.0         A Helm chart for Kubernetes
  • 升级一个应用

现在用 helm upgrade 命令将已部署的 mike-test 升级到新版本。你可以通过 --version 参数指定需要升级的版本号,如果没有指定版本号,则缺省使用最新版本。

$ helm upgrade mike-test local/mychart
Release "mike-test" has been upgraded. Happy Helming!
LAST DEPLOYED: Mon Jul 23 10:50:25 2018
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Pod(related)
NAME                                READY  STATUS   RESTARTS  AGE
mike-test-mychart-6d56f8c8c9-d685v  1/1    Running  0         9m

==> v1/Service
NAME               TYPE       CLUSTER-IP      EXTERNAL-IP  PORT(S)  AGE
mike-test-mychart  ClusterIP  10.254.120.177  <none>       80/TCP   9m

==> v1beta2/Deployment
NAME               DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
mike-test-mychart  1        1        1           1          9m

NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app=mychart,release=mike-test" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80

完成后,可以看到已部署的 mike-test 被升级到 0.2.0 版本。

$ helm list
NAME      REVISION  UPDATED                   STATUS    CHART         NAMESPACE
mike-test 2         Mon Jul 23 10:50:25 2018  DEPLOYED  mychart-0.2.0 default
  • 回退一个应用

如果更新后的程序由于某些原因运行有问题,需要回退到旧版本的应用。首先我们可以使用 helm history 命令查看一个 Release 的所有变更记录。

$ helm history mike-test
REVISION  UPDATED                   STATUS      CHART         DESCRIPTION
1         Mon Jul 23 10:41:20 2018  SUPERSEDED  mychart-0.1.0 Install complete
2         Mon Jul 23 10:50:25 2018  DEPLOYED    mychart-0.2.0 Upgrade complete

其次,我们可以使用下面的命令对指定的应用进行回退。

$ helm rollback mike-test 1
Rollback was a success! Happy Helming!

注:其中的参数 1 是 helm history 查看到 Release 的历史记录中 REVISION 对应的值。

最后,我们使用 helm listhelm history 命令都可以看到 mychart 的版本已经回退到 0.1.0 版本。

$ helm list
NAME      REVISION  UPDATED                   STATUS    CHART         NAMESPACE
mike-test 3         Mon Jul 23 10:53:42 2018  DEPLOYED  mychart-0.1.0 default

$ helm history mike-test
REVISION  UPDATED                   STATUS      CHART         DESCRIPTION
1         Mon Jul 23 10:41:20 2018  SUPERSEDED  mychart-0.1.0 Install complete
2         Mon Jul 23 10:50:25 2018  SUPERSEDED  mychart-0.2.0 Upgrade complete
3         Mon Jul 23 10:53:42 2018  DEPLOYED    mychart-0.1.0 Rollback to 1

~删除一个应用

如果需要删除一个已部署的 Release,可以利用 helm delete 命令来完成删除。

$ helm delete mike-test
release "mike-test" deleted

确认应用是否删除,该应用已被标记为 DELETED 状态。

$ helm ls -a mike-test
NAME      REVISION  UPDATED                   STATUS  CHART         NAMESPACE
mike-test 3         Mon Jul 23 10:53:42 2018  DELETED mychart-0.1.0 default

也可以使用 --deleted 参数来列出已经删除的 Release

$ helm ls --deleted
NAME      REVISION  UPDATED                   STATUS  CHART         NAMESPACE
mike-test 3         Mon Jul 23 10:53:42 2018  DELETED mychart-0.1.0 default

从上面的结果也可以看出,默认情况下已经删除的 Release 只是将状态标识为 DELETED 了 ,但该 Release 的历史信息还是继续被保存的。

$ helm hist mike-test
REVISION  UPDATED                   STATUS      CHART         DESCRIPTION
1         Mon Jul 23 10:41:20 2018  SUPERSEDED  mychart-0.1.0 Install complete
2         Mon Jul 23 10:50:25 2018  SUPERSEDED  mychart-0.2.0 Upgrade complete
3         Mon Jul 23 10:53:42 2018  DELETED     mychart-0.1.0 Deletion complete

如果要移除指定 Release 所有相关的 Kubernetes 资源和 Release 的历史记录,可以用如下命令:

$ helm delete --purge mike-test
release "mike-test" deleted

再次查看已删除的 Release,已经无法找到相关信息。

$ helm hist mike-test
Error: release: "mike-test" not found

# helm ls 命令也已均无查询记录。
$ helm ls --deleted
$ helm ls -a mike-test

Helm 部署应用实例

部署 Wordpress

这里以一个典型的三层应用 Wordpress 为例,包括 MySQL、PHP 和 Apache。

由于测试环境没有可用的 PersistentVolume(持久卷,简称 PV),这里暂时将其关闭。关于 Persistent Volumes 的相关信息我们会在后续的相关文章进行讲解。

$ helm install --name wordpress-test --set "persistence.enabled=false,mariadb.persistence.enabled=false,serviceType=NodePort"  stable/wordpress

NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1beta1/Deployment
NAME                      DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
wordpress-test-mariadb    1        1        1           1          26m
wordpress-test-wordpress  1        1        1           1          26m

==> v1/Pod(related)
NAME                                       READY  STATUS   RESTARTS  AGE
wordpress-test-mariadb-84b866bf95-n26ff    1/1    Running  1         26m
wordpress-test-wordpress-5ff8c64b6c-sgtvv  1/1    Running  6         26m

==> v1/Secret
NAME                      TYPE    DATA  AGE
wordpress-test-mariadb    Opaque  2     26m
wordpress-test-wordpress  Opaque  2     26m

==> v1/ConfigMap
NAME                          DATA  AGE
wordpress-test-mariadb        1     26m
wordpress-test-mariadb-tests  1     26m

==> v1/Service
NAME                      TYPE       CLUSTER-IP     EXTERNAL-IP  PORT(S)                   AGE
wordpress-test-mariadb    ClusterIP  10.254.99.67   <none>       3306/TCP                  26m
wordpress-test-wordpress  NodePort   10.254.175.16  <none>       80:8563/TCP,443:8839/TCP  26m

NOTES:
1. Get the WordPress URL:

Or running:

export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services wordpress-test-wordpress)
export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT/admin

2. Login with the following credentials to see your blog

echo Username: user
echo Password: $(kubectl get secret --namespace default wordpress-test-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode)

访问 Wordpress

部署完成后,我们可以通过上面的提示信息生成相应的访问地址和用户名、密码等相关信息。

# 生成 Wordpress 管理后台地址
$ export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services wordpress-test-wordpress)
$ export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
$ echo http://$NODE_IP:$NODE_PORT/admin
http://192.168.5.36:8433/admin

# 生成 Wordpress 管理帐号和密码
$ echo Username: user
Username: user
$ echo Password: $(kubectl get secret --namespace default wordpress-test-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode)
Password: 9jEXJgnVAY

给一张访问效果图吧:

img

Helm 其它使用技巧

  • 如何设置 helm 命令自动补全?

为了方便 helm 命令的使用,Helm 提供了自动补全功能,如果使用 ZSH 请执行:

$ source <(helm completion zsh)

如果使用 BASH 请执行:

$ source <(helm completion bash)
  • 如何使用第三方的 Chart 存储库?

随着 Helm 越来越普及,除了使用预置官方存储库,三方仓库也越来越多了(前提是网络是可达的)。你可以使用如下命令格式添加三方 Chart 存储库。

$ helm repo add 存储库名 存储库URL
$ helm repo update

一些三方存储库资源:

# Prometheus Operator
https://github.com/coreos/prometheus-operator/tree/master/helm

# Bitnami Library for Kubernetes
https://github.com/bitnami/charts

# Openstack-Helm
https://github.com/att-comdev/openstack-helm
https://github.com/sapcc/openstack-helm

# Tick-Charts
https://github.com/jackzampolin/tick-charts
  • Helm 如何结合 CI/CD ?

采用 Helm 可以把零散的 Kubernetes 应用配置文件作为一个 Chart 管理,Chart 源码可以和源代码一起放到 Git 库中管理。通过把 Chart 参数化,可以在测试环境和生产环境采用不同的 Chart 参数配置。

下图是采用了 Helm 的一个 CI/CD 流程

7YXAfu-1623198192253

  • Helm 如何管理多环境下 (Test、Staging、Production) 的业务配置?

Chart 是支持参数替换的,可以把业务配置相关的参数设置为模板变量。使用 helm install 命令部署的时候指定一个参数值文件,这样就可以把业务参数从 Chart 中剥离了。例如: helm install --values=values-production.yaml wordpress

  • Helm 如何解决服务依赖?

在 Chart 里可以通过 requirements.yaml 声明对其它 Chart 的依赖关系。如下面声明表明 Chart 依赖 Apache 和 MySQL 这两个第三方 Chart。

dependencies:
- name: mariadb
version: 2.1.1
repository: https://kubernetes-charts.storage.googleapis.com/
condition: mariadb.enabled
tags:
- wordpress-database
- name: apache
version: 1.4.0
repository: https://kubernetes-charts.storage.googleapis.com/
  • 如何让 Helm 连接到指定 Kubernetes 集群?

Helm 默认使用和 kubectl 命令相同的配置访问 Kubernetes 集群,其配置默认在 ~/.kube/config 中。

  • 如何在部署时指定命名空间?

helm install 默认情况下是部署在 default 这个命名空间的。如果想部署到指定的命令空间,可以加上 --namespace 参数,比如:

$ helm install local/mychart --name mike-test --namespace mynamespace
  • 如何查看已部署应用的详细信息?
$ helm get wordpress-test

默认情况下会显示最新的版本的相关信息,如果想要查看指定发布版本的信息可加上 --revision 参数。

$ helm get  --revision 1  wordpress-test

常用命令:

helm repo list 查看可用仓库

helm create NAME 创建chart

helm lint NAME 对chart进行语法检查

help package NAME 将chart进行打包

helm serve [–address IP:PORT] :创建helm仓库,将当前目录设置为根目录???,然后监听在8879端口下。我们也可以使用nginx等http服务提供仓库。

helm search NAME 在仓库列表中的所有仓库中查找NAME

helm install –name RELEASE_NAME local/myapp

helm status RELEASE_NAME

helm delete –purge RELEASE_NAME

helm rollback RELEASE_NAME REVISION #REVISION可以通过helm list|history查看。

实战:helm安装harbor

部署helm

helm

helm-ingress

helm本地仓库

https://hub.helm.sh/

git clone https://github.com/helm/charts.git