一、简单例子
我们创建一个Chart:
# helm create hello-helm
可以看到其目录结构如下:
[root@master helm]# tree hello-helm/
hello-helm/
├── charts
├── Chart.yaml
├── templates
│ ├── deployment.yaml
│ ├── _helpers.tpl
│ ├── ingress.yaml
│ ├── NOTES.txt
│ ├── service.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml
这是一个Nginx服务,我们修改其镜像(values.yaml):
...
replicaCount: 1
image:
repository: nginx
tag: 1.7.9
pullPolicy: IfNotPresent
...
然后安装这个Helm:
# helm install ./hello-helm/
NAME: winning-crab
LAST DEPLOYED: Wed Nov 6 14:36:45 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
winning-crab-hello-helm 0/1 0 0 0s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
winning-crab-hello-helm-6f59ffc587-x8lrs 0/1 Pending 0 0s
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
winning-crab-hello-helm ClusterIP 10.68.12.232 <none> 80/TCP 0s
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=hello-helm,app.kubernetes.io/instance=winning-crab" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80
这样就安装成功了,我们可以查看其Service和Pod:
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.68.0.1 <none> 443/TCP 62d
winning-crab-hello-helm ClusterIP 10.68.12.232 <none> 80/TCP 7m5s
# kubectl get pod
NAME READY STATUS RESTARTS AGE
winning-crab-hello-helm-6f59ffc587-x8lrs 1/1 Running 0 7m9s
查看release:
[root@master hello-helm]# helm list
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
winning-crab 1 Wed Nov 6 14:36:45 2019 DEPLOYED hello-helm-0.1.0 1.0 default
打包chart:
# helm package hello-helm
Successfully packaged chart and saved it to: /root/k8s/helm/hello-helm-0.1.0.tgz
然后我们就可以将打包的tgz文件分发到任意的服务器上,通过helm fetch就可以获取到该 Chart 了。
删除release:
# helm list
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
winning-crab 1 Wed Nov 6 14:36:45 2019 DEPLOYED hello-helm-0.1.0 1.0 default
# helm delete winning-crab
release "winning-crab" deleted
# helm list
#
二、常用操作
2.1、查找chart
命令:
# helm search
# helm search mysql
2.2、查看chart详情
命令:
# helm inspect stable/mysql
2.3、安装chart
命令:
# helm install stable/mysql
如果要自定义release名字使用如下命令:
# helm install stable/mysql --name mydb
2.4、查看release状态
# helm status mydb
2.5、自定义chart
首先通过helm inspect values命令来查看可配置选项。
如下:
# helm inspect values stable/mysql
## mysql image version
## ref: https://hub.docker.com/r/library/mysql/tags/
##
image: "mysql"
imageTag: "5.7.14"
busybox:
image: "busybox"
tag: "1.29.3"
testFramework:
image: "dduportal/bats"
tag: "0.4.0"
## Specify password for root user
##
## Default: random 10 character string
# mysqlRootPassword: testing
## Create a database user
##
# mysqlUser:
## Default: random 10 character string
# mysqlPassword:
## Allow unauthenticated access, uncomment to enable
##
# mysqlAllowEmptyPassword: true
## Create a database
##
# mysqlDatabase:
## Specify an imagePullPolicy (Required)
## It's recommended to change this to 'Always' if the image tag is 'latest'
## ref: http://kubernetes.io/docs/user-guide/images/#updating-images
##
imagePullPolicy: IfNotPresent
## Additionnal arguments that are passed to the MySQL container.
## For example use --default-authentication-plugin=mysql_native_password if older clients need to
## connect to a MySQL 8 instance.
args: []
extraVolumes: |
# - name: extras
# emptyDir: {}
extraVolumeMounts: |
# - name: extras
# mountPath: /usr/share/extras
# readOnly: true
extraInitContainers: |
# - name: do-something
# image: busybox
# command: ['do', 'something']
# Optionally specify an array of imagePullSecrets.
# Secrets must be manually created in the namespace.
# ref: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
# imagePullSecrets:
# - name: myRegistryKeySecretName
## Node selector
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
nodeSelector: {}
## Tolerations for pod assignment
## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
##
tolerations: []
livenessProbe:
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
readinessProbe:
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
## Persist data to a persistent volume
persistence:
enabled: true
## database data Persistent Volume Storage Class
## If defined, storageClassName: <storageClass>
## If set to "-", storageClassName: "", which disables dynamic provisioning
## If undefined (the default) or set to null, no storageClassName spec is
## set, choosing the default provisioner. (gp2 on AWS, standard on
## GKE, AWS & OpenStack)
##
# storageClass: "-"
accessMode: ReadWriteOnce
size: 8Gi
annotations: {}
## Use an alternate scheduler, e.g. "stork".
## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/
##
# schedulerName:
## Security context
securityContext:
enabled: false
runAsUser: 999
fsGroup: 999
## Configure resource requests and limits
## ref: http://kubernetes.io/docs/user-guide/compute-resources/
##
resources:
requests:
memory: 256Mi
cpu: 100m
# Custom mysql configuration files path
configurationFilesPath: /etc/mysql/conf.d/
# Custom mysql configuration files used to override default mysql settings
configurationFiles: {}
# mysql.cnf: |-
# [mysqld]
# skip-name-resolve
# ssl-ca=/ssl/ca.pem
# ssl-cert=/ssl/server-cert.pem
# ssl-key=/ssl/server-key.pem
# Custom mysql init SQL files used to initialize the database
initializationFiles: {}
# first-db.sql: |-
# CREATE DATABASE IF NOT EXISTS first DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
# second-db.sql: |-
# CREATE DATABASE IF NOT EXISTS second DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
metrics:
enabled: false
image: prom/mysqld-exporter
imageTag: v0.10.0
imagePullPolicy: IfNotPresent
resources: {}
annotations: {}
# prometheus.io/scrape: "true"
# prometheus.io/port: "9104"
livenessProbe:
initialDelaySeconds: 15
timeoutSeconds: 5
readinessProbe:
initialDelaySeconds: 5
timeoutSeconds: 1
flags: []
serviceMonitor:
enabled: false
additionalLabels: {}
## Configure the service
## ref: http://kubernetes.io/docs/user-guide/services/
service:
annotations: {}
## Specify a service type
## ref: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services---service-types
type: ClusterIP
port: 3306
# nodePort: 32000
# loadBalancerIP:
ssl:
enabled: false
secret: mysql-ssl-certs
certificates:
# - name: mysql-ssl-certs
# ca: |-
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
# cert: |-
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
# key: |-
# -----BEGIN RSA PRIVATE KEY-----
# ...
# -----END RSA PRIVATE KEY-----
## Populates the 'TZ' system timezone environment variable
## ref: https://dev.mysql.com/doc/refman/5.7/en/time-zone-support.html
##
## Default: nil (mysql will use image's default timezone, normally UTC)
## Example: 'Australia/Sydney'
# timezone:
# Deployment Annotations
deploymentAnnotations: {}
# To be added to the database server pod(s)
podAnnotations: {}
podLabels: {}
## Set pod priorityClassName
# priorityClassName: {}
## Init container resources defaults
initContainer:
resources:
requests:
memory: 10Mi
cpu: 10m
然后,我们可以直接在 YAML 格式的文件中来覆盖上面的任何配置,在安装的时候直接使用该配置文件即可:(config.yaml)
mysqlUser: unclejoker
mysqlDatabase: jokerDB
service:
type: NodePort
我们这里通过 config.yaml 文件定义了 mysqlUser 和 mysqlDatabase,并且把 service 的类型更改为了NodePort,然后现在我们来安装的时候直接指定该 yaml 文件:
# helm install -f config.yaml stable/mysql --name mydb
NAME: mydb
LAST DEPLOYED: Wed Nov 6 15:27:01 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/ConfigMap
NAME DATA AGE
mydb-mysql-test 1 1s
...
可以看到release的名字是我们定义的mydb:
# helm list
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
mydb 1 Wed Nov 6 15:27:01 2019 DEPLOYED mysql-1.3.1 5.7.14 default
其service也变成了我们config.yaml中定义的nodeport:
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.68.0.1 <none> 443/TCP 62d
mydb-mysql NodePort 10.68.108.76 <none> 3306:33158/TCP 83s
[root@master helm]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mydb-mysql-8d746574b-8b2n7 0/1 Pending 0 88s
而其中pod处于pending的状态原因如下:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 79s (x2 over 2m43s) default-scheduler pod has unbound immediate PersistentVolumeClaims (repeated 2 times)
我们可以发现两个 Pod 处于 Pending 状态的原因都是 PVC 没有被绑定上,所以这里我们可以通过 storageclass 或者手动创建一个合适的 PV 对象来解决这个问题。
2.6、升级
比如我们把上面的持久化禁用掉,改写config.yaml如下:
mysqlUser: unclejoker
mysqlDatabase: jokerDB
service:
type: NodePort
persistence:
enabled: false
然后执行以下命令:
# helm upgrade -f config.yaml mydb stable/mysql
Release "mydb" has been upgraded.
我们可以看到Pod的状态已经变了;
# kubectl get pod
NAME READY STATUS RESTARTS AGE
mydb-mysql-897fcbfcd-jv96j 0/1 PodInitializing 0 28s
其日志并不是PVC的问题了:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 67s default-scheduler Successfully assigned default/mydb-mysql-897fcbfcd-jv96j to 172.16.1.129
Normal Pulling 65s kubelet, 172.16.1.129 Pulling image "busybox:1.29.3"
Normal Pulled 46s kubelet, 172.16.1.129 Successfully pulled image "busybox:1.29.3"
Normal Created 46s kubelet, 172.16.1.129 Created container remove-lost-found
Normal Started 46s kubelet, 172.16.1.129 Started container remove-lost-found
Normal Pulling 45s kubelet, 172.16.1.129 Pulling image "mysql:5.7.14"
我们可以通过helm list查看release信息:
# helm list
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
mydb 2 Wed Nov 6 15:33:24 2019 DEPLOYED mysql-1.3.1 5.7.14 default
可以看到 mydb 这个 release 的REVISION已经变成2了,这是因为 release 的版本是递增的,每次安装、升级或者回滚,版本号都会加1,第一个版本号始终为1,同样我们可以使用 helm history 命令查看 release 的历史版本:
# helm history mydb
REVISION UPDATED STATUS CHART DESCRIPTION
1 Wed Nov 6 15:27:01 2019 SUPERSEDED mysql-1.3.1 Install complete
2 Wed Nov 6 15:33:24 2019 DEPLOYED mysql-1.3.1 Upgrade complete
2.7、回滚
命令如下:
# helm rollback mydb 1
2.8、删除
命令如下:
# helm delete mydb
这种删除并不会彻底删除,我们可以通过以下命令查看:
# helm list --all
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
mydb 2 Wed Nov 6 15:33:24 2019 DELETED mysql-1.3.1 5.7.14 default
winning-crab 1 Wed Nov 6 14:36:45 2019 DELETED hello-helm-0.1.0 1.0 default
如果要彻底删除需要加上—purge参数:
# helm delete mydb --purge