关键点

  • initContainers
  • Job

Job

k8s job模块的功能是执行任务,在部署过程中有两个特性需要了解,分别是:

  • 初始化操作:确保任务|脚本|SQL等可定制化的任务成功执行一次
  • 依赖检测
  • 执行完后任务即可消失

常常被用来执行初始化任务和定时任务,比如mysql表结构和数据SQL文件的导入。

helm chart values.yaml配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
jobs:
  chroots:
    enabled: false
    activeDeadlineSeconds: 3600
    backoffLimit: 500
    completions: 1
    zkimage: "mysqlinit:latest"
    parallelism: 1
    resources: {}
    restartPolicy: OnFailure
    config:
      create: []
      # - /zk
    env: []
    command:
      - sh
      - -exc
      - |
        mysql -uroot -psystem -P 3306 -h mysql test --default-character-set=utf8 < /tmp/ddl.sql && \
        mysql -uroot -psystem -P 3306 -h mysql test --default-character-set=utf8 < /tmp/dml.sql

helm chart template

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
{{- if .Values.jobs.chroots.enabled }}
{{- $root := . }}
{{- $job := .Values.jobs.chroots }}
apiVersion: batch/v1
kind: Job
metadata:
  name: {{ template "zookeeper.chroots" . }}
  annotations:
    "helm.sh/hook": post-install,post-upgrade
    "helm.sh/hook-weight": "-5"
    "helm.sh/hook-delete-policy": hook-succeeded
  labels:
    app: {{ template "zookeeper.name" . }}
    chart: {{ template "zookeeper.chart" . }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
    component: jobs
    job: chroots
spec:
  backoffLimit: {{ $job.backoffLimit }}
  completions: {{ $job.completions }}
  parallelism: {{ $job.parallelism }}
  template:
    metadata:
      labels:
        app: {{ template "zookeeper.name" . }}
        release: {{ .Release.Name }}
        component: jobs
        job: chroots
    spec:
      restartPolicy: {{ $job.restartPolicy }}
{{- if .Values.priorityClassName }}
      priorityClassName: "{{ .Values.priorityClassName }}"
{{- end }}
      imagePullSecrets: 
        - name: soso
      containers:
        - name: main
          image: "{{ $job.zkimage }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          {{- with $job.command }}
          command:
            {{- toYaml . | nindent 12 }}
          {{- end }}
          env:
          {{- with $job.env }}
            {{- toYaml . | nindent 12 }}
          {{- end }}
          resources:
{{ toYaml $job.resources | indent 12 }}
{{- end -}}

完整job yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# Source: $project/templates/job-chroots.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: "init-mysql" 
  annotations:
    "helm.sh/hook": post-install,post-upgrade
    "helm.sh/hook-weight": "-5"
    "helm.sh/hook-delete-policy": hook-succeeded
  labels:
    app: "init-mysql" 
    release: RELEASE-NAME
    heritage: Helm
    component: jobs
    job: chroots
spec:
  backoffLimit: 500
  completions: 1
  parallelism: 1
  template:
    metadata:
      labels:
        app: "init-mysql" 
        release: RELEASE-NAME
        component: jobs
        job: chroots
    spec:
      restartPolicy: OnFailure
      imagePullSecrets: 
        - name: something
      containers:
        - name: main
          image: "mysql:5.7"
          imagePullPolicy: IfNotPresent
          command:
            - sh
            - -exc
            - |
               mysql -uroot -psystem -P 3306 -h mysql test --default-character-set=utf8 < /tmp/ddl.sql && \
               mysql -uroot -psystem -P 3306 -h mysql test --default-character-set=utf8 < /tmp/dml.sql
          env:
          resources:
            {}

initContainers

initContainers是一种专用的容器,在应用程序容器启动之前运行,可以包括一些应用程序镜像中不存在的实用工具和安装脚本,可以完成应用的必要数据初始化等工作。总的来说就是在正式的容器启动之前做一些准备工作的。

  • 依赖检测
  • 初始化任务

我在这里是用来设置依赖启动的,目的是服务等3306的mysql和6379的redis启动完毕正常可访问以后再启动。

helm chart values.yaml配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
configJson: '{key:value}'
ns: default
app:
  name: "apps"
  replicaCount: 1
  log:
    name: "app-logs"
    path: "/logs" # 加载路径
    logpath: "/logs/*.log" # 日志路径正则
    appname: "app"
  imagePullSecrets: 
    - name: soso
  env:
    - name: "mysql.port"
      value: "3306"
    - name: "redis.port"
      value: "6379"
  # nodeSelector:
  #   kubernetes.io/role: node
  image: 
    repository: "nginx"
    tags: "latest"
    pullPolicy: "Always"
  port:
    - name: http
      containerPort: 80
      protocol: TCP
  resources:
    limits:
      cpu: "1"
      memory: 2Gi
    requests:
      cpu: "1"
      memory: 2Gi
  service:
    name: "apps"
    type: "NodePort"
    ports:
      - name: http
        protocol: TCP
        port: 80
        targetPort: 80
        nodePort: 8088
  initContainers:
  - name: init-mysql
    image: busybox
    command: ['sh', '-c']
    args:
    - echo Prepare to mysql initialize..;
      until nc -w 1 -z mysql 3306;
      do echo Waiting for mysql initialization to complete..; sleep 10; done;
      echo mysql Initialization successful!;
   - name: init-redis
    image: busybox
    command: ['sh', '-c']
    args:
    - echo Prepare to reids initialize..;
      until nc -w 1 -z redis 6379;
      do echo Waiting for redis initialization to complete..; sleep 10; done;
      echo redis Initialization successful!;

helm chart template

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
{{- $namespaces := .Values.ns -}}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Values.apps.name }}
  labels:
    app: {{ .Values.apps.name }}
spec:
  replicas: {{ .Values.apps.replicaCount }}
  selector:
    matchLabels:
      app: {{ .Values.apps.name }}
  template:
    metadata:
      labels:
        app: {{ .Values.apps.name }}
    spec:
      {{- with .Values.apps.initContainers }}
      initContainers:
      {{- toYaml . | nindent 6 }}
      {{- end }}
      containers:
      - name: {{ .Values.apps.name }}
        image: "{{ .Values.apps.image.repository }}:{{ .Values.apps.image.tags }}"
        imagePullPolicy: {{ .Values.apps.image.pullPolicy }}
        env:
        - name: SPRING_APPLICATION_JSON
          value: '{{ $configJson }}'
        {{- with .Values.apps.env }}
        {{- toYaml . | nindent 8 }}
        {{- end }}
        {{ if .Values.apps.log }}
        volumeMounts:
        - mountPath: {{ .Values.apps.log.path }}
          name: {{ .Values.apps.log.name }}
          readOnly: false
        {{ end }}
        {{- with .Values.apps.port }}
        ports:
          {{- toYaml . | nindent  8 }}
        {{- end}}
        {{- with .Values.apps.resources }}
        resources:
          {{- toYaml . | nindent 9 }}
        {{- end }}
      {{ if .Values.apps.log }}
      volumes:
      - name: {{ .Values.apps.log.name }}
        emptyDir: {}
      {{ end }}
      {{- with .Values.apps.imagePullSecrets }}
      imagePullSecrets:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.apps.nodeSelector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .network }}
      hostNetwork: {{ .value }}
      {{- end }}
      {{- with .dnsPolicy }}
      dnsPolicy: {{ .value }}
      {{- end }}

最终生成deployment yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# Source: cwos-mid/templates/multi-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: apps
  labels:
    app: apps
spec:
  replicas: 1
  selector:
    matchLabels:
      app: apps
  template:
    metadata:
      labels:
        app: apps
    spec:
      initContainers:
      - args:
        - echo Prepare to mysql initialize..; until nc -w 1 -z mysql 3306; do echo
          Waiting for mysql initialization to complete..; sleep 10; done; echo mysql Initialization
          successful!;
        command:
        - sh
        - -c
        image: busybox
        name: init-mysql
      - args:
        - echo Prepare to redis initialize..; until nc -w 1 -z redis 6379; do echo
          Waiting for redis initialization to complete..; sleep 10; done; echo redis Initialization
          successful!;
        command:
        - sh
        - -c
        image: busybox
        name: init-redis
      containers:
      - name: apps
        image: "nginx:latest"
        imagePullPolicy: Always
        env:
        - name: "mysql.port"
          value: "3306"
        - name: "redis.port"
          value: "6379"
        
        volumeMounts:
        - mountPath: /logs
          name: app-logs
          readOnly: false
        
        ports:
        - containerPort: 80
          name: http
          protocol: TCP
        resources:
         limits:
           cpu: "1"
           memory: 2Gi
         requests:
           cpu: "1"
           memory: 2Gi
      
      volumes:
      - name: app-logs
        emptyDir: {}
      
      imagePullSecrets:
        - name: soso