Настройка обновления рабочего узла

Управляемый сервис Kubernetes удобен в использовании и по сравнению с on-prem установкой имеет ряд преимуществ:

  • настройка и поддержка работоспособности мастер-узлов;

  • автомасштабирование узлов Kubernetes;

  • настройка самих сервисов внутри Kubernetes.

Но при этом необходимо обслуживать рабочие узлы кластера, так как часто стандартные политики обновления могут не применяться для конкретного пользователя по следующим причинам:

  • несовместимость развернутого приложения с более новой версией ОС;

  • длительный период тестирования нескольких узлов кластера, которые работают с различными версиями ОС, для получения более стабильного и предсказуемого результата;

  • политики обновления: rolling update, replace update и так далее;

  • отложенный механизм обновления для кластеров с высокой нагрузкой.

Для создания собственных политик обслуживания и обновления кластера Kubernetes можно использовать оригинальный проект System Upgrade Controller, разработанный компанией Rancher. Этот контроллер управляет Plans, выбирая узлы, на которых выполняются обновления Jobs. Путем указания селектора меток Plan определяет, какие узлы могут обновляться. После успешного выполнения Job на узле контроллер назначает ему метку в соответствии с Plan.

Это решение подходит как для облачных ресурсов, так и для on-prem инсталляции.

Перед началом работы

  1. Скачайте исходный файл с основными компонентами для создания Сontroller.

  2. Скачайте исходный файл конфигурации для Plan.

  3. Подключитесь к кластеру с помощью kubectl или любым удобным способом.

Настройка system-upgrade-controller

Перед использованием YAML-файла с конфигурацией ресурсов необходимо изменить параметр affinity. Также можно указать определенный узел или пул узлов, где будет развернут сервис.

Например, вы хотите разделить нагрузки ваших подов и запускать обновление на узле, предназначенного для обслуживания системы. Для этого сначала добавьте метку (label) для узла и потом соответствующий affinity.

  1. Чтобы изменить affinity, задайте параметры в YAML-файле:

    affinity:
      nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - key: type
              operator: In
              values:
              - upgrade
    

    Пример YAML-файла:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: system-upgrade
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: system-upgrade
      namespace: system-upgrade
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: system-upgrade
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: cluster-admin
    subjects:
    - kind: ServiceAccount
      name: system-upgrade
      namespace: system-upgrade
    ---
    apiVersion: v1
    data:
      SYSTEM_UPGRADE_CONTROLLER_DEBUG: "false"
      SYSTEM_UPGRADE_CONTROLLER_THREADS: "2"
      SYSTEM_UPGRADE_JOB_ACTIVE_DEADLINE_SECONDS: "900"
      SYSTEM_UPGRADE_JOB_BACKOFF_LIMIT: "99"
      SYSTEM_UPGRADE_JOB_IMAGE_PULL_POLICY: Always
      SYSTEM_UPGRADE_JOB_KUBECTL_IMAGE: rancher/kubectl:v1.21.9
      SYSTEM_UPGRADE_JOB_PRIVILEGED: "true"
      SYSTEM_UPGRADE_JOB_TTL_SECONDS_AFTER_FINISH: "900"
      SYSTEM_UPGRADE_PLAN_POLLING_INTERVAL: 15m
    kind: ConfigMap
    metadata:
      name: default-controller-env
      namespace: system-upgrade
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: system-upgrade-controller
      namespace: system-upgrade
    spec:
      selector:
        matchLabels:
          upgrade.cattle.io/controller: system-upgrade-controller
      template:
        metadata:
          labels:
            upgrade.cattle.io/controller: system-upgrade-controller
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: type
                    operator: In
                    values:
                    - upgrade
          containers:
          - env:
            - name: SYSTEM_UPGRADE_CONTROLLER_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.labels['upgrade.cattle.io/controller']
            - name: SYSTEM_UPGRADE_CONTROLLER_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            envFrom:
            - configMapRef:
                name: default-controller-env
            image: rancher/system-upgrade-controller:v0.11.0
            imagePullPolicy: IfNotPresent
            name: system-upgrade-controller
            volumeMounts:
            - mountPath: /etc/ssl
              name: etc-ssl
            - mountPath: /etc/pki
              name: etc-pki
            - mountPath: /etc/ca-certificates
              name: etc-ca-certificates
            - mountPath: /tmp
              name: tmp
          serviceAccountName: system-upgrade
          tolerations:
          - key: CriticalAddonsOnly
            operator: Exists
          - effect: NoSchedule
            key: node-role.kubernetes.io/master
            operator: Exists
          - effect: NoSchedule
            key: node-role.kubernetes.io/controlplane
            operator: Exists
          - effect: NoSchedule
            key: node-role.kubernetes.io/control-plane
            operator: Exists
          - effect: NoExecute
            key: node-role.kubernetes.io/etcd
            operator: Exists
          volumes:
          - hostPath:
              path: /etc/ssl
              type: Directory
            name: etc-ssl
          - hostPath:
              path: /etc/pki
              type: DirectoryOrCreate
            name: etc-pki
          - hostPath:
              path: /etc/ca-certificates
              type: DirectoryOrCreate
            name: etc-ca-certificates
          - emptyDir: {}
            name: tmp
    
  2. Чтобы применить конфигурацию, введите:

    kubectl apply -f system-upgrade-controller.yaml
    
  3. Чтобы проверить создание Deployment, введите:

    kubectl get deployment -n system-upgrade
    

    Примечание

    system-upgrade — это название пространства имен, где развернут Deployment. Этот параметр можно взять из YAML-файла.

    В выводе команды появится:

    ../_images/s__output1.png
  4. Чтобы проверить запущен ли под, введите:

    kubectl get po -n system-upgrade
    

    В выводе команды появится:

    ../_images/s__output2.png

Настройка конфигурации Plan

Измените YAML-файл, в котором описана конфигурация Plan и Secret.

В этом примере указана установка только security обновлений.

stringData:
  upgrade.sh: |
    #!/bin/sh
    set -e
    secrets=$(dirname $0)
    sudo yum -y update --security

Это стандартный bash-скрипт. Вы можете ввести любую последовательность команд.

Дополнительно измените блок с nodeSelector. Этот блок указывает, на каких узлах будет запущено обновление.

Так же обратите внимание на параметр drain. Этот параметр можно применить, когда нужно перераспределить под с текущего узла на другие доступные в кластере.

Пример YAML-файла:

---
apiVersion: v1
kind: Secret
metadata:
  name: bionic
  namespace: system-upgrade
type: Opaque
stringData:
  upgrade.sh: |
    #!/bin/sh
    set -e
    secrets=$(dirname $0)
    echo "Start" > /test/1.txt
    sudo date >> /test/1.txt
    sudo yum -y update --security >> /test/1.txt
    echo "Finish" >> /test/1.txt
---
apiVersion: upgrade.cattle.io/v1
kind: Plan
metadata:
  name: bionic
  namespace: system-upgrade
spec:
  concurrency: 1
  nodeSelector:
    matchExpressions:
      - {key: plan.upgrade.cattle.io/bionic, operator: Exists}
  serviceAccountName: system-upgrade
  secrets:
    - name: bionic
      path: /host/run/system-upgrade/secrets/bionic
  drain:
    force: true
  version: bionic
  upgrade:
    image: ubuntu
    command: ["chroot", "/host"]
    args: ["sh", "/run/system-upgrade/secrets/bionic/upgrade.sh"]
Запустили Evolution free tier
для Dev & Test
Получить