一、安裝Helm
helm教程以及安裝可以參考這篇文章
二、Heml說明
常見的helm模板如下
myapp - chart 包目錄名 ├── charts - 依賴的子包目錄,里面可以包含多個依賴的chart包 ├── Chart.yaml - chart定義,可以定義chart的名字,版本號信息。 ├── templates - k8s配置模版目錄, 我們編寫的k8s配置都在這個目錄, 除了NOTES.txt和下划線開頭命名的文件,其他文件可以隨意命名。 │ ├── deployment.yaml │ ├── _helpers.tpl - 下划線開頭的文件,helm視為公共庫定義文件,主要用於定義通用的子模版、函數等,helm不會將這些公共庫文件的渲染結果提交給k8s處理。 │ ├── ingress.yaml │ ├── NOTES.txt - chart包的幫助信息文件,執行helm install命令安裝成功后會輸出這個文件的內容。 │ └── service.yaml └── values.yaml - chart包的參數配置文件,模版可以引用這里參數。
其中 values.yaml 就是存放你變量的地方,這些變量可以應用在其他的 .yaml 文件中進行引用,類似於環境變量,引用方式:
{{ .Values.xxxxx }}
values.yaml文件如下:
# Default values for helm. # This is a YAML-formatted file. # Declare variables to be passed into your templates. name: Aeisen
三、數據卷Volume、數據卷聲明VolumeClaim
k8s應用(包括有狀態跟無狀態應用),需要使用數據卷的話,需要在存儲卷中進行設置和聲明,下面列出持久化數據卷的聲明跟設置的模板:
數據卷設置:
apiVersion: v1 kind: PersistentVolume -這里說明是持久化數據卷 metadata: finalizers: - kubernetes.io/pv-protection labels: alicloud-pvname: {{ .Values.volumes.name }} -數據卷標簽,eg:XXX-data name: {{ .Values.volumes.name }} -數據卷名稱,eg:XXX-data spec: accessModes: - ReadWriteMany -權限 capacity: storage: {{ .Values.volumes.storage }} -容量大小,eg:10Gi flexVolume: driver: alicloud/nas -數據卷類型是nas options: path: {{ .Values.volumes.path }} -數據卷路徑,eg:/tmp server: {{ .Values.volumes.server }} -數據卷服務商,eg:xxxxx.nas.aliyuncs.com vers: '3' persistentVolumeReclaimPolicy: Retain storageClassName: nas
數據卷聲明:
apiVersion: v1 kind: PersistentVolumeClaim -持久化數據卷聲明 metadata: annotations: pv.kubernetes.io/bind-completed: 'yes' pv.kubernetes.io/bound-by-controller: 'yes' finalizers: - kubernetes.io/pvc-protection name: {{ .Values.volumes.name }} spec: accessModes: - ReadWriteMany resources: requests: storage: {{ .Values.volumes.storage }} -容量,eg:10Gi selector: matchLabels: alicloud-pvname: {{ .Values.volumes.name }} storageClassName: nas volumeName: {{ .Values.volumes.name }}
四、伸縮配置 HorizontalPodAutoscaler
應用彈性伸縮配置,這個可以配置最大、最小副本集跟伸縮條件的參數到values.yaml文件里面
kind: HorizontalPodAutoscaler apiVersion: autoscaling/v1 metadata: name: {{ include "admin.appname" . }}-hpa -admin.appname就是后面執行helm命令的時候倒數第二個參數,為什么前面是admin呢,admin就是你配置Chart.yaml的時候里面的name變量的值 spec: scaleTargetRef: kind: Deployment name: {{ include "admin.appname" . }} apiVersion: apps/v1beta2 minReplicas: 1 -最小副本集 maxReplicas: 10 -最大副本集 targetCPUUtilizationPercentage: 70 -伸縮條件
五、配置項ConfigMap
配置項設置,一般每個項目有都對應的環境參數,比如:數據庫、redis等這些賬號密碼類的參數,這些可以抽離出來當成一個配置項處理
apiVersion: v1 kind: ConfigMap metadata: name: {{ .Values.envConfigName }} -每個環境就配置一個配置項 data: {{- range $k, $v := .Values.configDatas }} -這里是循環遍歷configDatas這個變量 {{ $k | indent 2 }}.php: >- -下面這兩行配置一個key->value的配置項(即文件名->文件內容) {{ $v | indent 4 }} {{- end -}}
六、鏡像密碼配置Secret
將鏡像的密碼配置到保密字典中
apiVersion: v1 kind: Secret metadata: name: image-secret -name隨意寫 data: .dockerconfigjson: {{ .Files.Get "image.pwd" | b64enc }} -內容 type: kubernetes.io/dockerconfigjson
TLs證書配置(后面配置ingress的時候要用到,不然無法用https)
apiVersion: v1 kind: Secret metadata: name: tls-secret data: tls.crt: {{ .Files.Get "XXXXX.com.pem" | b64enc }} tls.key: {{ .Files.Get "XXXXX.com.key" | b64enc }} type: Opaque
七、無狀態應用Deployment
apiVersion: apps/v1beta2 kind: Deployment -無狀態應用 metadata: name: {{ include "admin.appname" . }}-api-app -應用名稱 labels: app: {{ include "admin.appname" . }}-api-app -應用標簽 spec: replicas: {{ .Values.apiAppReplicaCount }} -副本集數,就是要開多少個應用 selector: matchLabels: app: {{ include "admin.appname" . }}-api-app -映射 template: metadata: labels: app: {{ include "admin.appname" . }}-api-app -映射標簽 release: {{ .Release.Revision | quote }} -版本號 spec: volumes: - configMap: defaultMode: 420 name: {{ .Values.configItemName }} -配置項名稱,這個是在上面配置項配置的時候的名稱 name: volume-{{ include "admin.appname" . }}-api-app -配置項名稱,這個是引入之后的別名 {{ if .Values.isDev -}} -開發環境多引入一個數據卷 - hostPath: path: {{ .Values.volumes.devWwwPath }} -數據卷位置 type: '' name: {{ .Values.volumes.devWwwName }} -數據卷名稱 {{- end }} imagePullSecrets: -鏡像密碼 - name: {{ .Values.image.imagePullSecrets }} dnsPolicy: ClusterFirst schedulerName: default-scheduler containers: - name: {{ include "admin.appname" . }}-api-app -容器名稱 image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" -鏡像地址跟標簽 command: - /scripts/start.sh -啟動腳本 volumeMounts: - mountPath: /alidata/config -配置項路徑 name: volume-{{ include "admin.appname" . }}-api-app -配置項名稱,跟上面的對應 {{ if .Values.isDev -}} -開發環境額外配置數據卷 - mountPath: {{ .Values.volumes.devWwwRealPath }} -引入的數據卷配置到容器哪個位置 name: {{ .Values.volumes.devWwwName }} -數據卷名稱 {{- end }} env: -配置環境變量 - name: ADMIN_CONSOLE_URL value: {{ .Values.consoleHost }} imagePullPolicy: Always -總是拉去鏡像 ports: - containerPort: 80 -暴露的端口 name: http -名字隨便取,不同端口的別一樣就行 protocol: TCP
- containerPort: 8080
name: http2
protocol: TCP strategy: -發布策略 type: RollingUpdate -滾動升級,下面是按什么比例滾動升級 rollingUpdate: maxUnavailable: 25% maxSurge: 25% livenessProbe: -存活檢測 failureThreshold: 3 initialDelaySeconds: 3 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 httpGet: path: / scheme: HTTP port: 80 readinessProbe: -就緒檢測 failureThreshold: 3 initialDelaySeconds: 3 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 httpGet: path: / scheme: HTTP port: 80 resources: -下面配置了資源限制,比如多少個cpu,多少內存等 {{ toYaml .Values.appResources | indent 12 }}
appResources配置可參考
#資源配置 apiAppResources: {} # 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
八、服務配置Service
服務配置,主要是跟應用暴露的端口進行綁定,一般應用也只會暴露80端口,提供新的端口給外部訪問,也可供路由Ingress訪問
apiVersion: v1 kind: Service metadata: name: {{ include "admin.appname" . }}-api-svc -名稱 spec: type: ClusterIP ports: - port: 80 -暴露的端口 targetPort: http -目標端口 protocol: TCP name: http
- port: 8080
targetPort: 8080
name: http2 selector: app: {{ include "admin.appname" . }}-api-app -綁定的無狀態應用
九、路由ingress
下面配置路由,主要跟上面配置的服務綁定,一般不讓服務直接暴露使用,這里多用了一層路由,主要是路由有負載跟灰度的作用,而且只提供一個IP(一般一個集群只有一個路由IP)
{{- if eq .Values.isRelease false -}} -非灰度環境就配置路由 apiVersion: extensions/v1beta1 kind: Ingress metadata: name: {{ include "admin.appname" . }}-api-ingress -路由名稱 annotations: nginx.ingress.kubernetes.io/service-weight: '' -權重之類的,這里筆者沒用到 nginx.ingress.kubernetes.io/ssl-redirect: 'false' -是否強制http跳https,true的話就強制跳 {{ if .Values.isProd -}} -這里是灰度判斷,如果帶有環境環境的cookie就把請求轉發到灰度環境的服務上 nginx.ingress.kubernetes.io/service-match: '{{ include "admin.release.appname" . }}-api-svc: cookie("admin_gray_tag", "release")' {{- end }} spec: tls: - hosts: - {{ .Values.apiHost }} -域名綁定 secretName: {{ .Values.hostTls }} -TLs配置 rules: - host: {{ .Values.apiHost }} -域名配置跳轉規則 http: paths: - path: / backend: serviceName: {{ include "admin.appname" . }}-api-svc -綁定的服務的名稱 servicePort: 80 {{ if .Values.isProd -}} - path: / backend: serviceName: {{ include "admin.release.appname" . }}-api-svc -綁定的灰度服務的名稱 servicePort: 80 {{- end }} {{- end -}}
十、結合Helm命令進行部署
Chart.yaml
apiVersion: v1 appVersion: "1.0" description: A Helm chart for Kubernetes name: admin version: 0.1.0
在 jenkins 的 shell 上使用 helm 命令部署k8s配置
APPNAME=admin
helm --kubeconfig k8s.conf upgrade -i \
--set-file configDatas.XXX=XXXX.txt \
--set apiAppResources.requests.cpu=1 \ ${APPNAME} ./chart
--kubeconfig:后面帶上k8s的配置,這里阿里雲的集群里面可以找到,有內網跟外網兩個,隨便用哪個都行
upgrade:表示升級,后面的 -i 表示沒有創建過的話就創建,有的話就更新
--set-file:這里主要是為了配置配置項跟數據字典索用到的,以文件的形式配置
--set:這個就比較重要了,我們在values.yaml里面的所有配置都可以用這個命令進行修改,用這個可以做到無環境化
倒數第二個參數:{{ include "admin.appname" . }} 上面的配置中多次用到了這種配置,倒數第二個參數就是這個的值,至於為什么簽名是admin,那就要看你Chart.yaml文件里面name是怎么取的了
最后一個參數:這個參數就是Chart.yaml文件的路徑
注意事項:
1、縮進問題,很多時候復制粘貼編譯器的縮進就亂了,導致后面配置有問題
2、文件命名問題,一般加上后綴好區分這個yaml文件是干嘛的,比如:應用的話加上-app,服務加上-svc,路由加上-ingress等,有上面好處呢,主要是同一套配置文件都在一起,方便管理,eg:
3、本文也可能存在不足,有錯誤的地方還請各位大佬多多指教