文章目录
  1. 1. Docker CI
    1. 1.1. 构建私有 Docker Registry
      1. 1.1.1. 启动 registry
      2. 1.1.2. Insecure Registry
      3. 1.1.3. 配置TLS
      4. 1.1.4. Storage
        1. 1.1.4.1. 使用配置文件启动
      5. 1.1.5. Authentication
        1. 1.1.5.1. 启用authentication后,certificate再次报错
    2. 1.2. 持续集成
      1. 1.2.1. GitLab 钩子触发构建
      2. 1.2.2. Jenkin 构建
      3. 1.2.3. 通知 Container
      4. 1.2.4. 手动触发更新

Docker CI

构建私有 Docker Registry

启动 registry

1
docker run -d -p 5000:5000 --name registry registry:2

Insecure Registry

当尝试从配有配置TLS的Registry会报如下错

1
FATA[0000] Error response from daemon: v1 ping attempt failed with error: Get https://121.42.160.161:5000/v1/_ping: tls: oversized record received with length 20527. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry 121.42.160.161:5000` to the daemon's arguments. In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/121.42.160.161:5000/ca.crt

并且官方文档提到

While it’s highly recommended to secure your registry using a TLS certificate issued by a known CA, you may alternatively decide to use self-signed certificates, or even use your registry over plain http.

并且

Warning: it’s not possible to use an insecure registry with basic authentication

配置TLS

生成自签名证书

1
2
3
mkdir -p certs && openssl req \
-newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
-x509 -days 365 -out certs/domain.crt

如果生成自签名证书的host地址是IP,则需要编辑/etc/ssl/openssl.cnf,在[v3_ca]段落内添加

1
subjectAltName = IP:192.168.2.107

否则客户端连接时会报错

Failed to tls handshake with 192.168.2.107 x509: cannot validate certificate for 192.168.2.107 because it doesn’t contain any IP SANs

然后重启容器启用TLS

1
2
3
4
5
docker run -d -p 5000:5000 --restart=always --name registry \
-v `pwd`/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2

然后通过拷贝domain.crt到客户端/etc/docker/certs.d/myregistrydomain.com:5000/ca.crt,让每个docker进程信任证书。

Storage

关于Aliyun OSS storage driver配置参数参考这里

  • accesskeyid 阿里云accesskeyid
  • accesskeysecret 阿里云accesskeysecret
  • bucket 对应要存储到的bucket名称
  • internal 是否使用内部网络
  • region bucket对应的地区,例如oss-cn-beijing
  • endpoint (可选),驱动可以自动根据bucket、inernal、region的参数值,配置endpoint的值

配置的具体内容,大概是这个样子

1
2
3
4
5
6
7
storage:
oss:
accesskeyid: xxxxxxx
accesskeysecret: xxxxxxx
bucket: my-registry
internal: true
region: oss-cn-qingdao

使用配置文件启动

1
2
3
docker run -d -p 5000:5000 --restart=always --name registry \
-v `pwd`/config.yml:/etc/docker/registry/config.yml \
registry:2

Authentication

使用htpasswd后端授权的配置如下

1
2
3
4
auth:
htpasswd:
realm: basic-realm
path: /path/to/htpasswd

使用htpasswd命令生成htpasswd文件前,需要先安装apache2-utils。 另外htpasswd授权必须配合TLS一同使用,并且只支持bcrypt格式的密码

1
htpasswd -cB auth-conf yourusername

也可以使用registry容器中自带的htpasswd命令

1
docker run --entrypoint htpasswd registry:2 -Bbn testuser testpassword > auth/htpasswd

启用authentication后,certificate再次报错

报错的内容如下

1
FATA[0008] Error response from daemon: no successful auth challenge for https://121.42.160.161:5000/v2/ - errors: [Get https://121.42.160.161:5000/v2/: x509: certificate signed by unknown authority]

原因是当启用authentication后,一些docke的版本需要在OS级别信任证书。Ubuntu下如下操作

1
2
cp auth/domain.crt /usr/local/share/ca-certificates/myregistrydomain.com.crt
update-ca-certificates

持续集成

GitLab 钩子触发构建

首先需要在Jenkis的构建触发器中,配置身份验证令牌,然后在GitLab的Web hooks配置地址/buildWithParameters?token=TOKEN_NAME。 之后每当有代码push到GitLab后,就会触发这个钩子,发起Jenkins的构建,最终将构建的镜像推送到私有Registry中。

Jenkin 构建

Jenkins的构建流程大致如下

  1. 编译、测试、打包工程
  2. 下载打包的结果工程,连同运行环境一起构建到Docker的镜像文件中
  3. Push到私有Registry

前面的编译、测试、打包的步骤通过Jenkins提供的选项来配置,后面的镜像构建通过脚本来进行

1
2
3
docker build -t myrepo/api-server .
docker tag myrepo/api-server xxx.xxx.xxx.xxx:5000/myrepo/api-server
docker push xxx.xxx.xxx.xxx:5000/myrepo/api-server

通知 Container

镜像推送的私有Registry,需要通过Nofification通知Endpoint,拉去最新的镜像文件来更新运行环境。

Endpoint的对于收到的Event的处理是需要自己来实现的,相关的API在这里

手动触发更新

通过Nofification的方式处理更新需要会golang的一些语法才能进行。当然我们也可以通过Jenkins来手动触发更新。

首先我们需要通过http远程运行docker。docker默认监听Unix socket,需要让其支持通过http通讯,具体的配置可以参考这里。然后执行如下脚本

1
2
docker pull xxx.xxx.xxx.xxx:5000/myrepo/api-server
docker run docker run -d -p 8888:8080 xxx.xxx.xxx.xxx:5000/myrepo/api-server
文章目录
  1. 1. Docker CI
    1. 1.1. 构建私有 Docker Registry
      1. 1.1.1. 启动 registry
      2. 1.1.2. Insecure Registry
      3. 1.1.3. 配置TLS
      4. 1.1.4. Storage
        1. 1.1.4.1. 使用配置文件启动
      5. 1.1.5. Authentication
        1. 1.1.5.1. 启用authentication后,certificate再次报错
    2. 1.2. 持续集成
      1. 1.2.1. GitLab 钩子触发构建
      2. 1.2.2. Jenkin 构建
      3. 1.2.3. 通知 Container
      4. 1.2.4. 手动触发更新
Fork me on GitHub