用 DevStream 搭建 Gitlab CI + Argo CD 工具链,管理 Python Flask 项目
- 使用 Docker 安装 GitLab,作为代码仓库(如果你的服务器上已经安装了 GitLab,可以跳过这一步);
- 在 GitLab 上创建一个 Python Web 应用程序仓库,基于 Flask 框架;
- 使用 GitHub CI 为我们创建的仓库设置基本的 CI 流水线;
- 在 一个已有的 Kubernetes 集群 中安装 以实现 GitOps;
- 创建一个 Argo CD 应用程序,用于部署第 1 步中生成的 Web 应用程序。
1 概览
DevStream 将使用下面的插件来实现中描述的目标:
- gitlab-ce-docker:用于在 Docker 中安装 GitLab;
- : 用于在 GitLab 上创建一个 Python Web 应用程序仓库;
- gitlab-ci:用于为我们创建的仓库设置基本的 CI 流水线;
- : 用于在 Kubernetes 集群中安装 Argo CD;
- argocdapp: 用于创建一个 Argo CD 应用程序,来部署第 1 步中生成的 Web 应用程序。
我们将分成两个步骤来完成这些目标:
- 编写一个配置文件,完成工具的安装,GitLab 和 Argo CD;
- 编写一个配置文件,完成后续流水线的创建、代码仓库的创建,并将其部署到 Argo CD 中。
为本教程创建一个临时工作目录:
Bash
接着,在新创建的目录下,运行下面的命令:
Bash
sh -c "$(curl -fsSL https://download.devstream.io/download.sh)"
这个脚本会根据你的操作系统来下载对应的 dtm
二进制文件,保存到当前目录。然后,赋予其可执行权限。
2 安装 GitLab 和 Argo CD
创建 config-tools.yaml
文件,你可以修改 vars
中的值来适应你的环境:
config-tools.yaml
config:
state:
backend: local
options:
stateFile: devstream-1.state
gitlabHostname: gitlab.example.com
gitlabSSHPort: 30022
gitlabHttpPort: 80
gitlabHttpsPort: 30443
tools:
- name: gitlab-ce-docker
instanceID: default
dependsOn: []
options:
hostname: [[ gitlabHostname ]]
gitlabHome: /srv/gitlab
sshPort: [[ gitlabSSHPort ]]
httpPort: [[ gitlabHttpPort ]]
httpsPort: [[ gitlabHttpsPort ]]
rmDataAfterDelete: false
imageTag: "rc"
- name: helm-installer
instanceID: argocd
并修改服务器的 /etc/hosts
文件,添加 gitlab.example.com
的域名解析。如果你的服务器 ip 是 44.33.22.11,就可以这样配置:
/etc/hosts
44.33.22.11 gitlab.example.com
2.2 初始化(Init)
运行下面的命令来下载安装 GitLab 和 Argo CD 所需的插件:
Bash
dtm init -f config-tools.yaml -y
2.3 应用(Apply)
Bash
你会看到类似于下面的输出:
2.4.1 访问 GitLab
你可以在自己的 PC 里配置 44.33.22.11 gitlab.example.com
静态域名解析记录,然后在浏览器里通过 http://gitlab.example.com
访问到 GitLab(如果浏览器报了:
GitLab 登录界面
通过执行如下命令,你可以设置 GitLab 的 root 密码:
get GitLab root Password
gitlab-rake "gitlab:password:reset" # 执行后按照提示输入用户名 root,回车后输入密码
拿到 root 密码后,你可以尝试用 root/YOUR_PASSWORD 来登录 GitLab。因为后面你还需要用到 GitLab 的 token,所以这时候你可以顺手先创建一个 token:
Generate GitLab token
2.4.2 查看 Argo CD
可以看到 Argo CD 已经被安装到了 Kubernetes 的 argocd
命名空间中:
Bash
[root@ip-10-18-13-200 devstream]# kubectl get ns
NAME STATUS AGE
argocd Active 36s
default Active 6d4h
kube-node-lease Active 6d4h
kube-public Active 6d4h
kube-system Active 6d4h
[root@ip-10-18-13-200 devstream]# kubectl get pods -n argocd
NAME READY STATUS RESTARTS AGE
argocd-application-controller-0 1/1 Running 0 49s
argocd-applicationset-controller-7f4577c5fd-8z926 1/1 Running 0 49s
argocd-dex-server-7cdb45c7c9-nspgz 1/1 Running 0 49s
argocd-notifications-controller-65b77fb646-phdwh 1/1 Running 0 49s
argocd-redis-577c6c8f5c-nf5xm 1/1 Running 0 49s
argocd-repo-server-7bd9fd899c-7f6cp 1/1 Running 0 49s
argocd-server-6686bbcf68-fms5w 1/1 Running 0 49s
3.1 配置准备
创建 config-apps.yaml
文件,你可以修改 vars
中的值来适应你的环境(尤其是dockerhubUser
这个配置):
config-apps.yaml
config:
state:
backend: local
options:
stateFile: devstream-2.state
vars:
appName: myapp
defaultBranch: main
dockerhubUser: DOCKERHUB_USER
apps:
- name: [[ appName ]]
spec:
language: python
framework: flask
repo:
url: [[ gitlabURL ]]/root/[[ appName ]].git
branch: [[ defaultBranch ]]
repoTemplate:
url: https://github.com/devstream-io/dtm-repo-scaffolding-python-flask.git
ci:
- type: template
templateName: ci-pipeline
cd:
- type: argocdapp
pipelineTemplates:
- name: ci-pipeline
type: gitlab-ci
options:
runner:
enable: true
imageRepo:
user: [[ dockerhubUser ]]
password: [[ env DOCKERHUB_TOKEN ]] # use "DOCKERHUB_TOKEN" env var
你可能已经注意到了,上面的配置中有形如 [[ env XXX ]]
的内容,这表示我们引用了 “XXX” 环境变量来填充配置。所以我们还需要设置如下两个环境变量:
Bash
export GITLAB_TOKEN="YOUR_GITLAB_TOKEN_HERE"
export DOCKERHUB_TOKEN="YOUR_DOCKERHUB_TOKEN_HERE"
3.2 初始化(Init)
Bash
运行:
Bash
dtm apply -f config-apps.yaml -y
你会看到类似下面的输出:
3.4 查看结果
3.4.1 查看 在 GitLab 上创建的 Flask 仓库
Flask 仓库
3.4.2 基于 GitLab CI 的 CI 流水线
通过浏览器访问 http://gitlab.example.com
,依次点击 CI/CD
、Pipelines
:
GitLab CI 概览
3.4.3 基于 Argo CD 的持续交付/部署
CI 流水线已经构建了一个 Docker 镜像并推送到了 Dockerhub,而 DevStream 创建的 Argo CD 应用也部署了这个应用:
Bash
[root@ip-10-18-13-200 devstream]# kubectl get deployment -n default
NAME READY UP-TO-DATE AVAILABLE AGE
myapp 1/1 1 1 101s
[root@ip-10-18-13-200 devstream]# kubectl get pods -n default
NAME READY STATUS RESTARTS AGE
myapp-b65774f56-8cmjc 1/1 Running 0 106s
[root@ip-10-18-13-200 devstream]# kubectl get services -n default
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 12d
myapp ClusterIP 10.101.148.66 <none> 8080/TCP 110s
我们可以通过端口转发来访问这个应用:
Bash
kubectl port-forward -n default svc/myapp 8080:8080
在浏览器中访问 localhost:8080
,你可以看到应用返回了一个 “Hello, World!”。大功告成!
4 清理
4.1 删除 Web 应用
运行:
Bash
dtm delete -f config-apps.yaml -y
运行:
Bash
4.3 删除其他文件
cd ../
rm -rf test/
rm -rf ~/.devstream/