使用 Gitlab Container Registry
前言⌗
在服务都趋向于 Go 语言化之后,遇到的第一个问题就是如何部署 Go 项目的二进制?我们一路走来爬了很多坑,总结出来的部署方式如下:
- 将二进制可执行文件直接复制到目标服务器,然后通过 Shell 脚本管理服务进程
- 将二进制可执行文件直接复制到目标服务器,通过预定义的 Service 配置文件,让 Systemd 管理服务进程
- 使用 Docker Image,在单台服务器上用 Docker CLI 管理服务进程
- 使用 Docker Image,通过容器编排与调度平台实现灰度发布
前三种方式有点是对于基础设施没啥要求,但是缺点也很明显,很难做到用户无感知的代码发布,除非在项目代码中集成一些第三方的服务注册与发现的基础设施,如 Consul 或 ETCD 等!
为了能顺利过渡到容器编排与调度,我们首先要做的就是从传统的二进制分发方式转变为 Docker Image 分发的方式,那么这就需要用到 Docker Container Registry。
对于代码管理用的是 Self-Hosted Gitlab 的团队而言,Gitlab Container Registry,是一个比较不错的选择,Gitlab 已经内置,只需要通过配置开启即可!
配置⌗
Gitlab 服务相关配置目录结构如下:
tree -a -I .git
.
├── .env
├── .gitignore
├── README.md
└── docker-compose.yml
1 directory, 5 files
.env
配置如下:
# Gitlab external access url
EXTERNAL_URL=https://gitlab.local
# Gitlab Pages external access url
PAGES_EXTERNAL_URL=https://pages.local
# Gitlab Container Registry external access url
REGISTRY_EXTERNAL_URL=https://registry.local
# The maximum size of the log before it is rolled. A positive integer plus a modifier representing the unit of measure (k, m, or g). Defaults to 20m.
GITLAB_CONTAINER_LOG_MAX_SIZE=1024m
# SSL Certificates
# SSL_CERTIFICATE=/etc/gitlab/ssl/fullchain.cer
# SSL_CERTIFICATE_KEY=/etc/gitlab/ssl/fullchain.key
# Email configuration
EMAIL_ENABLED=true
[email protected]
EMAIL_DISPLAY_NAME=Gitlab
[email protected]
# SMTP configuration. Related settings for other service providers please refer to https://docs.gitlab.com/omnibus/settings/smtp.html#example-configurations
SMTP_ENABLE=true
SMTP_ADDRESS=smtp.example.com
SMTP_PORT=465
[email protected]
[email protected]
SMTP_DOMAIN=smtp.example.com
SMTP_AUTHENTICATION=login
SMTP_ENABLE_STARTTLS_AUTO=false
SMTP_TLS=true
docker-compose.yaml
配置如下:
services:
gitlab:
image: 'gitlab/gitlab-ee:latest'
restart: no
logging:
options:
max-size: ${GITLAB_CONTAINER_LOG_MAX_SIZE}
hostname: gitlab
container_name: gitlab
networks:
- traefik
labels:
- traefik.enable=true
- traefik.http.routers.pages.tls=true
- traefik.http.routers.pages.rule=Host(`pages.local`)
- traefik.http.routers.pages.service=pages
- traefik.http.routers.pages.entrypoints=http,https
- traefik.http.routers.gitlab.tls=true
- traefik.http.routers.gitlab.rule=Host(`gitlab.local`)
- traefik.http.routers.gitlab.service=gitlab
- traefik.http.routers.gitlab.entrypoints=http,https
- traefik.http.routers.registry.tls=true
- traefik.http.routers.registry.rule=Host(`registry.local`)
- traefik.http.routers.registry.service=registry
- traefik.http.routers.registry.entrypoints=http,https
- traefik.http.services.pages.loadbalancer.server.port=80
- traefik.http.services.gitlab.loadbalancer.server.port=80
- traefik.http.services.registry.loadbalancer.server.port=5100
environment:
TZ: Asia/Shanghai
GITLAB_LOG_LEVEL: error
GITLAB_OMNIBUS_CONFIG: |
external_url '$EXTERNAL_URL';
nginx['enable'] = true;
nginx['listen_port'] = 80
nginx['listen_https'] = false
nginx['redirect_http_to_https'] = true
nginx['client_max_body_size'] = '1024m';
nginx['proxy_set_headers'] = {
"Host" => "$$http_host",
"Upgrade" => "$$http_upgrade",
"X-Real-IP" => "$$remote_addr",
"Connection" => "Upgrade",
"X-Forwarded-For" => "$$proxy_add_x_forwarded_for",
"X-Forwarded-Ssl" => "on",
"X-Forwarded-Proto" => "https"
};
registry['enable'] = true
registry_external_url '$REGISTRY_EXTERNAL_URL'
registry_nginx['listen_port'] = 5100
registry_nginx['listen_https'] = false
registry_nginx['redirect_http_to_https'] = true
registry_nginx['proxy_set_headers'] = {
"Host" => "$$http_host",
"X-Real-IP" => "$$remote_addr",
"X-Forwarded-For" => "$$proxy_add_x_forwarded_for",
"X-Forwarded-Ssl" => "on",
"X-Forwarded-Proto" => "https"
}
pages_external_url '$PAGES_EXTERNAL_URL';
gitlab_pages['enable'] = true;
gitlab_pages['listen_https'] = false;
gitlab_pages['inplace_chroot'] = true;
gitlab_pages['access_control'] = true;
pages_nginx['enable'] = true;
pages_nginx['listen_port'] = 80
pages_nginx['listen_https'] = false
pages_nginx['redirect_http_to_https'] = true
gitlab_rails['time_zone'] = 'Asia/Shanghai';
gitlab_rails['lfs_enabled'] = true;
gitlab_rails['gitlab_email_enabled'] = true;
gitlab_rails['gitlab_email_from'] = '$EMAIL_FROM';
gitlab_rails['gitlab_email_display_name'] = '$EMAIL_DISPLAY_NAME';
gitlab_rails['gitlab_email_reply_to'] = '$EMAIL_REPLY_TO';
gitlab_rails['smtp_enable'] = $SMTP_ENABLE;
gitlab_rails['smtp_address'] = '$SMTP_ADDRESS';
gitlab_rails['smtp_port'] = $SMTP_PORT;
gitlab_rails['smtp_user_name'] = '$SMTP_USER_NAME';
gitlab_rails['smtp_password'] = '$SMTP_PASSWORD';
gitlab_rails['smtp_domain'] = '$SMTP_DOMAIN';
gitlab_rails['smtp_authentication'] = '$SMTP_AUTHENTICATION';
gitlab_rails['smtp_enable_starttls_auto'] = $SMTP_ENABLE_STARTTLS_AUTO;
gitlab_rails['smtp_tls'] = $SMTP_TLS;
ports:
- "0.0.0.0:22:22"
volumes:
- gitlab-conf:/etc/gitlab
- gitlab-logs:/var/log/gitlab
- gitlab-data:/var/opt/gitlab
volumes:
gitlab-conf:
external: true
gitlab-logs:
external: true
gitlab-data:
external: true
networks:
traefik:
external: true
- 第 12~32 行
labels
用于向 Traefik 注册的反向代理。 - 第 54~64 行中的配置是用于开启 Gitlab Container Registry,以及配置 Nginx 反向代理。
我在本地搭建的所有的域名都用的
.local
这个 TLD。
启动服务⌗
docker compose up -d
测试⌗
访问 Gitlab 中项目的 Container Registry 页面:
登录⌗
docker login registry.local
Username: [email protected]
Password:
Login Succeeded
注意:这里如果域名不是公网可解析的域名,需要自己设置 DNS 或者设置
Docker Daemon
的 Proxy ,才能正常登录!将registry.local
替换为自己的域名。
Push Image⌗
我这里直接将 Traefik 官方的镜像重新打个 Tag 然后推送到 Gitlab Container Registry 中:
docker tag traefik:latest registry.local/devops/traefik:latest
docker push registry.local/devops/traefik:latest
The push refers to repository [registry.local/devops/traefik]
ef79cc9bf4db: Pushed
684de1f4a5df: Pushed
7f5495899e4d: Pushed
5f4d9fc4d98d: Pushed
latest: digest: sha256:4d7c60c1d882dafc8f0148231d836f7d1e2fef0d732daf1cd16f37d711afe689 size: 1157
然后再来看看项目中的 Container Registry 就有了刚才 Push 的 Image:
总结⌗
这只是服务容器化迈出的第一步,要想服务能够更好的发布,还需要更强大的编排和调度系统!
I hope this is helpful, Happy hacking…