VK Cloud logo
Обновлена28 декабря 2023 г. в 13:27

Настройка авторазвертывания приложения в кластер Kubernetes

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

  • Сервер Ubuntu 18.04 LTS x86_64: на нем будут установлены и настроены Docker, GitLab и Harbor.
  • Развернутый в VK Cloud кластер K8s.

Подготовительные шаги

  1. Установите и настройте Docker.
  2. Установите и настройте GitLab.
  3. Установите и настройте Harbor.

1. Настройте GitLab-runner

  1. Авторизуйтесь в веб-интерфейсе GitLab c правами администратора:

  2. Скопируйте registration token. В консоли на сервере, на котором установлен GitLab-runner, выполните команду:

    docker exec -it gitlab-runner gitlab-runner register -n --url https://<SERVER_DNS_NAME>/ --executor docker --registration-token ua2k238fbMtAxMBBRf_z --description "shared-runner" --docker-image="docker:dind" --tag-list "shared_runner" --docker-privileged --docker-volumes /var/run/docker.sock:/var/run/docker.sock

    В результате runner отобразится в веб-интерфейсе:

  3. Настройте переменные среды выполнения:

    1. Перейдите в раздел SettingsCI/CD.

    2. В блоке Variables нажмите кнопку Expand:

    3. Установите переменные, которые будут использоваться в файле автосборки .gitlab-ci.yml:

      • DOCKER_USER — пользователь для доступа к репозиторию в Harbor. В нашем примере — k8s.
      • DOCKER_PASSWORD — пароль пользователя k8s, который вы ввели при создании пользователя в Harbor. Отметьте для переменной опцию Masked — благодаря этому при попытке вывода текста в переменной в скрипте он маскируется, и пароль не виден.
      • DOCKER_REGISTRY — имя хоста, на котором расположен Harbor. В нашем примере — <SERVER_DNS_NAME>.

2. Настройте файл автосборки

  1. Перейдите в папку со скачанным репозиторием и создайте файл .gitlab-ci.yml с содержимым:

  2. Загрузите созданный файл в репозиторий:

    1ash-work:k8s-conf-demo git add .
    2ash-work:k8s-conf-demo git commit -m "create .gitlab-ci.yml"
    3[master 55dd5fa] create .gitlab-ci.yml
    41 file changed, 1 insertion(+), 1 deletion(-)
    5ash-work:k8s-conf-demo git push
    6Перечисление объектов: 5, готово.
    7Подсчет объектов: 100% (5/5), готово.
    8При сжатии изменений используется до 4 потоков
    9Сжатие объектов: 100% (3/3), готово.
    10Запись объектов: 100% (3/3)299 bytes | 299.00 KiB/s, готово.
    11Всего 3 (изменения 2), повторно использовано 0 (изменения 0)
    12To testrom.ddns.net:ash/k8s-conf-demo.git
    13   7c91eab..55dd5fa  master -> master

    Как только файл .gitlab-ci.yml появится в репозитории, GitLab автоматически запустит его сборку.

  3. Дождитесь завершения сборки.

  4. (Опционально) Проверьте наличие собранного образа в Harbor:

3. Разверните локальное приложение в кластере Kubernetes

  1. Создайте кластер Kubernetes в VK Cloud.

  2. Подключитесь к кластеру с помощью kubectl.

  3. Предоставьте кластеру права доступа к репозиторию образов Harbor:

    1. Создайте secret с <SERVER_DNS_NAME> (имя сервера Harbor) и <PASSWORD> (пароль пользователя k8s в Harbor):
    kubectl create secret docker-registry myprivateregistry --docker-server=https://<SERVER_DNS_NAME>:8443 --docker-username=k8s --docker-password=<PASSWORD>
    1. Убедитесь, что secret успешно создан:
    ash-work:~ kubectl get secret myprivateregistry --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
  4. Создайте файл приложения deployment.yml:

  5. Запустите приложение:

    kubectl create -f deployment.yaml
  6. Через некоторое время убедитесь, что контейнер поднялся:

    kubectl get pods

    Должна быть выведена похожая информация:

    1NAME READY STATUS RESTARTS AGE 
    2myapp-deployment-66d55bcbd5-s86m6   1/1     Running   0          39s
  7. Создайте файл service.yml:

  8. Создайте сервис:

    kubectl create -f service.yaml
  9. Чтобы обеспечить доступ к приложению из внешней сети, настройте ingress-контроллер. Для этого создайте файл ingress.yaml:

  10. Примените ingress-контроллер:

    kubectl create -f ingress.yaml
  11. Посмотрите состояние ingress-контроллера:

    kubectl describe ingress myapp-ingress

    Ожидаемый вывод команды:

    1Name: myapp-ingress 
    2Namespace: default 
    3Address: 
    4Default backend: default-http-backend:80 (<none>) 
    5Rules: 
    6Host Path Backends 
    7---- ---- -------- 
    8echo.com 
    9/ myapp-svc:8081 (10.100.69.71:8081) 
    10Annotations: 
    11Events: 
    12Type Reason Age From Message 
    13---- ------ ---- ---- ------- 
    14Normal CREATE 45s nginx-ingress-controller Ingress default/myapp-ingress 
    15  Normal  UPDATE  5s    nginx-ingress-controller  Ingress default/myapp-ingress
  12. Протестируйте работу приложения. Внешний IP-адрес, связанный с ingress-контроллером, можно на странице кластера. Он называется IP-адрес балансировщика нагрузки для Ingress Controller. Обозначим его как <INGRESS_EXTERNAL_IP>.

    ash-work:~ curl --resolve echo.com:80:<INGRESS_EXTERNAL_IP> http://echo.com/handler
  13. (Опционально) Удалите созданные в кластере сервисы:

    1ash-work:~ kubectl delete -f ingress.yaml
    2ash-work:~ kubectl delete -f service.yaml
    3ash-work:~ kubectl delete -f deployment.yaml

4. Разверните приложение в кластере Kubernetes с использованием GitLab CI/CD

GitLab по умолчанию поддерживает интеграцию с кластером Kubernetes. Чтобы настроить интеграцию, получите несколько параметров кластера:

  1. Получите API URL:

    ash-work:~ kubectl cluster-info | grep 'Kubernetes master' | awk '/http/ {print $NF}'
  2. Получите список секретов кластера:

    kubectl get secrets

    Ожидаемый вывод команды:

    1NAME                       TYPE                                  DATA   AGE
    2dashboard-sa-token-xnvmp   kubernetes.io/service-account-token   3      41h
    3default-token-fhvxq        kubernetes.io/service-account-token   3      41h
    4myprivateregistry          kubernetes.io/dockerconfigjson        1      39h
    5regcred                    kubernetes.io/dockerconfigjson        1      39h
  3. Получите PEM-сертификат секрета default-token:

    kubectl get secret default-token-fhvxq -o jsonpath="{['data']['ca\.crt']}" | base64 --decode
  4. Создайте файл gitlab-admin-service-account.yaml, который описывает права доступа GitLab к кластеру.

  5. Примените права и получите токен доступа к кластеру:

    1kubectl apply -f gitlab-admin-service-account.yaml
    2kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep gitlab-admin | awk '{print $1}')
  6. Перейдите в администраторскую часть интерфейса GitLab и нажмите Add Kubernetes Cluster:

  7. Выберите вкладку Add Existing cluster, внесите параметры (API URL, PEM, Token) и нажмите Add Kubernetes Cluster:

  8. Переместите файлы deployment.yaml, service.yaml, ingress.yaml в папку deployments проекта.

  9. В файл .gitlab-ci.yml добавьте секцию deploy:

  10. Проверьте namespace кластера:

    kubectl get namespaces

    Ожидаемый вывод команды:

    1NAME STATUS AGE
    2default Active 45h
    3gitlab-managed-apps Active 67m
    4ingress-nginx Active 45h
    5k8s-conf-demo-1-production Active 57m
    6kube-node-lease Active 45h
    7kube-public Active 45h
    8kube-system Active 45h
    9magnum-tiller Active 45h
  11. Посмотрите поды, сервисы и ingress в k8s-conf-demo-1-production:

    1kubectl get pods -n k8s-conf-demo-1-production
    2kubectl get services -n k8s-conf-demo-1-production
    3kubectl get ingress -n k8s-conf-demo-1-production
  12. Проверьте работоспособность приложения:

    ash-work:~ curl --resolve echo.com:<INGRESS_EXTERNAL_IP> http://echo.com/handler

    Ожидаемый вывод: OK.

  13. Для тестирования авторазвертывания измените код приложения: в файле репозитория app/app.py исправьте строку return 'OK' на return 'HANDLER OK'.

  14. Опубликуйте изменения:

    k8s-conf-demo git add . && git commit -m "update" && git push
  15. Дождитесь окончания выполнения CI/CD и проверьте вывод приложения повторно:

    ash-work:~ curl --resolve echo.com:<INGRESS_EXTERNAL_IP> http://echo.com/handler

    При успешной настройке авторазвертывания появится сообщение HANDLER OK.