Пример конфигураций DropAppConfiguration#

Конфигурация compute.userProvisioned#

Важно

Для релизов 2.x, 3.x и 4.x используются следующие версии Kubernetes:

  • релиз 2.x: kubernetes=1.26.15;

  • релиз 3.x: kubernetes=1.27.16;

  • релиз 4.x: kubernetes=1.28.15.

Конфигурация высокодоступного кластера#

Для создания НА-кластера, укажите несколько узлов controlPlane:

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
    publicDomain: domain.ru
    metallb:
      pools:
      - addresses: "<IP_ADDRESS_FOR_LOADBALANCER>/<SUBNET>" # Адрес LoadBalancer-сервиса, обычно указывает на сервис ingress-nginx-controller
        name: "dapp"
        l2Advertisement: true
  artifacts:
    imageRegistry:
      credentials: "" # Токен аутентификации в base64, в приведенном примере это `echo -n user:password | base64 | base64`
  compute:
    sshAccess:
      user: dapp      
      privateKeyPath: "~/.ssh/id_k8s"     
    userProvisioned:
      nodes:
        controlPlane:
            - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
            - ip: "<IP_ADDRESS_2_CONTROLPLANE>"
            nodePool: "control-plane"
            - ip: "<IP_ADDRESS_3_CONTROLPLANE>"
            nodePool: "control-plane"
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"

Конфигурация compute.libvirt#

Важно

Функциональность по умолчанию отключена, так как требует внешней зависимости в виде пакета libvirt-devel.

Пример конфигурации для создания кластера на libvirt:

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
    publicDomain: domain.ru
    metallb:
      pools:
      - addresses: "<IP_ADDRESS_FOR_LOADBALANCER>/<SUBNET>" # Адрес LoadBalancer-сервиса, обычно указывает на сервис ingress-nginx-controller
        name: "dapp"
        l2Advertisement: true
  artifacts:
    imageRegistry:             
      credentials: "" # Токен аутентификации в base64, в приведенном примере это `echo -n user:password | base64 | base64`
  compute:
    sshAccess:
      user: dapp      
      publicKey: "" # Публичный ключ для пользователя, который будет добавлен на все узлы
      privateKey: "~/.ssh/id_k8s"
    libvirt:
      url: "qemu:///system" # по умолчанию "qemu:///system"
      network: # по умолчанию type: nat, dhcp: default
        name: default
        dhcp: default
        type: nat
      storage:
        pool: default
      osImage: # обязательное
        qcow2FilePath: "/tmp/dapp/os.qcow2"
      nodes:
        controlPlane:
          - replicas: 1
            nodePool: "control-plane"
        worker:
          - replicas: 2
            nodePool: "worker"

Дополнительные конфигурации#

Конфигурация секции artifacts#

Настройка container registry и rpm-репозиториев для закрытых окружений (секция конфигурации spec.artifacts):

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
     publicDomain: domain.ru
     metallb:
       pools:
       - addresses: "<IP_ADDRESS_FOR_LOADBALANCER>/<SUBNET>" # Адрес LoadBalancer-сервиса, обычно указывает на сервис ingress-nginx-controller
         name: "dapp"
         l2Advertisement: true
  artifacts:
    imageRegistry:
      host: "host.ru"
      path: ""
      credentials: "" # Токен аутентификации в base64, в приведенном примере это `echo -n user:password | base64 | base64`
    rpmRepository:
      - name: "dapp-0.0.0"
        baseUrl: <BASE_URL_DAPP>
        gpgCheck: 1
        enabled: 1
        gpgKey: "file:///<GPG_KEY>
           http://<GPG_KEY>"
      - name: "slo-8.10-baseos"
        baseurl: <BASE_URL_BASEOS>
        gpgcheck: 1
        enabled: 1
        gpgKey: "file:///<GPG_KEY>
           http://<GPG_KEY>"
      - name: "slo-8.10-appstream"
        baseurl: <BASE_URL_APPSTREAM>
        gpgcheck: 1
        enabled: 1
        gpgKey: "file:///<GPG_KEY>
           http://<GPG_KEY>"
  compute:
    sshAccess:
      user: dapp                        
      privateKey: # Содержимое приватного ключа в кодировке base64 или путь к приватному ключу (например, ~/.ssh/id_k8s)
    userProvisioned:
      nodes:
        controlPlane:
          - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"

Конфигурация секции k8s#

Основная конфигурация кластера k8s#

Настройка Kubernetes, включая CIDR для pod и сервисов:

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
    publicDomain: domain.ru
    metallb:
      pools:
      - addresses: "<IP_ADDRESS_FOR_LOADBALANCER>/<SUBNET>" # Адрес LoadBalancer-сервиса, обычно указывает на сервис ingress-nginx-controller
        name: "dapp"
        l2Advertisement: true 
  artifacts:
    imageRegistry:
      credentials: "" # Токен аутентификации в base64, в приведенном примере это `echo -n user:password | base64 | base64`
  compute:
    sshAccess:
      user: dapp                        
      privateKey: # Содержимое приватного ключа в кодировке base64 или путь к приватному ключу (например, ~/.ssh/id_k8s)
    userProvisioned:
      nodes:
        controlPlane:
          - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"
  k8s:
    podSubnetCIDR: <IP_ADDRESS_1>/<SUBNET> # Диапазон IP-адресов в формате CIDR, выделенный для назначения IP-адресов pod
    serviceSubnetCIDR: <IP_ADDRESS_2>/<SUBNET> # Диапазон IP-адресов в формате CIDR, выделенный для назначения IP-адресов сервисам
    clusterDomain: "cluster.local"

Конфигурация kubeadm ClusterConfiguration#

Настройка дополнительных параметров apiserver, controllerManager и scheduler (секция конфигурации k8s):

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
    publicDomain: domain.ru
    metallb:
      pools:
      - addresses: "<IP_ADDRESS_FOR_LOADBALANCER>/<SUBNET>" # Адрес LoadBalancer-сервиса, обычно указывает на сервис ingress-nginx-controller
        name: "dapp"
        l2Advertisement: true 
  artifacts:
    imageRegistry:
      credentials: "" # Токен аутентификации в base64, в приведенном примере это `echo -n user:password | base64 | base64`
  compute:
    sshAccess:
      user: dapp                        
      privateKey: # Содержимое приватного ключа в кодировке base64 или путь к приватному ключу (например, ~/.ssh/id_k8s)
    userProvisioned:
      nodes:
        controlPlane:
          - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"
  k8s:
    apiServer:
      certSANs: # Список альтернативных имен (Subject Alternative Names) для сертификата API-сервера. Каждое значение может быть доменным именем или IP-адресом, для которых сертификат будет считаться действительным
        - <IP_ADDRESS_1_CERTSANS>
        - apiserver.dapp.test
      extraArgs:
        v: 5
      extraVolumes:
      - name: policies
        hostPath: /etc/kubernetes/policies
        mountPath: /etc/kubernetes/policies
      - name: kube-audit
        hostPath: /var/log/kubernetes
        mountPath: /var/log/kubernetes
    controllerManager:
      extraArgs:
        v: 5
    scheduler:
      extraArgs:
        v: 5

Конфигурация kubeadm InitConfiguration#

Настройка InitConfiguration для kubeadm (секция конфигурации k8s.init):

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
    publicDomain: domain.ru
    metallb:
      pools:
      - addresses: "<IP_ADDRESS_FOR_LOADBALANCER>/<SUBNET>" # Адрес LoadBalancer-сервиса, обычно указывает на сервис ingress-nginx-controller
        name: "dapp"
        l2Advertisement: true
  artifacts:
    imageRegistry:
      credentials: "" # Токен аутентификации в base64, в приведенном примере это `echo -n user:password | base64 | base64`
  compute:
    sshAccess:
      user: dapp                        
      privateKey: # Содержимое приватного ключа в кодировке base64 или путь к приватному ключу (например, ~/.ssh/id_k8s)
    userProvisioned:
      nodes:
        controlPlane:
          - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"
  k8s:
    init:
      skipPhases:
      - "upload-config/kubeadm"

Конфигурация ExternalEtcd#

Настройка внешнего кластера ETCD (секция конфигурации k8s.externalEtcd):

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
    publicDomain: domain.ru
    metallb:
      pools:
      - addresses: "<IP_ADDRESS_FOR_LOADBALANCER>/<SUBNET>" # Адрес LoadBalancer-сервиса, обычно указывает на сервис ingress-nginx-controller
        name: "dapp"
        l2Advertisement: true 
  artifacts:
    imageRegistry:
      credentials: "" # Токен аутентификации в base64, в приведенном примере это `echo -n user:password | base64 | base64`
  compute:
    sshAccess:
      user: dapp                        
      privateKey: # Содержимое приватного ключа в кодировке base64 или путь к приватному ключу (например, ~/.ssh/id_k8s)
    userProvisioned:
      nodes:
        controlPlane:
          - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"
  k8s:
    externalEtcd:
      endpoints:
      - "https://myetcd1.com"
      - "https://myetcd2.com"
      caFile: "/path/to/key"
      certFile: "/path/to/crt"
      keyFile: "/path/to/key"

Конфигурация шифрования Etcd#

Для обеспечения безопасного хранения секретов можно указать, с какими настройками будут зашифрованы ресурсы, хранящиеся в etcd. Пример включает secrets, configmaps и ключ шифрования aescbc:

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
    publicDomain: domain.ru
    metallb:
      pools:
      - addresses: "<IP_ADDRESS_FOR_LOADBALANCER>/<SUBNET>" # Адрес LoadBalancer-сервиса, обычно указывает на сервис ingress-nginx-controller
        name: "dapp"
        l2Advertisement: true 
  artifacts:
    imageRegistry:
      credentials: "" # Токен аутентификации в base64, в приведенном примере это `echo -n user:password | base64 | base64`
  compute:
    sshAccess:
      user: dapp                        
      privateKey: # Содержимое приватного ключа в кодировке base64 или путь к приватному ключу (например, ~/.ssh/id_k8s)
    userProvisioned:
      nodes:
        controlPlane:
          - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"
  k8s:
    etcd:
      encrypt:
        apiVersion: apiserver.config.k8s.io/v1
        kind: EncryptionConfiguration
        resources:
        - resources:
          - secrets
          - configmaps
          providers:
          - aescbc:
              keys:
              - name: key1
                secret: <clientSecret>
          - identity: {}

Конфигурация Pod Security Admission#

Настройка политики безопасности pod по умолчанию (секция конфигурации k8s.security):

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
    publicDomain: domain.ru
    metallb:
      pools:
      - addresses: "<IP_ADDRESS_FOR_LOADBALANCER>/<SUBNET>" # Адрес LoadBalancer-сервиса, обычно указывает на сервис ingress-nginx-controller
        name: "dapp"
        l2Advertisement: true 
  artifacts:
    imageRegistry:
      credentials: "" # Токен аутентификации в base64, в приведенном примере это `echo -n user:password | base64 | base64`
  compute:
    sshAccess:
      user: dapp                        
      privateKey: # Содержимое приватного ключа в кодировке base64 или путь к приватному ключу (например, ~/.ssh/id_k8s)
    userProvisioned:
      nodes:
        controlPlane:
          - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"
  k8s:
    security:
      pods:
        enforce: "baseline"
        audit: "restricted"
        warn: "baseline"

Конфигурация Cilium#

Воспользуйтесь следующими конфигурациями для настройки Cilium перед установкой кластера. (Подробнее см. раздел «Cilium»).

Настройка tunnelProtocol#

По умолчанию Cilium использует vxlan. Чтобы изменить, установите новое значение в tunnelProtocol.

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
    publicDomain: dapp.test
    metallb:
      pools:
      - addresses: "<IP_ADDRESS_FOR_LOADBALANCER>/<SUBNET>" # адрес для сервиса LoadBalancer; как правило, это сервис ingress-nginx-controller
        name: "dapp"
        l2Advertisement: true 
  artifacts:
    imageRegistry:
      host: "example.ru"
      path: "dev/dapp_dev/mgmt"
      credentials: # токен от registry в base64; echo -n user:password | base64 | base64
  compute:
    sshAccess:
      user: dapp                        
      privateKey: # base64 - содержимое приватного ключа, либо privateKeyPath - путь до ключа (например, "~/.ssh/id_k8s")
    userProvisioned:
      nodes:
        controlPlane:
          - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"
  k8s:
    cni:
      cilium:
        values:         
          tunnelProtocol: geneve

Включение hubble-relay и hubble-ui#

Включите hubble-relay и hubble-ui, используя следующую конфигурацию. В ней также создается Ingress для hubble-ui.

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
    publicDomain: dapp.test
    metallb:
      pools:
      - addresses: "<IP_ADDRESS_FOR_LOADBALANCER>/<SUBNET>" # адрес для сервиса LoadBalancer; как правило, это сервис ingress-nginx-controller
        name: "dapp"
        l2Advertisement: true 
  artifacts:
    imageRegistry:
      host: "example.ru"
      path: "dev/dapp_dev/mgmt"
      credentials: # токен от registry в base64; echo -n user:password | base64 | base64
  compute:
    sshAccess:
      user: dapp                        
      privateKey: # base64 - содержимое приватного ключа, либо privateKeyPath - путь до ключа (например, "~/.ssh/id_k8s")
    userProvisioned:
      nodes:
        controlPlane:
          - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"
  k8s:
    cni:
      cilium:
        values:         
          hubble:
            relay:
              enabled: true
            ui:
              enabled: true

Режим замены kube-proxy#

По умолчанию Cilium работает в режиме замены kube-proxy. Для изменения режима выключите kubeProxyReplacement.

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
    publicDomain: dapp.test
    metallb:
      pools:
      - addresses: "<IP_ADDRESS_FOR_LOADBALANCER>/<SUBNET>" # адрес для сервиса LoadBalancer; как правило, это сервис ingress-nginx-controller
        name: "dapp"
        l2Advertisement: true 
  artifacts:
    imageRegistry:
      credentials: # токен от registry в base64; echo -n user:password | base64 | base64
  compute:
    sshAccess:
      user: dapp                        
      privateKey: # base64 - содержимое приватного ключа, либо privateKeyPath - путь до ключа (например, "~/.ssh/id_k8s")
    userProvisioned:
      nodes:
        controlPlane:
          - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"
  k8s:
    cni:
      cilium:
        values:         
          kubeProxyReplacement: false

В установленном режиме происходят дополнительные настройки конфигураций: устанавливаются корректные значения k8sServiceHost и k8sServicePort, а также ipam.operator.clusterPoolIPv4PodCIDRList.

Подробнее про конфигурацию Cilium читайте в разделе «Конфигурация values».

Конфигурация балансировщика#

Metallb в режиме L2#

Чтобы настроить адресные пулы для Metallb (подробнее см. раздел «MetalLB») и включить l2 Advertisement, используйте следующий пример:

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
     publicDomain: dapp.test
     metallb:
       pools:
       - addresses: "<IP_ADDRESS_POOL>"
         name: "dapp"
         l2Advertisement: true
  artifacts:
    imageRegistry:
      credentials: # токен от registry в base64; echo -n user:password | base64 | base64
  compute:
    sshAccess:
      user: dapp                        
      privateKey: # base64 - содержимое приватного ключа, либо privateKeyPath - путь до ключа (например, "~/.ssh/id_k8s")
    userProvisioned:
      nodes:
        controlPlane:
          - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"

При данной конфигурации создадутся два CR (IPAddressPool и L2Advertisement):

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: dapp
  namespace: dapp-lb
spec:
  addresses:
  - <IP_ADDRESS_POOL>
  autoAssign: true
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: dapp
  namespace: dapp-lb
spec:
  ipAddressPools:
  - dapp

Из указанного пула будут назначаться внешние (external) IP-адреса для сервисов LoadBalancer, например, для Ingress-nginx-controller.

Metallb в режиме BGP#

Чтобы включить bgpAdvertisement, используйте конфигурацию:

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
     publicDomain: dapp.test
     metallb:      
       bgpPeer:
         myASN: 65001 # пример, ASN MetalLB
         peerASN: 65530 # пример, ASN роутера, пример
         peerAddress: <IP_ADDRESS_ROUTER> # IP-адрес роутера       
       pools:
       - addresses: "<IP_ADDRESS_POOL>"
         name: "dapp"
         bgpAdvertisement: true
  artifacts:
    imageRegistry:
      credentials: # токен от registry в base64; echo -n user:password | base64 | base64
  compute:
    sshAccess:
      user: dapp                        
      privateKey: # base64 - содержимое приватного ключа, либо privateKeyPath - путь до ключа (например, "~/.ssh/id_k8s")
    userProvisioned:
      nodes:
        controlPlane:
          - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"

При данной конфигурации создадутся три CR (IPAddressPool, BGPAdvertisement, BGPPeer):

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: dapp
  namespace: dapp-lb
spec:
  addresses:
  - "<IP_ADDRESS_POOL>"
  autoAssign: true
apiVersion: metallb.io/v1beta1
kind: BGPAdvertisement
metadata:
  name: dapp
  namespace: dapp-lb
spec:
  ipAddressPools:
  - dapp
apiVersion: metallb.io/v1beta2
kind: BGPPeer
metadata:
  name: dapp
  namespace: dapp-lb
spec:
  myASN: 64512
  peerASN: 64512
  peerAddress: <IP_ADDRESS_ROUTER>

Из указанного пула будут назначаться внешние (external) IP-адреса для сервисов LoadBalancer, например, для Ingress-nginx-controller.

Внешний балансировщик#

Примечание

В документации не предоставлены сценарии настройки внешних балансировщиков.

При использовании внешнего балансировщика следуйте инструкциям и сценариям, предоставленными разработчиками соответствующего ПО.

Удалите секцию Metallb:

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
     publicDomain: dapp.test
  artifacts:
    imageRegistry:
      credentials: # токен от registry в base64; echo -n user:password | base64 | base64
  compute:
    sshAccess:
      user: dapp                        
      privateKey: # base64 - содержимое приватного ключа, либо privateKeyPath - путь до ключа (например, "~/.ssh/id_k8s")
    userProvisioned:
      nodes:
        controlPlane:
          - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"

В данном случае компонент Load-balancer не будет установлен в кластере, однако компонент Ingress-nginx будет автоматически сконфигурирован со следующими настройками:

controller:
  dnsPolicy: ClusterFirstWithHostNet
  hostNetwork: true
  hostPort:
    enabled: true
    ports:
      http: 80
      https: 443
  kind: DaemonSet
  service:
    external:
      enabled: false

Конфигурация hostAliases#

При настройке конфигурации hostAliases соответствующая секция будет добавлена в Deployment Dex и Console, записи ip address hostname в /etc/hosts pod, а также узлов control-plane. Это нужно, например, если адрес LoadBalancer, выданный Metallb, не имеет DNS-записей для publicDomain.

Пример заполнения:

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "c01"
spec:
  network:
     publicDomain: dapp.test
     metallb:
       pools:
       - addresses: "<IP_ADDRESS_FOR_LOADBALANCER>/<SUBNET>"
         name: "dapp"
         l2Advertisement: true      
     hostAliases:
     - hostnames:  
       - console.c01.dapp.test
       - auth.c01.dapp.test
       - alertmanager.c01.dapp.test
       - metrics.c01.dapp.test
       ip: <IP_ADDRESS_ROUTER>  
  artifacts:
    imageRegistry:
      credentials: # токен от registry в base64; echo -n user:password | base64 | base64
  compute:
    sshAccess:
      user: dapp                        
      privateKey: # base64 - содержимое приватного ключа, либо privateKeyPath - путь до ключа (например, "~/.ssh/id_k8s")
    userProvisioned:
      nodes:
        controlPlane:
          - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"

Конфигурация сертификатов#

Кластерные сертификаты#

Чтобы настроить сертификаты, которые Kubernetes будет использовать для внутреннего взаимодействия, примените конфигурацию:

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
    publicDomain: dapp.test
    metallb:
      pools:
      - addresses: "<IP_ADDRESS_FOR_LOADBALANCER>/<SUBNET>" # адрес для сервиса LoadBalancer; как правило, это сервис ingress-nginx-controller
        name: "dapp"
        l2Advertisement: true   
  artifacts:
    imageRegistry:
      credentials: # токен от registry в base64; echo -n user:password | base64 | base64
  compute:
    sshAccess:
      user: dapp                        
      privateKey: # base64 - содержимое приватного ключа, либо privateKeyPath - путь до ключа (например, "~/.ssh/id_k8s")
    userProvisioned:
      nodes:
        controlPlane:
          - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"
  k8s:
    clusterTLS:
      cert:... # base64 содержимое ".crt"-файла
      key:... # base64 содержимое ".key"-файла

Ingress-сертификаты#

Чтобы настроить сертификаты, которые будут использоваться для всех ingress-объектов и для OIDC и AUTH компонента, примените конфигурацию:

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
    publicDomain: dapp.test
    metallb:
      pools:
      - addresses: "<IP_ADDRESS_FOR_LOADBALANCER>/<SUBNET>" # адрес для сервиса LoadBalancer; как правило, это сервис ingress-nginx-controller
        name: "dapp"
        l2Advertisement: true   
  artifacts:
    imageRegistry:
      credentials: # токен от registry в base64; echo -n user:password | base64 | base64
  compute:
    sshAccess:
      user: dapp                        
      privateKey: # base64 - содержимое приватного ключа, либо privateKeyPath - путь до ключа (например, "~/.ssh/id_k8s")
    userProvisioned:
      nodes:
        controlPlane:
          - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"
  k8s:
    ingressTLS:
      cert:... # base64 содержимое ".crt"-файла
      key:... # base64 содержимое ".key"-файла

Конфигурация OIDC#

Для настройки внешнего OIDC, если внутренний Dex не нужен, используйте конфигурацию:

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
    publicDomain: dapp.test
    metallb:
      pools:
      - addresses: "<IP_ADDRESS_FOR_LOADBALANCER>/<SUBNET>" # адрес для сервиса LoadBalancer; как правило, это сервис ingress-nginx-controller
        name: "dapp"
        l2Advertisement: true   
  artifacts:
    imageRegistry:
      credentials: # токен от registry в base64; echo -n user:password | base64 | base64
  compute:
    sshAccess:
      user: dapp                        
      privateKey: # base64 - содержимое приватного ключа, либо privateKeyPath - путь до ключа (например, "~/.ssh/id_k8s")
    userProvisioned:
      nodes:
        controlPlane:
          - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"
  k8s:    
    apiServer:
      extraArgs:
        oidc-issuer-url: https://accounts.provider.example
        oidc-client-id: dropapp
        oidc-username-claim: sub
        oidc-username-prefix: oidc
        oidc-groups-claim: groups
        oidc-groups-prefix: oidc
        oidc-ca-file: # локальный путь к ".crt"-файлу, файл должен быть на control-plane в каталоге /etc/kubernetes/pki

Конфигурация Control Plane Endpoint#

Для настройки высокодоступного кластера укажите внешний балансировщик в spec.k8s.controlPlaneEndpoint:

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
    publicDomain: dapp.test
    metallb:
      pools:
      - addresses: "<IP_ADDRESS_FOR_LOADBALANCER>/<SUBNET>" # адрес для сервиса LoadBalancer; как правило, это сервис ingress-nginx-controller
        name: "dapp"
        l2Advertisement: true   
  artifacts:
    imageRegistry:
      credentials: # токен от registry в base64; echo -n user:password | base64 | base64
  compute:
    sshAccess:
      user: dapp      
      privateKey: # base64 - содержимое приватного ключа, либо privateKeyPath - путь до ключа (например, "~/.ssh/id_k8s")
    userProvisioned:
      nodes:
        controlPlane:
          - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
          - ip: "<IP_ADDRESS_2_CONTROLPLANE>"
            nodePool: "control-plane"
          - ip: "<IP_ADDRESS_3_CONTROLPLANE>"
            nodePool: "control-plane" 
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"
  k8s:
    controlPlaneEndpoint: myloadbalancer.com

Конфигурация Taints и Tolerations#

В конфигурации можно настроить Taints для узлов, а также Tolerations и affinity для инструментов.

Например, выделенные узлы для Ingress-nginx и Metallb. На уровне рабочих узлов настройте taints и nodePool, а также toleration и affinity для Ingress-nginx и Metallb:

apiVersion: config.dropapp.ru/v1alpha1
kind: DropAppConfiguration
metadata:
  name: "my-cluster"
spec:
  network:
    publicDomain: dapp.test
    metallb:
      pools:
      - addresses: "<IP_ADDRESS_FOR_LOADBALANCER>/<SUBNET>" # адрес для сервиса LoadBalancer; как правило, это сервис ingress-nginx-controller
        name: "dapp"
        l2Advertisement: true   
  artifacts:
    imageRegistry:
      credentials: # токен от registry в base64; echo -n user:password | base64 | base64
  compute:
    sshAccess:
      user: dapp      
      privateKey: # base64 - содержимое приватного ключа, либо privateKeyPath - путь до ключа (например, "~/.ssh/id_k8s")
    userProvisioned:
      nodes:
        controlPlane:
          - ip: "<IP_ADDRESS_1_CONTROLPLANE>"
            nodePool: "control-plane"
          - ip: "<IP_ADDRESS_2_CONTROLPLANE>"
            nodePool: "control-plane"
          - ip: "<IP_ADDRESS_3_CONTROLPLANE>"
            nodePool: "control-plane" 
        worker:
          - ip: "<IP_ADDRESS_1_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_2_WORKER>"
            nodePool: "worker"
          - ip: "<IP_ADDRESS_3_WORKER>"
            nodePool: "ingress"
          - ip: "<IP_ADDRESS_4_WORKER>"
            nodePool: "ingress"
  components:   
  - name: load-balancer
    tools:
    - name: metallb
      values:
        speaker:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                  - matchExpressions:
                      - key: node-role.kubernetes.io/ingress
                        operator: Exists
  - name: ingress-controller
    tools:
    - name: ingress-nginx
      values:
        controller:
          replicaCount: 2
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                  - matchExpressions:
                      - key: node-role.kubernetes.io/ingress
                        operator: Exists
          tolerations:
          - key: "dedicated"
            operator: "Equal"
            value: "ingress"
            effect: "NoSchedule"

При данной конфигурации pod ingress-nginx-controller и metallb-speaker будут распределены на узлы worker3 и worker4. Также на эти узлы будут распределены pod cilium (для сети pod), prometheus-node-exporter (для сбора метрик) и vector-agent (для сбора логов). На узлах не будет других pod, кроме указанных ранее. При этом affinity гарантирует, что ingress-nginx-controller и metallb-speaker запустятся только на worker3 и worker4.