gitlab을 통한 CD 설정

한 번은 내 프로젝트 배포를 자동화하는 것에 대해 생각해 본 적이 있습니다. gitlab.com에서는 이를 위한 모든 도구를 친절하게 제공하고 있으며, 물론 그것을 파악하고 작은 배포 스크립트를 작성하여 사용하기로 결정했습니다. 이 기사에서 저는 제 경험을 커뮤니티와 공유합니다.

TL; DR

  1. VPS 설정: 루트 비활성화, 비밀번호 로그인, dockerd 설치, ufw 구성
  2. 서버 및 클라이언트용 인증서 생성 docs.docker.com/engine/security/https/#create-a-ca-server-and-client-keys-with-openssl tcp 소켓을 통한 dockerd 제어 활성화: docker 구성에서 -H fd:// 옵션을 제거합니다.
  3. docker.json에서 인증서 경로 설정
  4. 인증서의 내용으로 CI/CD 설정의 gitlab 변수에 등록합니다. 배포용 .gitlab-ci.yml 스크립트를 작성합니다.

데비안 배포판에 대한 모든 예를 보여드리겠습니다.

초기 VPS 설정

여기에서 예를 들어 인스턴스를 구입했습니다. DO, 가장 먼저 해야 할 일은 공격적인 외부 세계로부터 서버를 보호하는 것입니다. 나는 아무것도 증명하거나 주장하지 않을 것이며, 내 가상 서버의 /var/log/messages 로그만 표시할 것입니다.

스크린 샷gitlab을 통한 CD 설정

먼저 ufw 방화벽을 설치합니다.

apt-get update && apt-get install ufw

기본 정책 활성화: 모든 수신 연결 차단, 모든 발신 연결 허용:

ufw default deny incoming
ufw default allow outgoing

중요: ssh를 통한 연결을 허용하는 것을 잊지 마십시오.

ufw allow OpenSSH

일반 구문은 Allow connection on port: ufw allow 12345입니다. 여기서 12345는 포트 번호 또는 서비스 이름입니다. 거부: ufw 거부 12345

방화벽 켜기:

ufw enable

세션을 종료하고 ssh를 통해 다시 로그인합니다.

사용자를 추가하고 암호를 할당한 다음 sudo 그룹에 추가합니다.

apt-get install sudo
adduser scoty
usermod -aG sudo scoty

다음으로 계획에 따라 비밀번호 로그인을 비활성화해야 합니다. 이렇게 하려면 ssh 키를 서버에 복사합니다.

ssh-copy-id [email protected]

서버의 ip는 본인의 것이어야 합니다. 이제 이전에 생성한 사용자로 로그인을 시도하면 더 이상 비밀번호를 입력할 필요가 없습니다. 그런 다음 구성 설정에서 다음을 변경합니다.

sudo nano /etc/ssh/sshd_config

암호 로그인 비활성화:

PasswordAuthentication no

sshd 데몬을 다시 시작합니다.

sudo systemctl reload sshd

이제 귀하 또는 다른 사람이 루트로 로그인을 시도하면 실패합니다.

다음으로 dockerd를 설치합니다. 모든 것이 이미 변경될 수 있으므로 여기에서는 프로세스를 설명하지 않겠습니다. 공식 웹사이트 링크를 따라 가상 머신에 docker를 설치하는 단계를 진행합니다. https://docs.docker.com/install/linux/docker-ce/debian/

인증서 생성

docker 데몬을 원격으로 제어하려면 암호화된 TLS 연결이 필요합니다. 이렇게 하려면 생성하고 원격 시스템으로 전송하는 데 필요한 인증서와 키가 있어야 합니다. 공식 도커 웹 사이트의 지침에 제공된 단계를 따르십시오. https://docs.docker.com/engine/security/https/#create-a-ca-server-and-client-keys-with-openssl 서버에 대해 생성된 모든 *.pem 파일, 즉 ca.pem, server.pem, key.pem은 서버의 /etc/docker 디렉터리에 있어야 합니다.

도커 설정

docker 데몬 시작 스크립트에서 -H df:// 옵션을 제거합니다. 이 옵션은 docker 데몬을 제어할 수 있는 호스트를 알려줍니다.

# At /lib/systemd/system/docker.service
[Service]
Type=notify
ExecStart=/usr/bin/dockerd

다음으로, 아직 존재하지 않는 경우 설정 파일을 만들고 옵션을 설정합니다.

/etc/docker/docker.json

{
  "hosts": [
    "unix:///var/run/docker.sock",
    "tcp://0.0.0.0:2376"
  ],
  "labels": [
    "is-our-remote-engine=true"
  ],
  "tls": true,
  "tlscacert": "/etc/docker/ca.pem",
  "tlscert": "/etc/docker/server.pem",
  "tlskey": "/etc/docker/key.pem",
  "tlsverify": true
}

포트 2376에서 연결 허용:

sudo ufw allow 2376

새 설정으로 dockerd를 다시 시작합니다.

sudo systemctl daemon-reload && sudo systemctl restart docker

검사:

sudo systemctl status docker

모든 것이 녹색이면 서버에서 도커를 성공적으로 구성한 것으로 간주합니다.

gitlab에서 지속적 배포 설정

gitalab 작업자가 원격 도커 호스트에서 명령을 실행할 수 있으려면 dockerd에 대한 암호화된 연결을 위한 인증서와 키를 저장하는 방법과 위치를 결정해야 합니다. gitlbab 설정의 변수에 간단히 작성하여 이 문제를 해결했습니다.

스포일러 제목gitlab을 통한 CD 설정

cat을 통해 인증서와 키의 내용을 출력하기만 하면 됩니다. cat ca.pem. 복사하여 변수 값에 붙여넣습니다.

gitlab을 통해 배포를 위한 스크립트를 작성해 봅시다. docker-in-docker(dind) 이미지가 사용됩니다.

.gitlab-ci.yml

image:
  name: docker/compose:1.23.2
  # перепишем entrypoint , чтобы работало в dind
  entrypoint: ["/bin/sh", "-c"]

variables:
  DOCKER_HOST: tcp://docker:2375/
  DOCKER_DRIVER: overlay2

services:
  - docker:dind

stages:
  - deploy

deploy:
  stage: deploy
  script:
    - bin/deploy.sh # скрипт деплоя тут

주석이 있는 배포 스크립트의 내용:

빈/deploy.sh

#!/usr/bin/env sh
# Падаем сразу, если возникли какие-то ошибки
set -e
# Выводим, то , что делаем
set -v

# 
DOCKER_COMPOSE_FILE=docker-compose.yml
# Куда деплоим
DEPLOY_HOST=185.241.52.28
# Путь для сертификатов клиента, то есть в нашем случае - gitlab-воркера
DOCKER_CERT_PATH=/root/.docker

# проверим, что в контейнере все имеется
docker info
docker-compose version

# создаем путь (сейчас работаем в клиенте - воркере gitlab'а)
mkdir $DOCKER_CERT_PATH
# изымаем содержимое переменных, при этом удаляем лишние символы добавленные при сохранении переменных.
echo "$CA_PEM" | tr -d 'r' > $DOCKER_CERT_PATH/ca.pem
echo "$CERT_PEM" | tr -d 'r' > $DOCKER_CERT_PATH/cert.pem
echo "$KEY_PEM" | tr -d 'r' > $DOCKER_CERT_PATH/key.pem
# на всякий случай даем только читать
chmod 400 $DOCKER_CERT_PATH/ca.pem
chmod 400 $DOCKER_CERT_PATH/cert.pem
chmod 400 $DOCKER_CERT_PATH/key.pem

# далее начинаем уже работать с удаленным docker-демоном. Собственно, сам деплой
export DOCKER_TLS_VERIFY=1
export DOCKER_HOST=tcp://$DEPLOY_HOST:2376

# проверим, что коннектится все успешно
docker-compose 
  -f $DOCKER_COMPOSE_FILE 
  ps

# логинимся в docker-регистри, тут можете указать свой "местный" регистри
docker login -u $DOCKER_USER -p $DOCKER_PASSWORD

docker-compose 
  -f $DOCKER_COMPOSE_FILE 
  pull app
# поднимаем приложение
docker-compose 
  -f $DOCKER_COMPOSE_FILE 
  up -d app

주요 문제는 gitlab CI/CD 변수에서 일반 형식의 인증서 내용을 "풀아웃"하는 것이었습니다. 원격 호스트에 대한 연결이 작동하지 않는 이유를 알 수 없습니다. 호스트에서 sudo journalctl -u docker log를 보니 핸드셰이크에 오류가 있습니다. 나는 일반적으로 변수에 저장되는 것을 살펴보기로 결정했습니다. 이를 위해 cat -A $DOCKER_CERT_PATH/key.pem을 볼 수 있습니다. 캐럿 문자 tr -d 'r' 제거를 추가하여 오류를 해결했습니다.

또한 재량에 따라 출시 후 작업을 스크립트에 추가할 수 있습니다. 내 저장소에서 작업 버전을 확인할 수 있습니다. https://gitlab.com/isqad/gitlab-ci-cd

출처 : habr.com

코멘트를 추가