DockerRegistry设置Https

2018-06-12  本文已影响25人  土豆肉丝盖浇饭

起因

今天我们的Jenkins部署到Rancher的任务突然报错



然后百度了一圈,问题的可能性有如下两种


image.png
然后看了一下宿主机 和 docker容器内的时间
image.png

一个是CST,一个UTC
那么解决问题的重点在把docker内部镜像时间改为CST的
又是一顿百度


image.png
在把官方registry镜像封装成新的Dockerfile
From registry
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

然而还是改变不了这个时区

但是从我现在解决了这个问题之后来推断,Host和docker container内只相差了8个小时,主要还是由于证书过期引起

由于我们是通过域名push镜像到docker私库,并且从docker1.3.2版本开始默认docker registry使用的是https,所以也就是说nginx关于这个域名配置的https的证书过期了

在网上发现可以通过配置

ExecStart=/usr/bin/docker -d --insecure-registry 192.168.1.103:5000  -H fd:// $OPTIONS $DOCKER_STORAGE_OPTIONS  

可以跳过https认证,但是我不知道对域名是否有效

那么直接进入nginx的配置

server {
    listen       80;
    server_name  registry.51juban.cn;

    access_log  /app/logs/nginx/access_registry.51juban.cn_http.log  main;

    location / {
        rewrite ^(.*)$ https://$server_name$1 permanent;

}

}

server {
    listen       443;
    server_name  registry.51juban.cn;
    include      ssl/registry.51juban.cn.conf;

    access_log  /app/logs/nginx/access_registry.51juban.cn_https.log  main;
    client_max_body_size      0;
    chunked_transfer_encoding on;

#    auth_basic "Registry realm";
#    auth_basic_user_file htpasswd;

    location / {
        rewrite ^ /v2/_catalog redirect;
    }

    location /v2/ {
        add_header         'Docker-Distribution-Api-Version' 'registry/2.0';
        proxy_pass         http://127.0.0.1:5500;
        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;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_read_timeout 1800;
    }
}

这段nginx配置的意思是,http的请求会自动转成https的,https的配置在ssl/registry.51juban.cn.conf中

查看这个registry.51juban.cn.conf文件

    ssl on;
    ssl_certificate ssl/registry.51juban.cn.cer;
    ssl_certificate_key ssl/egistry.51juban.cn.key;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
    ssl_protocols TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_session_timeout 5m;
    ssl_session_cache shared:SSL:10m;

一开始我认为这个证书是openssh生成的
通过openssh的命令查看证书过期时间


image.png

刚好昨天过期了,那么问题的解决方案就出来了,重新生成https需要的证书

那么就通过openssh去生成证书,证书是生成了,但是浏览器不认,那么我想我这台Jenkins的服务器导入这个证书也行,毕竟我们也不通过浏览器访问

然后是不会玩openssl以及通过linux如何导入证书

一顿迷茫中,然后通过openssl的命令去查看这个证书的信息,发现了


image.png

然后百度了一下,发现了这个造福人类的免费https证书

Let's Encrypt获取免费证书

Let's Encrypt 是国外一个公共的免费SSL项目,由 Linux 基金会托管,它的来头不小,由 Mozilla、思科、Akamai、IdenTrust 和 EFF 等组织发起,目的就是向网站自动签发和管理免费证书,以便加速互联网由 HTTP 过渡到 HTTPS,目前 Facebook 等大公司开始加入赞助行列。

Let's Encrypt 已经得了 IdenTrust 的交叉签名,这意味着其证书现在已经可以被 Mozilla、Google、Microsoft 和 Apple 等主流的浏览器所信任,用户只需要在 Web 服务器证书链中配置交叉签名,浏览器客户端会自动处理好其它的一切,Let's Encrypt 安装简单,使用非常方便。

先下载Let's Encrypt的客户端

wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto

然后开始进行配置

./certbot-auto certonly -d 你的域名 --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory

有2个步骤需要注意下,邮箱邮件确认,以及配置特定dns解析进行验证

Please deploy a DNS TXT record under the name
_acme-challenge.www.shengchaojie.com with the following value:

Eal-gPmNRTmLAods1r0sfNRGQqgggGPUCYWMp3bnZ6Y

Before continuing, verify the record is deployed.

你需要在你域名的dns解析配置这个二级域名的TXT解析,配置完成后在continue
成功之后会在一个文件夹把对应的证书生成,有如下4个


image.png

然后在nginx SSL模块修改对应配置

ssl_certificate /etc/letsencrypt/live/registry.51juban.cn-0001/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/registry.51juban.cn-0001/privkey.pem;

fullchain.pem对应证书
privkey.pem对应私钥

具体原理就是浏览器会从证书的发行机构去获取公钥加密http报文,然后服务器用私钥解密,由证书结构给浏览器提供公钥,就避免了黑客中途修改证书的可能性

由于这个证书只有三个月的有效期,所以我们可以起一个定时任务去刷新,官方也提供了刷新证书的api
刷新证书命令如下

./path/to/certbot-auto renew

renew命令在证书不过期的情况下不会做任何操作,所以我们弄一个定时任务每天调用2次。
新建https_cron文件,内容如下

0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && ./certbot-auto renew

然后使用crontab https_cron启动定时任务即可

总结

运维的套路很多。。。
get免费https证书套路
官方文档很给力,学习劲量看官方文档吧,不过英语真的没耐心看

最后

希望大家关注下我的公众号


image
上一篇下一篇

猜你喜欢

热点阅读