kubernetes -- helm charts 开发: 15、编写deployment

秦楚
2023-12-01

1 deployment基础
deployment内部使用Replica Set实现。
使用场景:
滚动升级和回滚,扩缩容等。

2 重要属性
2.1)滚动升级相关
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  ....
spec:
  strategy:
    rollingUpdate:
      maxSurge: 3
      maxUnavailable: 70%
    type: RollingUpdate
......
解释:
maxUnavailable:最大不可用数量。如果是3副本,3*70%=2.1向下取整就是2,
maxSurge: 指定可以超过期望的Pod数量的最大个数。
    该值可以是一个绝对值(例如5)或者是期望的Pod数量的百分比(例如10%)。当MaxUnavailable为0时该值不可以为0。通过百分比计算的绝对值向上取整。默认值是1。
    例如,该值设置成30%,启动rolling update后新的ReplicatSet将会立即扩容,新老Pod的总数不能超过期望的Pod数量的130%。

2.2)亲和性和反亲和性相关
PodAffinity: pod亲和与互斥调度策略
requiredDuringSchedulingIgnoredDuringExecution
作用:
限制pod所能运行的节点,根据节点本身的标签判断调和度。
原理:
在具有标签X的节点上运行1个或多个符合条件Y的pod,那么pod应该(
如果是互斥,就拒绝)运行在这个节点上。
X: 指集群中的节点,区域等,可通过节点标签中的key声明;
key的名字: topologyKey,表达节点所属的topology范围。
种类:
kubernetes.io/hostname
failure-domain.beta.kubernetes.io/zone
failure-domain.beta.kubernetes.io/region

pod属于命名空间,条件Y表达的是Label Selector。
pod亲和互斥的条件设置也是:
requiredDuringSchedulingIgnoredDuringExecution和
prefferedDuringSchedulingIgnoredDuringExecution。
pod亲和性定义与pod sepc的affinity字段的podAffinity子字段里。
pod的互斥性定义则定义于同一层次的podAntiAffinity子字段中。

查看ceilometer-api的反亲和性
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    application: ceilometer
    component: api
    release_group: ceilometer
  name: ceilometer-api
   ......
spec:
  template:
    metadata:
      labels:
        application: ceilometer
        component: api
        release_group: ceilometer
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: release_group
                operator: In
                values:
                - ceilometer
              - key: application
                operator: In
                values:
                - ceilometer
              - key: component
                operator: In
                values:
                - api
            topologyKey: kubernetes.io/hostname
......

解释:
Selector(选择器):
.spec.selector是可选字段,用来指定 label selector ,圈定Deployment管理的pod范围。
如果被指定, .spec.selector 必须匹配 .spec.template.metadata.labels,否则它将被API拒绝。
如果 .spec.selector 没有被指定, .spec.selector.matchLabels 默认是.spec.template.metadata.labels。

requiredDuringSchedulingIgnoredDuringExecution: 必须的规则,满足必须的规则的pod才会被调度到特定的Node上。
preferredDuringSchedulingIgnoredDuringExecution: 软约束,不一定满足。
topologyKey:调度时指定区域,如果用node标签实现,则指定为kubernetes.io/hostname。
IgnoredDuringExecution: 如果Node上的标签发生更改,并且反亲和性不再满足时会忽略。而不会在节点上驱逐不再匹配规则的pod。


参考:
https://blog.csdn.net/weixin_33994429/article/details/92837489
https://www.kubernetes.org.cn/1890.html
https://blog.csdn.net/tiger435/article/details/78489369

2 deployment样例
以ceilometer-api为例,deployment-api.yaml内容如下:
{{/*
Copyright 2017 The Openstack-Helm Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/}}

{{- if .Values.manifests.deployment_api }}
{{- $envAll := . }}
{{- $dependencies := .Values.dependencies.api }}
{{- $mounts_ceilometer_api := .Values.pod.mounts.ceilometer_api.ceilometer_api }}
{{- $mounts_ceilometer_api_init := .Values.pod.mounts.ceilometer_api.init_container }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ceilometer-api
spec:
  replicas: {{ .Values.pod.replicas.api }}
{{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }}
  selector:
    matchLabels:
{{ tuple $envAll "ceilometer" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }}
  template:
    metadata:
      labels:
{{ tuple $envAll "ceilometer" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }}
      annotations:
        configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }}
        configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }}
    spec:
      affinity:
{{ tuple $envAll "ceilometer" "api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }}
      nodeSelector:
        {{ .Values.labels.api.node_selector_key }}: {{ .Values.labels.api.node_selector_value }}
      terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.api.timeout | default "30" }}
      initContainers:
{{ tuple $envAll $dependencies $mounts_ceilometer_api_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }}
      containers:
        - name: ceilometer-api
          image: {{ tuple .Values.images.tags "ceilometer_api" . | include "helm-toolkit.utils.update_image" }}
          imagePullPolicy: {{ .Values.images.pull_policy }}
{{ tuple $envAll $envAll.Values.pod.resources.api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
          command:
            - /tmp/ceilometer-api.sh
            - start
          lifecycle:
            preStop:
              exec:
                command:
                  - /tmp/ceilometer-api.sh
                  - stop
          ports:
            - name: ce-api
              containerPort: {{ .Values.network.api.port }}
          readinessProbe:
            tcpSocket:
              port: {{ .Values.network.api.port }}
          volumeMounts:
            - name: pod-etc-ceilometer
              mountPath: /etc/ceilometer
            - name: ceilometer-etc
              mountPath: /etc/ceilometer/ceilometer.conf
              subPath: ceilometer.conf
              readOnly: true
            - name: ceilometer-etc
              mountPath: /etc/ceilometer/api_paste.ini
              subPath: api_paste.ini
              readOnly: true
            - name: ceilometer-etc
              mountPath: /etc/ceilometer/policy.json
              subPath: policy.json
              readOnly: true
            - name: ceilometer-etc
              mountPath: /etc/ceilometer/event_definitions.yaml
              subPath: event_definitions.yaml
              readOnly: true
            - name: ceilometer-etc
              mountPath: /etc/ceilometer/event_pipeline.yaml
              subPath: event_pipeline.yaml
              readOnly: true
            - name: ceilometer-etc
              mountPath: /etc/ceilometer/pipeline.yaml
              subPath: pipeline.yaml
              readOnly: true
            - name: ceilometer-etc
              mountPath: /etc/ceilometer/gnocchi_resources.yaml
              subPath: gnocchi_resources.yaml
              readOnly: true
            - name: ceilometer-etc
              mountPath: /etc/httpd/conf.d/wsgi-ceilometer.conf
              subPath: wsgi-ceilometer.conf
              readOnly: true
            - name: ceilometer-etc
              mountPath: /etc/ceilometer/mapping.json
              subPath: mapping.json
              readOnly: true
            - name: ceilometer-bin
              mountPath: /tmp/ceilometer-api.sh
              subPath: ceilometer-api.sh
              readOnly: true
{{ if $mounts_ceilometer_api.volumeMounts }}{{ toYaml $mounts_ceilometer_api.volumeMounts | indent 12 }}{{ end }}
      volumes:
        - name: pod-etc-ceilometer
          emptyDir: {}
        - name: ceilometer-etc
          configMap:
            name: ceilometer-etc
            defaultMode: 0444
        - name: ceilometer-bin
          configMap:
            name: ceilometer-bin
            defaultMode: 0555
{{ if $mounts_ceilometer_api.volumes }}{{ toYaml $mounts_ceilometer_api.volumes | indent 8 }}{{ end }}
{{- end }}

最终生成的结果如下:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: 2020-01-15T07:45:52Z
  generation: 1
  labels:
    application: ceilometer
    component: api
    release_group: ceilometer
  name: ceilometer-api
  namespace: openstack
  resourceVersion: "1912908"
  selfLink: /apis/extensions/v1beta1/namespaces/openstack/deployments/ceilometer-api
  uid: 0e3137e9-376b-11ea-8f18-b82a72d4e66a
spec:
  progressDeadlineSeconds: 600
  replicas: 3
  revisionHistoryLimit: 3
  selector:
    matchLabels:
      application: ceilometer
      component: api
      release_group: ceilometer
  strategy:
    rollingUpdate:
      maxSurge: 3
      maxUnavailable: 70%
    type: RollingUpdate
  template:
    metadata:
      annotations:
        configmap-bin-hash: 94dd5d317e3cca222a9ff984000df31f2488a90ea7eef07b4b0f43a343f7e415
        configmap-etc-hash: a0ddd009707fc22ba1bd9091fa1bda212d1674b487d57d5dfae710986869ef8a
      creationTimestamp: null
      labels:
        application: ceilometer
        component: api
        release_group: ceilometer
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: release_group
                operator: In
                values:
                - ceilometer
              - key: application
                operator: In
                values:
                - ceilometer
              - key: component
                operator: In
                values:
                - api
            topologyKey: kubernetes.io/hostname
      containers:
      - command:
        - /tmp/ceilometer-api.sh
        - start
        image: hub.easystack.io/production/escloud-linux-source-ceilometer-api:5.0.3-1-beta.2
        imagePullPolicy: IfNotPresent
        lifecycle:
          preStop:
            exec:
              command:
              - /tmp/ceilometer-api.sh
              - stop
        name: ceilometer-api
        ports:
        - containerPort: 8777
          name: ce-api
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          periodSeconds: 10
          successThreshold: 1
          tcpSocket:
            port: 8777
          timeoutSeconds: 1
        resources:
          limits:
            cpu: "2"
            memory: 2Gi
          requests:
            cpu: 100m
            memory: 124Mi
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /etc/ceilometer
          name: pod-etc-ceilometer
        - mountPath: /etc/ceilometer/ceilometer.conf
          name: ceilometer-etc
          readOnly: true
          subPath: ceilometer.conf
        - mountPath: /etc/ceilometer/api_paste.ini
          name: ceilometer-etc
          readOnly: true
          subPath: api_paste.ini
        - mountPath: /etc/ceilometer/policy.json
          name: ceilometer-etc
          readOnly: true
          subPath: policy.json
        - mountPath: /etc/ceilometer/event_definitions.yaml
          name: ceilometer-etc
          readOnly: true
          subPath: event_definitions.yaml
        - mountPath: /etc/ceilometer/event_pipeline.yaml
          name: ceilometer-etc
          readOnly: true
          subPath: event_pipeline.yaml
        - mountPath: /etc/ceilometer/pipeline.yaml
          name: ceilometer-etc
          readOnly: true
          subPath: pipeline.yaml
        - mountPath: /etc/ceilometer/gnocchi_resources.yaml
          name: ceilometer-etc
          readOnly: true
          subPath: gnocchi_resources.yaml
        - mountPath: /etc/httpd/conf.d/wsgi-ceilometer.conf
          name: ceilometer-etc
          readOnly: true
          subPath: wsgi-ceilometer.conf
        - mountPath: /etc/ceilometer/mapping.json
          name: ceilometer-etc
          readOnly: true
          subPath: mapping.json
        - mountPath: /tmp/ceilometer-api.sh
          name: ceilometer-bin
          readOnly: true
          subPath: ceilometer-api.sh
      dnsPolicy: ClusterFirst
      initContainers:
      - command:
        - kubernetes-entrypoint
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
        - name: INTERFACE_NAME
          value: eth0
        - name: DEPENDENCY_SERVICE
          value: openstack:keystone-api,openstack:mariadb,openstack:mongodb
        - name: DEPENDENCY_JOBS
          value: ceilometer-db-init-mongodb,ceilometer-db-sync,ceilometer-ks-user,ceilometer-ks-endpoints
        - name: DEPENDENCY_DAEMONSET
        - name: DEPENDENCY_CONTAINER
        - name: COMMAND
          value: echo done
        image: hub.easystack.io/production/kubernetes-entrypoint:v0.2.1
        imagePullPolicy: IfNotPresent
        name: init
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      nodeSelector:
        openstack-control-plane: enabled
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 600
      volumes:
      - emptyDir: {}
        name: pod-etc-ceilometer
      - configMap:
          defaultMode: 292
          name: ceilometer-etc
        name: ceilometer-etc
      - configMap:
          defaultMode: 365
          name: ceilometer-bin
        name: ceilometer-bin
status:
  availableReplicas: 3
  conditions:
  - lastTransitionTime: 2020-01-15T10:05:02Z
    lastUpdateTime: 2020-01-15T10:12:02Z
    message: ReplicaSet "ceilometer-api-768b45c9cb" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  - lastTransitionTime: 2020-02-02T09:21:40Z
    lastUpdateTime: 2020-02-02T09:21:40Z
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available


参考:
kubernetes-handbook
https://www.cnblogs.com/linuxk/p/9578211.html
https://blog.csdn.net/weixin_33994429/article/details/92837489
https://www.kubernetes.org.cn/1890.html
https://blog.csdn.net/tiger435/article/details/78489369

 类似资料: