祝你有愉快的一天
我们有多个云集群,每个集群中都有大量虚拟机。 我们在 Hetzner 主办这一切。 在每个集群中,我们有一台主机,从中获取快照并自动分发到集群内的所有虚拟机。
这种方案不允许我们正常使用 gitlab-runners,因为当出现许多相同的注册运行器时会出现很多问题,这促使我们找到解决方法并写了这篇文章/手册。
这可能不是最佳实践,但这个解决方案看起来尽可能方便和简单。
- 蟒蛇
- 混帐
- 带有 ssh 密钥的文件
在所有虚拟机上实现自动肠道拉取的一般原则是,您需要一台安装 Ansible 的机器。 在这台机器上,ansible 将发送 git pull 命令并重新启动已更新的服务。 为此,我们在集群外部创建了一个单独的虚拟机并安装在其上:
- 蟒蛇
- ansible
- gitlab-runner
从组织问题来看 - 您需要注册 gitlab-runner,制作 ssh-keygen,将本机的公共 ssh 密钥上传到 .ssh/authorized_keys
在主机上,为主机上的 ansible 打开端口 22。
现在让我们配置ansible
因为我们的目标是实现一切可能的自动化。 在文件中 /etc/ansible/ansible.cfg
我们将取消注释该行 host_key_checking = False
这样 ansible 就不会要求确认新机器。
接下来,您需要自动生成 ansible 的清单文件,从该文件中它将获取您需要执行 git pull 的机器的 IP。
我们使用 Hetzner 的 API 生成此文件,您可以从 AWS、Asure 数据库中获取主机列表(您在某处有一个 API 可以显示正在运行的机器,对吧?)。
库存文件的结构对于 Ansible 非常重要;它应该如下所示:
[группа]
ip-адрес
ip-адрес
[группа2]
ip-адрес
ip-адрес
为了生成这样的文件,我们将制作一个简单的脚本(我们称之为 vm_list
):
#!/bin/bash
echo [group] > /etc/ansible/cloud_ip &&
"ваш CLI запрос на получение IP запущенных машин в кластере" >> /etc/ansible/cloud_ip
echo " " >> /etc/ansible/cloud_ip
echo [group2] > /etc/ansible/cloud_ip &&
"ваш CLI запрос на получение IP запущенных машин в другом кластере" >> /etc/ansible/cloud_ip
现在是时候检查 Ansible 是否正常工作并且是否能够友好地接收 IP 地址:
/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'hostname' group
输出应包含执行命令的计算机的主机名。
关于语法的几句话:
- /etc/ansible/./vm_list - 生成机器列表
- -i - 库存文件的绝对路径
- -m - 告诉ansible使用shell模块
- -a 是参数。 可以在这里输入任何命令
- group — 您的集群的名称。 如果需要在所有集群上执行此操作,请将组更改为 all
让我们更进一步 - 让我们尝试在虚拟机上执行 git pull :
/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'cd /path/to/project && git pull' group
如果在输出中我们看到已经是最新的或从存储库中卸载,则一切正常。
现在这就是一切的目的
让我们教我们的脚本在提交到 gitlab 中的 master 分支时自动运行
首先,让我们的脚本变得更漂亮,并将其放入可执行文件中(我们称之为 exec_pull) -
#!/bin/bash
/etc/ansible/./get_vms && ansible -i /etc/ansible/cloud_ip -m shell -a "$@"
我们去我们的gitlab,在项目中创建一个文件 .gitlab-ci.yml
我们将以下内容放入其中:
variables:
GIT_STRATEGY: none
VM_GROUP: group
stages:
- pull
- restart
run_exec_pull:
stage: pull
script:
- /etc/ansible/exec_pull 'cd /path/to/project/'$CI_PROJECT_NAME' && git pull' $VM_GROUP
only:
- master
run_service_restart:
stage: restart
script:
- /etc/ansible/exec_pull 'your_app_stop && your_app_start' $VM_GROUP
only:
- master
一切准备就绪。 现在 -
- 做出承诺
- 我很高兴一切正常
将 .yml 转移到其他项目时,只需更改要重启的服务的名称以及将执行 ansible 命令的集群的名称。
来源: habr.com