ALT Container OS подветка K8S: различия между версиями

Материал из ALT Linux Wiki
Нет описания правки
Нет описания правки
 
(не показано 175 промежуточных версий 8 участников)
Строка 2: Строка 2:
Подветка '''K8S''' обеспечивает разворачивание серверов для организации kubernetes-кластера.
Подветка '''K8S''' обеспечивает разворачивание серверов для организации kubernetes-кластера.


В настоящее время (16.11.2021) дистрибутив ALTLinux обеспечивает разворачивание kubernetes-кластера под двумя типами  
Дистрибутив ALTLinux обеспечивает разворачивание kubernetes-кластера под двумя типами  
"движков" (см. [[Kubernetes]]):
"движков" (см. [[Kubernetes]]):
* ''docker'';
* ''docker'';
* ''crio'' (''podman'')
* ''CRI-O'' (''podman'')
   
   
В текущей реализации был выбран вариант движка ''crio'' обеспечивающий повышенный уровень защита запускаемых контейнеров.  
В текущей реализации был выбран вариант движка ''CRI-O'', обеспечивающий повышенный уровень защиты запускаемых контейнеров.  
Но, так как подветка ''K8S'' наследуется от основной ветки потока, включающей движок ''docker'',
Но, так как подветка ''K8S'' наследуется от основной ветки потока, включающей движок ''docker'',
в раках данной подветки можно запускать ''docker-контейнеры'', сервисы под ''docker-compose'' и организовавать
в рамках данной подветки можно запускать ''docker-контейнеры'', сервисы под ''docker-compose'' и организовывать
параллельно (или вместо) с кластером ''kubernetes'' и ''docker swarm'' кластер.  
параллельно (или вместо) с кластером ''kubernetes'' и ''docker swarm'' кластер.  


== QCOW2 образ подветки altcos/x86_64/Sisyphus/k8s ==
== образ подветки altcos/x86_64/sisyphus/k8s ==


В настоящее время реализован образ ''QCOW2'' подветки '''altcos/x86_64/sisyphus/k8s'''.
Скачать образ можно [http://altcos.altlinux.org/?arch=x86_64&repo=sisyphus&ref=k8s тут]
Скачать его можно по следующим ссылкам:
[[http://altcos.altlinux.org/ALTCOS/streams/altcos/x86_64/sisyphus/k8s/images/qcow2/k8s.20211116.0.0.qcow2 Полный]]
[[http://altcos.altlinux.org/ALTCOS/streams/altcos/x86_64/sisyphus/k8s/images/qcow2/k8s.20211116.0.0.qcow2.xz Сжатый]]


Так как размер основного диска достаточно небольшой (около 4GB) для хранения образов и запуска pod'ов необходимо создать дополнительный диск. Для этого создайте файл необходимого размера (например 30GB):
Каталог расположения образа хранится во внешней переменной ''IMAGEHOME''.


dd if=/dev/zero  of=hdb.qcow2 bs=1G count=30
Образ включает в себя архив docker-образов, необходимых для разворачивания kubernetes-кластера.
Так что для разворачивания кластера доступ в Интернет не нужен.


Для запуска необходимо подготовить YML butane-файл, обеспечивающий следующий функционал при запуске образа:
До начала работы установите пакеты :
* форматирование дополнительного диска под файловую систему ''BTRFS'' для размещения образов и контейнеров;
apt-get install butane ignition ignition-validate
* монтирование его в каталог ''/var/lib'';
 
* копирование файлов конфигураций и "перекрытых" при монтировании подкаталогов каталога ''/var/lib/''.     
== Запуск образа в режиме master-узла через qemu-system-x86_64==
 
=== Подготовка YML butane-файла для master-узла ===
 
Для запуска необходимо подготовить YML butane-файл, обеспечивающий следующий функционал при запуске образа:    
* обеспечение доступа без пароля администратора по открытому ключу под пользователем altcos  (''passwd.users.ssh_authorized_keys'')
* получение без пароля прав администратора (''sudo'') для пользователя ''altcos'' (файл ''/etc/sudoers.d/altcos'');
* формирование переменных окружения для вызова команды ''kubectl'' (файл ''/etc/profile.d/kube.sh''- данный скрипт срабатывает только при повторном заходе после инициализации кластера) ;
* создание systemd-сервиса для инициализации master-узла kubernetes-кластера.
* создание systemd-сервиса для инициализации master-узла kubernetes-кластера.


Файл конфигурации '''k8s_master.yml ''' выглядит следующим образом:
Файл конфигурации ''k8s_master.yml '' выглядит следующим образом:
  variant: fcos
  variant: fcos
  version: 1.3.0
  version: 1.3.0
  passwd:
  passwd:
   users:
   users:
    - name: root
      groups:
        - wheel
        - docker
      password_hash: ...
      ssh_authorized_keys:
        - ssh-rsa ...
     - name: altcos
     - name: altcos
       groups:
       groups:
         - wheel
         - wheel
         - docker
         - docker
       password_hash: $y$j9T$ZEYmKSGPiNFOZNTjvobEm1$IXLGt5TxdNC/OhJyzFK5NVM.mt6VvdtP6mhhzSmvE94
       password_hash: ...
       ssh_authorized_keys:
       ssh_authorized_keys:
         - ssh-rsa ... user@domain
         - ssh-rsa ...  
  storage:  
storage:
  files:
    - path: /etc/sudoers.d/altcos
      contents:
        inline: |
          altcos ALL=NOPASSWD: ALL
    - path: /etc/profile.d/kube.sh
      mode: 0755
      contents:
        inline: |
          # Set  kube environment
          if [ `id -u ` = 0 ]
          then
            export KUBECONFIG=/etc/kubernetes/admin.conf
          else
            if [ -f /etc/kubernetes/admin.conf ]
            then
              if [ ! -d ~/.kube ]
              then
                mkdir -p ~/.kube
                sudo cp -i /etc/kubernetes/admin.conf ~/.kube/config
                sudo chown $(id -u):$(id -g) ~/.kube/config
                kubectl completion bash >> ~/.bashrc
              fi
            fi
          fi
systemd:
  units:
    - name: initk8smaster.service
      enabled: false
      contents: |
        [Unit]
        Description=Start up kubernetes in master mode
        After=crio.service kube-proxy.service kubelet.service systemd-networkd.service systemd-resolved.service
        [Service]
        Type=oneshot
        RemainAfterExit=yes
        Environment="KUBECONFIG=/etc/kubernetes/admin.conf"
        ExecStartPre=loadDockerArchiveImages.sh
        ExecStart=kubeadm init --cri-socket=/var/run/crio/crio.sock --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=SystemVerification --kubernetes-version=v1.20.12
        ExecStartPost=kubectl taint nodes localhost node-role.kubernetes.io/master-
        [Install]
        WantedBy=multi-user.target
 
=== Запуск образа как master-узла ===
 
Запуск образа производится скриптом ''run_master.sh'':
 
#!/bin/sh
if ! butane -p k8s_master.yml > k8s_master.ign
then
  exit 1;
fi
cp $IMAGEHOME/sisyphus_k8s.x86_64.*.qemu.qcow2 k8s.qcow2
sudo qemu-system-x86_64 \
-m 2048 \
-machine accel=kvm \
-cpu host \
-smp 2 \
-hda k8s.qcow2 \
-fw_cfg name=opt/com.coreos/config,file=k8s_master.ign \
-net user,hostfwd=tcp::10222-:22 -net nic
Команда ''butane'' производит конвертацию butane-файла YML ''k8s_master.yml'' в JSON-формате ''ignition'' в файл ''k8s_master.ign''.
 
Команда ''cp'' копирует образ ядра в файл '' k8s.qcow2''.
 
Обратите внимание, что для работы узла ''kubernetes'' требуется не менее 2-х ядер процессора и не менее 2GB оперативной памяти.
 
Доступ по протоколу ''ssh'' обеспечивается через порт ''10222'' HOST-компьютера ''localhost''.
 
=== Запуск kubernetes на master-узле ===
 
Для того, чтобы запустить сервис:
* зайдите через консоль или через ssh под пользователем ''altcos'';
* выполните запуск сервиса ''initk8smaster'':
$ sudo systemctl start initk8smaster
 
Данные действия можно сделать и "удаленно" по протоколу ''ssh'':
ssh -p 10222 altcos@localhost sudo systemctl start initk8smaster
 
Во время запуска длительностью менее минуты:
* производится загрузка из архива, входящего в состав qcow2-образа, необходимых docker-образов;
* запуск их как сервисов;
* инициализация master-узла кластера;
 
Логи запуска можно посмотреть командой:
 
$ journalctl -u initk8smaster
Starting Start up kubernetes in master mode...
...
Loaded image(s): k8s.gcr.io/coredns:1.7.0
...
Loaded image(s): k8s.gcr.io/etcd:3.4.13-0
...
Your Kubernetes control-plane has initialized successfully!
...
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 10.0.2.15:6443 --token yhhb22.0q7bovdkg89l6hr7 \
    --discovery-token-ca-cert-hash sha256:16a864c569f23a5ecacafe5cb42931840fc7e4896b8c3946d0710133ea0b82bc
...
node/localhost untainted
Finished Start up kubernetes in master mode.
 
Рабочие (''worker'') узлы можно присоединять к кластеру взятой из лога командой
 
kubeadm join ...
 
После запуска initk8smaster следует перелогиниться, чтобы в домашнем каталоге появился файл ''~/.kube/config''. Файл ''~/.kube/config'' в домашнем каталоге пользователя ''altcos'' автоматически создается скриптом ''/etc/profile.d/kube.sh'', описанным в YML-butane файле, при входе в пользователя ''altcos'' после инициализации узла кластера.
 
==== Работа с master-узлом кластера ====
 
Вы можете работать с мастер узлом как под обычным пользователем (например ''altcos''), так и от имени суперпользователя.
 
Для работы с master-узлом кластера из суперпользователя укажите при вызове ''sudo'' флаг ''-i''. Например:
sudo -i kubectl get all -A
 
==== Проверка работы master-узла ====
 
Для проверки работы узла наберите команду
# kubectl get nodes
NAME        STATUS  ROLES                  AGE  VERSION
localhost  Ready    control-plane,master  41m  v1.20.8
 
Для проверки работы всего функционала наберите команду:
 
$ kubectl get all -A
NAMESPACE    NAME                                    READY  STATUS    RESTARTS  AGE
kube-system  pod/coredns-74ff55c5b-b4rxp            1/1    Running  0          9h
kube-system  pod/coredns-74ff55c5b-kfsxv            1/1    Running  0          9h
kube-system  pod/etcd-localhost                      1/1    Running  0          9h
kube-system  pod/kube-apiserver-localhost            1/1    Running  0          9h
kube-system  pod/kube-controller-manager-localhost  1/1    Running  0          9h
kube-system  pod/kube-proxy-4t95d                    1/1    Running  0          9h
kube-system  pod/kube-scheduler-localhost            1/1    Running  0          9h
NAMESPACE    NAME                TYPE        CLUSTER-IP  EXTERNAL-IP  PORT(S)                  AGE
default      service/kubernetes  ClusterIP  10.96.0.1    <none>        443/TCP                  9h
kube-system  service/kube-dns    ClusterIP  10.96.0.10  <none>        53/UDP,53/TCP,9153/TCP  9h
NAMESPACE    NAME                        DESIRED  CURRENT  READY  UP-TO-DATE  AVAILABLE  NODE SELECTOR            AGE
kube-system  daemonset.apps/kube-proxy  1        1        1      1            1          kubernetes.io/os=linux  9h
NAMESPACE    NAME                      READY  UP-TO-DATE  AVAILABLE  AGE
kube-system  deployment.apps/coredns  2/2    2            2          9h
NAMESPACE    NAME                                DESIRED  CURRENT  READY  AGE
kube-system  replicaset.apps/coredns-74ff55c5b  2        2        2      9h
 
Должен быть:
* развернут ''deployment'' 'coredns' с двумя репликами (''replicaset coredns-xxx-yyy'');
* запушен ''daemonset'' 'kube-proxy' с одной (по числу узлов) репликой;
 
Все перечисленные POD'ы должны иметь состояние READY ''1/1''.
 
В ''kubernetes'' по умолчанию на ''master-узле'' не могут запускаться поды в ''namespace'' ''default''.
В одноузловом варианте в данном примере для снятия этого ограничения (см. YML-файл выше) запускается команда
kubectl taint nodes localhost node-role.kubernetes.io/master-
 
Для проверки запуска POD'ов на master-узле в ''namespace'' ''default'' наберите команду:
kubectl apply -f https://k8s.io/examples/application/deployment.yaml
 
Поcле загрузки образа ''nginx'' проверьте запуск POD'а на master-узле:
# kubectl get pods       
NAME                                READY  STATUS    RESTARTS  AGE
nginx-deployment-66b6c48dd5-5nfc6  1/1    Running  0          8m16s
nginx-deployment-66b6c48dd5-j8mww  1/1    Running  0          8m16s
 
==== Действия после перезагрузке системы ====
 
После перезагрузки системы никаких дополнительных действий не требуется.
master-узел kubernetes-кластера поднимается автоматически.
 
=== Подключение дополнительного BTRFS диска ===
 
Так как размер основного диска достаточно небольшой (около 4GB) для хранения образов и запуска pod'ов необходимо создать дополнительный диск.
В приведенных ниже примерах для хранения каталогов образов, контейнеров, ... в ''docker'' и ''CRI-O''
создается и монтируется отдельный диск с файловой системой ''BTRFS''.
 
==== Формирование YML butane-файла ====
 
Сформируем YML butane-файл ''k8s_master_btrfs.yml'' для форматирования, подключения тома ''BTRFS'', изменения каталогов, размещения данных ''docker-демона'' и ''CRI-O''/''podman'':
variant: fcos
version: 1.3.0
  storage:
   disks:
   disks:
     -
     - device: /dev/sdb # создадим на диске /dev/sdb партицию /dev/sdb1
      device: /dev/sdb
       wipe_table: true
       wipe_table: true
       partitions:
       partitions:
         - number: 1
         - number: 1
           label: varlib
           label: docker
   filesystems:
   filesystems:
     - path: /var/lib
     - device: /dev/sdb1 # создадим в партиции /dev/sdb1 файловую систему BTRFS
      device: /dev/sdb1
       format: btrfs
       format: btrfs
       wipe_filesystem: true
       wipe_filesystem: true
       label: varlib
       label: docker
       with_mount_unit: true
       with_mount_unit: false
   trees:
   directories:
     - local: root # скопировать файловое дерево локального каталога root
     - path: /var/mnt/docker # создадим каталог монтирования тома
       path: /
       overwrite: true
   files:
   files:
     - path: /etc/docker/daemon.json # переписав файл конфигурации dockerd с поддержкой overlay-драйвера BTRFS
     - path: /etc/fstab # добавим строку монтирования btrfs-тома на каталог /var/mnt/docker
      append:
        - inline: |
            LABEL=docker /var/mnt/docker btrfs defaults 0 2
            /var/mnt/docker/docker/ /var/lib/docker none bind 0 0
            /var/mnt/docker/containers/ /var/lib/containers/ none bind 0 0
    # заменим в конфигурации dockerd-демона:
    # тип storage-driver с overlay2 на btrfs
    - path: /etc/docker/daemon.json
       overwrite: true
       overwrite: true
     - path: /etc/containers/storage.conf # переписав файл конфигурации crio/podman с поддержкой overlay-драйвера BTRFS
      contents:
        inline: |
          {
          "init-path": "/usr/bin/tini",
          "userland-proxy-path": "/usr/bin/docker-proxy",
          "default-runtime": "docker-runc",
          "live-restore": false,
          "log-driver": "journald",
          "runtimes": {
            "docker-runc": {
              "path": "/usr/bin/runc"
            }
          },
          "default-ulimits": {
            "nofile": {
            "Name": "nofile",
            "Hard": 64000,
            "Soft": 64000
            }
          },
          "data-root": "/var/lib/docker/",
          "storage-driver": "btrfs"
          }
    # заменим в конфигурации CRI-O тип driver с overlay на btrfs
     - path: /etc/crio/crio.conf.d/00-btrfs.conf
       overwrite: true
       overwrite: true
      contents:
        inline: |
          [crio]
          root = "/var/lib/containers/storage"
          runroot = "/var/run/containers/storage"
          storage_driver = "btrfs"
          storage_option = []
          [crio.runtime]
          conmon = "/usr/bin/conmon"
          [crio.network]
          plugin_dirs = [
            "/usr/libexec/cni",
            "/opt/cni/bin/"
          ]
    # заменим в конфигурации podman тип driver с overlay2 на btrfs
    - path: /etc/containers/storage.conf
      overwrite: true
      contents:
        inline: |
          [storage]
          driver = "btrfs"
          runroot = "/var/run/containers/storage"
          graphroot = "/var/lib/containers/storage"
          [storage.options]
          additionalimagestores = [
          ]
          [storage.options.overlay]
          mountopt = "nodev,metacopy=on"
    # исключим определение flannel-подсети в CRIO
    - path: /etc/cni/net.d/100-crio-bridge.conf
      overwrite: true
      contents:
        inline: |
          {"type": "bridge"}
Данный YML-файл:
* В элементе ''ignition.config.merge.local'' импортирует из файла ''k8s_master.ign'' описанную выше в файле ''k8s_master.yml'' конфигурацию, сливая(''merge'') ее с нижеописанной конфигурацией.
* Создает раздел ''/dev/sdb1''.
* Создает в разделе файловую систему типа ''BTRFS''.
* Создает каталог монтирования ''/var/mnt/docker''.
* Добавляет в ''/etc/fstab''
  * строку монтирования файловой системы раздела ''/dev/sdb1'' в каталог ''/var/mnt/docker'';
  * монтирует каталог /var/lib/docker на /var/mnt/docker/docker/;
  * монтирует каталог /var/lib/containers/ на /var/mnt/docker/containers/.
* Заменяет файлы  конфигурации ''docker-демона'', ''CRI-O'', ''podman'', меняя тип драйвера с ''overlay2'' на ''btrfs'' и перемещая каталоги хранения слоев образов и контейнеров из каталога ''/var/lib'' диска ''/dev/sda1'' в каталог ''/var/mnt/docker'' диска ''/dev/sdb1''.
* В текущей версии пакета ''cri-o-1.22.1-alt1.x86_64'' файл конфигурации ''/etc/cni/net.d/100-crio-bridge.conf'' задает  адрес подсети для интерфейса ''cni0''. Для корректной работы сетевого плугина ''flannel'' необходимо исключить определение подсети, так как ''flannel'' самостоятельно на основе полученной конфигурации сети конфигурирует IP-адрес интерфейса ''cni0''.
==== Запуск образа как master-узла с хранилищем образов и контейнеров на BTRFS-диске ====
Запуск образа производится скриптом ''run_master_btrfs.sh''
#!/bin/sh
if ! butane -d . -p k8s_master_btrfs.yml > k8s_master_btrfs.ign
then
  exit 1;
fi
cp $IMAGEHOME/sisyphus_k8s.x86_64.*.qemu.qcow2 k8s.qcow2
qemu-img create -f qcow2 hdb.qcow2 10G
sudo qemu-system-x86_64 \
-m 2048 \
-machine accel=kvm \
-cpu host \
-smp 2 \
-hda k8s.qcow2 \
-hdb hdb.qcow2 \
-fw_cfg name=opt/com.coreos/config,file=k8s_master_btrfs.ign \
-net user,hostfwd=tcp::10222-:22 -net nic
Данный скрипт аналогичен вышеописанному ''run_master.sh'' за исключением:
* используется файл конфигурации '' k8s_master_btrfs.yml'', объединяющий свои описания с описанием ignition-файла конфигурации ''k8s_master.ign'', сформированного на предыдущем шаге, и записывающий объединенную конфигурация в файл  ''k8s_master.ign''.
* формируется файл ''hdb.qcow2'' размером ''10GB'' для тома с файловой системой ''BTRFS'';
* при вызове ''qemu-system-x86_64'' данный файл указывается как второй том в параметре ''-hdb''.
Все остальные действия по инициализации одноузлового кластера ''kubetnetes'' и работе с ним аналогичны описанным в предыдущем разделе.
== Создание kubernetes-кластера с одним мастером (control plane) в среде libvirt ==
Установите пакеты ''libvirt'', ''virt-manager'', ''qemu-system-x86-core'', ''virt-viewer''.
apt-get install libvirt virt-manager qemu-system-x86-core virt-viewer
Включите сервис libvirtd
sudo systemctl enable --now libvirtd
Запустите  ''virt-manager'', выделите подключение ''QEMU/KVM'', выберите пункт меню ''Правка/Свойства подключения'', на вкладке ''Виртуальные сети'' включите сеть ''default'', изменив значение ''Диапазон DHCP-'' c ''192.168.122.2 - 192.168.122.254'' на ''192.168.122.129 - 192.168.122.254''.
В описанном выше примере создается kubernetes кластер из 3-х узлов:
* ''master01'' с IP-адресом ''192.168.122.65'';
* ''worker01'' с IP-адресом ''192.168.122.66'';
* ''worker02'' с IP-адресом ''192.168.122.67''.
=== Установка master-узла master01 ===
==== Формирование YML butane-файла для узла master01 ====
Cформируем YML butane-файл ''k8s_master_1.yml'' для master-узла:
variant: fcos
version: 1.3.0
ignition:
  config:
    merge:
      - local: k8s_master_btrfs.ign
storage:
  files:
    - path: /etc/hostname
      overwrite: true
      contents:
        inline:
          master01
    - path: /etc/hosts
      append:
        - inline: |
            192.168.122.65 master01
            192.168.122.66 worker01
            192.168.122.67 worker02
    - path: /etc/systemd/network/20-wired.network
      overwrite: true
      contents:
        inline: |
          [Match]
          Name=eth0
          [Network]
          DHCP=no
          Address=192.168.122.65/24
          Gateway=192.168.122.1
          DNS=192.168.122.1
  systemd:
  systemd:
   units:
   units:
     - name: initk8s.service
     - name: initk8smaster01.service
       enabled: true
       enabled: false
       contents: |
       contents: |
         [Unit]
         [Unit]
Строка 77: Строка 432:
         Environment="KUBECONFIG=/etc/kubernetes/admin.conf"
         Environment="KUBECONFIG=/etc/kubernetes/admin.conf"
         ExecStartPre=loadDockerArchiveImages.sh
         ExecStartPre=loadDockerArchiveImages.sh
         ExecStart=kubeadm init --cri-socket=/var/run/crio/crio.sock --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=SystemVerification
         ExecStart=kubeadm init --cri-socket=/var/run/crio/crio.sock --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=SystemVerification --kubernetes-version=v1.20.12
         ExecStartPost=kubectl taint nodes localhost node-role.kubernetes.io/master-
        ExecStartPost=kubectl apply -f /usr/share/k8s/flannel/kube-flannel.yml
         #ExecStartPost=kubectl taint nodes master01 node-role.kubernetes.io/master-
         [Install]
         [Install]
         WantedBy=multi-user.target
         WantedBy=multi-user.target


Данный YML-файл:
* в элементе ''ignition.config.merge.local'' импортирует из файла ''k8s_master_btrfs.ign'' описанную выше в файле ''k8s_master_btrfs.ign'' конфигурацию, сливая(''merge'') ее с нижеописанной конфигурацией;
* заменяет в файле ''/etc/hostname'' имя узла на ''master01'';
* добавляет в файл ''/etc/hosts'' привязку имен узлов ''master01'', ''worker01'', ''worker02'' к их IP-адресам;
* перезаписывает файл конфигурации интерфейса ''eth0'', указывая в ней IP-адреса master-узла, шлюза и DNS-сервера;
* создает unit-сервис ''initk8smaster01.service'' для инициализации узла ''master01''.
В отличие от односерверного варианта  unit-сервис ''initk8smaster01.service'':
* загружает и конфигурирует overlay-сеть ''flannel'' для маршрутизации трафика между узлами;
* не снимает ограничение (''taint'') на запуск на master-узле POD'ов из namespace ''default''.
Если Вы планируете запускать  POD'ы из namespace ''default'' на master-узле, раскомментируйте:
        ExecStartPost=kubectl taint nodes master01 node-role.kubernetes.io/master-
==== Запуск образа как master01 ====
Запуск образа производится скриптом ''createMaster1.sh'':
#!/bin/sh
if ! butane -d . -p k8s_master_1.yml  > k8s_master_1.ign
then
  exit 1
fi
cp $IMAGEHOME/sisyphus_k8s.x86_64.*.qemu.qcow2 k8s_master_1.qcow2
qemu-img create -f qcow2 master01_hdb.qcow2 10G
virt-install --name k8s_master_1 \
  --vcpus 2 \
  --ram 4096 \
  --os-variant altlinux1.0 \
  --import \
  --disk k8s_master_1.qcow2 \
  --disk master01_hdb.qcow2 \
  --vnc \
  --qemu-commandline="-fw_cfg name=opt/com.coreos/config,file=$PWD/k8s_master_1.ign"
Чтобы виртуальные машины могли подключиться к сети default подключения QEMU/KVM, надо запускать этот скрипт создания виртуальной машины и последующие от имени пользователя root. Удалить ошибочно созданную виртуальную машину можно через графический интерфейс в приложении virt-manager.
После запуска образа перейдите в одно ''Менеджера виртуальных машин'' и проверьте запуск виртуальной машины ''k8s_master_1''.
После запуска виртуальной машины  ''k8s_master_1''(появления промптера ''login'' для входа):
* зайдите на нее по протоколу ssh:
ssh altcos@192.168.122.65
* запустите сервис инициализации master-узла:
sudo systemctl start initk8smaster01
* после окончания запуска сервиса перевойдите в пользователя ''altcos'' и проверьте работу всех необходимых сервисов:
sudo -i kubectl get all -A
В течение минуты вывод команды должен стать следующим:
NAMESPACE    NAME                                  READY  STATUS    RESTARTS  AGE
kube-system  pod/coredns-74ff55c5b-c9z4j            1/1    Running  0          82s
kube-system  pod/coredns-74ff55c5b-s8ntc            1/1    Running  0          82s
kube-system  pod/etcd-master01                      1/1    Running  0          16s
kube-system  pod/kube-apiserver-master01            1/1    Running  0          16s
kube-system  pod/kube-controller-manager-master01  1/1    Running  0          13s
kube-system  pod/kube-flannel-ds-xlkwf              1/1    Running  0          82s
kube-system  pod/kube-proxy-x4pwc                  1/1    Running  0          82s
kube-system  pod/kube-scheduler-master01            1/1    Running  0          31s
NAMESPACE    NAME                TYPE        CLUSTER-IP  EXTERNAL-IP  PORT(S)                  AGE
default      service/kubernetes  ClusterIP  10.96.0.1    <none>        443/TCP                  98s
kube-system  service/kube-dns    ClusterIP  10.96.0.10  <none>        53/UDP,53/TCP,9153/TCP  97s
NAMESPACE    NAME                            DESIRED  CURRENT  READY  UP-TO-DATE  AVAILABLE  NODE SELECTOR            AGE
kube-system  daemonset.apps/kube-flannel-ds  1        1        1      1            1          <none>                  97s
kube-system  daemonset.apps/kube-proxy        1        1        1      1            1          kubernetes.io/os=linux  97s
NAMESPACE    NAME                      READY  UP-TO-DATE  AVAILABLE  AGE
kube-system  deployment.apps/coredns  2/2    2            2          97s
NAMESPACE    NAME                                DESIRED  CURRENT  READY  AGE
kube-system  replicaset.apps/coredns-74ff55c5b  2        2        2      82s


Каталог '''root''' имеет следующую структуру:
==== Генерация ssh-ключей и сохранение открытого ключа ====


root/
Залогинившись под пользователем ''altcos'' master-узла, сгенерируйте ssh-ключи для беспарольного доступа на остальные узла кластера.
├── etc
     ├── containers
     │   └── storage.conf
     └── docker
        └── daemon.json


Файлы ''/etc/containers/storage.conf'', ''/etc/docker/daemon.json'' являются стандартными файлами конфигурации для  
$ ssh-keygen
''crio''('podman') и ''docker'' с измененными storage-драйверами с ''overlay'' на ''btrfs''.
Generating public/private rsa key pair.
Enter file in which to save the key (/var/home/altcos/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /var/home/altcos/.ssh/id_rsa
Your public key has been saved in /var/home/altcos/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:21N0WApmbf9bk61SK9NMMYRO00MCUhhxHmgc28zbYxk altcos@master01
The key's randomart image is:
+---[RSA 3072]----+
|      .=BOo.+o  |
|        =@ o*=+  |
|      .. =+E+.. |
|          +.++  |
|        S . *  +o|
|        o o .oo+|
|        . o  = o+|
|          .+ =. |
|            +  |
+----[SHA256]-----+
Скопируйте открытый ключ из файла  ''/var/home/altcos/.ssh/id_rsa.pub''.
Он будет использоваться при формировании YML butane-файла для worker-узлов.


==== Формирование строки подключения worker-узла к кластеру ====


Если Вы планировать стандартный storage-драйвер ''overlay'' то в в YML-файле,  
Залогинившись под пользователем altcos master-узла, наберите команду просмотра логов сервиса ''initk8smaster01'':
* секции ''storage.trees'', 'storage.files' можно опустить
  journalctl -u initk8smaster01
* в секции ''storage.filesystem.format'' указать ''ext4'';
Каталог ''root'' в этом случае не нужен.


Найдите в логах строку подключения к кластеру:
kubeadm join 192.168.122.65:6443 --token ... --discovery-token-ca-cert-hash sha256:...


== Запуск образа ==
Скопируйте ее, добавив к ней параметр ''--cri-socket=/var/run/crio/crio.sock ''.
Данная строка будет использоваться при формировании YML butane-файла для worker-узлов.


Запуск образа производится скриптом:
=== Установка worker-узла worker01 ===


==== Формирование YML butane-файла для узла worker01 ====
Cформируем YML butane-файл ''k8s_worker_1.yml'' для 1-го worker-узла:
variant: fcos
version: 1.3.0
ignition:
  config:
    merge:
      - local: k8s_master_btrfs.ign
passwd:
  users:
    - name: altcos
      groups:
        - wheel
        - docker
      password_hash: ..
      ssh_authorized_keys:
        - ssh-rsa ...
        # Открытый RSA-ключ master-узла
        - ssh-rsa ... altcos@master01
storage:
  files:
    - path: /etc/hostname
      overwrite: true
      contents:
        inline:
          worker01
    - path: /etc/hosts
      append:
        - inline: |
            192.168.122.65 master01
            192.168.122.66 worker01
            192.168.122.67 worker02
    - path: /etc/systemd/network/20-wired.network
      overwrite: true
      contents:
        inline: |
          [Match]
          Name=eth0
          [Network]
          DHCP=no
          Address=192.168.122.66/24
          Gateway=192.168.122.1
          DNS=192.168.122.1
Данный YML-файл:
* в элементе ''ignition.config.merge.local'' импортирует из файла ''k8s_master_btrfs.ign'' описанную выше в файле ''k8s_master_btrfs.ign'' конфигурацию, сливая(''merge'') ее с нижеописанной конфигурацией;
* в элемент ''passwd.users[0].ssh_authorized_keys'' добавлен открытый ключ пользователя ''altcos'' master-узла;
* заменяет в файле ''/etc/hostname'' имя узла на ''worker01'';
* добавляет в файл ''/etc/hosts'' привязку имен узлов ''master01'', ''worker01'', ''worker02'' к их IP-адресам;
* перезаписывает файл конфигурации интерфейса ''eth0'', указывая в ней IP-адреса worker-узла, шлюза и DNS-сервера;
==== Запуск образа как worker01 ====
Запуск образа производится скриптом ''createWorker1.sh'':
  #!/bin/sh
  #!/bin/sh
if ! butane -d . -p k8s_worker_1.yml  > k8s_worker_1.ign
then
  exit 1
fi
cp $IMAGEHOME/sisyphus_k8s.x86_64.*.qemu.qcow2 k8s_worker_1.qcow2
qemu-img create -f qcow2 worker_1_hdb.qcow2 10G
virt-install --name k8s_worker_1 \
  --vcpus 2 \
  --ram 2048 \
  --os-variant altlinux1.0 \
  --import \
  --disk k8s_worker_1.qcow2 \
  --disk worker_1_hdb.qcow2 \
  --vnc \
  --qemu-commandline="-fw_cfg name=opt/com.coreos/config,file=$PWD/k8s_worker_1.ign"
После запуска образа перейдите в одно ''Менеджера виртуальных машин'' и проверьте запуск виртуальной машины ''k8s_worker_1''.
После запуска виртуальной машины  ''k8s_worker_1'' (появления промптера ''login'' для входа)
* перейдите в терминальный интерфейс пользователя ''altcos'' виртуальной машины master-узла (''k8s_master_1'')
* наберите команду просмотра логов сервиса initk8smaster01
journalctl -u initk8smaster01
* найдите в ней строку подключения рабочих узлов
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.122.65:6443 --token ... \
  --discovery-token-ca-cert-hash sha256:...
* добавьте в ней параметр '--cri-socket=/var/run/crio/crio.sock'  (IP-адрес мастер узла 'xx.xx.xx.xx:6443' можно заменить на домен master01:6443);
* вызовите удаленно на рабочем узле ''worker01'' команду подключения к кластеру:
ssh worker01 sudo kubeadm join master01:6443 --token ...  --discovery-token-ca-cert-hash sha256:... --cri-socket=/var/run/crio/crio.sock
После завершения работы сервиса проверьте текущий список узлов кластера:
$ kubectl get nodes -o wide
NAME      STATUS  ROLES                  AGE    VERSION  INTERNAL-IP      EXTERNAL-IP  OS-IMAGE                    KERNEL-VERSION        CONTAINER-RUNTIME
master01  Ready    control-plane,master  3h17m  v1.20.8  192.168.122.65  <none>        ALT Starterkit (Hypericum)  5.10.77-std-def-alt1  cri-o://1.20.0
worker01  Ready    <none>                30m    v1.20.8  192.168.122.66  <none>        ALT Starterkit (Hypericum)  5.10.77-std-def-alt1  cri-o://1.20.0
Проверьте вывод команды
  $ kubectl get all -A -o wide
NAMESPACE    NAME                                  READY  STATUS    RESTARTS  AGE    IP              NODE      NOMINATED NODE  READINESS GATES
kube-system  pod/coredns-74ff55c5b-c9z4j            1/1    Running  0          3h22m  10.85.0.2        master01  <none>          <none>
kube-system  pod/coredns-74ff55c5b-s8ntc            1/1    Running  0          3h22m  10.85.0.3        master01  <none>          <none>
kube-system  pod/etcd-master01                      1/1    Running  0          3h21m  192.168.122.65  master01  <none>          <none>
kube-system  pod/kube-apiserver-master01            1/1    Running  0          3h21m  192.168.122.65  master01  <none>          <none>
kube-system  pod/kube-controller-manager-master01  1/1    Running  0          3h21m  192.168.122.65  master01  <none>          <none>
kube-system  pod/kube-flannel-ds-tgw4l              1/1    Running  0          35m    192.168.122.66  worker01  <none>          <none>
kube-system  pod/kube-flannel-ds-xlkwf              1/1    Running  0          3h22m  192.168.122.65  master01  <none>          <none>
kube-system  pod/kube-proxy-4xwm6                  1/1    Running  0          35m    192.168.122.66  worker01  <none>          <none>
kube-system  pod/kube-proxy-x4pwc                  1/1    Running  0          3h22m  192.168.122.65  master01  <none>          <none>
kube-system  pod/kube-scheduler-master01            1/1    Running  0          3h21m  192.168.122.65  master01  <none>          <none>
NAMESPACE    NAME                TYPE        CLUSTER-IP  EXTERNAL-IP  PORT(S)                  AGE    SELECTOR
default      service/kubernetes  ClusterIP  10.96.0.1    <none>        443/TCP                  3h22m  <none>
kube-system  service/kube-dns    ClusterIP  10.96.0.10  <none>        53/UDP,53/TCP,9153/TCP  3h22m  k8s-app=kube-dns
NAMESPACE    NAME                            DESIRED  CURRENT  READY  UP-TO-DATE  AVAILABLE  NODE SELECTOR            AGE    CONTAINERS    IMAGES                          SELECTOR
kube-system  daemonset.apps/kube-flannel-ds  2        2        2      2            2          <none>                  3h22m  kube-flannel  quay.io/coreos/flannel:v0.15.1  app=flannel
kube-system  daemonset.apps/kube-proxy        2        2        2      2            2          kubernetes.io/os=linux  3h22m  kube-proxy    k8s.gcr.io/kube-proxy:v1.20.12  k8s-app=kube-proxy
NAMESPACE    NAME                      READY  UP-TO-DATE  AVAILABLE  AGE    CONTAINERS  IMAGES                    SELECTOR
kube-system  deployment.apps/coredns  2/2    2            2          3h22m  coredns      k8s.gcr.io/coredns:1.7.0  k8s-app=kube-dns
NAMESPACE    NAME                                DESIRED  CURRENT  READY  AGE    CONTAINERS  IMAGES                    SELECTOR
kube-system  replicaset.apps/coredns-74ff55c5b  2
 
Количество работающих POD'ов ''kube-proxy'' и ''kube-flannel-ds'' должно быть равно двум - по одному на каждом узле кластера
=== Установка worker-узла worker02 ===
Установка worker-узла worker02 производится аналогичным образом:
* скопируйте YML butane файл 'k8s_worker_1.yml' в k8s_worker_2.yml, изменив в нем:
  * имя узла в файле ''/etc/hostname'' с ''worker01'' на ''worker02'';
  * IP-адрес сетевого интерфейса в файле ''/etc/systemd/network/20-wired.network'' с ''192.168.122.66'' на ''192.168.122.67'';
* скопируйте стартовый скрипт ''createWorker1.sh'' в скрипт ''createWorker2.sh'', изменив в нем
''worker_1'' на ''worker_2''.
После запуска образа перейдите в одно ''Менеджера виртуальных машин'' и проверьте запуск виртуальной машины ''k8s_worker_2''.
После запуска виртуальной машины  ''k8s_worker_2'' (появления промптера ''login'' для входа)
перейдите в терминальный интерфейс пользователя ''altcos'' виртуальной машины master-узла (''k8s_master_1'')
и наберите команду удаленного вызова на виртуальной машине ''k8s_worker_2'' сервиса подключения к kubernetes-кластеру:
ssh worker02 sudo systemctl  start joink8s
После завершения работы сервиса проверьте текущий список узлов кластера:
$ kubectl get nodes -o wide
NAME      STATUS  ROLES                  AGE    VERSION  INTERNAL-IP      EXTERNAL-IP  OS-IMAGE                    KERNEL-VERSION        CONTAINER-RUNTIME
master01  Ready    control-plane,master  3h46m  v1.20.8  192.168.122.65  <none>        ALT Starterkit (Hypericum)  5.10.77-std-def-alt1  cri-o://1.20.0
worker01  Ready    <none>                58m    v1.20.8  192.168.122.66  <none>        ALT Starterkit (Hypericum)  5.10.77-std-def-alt1  cri-o://1.20.0
worker02  Ready    <none>                26s    v1.20.8  192.168.122.67  <none>        ALT Starterkit (Hypericum)  5.10.77-std-def-alt1  cri-o://1.20.0
Проверьте вывод команды
  $ kubectl get all -A -o wide
NAMESPACE    NAME                                  READY  STATUS    RESTARTS  AGE    IP              NODE      NOMINATED NODE  READINESS GATES
...
kube-system  pod/kube-flannel-ds-tgw4l              1/1    Running  0          61m    192.168.122.66  worker01  <none>          <none>
kube-system  pod/kube-flannel-ds-xlkwf              1/1    Running  0          3h48m  192.168.122.65  master01  <none>          <none>
kube-system  pod/kube-flannel-ds-xv264              1/1    Running  0          2m54s  192.168.122.67  worker02  <none>          <none>
kube-system  pod/kube-proxy-4xwm6                  1/1    Running  0          61m    192.168.122.66  worker01  <none>          <none>
kube-system  pod/kube-proxy-rww95                  1/1    Running  0          2m54s  192.168.122.67  worker02  <none>          <none>
kube-system  pod/kube-proxy-x4pwc                  1/1    Running  0          3h48m  192.168.122.65  master01  <none>          <none>
...
NAMESPACE    NAME                            DESIRED  CURRENT  READY  UP-TO-DATE  AVAILABLE  NODE SELECTOR            AGE    CONTAINERS    IMAGES                          SELECTOR
kube-system  daemonset.apps/kube-flannel-ds  3        3        3      3            3          <none>                  3h48m  kube-flannel  quay.io/coreos/flannel:v0.15.1  app=flannel
kube-system  daemonset.apps/kube-proxy        3        3        3      3            3          kubernetes.io/os=linux  3h48m  kube-proxy    k8s.gcr.io/kube-proxy:v1.20.12  k8s-app=kube-proxy
Количество работающих POD'ов kube-proxy и kube-flannel-ds должно быть равно трем - по одному на каждом узле кластера.


  butane -d . -p k8s_master.yml > k8s_master.ign
Аналогичным образом добавляются и остальные рабочие узла kubernetes_кластера.
 
 
== Создание docker swarm кластеров в среде libvirt ==
 
Для создания ''docker swarm'' кластера зайдите под пользователем ''altcos'' на master-узел ''master01'' и наберите команду инициализации кластера:
$ sudo docker swarm init
Swarm initialized: current node (...) is now a manager.
To add a worker to this swarm, run the following command:
    docker swarm join --token ... 192.168.122.65:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.


  sudo qemu-system-x86_64 \
Скопируйте строку подключения ''docker swarm join ...'' и запустите ее удаленно на рабочих узлах кластера: 
-m 2048 \
  $ ssh worker01 sudo docker swarm join --token ... 192.168.122.65:2377
-machine accel=kvm \
This node joined a swarm as a worker.
-cpu host \
$ ssh worker02 sudo docker swarm join --token ... 192.168.122.65:2377
-smp 2 \
This node joined a swarm as a worker.
-hda k8s.20211116.0.0.qcow2 \
-hdb hdb.qcow2 \
-fw_cfg name=opt/com.coreos/config,file=k8s_master.ign \
-net user,hostfwd=tcp::10222-:22 -net nic


Обратите внимание, что за работы узла ''kubernetes'' требуется не менее 2-х ядер процессора и не менее 2GB оперативной памяти.
Проверьте подключение узлов к ''docker swarm'' -кластеру:
$ docker node ls
ID                            HOSTNAME  STATUS    AVAILABILITY  MANAGER STATUS  ENGINE VERSION
78lkzptg0o3zlgmoz0dnxrevx *  master01  Ready    Active        Leader          20.10.10
ssdv63wtxm3ytom54fia93kg1    worker01  Ready    Active                          20.10.10
1isza4rwiw3q2fykxdnuxp4pp    worker02  Ready    Active                          20.10.10

Текущая версия от 14:02, 25 декабря 2023

Подветка K8S обеспечивает разворачивание серверов для организации kubernetes-кластера.

Дистрибутив ALTLinux обеспечивает разворачивание kubernetes-кластера под двумя типами "движков" (см. Kubernetes):

  • docker;
  • CRI-O (podman)

В текущей реализации был выбран вариант движка CRI-O, обеспечивающий повышенный уровень защиты запускаемых контейнеров. Но, так как подветка K8S наследуется от основной ветки потока, включающей движок docker, в рамках данной подветки можно запускать docker-контейнеры, сервисы под docker-compose и организовывать параллельно (или вместо) с кластером kubernetes и docker swarm кластер.

образ подветки altcos/x86_64/sisyphus/k8s

Скачать образ можно тут

Каталог расположения образа хранится во внешней переменной IMAGEHOME.

Образ включает в себя архив docker-образов, необходимых для разворачивания kubernetes-кластера. Так что для разворачивания кластера доступ в Интернет не нужен.

До начала работы установите пакеты :

apt-get install butane ignition ignition-validate

Запуск образа в режиме master-узла через qemu-system-x86_64

Подготовка YML butane-файла для master-узла

Для запуска необходимо подготовить YML butane-файл, обеспечивающий следующий функционал при запуске образа:

  • обеспечение доступа без пароля администратора по открытому ключу под пользователем altcos (passwd.users.ssh_authorized_keys)
  • получение без пароля прав администратора (sudo) для пользователя altcos (файл /etc/sudoers.d/altcos);
  • формирование переменных окружения для вызова команды kubectl (файл /etc/profile.d/kube.sh- данный скрипт срабатывает только при повторном заходе после инициализации кластера) ;
  • создание systemd-сервиса для инициализации master-узла kubernetes-кластера.

Файл конфигурации k8s_master.yml выглядит следующим образом:

variant: fcos
version: 1.3.0
passwd:
  users:
    - name: root
      groups:
        - wheel
        - docker
      password_hash: ...
      ssh_authorized_keys:
        - ssh-rsa ... 
    - name: altcos
      groups:
        - wheel
        - docker
      password_hash: ...
      ssh_authorized_keys:
        - ssh-rsa ... 
storage:
  files:
    - path: /etc/sudoers.d/altcos
      contents:
        inline: |
          altcos ALL=NOPASSWD: ALL
    - path: /etc/profile.d/kube.sh
      mode: 0755
      contents:
        inline: |
          # Set  kube environment
          if [ `id -u ` = 0 ]
          then
            export KUBECONFIG=/etc/kubernetes/admin.conf
          else
            if [ -f /etc/kubernetes/admin.conf ]
            then
              if [ ! -d ~/.kube ]
              then
                mkdir -p ~/.kube
                sudo cp -i /etc/kubernetes/admin.conf ~/.kube/config
                sudo chown $(id -u):$(id -g) ~/.kube/config
                kubectl completion bash >> ~/.bashrc
              fi
            fi
          fi
systemd:
  units:
    - name: initk8smaster.service
      enabled: false
      contents: |
        [Unit]
        Description=Start up kubernetes in master mode
        After=crio.service kube-proxy.service kubelet.service systemd-networkd.service systemd-resolved.service
        [Service]
        Type=oneshot
        RemainAfterExit=yes
        Environment="KUBECONFIG=/etc/kubernetes/admin.conf"
        ExecStartPre=loadDockerArchiveImages.sh
        ExecStart=kubeadm init --cri-socket=/var/run/crio/crio.sock --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=SystemVerification --kubernetes-version=v1.20.12
        ExecStartPost=kubectl taint nodes localhost node-role.kubernetes.io/master-
        [Install]
        WantedBy=multi-user.target

Запуск образа как master-узла

Запуск образа производится скриптом run_master.sh:

#!/bin/sh
if ! butane -p k8s_master.yml > k8s_master.ign
then
  exit 1;
fi
cp $IMAGEHOME/sisyphus_k8s.x86_64.*.qemu.qcow2 k8s.qcow2

sudo qemu-system-x86_64 \
	-m 2048 \
	-machine accel=kvm \
	-cpu host \
	-smp 2 \
	-hda k8s.qcow2 \
	-fw_cfg name=opt/com.coreos/config,file=k8s_master.ign \
	-net user,hostfwd=tcp::10222-:22 -net nic

Команда butane производит конвертацию butane-файла YML k8s_master.yml в JSON-формате ignition в файл k8s_master.ign.

Команда cp копирует образ ядра в файл k8s.qcow2.

Обратите внимание, что для работы узла kubernetes требуется не менее 2-х ядер процессора и не менее 2GB оперативной памяти.

Доступ по протоколу ssh обеспечивается через порт 10222 HOST-компьютера localhost.

Запуск kubernetes на master-узле

Для того, чтобы запустить сервис:

  • зайдите через консоль или через ssh под пользователем altcos;
  • выполните запуск сервиса initk8smaster:
$ sudo systemctl start initk8smaster

Данные действия можно сделать и "удаленно" по протоколу ssh:

ssh -p 10222 altcos@localhost sudo systemctl start initk8smaster

Во время запуска длительностью менее минуты:

  • производится загрузка из архива, входящего в состав qcow2-образа, необходимых docker-образов;
  • запуск их как сервисов;
  • инициализация master-узла кластера;

Логи запуска можно посмотреть командой:

$ journalctl -u initk8smaster
Starting Start up kubernetes in master mode...
...
Loaded image(s): k8s.gcr.io/coredns:1.7.0
...
Loaded image(s): k8s.gcr.io/etcd:3.4.13-0
...
Your Kubernetes control-plane has initialized successfully!
...
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 10.0.2.15:6443 --token yhhb22.0q7bovdkg89l6hr7 \
    --discovery-token-ca-cert-hash sha256:16a864c569f23a5ecacafe5cb42931840fc7e4896b8c3946d0710133ea0b82bc
...
node/localhost untainted
Finished Start up kubernetes in master mode.

Рабочие (worker) узлы можно присоединять к кластеру взятой из лога командой

kubeadm join ...

После запуска initk8smaster следует перелогиниться, чтобы в домашнем каталоге появился файл ~/.kube/config. Файл ~/.kube/config в домашнем каталоге пользователя altcos автоматически создается скриптом /etc/profile.d/kube.sh, описанным в YML-butane файле, при входе в пользователя altcos после инициализации узла кластера.

Работа с master-узлом кластера

Вы можете работать с мастер узлом как под обычным пользователем (например altcos), так и от имени суперпользователя.

Для работы с master-узлом кластера из суперпользователя укажите при вызове sudo флаг -i. Например:

sudo -i kubectl get all -A

Проверка работы master-узла

Для проверки работы узла наберите команду

# kubectl get nodes
NAME        STATUS   ROLES                  AGE   VERSION
localhost   Ready    control-plane,master   41m   v1.20.8

Для проверки работы всего функционала наберите команду:

$ kubectl get all -A
NAMESPACE     NAME                                    READY   STATUS    RESTARTS   AGE
kube-system   pod/coredns-74ff55c5b-b4rxp             1/1     Running   0          9h
kube-system   pod/coredns-74ff55c5b-kfsxv             1/1     Running   0          9h
kube-system   pod/etcd-localhost                      1/1     Running   0          9h
kube-system   pod/kube-apiserver-localhost            1/1     Running   0          9h
kube-system   pod/kube-controller-manager-localhost   1/1     Running   0          9h
kube-system   pod/kube-proxy-4t95d                    1/1     Running   0          9h
kube-system   pod/kube-scheduler-localhost            1/1     Running   0          9h

NAMESPACE     NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
default       service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP                  9h
kube-system   service/kube-dns     ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   9h

NAMESPACE     NAME                        DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
kube-system   daemonset.apps/kube-proxy   1         1         1       1            1           kubernetes.io/os=linux   9h

NAMESPACE     NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
kube-system   deployment.apps/coredns   2/2     2            2           9h

NAMESPACE     NAME                                DESIRED   CURRENT   READY   AGE
kube-system   replicaset.apps/coredns-74ff55c5b   2         2         2       9h

Должен быть:

  • развернут deployment 'coredns' с двумя репликами (replicaset coredns-xxx-yyy);
  • запушен daemonset 'kube-proxy' с одной (по числу узлов) репликой;

Все перечисленные POD'ы должны иметь состояние READY 1/1.

В kubernetes по умолчанию на master-узле не могут запускаться поды в namespace default. В одноузловом варианте в данном примере для снятия этого ограничения (см. YML-файл выше) запускается команда

kubectl taint nodes localhost node-role.kubernetes.io/master-

Для проверки запуска POD'ов на master-узле в namespace default наберите команду:

kubectl apply -f https://k8s.io/examples/application/deployment.yaml

Поcле загрузки образа nginx проверьте запуск POD'а на master-узле:

# kubectl get pods        
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-66b6c48dd5-5nfc6   1/1     Running   0          8m16s
nginx-deployment-66b6c48dd5-j8mww   1/1     Running   0          8m16s

Действия после перезагрузке системы

После перезагрузки системы никаких дополнительных действий не требуется. master-узел kubernetes-кластера поднимается автоматически.

Подключение дополнительного BTRFS диска

Так как размер основного диска достаточно небольшой (около 4GB) для хранения образов и запуска pod'ов необходимо создать дополнительный диск. В приведенных ниже примерах для хранения каталогов образов, контейнеров, ... в docker и CRI-O создается и монтируется отдельный диск с файловой системой BTRFS.

Формирование YML butane-файла

Сформируем YML butane-файл k8s_master_btrfs.yml для форматирования, подключения тома BTRFS, изменения каталогов, размещения данных docker-демона и CRI-O/podman:

variant: fcos
version: 1.3.0
storage:
  disks:
    - device: /dev/sdb # создадим на диске /dev/sdb партицию /dev/sdb1
      wipe_table: true
      partitions:
        - number: 1
          label: docker
  filesystems:
    - device: /dev/sdb1 # создадим в партиции /dev/sdb1 файловую систему BTRFS
      format: btrfs
      wipe_filesystem: true
      label: docker
      with_mount_unit: false
  directories:
    - path: /var/mnt/docker # создадим каталог монтирования тома
      overwrite: true
  files:
    - path: /etc/fstab # добавим строку монтирования btrfs-тома на каталог /var/mnt/docker
      append:
        - inline: |
            LABEL=docker /var/mnt/docker btrfs defaults 0 2
            /var/mnt/docker/docker/ /var/lib/docker none bind 0 0
            /var/mnt/docker/containers/ /var/lib/containers/ none bind 0 0

    # заменим в конфигурации dockerd-демона:
    # тип storage-driver с overlay2 на btrfs
    - path: /etc/docker/daemon.json
      overwrite: true
      contents:
        inline: |
          {
          "init-path": "/usr/bin/tini",
          "userland-proxy-path": "/usr/bin/docker-proxy",
          "default-runtime": "docker-runc",
          "live-restore": false,
          "log-driver": "journald",
          "runtimes": {
            "docker-runc": {
              "path": "/usr/bin/runc"
            }
          },
          "default-ulimits": {
            "nofile": {
            "Name": "nofile",
            "Hard": 64000,
            "Soft": 64000
            }
          },
          "data-root": "/var/lib/docker/",
          "storage-driver": "btrfs"
          }
    # заменим в конфигурации CRI-O тип driver с overlay на btrfs
    - path: /etc/crio/crio.conf.d/00-btrfs.conf
      overwrite: true
      contents:
        inline: |
          [crio]
          root = "/var/lib/containers/storage"
          runroot = "/var/run/containers/storage"
          storage_driver = "btrfs"
          storage_option = []
          [crio.runtime]
          conmon = "/usr/bin/conmon"
          [crio.network]
          plugin_dirs = [
            "/usr/libexec/cni",
            "/opt/cni/bin/"
          ]
    # заменим в конфигурации podman тип driver с overlay2 на btrfs
    - path: /etc/containers/storage.conf
      overwrite: true
      contents:
        inline: |
          [storage]
          driver = "btrfs"
          runroot = "/var/run/containers/storage"
          graphroot = "/var/lib/containers/storage"

          [storage.options]
          additionalimagestores = [
          ]
          [storage.options.overlay]
          mountopt = "nodev,metacopy=on"
    # исключим определение flannel-подсети в CRIO 
    - path: /etc/cni/net.d/100-crio-bridge.conf
      overwrite: true
      contents:
        inline: |
          {"type": "bridge"}

Данный YML-файл:

  • В элементе ignition.config.merge.local импортирует из файла k8s_master.ign описанную выше в файле k8s_master.yml конфигурацию, сливая(merge) ее с нижеописанной конфигурацией.
  • Создает раздел /dev/sdb1.
  • Создает в разделе файловую систему типа BTRFS.
  • Создает каталог монтирования /var/mnt/docker.
  • Добавляет в /etc/fstab
 * строку монтирования файловой системы раздела /dev/sdb1 в каталог /var/mnt/docker;
 * монтирует каталог /var/lib/docker на /var/mnt/docker/docker/;
 * монтирует каталог /var/lib/containers/ на /var/mnt/docker/containers/.
  • Заменяет файлы конфигурации docker-демона, CRI-O, podman, меняя тип драйвера с overlay2 на btrfs и перемещая каталоги хранения слоев образов и контейнеров из каталога /var/lib диска /dev/sda1 в каталог /var/mnt/docker диска /dev/sdb1.
  • В текущей версии пакета cri-o-1.22.1-alt1.x86_64 файл конфигурации /etc/cni/net.d/100-crio-bridge.conf задает адрес подсети для интерфейса cni0. Для корректной работы сетевого плугина flannel необходимо исключить определение подсети, так как flannel самостоятельно на основе полученной конфигурации сети конфигурирует IP-адрес интерфейса cni0.

Запуск образа как master-узла с хранилищем образов и контейнеров на BTRFS-диске

Запуск образа производится скриптом run_master_btrfs.sh

#!/bin/sh
if ! butane -d . -p k8s_master_btrfs.yml > k8s_master_btrfs.ign
then
  exit 1;
fi
cp $IMAGEHOME/sisyphus_k8s.x86_64.*.qemu.qcow2 k8s.qcow2
qemu-img create -f qcow2 hdb.qcow2 10G
sudo qemu-system-x86_64 \
	-m 2048 \
	-machine accel=kvm \
	-cpu host \
	-smp 2 \
	-hda k8s.qcow2 \
	-hdb hdb.qcow2 \
	-fw_cfg name=opt/com.coreos/config,file=k8s_master_btrfs.ign \
	-net user,hostfwd=tcp::10222-:22 -net nic 

Данный скрипт аналогичен вышеописанному run_master.sh за исключением:

  • используется файл конфигурации k8s_master_btrfs.yml, объединяющий свои описания с описанием ignition-файла конфигурации k8s_master.ign, сформированного на предыдущем шаге, и записывающий объединенную конфигурация в файл k8s_master.ign.
  • формируется файл hdb.qcow2 размером 10GB для тома с файловой системой BTRFS;
  • при вызове qemu-system-x86_64 данный файл указывается как второй том в параметре -hdb.

Все остальные действия по инициализации одноузлового кластера kubetnetes и работе с ним аналогичны описанным в предыдущем разделе.

Создание kubernetes-кластера с одним мастером (control plane) в среде libvirt

Установите пакеты libvirt, virt-manager, qemu-system-x86-core, virt-viewer.

apt-get install libvirt virt-manager qemu-system-x86-core virt-viewer

Включите сервис libvirtd

sudo systemctl enable --now libvirtd

Запустите virt-manager, выделите подключение QEMU/KVM, выберите пункт меню Правка/Свойства подключения, на вкладке Виртуальные сети включите сеть default, изменив значение Диапазон DHCP- c 192.168.122.2 - 192.168.122.254 на 192.168.122.129 - 192.168.122.254.

В описанном выше примере создается kubernetes кластер из 3-х узлов:

  • master01 с IP-адресом 192.168.122.65;
  • worker01 с IP-адресом 192.168.122.66;
  • worker02 с IP-адресом 192.168.122.67.

Установка master-узла master01

Формирование YML butane-файла для узла master01

Cформируем YML butane-файл k8s_master_1.yml для master-узла:

variant: fcos
version: 1.3.0

ignition:
  config:
    merge:
      - local: k8s_master_btrfs.ign
storage:
  files:
    - path: /etc/hostname
      overwrite: true
      contents:
        inline:
          master01
    - path: /etc/hosts
      append:
        - inline: |
            192.168.122.65 master01
            192.168.122.66 worker01
            192.168.122.67 worker02
    - path: /etc/systemd/network/20-wired.network
      overwrite: true
      contents:
        inline: |
          [Match]
          Name=eth0
          [Network]
          DHCP=no
          Address=192.168.122.65/24
          Gateway=192.168.122.1
          DNS=192.168.122.1

systemd:
  units:
    - name: initk8smaster01.service
      enabled: false
      contents: |
        [Unit]
        Description=Start up kubernetes in master mode
        After=crio.service kube-proxy.service kubelet.service systemd-networkd.service systemd-resolved.service
        [Service]
        Type=oneshot
        RemainAfterExit=yes
        Environment="KUBECONFIG=/etc/kubernetes/admin.conf"
        ExecStartPre=loadDockerArchiveImages.sh
        ExecStart=kubeadm init --cri-socket=/var/run/crio/crio.sock --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=SystemVerification --kubernetes-version=v1.20.12
        ExecStartPost=kubectl apply -f /usr/share/k8s/flannel/kube-flannel.yml
        #ExecStartPost=kubectl taint nodes master01 node-role.kubernetes.io/master-
        [Install]
        WantedBy=multi-user.target

Данный YML-файл:

  • в элементе ignition.config.merge.local импортирует из файла k8s_master_btrfs.ign описанную выше в файле k8s_master_btrfs.ign конфигурацию, сливая(merge) ее с нижеописанной конфигурацией;
  • заменяет в файле /etc/hostname имя узла на master01;
  • добавляет в файл /etc/hosts привязку имен узлов master01, worker01, worker02 к их IP-адресам;
  • перезаписывает файл конфигурации интерфейса eth0, указывая в ней IP-адреса master-узла, шлюза и DNS-сервера;
  • создает unit-сервис initk8smaster01.service для инициализации узла master01.

В отличие от односерверного варианта unit-сервис initk8smaster01.service:

  • загружает и конфигурирует overlay-сеть flannel для маршрутизации трафика между узлами;
  • не снимает ограничение (taint) на запуск на master-узле POD'ов из namespace default.

Если Вы планируете запускать POD'ы из namespace default на master-узле, раскомментируйте:

        ExecStartPost=kubectl taint nodes master01 node-role.kubernetes.io/master-

Запуск образа как master01

Запуск образа производится скриптом createMaster1.sh:

#!/bin/sh
if ! butane -d . -p k8s_master_1.yml  > k8s_master_1.ign
then
  exit 1
fi
cp $IMAGEHOME/sisyphus_k8s.x86_64.*.qemu.qcow2 k8s_master_1.qcow2
qemu-img create -f qcow2 master01_hdb.qcow2 10G
virt-install --name k8s_master_1 \
  --vcpus 2 \
  --ram 4096 \
  --os-variant altlinux1.0 \
  --import \
  --disk k8s_master_1.qcow2 \
  --disk master01_hdb.qcow2 \
  --vnc \
  --qemu-commandline="-fw_cfg name=opt/com.coreos/config,file=$PWD/k8s_master_1.ign"

Чтобы виртуальные машины могли подключиться к сети default подключения QEMU/KVM, надо запускать этот скрипт создания виртуальной машины и последующие от имени пользователя root. Удалить ошибочно созданную виртуальную машину можно через графический интерфейс в приложении virt-manager.

После запуска образа перейдите в одно Менеджера виртуальных машин и проверьте запуск виртуальной машины k8s_master_1.

После запуска виртуальной машины k8s_master_1(появления промптера login для входа):

  • зайдите на нее по протоколу ssh:
ssh altcos@192.168.122.65
  • запустите сервис инициализации master-узла:
sudo systemctl start initk8smaster01
  • после окончания запуска сервиса перевойдите в пользователя altcos и проверьте работу всех необходимых сервисов:
sudo -i kubectl get all -A

В течение минуты вывод команды должен стать следующим:

NAMESPACE     NAME                                   READY   STATUS    RESTARTS   AGE
kube-system   pod/coredns-74ff55c5b-c9z4j            1/1     Running   0          82s
kube-system   pod/coredns-74ff55c5b-s8ntc            1/1     Running   0          82s
kube-system   pod/etcd-master01                      1/1     Running   0          16s
kube-system   pod/kube-apiserver-master01            1/1     Running   0          16s
kube-system   pod/kube-controller-manager-master01   1/1     Running   0          13s
kube-system   pod/kube-flannel-ds-xlkwf              1/1     Running   0          82s
kube-system   pod/kube-proxy-x4pwc                   1/1     Running   0          82s
kube-system   pod/kube-scheduler-master01            1/1     Running   0          31s

NAMESPACE     NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
default       service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP                  98s
kube-system   service/kube-dns     ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   97s

NAMESPACE     NAME                             DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
kube-system   daemonset.apps/kube-flannel-ds   1         1         1       1            1           <none>                   97s
kube-system   daemonset.apps/kube-proxy        1         1         1       1            1           kubernetes.io/os=linux   97s

NAMESPACE     NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
kube-system   deployment.apps/coredns   2/2     2            2           97s

NAMESPACE     NAME                                DESIRED   CURRENT   READY   AGE
kube-system   replicaset.apps/coredns-74ff55c5b   2         2         2       82s

Генерация ssh-ключей и сохранение открытого ключа

Залогинившись под пользователем altcos master-узла, сгенерируйте ssh-ключи для беспарольного доступа на остальные узла кластера.

$ ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/var/home/altcos/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /var/home/altcos/.ssh/id_rsa
Your public key has been saved in /var/home/altcos/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:21N0WApmbf9bk61SK9NMMYRO00MCUhhxHmgc28zbYxk altcos@master01
The key's randomart image is:
+---[RSA 3072]----+
|       .=BOo.+o  |
|        =@ o*=+  |
|       .. =+E+.. |
|           +.++  |
|        S . *  +o|
|         o o .oo+|
|        . o  = o+|
|           .+ =. |
|             +   |
+----[SHA256]-----+

Скопируйте открытый ключ из файла /var/home/altcos/.ssh/id_rsa.pub. Он будет использоваться при формировании YML butane-файла для worker-узлов.

Формирование строки подключения worker-узла к кластеру

Залогинившись под пользователем altcos master-узла, наберите команду просмотра логов сервиса initk8smaster01:

journalctl -u initk8smaster01

Найдите в логах строку подключения к кластеру:

kubeadm join 192.168.122.65:6443 --token ... --discovery-token-ca-cert-hash sha256:...

Скопируйте ее, добавив к ней параметр --cri-socket=/var/run/crio/crio.sock . Данная строка будет использоваться при формировании YML butane-файла для worker-узлов.

Установка worker-узла worker01

Формирование YML butane-файла для узла worker01

Cформируем YML butane-файл k8s_worker_1.yml для 1-го worker-узла:

variant: fcos
version: 1.3.0

ignition:
  config:
    merge:
      - local: k8s_master_btrfs.ign
passwd:
  users:
    - name: altcos
      groups:
        - wheel
        - docker
      password_hash: ..
      ssh_authorized_keys:
        - ssh-rsa ...
        # Открытый RSA-ключ master-узла 
        - ssh-rsa ... altcos@master01
storage:
  files:
    - path: /etc/hostname
      overwrite: true
      contents:
        inline:
          worker01
    - path: /etc/hosts
      append:
        - inline: |
            192.168.122.65 master01
            192.168.122.66 worker01
            192.168.122.67 worker02
    - path: /etc/systemd/network/20-wired.network
      overwrite: true
      contents:
        inline: |
          [Match]
          Name=eth0
          [Network]
          DHCP=no
          Address=192.168.122.66/24
          Gateway=192.168.122.1
          DNS=192.168.122.1

Данный YML-файл:

  • в элементе ignition.config.merge.local импортирует из файла k8s_master_btrfs.ign описанную выше в файле k8s_master_btrfs.ign конфигурацию, сливая(merge) ее с нижеописанной конфигурацией;
  • в элемент passwd.users[0].ssh_authorized_keys добавлен открытый ключ пользователя altcos master-узла;
  • заменяет в файле /etc/hostname имя узла на worker01;
  • добавляет в файл /etc/hosts привязку имен узлов master01, worker01, worker02 к их IP-адресам;
  • перезаписывает файл конфигурации интерфейса eth0, указывая в ней IP-адреса worker-узла, шлюза и DNS-сервера;

Запуск образа как worker01

Запуск образа производится скриптом createWorker1.sh:

#!/bin/sh
if ! butane -d . -p k8s_worker_1.yml  > k8s_worker_1.ign
then
  exit 1
fi
cp $IMAGEHOME/sisyphus_k8s.x86_64.*.qemu.qcow2 k8s_worker_1.qcow2
qemu-img create -f qcow2 worker_1_hdb.qcow2 10G
virt-install --name k8s_worker_1 \
  --vcpus 2 \
  --ram 2048 \
  --os-variant altlinux1.0 \
  --import \
  --disk k8s_worker_1.qcow2 \
  --disk worker_1_hdb.qcow2 \
  --vnc \
  --qemu-commandline="-fw_cfg name=opt/com.coreos/config,file=$PWD/k8s_worker_1.ign"

После запуска образа перейдите в одно Менеджера виртуальных машин и проверьте запуск виртуальной машины k8s_worker_1.

После запуска виртуальной машины k8s_worker_1 (появления промптера login для входа)

  • перейдите в терминальный интерфейс пользователя altcos виртуальной машины master-узла (k8s_master_1)
  • наберите команду просмотра логов сервиса initk8smaster01
journalctl -u initk8smaster01
  • найдите в ней строку подключения рабочих узлов
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.122.65:6443 --token ... \
 --discovery-token-ca-cert-hash sha256:...
  • добавьте в ней параметр '--cri-socket=/var/run/crio/crio.sock' (IP-адрес мастер узла 'xx.xx.xx.xx:6443' можно заменить на домен master01:6443);
  • вызовите удаленно на рабочем узле worker01 команду подключения к кластеру:
ssh worker01 sudo kubeadm join master01:6443 --token ...  --discovery-token-ca-cert-hash sha256:... --cri-socket=/var/run/crio/crio.sock

После завершения работы сервиса проверьте текущий список узлов кластера:

$ kubectl get nodes -o wide
NAME       STATUS   ROLES                  AGE     VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE                     KERNEL-VERSION         CONTAINER-RUNTIME
master01   Ready    control-plane,master   3h17m   v1.20.8   192.168.122.65   <none>        ALT Starterkit (Hypericum)   5.10.77-std-def-alt1   cri-o://1.20.0
worker01   Ready    <none>                 30m     v1.20.8   192.168.122.66   <none>        ALT Starterkit (Hypericum)   5.10.77-std-def-alt1   cri-o://1.20.0

Проверьте вывод команды

 $ kubectl get all -A -o wide
NAMESPACE     NAME                                   READY   STATUS    RESTARTS   AGE     IP               NODE       NOMINATED NODE   READINESS GATES
kube-system   pod/coredns-74ff55c5b-c9z4j            1/1     Running   0          3h22m   10.85.0.2        master01   <none>           <none>
kube-system   pod/coredns-74ff55c5b-s8ntc            1/1     Running   0          3h22m   10.85.0.3        master01   <none>           <none>
kube-system   pod/etcd-master01                      1/1     Running   0          3h21m   192.168.122.65   master01   <none>           <none>
kube-system   pod/kube-apiserver-master01            1/1     Running   0          3h21m   192.168.122.65   master01   <none>           <none>
kube-system   pod/kube-controller-manager-master01   1/1     Running   0          3h21m   192.168.122.65   master01   <none>           <none>
kube-system   pod/kube-flannel-ds-tgw4l              1/1     Running   0          35m     192.168.122.66   worker01   <none>           <none>
kube-system   pod/kube-flannel-ds-xlkwf              1/1     Running   0          3h22m   192.168.122.65   master01   <none>           <none>
kube-system   pod/kube-proxy-4xwm6                   1/1     Running   0          35m     192.168.122.66   worker01   <none>           <none>
kube-system   pod/kube-proxy-x4pwc                   1/1     Running   0          3h22m   192.168.122.65   master01   <none>           <none>
kube-system   pod/kube-scheduler-master01            1/1     Running   0          3h21m   192.168.122.65   master01   <none>           <none>

NAMESPACE     NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE     SELECTOR
default       service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP                  3h22m   <none>
kube-system   service/kube-dns     ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   3h22m   k8s-app=kube-dns

NAMESPACE     NAME                             DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE     CONTAINERS     IMAGES                           SELECTOR
kube-system   daemonset.apps/kube-flannel-ds   2         2         2       2            2           <none>                   3h22m   kube-flannel   quay.io/coreos/flannel:v0.15.1   app=flannel
kube-system   daemonset.apps/kube-proxy        2         2         2       2            2           kubernetes.io/os=linux   3h22m   kube-proxy     k8s.gcr.io/kube-proxy:v1.20.12   k8s-app=kube-proxy

NAMESPACE     NAME                      READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES                     SELECTOR
kube-system   deployment.apps/coredns   2/2     2            2           3h22m   coredns      k8s.gcr.io/coredns:1.7.0   k8s-app=kube-dns

NAMESPACE     NAME                                DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES                     SELECTOR
kube-system   replicaset.apps/coredns-74ff55c5b   2 
 

Количество работающих POD'ов kube-proxy и kube-flannel-ds должно быть равно двум - по одному на каждом узле кластера

Установка worker-узла worker02

Установка worker-узла worker02 производится аналогичным образом:

  • скопируйте YML butane файл 'k8s_worker_1.yml' в k8s_worker_2.yml, изменив в нем:
 * имя узла в файле /etc/hostname с worker01 на worker02;
 * IP-адрес сетевого интерфейса в файле /etc/systemd/network/20-wired.network с 192.168.122.66 на 192.168.122.67;
  • скопируйте стартовый скрипт createWorker1.sh в скрипт createWorker2.sh, изменив в нем

worker_1 на worker_2.

После запуска образа перейдите в одно Менеджера виртуальных машин и проверьте запуск виртуальной машины k8s_worker_2.

После запуска виртуальной машины k8s_worker_2 (появления промптера login для входа) перейдите в терминальный интерфейс пользователя altcos виртуальной машины master-узла (k8s_master_1) и наберите команду удаленного вызова на виртуальной машине k8s_worker_2 сервиса подключения к kubernetes-кластеру:

ssh worker02 sudo systemctl  start joink8s

После завершения работы сервиса проверьте текущий список узлов кластера:

$ kubectl get nodes -o wide
NAME       STATUS   ROLES                  AGE     VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE                     KERNEL-VERSION         CONTAINER-RUNTIME
master01   Ready    control-plane,master   3h46m   v1.20.8   192.168.122.65   <none>        ALT Starterkit (Hypericum)   5.10.77-std-def-alt1   cri-o://1.20.0
worker01   Ready    <none>                 58m     v1.20.8   192.168.122.66   <none>        ALT Starterkit (Hypericum)   5.10.77-std-def-alt1   cri-o://1.20.0
worker02   Ready    <none>                 26s     v1.20.8   192.168.122.67   <none>        ALT Starterkit (Hypericum)   5.10.77-std-def-alt1   cri-o://1.20.0

Проверьте вывод команды

 $ kubectl get all -A -o wide
NAMESPACE     NAME                                   READY   STATUS    RESTARTS   AGE     IP               NODE       NOMINATED NODE   READINESS GATES
...
kube-system   pod/kube-flannel-ds-tgw4l              1/1     Running   0          61m     192.168.122.66   worker01   <none>           <none>
kube-system   pod/kube-flannel-ds-xlkwf              1/1     Running   0          3h48m   192.168.122.65   master01   <none>           <none>
kube-system   pod/kube-flannel-ds-xv264              1/1     Running   0          2m54s   192.168.122.67   worker02   <none>           <none>
kube-system   pod/kube-proxy-4xwm6                   1/1     Running   0          61m     192.168.122.66   worker01   <none>           <none>
kube-system   pod/kube-proxy-rww95                   1/1     Running   0          2m54s   192.168.122.67   worker02   <none>           <none>
kube-system   pod/kube-proxy-x4pwc                   1/1     Running   0          3h48m   192.168.122.65   master01   <none>           <none>
...

NAMESPACE     NAME                             DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE     CONTAINERS     IMAGES                           SELECTOR
kube-system   daemonset.apps/kube-flannel-ds   3         3         3       3            3           <none>                   3h48m   kube-flannel   quay.io/coreos/flannel:v0.15.1   app=flannel
kube-system   daemonset.apps/kube-proxy        3         3         3       3            3           kubernetes.io/os=linux   3h48m   kube-proxy     k8s.gcr.io/kube-proxy:v1.20.12   k8s-app=kube-proxy

Количество работающих POD'ов kube-proxy и kube-flannel-ds должно быть равно трем - по одному на каждом узле кластера.

Аналогичным образом добавляются и остальные рабочие узла kubernetes_кластера.


Создание docker swarm кластеров в среде libvirt

Для создания docker swarm кластера зайдите под пользователем altcos на master-узел master01 и наберите команду инициализации кластера:

$ sudo docker swarm init
Swarm initialized: current node (...) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token ... 192.168.122.65:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

Скопируйте строку подключения docker swarm join ... и запустите ее удаленно на рабочих узлах кластера:

$ ssh worker01 sudo docker swarm join --token ... 192.168.122.65:2377
This node joined a swarm as a worker.
$ ssh worker02 sudo docker swarm join --token ... 192.168.122.65:2377
This node joined a swarm as a worker.

Проверьте подключение узлов к docker swarm -кластеру:

$ docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
78lkzptg0o3zlgmoz0dnxrevx *   master01   Ready     Active         Leader           20.10.10
ssdv63wtxm3ytom54fia93kg1     worker01   Ready     Active                          20.10.10
1isza4rwiw3q2fykxdnuxp4pp     worker02   Ready     Active                          20.10.10