# Kubernetes Helm包管理工具

## 1 Helm介绍

官网：

```
https://v3.helm.sh/zh/docs/
```

Helm是kubernetes的包管理工具，相当于linux环境下的yum/apg-get命令。

Helm的首要目标一直是让 从零到 Kubernetes” 变得轻松。无论是 运维、 开发人员、经验丰富的 DevOps工程师，还是刚刚入门的学生， Helm 的 目标是让大家在两分钟内就可以在 Kubernetes 上安装应用程序。

Helm 可以解决的问题：运维人员写好资源文件模板交给 开发人员填 写 参数即可

Helm中的一些概念：

- helm：命令行客户端工具，主要用于 Kubernetes 应用 中的 chart 的创建、打包、发布和管理。
- Chart： helm 程序包 ，一系列用于描述 k8s 资源相关文件的集合 ，
  - 比方说我们部署nginx，需要deployment.yaml，需要service的yaml，这两个清单文件就是一个helm程序包，在k8s中把这些yaml清单文件叫做chart图表。
  - vlues.yaml文件为模板中的文件赋值，可以实现我们自定义安装
  - 如果是chart开发者需要自定义模板，如果是chart使用者只需要修改values.yaml即可
  - repository：存放chart图表的仓库，提供部署k8s应用程序需要的那些yaml清单文件
  - chart--->通过values.yaml这个文件赋值-->生成release实例
  - helm也是go语言开发的
- Release ：基于 Chart 的部署实体，一个 chart 被 Helm 运行后将会生成对应的一个 release ；将在k8s 中创建出真实运行的资源对象。

helm把 kubernetes 资源打包到一个 chart 中，制作并完成各个 chart 和 chart 本身依赖关系并利用chart 仓库实现对外分发，而 helm 还可通过 values.yaml 文件完成可配置的发布，如果 chart 版本更新了， helm 自动支持滚更更新机制，还可以一键回滚，但是不是适合在生产环境使用，除非具有定义自制chart 的能力 。

## 2 Helm V3版本变化

2019年 11 月 13 日， Helm 团队发布 Helmv3 的第一个稳定版本。

[![img](https://note-1308251438.cos.ap-guangzhou.myqcloud.com/typora/202211180227750.png)](https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/Work/image-20211109154031755.png)

该版本主要变化如下：

架构变化：

- Helm 服务端 Tiller 被 删除
- Release 名称可以在不同命名空间重用
- 支持将 Chart 推送至 Docker 镜像仓库中
- 使用 JSONSchema 验证 chartvalues

## 3 安装Helm V3

K8s版本支持的各个 helm 版本对照表：



```
https://helm.sh/zh/docs/topics/version_skew/
```

[![img](https://note-1308251438.cos.ap-guangzhou.myqcloud.com/typora/202211180227826.png)](https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/Work/image-20211109154138079.png)

 



```
# 下载软件包
wget https://get.helm.sh/helm-v3.6.3-linux-amd64.tar.gz

# 解压
tar zxvf helm-v3.6.3-linux-amd64.tar.gz && mv linux-amd64/helm /usr/local/bin/
```

[![img](https://note-1308251438.cos.ap-guangzhou.myqcloud.com/typora/202211180227925.png)](https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/Work/image-20211109154912102.png)

## 4 配置chart仓库

阿里云仓库

```
https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
```

官方仓库

```
https://hub.kubeapps.com/charts/incubator
```

微软仓库

```
http://mirror.azure.cn/kubernetes/charts/charts/
```

### 4.1 添加阿里云chart仓库

```
# 添加仓库
helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
```

[![img](https://note-1308251438.cos.ap-guangzhou.myqcloud.com/typora/202211180227741.png)](https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/Work/image-20211109155222167.png)



```
# 更新本地仓库
helm repo update
```

### 4.2 常用命令



```
# 添加chart仓库
helm repo add <chart-name> <chart-url>

# 查看chart仓库
helm repo list

# 删除chart仓库
helm repo remove <chart-name>

# 更新chart仓库
helm repo update

# 搜索chart仓库
helm search repo <chart-name>
```

## 5 基本使用

### 5.1 搜索和下载Chart

1）查看阿里云 chart 仓库中的 memcached



```
helm search repo aliyun | grep memcached 
```

[![img](https://note-1308251438.cos.ap-guangzhou.myqcloud.com/typora/202211180227631.png)](https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/Work/image-20211109160023348.png)

2）查看chart信息



```
helm show chart aliyun/memcached
```

[![img](https://note-1308251438.cos.ap-guangzhou.myqcloud.com/typora/202211180227892.png)](https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/Work/image-20211109160549529.png)

3）下载chart包到本地

```
helm pull aliyun/memcached
```

```
tar zxvf memcached-2.0.1.tgz && cd memcached
```

[![img](https://note-1308251438.cos.ap-guangzhou.myqcloud.com/typora/202211180227696.png)](https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/Work/image-20211109160736631.png)

- Chart.yaml: chart 的基本信息，包括版本名字之类
- templates:存放 k8s 的部署资源模板，通过渲染变量得到部署文件
- values.yaml：存放全局变量 templates 下的文件可以调用

[![img](https://note-1308251438.cos.ap-guangzhou.myqcloud.com/typora/202211180227440.png)](https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/Work/image-20211109160812443.png)

- _helpers.tpl：存放能够复用的模板
- NOTES.txt：为用户提供一个关于 chart 部署后使用说明的文件

### 5.2 部署chart

生成环境中不建议使用

1）修改 templates/statefulset.yaml api版本信息

[![img](https://note-1308251438.cos.ap-guangzhou.myqcloud.com/typora/202211180227495.png)](https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/Work/image-20211109163613710.png)

2）添加selector字段

```
  selector:
    matchLabels:
      app: {{ template "memcached.fullname" . }}
      chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
      release: "{{ .Release.Name }}"
      heritage: "{{ .Release.Service }}"
```

[![img](https://note-1308251438.cos.ap-guangzhou.myqcloud.com/typora/202211180227665.png)](https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/Work/image-20211109164101070.png)

3）删除affinity亲和性配置

[![img](https://note-1308251438.cos.ap-guangzhou.myqcloud.com/typora/202211180227675.png)](https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/Work/image-20211109163904613.png)

4）安装

```
helm install mamcached ./ 
```

[![img](https://note-1308251438.cos.ap-guangzhou.myqcloud.com/typora/202211180227900.png)](https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/Work/image-20211109164355513.png)

```
kubectl get pods,sts
```

[![img](https://note-1308251438.cos.ap-guangzhou.myqcloud.com/typora/202211180227451.png)](https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/Work/image-20211109164212703.png)

5）测试

```
# If you'd like to test your instance, forward the port locally:

export POD_NAME=$(kubectl get pods --namespace default -l "app=mamcached-memcached" -o jsonpath="{.items[0].metadata.name}")
  
kubectl port-forward $POD_NAME 11211

# In another tab, attempt to set a key:

echo -e 'set mykey 0 60 5\r\nhello\r' | nc localhost 11211
```

[![img](https://note-1308251438.cos.ap-guangzhou.myqcloud.com/typora/202211180227371.png)](https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/Work/image-20211109164658377.png)

### 5.3 release相关操作

1）查看release

```
helm list
```

[![img](https://note-1308251438.cos.ap-guangzhou.myqcloud.com/typora/202211180227472.png)](https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/Work/image-20211109164957095.png)

2）删除release

```
helm delete mamcached
```

## 6 自定义Chart模板

### 6.1 自定义一个Chart

```
helm create myapp
```

[![img](https://note-1308251438.cos.ap-guangzhou.myqcloud.com/typora/202211180227352.png)](https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/Work/image-20211109170018249.png)

```
├── charts 用于存放所依赖的子 chart
├── Chart.yaml 描述这个 Chart 的相关信息、包括名字、描述信息、版本等
├── templates 模板目录，保留创建 k 8s 的资源清单文件
│  │
│  ├── deployment.yaml deployment 资源的 go 模板文件
│  │
│  ├── _helpers.tpl # 模板助手文件，定义的值可在模板中使用
│  │
│  ├── hpa.yaml 水平 pod 自动扩缩容 go 模板文件
│  │
│  ├── ingress.yaml 七层代理 go 模板文件
│  │
│  ├── NOTES.txt
│  │
│  ├── serviceaccount.yaml
│  │
│  ├── service.yaml service 的 go 模板文件
│  │
│  └── tests
│     │
│     └── test connection.yaml
└──values.yaml 模板的值文件，这些值会在安装时应用到 GO 模板生成部署文件
```

### 6.2 Chart编写规则

```
apiVersion: v2
name: myapp
description: A Helm chart for Kubernetes
version: 0.0.1
appVersion: "latest"
type: application
maintainer:
- name: gudu
  wechat: gududexiaorenwu
appVersion: "1.16.0"
```

解释说明：Chart.yaml 文件主要用来描述对应 chart 的相关属性信息，其中 apiVersion 字段用于描述对应 chart 使用的 api 版本，默认是 v2 版本； name 字段用于描述对应 chart 的名称； description 字段用于描述对应 chart 的说明简介； type 字段用 户描述对应 chart 是应用程序还是库文件，应用程序类型的chart ，它可以运行为一个 release ，但库类型的 chart 不能运行为 release ，它只能作为依赖被application 类型的 chart 所使用； version 字段用于描述对应 chart 版本； appVersion 字段用于描述对应 chart 内部程序的版本信息；

### 6.3 GO模板文件渲染

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "myapp.fullname" . }}
  labels:
    {{- include "myapp.labels" . | nindent 4 }}
spec:
  {{- if not .Values.autoscaling.enabled }}
  replicas: {{ .Values.replicaCount }}
  {{- end }}
  selector:
    matchLabels:
      {{- include "myapp.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      {{- with .Values.podAnnotations }}
      annotations:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      labels:
        {{- include "myapp.selectorLabels" . | nindent 8 }}
    spec:
      {{- with .Values.imagePullSecrets }}
      imagePullSecrets:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      serviceAccountName: {{ include "myapp.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 }}
```

解释说明·：该部署清单模板文件，主要用 go 模板语言来写的，其中 {{ include "myapp.fullname" . 就表示取 myapp 的全名； ；{{ .Values.image.repository 这段代 码表示读取当前目录下的 values 文件中的image.repository 字段的值； ；{{ .Values.image.tag | default .Chart.AppVersion 表示对于 values文件中 image.tag 的值或者读取 default.chart 文件中的 AppVersion 字段的值；简单讲 go 模板就是应用对应 go 模板语法来定义关属性的的值；一般都是从 values.yaml 文件中加载对应字段的值作为模板文件相关属性的值 。

- nindent 4：表示首行缩进 4 个 字母
- TRUNC（NUMBER）表示截断数字

### 6.4 Values编写规则

```
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
  className: ""
  annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  hosts:
    - host: chart-example.local
      paths:
        - path: /
          pathType: ImplementationSpecific
  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: {}
```

### 6.5 部署release

```
helm install myapp .
```

[![img](https://note-1308251438.cos.ap-guangzhou.myqcloud.com/typora/202211180227887.png)](https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/Work/image-20211109171532982.png)

[![img](https://note-1308251438.cos.ap-guangzhou.myqcloud.com/typora/202211180227892.png)](https://cunqi0105-1300757323.cos.ap-shanghai.myqcloud.com/Work/image-20211109171559576.png)

## 7 扩展自制国内镜像，每三天更新一次

helm官方charts仓库需要国外网络访问， 阿里云提供了一个镜像仓库：然而从11月开始好像就没有更新过， 而helm的项目迭代得非常快，阿里镜像里连rabbitmq-ha都还没有。 可以直接从官方源爬过来放到自己服务器下。 这里使用了官方推荐的使用gitPage搭建charts仓库的方式。

项目地址：

```
https://github.com/BurdenBear/kube-charts-mirror
```

 