通过 gitlab 设置 CD

我曾经想过自动化我的项目的部署。 gitlab.com 慷慨地为此提供了所有工具,当然我决定利用它,弄清楚它并编写一个小型部署脚本。 在这篇文章中,我与社区分享了我的经验。

TL博士

  1. 设置VPS:禁用root,使用密码登录,安装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进行部署。

我将展示 Debian 发行版上的所有示例。

初始 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

一般语法如下: 允许端口连接:ufw allowed 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

现在,如果您或其他人尝试以 root 用户身份登录,则将无法正常工作。

接下来,安装 dockerd,我不会在这里描述这个过程,因为一切都可以改变,按照官方网站的链接,完成在虚拟机上安装 docker 的步骤: https://docs.docker.com/install/linux/docker-ce/debian/

生成证书

要远程控制 docker 守护进程,需要加密的 TLS 连接。 为此,您需要拥有证书和密钥,必须生成证书和密钥并将其传输到远程计算机。 按照 docker 官方网站上的说明中给出的步骤进行操作: 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 目录中。

设置 dockerd

在docker daemon启动脚本中,我们删除了-H df://选项,该选项决定了docker daemon可以控制在哪台主机上。

# 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

如果一切都是“绿色”,那么我们就认为我们已经在服务器上成功配置了 docker。

在gitlab上设置持续交付

为了使 Gitalaba Worker 能够在远程 Docker 主机上执行命令,有必要决定如何以及在何处存储证书以及与 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 # скрипт деплоя тут

部署脚本的内容及注释:

bin/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 变量中“拉取”正常形式的证书内容。 我不明白为什么与远程主机的连接不起作用。 在主机上我查看了日志 sudojournalctl -u docker,握手过程中出现错误。 我决定查看变量中通常存储的内容;为此,您可以如下所示:cat -A $DOCKER_CERT_PATH/key.pem。 我通过添加删除回车符 tr -d 'r' 克服了该错误。

接下来,您可以自行决定将发布后任务添加到脚本中。 您可以在我的存储库中查看工作版本 https://gitlab.com/isqad/gitlab-ci-cd

来源: habr.com

添加评论