亚马逊AWS官方博客

关于Amazon EKS基于Gitlab的CICD实践一 Gitlab的部署和配置篇

关于Amazon EKS基于Gitlab的CICD实践二 基础架构和应用架构创建篇

在容器化,微服务,基础设施即代码(IaC)以及DevOps的理念不断被大家所接受和理解,摆在大家面前的是如何在实际的工作中应用和实践这些理念了? 本文将讨论基于Gitlab来实现针对公有云基础设施(亚马逊云科技的公有云)和应用系统(基于亚马逊云科技的EKS)的CICD的实践。
首先,我来先回顾和理解一下什么是DevOps, CICD, GitOps,以及他们的关联关系?
1) DevOps: 是文化理念、实践和工具的结合,它提高了组织高速交付应用和服务的能力。与使用传统软件开发和基础设施管理流程的组织相比,以更快的速度发展和改进产品。这种速度使组织能够更好地服务于他们的客户并在市场上更有效地竞争。
在DevOps模式下,开发和运营团队不再是 “孤立的”。有时,这两个团队被合并成一个团队,工程师们在整个应用程序的生命周期中工作,从开发和测试到部署到运营,并发展一系列的技能,而不局限于单一功能。
2) CICD: Continuous Integration and Continuous Delivery/Deployment,CI是一种编码哲学和一套实践,它促使开发团队实施小的变化,并经常向版本控制库提交代码。因为大多数现代应用程序需要在不同的平台和工具中开发代码,团队需要一个机制来整合和验证其变化。自动化的测试和验证完成之后,CD将应用程序自动交付给选定的基础设施环境(可以线下数据中心也可以是亚马逊云科技的公有云)。另外,CICD是DevOps团队需要实施的最佳实践之一。它也是一种敏捷方法论的最佳实践,因为它使软件开发团队能够专注于满足业务需求、代码质量和安全,又因为其编译,测试和部署的步骤是自动化的,从而能达到敏捷。
3) GitOps:  是一个操作框架,它采用了用于应用开发的DevOps最佳实践,如版本控制、协作、合规和CI/CD,并将其应用于基础设施自动化。GitOps坚持的原则是,Git是唯一的真理之源。GitOps要求将系统的理想状态存储在版本控制中,这样任何人都可以查看整个变化的审计状况。所有对预期状态的修改都是完全可追踪的提交(PM),与提交者信息、提交ID和时间戳相关联。这意味着应用程序和基础设施现在都是版本化的工件,可以使用软件开发和交付的黄金标准进行审计。GitOps基于Git的源代码管理系统,因此GitHub、GitLab和Bitbucket都是适合的选择。

可以看出DevOps是更偏向方法论,而CICD是对DevOps这一方法论的实践,而对于Kubernetes和IaC,GitOps又是对DevOps的一个具体的细化和实践。
在进入正式的部署和实践的过程之前,我们先来了解一下我们需要用到的工具,其实在基于Kubernetes来交付应用的CICD工具,现在就已经有ArgoCD, FluxCD, Jenkins X, 它们的对比可以参考下文:
FluxCD, ArgoCD or Jenkins X: Which Is the Right GitOps Tool for You?
https://blog.container-solutions.com/fluxcd-argocd-jenkins-x-gitops-tools
但是今天我们会讨论更普适的CICD工具Gitlab, 因为它不仅能满足基于Kubernetes来实现CICD,而且它还可以实现更多其他场景下的CICD。具体需要使用的工具介绍:

功能 具体工具 注释
版本控制 Git Git是一个开源的分布式的版本控制系统
DevOps系统 Gitlab Gitlab是一个DevOps平台.
CICD系统 Gitlab CICD GitLab CI/CD是一个内置于GitLab的软件开发工具
基础设施即代码 Terraform Terraform是一个开源的基础设施即代码工具
数据库版本控制 Liquibase Liquibase是一个开源的数据库版本控制和迁移工具
容器编排 Amazon EKS Amazon EKS是一个亚马逊云科技提供的托管的Kubernetes服务
数据库 Amazon RDS Amazon RDS是一个亚马逊云科技提供的托管的数据库服务
容器仓库 Amazon ECR Amazon ECR是一个全托管的容器镜像仓库
容器技术 Docker Docker是一种容器技术
包管理 Helm Helm是一个开源的Kubernetes应用程序/包管理工具

具体的内容分成如下的部分:
(一)部署的架构
(二)Gitlab的部署和配置
(三)基础架构的部署

(1) Amazon RDS 的创建

(2) Amazon EKS的创建

(四)应用架构的部署

(1) Amazon RDS 数据库中数据的部署

(2) Amazon EKS集群中应用的部署

(一)部署的架构



(1)部署Gitlab的环境,这里为单机环境用于演示
(2)部署和配置Runner
(3)通过Terraform创建Amazon RDS for MySql数据库
(4)通过Terraform创建Amazon EKS集群
(5)编译docker镜像,推送到ECR中,部署EKS Ingress,再通过EKS编排和发布容器应用
(6)通过Liquibase来版本控制数据库的数据更新,向Amazon RDS for MySql数据库中导入数据或回滚
其中有Runner(运行器)和Executor(执行器)两个概念特别重要,它们具体的含义和作用以及需要注意的点如下:

1)Runner(运行器)

GitLab Runner是一个与GitLab CI/CD协同工作的应用程序,可以在一个CICD pipeline中运行你设定的job(作业)。
你可以选择在你拥有或管理的基础设施上安装GitLab Runner应用程序。如果这样的话,出于安全和性能的考虑,你应该把GitLab Runner安装在其他不同机器上。如上面的部署架构图,GitLab是安装在EC2(Gitlab) 的实例上,GitLab Runner是可以部署在EC2(runner)-A,EC2(runner)-B,或是Server(runner),VM(runner)等on-premise环境上。当你使用独立的机器时,你可以在每个机器上使用不同的操作系统和工具,如Kubernetes或Docker。这样承载你的CICD的pipeline是在一个中心化的Gitlab端(调度管理端),而执行你CICD pipeline作业的执行器可以在任何方便和目标基础设施环境通讯的机器上。本次部署,为了runner端便于下载需要的软件包,runner是部署在EC2(runner)-B,海外的EC2上。
另外,安装完应用程序后,要注册各个Runner。因为Runner是运行来自GitLab的CI/CD作业的代理,所以当你注册一个运行器时,你将在你的GitLab实例和安装GitLab运行者的机器之间建立通信。

2)Executor(执行器)

当你注册一个runner时,你必须选择一个执行器。执行器决定了每个作业的运行环境。
比如说:
如果你想让你的CI/CD工作运行PowerShell命令,你可以在Windows服务器上安装GitLab Runner,然后注册一个使用shell执行器的运行器。
如果你想让你的CI/CD工作在自定义的Docker容器中运行命令,你可以在Linux服务器上安装GitLab Runner并注册一个使用Docker执行器的运行器。
这些只是其中几种可能的配置。你可以将GitLab Runner安装在一台虚拟机上,比如部署架构图中的VM(runner),让它使用另一台虚拟机作为执行器。
当你在Docker容器中安装GitLab Runner并选择Docker执行器来运行你的作业时,它有时被称为 “Docker-in-Docker “配置。

3)谁可以在GitLab用户界面中访问运行器

在注册一个运行器之前,你应该确定是否GitLab中的每个人都应该访问它,或者你想把它限制在一个特定的GitLab组或项目。根据你想要限定的访问对象,有三种类型的运行器。
Shared runners: 是供所有项目使用的
Group runners: 适用于一个群组中的所有项目和子群组
Specific runners: 是为单个项目使用的

4)标签

当你注册一个运行器时,你可以给它添加标签。当CI/CD job(作业)运行时,它通过查看分配的标签知道使用哪个运行器。
例如,如果一个运行器有ruby标签,你可以在项目的 .gitlab-ci.yml 文件中添加这段代码。
job:

tags:

– ruby

当作业运行时,它会使用带有ruby标签的运行器。

(二)Gitlab的部署和配置

此处以亚马逊云科技宁夏区域为例,并假设您已经创建了部署架构图(如上)中的VPC和(1)处的EC2(Amazon Linux 2)。如您没有创建,请参考如下链接:
教程:Amazon EC2 Linux 实例入门,注意在创建安全组的时候需要放开ssh(TCP 22)和https(TCP 443)两个端口。
Gitlab是开源软件,主要分为两个版本CE(Community Edition—社区版)和EE(Enterprise Edition—企业版), 社区版和企业版都是免费的,也都不需要注册或获得许可证,但是企业版包括了社区版的所有功能,如果你决定升级到付费级别并解锁更多的功能,请使用企业版,会更方便地做到这一点。这里的安装演示仍然以社区版为例,登陆到EC2(Gitlab):
# 安装依赖的软件包
sudo yum install -y curl policycoreutils-python openssh-server openssh-clients perl
# 查看sshd服务是否开启
sudo systemctl status sshd
命令输出中显示active(running),说明sshd服务正常运行
# 如果sshd服务没有开启,请启动
sudo systemctl enable sshd
sudo systemctl start sshd
# 配置gitlab的yum repository
curl -s https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash

在安装Gitlab之前,请确认EC2 DNS名称正确启用,特别是通过EIP来访问未来的Gitlab页面的话,确保共有IPV4 DNS可以正常访问

# 安装Gitlab,替换掉EXTERNAL_URL=后面https://…部分为你的EC2的共有IPV4 DNS
sudo EXTERNAL_URL="https://ec2-161-*-*-*.cn-northwest-1.compute.amazonaws.com.cn" yum install -y gitlab-ce
可以看到在安装结束后,会告诉我们登陆Gitlab的用户名和密码的位置,以及Gitlab访问的地址,其实就是EC2的DNS地址
所以Gitlab单机安装是比较方便简单的,对于一个企业级环境,特别是在亚马逊云科技的公有云上部署,推荐使用如下的架构,链接中包含部署和配置步骤:
https://docs.gitlab.com/ee/install/aws/

另外,Gitlab官方针对用户数的不同有推荐的云端资源(EC2机型等)的推荐,请参考:
https://docs.gitlab.com/ee/administration/reference_architectures/index.html
登陆Gitlab的系统后,立即修改密码


创建Project,点击 New project 按钮

选择 Create blank project
设定你的Project的名称,此处为gitlabcicd,Project slug会随着Project name自动生成

配置SSH Key,这样客户端(workstation)通过git命令就可以访问Gitlab

# 创建SSH keypair,可以在您的workstation/笔记本上生成,workstation/笔记本上Git命令将使用这个私钥和Gitlab通讯
ssh-keygen -t rsa -b 2048 -C "gitlabcicd"

# 添加公钥(id_rsa.pub)到Gitlab, 可以使用如下的命令来复制公钥,也可以直接打开id_rsa.pub文件,复制其中内容。但需要注意
粘贴你的SSH公钥,它通常包含在~/.ssh/id_rsa.pub文件中,以ssh-rsa开头。不要粘贴你的ssh的私钥,因为那会暴露你的身份,有安全风险。
macOS:
tr -d '\n' < ~/.ssh/id_rsa.pub | pbcopy
Linux (requires the xclip package):
xclip -sel clip < ~/.ssh/id_rsa.pub
Git Bash on Windows:
cat ~/.ssh/id_rsa.pub | clip

我已经将所有要用到的代码和各种文件都已经存放在Github上,地址为https://github.com/jerryjin2018/gitlabcicd   所以接下来我们将从Github下载的内容push到Gitlab上。
# 在您的workstation/笔记本执行如下命令
cd ~
git clone https://github.com/jerryjin2018/gitlabcicd.git
cd gitlabcicd
rm -fr ./.git

git init --initial-branch=main
git remote add origin git@ec2-161-*-*-*.cn-northwest-1.compute.amazonaws.com.cn:root/gitlabcicd.git
git add .
git commit -m "Initial commit"
git push -u origin main


这样就把代码和文件push到Gitlab上了。

在进入下一个环节之前,还需要配置Gitlab runner,登陆到EC2(runner)-B,执行如下的命令:
#  安装docker
sudo yum install -y docker

# 启动docker服务
sudo systemctl enable docker.service
sudo systemctl enable docker.socket
sudo systemctl start docker.service
ps -ef | grep -i docker

#  创建Gitlab 官方的yum repo
#  For RHEL/CentOS/Fedora
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh" | sudo bash

#  安装Gitlab runner
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh" | sudo bash


# 检查Gitlab runner的运行情况,特别是其配置文件的位置
sudo ps -ef | grep -i runner

我们可以改变GitLab runner的行为,通过修改一个名为config.toml的文件,该文件使用TOML格式。
你可以在以下位置找到config.toml文件。
/etc/gitlab-runner/ 在*nix系统中,当GitLab Runner以root身份执行时(这也是服务配置的路径)。
~/.gitlab-runner/ 在*nix系统上,当GitLab Runner以非root身份执行时。
根据之前命令的输出,可以知道Gitlab runner的配置文件的位置为/etc/gitlab-runner/config.toml
在Register(注册)runner之前,我们需要获得URL和registration token信息。
根据运行器(runner)你设定的类型不同,获取相应信息的步骤如下:
shared runner,请管理员进入GitLab管理区,点击 Overview > Runners
group runner,进入 Settings > CI/CD 并展开 Runners 部分
project-specific runner,进入 Settings > CI/CD 并展 Runners 部分
此处以project-specific runner为例:
1)打开之前创建的gitlabcicd project:

2)到setting-CI/CD-Runners的页面

3)获得需要的URL和registration token信息,复制下来供以下步骤使用

使用如下命令Register(注册)runner,–url后替换为上一步获得的url,–registration-token 后替换为上一步获得的registration token,–executor 后替换为你要使用的executor(执行器),此处使用的是docker,–docker-image 后替换为你指定的docker镜像。–name后面为设定的runner的名称。
sudo gitlab-runner register -n  --url=https://ec2-161-*-*-*.cn-northwest-1.compute.amazonaws.com.cn --name=project-runner-1   --registration-token=k_*******************  --run-untagged=true   --locked=false   --executor=docker --docker-image=hashicorp/terraform:light

另外为了确保后面的Docker in Docker(Dind)能正确获得权限,请修改/etc/gitlab-runner/config.toml中 privileged = false 为 privileged = true。
这是在gitlab的页面中

至此Gitlab的部署和配置完成。

关于Amazon EKS基于Gitlab的CICD实践二 基础架构和应用架构创建篇

参考材料:

https://www.infoworld.com/article/3271126/what-is-cicd-continuous-integration-and-continuous-delivery-explained.html
https://blog.container-solutions.com/fluxcd-argocd-jenkins-x-gitops-tools
https://aws.amazon.com/devops/
https://about.gitlab.com/topics/gitops/
https://www.cloudbees.com/gitops/what-is-gitops
https://about.gitlab.com/is-it-any-good/
https://about.gitlab.com/stages-devops-lifecycle/continuous-integration/
https://www.terraform.io/
https://www.liquibase.org/
https://www.amazonaws.cn/eks/?nc1=h_ls
https://www.amazonaws.cn/rds/?nc1=h_ls
https://www.amazonaws.cn/ecr/?nc1=h_ls
https://www.docker.com/
https://helm.sh/

本篇作者

金忠敏

AWS解决方案架构师,现在专注于云计算解决方案和架构的工作。具有超过15年的IT从业经验,曾从事软件开发,售后支持,系统交付,售前等工作。参与过很多大型项目架构设计和实施交付。

肖元君

AWS解决方案架构师,负责基于AWS云计算方案的架构咨询和设计实现,同时致力于数据分析与AI的研究与应用。