задний план
В настоящее время используется 5 серверов для сборкиKubernetes
В кластерной среде реализованы мониторинг и сбор журналов, а бизнес также вручную перенесен в кластер для бесперебойной работы, поэтому необходимоdocker
Процесс CICD среды перенесен вKubernetes
в кластере
Преимущество
Kubernetes
Кластеризация для реализации CICD имеет несколько существенных преимуществ.
-
Deployment
Естественная поддержка непрерывного развертывания в сочетании с другимиKubernetes
Функции также могут обеспечить сине-зеленое развертывание, канареечное развертывание и т. д. - новая версия
GitLab
иGitLab Runner
естественная поддержкаKubernetes
кластер, поддержкаrunner
Автоматическое масштабирование для сокращения использования ресурсов
окрестности
Kubernetes
Версия: 1.14
GitLab
Версия: 12.2.5
GitLab-Runner
Версия: 12.1.0
Docker
Версия среды: 17.03.1
Развертывание GitLab-Runner
Введение в конфигурацию
исходная средаgitlab runner
Выполняя вручную команду регистрации и команду запуска, предоставленную на официальном веб-сайте, он делится на два развертывания, что требует большего количества ручных операций.Kubernetes
, который поддерживает использованиеHelm
Развертывание в один клик, официальные документы следующие
На самом деле, рекомендации официальной документации не ясны, и многие конфигурации не представлены в документации.Рекомендуется перейти в репозиторий исходного кода, чтобы просмотреть подробную документацию по использованию параметров.
Введено несколько ключевых конфигураций, позже проект будет изменен.ci
будет использоваться файл конфигурации
Сборка с DinD больше не рекомендуется
официальная документациявводить
Use docker-in-docker workflow with Docker executor
The second approach is to use the special docker-in-docker (dind) Docker image with all tools installed (
docker
) and run the job script in context of that image in privileged mode.Note:
docker-compose
is not part of docker-in-docker (dind). To usedocker-compose
in your CI builds, follow thedocker-compose
installation instructions.Danger: By enabling
--docker-privileged
, you are effectively disabling all of the security mechanisms of containers and exposing your host to privilege escalation which can lead to container breakout. For more information, check out the official Docker documentation on Runtime privilege and Linux capabilities.Docker-in-Docker works well, and is the recommended configuration, but it is not without its own challenges:
- При использовании docker-in-docker каждое задание находится в чистой среде без прошлой истории. Параллельные задания работают нормально, потому что каждая сборка получает собственный экземпляр механизма Docker, поэтому они не будут конфликтовать друг с другом. Но это также означает, что задания могут быть медленнее, потому что нет кэширования слоев.
- By default, Docker 17.09 and higher uses
--storage-driver overlay2
which is the recommended storage driver. See Using the overlayfs driver for details.- Since the
docker:19.03.1-dind
контейнер и контейнер Runner не используют общую корневую файловую систему, рабочий каталог задания можно использовать в качестве точки монтирования для дочерних контейнеров.Например, если у вас есть файлы, которыми вы хотите поделиться с дочерним контейнером, вы можете создать подкаталог в/builds/$CI_PROJECT_PATH
and use it as your mount point (for a more thorough explanation, check issue #41227):
В любом случае используйтеDinD
Выполнение сборки контейнеров возможно, но сталкивается со многими проблемами, такими как использованиеoverlay2
Для работы в сети требуется версия Docker выше 17.09.
Using
docker:dind
Running the
docker:dind
also known as thedocker-in-docker
image is also possible but sadly needs the containers to be run in privileged mode. If you're willing to take that risk other problems will arise that might not seem as straight forward at first glance. Because the docker daemon is started as aservice
usually in your.gitlab-ci.yaml
it will be run as a separate container in your Pod. Basically containers in Pods only share volumes assigned to them and an IP address by which they can reach each other usinglocalhost
./var/run/docker.sock
is not shared by thedocker:dind
container and thedocker
binary tries to use it by default.To overwrite this and make the client use TCP to contact the Docker daemon, in the other container, be sure to include the environment variables of the build container:
DOCKER_HOST=tcp://localhost:2375
for no TLS connection.DOCKER_HOST=tcp://localhost:2376
for TLS connection.Make sure to configure those properly. As of Docker 19.03, TLS is enabled by default but it requires mapping certificates to your client. You can enable non-TLS connection for DIND or mount certificates as described in Use Docker In Docker Workflow wiht Docker executor
Включено по умолчанию после Docker 19.03.1TLS
Конфигурация, ее необходимо объявить во встроенной переменной окружения, иначе сообщение о подключении невозможноdocker
ошибка и используйтеDinD
создавать потребностиrunner
Включите привилегированный режим для доступа к ресурсам хоста, а так как привилегированный режим используется, вPod
средняя параrunner
Ограничение ресурсов, которое необходимо использовать, будет недействительным.
Создание образов Docker с помощью Kaniko
В настоящее время официально предусмотрен другой метод вdocker
Создавайте и отправляйте образы в контейнер, который является более элегантным и может обеспечить плавную миграцию, т.е.kaniko
Building a Docker image with kaniko
Его преимущества описаны на официальном сайте следующим образом.
Другой способ создать образ Docker в кластере Kubernetes — использоватьkaniko. икоко
- Позволяет создавать образы без привилегированного доступа.
- Работает без демона Docker.
В следующей практике для сборки образов Docker будут использоваться два метода, которые можно выбрать в соответствии с реальной ситуацией.
Развертывание с помощью Helm
ВытащитьHelm
Gitlab-Runner
Склад на локальный, изменить конфигурацию
поставь оригиналgitlab-runner
Конфигурация перенесена вHelm
, после миграции следующим образом
image: alpine-v12.1.0
imagePullPolicy: IfNotPresent
gitlabUrl: https://gitlab.fjy8018.top/
runnerRegistrationToken: "ZXhpuj4Dxmx2tpxW9Kdr"
unregisterRunners: true
terminationGracePeriodSeconds: 3600
concurrent: 10
checkInterval: 30
rbac:
create: true
clusterWideAccess: false
metrics:
enabled: true
listenPort: 9090
runners:
image: ubuntu:16.04
imagePullSecrets:
- name: registry-secret
locked: false
tags: "k8s"
runUntagged: true
privileged: true
pollTimeout: 180
outputLimit: 4096
cache: {}
builds: {}
services: {}
helpers: {}
resources:
limits:
memory: 2048Mi
cpu: 1500m
requests:
memory: 128Mi
cpu: 200m
affinity: {}
nodeSelector: {}
tolerations: []
hostAliases:
- ip: "192.168.1.13"
hostnames:
- "gitlab.fjy8018.top"
- ip: "192.168.1.30"
hostnames:
- "harbor.fjy8018.top"
podAnnotations: {}
Который настроен с закрытым ключом, интранетharbor
адрес,harbor
Извлечь закрытый ключ ресурса, политика ограничения ресурсов
Выбор GitLab-Runner может привести к ямам
выберитеrunner
зеркально какalpine-v12.1.0
, только этот момент, последняя версия бегуна 12.5.0, но в ней много проблем,alpine
Новая версия зеркала находится вKubernetes
Произошло прерывание, которое не удалось разрешитьDNS
проблема, отраженная вGitLab-Runner
в центреCould not resolve host
иserver misbehaving
Ознакомьтесь с решением
В ходе запроса выясняется, что на его официальном складе все еще есть много связанных проблем, которые не были закрыты.
Официальный гитлаб:Kubernetes runner: Could not resolve host
переполнение стека:Gitlab Runner is not able to resolve DNS of Gitlab Server
Приведенные решения без исключения относятся к переходу на alpine-v12.1.0.
We had same issue for couple of days. We tried change CoreDNS config, move runners to different k8s cluster and so on. Finally today i checked my personal runner and found that i'm using different version. Runners in cluster had
gitlab/gitlab-runner:alpine-v12.3.0
, when mine hadgitlab/gitlab-runner:alpine-v12.0.1
. We added lineimage: gitlab/gitlab-runner:alpine-v12.1.0
in
values.yaml
and this solved problem for us
Корень проблемы должен быть в том, что у базового образа alpine проблема с поддержкой кластера Kubernetes.
ndots breaks DNS resolving #64924
docker-alpine
Имеются также незакрытые соответствующие складыissue
, в котором упоминается оDNS
Проблемы с разбором тайм-аутов и исключений
Установить
Однострочная команда для установки
$ helm install /root/gitlab-runner/ --name k8s-gitlab-runner --namespace gitlab-runner
Вывод выглядит следующим образом
NAME: k8s-gitlab-runner
LAST DEPLOYED: Tue Nov 26 21:51:57 2019
NAMESPACE: gitlab-runner
STATUS: DEPLOYED
RESOURCES:
==> v1/ConfigMap
NAME DATA AGE
k8s-gitlab-runner-gitlab-runner 5 0s
==> v1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
k8s-gitlab-runner-gitlab-runner 0/1 1 0 0s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
k8s-gitlab-runner-gitlab-runner-744d598997-xwh92 0/1 Pending 0 0s
==> v1/Role
NAME AGE
k8s-gitlab-runner-gitlab-runner 0s
==> v1/RoleBinding
NAME AGE
k8s-gitlab-runner-gitlab-runner 0s
==> v1/Secret
NAME TYPE DATA AGE
k8s-gitlab-runner-gitlab-runner Opaque 2 0s
==> v1/ServiceAccount
NAME SECRETS AGE
k8s-gitlab-runner-gitlab-runner 1 0s
NOTES:
Your GitLab Runner should now be registered against the GitLab instance reachable at: "https://gitlab.fjy8018.top/"
Проверьте страницу администратора gitlab и обнаружите, что бегун был успешно зарегистрирован.
Инженерная конфигурация
DinD способ сборки необходимой конфигурации
Если оригиналci
файл основан на19.03 DinD
Зеркальные сборки должны быть добавленыTLS
Связанная конфигурация
image: docker:19.03
variables:
DOCKER_DRIVER: overlay
DOCKER_HOST: tcp://localhost:2375
DOCKER_TLS_CERTDIR: ""
...
Остальная конфигурация остается прежней, построена с помощью DinD.
Конфигурация разрешений Kubectl и Kubernetes
из-за использованияk8s
кластер, а развертывание через кластер требует использованияkubectl
клиент, поэтому вручную создалkubectl
docker
зеркало, использоватьgitlab
курокdockerhub
Конструкция, содержимое конструкции открыто и прозрачно, и его можно использовать с уверенностью.Если есть другие версии требований к конструкции, вы также можете отправить запрос на вытягивание, который будет добавлен позже.В настоящее время используется только 1.14.0.
имеютkubectl
Клиент, также необходимо настроить подключениеTLS
и связанные аккаунты
Для обеспечения безопасности создайте новый, который специально обращается к пространству имен проекта.ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: hmdt-gitlab-ci
namespace: hmdt
Используйте механизм RBAC, предоставляемый кластером, чтобы предоставить учетной записи права администратора для пространства имен.
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: hmdt-gitlab-role
namespace: hmdt
subjects:
- kind: ServiceAccount
name: hmdt-gitlab-ci
namespace: hmdt
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: admin
После создания запросите его уникальное имя, сгенерированное в кластере k8s, вотhmdt-gitlab-ci-token-86n89
$ kubectl describe sa hmdt-gitlab-ci -n hmdt
Name: hmdt-gitlab-ci
Namespace: hmdt
Labels: <none>
Annotations: kubectl.`Kubernetes`.io/last-applied-configuration:
{"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"hmdt-gitlab-ci","namespace":"hmdt"}}
Image pull secrets: <none>
Mountable secrets: hmdt-gitlab-ci-token-86n89
Tokens: hmdt-gitlab-ci-token-86n89
Events: <none>
Затем найдите сертификат ЦС в соответствии с приведенным выше секретом.
$ kubectl get secret hmdt-gitlab-ci-token-86n89 -n hmdt -o json | jq -r '.data["ca.crt"]' | base64 -d
Затем найдите соответствующий токен
$ kubectl get secret hmdt-gitlab-ci-token-86n89 -n hmdt -o json | jq -r '.data.token' | base64 -d
Конфигурация GitLab, связанная с Kubernetes
Войдите на страницу конфигурации кластера gitlab Kubernetes, заполните соответствующую информацию и разрешите gitlab автоматически подключаться к среде кластера.
Обратите внимание, что вам нужно снять этот флажок, иначе gitlab автоматически создаст новую учетную запись пользователя вместо использования уже созданной учетной записи пользователя и не сообщит об ошибке разрешения во время работы.
Ошибка, вызванная отказом от отмены, выглядит следующим образом: gitlab создал новую учетную запись пользователя.hmdt-prod-service-account
, но не имеет разрешения на работу с указанным пространством имен
Конфигурация среды GitLab
Создайте среду
Имя и URL-адрес можно настроить по мере необходимости.
Конфигурация CI-скрипта
Окончательный файл конфигурации CI выглядит следующим образом, в котором используетсяDinD
способ построитьDockerfile
image: docker:19.03
variables:
MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode -Dmaven.test.skip=true"
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
DOCKER_DRIVER: overlay
DOCKER_HOST: tcp://localhost:2375
DOCKER_TLS_CERTDIR: ""
SPRING_PROFILES_ACTIVE: docker
IMAGE_VERSION: "1.8.6"
DOCKER_REGISTRY_MIRROR: "https://XXX.mirror.aliyuncs.com"
stages:
- test
- package
- review
- deploy
maven-build:
image: maven:3-jdk-8
stage: test
retry: 2
script:
- mvn $MAVEN_CLI_OPTS clean package -U -B -T 2C
artifacts:
expire_in: 1 week
paths:
- target/*.jar
maven-scan:
stage: test
retry: 2
image: maven:3-jdk-8
script:
- mvn $MAVEN_CLI_OPTS verify sonar:sonar
maven-deploy:
stage: deploy
retry: 2
image: maven:3-jdk-8
script:
- mvn $MAVEN_CLI_OPTS deploy
docker-harbor-build:
image: docker:19.03
stage: package
retry: 2
services:
- name: docker:19.03-dind
alias: docker
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script:
- docker build --pull -t "$CI_REGISTRY_IMAGE:$IMAGE_VERSION" .
- docker push "$CI_REGISTRY_IMAGE:$IMAGE_VERSION"
- docker logout $CI_REGISTRY
deploy_live:
image: fjy8018/kubectl:v1.14.0
stage: deploy
retry: 2
environment:
name: prod
url: https://XXXX
script:
- kubectl version
- kubectl get pods -n hmdt
- cd manifests/
- sed -i "s/__IMAGE_VERSION_SLUG__/${IMAGE_VERSION}/" deployment.yaml
- kubectl apply -f deployment.yaml
- kubectl rollout status -f deployment.yaml
- kubectl get pods -n hmdt
Используйте при необходимостиKaniko
ПостроитьDockerfile
, конфигурация следующая
Обратите внимание, что зеркала, которые зависят от нихgcr.io/kaniko-project/executor:debug
Он принадлежит зеркальному складу Google и может быть недоступен.
image: docker:19.03
variables:
MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode -Dmaven.test.skip=true"
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
DOCKER_DRIVER: overlay
DOCKER_HOST: tcp://localhost:2375
DOCKER_TLS_CERTDIR: ""
SPRING_PROFILES_ACTIVE: docker
IMAGE_VERSION: "1.8.6"
DOCKER_REGISTRY_MIRROR: "https://XXX.mirror.aliyuncs.com"
cache:
paths:
- target/
stages:
- test
- package
- review
- deploy
maven-build:
image: maven:3-jdk-8
stage: test
retry: 2
script:
- mvn $MAVEN_CLI_OPTS clean package -U -B -T 2C
artifacts:
expire_in: 1 week
paths:
- target/*.jar
maven-scan:
stage: test
retry: 2
image: maven:3-jdk-8
script:
- mvn $MAVEN_CLI_OPTS verify sonar:sonar
maven-deploy:
stage: deploy
retry: 2
image: maven:3-jdk-8
script:
- mvn $MAVEN_CLI_OPTS deploy
docker-harbor-build:
stage: package
retry: 2
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
script:
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
- /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_REGISTRY_IMAGE:$IMAGE_VERSION
deploy_live:
image: fjy8018/kubectl:v1.14.0
stage: deploy
retry: 2
environment:
name: prod
url: https://XXXX
script:
- kubectl version
- kubectl get pods -n hmdt
- cd manifests/
- sed -i "s/__IMAGE_VERSION_SLUG__/${IMAGE_VERSION}/" deployment.yaml
- kubectl apply -f deployment.yaml
- kubectl rollout status -f deployment.yaml
- kubectl get pods -n hmdt
конвейер выполнения
бегун автоматически расширяется и сжимается
Kubernetes
Бегун в раннере будет автоматически расширяться и сжиматься в зависимости от количества задач Текущее ограничение конфигурации — 10.
Grafana также может отслеживать использование ресурсов кластера в процессе сборки.
использоватьDinD
ПостроитьDockerfile
результат
использоватьKaniko
ПостроитьDockerfile
результат
Результат развертывания
При развертывании gitlab автоматически внедрит настроенную конфигурацию.kubectl
config
построить результат
После завершения развертывания вы можете просмотреть результаты развертывания на странице конфигурации среды.Будут записаны только успешные развертывания.