43. Helm 的基本使用

上节课我们成功安装了Helm的客户端以及服务端Tiller Server,我们也自己尝试创建了我们的第一个 Helm Chart 包,这节课就来和大家一起学习下 Helm 中的一些常用的操作方法。

仓库

Helm 的 Repo 仓库和 Docker Registry 比较类似,Chart 库可以用来存储和共享打包 Chart 的位置,我们在安装了 Helm 后,默认的仓库地址是 google 的一个地址,这对于我们不能科学上网的同学就比较苦恼了,没办法访问到官方提供的 Chart 仓库,可以用helm repo list来查看当前的仓库配置:

  1. $ helm repo list
  2. NAME URL
  3. stable https://kubernetes-charts.storage.googleapis.com/
  4. local http://127.0.0.1:8879/charts

我们可以看到除了一个默认的 stable 的仓库配置外,还有一个 local 的本地仓库,这是我们本地测试的一个仓库地址。其实要创建一个 Chart 仓库也是非常简单的,Chart 仓库其实就是一个带有index.yaml索引文件和任意个打包的 Chart 的 HTTP 服务器而已,比如我们想要分享一个 Chart 包的时候,将我们本地的 Chart 包上传到该服务器上面,别人就可以使用了,所以其实我们自己托管一个 Chart 仓库也是非常简单的,比如阿里云的 OSS、Github Pages,甚至自己创建的一个简单服务器都可以。

为了解决科学上网的问题,我这里建了一个 Github Pages 仓库,每天会自动和官方的仓库进行同步,地址是:https://github.com/cnych/kube-charts-mirror,这样我们就可以将我们的 Helm 默认仓库地址更改成我们自己的仓库地址了:

  1. $ helm repo remove stable
  2. "stable" has been removed from your repositories
  3. $ helm repo add stable https://cnych.github.io/kube-charts-mirror/
  4. "stable" has been added to your repositories
  5. $ helm repo list
  6. NAME URL
  7. stable https://cnych.github.io/kube-charts-mirror/
  8. local http://127.0.0.1:8879/charts
  9. $ helm repo update
  10. Hang tight while we grab the latest from your chart repositories...
  11. ...Skip local chart repository
  12. ...Successfully got an update from the "stable" chart repository
  13. Update Complete. Happy Helming!⎈

仓库添加完成后,可以使用 update 命令进行仓库更新。当然如果要我们自己来创建一个 web 服务器来服务 Helm Chart 的话,只需要实现下面几个功能点就可以提供服务了:

  • 将索引和Chart置于服务器目录中
  • 确保索引文件index.yaml可以在没有认证要求的情况下访问
  • 确保 yaml 文件的正确内容类型(text/yaml 或 text/x-yaml)

如果你的 web 服务提供了上面几个功能,那么也就可以当做 Helm Chart 仓库来使用了。

查找 chart

Helm 将 Charts 包安装到 Kubernetes 集群中,一个安装实例就是一个新的 Release,要找到新的 Chart,我们可以通过搜索命令完成。

记住,如果不能科学上网,将默认的 stable 的仓库地址更换成上面我们创建的地址

直接运行helm search命令可以查看有哪些 Charts 是可用的:

  1. $ helm search
  2. NAME CHART VERSION APP VERSION DESCRIPTION
  3. ...
  4. stable/minio 1.6.3 RELEASE.2018-08-25T01-56-38Z Minio is a high performance distributed object storage se...
  5. stable/mission-control 0.4.2 3.1.2 A Helm chart for JFrog Mission Control
  6. stable/mongodb 4.2.2 4.0.2 NoSQL document-oriented database that stores JSON-like do...
  7. stable/mongodb-replicaset 3.5.6 3.6 NoSQL document-oriented database that stores JSON-like do...
  8. ...
  9. stable/zetcd 0.1.9 0.0.3 CoreOS zetcd Helm chart for Kubernetes
  10. ...

如果没有使用过滤条件,helm search 显示所有可用的 charts。可以通过使用过滤条件进行搜索来缩小搜索的结果范围:

  1. $ helm search mysql
  2. NAME CHART VERSION APP VERSION DESCRIPTION
  3. ...
  4. stable/mysql 0.10.1 5.7.14 Fast, reliable, scalable, and easy to use open-source rel...
  5. stable/mysqldump 0.1.0 5.7.21 A Helm chart to help backup MySQL databases using mysqldump
  6. stable/prometheus-mysql-exporter 0.1.0 v0.10.0 A Helm chart for prometheus
  7. stable/mariadb 4.4.0 10.1.35 Fast, reliable, scalable, and easy to use open-source rel...
  8. ...

可以看到明显少了很多 charts 了,同样的,我们可以使用 inspect 命令来查看一个 chart 的详细信息:

  1. $ helm inspect stable/mysql
  2. appVersion: 5.7.14
  3. description: Fast, reliable, scalable, and easy to use open-source relational database
  4. system.
  5. engine: gotpl
  6. home: https://www.mysql.com/
  7. icon: https://www.mysql.com/common/logos/logo-mysql-170x115.png
  8. keywords:
  9. - mysql
  10. - database
  11. - sql
  12. maintainers:
  13. - email: o.with@sportradar.com
  14. name: olemarkus
  15. - email: viglesias@google.com
  16. name: viglesiasce
  17. name: mysql
  18. sources:
  19. - https://github.com/kubernetes/charts
  20. - https://github.com/docker-library/mysql
  21. version: 0.10.1
  22. ---
  23. ## mysql image version
  24. ## ref: https://hub.docker.com/r/library/mysql/tags/
  25. ##
  26. image: "mysql"
  27. imageTag: "5.7.14"
  28. ...

使用 inspect 命令可以查看到该 chart 里面所有描述信息,包括运行方式、配置信息等等。

通过 helm search 命令可以找到我们想要的 chart 包,找到后就可以通过 helm install 命令来进行安装了。

安装 chart

要安装新的软件包,直接使用 helm install 命令即可。最简单的情况下,它只需要一个 chart 的名称参数:

  1. $ helm install stable/mysql
  2. NAME: mewing-squid
  3. LAST DEPLOYED: Tue Sep 4 23:31:23 2018
  4. NAMESPACE: default
  5. STATUS: DEPLOYED
  6. RESOURCES:
  7. ==> v1/PersistentVolumeClaim
  8. NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
  9. mewing-squid-mysql Pending 1s
  10. ==> v1/Service
  11. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  12. mewing-squid-mysql ClusterIP 10.108.197.48 <none> 3306/TCP 1s
  13. ==> v1beta1/Deployment
  14. NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
  15. mewing-squid-mysql 1 0 0 0 1s
  16. ==> v1/Pod(related)
  17. NAME READY STATUS RESTARTS AGE
  18. mewing-squid-mysql-69f587bdf9-z7glv 0/1 Pending 0 0s
  19. ==> v1/Secret
  20. NAME TYPE DATA AGE
  21. mewing-squid-mysql Opaque 2 1s
  22. ==> v1/ConfigMap
  23. NAME DATA AGE
  24. mewing-squid-mysql-test 1 1s
  25. NOTES:
  26. MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
  27. mewing-squid-mysql.default.svc.cluster.local
  28. To get your root password run:
  29. MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace default mewing-squid-mysql -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echo)
  30. To connect to your database:
  31. 1. Run an Ubuntu pod that you can use as a client:
  32. kubectl run -i --tty ubuntu --image=ubuntu:16.04 --restart=Never -- bash -il
  33. 2. Install the mysql client:
  34. $ apt-get update && apt-get install mysql-client -y
  35. 3. Connect using the mysql cli, then provide your password:
  36. $ mysql -h mewing-squid-mysql -p
  37. To connect to your database directly from outside the K8s cluster:
  38. MYSQL_HOST=127.0.0.1
  39. MYSQL_PORT=3306
  40. # Execute the following command to route the connection:
  41. kubectl port-forward svc/mewing-squid-mysql 3306
  42. mysql -h ${MYSQL_HOST} -P${MYSQL_PORT} -u root -p${MYSQL_ROOT_PASSWORD}

现在 mysql chart 已经安装上了,安装 chart 会创建一个新 release 对象。上面的 release 被命名为 hmewing-squid。如果你想使用你自己的 release 名称,只需使用--name参数指定即可,比如:

  1. $ helm install stable/mysql --name mydb

在安装过程中,helm 客户端将打印有关创建哪些资源的有用信息,release 的状态以及其他有用的配置信息,比如这里的有访问 mysql 服务的方法、获取 root 用户的密码以及连接 mysql 的方法等信息。

值得注意的是 Helm 并不会一直等到所有资源都运行才退出。因为很多 charts 需要的镜像资源非常大,所以可能需要很长时间才能安装到集群中去。

要跟踪 release 状态或重新读取配置信息,可以使用 helm status 查看:

  1. $ helm status mewing-squid
  2. LAST DEPLOYED: Tue Sep 4 23:31:23 2018
  3. NAMESPACE: default
  4. STATUS: DEPLOYED
  5. RESOURCES:
  6. ...

可以看到当前 release 的状态是DEPLOYED,下面还有一些安装的时候出现的信息。

自定义 chart

上面的安装方式是使用 chart 的默认配置选项。但是在很多时候,我们都需要自定义 chart 以满足自身的需求,要自定义 chart,我们就需要知道我们使用的 chart 支持的可配置选项才行。

要查看 chart 上可配置的选项,使用helm inspect values命令即可,比如我们这里查看上面的 mysql 的配置选项:

  1. $ helm inspect values stable/mysql
  2. ## mysql image version
  3. ## ref: https://hub.docker.com/r/library/mysql/tags/
  4. ##
  5. image: "mysql"
  6. imageTag: "5.7.14"
  7. ## Specify password for root user
  8. ##
  9. ## Default: random 10 character string
  10. # mysqlRootPassword: testing
  11. ## Create a database user
  12. ##
  13. # mysqlUser:
  14. ## Default: random 10 character string
  15. # mysqlPassword:
  16. ## Allow unauthenticated access, uncomment to enable
  17. ##
  18. # mysqlAllowEmptyPassword: true
  19. ## Create a database
  20. ##
  21. # mysqlDatabase:
  22. ## Specify an imagePullPolicy (Required)
  23. ## It's recommended to change this to 'Always' if the image tag is 'latest'
  24. ## ref: http://kubernetes.io/docs/user-guide/images/#updating-images
  25. ##
  26. imagePullPolicy: IfNotPresent
  27. extraVolumes: |
  28. # - name: extras
  29. # emptyDir: {}
  30. extraVolumeMounts: |
  31. # - name: extras
  32. # mountPath: /usr/share/extras
  33. # readOnly: true
  34. extraInitContainers: |
  35. # - name: do-something
  36. # image: busybox
  37. # command: ['do', 'something']
  38. # Optionally specify an array of imagePullSecrets.
  39. # Secrets must be manually created in the namespace.
  40. # ref: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
  41. # imagePullSecrets:
  42. # - name: myRegistryKeySecretName
  43. ## Node selector
  44. ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
  45. nodeSelector: {}
  46. livenessProbe:
  47. initialDelaySeconds: 30
  48. periodSeconds: 10
  49. timeoutSeconds: 5
  50. successThreshold: 1
  51. failureThreshold: 3
  52. readinessProbe:
  53. initialDelaySeconds: 5
  54. periodSeconds: 10
  55. timeoutSeconds: 1
  56. successThreshold: 1
  57. failureThreshold: 3
  58. ## Persist data to a persistent volume
  59. persistence:
  60. enabled: true
  61. ## database data Persistent Volume Storage Class
  62. ## If defined, storageClassName: <storageClass>
  63. ## If set to "-", storageClassName: "", which disables dynamic provisioning
  64. ## If undefined (the default) or set to null, no storageClassName spec is
  65. ## set, choosing the default provisioner. (gp2 on AWS, standard on
  66. ## GKE, AWS & OpenStack)
  67. ##
  68. # storageClass: "-"
  69. accessMode: ReadWriteOnce
  70. size: 8Gi
  71. annotations: {}
  72. ## Configure resource requests and limits
  73. ## ref: http://kubernetes.io/docs/user-guide/compute-resources/
  74. ##
  75. resources:
  76. requests:
  77. memory: 256Mi
  78. cpu: 100m
  79. # Custom mysql configuration files used to override default mysql settings
  80. configurationFiles: {}
  81. # mysql.cnf: |-
  82. # [mysqld]
  83. # skip-name-resolve
  84. # ssl-ca=/ssl/ca.pem
  85. # ssl-cert=/ssl/server-cert.pem
  86. # ssl-key=/ssl/server-key.pem
  87. # Custom mysql init SQL files used to initialize the database
  88. initializationFiles: {}
  89. # first-db.sql: |-
  90. # CREATE DATABASE IF NOT EXISTS first DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
  91. # second-db.sql: |-
  92. # CREATE DATABASE IF NOT EXISTS second DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
  93. metrics:
  94. enabled: false
  95. image: prom/mysqld-exporter
  96. imageTag: v0.10.0
  97. imagePullPolicy: IfNotPresent
  98. resources: {}
  99. annotations: {}
  100. # prometheus.io/scrape: "true"
  101. # prometheus.io/port: "9104"
  102. livenessProbe:
  103. initialDelaySeconds: 15
  104. timeoutSeconds: 5
  105. readinessProbe:
  106. initialDelaySeconds: 5
  107. timeoutSeconds: 1
  108. ## Configure the service
  109. ## ref: http://kubernetes.io/docs/user-guide/services/
  110. service:
  111. ## Specify a service type
  112. ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services---service-types
  113. type: ClusterIP
  114. port: 3306
  115. # nodePort: 32000
  116. ssl:
  117. enabled: false
  118. secret: mysql-ssl-certs
  119. certificates:
  120. # - name: mysql-ssl-certs
  121. # ca: |-
  122. # -----BEGIN CERTIFICATE-----
  123. # ...
  124. # -----END CERTIFICATE-----
  125. # cert: |-
  126. # -----BEGIN CERTIFICATE-----
  127. # ...
  128. # -----END CERTIFICATE-----
  129. # key: |-
  130. # -----BEGIN RSA PRIVATE KEY-----
  131. # ...
  132. # -----END RSA PRIVATE KEY-----
  133. ## Populates the 'TZ' system timezone environment variable
  134. ## ref: https://dev.mysql.com/doc/refman/5.7/en/time-zone-support.html
  135. ##
  136. ## Default: nil (mysql will use image's default timezone, normally UTC)
  137. ## Example: 'Australia/Sydney'
  138. # timezone:
  139. # To be added to the database server pod(s)
  140. podAnnotations: {}

然后,我们可以直接在 YAML 格式的文件中来覆盖上面的任何配置,在安装的时候直接使用该配置文件即可:(config.yaml)

  1. mysqlUser: haimaxyUser
  2. mysqlDatabase: haimaxyDB
  3. service:
  4. type: NodePort

我们这里通过 config.yaml 文件定义了 mysqlUser 和 mysqlDatabase,并且把 service 的类型更改为了 NodePort,然后现在我们来安装的时候直接指定该 yaml 文件:

  1. $ helm install -f config.yaml stable/mysql --name mydb
  2. NAME: mydb
  3. LAST DEPLOYED: Wed Sep 5 00:09:44 2018
  4. NAMESPACE: default
  5. STATUS: DEPLOYED
  6. RESOURCES:
  7. ==> v1/Secret
  8. NAME TYPE DATA AGE
  9. mydb-mysql Opaque 2 1s
  10. ==> v1/ConfigMap
  11. NAME DATA AGE
  12. mydb-mysql-test 1 1s
  13. ==> v1/PersistentVolumeClaim
  14. NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
  15. mydb-mysql Pending 1s
  16. ==> v1/Service
  17. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  18. mydb-mysql NodePort 10.96.150.198 <none> 3306:32604/TCP 0s
  19. ==> v1beta1/Deployment
  20. NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
  21. mydb-mysql 1 1 1 0 0s
  22. ==> v1/Pod(related)
  23. NAME READY STATUS RESTARTS AGE
  24. mydb-mysql-dfc999888-hbw5d 0/1 Pending 0 0s
  25. ...

我们可以看到当前 release 的名字已经变成 mydb 了。然后可以查看下 mydb 关联的 Service 是否变成 NodePort 类型的了:

  1. $ kubectl get svc
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 110d
  4. mewing-squid-mysql ClusterIP 10.108.197.48 <none> 3306/TCP 46m
  5. mydb-mysql NodePort 10.96.150.198 <none> 3306:32604/TCP 8m

看到服务 mydb-mysql 变成了 NodePort 类型的,二之前默认创建的 mewing-squid-mysql 是 ClusterIP 类型的,证明上面我们通过 YAML 文件来覆盖 values 是成功的。

接下来我们查看下 Pod 的状况:

  1. $ kubectl get pods
  2. NAME READY STATUS RESTARTS AGE
  3. mewing-squid-mysql-69f587bdf9-z7glv 0/1 Pending 0 49m
  4. mydb-mysql-dfc999888-hbw5d 0/1 Pending 0 11m

比较奇怪的是之前默认创建的和现在的 mydb 的 release 创建的 Pod 都是 Pending 状态,直接使用 describe 命令查看下:

  1. $ kubectl describe pod mydb-mysql-dfc999888-hbw5d
  2. Name: mydb-mysql-dfc999888-hbw5d
  3. Namespace: default
  4. Node: <none>
  5. Labels: app=mydb-mysql
  6. pod-template-hash=897555444
  7. ...
  8. Events:
  9. Type Reason Age From Message
  10. ---- ------ ---- ---- -------
  11. Warning FailedScheduling 2m (x37 over 12m) default-scheduler pod has unbound PersistentVolumeClaims (repeated 2 times)

我们可以发现两个 Pod 处于 Pending 状态的原因都是 PVC 没有被绑定上,所以这里我们可以通过 storageclass 或者手动创建一个合适的 PV 对象来解决这个问题。

另外为了说明 helm 更新的用法,我们这里来直接禁用掉数据持久化,可以在上面的 config.yaml 文件中设置:

  1. persistence:
  2. enabled: false

另外一种方法就是在安装过程中使用--set来覆盖对应的 value 值,比如禁用数据持久化,我们这里可以这样来覆盖:

  1. $ helm install stable/mysql --set persistence.enabled=false --name mydb

升级

我们这里将数据持久化禁用掉来对上面的 mydb 进行升级:

  1. $ echo config.yaml
  2. mysqlUser: haimaxyUser
  3. mysqlDatabase: haimaxyDB
  4. service:
  5. type: NodePort
  6. persistence:
  7. enabled: false
  8. $ helm upgrade -f config.yaml mydb stable/mysql
  9. helm upgrade -f config.yaml mydb stable/mysql
  10. Release "mydb" has been upgraded. Happy Helming!
  11. LAST DEPLOYED: Wed Sep 5 00:38:33 2018
  12. NAMESPACE: default
  13. STATUS: DEPLOYED
  14. RESOURCES:
  15. ...

可以看到已经变成 DEPLOYED 状态了,现在我们再去看看 Pod 的状态呢:

  1. $ kubectl get pods
  2. NAME READY STATUS RESTARTS AGE
  3. mewing-squid-mysql-69f587bdf9-z7glv 0/1 Pending 0 1h
  4. mydb-mysql-6ffc84bbf6-lcn4d 0/1 PodInitializing 0 49s
  5. ...

我们看到 mydb 关联的 Pod 已经变成了 PodInitializing 的状态,已经不是 Pending 状态了,同样的,使用 describe 命令查看:

  1. $ kubectl describe pod mydb-mysql-6ffc84bbf6-lcn4d
  2. Name: mydb-mysql-6ffc84bbf6-lcn4d
  3. Namespace: default
  4. Node: node02/10.151.30.63
  5. Start Time: Wed, 05 Sep 2018 00:38:33 +0800
  6. Labels: app=mydb-mysql
  7. pod-template-hash=2997406692
  8. Annotations: <none>
  9. Status: Pending
  10. ...
  11. Events:
  12. Type Reason Age From Message
  13. ---- ------ ---- ---- -------
  14. Normal SuccessfulMountVolume 58s kubelet, node02 MountVolume.SetUp succeeded for volume "data"
  15. Normal SuccessfulMountVolume 58s kubelet, node02 MountVolume.SetUp succeeded for volume "default-token-n9w2d"
  16. Normal Scheduled 57s default-scheduler Successfully assigned mydb-mysql-6ffc84bbf6-lcn4d to node02
  17. Normal Pulling 57s kubelet, node02 pulling image "busybox:1.25.0"
  18. Normal Pulled 45s kubelet, node02 Successfully pulled image "busybox:1.25.0"
  19. Normal Created 44s kubelet, node02 Created container
  20. Normal Started 44s kubelet, node02 Started container
  21. Normal Pulling 41s kubelet, node02 pulling image "mysql:5.7.14"

我们可以看到现在没有任何关于 PVC 的错误信息了,这是因为我们刚刚更新的版本中就是禁用掉了的数据持久化的,证明 helm upgrade 和 —values 是生效了的。现在我们使用 helm ls 命令查看先当前的 release:

  1. $ helm ls
  2. NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
  3. mewing-squid 1 Tue Sep 4 23:31:23 2018 DEPLOYED mysql-0.10.1 5.7.14 default
  4. mydb 2 Wed Sep 5 00:38:33 2018 DEPLOYED mysql-0.10.1 5.7.14 default

可以看到 mydb 这个 release 的REVISION已经变成2了,这是因为 release 的版本是递增的,每次安装、升级或者回滚,版本号都会加1,第一个版本号始终为1,同样我们可以使用 helm history 命令查看 release 的历史版本:

  1. $ helm history mydb
  2. REVISION UPDATED STATUS CHART DESCRIPTION
  3. 1 Wed Sep 5 00:09:44 2018 SUPERSEDED mysql-0.10.1 Install complete
  4. 2 Wed Sep 5 00:38:33 2018 DEPLOYED mysql-0.10.1 Upgrade complete

当然如果我们要回滚到某一个版本的话,使用 helm rollback 命令即可,比如我们将 mydb 回滚到上一个版本:

  1. $ $ helm rollback mydb 1

删除

上节课我们就学习了要删除一个 release 直接使用 helm delete 命令就 OK:

  1. $ helm delete mewing-squid
  2. release "mewing-squid" deleted

这将从集群中删除该 release,但是这并不代表就完全删除了,我们还可以通过--deleted参数来显示被删除掉 release:

  1. $ helm list --deleted
  2. NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
  3. mewing-squid 1 Tue Sep 4 23:31:23 2018 DELETED mysql-0.10.1 5.7.14 default
  4. $ helm list --all
  5. NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
  6. mewing-squid 1 Tue Sep 4 23:31:23 2018 DELETED mysql-0.10.1 5.7.14 default
  7. mydb 2 Wed Sep 5 00:38:33 2018 DEPLOYED mysql-0.10.1 5.7.14 default

helm list --all则会显示所有的 release,包括已经被删除的

由于 Helm 保留已删除 release 的记录,因此不能重新使用 release 名称。(如果 确实 需要重新使用此 release 名称,则可以使用此 —replace 参数,但它只会重用现有 release 并替换其资源。)这点是不是和 docker container 的管理比较类似

请注意,因为 release 以这种方式保存,所以可以回滚已删除的资源并重新激活它。

如果要彻底删除 release,则需要加上--purge参数:

  1. $ helm delete mewing-squid --purge
  2. release "mewing-squid" deleted

我们这里只是讲到了 Helm 的一些常用的方法,更多用法我们将在后面的课程中和大家接触到。


点击查看本文视频

扫描下面的二维码(或微信搜索k8s技术圈)关注我们的微信公众帐号,在微信公众帐号中回复 加群 即可加入到我们的 kubernetes 讨论群里面共同学习。

k8s技术圈二维码