容器編排系統K8s之包管理器Helm基礎使用(二)

  前文我們介紹了helm的相關術語和使用helm安裝和卸載應用,回顧請參考://www.cnblogs.com/qiuhom-1874/p/14305902.html;今天我們來介紹下自定義chart以及打包chart,helm其他命令使用和私有helm倉庫搭建相關話題;

  繼上一篇部落格,我們了解了使用helm在k8s上安裝應用,卸載應用,以及倉庫的添加刪除更新等等操作;對於helm chart來說,它就是一個打包文件,把我們需要用到的配置清單,以模板的形式發布出來,用戶使用時,可以根據values.yaml文件來自行定義對應的屬性的值,當然也可以使用–set選項來指定個別配置清單的屬性的值;那麼我們使用helm命令從倉庫中安裝應用,它對應的打包文件放在那裡的呢?默認情況我們使用helm命令安裝應用,它會把對應應用的chart 打包文件存放在當前用戶的家目錄中的.cache/helm/repository/目錄下,以.tgz結尾的一個壓縮包;如下

  提示:上述目錄只要我們使用過helm install命令安裝應用,對應的chart 打包文件都會下載到此處;

  查看對應打包目錄結構

[[email protected] ~]# ll .cache/helm/repository/
total 6520
-rw-r--r-- 1 root root     865 Jan 21 02:23 bitnami-charts.txt
-rw-r--r-- 1 root root 6555926 Jan 21 02:23 bitnami-index.yaml
-rw-r--r-- 1 root root    4381 Jan 20 23:19 redis
-rw-r--r-- 1 root root   31909 Jan 20 22:54 redis-10.5.7.tgz
-rw-r--r-- 1 root root   72791 Jan 21 02:26 redis-12.6.2.tgz
[[email protected] ~]# cp .cache/helm/repository/redis-12.6.2.tgz .
[[email protected] ~]# ls
redis-12.6.2.tgz
[[email protected] ~]# tar xf redis-12.6.2.tgz 
[[email protected] ~]# ls
redis  redis-12.6.2.tgz
[[email protected] ~]# tree redis
redis
├── Chart.lock
├── charts
│   └── common
│       ├── Chart.yaml
│       ├── README.md
│       ├── templates
│       │   ├── _affinities.tpl
│       │   ├── _capabilities.tpl
│       │   ├── _errors.tpl
│       │   ├── _images.tpl
│       │   ├── _ingress.tpl
│       │   ├── _labels.tpl
│       │   ├── _names.tpl
│       │   ├── _secrets.tpl
│       │   ├── _storage.tpl
│       │   ├── _tplvalues.tpl
│       │   ├── _utils.tpl
│       │   ├── validations
│       │   │   ├── _cassandra.tpl
│       │   │   ├── _mariadb.tpl
│       │   │   ├── _mongodb.tpl
│       │   │   ├── _postgresql.tpl
│       │   │   ├── _redis.tpl
│       │   │   └── _validations.tpl
│       │   └── _warnings.tpl
│       └── values.yaml
├── Chart.yaml
├── ci
│   ├── default-values.yaml
│   ├── extra-flags-values.yaml
│   └── production-sentinel-values.yaml
├── img
│   ├── redis-cluster-topology.png
│   └── redis-topology.png
├── README.md
├── templates
│   ├── configmap-scripts.yaml
│   ├── configmap.yaml
│   ├── headless-svc.yaml
│   ├── health-configmap.yaml
│   ├── _helpers.tpl
│   ├── metrics-prometheus.yaml
│   ├── metrics-svc.yaml
│   ├── networkpolicy.yaml
│   ├── NOTES.txt
│   ├── pdb.yaml
│   ├── prometheusrule.yaml
│   ├── psp.yaml
│   ├── redis-master-statefulset.yaml
│   ├── redis-master-svc.yaml
│   ├── redis-node-statefulset.yaml
│   ├── redis-rolebinding.yaml
│   ├── redis-role.yaml
│   ├── redis-serviceaccount.yaml
│   ├── redis-slave-statefulset.yaml
│   ├── redis-slave-svc.yaml
│   ├── redis-with-sentinel-svc.yaml
│   └── secret.yaml
├── values.schema.json
└── values.yaml

7 directories, 53 files
[[email protected] ~]# 

  提示:charts目錄主要用來存放對應chart所依賴的其他chart文件;chart.yaml文件主要用來描述對應chart的元數據資訊,比如chart 的版本,名字,簡介資訊等等;ci目錄用於存放各種環境的values.yaml文件,默認情況不指定values文件,對應生效的是values.yaml文件;img目錄主要用於存放對應chart在倉庫中對應的圖標;README.md文件用於描述該chart的使用方式,部署手冊等等資訊;template目錄主要用來存放該chart部署為release所需的所有資源清單文件,該目錄下的資源清單文件不是我們前邊使用的資源清單文件,它裡面的格式是通過go模板語言寫的資源清單,在使用時,我們必須結合values.yaml中定義的值,通過模板引擎將其渲染以後才能正常使用;values.yaml文件主要用來描述對應資源模板清單中對應屬性的默認值,一般不指定values文件,chart應用的值都來自於values.yaml文件,當然用戶可以通過–set 來指定對應屬性的值,也可以手動編輯values文件,用–values或者-f選項指定對應的值文件也行;

  創建自定義chart命令幫助

[[email protected] ~]# helm create -h

This command creates a chart directory along with the common files and
directories used in a chart.

For example, 'helm create foo' will create a directory structure that looks
something like this:

    foo/
    ├── .helmignore   # Contains patterns to ignore when packaging Helm charts.
    ├── Chart.yaml    # Information about your chart
    ├── values.yaml   # The default values for your templates
    ├── charts/       # Charts that this chart depends on
    └── templates/    # The template files
        └── tests/    # The test files

'helm create' takes a path for an argument. If directories in the given path
do not exist, Helm will attempt to create them as it goes. If the given
destination exists and there are files in that directory, conflicting files
will be overwritten, but other files will be left alone.

Usage:
  helm create NAME [flags]

Flags:
  -h, --help             help for create
  -p, --starter string   the name or absolute path to Helm starter scaffold

Global Flags:
      --debug                       enable verbose output
      --kube-apiserver string       the address and the port for the Kubernetes API server
      --kube-as-group stringArray   group to impersonate for the operation, this flag can be repeated to specify multiple groups.
      --kube-as-user string         username to impersonate for the operation
      --kube-ca-file string         the certificate authority file for the Kubernetes API server connection
      --kube-context string         name of the kubeconfig context to use
      --kube-token string           bearer token used for authentication
      --kubeconfig string           path to the kubeconfig file
  -n, --namespace string            namespace scope for this request
      --registry-config string      path to the registry config file (default "/root/.config/helm/registry.json")
      --repository-cache string     path to the file containing cached repository indexes (default "/root/.cache/helm/repository")
      --repository-config string    path to the file containing repository names and URLs (default "/root/.config/helm/repositories.yaml")
[[email protected] ~]# 

  示例:創建一個myapp的chart

[[email protected] ~]# helm create myapp
Creating myapp
[[email protected] ~]# ls
myapp  redis  redis-12.6.2.tgz
[[email protected] ~]# tree myapp/
myapp/
├── 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
[[email protected] ~]# 

  查看chart.yaml文件內容

[[email protected] ~]# cat myapp/Chart.yaml 
apiVersion: v2
name: myapp
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 (//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.
# It is recommended to use it with quotes.
appVersion: "1.16.0"
[[email protected] ~]# 

  提示:Chart.yaml文件主要用來描述對應chart的相關屬性資訊,其中apiVersion欄位用於描述對應chart使用的api版本,默認是v2版本;name欄位用於描述對應chart的名稱;description欄位用於描述對應chart的說明簡介;type欄位用戶描述對應chart是應用程式還是庫文件,應用程式類型的chart,它可以運行為一個release,但庫類型的chart不能運行為release,它只能作為依賴被application類型的chart所使用;version欄位用於描述對應chart版本;appVersion欄位用於描述對應chart內部程式的版本資訊;

  查看模板文件

[[email protected] ~]# ll myapp/templates/
total 28
-rw-r--r-- 1 root root 1826 Jan 21 14:44 deployment.yaml
-rw-r--r-- 1 root root 1762 Jan 21 14:44 _helpers.tpl
-rw-r--r-- 1 root root  910 Jan 21 14:44 hpa.yaml
-rw-r--r-- 1 root root 1052 Jan 21 14:44 ingress.yaml
-rw-r--r-- 1 root root 1739 Jan 21 14:44 NOTES.txt
-rw-r--r-- 1 root root  316 Jan 21 14:44 serviceaccount.yaml
-rw-r--r-- 1 root root  355 Jan 21 14:44 service.yaml
drwxr-xr-x 2 root root   34 Jan 21 14:44 tests
[[email protected] ~]# cat myapp/templates/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.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 }}
[[email protected] ~]# 

  提示:該部署清單模板文件,主要用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文件中載入對應欄位的值作為模板文件相關屬性的值;

  values文件中的值引用

[[email protected] ~]# cat myapp/values.yaml 
# Default values for myapp.
# 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: {}
[[email protected] ~]# 

  提示:比如我們要引用values.yaml文件中的image欄位下的tag欄位的值,我們可以在模板文件中寫成{{ .Values.image.tag }};如果在命令行使用–set選項來應用我們可以寫成 image.tag;修改對應的值可以直接編輯對應values.yaml文件中對應欄位的值,也可以直接使用–set 指定對應欄位的對應值即可;默認情況在命令行使用–set選項給出的值,都會直接被替換,沒有給定的值,默認還是使用values.yaml文件中給定的默認值;

  示例:修改values.yaml文件中的值

[[email protected] ~]# cat myapp/values.yaml
# Default values for myapp.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 1

image:
  repository: ikubernetes/myapp
  pullPolicy: IfNotPresent
  # Overrides the image tag whose default is the chart appVersion.
  tag: "v1"

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: {}
[[email protected] ~]# 

  提示:上述values.yaml文件,我們修改了image.repository的值為ikubernetes/myapp和image.tag為v1;這表示對應chart使用程式的鏡像倉庫為ikubernetes/myapp倉庫;版本為v1;然後修改了resources欄位;添加了對應的資源限制配置;

  檢查對應values文件的語法是否正確?

[[email protected] ~]# helm  lint ./myapp/
==> Linting ./myapp/
[INFO] Chart.yaml: icon is recommended
[ERROR] values.yaml: unable to parse YAML: error converting YAML to JSON: yaml: line 60: did not find expected key
[ERROR] templates/: cannot load values.yaml: error converting YAML to JSON: yaml: line 60: did not find expected key
[ERROR] : unable to load chart
        cannot load values.yaml: error converting YAML to JSON: yaml: line 60: did not find expected key

Error: 1 chart(s) linted, 1 chart(s) failed
[[email protected] ~]# 

  提示:檢查values文件的配置語法,可以使用helm lint命令指定對應chart的目錄即可;上述檢查結果告訴我們所values.yaml的60配置有問題;

  提示:上述values文件中,resource欄位後面給定了對應的配置,對應{}就不能再使用,使用{}表示把resource欄位留空;所以我們只需把對應的大括弧刪除即可;

  刪除resource欄位的大括弧,再次檢查values的語法

[[email protected] ~]# helm  lint ./myapp/  
==> Linting ./myapp/
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, 0 chart(s) failed
[[email protected] ~]# 

  提示:只要上述檢查過程中沒有出現錯誤的類資訊,表示values語法正確;到此我們就可以使用我們手動創建的chart來部署為一個release了;

  修改Chart.yaml中的資訊,將myapp chart 部署為一個release

[[email protected] ~]# cat ./myapp/Chart.yaml
apiVersion: v2
name: myapp
description: web server

# 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 (//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.
# It is recommended to use it with quotes.
appVersion: "v1"
[[email protected] ~]# 

  應用myapp chart

[[email protected] ~]# helm install myapp-v1 ./myapp/ 
NAME: myapp-v1
LAST DEPLOYED: Thu Jan 21 15:15:52 2021
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-v1" -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 //127.0.0.1:8080 to use your application"
  kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
[[email protected] ~]#

  提示:部署自定義chart 使用helm install 指定對應release名稱,以及chart所在目錄即可;

  查看release

[[email protected] ~]# helm list
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
myapp-v1        default         1               2021-01-21 15:15:52.57286036 +0800 CST  deployed        myapp-0.1.0     v1         
redis           default         1               2021-01-21 02:26:26.13324987 +0800 CST  deployed        redis-12.6.2    6.0.10     
redis-demo      default         1               2021-01-21 01:58:18.20798703 +0800 CST  deployed        redis-12.6.2    6.0.10     
[[email protected] ~]# 

  查看對應pod是否正常運行?對應service是否正常創建?

  提示:可以看到對應pod和svc都正常創建;

  升級release

  更改Chart.yaml文件中的內容

[[email protected] ~]# cat myapp/Chart.yaml
apiVersion: v2
name: myapp
description: web server

# 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 (//semver.org/)
version: 0.2.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.
# It is recommended to use it with quotes.
appVersion: "v2"
[[email protected] ~]# 

  更改values.yaml文件中對應鏡像的版本

[[email protected] ~]# cat myapp/values.yaml
# Default values for myapp.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 1

image:
  repository: ikubernetes/myapp
  pullPolicy: IfNotPresent
  # Overrides the image tag whose default is the chart appVersion.
  tag: "v2"

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: {}
[[email protected] ~]# 

  使用upgrade命令升級release

[[email protected] ~]# helm list
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
myapp-v1        default         1               2021-01-21 15:15:52.57286036 +0800 CST  deployed        myapp-0.1.0     v1         
redis           default         1               2021-01-21 02:26:26.13324987 +0800 CST  deployed        redis-12.6.2    6.0.10     
redis-demo      default         1               2021-01-21 01:58:18.20798703 +0800 CST  deployed        redis-12.6.2    6.0.10     
[[email protected] ~]# helm upgrade --set service.type="NodePort" myapp-v1 ./myapp/ 
Release "myapp-v1" has been upgraded. Happy Helming!
NAME: myapp-v1
LAST DEPLOYED: Thu Jan 21 15:24:22 2021
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-v1)
  export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
  echo //$NODE_IP:$NODE_PORT
[[email protected] ~]# helm list
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
myapp-v1        default         2               2021-01-21 15:24:22.882236621 +0800 CST deployed        myapp-0.2.0     v2         
redis           default         1               2021-01-21 02:26:26.13324987 +0800 CST  deployed        redis-12.6.2    6.0.10     
redis-demo      default         1               2021-01-21 01:58:18.20798703 +0800 CST  deployed        redis-12.6.2    6.0.10     
[[email protected] ~]# kubectl get pods
NAME                        READY   STATUS        RESTARTS   AGE
myapp-v1-7c9d7c999f-8k6rm   0/1     Terminating   0          8m47s
myapp-v1-866b6d4cc6-nx87c   1/1     Running       0          16s
redis-demo-master-0         1/1     Running       1          13h
redis-demo-slave-0          1/1     Running       2          13h
redis-demo-slave-1          1/1     Running       7          13h
redis-master-0              1/1     Running       1          12h
redis-slave-0               1/1     Running       1          12h
redis-slave-1               1/1     Running       1          12h
[[email protected] ~]# kubectl get svc
NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes            ClusterIP   10.96.0.1        <none>        443/TCP        15h
myapp-v1              NodePort    10.110.153.241   <none>        80:32434/TCP   8m53s
redis-demo-headless   ClusterIP   None             <none>        6379/TCP       13h
redis-demo-master     ClusterIP   10.109.45.70     <none>        6379/TCP       13h
redis-demo-slave      ClusterIP   10.111.222.218   <none>        6379/TCP       13h
redis-headless        ClusterIP   None             <none>        6379/TCP       12h
redis-master          ClusterIP   10.108.35.165    <none>        6379/TCP       12h
redis-slave           ClusterIP   10.99.96.166     <none>        6379/TCP       12h
[[email protected] ~]# 

  提示:可以看到對應myapp-v1pod和svc都發生了變化;

  驗證:查看對應pod的版本資訊

[[email protected] ~]# kubectl describe pods myapp-v1-866b6d4cc6-nx87c |grep Image
    Image:          ikubernetes/myapp:v2
    Image ID:       docker-pullable://ikubernetes/[email protected]:85a2b81a62f09a414ea33b74fb8aa686ed9b168294b26b4c819df0be0712d358
[[email protected] ~]# 

  當然如果更新操作改動的資訊較少,我們也可以直接在命令使用–set選項來指定對應的屬性的值進行更新也行,如下

[[email protected] ~]# helm list
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
myapp-v1        default         2               2021-01-21 15:24:22.882236621 +0800 CST deployed        myapp-0.2.0     v2         
redis           default         1               2021-01-21 02:26:26.13324987 +0800 CST  deployed        redis-12.6.2    6.0.10     
redis-demo      default         1               2021-01-21 01:58:18.20798703 +0800 CST  deployed        redis-12.6.2    6.0.10     
[[email protected] ~]# helm upgrade --set image.tag="v3" myapp-v1 ./myapp/
Release "myapp-v1" has been upgraded. Happy Helming!
NAME: myapp-v1
LAST DEPLOYED: Thu Jan 21 15:29:46 2021
NAMESPACE: default
STATUS: deployed
REVISION: 3
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-v1" -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 //127.0.0.1:8080 to use your application"
  kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
[[email protected] ~]# helm list
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
myapp-v1        default         3               2021-01-21 15:29:46.491467084 +0800 CST deployed        myapp-0.2.0     v2         
redis           default         1               2021-01-21 02:26:26.13324987 +0800 CST  deployed        redis-12.6.2    6.0.10     
redis-demo      default         1               2021-01-21 01:58:18.20798703 +0800 CST  deployed        redis-12.6.2    6.0.10     
[[email protected] ~]# 

  提示:手動使用命令行選項–set更新,對應我們需要把對應的Chart中的資訊要提前修改了,否則像上面我們沒有修改對應文件中的資訊,它保留的還是原來的資訊;

  驗證:查看對應pod是否更新了版本?

[[email protected] ~]# kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
myapp-v1-675d685ddf-nn2zd   1/1     Running   0          106s
redis-demo-master-0         1/1     Running   1          13h
redis-demo-slave-0          1/1     Running   2          13h
redis-demo-slave-1          1/1     Running   7          13h
redis-master-0              1/1     Running   1          13h
redis-slave-0               1/1     Running   1          13h
redis-slave-1               1/1     Running   1          13h
[[email protected] ~]# kubectl describe pods/myapp-v1-675d685ddf-nn2zd |grep Image
    Image:          ikubernetes/myapp:v3
    Image ID:       docker-pullable://ikubernetes/[email protected]:b8d74db2515d3c1391c78c5768272b9344428035ef6d72158fd9f6c4239b2c69
[[email protected] ~]# kubectl get svc
NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
kubernetes            ClusterIP   10.96.0.1        <none>        443/TCP    15h
myapp-v1              ClusterIP   10.110.153.241   <none>        80/TCP     16m
redis-demo-headless   ClusterIP   None             <none>        6379/TCP   13h
redis-demo-master     ClusterIP   10.109.45.70     <none>        6379/TCP   13h
redis-demo-slave      ClusterIP   10.111.222.218   <none>        6379/TCP   13h
redis-headless        ClusterIP   None             <none>        6379/TCP   13h
redis-master          ClusterIP   10.108.35.165    <none>        6379/TCP   13h
redis-slave           ClusterIP   10.99.96.166     <none>        6379/TCP   13h
[[email protected] ~]# 

  提示:上面用命令行選項指定對應鏡像的版本更新是成功的;對應svc沒有指定其類型,也是使用的默認類型;

  回滾release

[[email protected] ~]# helm list       
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
myapp-v1        default         3               2021-01-21 15:29:46.491467084 +0800 CST deployed        myapp-0.2.0     v2         
redis           default         1               2021-01-21 02:26:26.13324987 +0800 CST  deployed        redis-12.6.2    6.0.10     
redis-demo      default         1               2021-01-21 01:58:18.20798703 +0800 CST  deployed        redis-12.6.2    6.0.10     
[[email protected] ~]# helm rollback myapp-v1 2
Rollback was a success! Happy Helming!
[[email protected] ~]# helm list
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
myapp-v1        default         4               2021-01-21 15:33:58.389015959 +0800 CST deployed        myapp-0.2.0     v2         
redis           default         1               2021-01-21 02:26:26.13324987 +0800 CST  deployed        redis-12.6.2    6.0.10     
redis-demo      default         1               2021-01-21 01:58:18.20798703 +0800 CST  deployed        redis-12.6.2    6.0.10     
[[email protected] ~]# helm rollback myapp-v1 2
Rollback was a success! Happy Helming!
[[email protected] ~]# helm rollback myapp-v1 1
Rollback was a success! Happy Helming!
[[email protected] ~]# helm history myapp-v1
REVISION        UPDATED                         STATUS          CHART           APP VERSION     DESCRIPTION     
1               Thu Jan 21 15:15:52 2021        superseded      myapp-0.1.0     v1              Install complete
2               Thu Jan 21 15:24:22 2021        superseded      myapp-0.2.0     v2              Upgrade complete
3               Thu Jan 21 15:29:46 2021        superseded      myapp-0.2.0     v2              Upgrade complete
4               Thu Jan 21 15:33:58 2021        superseded      myapp-0.2.0     v2              Rollback to 2   
5               Thu Jan 21 15:36:08 2021        superseded      myapp-0.2.0     v2              Rollback to 2   
6               Thu Jan 21 15:36:26 2021        deployed        myapp-0.1.0     v1              Rollback to 1   
[[email protected] ~]# helm rollback myapp-v1 1
Rollback was a success! Happy Helming!
[[email protected] ~]# helm history myapp-v1   
REVISION        UPDATED                         STATUS          CHART           APP VERSION     DESCRIPTION     
1               Thu Jan 21 15:15:52 2021        superseded      myapp-0.1.0     v1              Install complete
2               Thu Jan 21 15:24:22 2021        superseded      myapp-0.2.0     v2              Upgrade complete
3               Thu Jan 21 15:29:46 2021        superseded      myapp-0.2.0     v2              Upgrade complete
4               Thu Jan 21 15:33:58 2021        superseded      myapp-0.2.0     v2              Rollback to 2   
5               Thu Jan 21 15:36:08 2021        superseded      myapp-0.2.0     v2              Rollback to 2   
6               Thu Jan 21 15:36:26 2021        superseded      myapp-0.1.0     v1              Rollback to 1   
7               Thu Jan 21 15:38:21 2021        deployed        myapp-0.1.0     v1              Rollback to 1   
[[email protected] ~]# helm rollback myapp-v1 3
Rollback was a success! Happy Helming!
[[email protected] ~]# helm history myapp-v1   
REVISION        UPDATED                         STATUS          CHART           APP VERSION     DESCRIPTION     
1               Thu Jan 21 15:15:52 2021        superseded      myapp-0.1.0     v1              Install complete
2               Thu Jan 21 15:24:22 2021        superseded      myapp-0.2.0     v2              Upgrade complete
3               Thu Jan 21 15:29:46 2021        superseded      myapp-0.2.0     v2              Upgrade complete
4               Thu Jan 21 15:33:58 2021        superseded      myapp-0.2.0     v2              Rollback to 2   
5               Thu Jan 21 15:36:08 2021        superseded      myapp-0.2.0     v2              Rollback to 2   
6               Thu Jan 21 15:36:26 2021        superseded      myapp-0.1.0     v1              Rollback to 1   
7               Thu Jan 21 15:38:21 2021        superseded      myapp-0.1.0     v1              Rollback to 1   
8               Thu Jan 21 15:40:38 2021        deployed        myapp-0.2.0     v2              Rollback to 3   
[[email protected] ~]# 

  提示:回滾操作我們需要指定對應回滾的位置,這個位置用一個數字表示,這個數字就是對應的歷史版本的序號;比如回滾到序號為2的版本上,就使用helm rollback myapp-v1 2;如果回滾到版本序號為3的版本上,就把對應後面的版本序號更改為3即可;依此邏輯進行回滾;查看對應release的版本歷史,可以使用helm history RELEASE_NAME來查看;上述命令最後我們會滾到序號為3的版本上,該版本對應應用程式的版本為v3;

  驗證:查看對應pod程式版本是否v3?

[[email protected] ~]# kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
myapp-v1-675d685ddf-7c8zd   1/1     Running   0          11m
redis-demo-master-0         1/1     Running   1          13h
redis-demo-slave-0          1/1     Running   2          13h
redis-demo-slave-1          1/1     Running   7          13h
redis-master-0              1/1     Running   1          13h
redis-slave-0               1/1     Running   1          13h
redis-slave-1               1/1     Running   1          13h
[[email protected] ~]# kubectl describe pods/myapp-v1-675d685ddf-7c8zd |grep Image
    Image:          ikubernetes/myapp:v3
    Image ID:       docker-pullable://ikubernetes/[email protected]:b8d74db2515d3c1391c78c5768272b9344428035ef6d72158fd9f6c4239b2c69
[[email protected] ~]# 

  提示:可以看到對應pod使用的鏡像版本是v3;

  查看myapp-v1的狀態

[[email protected] ~]# helm status myapp-v1
NAME: myapp-v1
LAST DEPLOYED: Thu Jan 21 15:40:38 2021
NAMESPACE: default
STATUS: deployed
REVISION: 8
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-v1" -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 //127.0.0.1:8080 to use your application"
  kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
[[email protected] ~]# 

  提示:helm status命令就相當於是把對應chart中的template目錄下NOTES.txt文件進行渲染以後,輸出給用戶;這個內容主要告訴用戶對應chart怎麼連接使用,對應chart的狀態資訊等等;

  使用命令查看readme文件內容,chart.yaml文件內容和values文件內容

[[email protected] ~]# helm show readme 
[[email protected] ~]# helm show readme myapp/
[[email protected] ~]# helm show chart myapp/ 
apiVersion: v2
appVersion: v2
description: web server
name: myapp
type: application
version: 0.2.0

[[email protected] ~]# helm show values myapp/
# Default values for myapp.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 1

image:
  repository: ikubernetes/myapp
  pullPolicy: IfNotPresent
  # Overrides the image tag whose default is the chart appVersion.
  tag: "v2"

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: {}

[[email protected] ~]# 

  提示:對應chart中沒有README.md文件,對應使用helm show readme命令也是無法獲取到對應內容;

  查看template目錄下的模板文件內容

[[email protected] ~]# helm template myapp/
---
# Source: myapp/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: RELEASE-NAME-myapp
  labels:
    helm.sh/chart: myapp-0.2.0
    app.kubernetes.io/name: myapp
    app.kubernetes.io/instance: RELEASE-NAME
    app.kubernetes.io/version: "v2"
    app.kubernetes.io/managed-by: Helm
---
# Source: myapp/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: RELEASE-NAME-myapp
  labels:
    helm.sh/chart: myapp-0.2.0
    app.kubernetes.io/name: myapp
    app.kubernetes.io/instance: RELEASE-NAME
    app.kubernetes.io/version: "v2"
    app.kubernetes.io/managed-by: Helm
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: myapp
    app.kubernetes.io/instance: RELEASE-NAME
---
# Source: myapp/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: RELEASE-NAME-myapp
  labels:
    helm.sh/chart: myapp-0.2.0
    app.kubernetes.io/name: myapp
    app.kubernetes.io/instance: RELEASE-NAME
    app.kubernetes.io/version: "v2"
    app.kubernetes.io/managed-by: Helm
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: myapp
      app.kubernetes.io/instance: RELEASE-NAME
  template:
    metadata:
      labels:
        app.kubernetes.io/name: myapp
        app.kubernetes.io/instance: RELEASE-NAME
    spec:
      serviceAccountName: RELEASE-NAME-myapp
      securityContext:
        {}
      containers:
        - name: myapp
          securityContext:
            {}
          image: "ikubernetes/myapp:v2"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            limits:
              cpu: 100m
              memory: 128Mi
            requests:
              cpu: 100m
              memory: 128Mi
---
# Source: myapp/templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
  name: "RELEASE-NAME-myapp-test-connection"
  labels:
    helm.sh/chart: myapp-0.2.0
    app.kubernetes.io/name: myapp
    app.kubernetes.io/instance: RELEASE-NAME
    app.kubernetes.io/version: "v2"
    app.kubernetes.io/managed-by: Helm
  annotations:
    "helm.sh/hook": test
spec:
  containers:
    - name: wget
      image: busybox
      command: ['wget']
      args: ['RELEASE-NAME-myapp:80']
  restartPolicy: Never
[[email protected] ~]# 

  提示:上述清單是通過模板引擎結合values文件中定義的值進行渲染以後的結果;

  從倉庫中下載chart文件到本地

  提示:如果要下載對應chart文件,我們可以使用pull命令,該命令會到對應倉庫把對應chart的打包文件下載到本地;你的伺服器不能正常連接倉庫,請使用代理;如上;

  獲取已經安裝的release的擴展資訊

[[email protected] ~]# helm list
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
myapp-v1        default         8               2021-01-21 15:40:38.060295891 +0800 CST deployed        myapp-0.2.0     v2         
redis           default         1               2021-01-21 02:26:26.13324987 +0800 CST  deployed        redis-12.6.2    6.0.10     
redis-demo      default         1               2021-01-21 01:58:18.20798703 +0800 CST  deployed        redis-12.6.2    6.0.10     
[[email protected] ~]# helm get values myapp-v1
USER-SUPPLIED VALUES:
image:
  tag: v3
[[email protected] ~]# helm get notes myapp-v1 
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-v1" -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 //127.0.0.1:8080 to use your application"
  kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT

[[email protected] ~]# helm get hooks myapp-v1
---
# Source: myapp/templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
  name: "myapp-v1-test-connection"
  labels:
    helm.sh/chart: myapp-0.2.0
    app.kubernetes.io/name: myapp
    app.kubernetes.io/instance: myapp-v1
    app.kubernetes.io/version: "v2"
    app.kubernetes.io/managed-by: Helm
  annotations:
    "helm.sh/hook": test
spec:
  containers:
    - name: wget
      image: busybox
      command: ['wget']
      args: ['myapp-v1:80']
  restartPolicy: Never
[[email protected] ~]# helm get manifest myapp-v1
---
# Source: myapp/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: myapp-v1
  labels:
    helm.sh/chart: myapp-0.2.0
    app.kubernetes.io/name: myapp
    app.kubernetes.io/instance: myapp-v1
    app.kubernetes.io/version: "v2"
    app.kubernetes.io/managed-by: Helm
---
# Source: myapp/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-v1
  labels:
    helm.sh/chart: myapp-0.2.0
    app.kubernetes.io/name: myapp
    app.kubernetes.io/instance: myapp-v1
    app.kubernetes.io/version: "v2"
    app.kubernetes.io/managed-by: Helm
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: myapp
    app.kubernetes.io/instance: myapp-v1
---
# Source: myapp/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-v1
  labels:
    helm.sh/chart: myapp-0.2.0
    app.kubernetes.io/name: myapp
    app.kubernetes.io/instance: myapp-v1
    app.kubernetes.io/version: "v2"
    app.kubernetes.io/managed-by: Helm
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: myapp
      app.kubernetes.io/instance: myapp-v1
  template:
    metadata:
      labels:
        app.kubernetes.io/name: myapp
        app.kubernetes.io/instance: myapp-v1
    spec:
      serviceAccountName: myapp-v1
      securityContext:
        {}
      containers:
        - name: myapp
          securityContext:
            {}
          image: "ikubernetes/myapp:v3"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            limits:
              cpu: 100m
              memory: 128Mi
            requests:
              cpu: 100m
              memory: 128Mi

[[email protected] ~]# 

  提示:如果要一次獲取上述所有內容,可以使用helm get all 命令進行獲取;

  打包自定義chart

[[email protected] ~]# ls
logstash-3.0.2.tgz  myapp  redis  redis-12.6.2.tgz
[[email protected] ~]# helm package ./myapp/
Successfully packaged chart and saved it to: /root/myapp-0.2.0.tgz
[[email protected] ~]# ls
logstash-3.0.2.tgz  myapp  myapp-0.2.0.tgz  redis  redis-12.6.2.tgz
[[email protected] ~]# 

  提示:打包好chart文件以後,我們就可以把對應文件放到對應的倉庫中共享給別人使用;

  helm私有倉庫搭建

  helm私有倉庫本質上就是一個http文件伺服器,我們只需要將對應的chart打包文件,以及對應倉庫的元數據資訊放到對應目錄即可

  找一台伺服器安裝nginx作為helm 私有倉庫

[[email protected]_registry ~]# yum install -y nginx

  生成倉庫元數據資訊

[[email protected] ~]# mkdir repo-test
[[email protected] ~]# mv *.tgz repo-test/
[[email protected] ~]# ls
myapp  redis  repo-test
[[email protected] ~]# cd repo-test/
[[email protected] repo-test]# helm repo index . --url //192.168.0.99/repo-test
[[email protected] repo-test]# ls
index.yaml  logstash-3.0.2.tgz  myapp-0.2.0.tgz  redis-12.6.2.tgz
[[email protected] repo-test]# cat index.yaml 
apiVersion: v1
entries:
  logstash:
  - annotations:
      category: LogManagement
    apiVersion: v2
    appVersion: 7.10.2
    created: "2021-01-21T16:43:51.585642435+08:00"
    dependencies:
    - name: common
      repository: //charts.bitnami.com/bitnami
      tags:
      - bitnami-common
      version: 1.x.x
    description: Logstash is an open source, server-side data processing pipeline that ingests data from a multitude of sources simultaneously, transforms it, and then sends it to your favorite "stash".
    digest: b60ccc7d48acfbfafd6a226b32316fff173f7e17112cee8367c5680012bc37a1
    home: //github.com/bitnami/charts/tree/master/bitnami/logstash
    icon: //bitnami.com/assets/stacks/logstash/img/logstash-stack-220x234.png
    keywords:
    - logstash
    - logging
    - elk
    maintainers:
    - email: [email protected]
      name: Bitnami
    name: logstash
    sources:
    - //github.com/bitnami/bitnami-docker-logstash
    - //www.elastic.co/products/logstash
    urls:
    - //192.168.0.99/repo-test/logstash-3.0.2.tgz
    version: 3.0.2
  myapp:
  - apiVersion: v2
    appVersion: v2
    created: "2021-01-21T16:43:51.586100842+08:00"
    description: web server
    digest: 55710394a8f2a8b0770c7212aaa92477adefebfbe72640d8c84e42c7999dd1d9
    name: myapp
    type: application
    urls:
    - //192.168.0.99/repo-test/myapp-0.2.0.tgz
    version: 0.2.0
  redis:
  - annotations:
      category: Database
    apiVersion: v2
    appVersion: 6.0.10
    created: "2021-01-21T16:43:51.589712477+08:00"
    dependencies:
    - name: common
      repository: //charts.bitnami.com/bitnami
      tags:
      - bitnami-common
      version: 1.x.x
    description: Open source, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets.
    digest: 4208a6eae05c9486dbecc55db3bc6e04960708e0b389adfa1f7e309d3937a451
    home: //github.com/bitnami/charts/tree/master/bitnami/redis
    icon: //bitnami.com/assets/stacks/redis/img/redis-stack-220x234.png
    keywords:
    - redis
    - keyvalue
    - database
    maintainers:
    - email: [email protected]
      name: Bitnami
    - email: [email protected]
      name: desaintmartin
    name: redis
    sources:
    - //github.com/bitnami/bitnami-docker-redis
    - //redis.io/
    urls:
    - //192.168.0.99/repo-test/redis-12.6.2.tgz
    version: 12.6.2
generated: "2021-01-21T16:43:51.568008766+08:00"
[[email protected] repo-test]# 

  複製repo-test目錄到web伺服器nginx的網頁根目錄

[[email protected] repo-test]# cd ..
[[email protected] ~]# scp -r repo-test 192.168.0.99:/usr/share/nginx/html/
[email protected]'s password: 
logstash-3.0.2.tgz                                                                                      100%   26KB   8.8MB/s   00:00    
myapp-0.2.0.tgz                                                                                         100% 3584   406.3KB/s   00:00    
redis-12.6.2.tgz                                                                                        100%   71KB  10.5MB/s   00:00    
index.yaml                                                                                              100% 2548   348.1KB/s   00:00    
[[email protected] ~]# ssh 192.168.0.99
[email protected]'s password: 
Last login: Thu Jan 21 16:35:28 2021 from 192.168.0.232
[[email protected]_registry ~]# ll /usr/share/nginx/html/
total 12
-rw-r--r-- 1 root root 3650 Nov  1 10:01 404.html
-rw-r--r-- 1 root root 3693 Nov  1 10:01 50x.html
lrwxrwxrwx 1 root root   20 Jan 21 16:36 en-US -> ../../doc/HTML/en-US
drwxr-xr-x 2 root root   27 Jan 21 16:36 icons
lrwxrwxrwx 1 root root   18 Jan 21 16:36 img -> ../../doc/HTML/img
lrwxrwxrwx 1 root root   25 Jan 21 16:36 index.html -> ../../doc/HTML/index.html
-rw-r--r-- 1 root root  368 Nov  1 10:01 nginx-logo.png
lrwxrwxrwx 1 root root   14 Jan 21 16:36 poweredby.png -> nginx-logo.png
drwxr-xr-x 2 root root   97 Jan 21 16:45 repo-test
[[email protected]_registry ~]# 

  啟動nginx服務

[[email protected]_registry ~]# systemctl start nginx
[[email protected]_registry ~]# ss -tnl
State      Recv-Q Send-Q                        Local Address:Port                                       Peer Address:Port              
LISTEN     0      128                                       *:111                                                   *:*                  
LISTEN     0      128                                       *:80                                                    *:*                  
LISTEN     0      128                                       *:20048                                                 *:*                  
LISTEN     0      5                             192.168.122.1:53                                                    *:*                  
LISTEN     0      128                                       *:22                                                    *:*                  
LISTEN     0      128                            192.168.0.99:631                                                   *:*                  
LISTEN     0      100                               127.0.0.1:25                                                    *:*                  
LISTEN     0      64                                        *:45725                                                 *:*                  
LISTEN     0      128                                       *:36254                                                 *:*                  
LISTEN     0      64                                        *:2049                                                  *:*                  
LISTEN     0      128                                      :::111                                                  :::*                  
LISTEN     0      128                                      :::80                                                   :::*                  
LISTEN     0      128                                      :::20048                                                :::*                  
LISTEN     0      128                                      :::22                                                   :::*                  
LISTEN     0      100                                     ::1:25                                                   :::*                  
LISTEN     0      128                                      :::52761                                                :::*                  
LISTEN     0      64                                       :::2049                                                 :::*                  
LISTEN     0      64                                       :::43907                                                :::*                  
[[email protected]_registry ~]# 

  驗證:使用helm添加私有倉庫

[[email protected] ~]# helm repo add repo-test //192.168.0.99/repo-test
"repo-test" has been added to your repositories
[[email protected] ~]# helm repo list
NAME            URL                               
bitnami         //charts.bitnami.com/bitnami
repo-test       //192.168.0.99/repo-test     
[[email protected] ~]# helm search repo repo-test
NAME                    CHART VERSION   APP VERSION     DESCRIPTION                                       
repo-test/logstash      3.0.2           7.10.2          Logstash is an open source, server-side data pr...
repo-test/myapp         0.2.0           v2              web server                                        
repo-test/redis         12.6.2          6.0.10          Open source, advanced key-value store. It is of...
[[email protected] ~]# 

  提示:可以看到對應倉庫中的chart都可以正常列出來;

  安裝私有倉庫中的chart

[[email protected] ~]# helm install myapp-test repo-test/myapp
NAME: myapp-test
LAST DEPLOYED: Thu Jan 21 16:54:06 2021
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-test" -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 //127.0.0.1:8080 to use your application"
  kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
[[email protected] ~]# helm list
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
myapp-test      default         1               2021-01-21 16:54:06.041883984 +0800 CST deployed        myapp-0.2.0     v2         
myapp-v1        default         8               2021-01-21 15:40:38.060295891 +0800 CST deployed        myapp-0.2.0     v2         
redis           default         1               2021-01-21 02:26:26.13324987 +0800 CST  deployed        redis-12.6.2    6.0.10     
redis-demo      default         1               2021-01-21 01:58:18.20798703 +0800 CST  deployed        redis-12.6.2    6.0.10     
[[email protected] ~]# kubectl get pods 
NAME                          READY   STATUS    RESTARTS   AGE
myapp-test-58c57d75fc-s22cn   1/1     Running   0          31s
myapp-v1-675d685ddf-7c8zd     1/1     Running   0          73m
redis-demo-master-0           1/1     Running   1          14h
redis-demo-slave-0            1/1     Running   2          14h
redis-demo-slave-1            1/1     Running   7          14h
redis-master-0                1/1     Running   1          14h
redis-slave-0                 1/1     Running   1          14h
redis-slave-1                 1/1     Running   1          14h
[[email protected] ~]# kubectl get svc
NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
kubernetes            ClusterIP   10.96.0.1        <none>        443/TCP    17h
myapp-test            ClusterIP   10.108.7.220     <none>        80/TCP     39s
myapp-v1              ClusterIP   10.110.153.241   <none>        80/TCP     98m
redis-demo-headless   ClusterIP   None             <none>        6379/TCP   14h
redis-demo-master     ClusterIP   10.109.45.70     <none>        6379/TCP   14h
redis-demo-slave      ClusterIP   10.111.222.218   <none>        6379/TCP   14h
redis-headless        ClusterIP   None             <none>        6379/TCP   14h
redis-master          ClusterIP   10.108.35.165    <none>        6379/TCP   14h
redis-slave           ClusterIP   10.99.96.166     <none>        6379/TCP   14h
[[email protected] ~]# curl 10.108.7.220
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[[email protected] ~]# 

  提示:可以看到使用私有倉庫中的chart能夠正常運行為一個release,對應生成的svc也能正常訪問;

  使用阿里云云效私有helm倉庫

  1、進入://repomanage.rdc.aliyun.com/my/repo?spm=a2c4g.11186623.2.7.7b646b06Zv1cAd,登錄阿里雲帳號,並註冊開通雲效服務,創建一個企業;

  2、創建名稱空間

 

  3、添加倉庫

  4、helm push 插件

[[email protected] ~]# helm plugin install //github.com/chartmuseum/helm-push 
Downloading and installing helm-push v0.9.0 ...
//github.com/chartmuseum/helm-push/releases/download/v0.9.0/helm-push_0.9.0_linux_amd64.tar.gz
Installed plugin: push
[[email protected] ~]# 

  5、發布chart目錄

[[email protected] ~]# cat myapp/Chart.yaml 
apiVersion: v2
name: myapp
description: web server

# 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 (//semver.org/)
version: 0.2.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.
# It is recommended to use it with quotes.
appVersion: "v2"
[[email protected] ~]# helm push myapp/ $NAMESPACE
Pushing myapp-0.2.0.tgz to 136529-test...
Done.
[[email protected] ~]# 

  6、發布chart打包文件

[[email protected] ~]#  helm push repo-test/myapp-0.2.0.tgz $NAMESPACE
Pushing myapp-0.2.0.tgz to 136529-test...
Done.
[[email protected] ~]# 

  提示:如果沒有將自定義chart打包,請先使用helm package CHART_DIR打包;

  7、更新本地倉庫索引

[[email protected] ~]# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "repo-test" chart repository
...Successfully got an update from the "bitnami" chart repository
...Successfully got an update from the "136529-test" chart repository
Update Complete. ⎈Happy Helming!⎈
[[email protected] ~]# 

  驗證:搜索myapp,看看對應倉庫是否能夠列出對應的chart?

[[email protected] ~]# helm search repo myapp
NAME                    CHART VERSION   APP VERSION     DESCRIPTION
136529-test/myapp       0.2.0           v2              web server 
repo-test/myapp         0.2.0           v2              web server 
[[email protected] ~]# 

  在阿里云云效網站上查看上傳的chart

  驗證:安裝myapp,看看對應chart是否能夠運行為一個release?

  提示:可以看到可以從對應helm倉庫下載對應的chart,並在k8s上運行為一個release;