在阿里云 ACK 中部署 GitLab
常见 GitLab 安装方式
Omnibus GitLab 和官方 Docker 镜像
你可以通过 GitLab 的 Linux 安装包(即 Omnibus GitLab)可以在机器上直接安装,或者可以通过 官方的 GitLab 镜像 在 Docker 中部署 GitLab,官方 GitLab Docker 镜像本质上是在 Docker 环境中安装了 Omnibus GitLab,所以二者使用和配置方式几乎接近。安装 Omnibus GitLab 包会一起安装 GitLab 所需的依赖,例如 Redis,PostgreSQL,sidekiq 等组件,这也就意味着用官方 GitLab Docker 镜像启动时,容器内已经运行了所有你需要的或者需要的组件。
1 | export GITLAB_HOME=$HOME/gitlab-vol |
成功启动后,通过 docker stats
查看 GitLab 容器的大概资源占用情况。
1 | docker stats gitlab --no-stream |
Helm chart 和 Operator
官方提供了 Helm chart 和 Operator 两种在 K8s 部署 GitLab 的方式。
Helm chart 和 Docker 镜像不同的是 GitLab 服务不再集中在一个容器中,你可以仅修改几个配置来快速部署 GitLab,也可以按需对 GitLab chart 定制,例如无需创建 PostgreSQL 和 Redis,而是直接连接生产环境中的服务,来满足更复杂的使用需求。
Helm 添加 GitLab chart repo:
1 | helm repo add gitlab https://charts.gitlab.io/ |
创建必要的初始配置后,执行命令(来自文档)来快速部署一个 GitLab chart 的 PoC:
1 | helm upgrade --install --version 7.10.2 gitlab gitlab/gitlab \ |
NOTE: 如果域名不正确,GitLab Runner 自动注册会失败。
版本 7.10.2 对应 GitLab 16.10.2,如果不确定版本,可以通过命令搜索:
1 | helm search repo -l gitlab/gitlab |
Operator 方式则是先在集群中部署 GitLab Operator,通过 CR(Custom Resource) 维护 GitLab chart 配置,GitLab Operator 会把根据 CR 创建和调整 GitLab 服务。
sameersbn/gitlab
sameersbn/gitlab 也是一个非常流行的 GitLab Docker 镜像,它从源码构建 GitLab CE,附带了 Nginx、Sidekiq 等必备的依赖组件,但不包含 Redis 和 PostgreSQL。它的最大优点是通过环境变量就能配置 GitLab,这样不论你是通过 Docker、Docker-Compose、或是直接在 K8s 环境中部署和管理它都很方便。
在 ACK 中部署 GitLab
我的部署方式就是使用 sameersbn/gitlab 镜像,因为它没有预装 PostgreSQL 和 Redis,所以我使用了 bitnami/postgresql 和 bitnami/redis 自建 PostgreSQL 和 Redis。也可以直接购买阿里云的相关产品代替自建。运行 GitLab 容器还是需要比较大的内存,考虑到 K8s Worker 上本来就会跑一些服务,机器最好是 4C8G 以上的配置。
NAS 存储类
部署中需要的持久卷都通过 StorageClass 动态卷制备,所以先在 NAS 控制台创建一个 NAS 文件系统,然后在 ACK 集群 - 存醋 - 存储类
中创建 StorageClass,你可以使用 GUI 创建,或者参考 gitlab-nas-sc.yaml 通过 YAML 创建一个 StorageClass。
部署 bitnami/postgresql 和 bitnami/redis
这两个镜像部署流程接近:
- 创建 PVC,这一步会从 StorageClass 创建 PV,并且和 PVC 绑定
- 通过环境变量配置,我偷懒把所有配置都写在了 ConfigMap 里,在 Pod 启动时,会从 ConfigMap 加载环境变量
- 在 ACK 里创建 StatefulSet,StatefulSet 的启动策略可以避免正在启动的 Pod 和即将退出的 Pod 同时挂载一个 PV
- 配置相应的网络 Service,这里我用了 Headless Service,毕竟都是只有一个实例,没有负载均衡的场景。
权限问题
bitnami 容器不运行在 root 用户,而 NAS 挂载的目录默认是 root 的,所以在挂载后访问会出现 Permission Denied
的情况。参考阿里云的文档,需要配置 securityContext:
1 | securityContext: |
runAsUser
和 fsGroup
一致,配置为 bitnami 镜像默认的用户 1001
。fsGroupChangePolicy
可以在持久卷重新挂载(比如 Pod 重启)时避免不需要的 chown 操作。
runAsGroup
不能配置,bitnami 容器运行时很多目录是通过 root 组权限访问的。
具体原因参考文档。
完整 YAML 文件参考 gitlab-redis.yaml 和 gitlab-pgsql.yaml。
部署 sameersbn/gitlab
部署 sameersbn/gitlab 流程和 bitnami 的差不多,参考文档调整配置,然后创建 StatefulSet 就可以了,不过没有什么权限需要特殊处理。就是镜像比较大,初次启动比较慢。
有几个配置需要注意:
GITLAB_HTTPS
设为了 true,这种情况下 GitLab 容器会额外监听 443 端口。这个配置会影响 GitLab UI 中展示链接时是否带上 https,而我们 https 是通过 Ingress 来实现的,所以在 Service 里还是只暴露 80。GITLAB_SSH_HOST
设置了一个不同的主机名,GITLAB_HOST
关联了 Ingress 端点,需要设置GITLAB_SSH_HOST
来关联 External Service 端点。
参考文件 gitlab-app.yaml。
ALB Ingress 和 NLB Service
简单聊聊在 ACK 中用 ALB、CLB、NLB 三款负载均衡产品。
ALB 和 ACK 结合最好,可以通过 CRD 管理,配置 Ingress 时,只要指定 Class 就行。但是最近有一个恶心人的操作,就是把基础版的功能 HTTPS 证书支持强行削了,手动可以配置 ALB 基础版的证书,但是没办法通过 CRD 匹配到证书了,你必须使用 3 倍价格的标准版才行。
CLB 用在 Nginx Ingress 上,如果用这套机制,ACK 会给一个集群域名,自动绑定到 CLB 端点上。
NLB 和 CLB 都是 4 层的,但是用法上不太一样。ACK 支持在 Service 的 annotations 里创建或者指定 NLB 实例,阿里云推荐使用这种方式把 Service 对外暴露。我试过创建一个 Nginx Ingress,然后通过修改 nginx-ingress-controller 的方式,让 Nginx Ingress 通过 NLB 对外暴露,不过这样会让 Ingress 处于非托管的状态,算是一种尝试性用法。
结尾
去年年初搭完 GitLab 后本想整理一下发篇博客的,结果一拖就拖到了现在。今年正好负责新集群搭建,迁移了 GitLab 后又想起这事,趁我还没忘记细节,赶紧整理出来。
这篇文章目的是聊聊用阿里云全家桶在 ACK 部署简单部署一个 GitLab,以及我的各种不靠谱操作,但从整体观感看,更像是 GitLab 场景下阿里云 ACK 全家桶使用。我在 ACK 中部署 GitLab 单纯是为了管理统一,如果考虑经济实惠,建议直接用 Omnibus 安装包方式,或者看看 gitea。