Kubernetes: дебаг Init containers при запуске SQL-миграций

Автор: | 10/15/2020
 

Имеется приложение в Kubernetes.

Деплоится из Helm-чарта.

При очередном деплое — новые поды не стартуют, а сам деплой падает со стандартной ошибкой «Upgrade «CHARTNAME» failed: timed out waiting for the condition«:

wait.go:225: [debug] Deployment is not ready: eks-dev-1-community-api-ns/community-api. 0 out of 3 expected pods are ready
upgrade.go:367: [debug] warning: Upgrade «community-api» failed: timed out waiting for the condition
upgrade.go:385: [debug] Upgrade failed and atomic is set, rolling back to last successful release

Проблема возникает на этапе запуска InitContainer для выполнения SQL-миграций. Сами миграции запускаются не лучшим образом, но — как есть.

Собственно ниже — подебажим запуск таких контейнеров, и зафиксим ошибку.

InitContainer — Init:1/2

Проверяем статус подов:

kk -n eks-dev-1-community-api-ns get pod
NAME                             READY   STATUS     RESTARTS   AGE
community-api-778dfdcd5b-7ckxj   0/1     Init:1/2   0          46m
community-api-778dfdcd5b-dppth   0/1     Init:1/2   0          46m
community-api-778dfdcd5b-wh4wh   1/1     Running    0          8

Статус пода «Init:1/2» — один из двух Init-конейнеров в поде не отработал.

Проверяем state пода:

kk -n eks-dev-1-community-api-ns get pod community-api-778dfdcd5b-7ckxj -o yaml
...
containerStatuses:
- image: projectname/community-api:16.b2cbe959
imageID: ""
lastState: {}
name: community-api
ready: false
restartCount: 0
state:
waiting:
reason: PodInitializing
...

PodInitializing — под ждёт Init-контейнер.

В деплойменте проверим, какие Init-контейнеры должны запуститься:

...
  initContainers:
  - name: git-clone
    image: projectname/git-cloner
...
    command: ['sh', '-c', '/opt/git/git.sh']
...
  - name: init-migration
    image: fufuhu/sql-migrate:latest
    command: ['sh', '-c', 'while [ ! -d /git/db/migrations ]; do sleep 2; done && sleep 2; /bin/sql-migrate up -config=/config/config.yaml -env=main']
...

Проверяем события:

kk -n eks-dev-1-community-api-ns get events
...
51m         Normal    Created                  pod/community-api-778dfdcd5b-7ckxj          Created container git-clone
51m         Normal    Started                  pod/community-api-778dfdcd5b-7ckxj          Started container git-clone
...
51m         Normal    Created                  pod/community-api-778dfdcd5b-7ckxj          Created container init-migration
51m         Normal    Started                  pod/community-api-778dfdcd5b-7ckxj          Started container init-migration
...

Хорошо — контейнеры создавались и запускались.

Kubernetes Pod: .status.initContainerStatuses

С помощью --template '{{.status.initContainerStatuses}}' проверим статусы Init-контейнеров в поде:

kk-n eks-dev-1-community-api-ns get pod community-api-778dfdcd5b-7ckxj --template '{{.status.initContainerStatuses}}'
[map[image:*** lastState:map[] name:git-clone ready:true restartCount:0 [...] exitCode:0 finishedAt:2020-09-30T08:15:07Z reason:Completed]]
map[imageID:*** lastState:map[] name:init-migration ready:false restartCount:0 state:map[running[...]]

Тут два контейнера — git-clone, который свою задачу «выполнил» (reason:Completed), и второй контейнер — init-migration, который в статусе running.

Смотрим их логи.

Если просто попробовать посмотреть логи пода — то kubectl сообщит, что:

kk logs -f community-api-778dfdcd5b-7ckxj
Error from server (BadRequest): container "community-api" in pod "community-api-778dfdcd5b-7ckxj" is waiting to start: PodInitializing

Поэтому — указываем контейнер явно. Первым запускается git-clone, указываем его через -c git-clone:

kk -n eks-dev-1-community-api-ns logs community-api-778dfdcd5b-7ckxj -c git-clone
Setting up SSH settings...
Setting up SSH private key...
....
Warning: Permanently added 'github.com,140.82.114.3' (RSA) to the list of known hosts.
ERROR: Repository not found.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
Purging private key...

Собственно — всё понятно: git-clone попытался склонировать репозиторий, не смог, но завершил работу с кодом 0 (name:git-clone ready:true restartCount:0 [...] exitCode:0 в выводе .status.initContainerStatuses), после чего запустился контенер для запуска миграций баз данных, но он отработать не может, так как файлов миграции нет — и он висит.

Проверяем скрипт Гита, который указан в деплойменте — command: ['sh', '-c', '/opt/git/git.sh']и используется в нашем контейнере git-clone для клонирования репозитория:

docker run -ti projectname/git-cloner cat /opt/git/git.sh
...
Status: Downloaded newer image for projectname/git-cloner:latest
!/bin/sh
echo "Setting up SSH settings..."
echo "ssh -o StrictHostKeyChecking=no -i private \$@;" > ./sshOverride.sh
chmod 700 ./sshOverride.sh;
echo "Setting up SSH private key..."
echo -e "$SSH_PRIVATE_KEY" > private
chmod 600 private
echo "Setting up GIT settings..."
export GIT_SSH=./sshOverride.sh
echo "Cloning repository..."
git clone -b $GIT_BRANCH $REPOSITORY_URL /git
echo "Purging private key..."
rm -f private

А ошибка у нас выглядела:

ERROR: Repository not found. fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.

Пробуем склонировать репозиторий со своим ключём:

GIT_SSH_COMMAND='ssh -i ~/.ssh/setevoy_main_priv_openssh -o IdentitiesOnly=yes' git clone git@github.com:projectname-dev/backend-services.git -b feature/WLIOS-7335-community-api
Cloning into 'backend-services'...
...
Resolving deltas: 100% (2624/2624), done.

Всё работает, репозиторий и бранч есть.

Проверяем секрет — есть ли сам ключ id_rsa в Kubernetes Secrets:

...
        env:
        - name: SSH_PRIVATE_KEY
          valueFrom:
            secretKeyRef:
              name: git-ssh-key
              key: id_rsa
...
kk -n eks-dev-1-community-api-ns get secret git-ssh-key -o yaml
apiVersion: v1
data:
id_rsa: LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYj...
...

Да, есть, вроде всё ОК.

Попробуем с ним скачать — получаем сам ключ из содержимого поля id_rsa, сохраняем его в файл key.rsa:

echo LS0***S0= | base64 -d > key.rsa
chmod 600 key.rsa

И пробуем применить его:

GIT_SSH_COMMAND='ssh -i key.rsa -o IdentitiesOnly=yes' git clone git@github.com:projectname-dev/backend-services.git -b feature/WLIOS-7335-community-api
Cloning into 'backend-services'...
Load key "key.rsa": invalid format
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Проблема ясна — Deploy Key в Github репозитории не подходит.

Обновляем его в секретах, передеплоиваем, проверяем:

kk -n eks-dev-1-community-api-ns logs community-api-7d8967d448-mvw8m -c git-clone
Setting up SSH settings...
Setting up SSH private key...
Setting up GIT settings...
Cloning repository...
Cloning into '/git'...
Warning: Permanently added 'github.com,140.82.114.3' (RSA) to the list of known hosts.
Purging private key...

И поды запустились:

kk -n eks-dev-1-community-api-ns get pod
NAME                            READY   STATUS    RESTARTS   AGE
community-api-84675f55dd-5jn5z   1/1     Running   0          58m
community-api-84675f55dd-qvjfw   1/1     Running   0          58m

Готово.