docker镜像容器仓库

2016-04-27 22:39:03

1. docker镜像

1.1 列出镜像

	# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
registry 2 5ab64ea20db7 6 weeks ago 171.2 MB
nginx 1.9 44d8b6f34ba1 6 weeks ago 182.8 MB
tomcat latest 38111fcdfd7f 4 months ago 356.9 MB

其中tag指镜像标签,id为镜像唯一标示,本地镜像保持在/var/lib/docker目录下

1.2 拉取镜像

可以使用docker pull 镜像:tag命令从docker官方仓库拉取镜像,如果未指定标签,docker默认下载latest标签的镜像。docker仓库一般速度会很慢,可以自己搭建的私有仓库下文有描述,也可以通过docker run -it ubuntu /bin/bash命令启动容器,如该镜像本地不存在,docker会从docker Hub下载该镜像

1.3 查找镜像

# docker search tomcat
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
tomcat Apache Tomcat is an open source implementa... 741 [OK]
dordoka/tomcat Ubuntu 14.04, Oracle JDK 8 and Tomcat 8 ba... 19 [OK]
consol/tomcat-7.0 Tomcat 7.0.57, 8080, "admin/admin" 16 [OK]

Stars代表欢迎程度,official代表是否官方,Automated表示这个镜像是由Docker Hub自动创建流程所创建

1.4 构建镜像

  • docker commit方式

docker commit 49695d4fb903 registry/nginx:v2命令保存当前容器为镜像,49695d4fb903代表一个运行容器的id,registry/nginx:v2代表一个目标仓库、镜像名和标签。docker commit提交的只是容器的镜像与容器当前状态之间有差异的部分,可通过docker inspect命令查看镜像详情信息

  • Dockerfile创建镜像

新建一个目录和Dockerfile

$ mkdir static_web
$ cd static_web
$ touch Dockerfile

Dockerfile 中每一条指令都创建镜像的一层,例如:

# This is a comment
FROM ubuntu
MAINTAINER Docker Newbee <test@docker.com>
RUN apt-get -qq update
RUN apt-get -qqy install ruby ruby-dev

然后使用docker built -t="registry/static_web:v2"命令创建镜像,dockerfile方式会另起文章详细说明

1.5 删除镜像

使用docker rmi registry/static_web命令删除镜像,在删除镜像之前要先用docker rm 删掉依赖于这个镜像的所有容器

2. docker容器

2.1 容器启动

  • 镜像启动容器

docker run -d -p 80:80 --name static_web registry/static_web命令启动一个容器,docker run命令启动一个命名为static_web的容器,其中-d选项指后台运行,前台交互运行需用-it选项;-p 80:80指将容器内的80端口绑定到本地宿主机的80端口上

  • 启动已终止的容器

docker start命令可启动一个已经终止的容器启动运行
docker restart命令重启一个运行状态的容器

2.2 容器终止销毁

使用docker stop命令终止一个运行中的容器,终止状态的容器可通过docker ps -a命令查看。
使用docker rm命令删除一个终止状态的容器
使用docker rm $(docker ps -a -q)命令清理所有处于终止状态的容器

2.3 查看容器日志

使用docker logs命令来获取容器的日志,也可用-f参数实时监控docker的日志

2.4 进入容器

使用docker exec -it 4e6d92763e68 /bin/bash命令进入正在运行中容器
使用docker top命令查看容器内运行的进程

3. docker仓库

3.1 dokcer hub

docker hub是docker官方维护的公共仓库,可通过docker login命令登录,需输入用户名、密码和邮箱,登录后认证信息会保持在用户目录下的.docker/config.json文件中;通过docker search命令后跟镜像名查找官方镜像,官方镜像一般采用单词命名,用户镜像一般采用username/imagename命名;通过docker pull命令从官网下载镜像到本地,docker push命令上传镜像到Docker Hub;另外docker hub还支持自动创建,放在github上的代码一旦提交会自动触发创建镜像并上传docker hub

3.2 创建私有仓库

  • 获取官网最新镜像
$ sudo docker run -d -p 5000:5000 registry

仓库存储默认在容器里/tmp/registry目录下

  • 启动私有仓库配置本地存储
$ sudo docker run -d -p 5000:5000 -v /data/registry:/tmp/registry registry
  • 使用docker tag标记一个镜像,格式为 docker tag IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]
# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
dockerui/dockerui latest 95c8b9dc91e0 3 months ago 6.13 MB
registry latest 07d93e41c370 3 months ago 422.9 MB
# docker tag 95c8 127.0.0.1:5000/test
# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
127.0.0.1:5000/test latest 95c8b9dc91e0 3 months ago 6.13 MB
dockerui/dockerui latest 95c8b9dc91e0 3 months ago 6.13 MB
registry latest 07d93e41c370 3 months ago 422.9 MB
  • 上传镜像、查看镜像、下载镜像从私有仓库
#docker push 127.0.0.1:5000/test           push到私有仓库
Pushing repository 127.0.0.1:5000/test (1 tags)
706db4235055: Image successfully pushed
84f978a622ba: Image successfully pushed
95c8b9dc91e0: Image successfully pushed
Pushing tag for rev [95c8b9dc91e0] on {http://127.0.0.1:5000/v1/repositories/test/tags/latest}
# curl http://127.0.0.1:5000/v1/search 用 curl 查看仓库中的镜像
{"num_results": 2, "query": "", "results": [{"description": "", "name": "library/test"}, {"description": "", "name": "library/test1"}]}
# docker pull 127.0.0.1:5000/test 从私有仓库pull到本地
Pulling repository 127.0.0.1:5000/test
95c8b9dc91e0: Download complete
95c8b9dc91e0: Pulling image (latest) from 127.0.0.1:5000/test
706db4235055: Download complete
Status: Image is up to date for 127.0.0.1:5000/test:latest
  • 用本机ip或域名上传镜像失败
# docker push 192.168.1.7:5000/test
Error response from daemon: invalid registry endpoint https://192.168.1.7:5000/v0/: unable to ping registry endpoint https://192.168.1.7:5000/v0/
v2 ping attempt failed with error: Get https://192.168.1.7:5000/v2/: EOF
v1 ping attempt failed with error: Get https://192.168.1.7:5000/v1/_ping: EOF. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry 192.168.1.7: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/192.168.1.7:5000/ca.crt

解决方案:

  1. #service docker stop
    docker -d --insecure-registry 192.168.1.7:5000
  2. 设置docker配置文件/etc/sysconfig/docker
    other_args="--insecure-registry=registry.com:5000"

3.3 私有仓库支持https

  • install the apache2-utils package

htpasswd utility that can easily generate password hashes Nginx can understand

#yum install httpd-tools
  • 安装Docker Compose,安装详细信息查看官网
    注意docker-compose版本和docker版本对应关系,别下错版本
#curl -L https://github.com/docker/compose/releases/download/1.5.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
#chmod +x /usr/local/bin/docker-compose
#docker-compose --version
docker-compose version: 1.5.2

如果curl命令下载速度很慢,可去官网直接找相应的版本下载

  • 配置nginx容器
#mkdir ~/docker-registry && cd $_
#mkdir data
#mkdir nginx
#vim docker-compose.yml

nginx:
image: "nginx:1.9" #从官网拉去nginx镜像
ports:
- 5043:443 #映射端口
links:
- registry:registry #连接registry容器,通过hostname
volumes:
- ./nginx/:/etc/nginx/conf.d #数据卷挂载当前nginx目录下
registry:
image: registry:2
ports:
- 127.0.0.1:5000:5000
environment:
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data #设置仓库存储目录
volumes:
- ./data:/data #将容器中的镜像存放目录挂载在宿主机当前data目录下

此时运行docker-compose up命令,将启动两个容器,一个docker仓库,另一个是ningx容器
然后设置nginx的配置文件 ~/docker-registry/nginx/registry.conf

upstream docker-registry {
server registry:5000;
}

server {
listen 443;
server_name registry.com;

# SSL
# ssl on;
# ssl_certificate /etc/nginx/conf.d/domain.crt;
# ssl_certificate_key /etc/nginx/conf.d/domain.key;

# disable any limits to avoid HTTP 413 for large image uploads
client_max_body_size 0;

# required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
chunked_transfer_encoding on;

location /v2/ {
# Do not allow connections from docker 1.5 and earlier
# docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
return 404;
}

# To add basic authentication to v2 use auth_basic setting plus add_header
# auth_basic "registry.localhost";
# auth_basic_user_file /etc/nginx/conf.d/registry.password;
# add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;

proxy_pass http://docker-registry;
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 X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 900;
}
}

再次运行docker-compose up命令,然后通过如下命令测试通过nginx访问仓库和不通过nginx访问仓库结果是否一致

curl http://registry.com:5000/v2/

Output
{}

curl http://registry.com:5043/v2/     #nginx代理
#通过代理方式,两个容器一致ping不通,后经查是宿主机防火墙规则导致,清空规则
#iptables -F
#iptables -t nat -F

Output
{}

  • 设置nginx访问认证
$ cd ~/docker-registry/nginx
$ htpasswd -c registry.password USERNAME #创建一个认证文件增加用户设置密码
$ vim ~/docker-registry/nginx/registry.conf #修改nginx配置文件,把下面三行注释去掉
# To add basic authentication to v2 use auth_basic setting plus add_header
auth_basic "registry.localhost";
auth_basic_user_file /etc/nginx/conf.d/registry.password;
add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;
$ cd ~/docker-registry
$ docker-compose up

通过如下命令访问nginx,返回401

curl -sv0 http://registry.com:5043/v2/

< HTTP/1.1 401 Unauthorized
< Server: nginx/1.9.15
< Date: Mon, 16 May 2016 13:56:07 GMT
< Content-Type: text/html
< Content-Length: 195
< Connection: close
< WWW-Authenticate: Basic realm=”registry.localhost”
< Docker-Distribution-Api-Version: registry/2.0
正常方法方式如下,加上用户名和密码:

curl http://USERNAME:PASSWORD@localhost:5043/v2/
  • 设置nginx ssl
# SSL     设置下面三行nginx配置,把注释去掉,并把domain设置成自己的server_name
ssl on;
ssl_certificate /etc/nginx/conf.d/domain.crt;
ssl_certificate_key /etc/nginx/conf.d/domain.key;

然后需要生成nginx私钥和证书,请看另一篇博文nginx配置SSL
在宿主机或其他需要连接docker私有仓库的客户机都需要配置证书,执行如下步骤:

mkdir -p /usr/local/share/ca-certificates/docker-dev-cert
cp devdockerCA.crt /usr/local/share/ca-certificates/docker-dev-cert

重启docker测试sslservice docker restart
通过curl https://USERNAME:PASSWORD@[YOUR-DOMAIN]:5043/v2/命令访问报错
curl: (60) Peer certificate cannot be authenticated with known CA certificates
正确的访问方式是curl加入-k选项不校验,例
curl -k https://USERNAME:PASSWORD@[YOUR-DOMAIN]:5043/v2/

用443端口代替5043端口,访问nginx默认不需要输入端口信息,例
curl -k https://USERNAME:PASSWORD@[YOUR-DOMAIN]/v2/

在centos6中需把证书放到/etc/docker/certs.d/registry.com目录才能登陆成功,如下

mkdir -p /etc/docker/certs.d/registry.com
cp /docker-registry/nginx/devdockerCA.crt /etc/docker/certs.d/registry.com
service docker restart
docker-compose up
docker login https://registry.com #输入之前创建的用户名密码和邮箱,登录后显示login sucessded
  • 私有仓库上传下载

通过上一步登录成功后,镜像打标签,需在前面加上域名方便定位,命令如下:
docker tag test-image [YOUR-DOMAIN]/test-image
现在就可以上传该镜像到私有仓库了,命令如下:
docker push [YOUR-DOMAIN]/test-image
然后就可在另一个机器从私有仓库下载镜像,命令如下:
docker pull [YOUR-DOMAIN]/test-image

参考于
How To Set Up a Private Docker Registry on Ubuntu 14.04