部署和配置 registry
我们已经有自己的服务器了,下面我们来装几个必要软件吧。
# 安装软件之前,我们先更新一下软件源列表,然后重启
ubuntu@docker-internal:~$ sudo apt-get update
ubuntu@docker-internal:~$ sudo apt-get upgrade
ubuntu@docker-internal:~$ sudo reboot now
#登陆到docker registry
$ ssh ubuntu@docker-internal.example.com
# 切换到root用户
ubuntu@docker-internal:~$ sudo su
# 安装nginx-extras包,我们要用其中的chunkin模块
root@docker-internal:~# apt-get install git nginx-extras
# 安装apache2-utils包,这样我们就可以用htpasswd命令来设置密码
root@docker-internal:~# apt-get install apache2-utils
# 安装一些必要的依赖
root@docker-internal:~# apt-get install build-essential libevent-dev libssl-dev liblzma-dev python-dev python-pip
# 安装redis来实现我们的LRU缓存策略
root@docker-internal:~# apt-get install redis-server
root@docker-internal:~# apt-get clean
必要的软件都装好了,下面我们就来安装 docker registry:
root@docker-internal:~# git clone https://github.com/dotcloud/docker-registry.git /opt/docker-registry
root@docker-internal:~# cd /opt/docker-registry
# 切换到最新的 registry 版本
root@docker-internal:~# git checkout 0.6.3
# 创建日志路径
root@docker-internal:~# mkdir -p /var/log/docker-registry
# 安装 pip 包
root@docker-internal:~# pip install -r requirements.txt
root@docker-internal:~# cp config/config_sample.yml
如果一切顺利,我们现在应该可以用下面的命令来测试一下 docker registry 了:
root@docker-internal:~# ./wsgi.py
2014-01-13 23:38:38,470 INFO: * Running on http://0.0.0.0:5000/
2014-01-13 23:38:38,470 INFO: * Restarting with reloader
如果你看到的结果和上面一样,那么,恭喜你,成功了!接下来我们需要设置一些选项,记得我们之前分配给 docker registry 的分区吗?现在我们就来挂在这个分区:
root@docker-internal:~# mkdir -p /data/registry
root@docker-internal:~# mkfs.ext4 /dev/vdb
root@docker-internal:~# mount /dev/vdb /data/registry
现在,我们来编辑 docker registry 的配置文件,我们用 http://uuidgenerator.net 在线生成密钥:
root@docker-internal:~# cat << EOF > /opt/docker-registry/config/config.yml
# The 'common' part is automatically included (and possibly overriden by
# all other flavors)
common:
# Set a random string here
secret_key: REPLACEME
standalone: true
# This is the default configuration when no flavor is specified
dev:
storage: local
storage_path: /tmp/registry
loglevel: debug
# To specify another flavor, set the environment variable SETTINGS_FLAVOR
# $ export SETTINGS_FLAVOR=prod
prod:
storage: local
storage_path: /data/registry
loglevel: info
# Enabling LRU cache for small files. This speeds up read/write on
# small files when using a remote storage backend (like S3).
cache:
host: localhost
port: 6379
cache_lru:
host: localhost
port: 6379
EOF
然后为 docker registry 设置一个 upstart 作业:
root@docker-internal:~# cat << EOF > /etc/init/docker-registry.conf
description "Docker Registry"
version "0.6.3"
author "Docker, Inc."
start on runlevel [2345]
stop on runlevel [016]
respawn
respawn limit 10 5
# set environment variables
env REGISTRY_HOME=/opt/docker-registry
env SETTINGS_FLAVOR=prod
script
cd $REGISTRY_HOME
exec gunicorn -k gevent --max-requests 100 --graceful-timeout 3600 -t 3600 -b 0.0.0.0:5000 -w 8 --access-logfile /var/log/docker-registry/access.log --error-logfile /var/log/docker-registry/server.log wsgi:application
end script
EOF
用下面的命令启动 registry 的作业:
root@docker-internal:~# start docker-registry
docker-registry start/running, process 10872
用下面的命令检查 registry 的作业是否运行:
root@docker-internal:~# cat /var/log/docker-registry/server.log
2014-01-14 00:33:44 [15051] [INFO] Starting gunicorn 18.0
2014-01-14 00:33:44 [15051] [INFO] Listening at: http://0.0.0.0:5000 (15051)
2014-01-14 00:33:44 [15051] [INFO] Using worker: gevent
2014-01-14 00:33:44 [15056] [INFO] Booting worker with pid: 15056
2014-01-14 00:33:44 [15057] [INFO] Booting worker with pid: 15057
2014-01-14 00:33:44 [15062] [INFO] Booting worker with pid: 15062
2014-01-14 00:33:45 [15067] [INFO] Booting worker with pid: 15067
2014-01-14 00:33:45 [15068] [INFO] Booting worker with pid: 15068
2014-01-14 00:33:45 [15069] [INFO] Booting worker with pid: 15069
2014-01-14 00:33:45 [15070] [INFO] Booting worker with pid: 15070
2014-01-14 00:33:45 [15071] [INFO] Booting worker with pid: 15071
接下来,我们设置 nginx:
root@docker-internal:~# rm /etc/nginx/sites-enabled/default
root@docker-internal:~# cat << EOF > /etc/nginx/sites-enabled/docker-registry
nginx的配置:
upstream docker-registry {
server localhost:5000;
}
server {
listen 443;
server_name docker-internal.example.com;
ssl on;
ssl_certificate /etc/ssl/certs/docker-registry.crt;
ssl_certificate_key /etc/ssl/private/docker-registry.key;
proxy_set_header Host $http_host; # required for docker client's sake
proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP
proxy_set_header Authorization ""; # see https://github.com/dotcloud/docker-registry/issues/170
client_max_body_size 0; # disable any limits to avoid HTTP 413 for large image uploads
# required to avoid HTTP 411: see Issue #1486 (https://github.com/dotcloud/docker/issues/1486)
chunkin on;
error_page 411 = @my_411_error;
location @my_411_error {
chunkin_resume;
}
location / {
auth_basic "Restricted";
auth_basic_user_file docker-registry.htpasswd;
proxy_pass http://docker-registry;
proxy_set_header Host $host;
proxy_read_timeout 900;
}
location /_ping {
auth_basic off;
proxy_pass http://docker-registry;
}
location /v1/_ping {
auth_basic off;
proxy_pass http://docker-registry;
}
}
EOF
root@docker-internal:~# service nginx restart
别忘了在 htpasswd 文件里设置账号密码:
root@docker-internal:~# htpasswd -bc /etc/nginx/docker-registry.htpasswd USERNAME PASSWORD
我们还要在服务器上安装一个 SSL 密钥。本例中,假设我们已经有认证机构颁发的 SSL证 书了,SSL 授权给'docker-internal.example.com'或者'*.example.com',用下面的命令来安装 SSL 密钥:
root@docker-internal:~# mv server.key /etc/ssl/private/docker-registry.key
root@docker-internal:~# mv server.crt /etc/ssl/certs/docker-registry.crt
如果你不打算花钱去搞一个认证机构授权的SSL密钥,或者你只是练习着部署 docker registry,那么你也可以按照 Akadia的教程 装一个自己授权的 SSL key,如下:
root@docker-internal:~# openssl genrsa -des3 -out server.key 1024
root@docker-internal:~# openssl req -new -key server.key -out server.csr
root@docker-internal:~# cp server.key server.key.org
root@docker-internal:~# openssl rsa -in server.key.org -out server.key
root@docker-internal:~# openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt
请注意,现在官方的 docker 还不能用自授权的证书,要等到 #2687
的 pull request 合并到官方 master 分支后才能使用。或者,你也可以试着修改 docker 的源代码来让它支持自授权证书。
测试
最后,我们来测试一下自己的 docker registry:
root@docker-internal:~# exit
ubuntu@docker-internal:~$ exit
$ curl -u bacongobbler:******* https://docker-internal.example.com
"docker-registry server (prod)"
$ docker login https://docker-internal.example.com
Login against server at https://docker-internal.example.com/v1/
Username (): bacongobbler
Login Succeeded
$ docker pull busybox
Pulling repository busybox
e9aa60c60128: Download complete
$ docker tag busybox docker-internal.example.com/busybox
$ docker push docker-internal.example.com/busybox
The push refers to a repository [docker-internal.example.com/busybox] (len: 1)
Sending image list
Pushing repository docker-internal.example.com/busybox (1 tags)
Pushing tags for rev [e9aa60c60128] on {https://docker-internal.example.com/v1/repositories/busybox/tags/latest}
e9aa60c60128: Image already pushed, skipping
完成!现在我们在 Openstack 上部署了一个 docker registry,随时可用!
下一步
部署好 docker registry 后,我们还可以进一步让它跑的更好,比如:
- 当docker registry崩溃的时候,发出邮件通知
- 用 logstash 或其他日志软件来管理日志
- 把docker registry部署到CentOS或者RHEL
- 做一些测试,看看docker registry的性能如何
这只是我想到的一些,如果你有什么好点子,请在下面留言!
在 ActiveState,我们在 Stackato v3 项目中大量的使用了 Docker。Phil 在博客中全面的介绍了 Stackat v3,如果你还没来得及看,一定要去拜读他的 大作 ,特别是其中 Stackato在哪些地方适合用Docker 这一节。
图片来自:Glyn Lowe Photoworks