Kubernetes Helm 使用

配置国内存放 chart 仓库的地址

#阿里云仓库(https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts)
#官方仓库(https://hub.kubeapps.com/charts/incubator)官方 chart 仓库,国内可能无法访问。
#微软仓库(http://mirror.azure.cn/kubernetes/charts/)这个仓库推荐,基本上官网有的 chart这里都有,国内可能无法访问。

#添加阿里云的 chart 仓库
[root@ca-k8s-master01 helm]# helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
"aliyun" has been added to your repositories

##添加 bitnami 的 chart 仓库
[root@ca-k8s-master01 helm]#  helm repo add bitnami https://charts.bitnami.com/bitnami
"bitnami" has been added to your repositories

#查看配置的 chart 仓库有哪些
[root@ca-k8s-master01 helm]# helm repo list
NAME    URL
harbor  https://helm.goharbor.io
aliyun  https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
bitnami https://charts.bitnami.com/bitnami

#删除 chart 仓库地址
[root@ca-k8s-master01 helm]# helm repo remove aliyun
"aliyun" has been removed from your repositories

#重新添加阿里云的 chart 仓库
[root@ca-k8s-master01 helm]# helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
"aliyun" has been added to your repositories
#更新 chart 仓库
[root@ca-k8s-master01 helm]# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "aliyun" chart repository
...Successfully got an update from the "harbor" chart repository
...Successfully got an update from the "bitnami" chart repository
Update Complete. ⎈Happy Helming!⎈

#从指定 chart 仓库地址搜索 chart

 Helm 基本使用

 搜索和下载 Chart

#查看阿里云 chart 仓库中的 memcached
[root@ca-k8s-master01 helm]#  helm search repo aliyun |grep memcached
aliyun/mcrouter                 0.1.0           0.36.0          Mcrouter is a memcached protocol router for sca...
aliyun/memcached                2.0.1                           Free & open source, high-performance, distribut...

#查看 chart 信息
[root@ca-k8s-master01 helm]# helm show chart aliyun/memcached
apiVersion: v1
description: Free & open source, high-performance, distributed memory object caching
  system.
home: http://memcached.org/
icon: https://upload.wikimedia.org/wikipedia/en/thumb/2/27/Memcached.svg/1024px-Memcached.svg.png
keywords:
- memcached
- cache
maintainers:
- email: gtaylor@gc-taylor.com
  name: Greg Taylor
name: memcached
sources:
- https://github.com/docker-library/memcached
version: 2.0.1

#下载 chart 包到本地
[root@ca-k8s-master01 helm]# helm pull aliyun/memcached
[root@ca-k8s-master01 helm]# ll
-rw-r--r-- 1 root root       3194 Jan 26 20:18 memcached-2.0.1.tgz
[root@ca-k8s-master01 helm]# cd memcached
[root@ca-k8s-master01 helm]# tar zxvf memcached-2.0.1.tgz
[root@ca-k8s-master01 memcached]# ls
Chart.yaml  README.md  templates  values.yaml

#Chart.yaml: chart 的基本信息,包括版本名字之类
#templates: 存放 k8s 的部署资源模板,通过渲染变量得到部署文件
#values.yaml:存放全局变量,templates 下的文件可以调用

[root@ca-k8s-master01 memcached]# cd templates/
[root@ca-k8s-master01 templates]# ll
total 20
-rwxr-xr-x 1 root root  536 Jan  1  1970 _helpers.tpl
-rwxr-xr-x 1 root root  570 Jan  1  1970 NOTES.txt
-rwxr-xr-x 1 root root  373 Jan  1  1970 pdb.yaml
-rwxr-xr-x 1 root root 2305 Jan  1  1970 statefulset.yaml
-rwxr-xr-x 1 root root  420 Jan  1  1970 svc.yaml
#_helpers.tpl 存放能够复用的模板
#NOTES.txt 为用户提供一个关于 chart 部署后使用说明的文件

 部署 chart

helm 部署 memcached 服务

#安装 memcached 的 Chart
[root@ca-k8s-node02 Ingress]#  crictl pull memcached:1.4.36-alpine
#修改 statefulset.yaml 文件 apps/v1beta 改为 apps/v1
[root@ca-k8s-master01 memcached]# vim templates/statefulset.yaml
apiVersion: apps/v1

#添加字段
[root@ca-k8s-master01 memcached]# vim templates/statefulset.yaml
spec:
  selector:
    matchLabels:
      app: {{ template "memcached.fullname" . }}
      chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
      release: "{{ .Release.Name }}"
      heritage: "{{ .Release.Service }}"

#删除affinity亲和性配置删除
      affinity:
        podAntiAffinity:
        {{- if eq .Values.AntiAffinity "hard" }}
          requiredDuringSchedulingIgnoredDuringExecution:
          - topologyKey: "kubernetes.io/hostname"
            labelSelector:
              matchLabels:
                app:  {{ template "memcached.fullname" . }}
                release: {{ .Release.Name | quote }}
        {{- else if eq .Values.AntiAffinity "soft" }}
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 5
            podAffinityTerm:
              topologyKey: "kubernetes.io/hostname"
              labelSelector:
                matchLabels:
                  app:  {{ template "memcached.fullname" . }}
                  release: {{ .Release.Name | quote }}
        {{- end }}

#文件
[root@ca-k8s-master01 memcached]# cat templates/statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: {{ template "memcached.fullname" . }}
  labels:
    app: {{ template "memcached.fullname" . }}
    chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    release: "{{ .Release.Name }}"
    heritage: "{{ .Release.Service }}"
spec:
  selector:
    matchLabels:
      app: {{ template "memcached.fullname" . }}
      chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
      release: "{{ .Release.Name }}"
      heritage: "{{ .Release.Service }}"
  serviceName: {{ template "memcached.fullname" . }}
  replicas: {{ .Values.replicaCount }}
  template:
    metadata:
      labels:
        app: {{ template "memcached.fullname" . }}
        chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
        release: "{{ .Release.Name }}"
        heritage: "{{ .Release.Service }}"
    spec:
      containers:
      - name: {{ template "memcached.fullname" . }}
        image: {{ .Values.image }}
        imagePullPolicy: {{ default "" .Values.imagePullPolicy | quote }}
        command:
        - memcached
        - -m {{ .Values.memcached.maxItemMemory  }}
        {{- if .Values.memcached.extendedOptions }}
        - -o
        - {{ .Values.memcached.extendedOptions }}
        {{- end }}
        {{- if .Values.memcached.verbosity }}
        - -{{ .Values.memcached.verbosity }}
        {{- end }}
        ports:
        - name: memcache
          containerPort: 11211
        livenessProbe:
          tcpSocket:
            port: memcache
          initialDelaySeconds: 30
          timeoutSeconds: 5
        readinessProbe:
          tcpSocket:
            port: memcache
          initialDelaySeconds: 5
          timeoutSeconds: 1
        resources:
{{ toYaml .Values.resources | indent 10 }}

#因为Kubenetes是 1.28版本 apiVersion: policy/v1beta1 改为 policy/v1
[root@ca-k8s-master01 memcached]# vim templates/pdb.yaml 
apiVersion: policy/v1beta1

#安装
[root@ca-k8s-master01 memcached]# helm install memcached ./
NAME: memcached
LAST DEPLOYED: Fri Jan 26 20:36:26 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Memcached can be accessed via port 11211 on the following DNS name from within your cluster:
memcached-memcached.default.svc.cluster.local

If you'd like to test your instance, forward the port locally:

  export POD_NAME=$(kubectl get pods --namespace default -l "app=memcached-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

You should see:

  STORED

#
[root@ca-k8s-master01 memcached]# kubectl get pods | grep mem
memcached-memcached-0                                   1/1     Running            0                  72s
memcached-memcached-1                                   1/1     Running            0                  52s
memcached-memcached-2                                   1/1     Running            0                  41s

#测试检验
[root@ca-k8s-master01 memcached]#  export POD_NAME=$(kubectl get pods --namespace default -l "app=memcached-memcached" -o jsonpath="{.items[0].metadata.name}")

[root@ca-k8s-master01 memcached]#  kubectl port-forward $POD_NAME 11211
Forwarding from 127.0.0.1:11211 -> 11211
Forwarding from [::1]:11211 -> 11211
Handling connection for 11211
Handling connection for 11211

[root@ca-k8s-master01 ~]# echo -e 'set mykey 0 60 5\r\nhello\r' | nc localhost 11211
STORED

 release 相关操作

#查看 release 发布状态
[root@ca-k8s-master01 memcached]# helm list
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
memcached       default         1               2024-01-26 20:36:26.289458378 +0800 CST deployed        memcached-2.0.1

#删除 release
[root@ca-k8s-master01 memcached]# helm delete memcached
release "memcached" uninstalled

#删除 release 会把 release 下对应的资源也删除
[root@ca-k8s-master01 memcached]# kubectl get pods | grep memacache

自定义Chart模板

 自定义一个 Chart

[root@ca-k8s-master01 helm]#  helm create myapp
Creating myapp

[root@ca-k8s-master01 helm]# cd myapp/
[root@ca-k8s-master01 myapp]# yum install tree -y

[root@ca-k8s-master01 myapp]# tree ./
./
├── charts     # 用于存放所依赖的子 chart 
├── Chart.yaml # 描述这个 Chart 的相关信息、包括名字、描述信息、版本等
├── templates  #模板目录,保留创建 k8s 的资源清单文件
│   ├── 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  #模板的值文件,这些值会在安装时应用到 GO 模板生成部署文件
└── values.yaml

  Chart.yaml 编写规则

[root@ca-k8s-master01 myapp]# grep -Ev "^#|^$" Chart.yaml
apiVersion: v2
name: myapp
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
appVersion: "1.16.0"
maintainer:
- name: xks
  Location: Shanghai

解释说明:Chart.yaml 文件主要用来描述对应 chart 的相关属性信息,其中 apiVersion 字段用于描述对
应 chart 使用的 api 版本,默认是 v2 版本;name 字段用于描述对应 chart 的名称;description 字段用
于描述对应 chart 的说明简介;type 字段用户描述对应 chart 是应用程序还是库文件,应用程序类型的
chart,它可以运行为一个 release,但库类型的 chart 不能运行为 release,它只能作为依赖被
application 类型的 chart 所使用;version 字段用于描述对应 chart 版本;appVersion 字段用于描述对
应 chart 内部程序的版本信息;

 go 模板文件渲染

[root@ca-k8s-master01 templates]# cat deployment.yaml
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.labels" . | nindent 8 }}
        {{- with .Values.podLabels }}
        {{- toYaml . | nindent 8 }}
        {{- end }}
    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: {{ .Values.service.port }}
              protocol: TCP
          livenessProbe:
            {{- toYaml .Values.livenessProbe | nindent 12 }}
          readinessProbe:
            {{- toYaml .Values.readinessProbe | nindent 12 }}
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
          {{- with .Values.volumeMounts }}
          volumeMounts:
            {{- toYaml . | nindent 12 }}
          {{- end }}
      {{- with .Values.volumes }}
      volumes:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- 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)表示截断数字

values.yaml编写

[root@ca-k8s-master01 myapp]# grep -Ev "^#|^$|*#" values.yaml
replicaCount: 1
image:
  repository: nginx
  pullPolicy: IfNotPresent
  tag: ""
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
  create: true
  automount: true
  annotations: {}
  name: ""
podAnnotations: {}
podLabels: {}
podSecurityContext: {}
securityContext: {}
service:
  type: ClusterIP
  port: 80
ingress:
  enabled: false
  className: ""
  annotations: {}
  hosts:
    - host: chart-example.local
      paths:
        - path: /
          pathType: ImplementationSpecific
  tls: []
resources: {}
livenessProbe:
  httpGet:
    path: /
    port: http
readinessProbe:
  httpGet:
    path: /
    port: http
autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 100
  targetCPUUtilizationPercentage: 80
volumes: []
volumeMounts: []
nodeSelector: {}
tolerations: []
affinity: {}


解释:比如我们要引用 values.yaml 文件中的 image 字段下的 tag 字段的值,我们可以在模板文件中写成{{ .Values.image.tag }};
如果在命令行使用--set 选项来应用我们可以写成 image.tag;
修改对应的值可以直接编辑对应 values.yaml 文件中对应字段的值,也可以直接使用--set 指定对应字段的对应值即可;
默认情况在命令行使用--set 选项给出的值,都会直接被替换,没有给定的值,默认还是使用values.yaml 文件中给定的默认值;

 部署 release

[root@ca-k8s-master01 myapp]# helm install myapp .
NAME: myapp
LAST DEPLOYED: Sat Jan 27 14:49:32 2024
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=myapp,app.kubernetes.io/instance=myapp" -o jsonpath="{.items[0].metadata.name}")
  export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
  
[root@ca-k8s-master01 myapp]# kubectl get pods | grep myapp
myapp-5dfc6df56-mgzdg                                   1/1     Running            0                  11m

Helm 常用命令演示

[root@ca-k8s-master01 myapp]# helm lint /root/helm/myapp/
==> Linting /root/helm/myapp/
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, 0 chart(s) failed

 upgrade 升级 release

[root@ca-k8s-master01 myapp]# kubectl get svc | grep myapp
myapp                                        ClusterIP      10.100.208.187   <none>                                                     80/TCP                                               13m

[root@ca-k8s-master01 myapp]# helm upgrade --set service.type="NodePort" myapp .
Release "myapp" has been upgraded. Happy Helming!
NAME: myapp
LAST DEPLOYED: Sat Jan 27 15:03:36 2024
NAMESPACE: default
STATUS: deployed
REVISION: 2
NOTES:
1. Get the application URL by running these commands:
  export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services myapp)
  export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
  echo http://$NODE_IP:$NODE_PORT
  
[root@ca-k8s-master01 myapp]# kubectl get svc | grep myapp
myapp                                        NodePort       10.100.208.187   <none>                                                     80:30820/TCP                                         14m

[root@ca-k8s-master01 myapp]# curl 192.168.40.120:30820
<!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>

回滚 release

#查看历史版本
[root@ca-k8s-master01 myapp]# helm history myapp
REVISION        UPDATED                         STATUS          CHART           APP VERSION     DESCRIPTION
1               Sat Jan 27 14:49:32 2024        superseded      myapp-0.1.0     1.16.0          Install complete
2               Sat Jan 27 15:03:36 2024        deployed        myapp-0.1.0     1.16.0          Upgrade complete

#把 myapp 回滚到版本 1
[root@ca-k8s-master01 myapp]# helm rollback myapp 1
Rollback was a success! Happy Helming!

#可以看到 service 已经完成回滚了
[root@ca-k8s-master01 myapp]# kubectl get svc | grep myapp
myapp     ClusterIP      10.100.208.187   <none>  80/TCP  6h3m

打包 Chart

[root@ca-k8s-master01 helm]# helm package /root/helm/myapp/
Successfully packaged chart and saved it to: /root/helm/myapp-0.1.0.tgz

[root@ca-k8s-master01 helm]# ll | grep tgz
-rw-r--r-- 1 root root       4003 Jan 27 20:54 myapp-0.1.0.tgz

 操作 release 命令

#升级 release 版本
helm upgrade
#回滚 release 版本
helm rollback
#创建一个 release 实例
helm install
#卸载 release
helm uninstall
#查看历史版本
helm history

操作 Chart 命令

#检查 Chat 的语法
helm lint
#chart 相关的查看 chart 的详细信息
helm inspect
#把 chart 下载下来
helm pull
#把 chart 打包
helm package

posted @ 2024-01-26 20:44  しみずよしだ  阅读(73)  评论(0)    收藏  举报