Перейти к основному содержимому

Релиз v6.11.0 (оффлайн)

Требования
  • Предыдущая версия monq == 6.10.1
  • Опыт администрирования Linux
  • Базовые знания Kubernetes
  • Осознание выполняемых команд

В обновлении:

ПродуктНовая версия
pl6.11.0
sm6.11.0
cl6.11.0
fm6.11.0
plugins6.10.0
⚠️ Уровень простоя - полная деградация на время обновления

Базовая информация

Релиз включает обновление основных компонентов СПО и различных модулей monq.

Если установлен только определенный набор модулей monq, например: pl и cl, то разделы с остальными модулями можно проигнорировать.

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

Проведение миграции

Для запуска обновления требуется скачать клиент управления monq monqctl и выполнить конфигурацию контекста monqctl если это не было выполнено ранее.

Требования

Минимальная версия monqctl: 1.2.3

Примечание: можно настроить 2 контекста для stage и production одновременно.

Примечание 2: токен для доступа в monq ReleaseHub для скачивания обновления требуется получить, обратившись в поддержку monq, либо из письма с регистрацией лицензии.

осторожно

⚠️ Выполнить бекап K8s master средствами виртуализации

Сформировать пакет обновления для переноса на VM

На машине с доступом к registry.monqlab.com нужно скачать релизные пакеты и архивы с программами и образами для проведения обновлений

mkdir ./update
TOKEN="<токен обновления>"
curl -H "Authorization: Bearer ${TOKEN}" https://downloads.monqlab.com/monq/updates/monq_6_11_0.tar.gz -o monq_6_11_0.tar.gz
tar -C ./ -xvf monq_6_11_0.tar.gz

monqctl release version export 3.5.0 --product=monq-registry --dest=update/registry/
monqctl registry export registry 3.5.0 --dest=update/registry/containers
monqctl release version export 6.11.0 --product=monq --dest=update/monq/

После сборки пакета нужно скопировать каталог update на обновляемые сервера с установленным kubernetes

Выполнить предрелизную подготовку

Проверить контекст monqctl и статус реестра микросервисов.

# Просмотреть текущий контекст, с которым работает monqctl.
monqctl config current-context
# Просмотреть статус реестра микросервисов из контекста.
monqctl registry get status
# Просмотреть статус сервисов в реестре микросервисов из контекста.
monqctl registry get services

Примечание: В ответе на команду monqctl registry get status вывод будет содержать

-------------------------
Consul | Failed
-------------------------

На данном этапе можно проигнорировать. Сервис Consul добавлен только для возможности получить адрес и токен monqctl, который формирует файл доступа для программы-мигратора. Но для Consul в реестре микросервисов не реализованы методы генерирования шаблонов микросервисов, поэтому и выбрасывается ошибка валидации. Будет исправлено в последующих версиях.

Выполнить обновление реестра микросервисов

# Выполнить команду `registry update registry` с аргументом `--sourceDir`.
cd ./update/registry/containers/
monqctl registry update registry --version=3.5.0 --sourceDir=./
cd ../../../

Получить манифесты, необходимые для обновления

monqctl release use-version 3.5.0 --product=monq-registry --sourceDir=./update/registry/
CONTEXT=$(monqctl config current-context)
cp /tmp/monqctl/updates/${CONTEXT}/monq-registry/3.5.0/mreg/* ./update/

Остановить monq

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

kubectl scale deploy -n production --replicas=0 --all

Выполнить остановку СУБД (при запуске в k8s):

kubectl scale deploy -n infra --replicas=0 --all

Выполнить изменение конфига coredns:

kubectl get cm -n kube-system coredns -o json | sed 's/reload/reload\\n    ready :8181/g;s/       upstream\\n//g' | kubectl apply -f -

Выполнить бекап конфига coredns:

kubectl get cm -n kube-system coredns -o yaml >> ./update/coredns-cm.yaml

Отключить плагин auto coredns:

kubectl get cm -n kube-system coredns -o json | sed -E 's|auto \{.* \}||g' | kubectl apply -f -

Обновление flannel

Выполнить модификацию конфига flannel:

kubectl get cm -n kube-system kube-flannel-cfg -o json | sed 's/\\"cbr0\\",\\n/\\"cbr0\\",\\n  \\"cniVersion\\":\\"0.3.1\\",\\n/g' | kubectl apply -f -

Удалить flannel:

kubectl delete daemonSet -n kube-system kube-flannel-ds-amd64
kubectl delete podsecuritypolicy -n kube-system psp.flannel.unprivileged
kubectl delete clusterrolebinding -n kube-system flannel
kubectl delete clusterrole -n kube-system flannel

Применить новый манифест:

docker load -i update/infra_containers/docker.img
kubectl apply -f ./update/flannel.yaml

Убедиться что статус всех нод "Ready":

kubectl get node

Отметить ноду как master

kubectl label node d-head node-role.kubernetes.io/master=
Выполняется ТОЛЬКО ДЛЯ УСТАНОВЩИКА С LOOPBACK интерфейсом!

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

ip a show lo1

По результату выполнения команды можно определить:

Установщик с Loopback интерфейсом

3: lo1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 62:c4:b1:dd:d0:0f brd ff:ff:ff:ff:ff:ff
inet 10.10.40.50/32 brd 10.10.40.50 scope global noprefixroute lo1
valid_lft forever preferred_lft forever

Установщик без Loopback интерфейса

Device "lo1" does not exist.

Перегенерировать сертификаты etcd

Выполнить бекап текущих сертификатов:

mkdir ./update/certs
mv /etc/kubernetes/pki/etcd/server.key /etc/kubernetes/pki/etcd/server.crt /etc/kubernetes/pki/etcd/peer.key /etc/kubernetes/pki/etcd/peer.crt /etc/kubernetes/pki/etcd/healthcheck-client.key /etc/kubernetes/pki/etcd/healthcheck-client.crt /etc/kubernetes/pki/apiserver-etcd-client.key /etc/kubernetes/pki/apiserver-etcd-client.crt ./update/certs

Заполнить конфиг kubeadm:

cat > kubeadm.yaml << EOF
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
apiServer:
certSANs:
- "127.0.0.1"
- "10.10.40.50"
- "k8s-api.in.monq.local"
extraArgs:
advertise-address: "10.10.40.50"
bind-address: "10.10.40.50"
controllerManager:
extraArgs:
allocate-node-cidrs: "true"
cluster-cidr: "10.244.0.0/16"
etcd:
local:
serverCertSANs:
- "10.10.40.50"
- "etcd.in.monq.local"
peerCertSANs:
- "10.10.40.50"
- "etcd.in.monq.local"
extraArgs:
initial-cluster: "d-head=https://10.10.40.50:2380"
listen-peer-urls: "https://10.10.40.50:2380"
listen-client-urls: "https://127.0.0.1:2379,https://10.10.40.50:2379"
advertise-client-urls: "https://10.10.40.50:2379"
initial-advertise-peer-urls: "https://10.10.40.50:2380"
controlPlaneEndpoint: "k8s-api.in.monq.local:6443"
networking:
serviceSubnet: "10.16.0.0/24"
podSubnet: "10.244.0.0/16"
dnsDomain: "cluster.local"
EOF

Выпустить новые сертификаты etcd:

kubeadm init phase certs etcd-server --config kubeadm.yaml
kubeadm init phase certs etcd-peer --config kubeadm.yaml
kubeadm init phase certs etcd-healthcheck-client --config kubeadm.yaml
kubeadm init phase certs apiserver-etcd-client --config kubeadm.yaml

Заменить адрес apiserver и etcd:

CURRENT_IP=$(hostname -I | cut -d' ' -f1)
kubectl get cm -n kube-system kubeadm-config -o yaml | sed -E "s/advertiseAddress: .*/advertiseAddress: ${CURRENT_IP}/g" | kubectl apply -f -
sed -i -E "s/listen-client-urls(.*)/listen-client-urls\1,https:\/\/${CURRENT_IP}:2379/g" /etc/kubernetes/manifests/etcd.yaml
systemctl restart kubelet

1.15.12 -> 1.16.15

Обновление master ноды

Установить значение переменной в имя ноды k8s:

NODE_NAME=<имя master ноды>

Обновить kubeadm:

yum localinstall --disablerepo='*' update/kubeadm-1.16/*.rpm -y

Остановить scheduling для ноды (Не выполнять если в кластере всего 1 нода):

kubectl drain ${NODE_NAME} --ignore-daemonsets --delete-local-data

Проверить план обновления. Не продолжать если завершился с ошибкой:

kubeadm upgrade plan --ignore-preflight-errors=CoreDNSUnsupportedPlugins,CoreDNSMigration,CoreDNSUnsupportedPlugins

Загрузить новые образы для kubernetes:

docker load -i update/kubeadm-1.16/docker.img

Выполнить обновление кластера:

kubeadm upgrade apply v1.16.15 --ignore-preflight-errors=CoreDNSUnsupportedPlugins,CoreDNSMigration,CoreDNSUnsupportedPlugins

Перезагрузить kubelet:

systemctl daemon-reload && systemctl restart kubelet

Включить ноду в работу если ранее отключалась:

kubectl uncordon ${NODE_NAME}
Выполняется, если у вас есть worker ноды

Обновление worker ноды

Остановить scheduling для ноды(выполняется на master):

NODE_NAME=<имя worker ноды>
kubectl drain ${NODE_NAME} --ignore-daemonsets --delete-local-data

Выполнить обновление ноды:

docker load -i update/kubeadm-1.16/docker.img
yum localinstall --disablerepo='*' update/kubeadm-1.16/*.rpm -y
kubeadm upgrade node
systemctl daemon-reload && systemctl restart kubelet

Включить ноду в работу(выполняется на master):

kubectl uncordon ${NODE_NAME}

1.16.15 -> 1.17.17

Обновление master ноды

Установить значение переменной в имя ноды k8s:

NODE_NAME=<имя master ноды>

Обновить kubeadm:

yum localinstall --disablerepo='*' update/kubeadm-1.17/*.rpm -y

Остановить scheduling для ноды (Не выполнять если в кластере всего 1 нода):

kubectl drain ${NODE_NAME} --ignore-daemonsets --delete-local-data

Проверить план обновления. Не продолжать если завершился с ошибкой:

kubeadm upgrade plan --ignore-preflight-errors=CoreDNSUnsupportedPlugins

Загрузить новые образы для kubernetes:

docker load -i update/kubeadm-1.17/docker.img

Выполнить обновление кластера:

kubeadm upgrade apply v1.17.17 --ignore-preflight-errors=CoreDNSUnsupportedPlugins

Перезагрузить kubelet:

systemctl daemon-reload && systemctl restart kubelet

Включить ноду в работу если ранее отключалась:

kubectl uncordon ${NODE_NAME}
Выполняется, если у вас есть worker ноды

Обновление worker ноды

Остановить scheduling для ноды(выполняется на master):

NODE_NAME=<имя worker ноды>
kubectl drain ${NODE_NAME} --ignore-daemonsets --delete-local-data

Выполнить обновление ноды:

docker load -i update/kubeadm-1.17/docker.img
yum localinstall --disablerepo='*' update/kubeadm-1.17/*.rpm -y
kubeadm upgrade node
systemctl daemon-reload && systemctl restart kubelet

Включить ноду в работу(выполняется на master):

kubectl uncordon ${NODE_NAME}

1.17.17 -> 1.18.20

Обновление master ноды

Установить значение переменной в имя ноды k8s:

NODE_NAME=<имя master ноды>

Обновить kubeadm:

yum localinstall --disablerepo='*' update/kubeadm-1.18/*.rpm -y

Остановить scheduling для ноды (Не выполнять если в кластере всего 1 нода):

kubectl drain ${NODE_NAME} --ignore-daemonsets --delete-local-data

Проверить план обновления. Не продолжать если завершился с ошибкой:

kubeadm upgrade plan --ignore-preflight-errors=CoreDNSUnsupportedPlugins

Загрузить новые образы для kubernetes:

docker load -i update/kubeadm-1.18/docker.img

Выполнить обновление кластера:

kubeadm upgrade apply v1.18.20 --ignore-preflight-errors=CoreDNSUnsupportedPlugins

Перезагрузить kubelet:

systemctl daemon-reload && systemctl restart kubelet

Включить ноду в работу если ранее отключалась:

kubectl uncordon ${NODE_NAME}
Выполняется, если у вас есть worker ноды

Обновление worker ноды

Остановить scheduling для ноды(выполняется на master):

NODE_NAME=<имя worker ноды>
kubectl drain ${NODE_NAME} --ignore-daemonsets --delete-local-data

Выполнить обновление ноды:

docker load -i update/kubeadm-1.18/docker.img
yum localinstall --disablerepo='*' update/kubeadm-1.18/*.rpm -y
kubeadm upgrade node
systemctl daemon-reload && systemctl restart kubelet

Включить ноду в работу(выполняется на master):

kubectl uncordon ${NODE_NAME}

1.18.20 -> 1.19.16

Обновление master ноды

Установить значение переменной в имя ноды k8s:

NODE_NAME=<имя master ноды>

Обновить kubeadm:

yum localinstall --disablerepo='*' update/kubeadm-1.19/*.rpm -y

Остановить scheduling для ноды (Не выполнять если в кластере всего 1 нода):

kubectl drain ${NODE_NAME} --ignore-daemonsets --delete-local-data

Проверить план обновления. Не продолжать если завершился с ошибкой:

kubeadm upgrade plan --ignore-preflight-errors=CoreDNSUnsupportedPlugins

Загрузить новые образы для kubernetes:

docker load -i update/kubeadm-1.19/docker.img

Выполнить обновление кластера:

kubeadm upgrade apply v1.19.16 --ignore-preflight-errors=CoreDNSUnsupportedPlugins

Перезагрузить kubelet:

systemctl daemon-reload && systemctl restart kubelet

Включить ноду в работу если ранее отключалась:

kubectl uncordon ${NODE_NAME}
Выполняется, если у вас есть worker ноды

Обновление worker ноды

Остановить scheduling для ноды(выполняется на master):

NODE_NAME=<имя worker ноды>
kubectl drain ${NODE_NAME} --ignore-daemonsets --delete-local-data

Выполнить обновление ноды:

docker load -i update/kubeadm-1.19/docker.img
yum localinstall --disablerepo='*' update/kubeadm-1.19/*.rpm -y
kubeadm upgrade node
systemctl daemon-reload && systemctl restart kubelet

Включить ноду в работу(выполняется на master):

kubectl uncordon ${NODE_NAME}

1.19.16 -> 1.20.15

Обновление master ноды

Установить значение переменной в имя ноды k8s:

NODE_NAME=<имя master ноды>

Обновить kubeadm:

yum localinstall --disablerepo='*' update/kubeadm-1.20/*.rpm -y

Остановить scheduling для ноды (Не выполнять если в кластере всего 1 нода):

kubectl drain ${NODE_NAME} --ignore-daemonsets --delete-local-data

Проверить план обновления. Не продолжать если завершился с ошибкой:

kubeadm upgrade plan --ignore-preflight-errors=CoreDNSUnsupportedPlugins

Загрузить новые образы для kubernetes:

docker load -i update/kubeadm-1.20/docker.img

Выполнить обновление кластера:

kubeadm upgrade apply v1.20.15 --ignore-preflight-errors=CoreDNSUnsupportedPlugins

Перезагрузить kubelet:

systemctl daemon-reload && systemctl restart kubelet

Включить ноду в работу если ранее отключалась:

kubectl uncordon ${NODE_NAME}
Выполняется, если у вас есть worker ноды

Обновление worker ноды

Остановить scheduling для ноды(выполняется на master):

NODE_NAME=<имя worker ноды>
kubectl drain ${NODE_NAME} --ignore-daemonsets --delete-local-data

Выполнить обновление ноды:

docker load -i update/kubeadm-1.20/docker.img
yum localinstall --disablerepo='*' update/kubeadm-1.20/*.rpm -y
kubeadm upgrade node
systemctl daemon-reload && systemctl restart kubelet

Включить ноду в работу(выполняется на master):

kubectl uncordon ${NODE_NAME}

1.20.15 -> 1.21.12

Обновление master ноды

Установить значение переменной в имя ноды k8s:

NODE_NAME=<имя master ноды>

Обновить kubeadm:

yum localinstall --disablerepo='*' update/kubeadm-1.21/*.rpm -y

Остановить scheduling для ноды (Не выполнять если в кластере всего 1 нода):

kubectl drain ${NODE_NAME} --ignore-daemonsets --delete-local-data

Проверить план обновления. Не продолжать если завершился с ошибкой:

kubeadm upgrade plan --ignore-preflight-errors=CoreDNSUnsupportedPlugins

Загрузить новые образы для kubernetes:

docker load -i update/kubeadm-1.21/docker.img

Выполнить обновление кластера:

kubeadm upgrade apply v1.21.12 --ignore-preflight-errors=CoreDNSUnsupportedPlugins

Перезагрузить kubelet:

systemctl daemon-reload && systemctl restart kubelet

Включить ноду в работу если ранее отключалась:

kubectl uncordon ${NODE_NAME}
Выполняется, если у вас есть worker ноды

Обновление worker ноды

Остановить scheduling для ноды(выполняется на master):

NODE_NAME=<имя worker ноды>
kubectl drain ${NODE_NAME} --ignore-daemonsets --delete-local-data

Выполнить обновление ноды:

docker load -i update/kubeadm-1.21/docker.img
yum localinstall --disablerepo='*' update/kubeadm-1.21/*.rpm -y
kubeadm upgrade node
systemctl daemon-reload && systemctl restart kubelet

Включить ноду в работу(выполняется на master):

kubectl uncordon ${NODE_NAME}

1.21.12 -> 1.22.9

Обновление master ноды

Установить значение переменной в имя ноды k8s:

NODE_NAME=<имя master ноды>

Обновить kubeadm:

yum localinstall --disablerepo='*' update/kubeadm-1.22/*.rpm -y

Остановить scheduling для ноды (Не выполнять если в кластере всего 1 нода):

kubectl drain ${NODE_NAME} --ignore-daemonsets --delete-local-data

Проверить план обновления. Не продолжать если завершился с ошибкой:

kubeadm upgrade plan --ignore-preflight-errors=CoreDNSUnsupportedPlugins

Загрузить новые образы для kubernetes:

docker load -i update/kubeadm-1.22/docker.img

Выполнить обновление кластера:

kubeadm upgrade apply v1.22.9 --ignore-preflight-errors=CoreDNSUnsupportedPlugins

Перезагрузить kubelet:

systemctl daemon-reload && systemctl restart kubelet

Включить ноду в работу если ранее отключалась:

kubectl uncordon ${NODE_NAME}
Выполняется, если у вас есть worker ноды

Обновление worker ноды

Остановить scheduling для ноды(выполняется на master):

NODE_NAME=<имя worker ноды>
kubectl drain ${NODE_NAME} --ignore-daemonsets --delete-local-data

Выполнить обновление ноды:

docker load -i update/kubeadm-1.22/docker.img
yum localinstall --disablerepo='*' update/kubeadm-1.22/*.rpm -y
kubeadm upgrade node
systemctl daemon-reload && systemctl restart kubelet

Включить ноду в работу(выполняется на master):

kubectl uncordon ${NODE_NAME}

1.22.9 -> 1.23.6

Обновление master ноды

Установить значение переменной в имя ноды k8s:

NODE_NAME=<имя master ноды>

Обновить kubeadm:

yum localinstall --disablerepo='*' update/kubeadm-1.23/*.rpm -y

Остановить scheduling для ноды (Не выполнять если в кластере всего 1 нода):

kubectl drain ${NODE_NAME} --ignore-daemonsets --delete-local-data

Проверить план обновления. Не продолжать если завершился с ошибкой:

kubeadm upgrade plan --ignore-preflight-errors=CoreDNSUnsupportedPlugins

Загрузить новые образы для kubernetes:

docker load -i update/kubeadm-1.23/docker.img

Выполнить обновление кластера:

kubeadm upgrade apply v1.23.6 --ignore-preflight-errors=CoreDNSUnsupportedPlugins

Выполнить обновление компонентов:

systemctl daemon-reload && systemctl restart kubelet

Включить ноду в работу если ранее отключалась:

kubectl uncordon ${NODE_NAME}

Выпонить обновление bash completions:

kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl > /dev/null
Выполняется, если у вас есть worker ноды

Обновление worker ноды

Остановить scheduling для ноды(выполняется на master):

NODE_NAME=<имя worker ноды>
kubectl drain ${NODE_NAME} --ignore-daemonsets --delete-local-data

Выполнить обновление ноды:

docker load -i update/kubeadm-1.23/docker.img
yum localinstall --disablerepo='*' update/kubeadm-1.23/*.rpm -y
kubeadm upgrade node
systemctl daemon-reload && systemctl restart kubelet

Включить ноду в работу(выполняется на master):

kubectl uncordon ${NODE_NAME}

ТОЛЬКО ДЛЯ УСТАНОВЩИКА С LOOPBACK интерфейсом!

Kube-proxy:

kubectl get cm -n kube-system kube-proxy -o yaml | sed -E 's|server: .*|server: https://k8s-api.in.monq.local:6443|g' | kubectl apply -f -
kubectl delete po -n kube-system -l k8s-app=kube-proxy

Перезапустить flannel:

kubectl delete po -n kube-system -l app=flannel

Apiserver:

sed -i '/--advertise-address/d' /etc/kubernetes/manifests/kube-apiserver.yaml

etcd:

CURRENT_IP=$(hostname -I | cut -d' ' -f1)
sed -i "s|${CURRENT_IP}|10.10.40.50|g" /etc/kubernetes/manifests/etcd.yaml

Восстановление ds coredns

Восстановление coredns:

kubectl scale deploy -n kube-system coredns --replicas=0
kubectl delete cm -n kube-system coredns
kubectl apply -f update/coredns-cm.yaml
kubectl get cm -n kube-system coredns -o json | sed 's/ready :8181/ready :8091/g' | kubectl apply -f -
kubectl patch ds -n kube-system coredns --type='json' \
-p='[{"op": "replace", "path": "/spec/template/spec/containers/0/readinessProbe/httpGet/path", "value": "/ready"}]'
kubectl patch ds -n kube-system coredns --type='json' \
-p='[{"op": "replace", "path": "/spec/template/spec/containers/0/readinessProbe/httpGet/port", "value": 8091}]'
kubectl set image -n kube-system daemonset coredns coredns=k8s.gcr.io/coredns/coredns:v1.8.6

Обновление ingress-nginx-controller

Обновить ingress-nginx-controller

kubectl get cm -n ingress-nginx ingress-nginx-controller -o json | jq '.data."allow-snippet-annotations"="true"' | kubectl apply -f -
sed -i -E 's/(.*)\@.*$/\1/g' update/ingress-nginx.yaml
kubectl apply -f update/ingress-nginx.yaml

docker -> containerd

Настраиваем опции логирования в кластере:

kubectl get cm -n kube-system kubelet-config-1.23 -o yaml | sed 's/containerLogMaxFiles: 5/containerLogMaxFiles: 2/g' | kubectl apply -f -

Проверяем текущий runtime (содержиться в колонке CONTAINER-RUNTIME)

kubectl get nodes -o wide

Обновление runtime

Внимание!

Последующие операции по обновлению runtime необходимо повторить для каждой ноды кластера!

Остановить scheduling для ноды(выполняется на master):

NODE_NAME=<имя ноды>
kubectl drain ${NODE_NAME} --ignore-daemonsets --delete-local-data

Добавить загрузку модуля ядра:

cat <<EOF > /etc/modules-load.d/k8s.conf
br_netfilter
EOF
modprobe br_netfilter

Останавливаем kubelet:

systemctl stop kubelet

Очищаем и останавливаем docker:

docker rm -vf $(docker ps -aq)
docker rmi -f $(docker images -aq)
systemctl stop docker
systemctl disable docker

Проверяем версию containerd (должна быть >= v1.4.11):

containerd --version

При необходимости Обновляем/устанавливаем containerd:

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install containerd.io -y

Настраиваем crictl:

crictl completion bash | sudo tee /etc/bash_completion.d/crictl > /dev/null
cat > /etc/crictl.yaml << EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 2
debug: false
pull-image-on-create: true
EOF

Включаем CRI в containerd:

containerd config default > /etc/containerd/config.toml
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
systemctl restart containerd
systemctl enable containerd --now

Включить поддержку insecure registry в containerd (При использовании http registry):

# Конфигурационный файл имеет определенный формат, строка ниже сформирована с учетом нужного количества пробелов.
sed -i '/plugins."io.containerd.grpc.v1.cri".registry.mirrors.$/a\ \
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.in.monq.local:80"] \
endpoint = ["http://registry.in.monq.local:80"]' /etc/containerd/config.toml

systemctl restart containerd.service

Загрузить образы:

ctr -n=k8s.io image import update/kubeadm-1.23/docker.img
ctr -n=k8s.io image import update/infra_containers/docker.img

Добаляем флаги kubelet:

KUBELET_FLAGS=$(cat /var/lib/kubelet/kubeadm-flags.env | sed -nE 's/KUBELET_KUBEADM_ARGS="(.*)"/\1/p')
echo "KUBELET_KUBEADM_ARGS=\"$KUBELET_FLAGS --container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock\"" > /var/lib/kubelet/kubeadm-flags.env
sed -i 's/containerLogMaxFiles: 5/containerLogMaxFiles: 2/g' /var/lib/kubelet/config.yaml
systemctl start kubelet

Проверяем текущий runtime (выполняется на master)

kubectl get nodes -o wide

Изменяем путь socket CRI(выполняется на master):

kubectl annotate node ${NODE_NAME} --overwrite kubeadm.alpha.kubernetes.io/cri-socket=unix:///run/containerd/containerd.sock

Выполнить перезагрузку ноды:

reboot

Включаем ноду в работу (выполняется на master):

kubectl uncordon ${NODE_NAME}

Зафиксировать версию инфраструктурного релиза

cat <<EOF | kubectl apply -f -
apiVersion: v1
data:
version: 1.6.0
kind: ConfigMap
metadata:
name: infra
namespace: infra
EOF

Запуск monq

Выполнить запуск registry (при запуске в k8s):

kubectl scale deploy -n infra --replicas=1 registry

Дождаться запуска registry (при запуске в k8s):

kubectl get po -n infra

Выполнить запуск СУБД (при запуске в k8s):

kubectl scale deploy -n infra --replicas=1 --all

Миграция ingress:

kubectl get ing --all-namespaces -o json | jq '.items[].spec.ingressClassName = "nginx"' | jq '.items[].spec.rules[].http.paths[].pathType = "Prefix"' | kubectl apply -f -

Применить обновленную роль для реестра микросервисов:

kubectl apply -f ./update/pl-microservice-registry-role.yaml -n production

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

kubectl scale deploy -n production --replicas=1 pl-microservice-registry-api-service

Выполнить обновление шаблонов k8s в реестре микросервисов:

# Получить текущий шаблон k8s из реестра микросервисов.
monqctl registry get services K8s --output json > ./update/registry-k8s-template.backup.json
# Выполнить обновление шаблона.
cat ./update/registry-k8s-template.backup.json | jq '.JsonConfig.Ingress.apiVersion = "networking.k8s.io/v1" |
.JsonConfig.routingIngress.apiVersion = "networking.k8s.io/v1" | .JsonConfig.Deployment.apiVersion = "apps/v1" |
.JsonConfig.Ingress.spec.ingressClassName = "nginx" | .JsonConfig.routingIngress.spec.ingressClassName = "nginx" |
.JsonConfig.Ingress.spec.rules = [{"host":"%AppNameShort%.api.%GlobalDomain%","http":{"paths":[{"path":"/","pathType":"Prefix","backend":{"service":{"name":"%AppName%","port":{"number":80}}}}]}}] |
.JsonConfig.Deployment.metadata.labels = {"app":"%AppName%","tier":"backend"} |
.JsonConfig.Deployment.spec.selector.matchLabels = {"app":"%AppName%","tier":"backend"}' > ./update/registry-k8s-template.json
# Применить обновленный шаблон в реестр.
monqctl registry apply service K8s --file ./update/registry-k8s-template.json

Очистить шаблоны микросервисов для сервиса k8s:

NAMESPACE="production"
REGISTRY_CONNECTION_STRING=$(kubectl get secret -n $NAMESPACE registry-pg-con --template={{.data.ConnectionString}} | base64 -d)
REGISTRY_DB_HOST=$(echo $REGISTRY_CONNECTION_STRING | sed -nE 's/.*(server|Host)=([^;]+)(;)?.*$/\2/p')
REGISTRY_DATABASE=$(echo $REGISTRY_CONNECTION_STRING | sed -nE 's/.*[Dd]atabase=([^;]+)(;)?.*$/\1/p')
REGISTRY_DATABASE_USER=$(echo $REGISTRY_CONNECTION_STRING | sed -nE 's/.*(uid|[Uu]sername)=([^;]+)(;)?.*$/\2/p')
REGISTRY_DATABASE_PASS=$(echo $REGISTRY_CONNECTION_STRING | sed -nE 's/.*(pwd|[Pp]assword)=([^;]+)(;)?.*$/\2/p')
PGPASSWORD=${REGISTRY_DATABASE_PASS} psql -h ${REGISTRY_DB_HOST} -U ${REGISTRY_DATABASE_USER} -w -d ${REGISTRY_DATABASE} -a -v ON_ERROR_STOP=1 \
-c "DELETE FROM public.\"MicroserviceAtService\" WHERE \"ServiceId\" = 9"
Если psql отсутствует в системе
CONTAINER_ID=$(crictl ps --name=postgres -q)
crictl exec -ti ${CONTAINER_ID} psql postgresql://${REGISTRY_DATABASE_USER}:${REGISTRY_DATABASE_PASS}@${REGISTRY_DB_HOST}:5432/${REGISTRY_DATABASE} -a -v ON_ERROR_STOP=1 -c "DELETE FROM public.\"MicroserviceAtService\" WHERE \"ServiceId\" = 9"

Проверить контекст monqctl и статус реестра микросервисов:

# Просмотреть текущий контекст, с которым работает monqctl.
monqctl config current-context
# Просмотреть статус реестра микросервисов из контекста.
monqctl registry get status
# Просмотреть статус сервисов в реестре микросервисов из контекста.
monqctl registry get services

Примечание: В ответе на команду monqctl registry get status вывод будет содержать

-------------------------
Consul | Failed
-------------------------

На данном этапе можно проигнорировать. Сервис Consul добавлен только для возможности получить адрес и токен monqctl, который формирует файл доступа для программы-мигратора. Но для Consul в реестре микросервисов не реализованы методы генерирования шаблонов микросервисов, поэтому и выбрасывается ошибка валидации. Будет исправлено в последующих версиях.

Установить контекст релиза, с которым будет работать monqctl в рамках контекста установленного Monq. Команда при этом скачивает и подготавливает релиз:

# Выполнить команду `use-version` с аргументом `--sourceDir`.
monqctl release use-version 6.11.0 --product=monq --sourceDir=update/monq/

Выполнить обновление маршрутизации

monqctl release update routing --module=pl
monqctl release update routing --module=cl
monqctl release update routing --module=plugins
monqctl release update routing --module=sm # Не применять, если не установлен модуль AIOps.
monqctl release update routing --module=fm # Не применять, если не установлен модуль FMonq.
monqctl release update routing --module=sm --file monq.json # Не применять еси установлена Lite версия monq
monqctl release update routing --module cl --file lite.json # Не применять если установлена full версия monq

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

monqctl release update microservices --module=pl --full --k8s-merge-type Replace
monqctl release update microservices --module=cl --full --k8s-merge-type Replace
monqctl release update microservices --module=plugins --full --k8s-merge-type Replace
monqctl release update microservices --module=sm --full --k8s-merge-type Replace # Не применять, если не установлен модуль AIOps.
monqctl release update microservices --module=fm --full --k8s-merge-type Replace # Не применять, если не установлен модуль FMonq.

Отключить cl-stream-data-ml

kubectl scale -n production deployment --replicas=0 cl-stream-data-ml-scheduler-service
kubectl scale -n production deployment --replicas=0 cl-stream-data-ml-processor-service
kubectl scale -n production deployment --replicas=0 cl-stream-data-ml-model-service

Удостовериться, что все поды во всех пространствах находятся в статусе Running.