Kuberneters-HelmV3.3.1入门介绍及实践

微信扫一扫,分享到朋友圈

Kuberneters-HelmV3.3.1入门介绍及实践

一、为什么需要Helm

Kubernetes目前已成为容器编排的事实标准,随着传统架构向微服务容器化架构的转变,从一个巨大的单体的应用切分为多个微服务,每个微服务可独立部署和扩展,实现了敏捷开发和快速部署,但是由于从大一个应用变成了多个微服务,导致服务数大幅增加,对于Kubernetes来说,针对每个服务需要部署如deployment、statufulset、service、pod 等资源文件,而对于一个复杂的应用来说,可能会有很多类似上面的资源文件,其中还有更新或回滚的需求,若要执行,需要修改和维护相关的大量资源文件,这时候,如何针对每个服务涉及到资源集合到 一个整体
来实现部署、升级和回滚是亟待需要解决的难题,Helm就是在这个背景下诞生的。

二、Helm的简介和使用场景

那么Helm是如何解决上述难题的呢?它其实是将Kubernetes资源(如deployment、statufulset、service、pod) 打包到一个chart中,而chart被打包并推送保存到chart仓库(repo),然后通过chart仓库用来存储和分享chart包。Helm可直接拉取并安装chart包,生成helm维度整体的应用,其应用会包含如deployment、statufulset、service、pod的资源, 并支持以一个整体Helm应用的维度来进行版本控制、打包、发布、删除、更新等操作
。针对用户来说主要适用如下场景:

1、将常用搭配、标准化的多个资源文件放在同一个chart包中,方便统一的版本控制、安装、部署、升级、回滚和删除

2、可以大大简化了使用Kubernetes部署的难度,降低了用户使用门槛,只需配置参数即可一键部署

三、Helm实践

本次演示Helm的版本号如下:

[root@k8s-master my-second-helm]# helm version
version.BuildInfo{Version:"v3.3.1", GitCommit:"249e5215cde0c3fa72e27eb7a30e8d55c9696144", GitTreeState:"clean", GoVersion:"go1.14.7"}

1、安装

1)制作chart包的形式

Helm 应用的安装既可以从远程的repo进行拉取chart包进行安装,repo中提供了很多官方的chart包,若无个性化的需求,可以类似公开镜像一样进行拉取并安装,若需要单独调整,可以在已有的chart包进行更新再次打包,然后拉取更新后的chart包进行安装,接下来先来实践下后者,我们先新建一个helm的目录,然后在此目录下执行如下命令:

[root@k8s-master helm]# helm create my-second-helm
Creating my-second-helm
[root@k8s-master helm]# ls
my-first-helm  my-second-helm
[root@k8s-master helm]# cd my-second-helm/
[root@k8s-master my-second-helm]# ls
charts  Chart.yaml  templates  values.yaml
[root@k8s-master helm]# tree my-second-helm
my-second-helm
├── charts
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── NOTES.txt
│   ├── serviceaccount.yaml
│   ├── service.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml
3 directories, 10 files

我们在前面的操作中只是指定了这个文件夹的名字my-second-helm,但是在这个文件下默认创建了多个目录和文件,接下里我们一起看下默认的文件中都包含哪些内容,各自充当什么作用,先一起看下Chart.yaml这个文件

[root@k8s-master my-second-helm]# cat Chart.yaml
apiVersion: v2
name: my-second-helm
description: A Helm chart for Kubernetes
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
appVersion: 1.16.0

可以看到 Chart.yaml
这个文件主要是用来对chart进行的描述,声明了当前 Chart 的名称、版本等基本信息,如果我们自己制作的chart有相关的描述都可以写入到文件,这些信息会在该 Chart 被放入仓库后,供用户浏览检索,方便用户了解这个chart。

templates
这个目录下,我们看到了大家比较熟悉的资源,我们看下deployment.yaml的构成

[root@k8s-master templates]# cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-second-helm.fullname" . }}
labels:
{{- include "my-second-helm.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "my-second-helm.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "my-second-helm.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "my-second-helm.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

细心的读者可能发现了,这个kind为deployment的资源与我们平常自己写的有些出入,主要是出现了很多类似{}的内容,如:replicas: {{ .Values.replicaCount }},平常我们是用replicas: 数字的形式,而这里已经换成了变量,而整个文件出现了很多类似的变量,想必读者也猜到了原来Helm是通过设置变量来统一管理很多需要输入的值,若有多个文件引用同一个变量,就再也不用同时修改多个文件了,细心的读者可能会发现,即便对K8s不太了解的用户,也可以仅设置变量的值也可以轻松部署应用,岂不可以大大降低部署的难度,确实如此,这就是helm的一个主要的特点,让部署变的简单,特别是常用的标准的配置我们可将其制作成chart 一键部署,
让我们再回到replicas: {{ .Values.replicaCount }}这个变量上,既然存在变量,那变量的设值在哪里呢? 我们可以看到变量的组成中存在Values,而和我们templates同级别的目录选还存在一个很重要的文件 values.yaml,
我们看下这个文件里面的内容:

[root@k8s-master my-second-helm]# cat values.yaml
# Default values for my-second-helm.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: nginx
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
#   drop:
#   - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
ingress:
enabled: false
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: chart-example.local
paths: []
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
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}

可以看到这个文件包含的是整个chart中各个资源下变量的值,如replicaCount: 1,前面replicas: {{ .Values.replicaCount }},因此上面的deployment的replicas为1,其他变量的值类似,其中{}表示未指定,用户可根据需要进行自定义。

接下来我们通过vim 修改下value.yaml文件中replicaCount: 2内容然后进行安装部署,但是安装部署之前需要先打包,我们在上面的操作都是针对目录和文件的,helm只能针对包进行安装,因此我们需先打包,打包之前,最好先验证下我们之前在各个文件输入的值是否合法,可以通过操作进行校验

[root@k8s-master my-second-helm]# helm lint --strict my-second-helm
==> Linting my-second-helm
Error unable to check Chart.yaml file in chart: stat my-second-helm/Chart.yaml: no such file or directory
Error: 1 chart(s) linted, 1 chart(s) failed
[root@k8s-master my-second-helm]# cd ..
[root@k8s-master helm]# ls
my-first-helm  my-second-helm
[root@k8s-master helm]# helm lint --strict my-second-helm
==> Linting my-second-helm
[INFO] Chart.yaml: icon is recommended
1 chart(s) linted, 0 chart(s) failed

可以看到在进行校验的时候,需要回到chart的根目录,0 chart(s) failed显示这个chart的之前输入的value值应无问题,接下来可以执行打包操作了,如下所示,红色字体就是我们打包后的结果

[root@k8s-master helm]# helm package my-second-helm
Successfully packaged chart and saved it to: /home/James/zhanglei/helm/my-second-helm-0.1.0.tgz
[root@k8s-master helm]# ls
my-first-helm  my-second-helm  my-second-helm-0.1.0.tgz

这个就是我们所说的chart包,接下来终于可以执行安装的操作了

[root@k8s-master helm]# helm install my-second-helm-test my-second-helm-0.1.0.tgz
NAME: my-second-helm-test
LAST DEPLOYED: Sat Sep 12 21:48:18 2020
NAMESPACE: default
STATUS: deployed                # 状态
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=my-second-helm,app.kubernetes.io/instance=my-second-helm-test" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:80
[root@k8s-master helm]# helm list
NAME                   NAMESPACE    REVISION    UPDATED                                    STATUS    CHART                   APP VERSION
my-second-helm-test    default      1           2020-09-12 21:48:18.480694046 +0800 CST    deployed  my-second-helm-0.1.0    1.16.0

可以看到在install后面指定的就是部署名称,在helm list中可追溯到时通过哪个版本的chart包进行的安装,可以看到状态为deployed,我们之前设定了deployment的副本实例数为2,我们一起来验证下:

[root@k8s-master helm]# kubectl get pod -o wide |grep my-second-helm
my-second-helm-test-566f5d8757-x27zf        1/1     Running            0          5m25s   10.122.235.244   k8s-master   <none>           <none>
my-second-helm-test-566f5d8757-zdm47        1/1     Running            0          5m25s   10.122.235.247   k8s-master   <none>           <none>

可以看到2个Pod已经running了,我们测试这个nginx如下所示为正常了,也就是说我们通过helm install chart包的方式成功安装了NGINX的应用

[root@k8s-master helm]# curl 10.122.235.244:80
<!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>

至此,我们演示了通过在本地目录里面新建了一个默认的chart目录,然后对value中的值进行修改,最后的再次打包,然后安装的全过程,有读者不免发问了,这个过程太麻烦了,我只需要类型像公有镜像,并不想制作chart,是否可以远程直接拉取chart包安装?答案是:可以!接下来我将介绍第二种创建helm 应用的方式。

2)远程拉取chart包

但是在拉取公有的chart包之前,需要先配置好chart repo,如下所示是我已经配置好的chart repo,里面提供常用的chart包

[root@k8s-master my-first-helm]# helm repo list
NAME         URL
stable       http://mirror.azure.cn/kubernetes/charts
incubator    http://mirror.azure.cn/kubernetes/charts-incubator
svc-cat      http://mirror.azure.cn/kubernetes/svc-catalog-charts

我们在正式拉取chart包之前,很多时候想在对应的仓库中先查找下有想要的chart包,可以通过如下操作进行查看下,比如我想查看下有无nginx的chart

[root@k8s-master my-first-helm]# helm search repo nginx
NAME                           CHART VERSION    APP VERSION    DESCRIPTION
stable/nginx-ingress           1.41.3           v0.34.1        DEPRECATED! An nginx Ingress controller that us...
stable/nginx-ldapauth-proxy    0.1.4            1.13.5         nginx proxy with ldapauth
stable/nginx-lego              0.3.1                           Chart for nginx-ingress-controller and kube-lego
stable/gcloud-endpoints        0.1.2            1              DEPRECATED Develop, deploy, protect and monitor...

可以看到,通过search命令,可查询到仓库中已有的NGINX的chart包,其中stable是repo的类型,CHART VERSION:chart包的版本,APP VERSION:应用版本,DESCRIPTION:针对此chart包的描述,看到这里是不是有印象,这正式是我们在上文提到Chart.yaml文件里面的信息,接下来我们尝试直接从远程仓库进行拉取并完成安装的操作

[root@k8s-master helm]# helm install nginx-test stable/nginx-ingress
WARNING: This chart is deprecated
NAME: nginx-test
LAST DEPLOYED: Sat Sep 12 23:47:59 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
*******************************************************************************************************
* DEPRECATED, please use https://github.com/kubernetes/ingress-nginx/tree/master/charts/ingress-nginx *
*******************************************************************************************************
The nginx-ingress controller has been installed.
It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status by running 'kubectl --namespace default get services -o wide -w nginx-test-nginx-ingress-controller'
An example Ingress that makes use of the controller:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
name: example
namespace: foo
spec:
rules:
- host: www.example.com
http:
paths:
- backend:
serviceName: exampleService
servicePort: 80
path: /
# This section is only required if TLS is to be enabled for the Ingress
tls:
- hosts:
- www.example.com
secretName: example-tls
If TLS is enabled for the Ingress, a Secret containing the certificate and key must also be provided:
apiVersion: v1
kind: Secret
metadata:
name: example-tls
namespace: foo
data:
tls.crt: <base64 encoded cert>
tls.key: <base64 encoded key>
type: kubernetes.io/tls
[root@k8s-master helm]# helm list
NAME                   NAMESPACE    REVISION    UPDATED                                    STATUS    CHART                   APP VERSION
my-second-helm-test    default      1           2020-09-12 21:48:18.480694046 +0800 CST    deployed  my-second-helm-0.1.0    1.16.0
nginx-test             default      1           2020-09-12 23:47:59.084999904 +0800 CST    deployed  nginx-ingress-1.41.3    v0.34.1

可以看到helm应用已经部署成功其应用名称为nginx-test。

2、升级

1)通过修改文件内容升级

可以针对chart目录的文件内容更新后再进行升级,如vim values.yaml文件,我们将之前replicaCount的值设置为4

[root@k8s-master my-second-helm]# vim values.yaml
# Default values for my-second-helm.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 4
[root@k8s-master my-second-helm]# helm upgrade -f values.yaml my-second-helm-test ./
Release "my-second-helm-test" has been upgraded. Happy Helming!   # 显示升级成功
NAME: my-second-helm-test
LAST DEPLOYED: Sun Sep 13 10:41:27 2020
NAMESPACE: default
STATUS: deployed
REVISION: 5                # release的版本号为5
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=my-second-helm,app.kubernetes.io/instance=my-second-helm-test" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:80
[root@k8s-master my-second-helm]# kubectl get pod |grep my-second
my-second-helm-test-566f5d8757-8v8wc        1/1     Running   0          6m32s
my-second-helm-test-566f5d8757-kfh5s        1/1     Running   0          11h
my-second-helm-test-566f5d8757-s4286        1/1     Running   0          86s
my-second-helm-test-566f5d8757-t2hhx        1/1     Running   0          11h

如上看到4个pod实例已经正常Running了,升级成功。

2)通过–set参数升级

其格式为: helm upgrade -f 指定目录/指定文件 –set 指定文件参数=value  部署名称 chart目录

[root@k8s-master helm]# helm upgrade -f my-second-helm/values.yaml --set replicaCount=3 my-second-helm-test ./my-second-helm
Release "my-second-helm-test" has been upgraded. Happy Helming!
NAME: my-second-helm-test
LAST DEPLOYED: Sun Sep 13 11:08:30 2020
NAMESPACE: default
STATUS: deployed
REVISION: 6              #  版本6
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=my-second-helm,app.kubernetes.io/instance=my-second-helm-test" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:80
[root@k8s-master helm]# kubectl get pod | grep my-se
my-second-helm-test-566f5d8757-8v8wc        1/1     Running   0          32m
my-second-helm-test-566f5d8757-kfh5s        1/1     Running   0          12h
my-second-helm-test-566f5d8757-t2hhx        1/1     Running   0          12h

在上个版本5中我们在values.yaml修改replicaCount的值为4,版本6中通过–set的方式我们修改了replicaCount的值为3,这个是否会同步到values.yaml中呢?

[root@k8s-master my-second-helm]# cat values.yaml
# Default values for my-second-helm.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 4

通过查看,replicaCount的值任然是版本5的值,并未发生改变,也就是说通过–set的值并不会影响到chart目录下源文件的值,另外从这种方式的升级来看, 我们得知helm应用的升级是针对已经部署后的应用进行升级,并非针对chart版本的版本进行升级
,这些地方都需要注意下!

3、回滚

升级操作成功后,每升级一次版本都会加1,在上面的例子里版本号已经6了,若我们想回到版本5该如何进行操作呢?我们先看下整个release的部署历史:

[root@k8s-master helm]# helm history my-second-helm-test
REVISION    UPDATED                     STATUS        CHART                   APP VERSION    DESCRIPTION
1           Sat Sep 12 21:48:18 2020    superseded    my-second-helm-0.1.0    1.16.0         Install complete
2           Sun Sep 13 00:07:17 2020    superseded    my-second-helm-0.1.0    1.16.0         Upgrade complete
3           Sun Sep 13 10:30:36 2020    superseded    my-second-helm-0.1.0    1.16.0         Upgrade complete
4           Sun Sep 13 10:36:21 2020    superseded    my-second-helm-0.1.0    1.16.0         Upgrade complete
5           Sun Sep 13 10:41:27 2020    superseded    my-second-helm-0.1.0    1.16.0         Upgrade complete
6           Sun Sep 13 11:08:30 2020    deployed      my-second-helm-0.1.0    1.16.0         Upgrade complete

可以看到针对同一个release来说,最终生效的只有一个版本,其状态为:deployed,其他版本为superseded的状态,接下来我们将版本6回滚到版本5

[root@k8s-master my-second-helm]# helm rollback my-second-helm-test 5
Rollback was a success! Happy Helming!
[root@k8s-master my-second-helm]# kubectl get pod |grep my-second-test
[root@k8s-master my-second-helm]# kubectl get pod |grep my-second
my-second-helm-test-566f5d8757-8v8wc        1/1     Running   0          51m
my-second-helm-test-566f5d8757-kfh5s        1/1     Running   0          12h
my-second-helm-test-566f5d8757-njqbn        1/1     Running   0          61s
my-second-helm-test-566f5d8757-t2hhx        1/1     Running   0          12h

版本5:4个Pod,版本6:3个Pod,可以看到命令执行完成之后立马就回滚且生效了,而回滚的操作命令也很简单,其格式为: helm rollback 部署名称 版本号

4、删除

若想删除已经部署成功的helm应用该如何操作呢?helm应用的删除其chart下的资源如Pod是否会保留?我们带着这些问题实践下:

[root@k8s-master my-second-helm]# helm delete my-second-helm-test
release "my-second-helm-test" uninstalled
[root@k8s-master my-second-helm]# kubectl get all |grep my-second-helm
[root@k8s-master my-second-helm]#

删除的格式为: helm delete 部署名称
, 经验证,一旦删除helm的应用,其关联生成的所有资源会被全部删除掉,也就是说,helm提供给用户是一个集合了所需资源的整体应用,其新建和删除也都是以整体应用为维度。

四、总结

本文介绍了什么是Helm,在哪些场景下适用Helm,然后介绍了Helm应用的安装、部署、升级、回滚和删除等操作,Helm应用是一个资源的集合,以整体为用户提供服务,通过这个服务,可以大大简化用户部署的难度,另外还针对应用的版本进行了历史管理,升级和回滚的操作减少了用户自己重新部署和维护版本的成本,在产品设计中,我们可将整个部署helm的流程体现在UI化达到进一步降低部署应用的门槛, 校验chart》安装chart-》部署-》升级-》回滚-》删除
,设计的重点保证这个业务主流程信息可以清晰的传递给用户,针对重点的操作,需要在页面中重点凸显出来,且要方便用户实际进行操作。

作者简介:云计算容器\Docker\K8s\Serverless方向产品经理,学点技术,为更好地设计产品。

微信扫一扫,分享到朋友圈

Kuberneters-HelmV3.3.1入门介绍及实践

如何将tensorflow1.x代码改写为pytorch代码(以图注意力网络(GAT)为例)

上一篇

罗永浩怒斥手机圈 李楠附和:警惕口high键盘侠、行业专家kol

下一篇

你也可能喜欢

Kuberneters-HelmV3.3.1入门介绍及实践

长按储存图像,分享给朋友