Harbor定制nginx

问题分析

最近公司的Harbor仓库使用Amazon S3。docker在push和pull镜像会出现失败的情况,主要原因是公司内网某些网段无法访问acc.gz.test.cn。

1
error pulling image configuration: Get http://acc.gz.test.cn/Vault_For_Test/harbor/prefix/docker/registry/v2/blobs/sha256/c5/c59f17fe53b08db7dae3f597e863281517faf09739f1f6b35965cd6931de 88b3/data?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=bv2enbwmVLqusc1teSvh%2F20171218%2Fus-west-1%2Fs3%2Faws4_request&X-Amz-Date=20171218T032155Z&X-Amz-Expires=1200&X-Amz-SignedHeaders =host&X-Amz-Signature=3fc5d5bdb223efeedc6da18f90b4f300fd1bec06dedcf947a88621fd8d5aae7a: dial tcp: lookup ac.gz.test.cn on 172.17.82.12:53: no such host

本来该问题的解决方法比较简单,在内网找一个能够访问acc.gz.test.cn的网关,通过Nginx代理,在不能访问的网段配置Hosts文件即可即可。然而考虑到用户的使用习惯,还是决定解决一下。

通过错误信息,可以判断docker在push或者pull的时候,发生了重定向的操作。重定向的Location就是报错信息中的

1
2
3
http://acc.gz.test.cn/Vault_For_Test/harbor/prefix/docker/registry/v2/blobs/sha256/c5/c59f17fe53b08db7dae3f597e863281517faf09739f1f6b35965cd6931de
88b3/data?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=bv2enbwmVLqusc1teSvh%2F20171218%2Fus-west-1%2Fs3%2Faws4_request&X-Amz-Date=20171218T032155Z&X-Amz-Expires=1200&X-Amz-SignedHeaders
=host&X-Amz-Signature=3fc5d5bdb223efeedc6da18f90b4f300fd1bec06dedcf947a88621fd8d5aae7a

查看nginx的日志信息,发现在访问Registry的V2接口的时候,有返回307的响应。

那么,在Harbor的nginx这里做一些手脚,当返回的响应是307的时候,修改Location字段,将acc.gz.test.cn替换为其他可以被DNS解析的域名,将该域名代理到acc.gz.test.cn。

定制Nginx

因为需要修改HTTP响应,Harbor自带的Nginx是不行的,需要使用openresty。

首先,修改docker-compose.yml 文件。

1
2
3
4
5
6
7
proxy:
image: openresty/openresty:alpine
container_name: nginx
restart: always
volumes:
- ./common/config/nginx:/usr/local/openresty/nginx/conf:z
#- ./common/config/nginx:/etc/nginx:z

其次,修改common/templates/nginx/nginx.https.conf。将acc.gz.test.cn 替换为其他可在内网解析域名,例如 acc-test.gz.test.cn。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
location /v2/ {
proxy_pass http://ui/registryproxy/v2/;
proxy_set_header Host $$http_host;
proxy_set_header X-Real-IP $$remote_addr;
proxy_set_header X-Forwarded-For $$proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $$scheme;
proxy_buffering off;
proxy_request_buffering off;
header_filter_by_lua '
if 307 == ngx.status then
location = ngx.header.Location
ngx.header.Location = string.gsub(location,"acc.gz.test.cn","acc-test.gz.test.cn")
end
';
}

接下来,不要忘了修改https的证书位置。Harbor默认将nginx的证书挂载到/etc/nginx/cert/。但是没有提供修改的方式,可以执行完./install 或者 ./prepare 之后,人工修改证书挂载到openresty中的位置 。修改./common/config/nginx/nginx.conf 。

1
2
ssl_certificate /usr/local/openresty/nginx/conf/cert/gz.test.cn.crt;
ssl_certificate_key /usr/local/openresty/nginx/conf/cert/gz.test.cn.key;

最后,重启harbor 。此时不要再执行./install 或 ./prepare

1
2
docker-compose down
docker-compose up -d

代理

其中,需要注意设置正确的Host proxy_set_header Host acc.gz.test.cn;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
server {
listen 80;
server_name acc-test.gz.test.cn;
#charset koi8-r;
access_log /usr/local/nginx/log/acc-test.gz.test.cn.log main;
location / {
proxy_pass http://acc.gz.test.cn/;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Cookie $http_cookie;
proxy_set_header Host acc.gz.test.cn;
proxy_set_header X-Real-IP $remote_addr;
...
}
}