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

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


В настоящее время (16.11.2021) дистрибутив ALTLinux обеспечивает разворачивание kubernetes-кластера под двумя типами  
Дистрибутив ALTLinux обеспечивает разворачивание kubernetes-кластера под двумя типами  
"движков" (см. [[Kubernetes]]):
"движков" (см. [[Kubernetes]]):
* ''docker'';
* ''docker'';
Строка 12: Строка 12:
параллельно (или вместо) с кластером ''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-кластера.
Так что для разворачивания кластера доступ в Интернет не нужен.


== Запуск образа в режиме master-узла ==
До начала работы установите пакеты :
apt-get install butane ignition ignition-validate
 
== Запуск образа в режиме master-узла через qemu-system-x86_64==


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


Для запуска необходимо подготовить YML butane-файл, обеспечивающий следующий функционал при запуске образа:
Для запуска необходимо подготовить YML butane-файл, обеспечивающий следующий функционал при запуске образа:    
* форматирование дополнительного диска под файловую систему ''BTRFS'' для размещения образов и контейнеров;
* обеспечение доступа без пароля администратора по открытому ключу под пользователем altcos  (''passwd.users.ssh_authorized_keys'')
* монтирование его в каталог ''/var/lib'';
* получение без пароля прав администратора (''sudo'') для пользователя ''altcos'' (файл ''/etc/sudoers.d/altcos'');
* копирование файлов конфигураций и "перекрытых" при монтировании подкаталогов каталога ''/var/lib/''.     
* формирование переменных окружения для вызова команды ''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 AAAAB3NzaC1yc2EAAAADAQABAAABAQC1/GiEhIOcqs14pHPU9tNPKmV9XswRK91KEfqnhLtl9wWkojzuFekosSbCiy6g9DKTWK7rps7uZ4HAAGAof78e60kRWFgNWkQQqG/NKe1rrb0Iwv7kWwGhIWysWgZi466suvEGRFy1ysBpP1K0ChMRti+BWOqe8+OVCjSgT0WpguzL4j6onTXT8WJNTInPty6Fcfw2nMeq0JOu6zh49eblKAuB8nYJqUCNXYy5XJVUB5Qg54dKi2V0kBzbUWeKLhSGsHyBWW6HMsuOC5U9PVAX++h1+25vEarLyK1/R1EhTATkFJ2c6AMCTkrbhlkij0KrnpyHWd7G7vMb14+6Ewih kaf@basealt
         - ssh-rsa ...
  storage:
  storage:
  disks:
    -
      device: /dev/sdb
      wipe_table: true
      partitions:
        - number: 1
          label: varlib
  filesystems:
    - path: /var/lib
      device: /dev/sdb1
      format: btrfs
      wipe_filesystem: true
      label: varlib
      with_mount_unit: true
  trees:
    - local: root # скопировать файловое дерево локального каталога root
      path: /
   files:
   files:
     - path: /etc/docker/daemon.json # переписав файл конфигурации dockerd с поддержкой overlay-драйвера BTRFS
     - path: /etc/sudoers.d/altcos
       overwrite: true
       contents:
        inline: |
    - path: /etc/containers/storage.conf # переписав файл конфигурации crio/podman с поддержкой overlay-драйвера BTRFS
          altcos ALL=NOPASSWD: ALL
      overwrite: true
     - path: /etc/profile.d/kube.sh
     - path: /etc/profile.d/kube.sh
       mode: 0755
       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:
  systemd:
   units:
   units:
     - name: initk8s.service
     - name: initk8smaster.service
       enabled: false
       enabled: false
       contents: |
       contents: |
Строка 86: Строка 87:
         Description=Start up kubernetes in master mode
         Description=Start up kubernetes in master mode
         After=crio.service kube-proxy.service kubelet.service systemd-networkd.service systemd-resolved.service
         After=crio.service kube-proxy.service kubelet.service systemd-networkd.service systemd-resolved.service
         [Service]
         [Service]
         Type=oneshot
         Type=oneshot
Строка 92: Строка 92:
         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 taint nodes localhost node-role.kubernetes.io/master-
         [Install]
         [Install]
         WantedBy=multi-user.target  
         WantedBy=multi-user.target
 
Каталог '''root''' имеет следующую структуру:
 
root/
└── etc
    ├── containers
    │   └── storage.conf
    ├── docker
    │   └── daemon.json
    ├── profile.d
    │   └── kube.sh
    └── sudoers.d
        └── altcos
 
Файлы ''/etc/containers/storage.conf'', ''/etc/docker/daemon.json'' являются стандартными файлами конфигурации для
''CRI-O''('podman') и ''docker'' с измененными storage-драйверами с ''overlay'' на ''btrfs''.
 
Файл ''/etc/profile.d/kube.sh' обеспечивает инициализацию переменной ''KUBECONFIG'' при работе под суперпользователем или инициализацию каталога ''~/.kube/'' при работе под пользователем ''altcos''.
 
Файл ''/etc/sudoers.d/altcos'' обеспечивает беспарольный запуск ''sudo'' для удаленной инициализации узла кластера по протоколу ''ssh''.
 
Архив каталога ''root'':
[[Файл:Kuber root.tar|мини]]
 
Если Вы планируете использовать стандартный storage-драйвер ''overlay'' то в в YML-файле,
* секции ''storage.trees'', 'storage.files' можно опустить
* в секции ''storage.filesystem.format'' указать ''ext4'';
Каталог ''root'' в этом случае не нужен.


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


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


  #!/bin/sh
  #!/bin/sh
  if ! butane -d . -p k8s_master.yml > k8s_master.ign
  if ! butane -p k8s_master.yml > k8s_master.ign
  then
  then
   exit 1;
   exit 1;
  fi
  fi
cp $IMAGEHOME/sisyphus_k8s.x86_64.*.qemu.qcow2 k8s.qcow2
  sudo qemu-system-x86_64 \
  sudo qemu-system-x86_64 \
  -m 2048 \
  -m 2048 \
Строка 140: Строка 113:
  -cpu host \
  -cpu host \
  -smp 2 \
  -smp 2 \
  -hda k8s.20211116.0.0.qcow2 \
  -hda k8s.qcow2 \
-hdb hdb.qcow2 \
  -fw_cfg name=opt/com.coreos/config,file=k8s_master.ign \
  -fw_cfg name=opt/com.coreos/config,file=k8s_master.ign \
  -net user,hostfwd=tcp::10222-:22 -net nic
  -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 оперативной памяти.
Обратите внимание, что для работы узла ''kubernetes'' требуется не менее 2-х ядер процессора и не менее 2GB оперативной памяти.
Каталог ''root'', содержащий файлы конфигурации ''/etc/containers/storage.conf'', ''/etc/docker/daemon.json'',
должен находиться в каталоге запуска скрипта.
Если это не так укажите при запуска команды butane после флага ''-d'' каталог месторасположение каталога ''root''.


Доступ по протоколу ''ssh'' обеспечивается через порт ''10222'' HOST-компьютера ''localhost''.
Доступ по протоколу ''ssh'' обеспечивается через порт ''10222'' HOST-компьютера ''localhost''.
Строка 156: Строка 129:
Для того, чтобы запустить сервис:
Для того, чтобы запустить сервис:
* зайдите через консоль или через ssh под пользователем ''altcos'';
* зайдите через консоль или через ssh под пользователем ''altcos'';
* выполните запуск сервиса ''initk8s'':
* выполните запуск сервиса ''initk8smaster'':
  $ sudo systemctl start initk8s
  $ sudo systemctl start initk8smaster


Данные действия можно сделать и "удаленно" по протоколу ''ssh'':
Данные действия можно сделать и "удаленно" по протоколу ''ssh'':
  ssh -p 10222 altcos@localhost sudo systemctl start initk8s
  ssh -p 10222 altcos@localhost sudo systemctl start initk8smaster


Во время запуска длительностью пару минут:
Во время запуска длительностью менее минуты:
* производится загрузка из архива, входящего в состав qcow2-образа, необходимых docker-образов;
* производится загрузка из архива, входящего в состав qcow2-образа, необходимых docker-образов;
* запуск их как сервисов;
* запуск их как сервисов;
Строка 169: Строка 142:
Логи запуска можно посмотреть командой:
Логи запуска можно посмотреть командой:


  $ journalctl -u initk8s
  $ journalctl -u initk8smaster
  Starting Start up kubernetes in master mode...
  Starting Start up kubernetes in master mode...
  ...
  ...
Строка 185: Строка 158:
  Finished Start up kubernetes in master mode.
  Finished Start up kubernetes in master mode.


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


  kubeadm join ...
  kubeadm join ...


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


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


Для работы с master-узлом кластера под обычным пользователем с правами выполнения ''sudo'' выполните следующие команды:
Для работы с master-узлом кластера из суперпользователя укажите при вызове ''sudo'' флаг ''-i''. Например:
sudo -i kubectl get all -A


mkdir -p ~/.kube
==== Проверка работы master-узла ====
sudo cp -i /etc/kubernetes/admin.conf ~/.kube/config
sudo chown $(id -u):$(id -g) ~/.kube/config
 
Данный каталог создается скриптом ''/etc/profile.d/kube.sh'', описанным в YNL-butane файла
при входе в пользователь ''altcos'' после инициализации узла кластера.
 
Для работы с master-узлом кластера из суперпользователя выполните команду:
export KUBECONFIG=/etc/kubernetes/admin.conf
 
=== Проверка работы master-узла ===


Для проверки работы узла наберите команду
Для проверки работы узла наберите команду
Строка 212: Строка 178:
  localhost  Ready    control-plane,master  41m  v1.20.8
  localhost  Ready    control-plane,master  41m  v1.20.8


Примеры запуска POD'ов смотрите в документе [[Kubernetes]].
Для проверки работы всего функционала наберите команду:
 
$ 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-кластера поднимается автоматически.
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

Текущая версия от 17: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