Deckhouse Kubernetes Platform на bare metal

На данном этапе вы создали кластер, который состоит из единственного узла — master-узла. На master-узле по умолчанию работает только ограниченный набор системных компонентов. Для полноценной работы кластера необходимо либо добавить в кластер хотя бы один worker-узел, либо разрешить остальным компонентам Deckhouse работать на master-узле.

Выберите ниже один из двух вариантов, для продолжения установки кластера:

Добавьте узел в кластер (подробнее о добавлении статического узла в кластер читайте в документации):

  • Подготовьте чистую виртуальную машину, которая будет узлом кластера.
  • Настройте StorageClass локального хранилища, выполнив на master-узле следующую команду:

    sudo /opt/deckhouse/bin/kubectl create -f - << EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: LocalPathProvisioner
    metadata:
      name: localpath
    spec:
      path: "/opt/local-path-provisioner"
      reclaimPolicy: Delete
    EOF
    
    sudo /opt/deckhouse/bin/kubectl create -f - << EOF apiVersion: deckhouse.io/v1alpha1 kind: LocalPathProvisioner metadata: name: localpath spec: path: "/opt/local-path-provisioner" reclaimPolicy: Delete EOF
  • Укажите, что созданный StorageClass должен использоваться как StorageClass по умолчанию. Для этого выполните на master-узле следующую команду, чтобы добавить для StorageClass аннотацию storageclass.kubernetes.io/is-default-class='true':

    sudo /opt/deckhouse/bin/kubectl annotate sc localpath storageclass.kubernetes.io/is-default-class='true'
    
    sudo /opt/deckhouse/bin/kubectl annotate sc localpath storageclass.kubernetes.io/is-default-class='true'
  • Создайте NodeGroup worker. Для этого выполните на master-узле следующую команду:

    sudo /opt/deckhouse/bin/kubectl create -f - << EOF
    apiVersion: deckhouse.io/v1
    kind: NodeGroup
    metadata:
      name: worker
    spec:
      nodeType: Static
      staticInstances:
        count: 1
        labelSelector:
          matchLabels:
            role: worker
    EOF
    
    sudo /opt/deckhouse/bin/kubectl create -f - << EOF apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: worker spec: nodeType: Static staticInstances: count: 1 labelSelector: matchLabels: role: worker EOF
  • Сгенерируйте SSH-ключ с пустой парольной фразой. Для этого выполните на master-узле следующую команду:

    ssh-keygen -t rsa -f /dev/shm/caps-id -C "" -N ""
    
    ssh-keygen -t rsa -f /dev/shm/caps-id -C "" -N ""
  • Создайте в кластере ресурс SSHCredentials. Для этого выполните на master-узле следующую команду:

    kubectl create -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: SSHCredentials
    metadata:
      name: caps
    spec:
      user: caps
      privateSSHKey: "`cat /dev/shm/caps-id | base64 -w0`"
    EOF
    
    kubectl create -f - <<EOF apiVersion: deckhouse.io/v1alpha1 kind: SSHCredentials metadata: name: caps spec: user: caps privateSSHKey: "`cat /dev/shm/caps-id | base64 -w0`" EOF
  • Выведите публичную часть сгенерированного ранее SSH-ключа (он понадобится на следующем шаге). Для этого выполните на master-узле следующую команду:

    cat /dev/shm/caps-id.pub
    
    cat /dev/shm/caps-id.pub
  • На подготовленной виртуальной машине создайте пользователя caps. Для этого выполните следующую команду, указав публичную часть SSH-ключа, полученную на предыдущем шаге:

    # Укажите публичную часть SSH-ключа пользователя.
    export KEY='<SSH-PUBLIC-KEY>'
    useradd -m -s /bin/bash caps
    usermod -aG sudo caps
    echo 'caps ALL=(ALL) NOPASSWD: ALL' | sudo EDITOR='tee -a' visudo
    mkdir /home/caps/.ssh
    echo $KEY >> /home/caps/.ssh/authorized_keys
    chown -R caps:caps /home/caps
    chmod 700 /home/caps/.ssh
    chmod 600 /home/caps/.ssh/authorized_keys
    
    # Укажите публичную часть SSH-ключа пользователя. export KEY='<SSH-PUBLIC-KEY>' useradd -m -s /bin/bash caps usermod -aG sudo caps echo 'caps ALL=(ALL) NOPASSWD: ALL' | sudo EDITOR='tee -a' visudo mkdir /home/caps/.ssh echo $KEY >> /home/caps/.ssh/authorized_keys chown -R caps:caps /home/caps chmod 700 /home/caps/.ssh chmod 600 /home/caps/.ssh/authorized_keys
  • В операционных системах семейства Astra Linux, при использовании модуля мандатного контроля целостности Parsec, сконфигурируйте максимальный уровень целостности для пользователя caps:

    pdpl-user -i 63 caps
    
    pdpl-user -i 63 caps
  • Создайте StaticInstance для добавляемого узла. Для этого выполните на master-узле следующую команду, указав IP-адрес добавляемого узла:

    # Укажите IP-адрес узла, который необходимо подключить к кластеру.
    export NODE=<NODE-IP-ADDRESS>
    kubectl create -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: StaticInstance
    metadata:
      name: d8cluster-worker
      labels:
        role: worker
    spec:
      address: "$NODE"
      credentialsRef:
        kind: SSHCredentials
        name: caps
    EOF
    
    # Укажите IP-адрес узла, который необходимо подключить к кластеру. export NODE=<NODE-IP-ADDRESS> kubectl create -f - <<EOF apiVersion: deckhouse.io/v1alpha1 kind: StaticInstance metadata: name: d8cluster-worker labels: role: worker spec: address: "$NODE" credentialsRef: kind: SSHCredentials name: caps EOF
  • Убедитесь, что все узлы кластера находятся в статусе Ready.

    Выполните на master-узле следующую команду, чтобы получить список узлов кластера:

    sudo /opt/deckhouse/bin/kubectl get no
    
    sudo /opt/deckhouse/bin/kubectl get no

    Пример вывода...

    $ sudo /opt/deckhouse/bin/kubectl get no
    NAME               STATUS   ROLES                  AGE    VERSION
    d8cluster          Ready    control-plane,master   30m   v1.23.17
    d8cluster-worker   Ready    worker                 10m   v1.23.17
    

Запуск всех компонентов Deckhouse после завершения установки может занять какое-то время.

  • Убедитесь, что под Kruise controller manager модуля ingress-nginx запустился и находится в статусе Ready.

    Выполните на master-узле следующую команду:

    sudo /opt/deckhouse/bin/kubectl -n d8-ingress-nginx get po -l app=kruise
    
    sudo /opt/deckhouse/bin/kubectl -n d8-ingress-nginx get po -l app=kruise

    Пример вывода...

    $ sudo /opt/deckhouse/bin/kubectl -n d8-ingress-nginx get po -l app=kruise
    NAME                                         READY   STATUS    RESTARTS    AGE
    kruise-controller-manager-7dfcbdc549-b4wk7   3/3     Running   0           15m
    

Далее нужно создать Ingress-контроллер, создать пользователя для доступа в веб-интерфейсы и настроить DNS.

  • Установка Ingress-контроллера

    Создайте на master-узле файл ingress-nginx-controller.yml содержащий конфигурацию Ingress-контроллера:

    # Секция, описывающая параметры NGINX Ingress controller.
    # https://deckhouse.ru/products/kubernetes-platform/documentation/v1/modules/402-ingress-nginx/cr.html
    apiVersion: deckhouse.io/v1
    kind: IngressNginxController
    metadata:
      name: nginx
    spec:
      ingressClass: nginx
      # Способ поступления трафика из внешнего мира.
      inlet: HostPort
      hostPort:
        httpPort: 80
        httpsPort: 443
      # Описывает, на каких узлах будет находиться Ingress-контроллер.
      # Возможно, захотите изменить.
      # Больше примеров здесь
      # https://deckhouse.ru/products/kubernetes-platform/documentation/v1/modules/402-ingress-nginx/examples.html
      nodeSelector:
        node-role.kubernetes.io/control-plane: ""
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/control-plane
        operator: Exists
    
    # Секция, описывающая параметры NGINX Ingress controller. # https://deckhouse.ru/products/kubernetes-platform/documentation/v1/modules/402-ingress-nginx/cr.html apiVersion: deckhouse.io/v1 kind: IngressNginxController metadata: name: nginx spec: ingressClass: nginx # Способ поступления трафика из внешнего мира. inlet: HostPort hostPort: httpPort: 80 httpsPort: 443 # Описывает, на каких узлах будет находиться Ingress-контроллер. # Возможно, захотите изменить. # Больше примеров здесь # https://deckhouse.ru/products/kubernetes-platform/documentation/v1/modules/402-ingress-nginx/examples.html nodeSelector: node-role.kubernetes.io/control-plane: "" tolerations: - effect: NoSchedule key: node-role.kubernetes.io/control-plane operator: Exists

    Примените его, выполнив на master-узле следующую команду:

    sudo /opt/deckhouse/bin/kubectl create -f ingress-nginx-controller.yml
    
    sudo /opt/deckhouse/bin/kubectl create -f ingress-nginx-controller.yml
    Запуск Ingress-контроллера после завершения установки Deckhouse может занять какое-то время. Прежде чем продолжить убедитесь что Ingress-контроллер запустился (выполните на master-узле):
    sudo /opt/deckhouse/bin/kubectl -n d8-ingress-nginx get po -l app=controller
    
    sudo /opt/deckhouse/bin/kubectl -n d8-ingress-nginx get po -l app=controller
    Дождитесь перехода подов Ingress-контроллера в статус Ready.

    Пример вывода...

    $ sudo /opt/deckhouse/bin/kubectl -n d8-ingress-nginx get po -l app=controller
    NAME                                       READY   STATUS    RESTARTS   AGE
    controller-nginx-r6hxc                     3/3     Running   0          5m
    
  • Создание пользователя для доступа в веб-интерфейсы кластера

    Создайте на master-узле файл user.yml содержащий описание учетной записи пользователя и прав доступа:

    apiVersion: deckhouse.io/v1
    kind: ClusterAuthorizationRule
    metadata:
      name: admin
    spec:
      # список учётных записей Kubernetes RBAC
      subjects:
      - kind: User
        name: admin@deckhouse.io
      # предустановленный шаблон уровня доступа
      accessLevel: SuperAdmin
      # разрешить пользователю делать kubectl port-forward
      portForwarding: true
    ---
    # секция, описывающая параметры статического пользователя
    # используемая версия API Deckhouse
    apiVersion: deckhouse.io/v1
    kind: User
    metadata:
      name: admin
    spec:
      # e-mail пользователя
      email: admin@deckhouse.io
      # это хэш пароля <GENERATED_PASSWORD>, сгенерированного сейчас
      # сгенерируйте свой или используйте этот, но только для тестирования
      # echo "<GENERATED_PASSWORD>" | htpasswd -BinC 10 "" | cut -d: -f2 | base64 -w0
      # возможно, захотите изменить
      password: <GENERATED_PASSWORD_HASH>
    
    apiVersion: deckhouse.io/v1 kind: ClusterAuthorizationRule metadata: name: admin spec: # список учётных записей Kubernetes RBAC subjects: - kind: User name: admin@deckhouse.io # предустановленный шаблон уровня доступа accessLevel: SuperAdmin # разрешить пользователю делать kubectl port-forward portForwarding: true --- # секция, описывающая параметры статического пользователя # используемая версия API Deckhouse apiVersion: deckhouse.io/v1 kind: User metadata: name: admin spec: # e-mail пользователя email: admin@deckhouse.io # это хэш пароля <GENERATED_PASSWORD>, сгенерированного сейчас # сгенерируйте свой или используйте этот, но только для тестирования # echo "<GENERATED_PASSWORD>" | htpasswd -BinC 10 "" | cut -d: -f2 | base64 -w0 # возможно, захотите изменить password: <GENERATED_PASSWORD_HASH>

    Примените его, выполнив на master-узле следующую команду:

    sudo /opt/deckhouse/bin/kubectl create -f user.yml
    
    sudo /opt/deckhouse/bin/kubectl create -f user.yml
  • Создание DNS-записи, для доступа в веб-интерфейсы кластера
    • Выясните публичный IP-адрес узла, на котором работает Ingress-контроллер.
    • Если у вас есть возможность добавить DNS-запись используя DNS-сервер:
      • Если ваш шаблон DNS-имен кластера является wildcard DNS-шаблоном (например, %s.kube.my), то добавьте соответствующую wildcard A-запись со значением публичного IP-адреса, который вы получили выше.
      • Если ваш шаблон DNS-имен кластера НЕ является wildcard DNS-шаблоном (например, %s-kube.company.my), то добавьте А или CNAME-записи со значением публичного IP-адреса, который вы получили выше, для следующих DNS-имен сервисов Deckhouse в вашем кластере:
        api.example.com
        argocd.example.com
        dashboard.example.com
        documentation.example.com
        dex.example.com
        grafana.example.com
        hubble.example.com
        istio.example.com
        istio-api-proxy.example.com
        kubeconfig.example.com
        openvpn-admin.example.com
        prometheus.example.com
        status.example.com
        upmeter.example.com
        
      • Важно: Домен, используемый в шаблоне, не должен совпадать с доменом, указанным в параметре clusterDomain и внутренней сервисной зоне сети. Например, если используется clusterDomain: cluster.local (значение по умолчанию), а сервисная зона сети — ru-central1.internal, то publicDomainTemplate не может быть %s.cluster.local или %s.ru-central1.internal.
    • Если вы не имеете под управлением DNS-сервер: добавьте статические записи соответствия имен конкретных сервисов публичному IP-адресу узла, на котором работает Ingress-контроллер.

      Например, на персональном Linux-компьютере, с которого необходим доступ к сервисам Deckhouse, выполните следующую команду (укажите ваш публичный IP-адрес в переменной PUBLIC_IP) для добавления записей в файл /etc/hosts (для Windows используйте файл %SystemRoot%\system32\drivers\etc\hosts):

      export PUBLIC_IP="<PUBLIC_IP>"
      sudo -E bash -c "cat <<EOF >> /etc/hosts
      $PUBLIC_IP api.example.com
      $PUBLIC_IP argocd.example.com
      $PUBLIC_IP dashboard.example.com
      $PUBLIC_IP documentation.example.com
      $PUBLIC_IP dex.example.com
      $PUBLIC_IP grafana.example.com
      $PUBLIC_IP hubble.example.com
      $PUBLIC_IP istio.example.com
      $PUBLIC_IP istio-api-proxy.example.com
      $PUBLIC_IP kubeconfig.example.com
      $PUBLIC_IP openvpn-admin.example.com
      $PUBLIC_IP prometheus.example.com
      $PUBLIC_IP status.example.com
      $PUBLIC_IP upmeter.example.com
      EOF
      "
      
      export PUBLIC_IP="<PUBLIC_IP>" sudo -E bash -c "cat <<EOF >> /etc/hosts $PUBLIC_IP api.example.com $PUBLIC_IP argocd.example.com $PUBLIC_IP dashboard.example.com $PUBLIC_IP documentation.example.com $PUBLIC_IP dex.example.com $PUBLIC_IP grafana.example.com $PUBLIC_IP hubble.example.com $PUBLIC_IP istio.example.com $PUBLIC_IP istio-api-proxy.example.com $PUBLIC_IP kubeconfig.example.com $PUBLIC_IP openvpn-admin.example.com $PUBLIC_IP prometheus.example.com $PUBLIC_IP status.example.com $PUBLIC_IP upmeter.example.com EOF "