Docker系列(二):镜像管理

简介

Docker的容器是基于镜像的,所有容器是通过制作好的镜像启动的,下面会介绍镜像的管理和容器的管理。

镜像管理

Docker的镜像可以通过多种途径获取,获取镜像后将镜像存入本地镜像库中,以供容器使用。

1. 获取镜像

镜像可以从公共镜像库中获取(类似yum源),也可以自己制作,或导入已有镜像(从别的Docker导出的或OpenVZ一类虚拟化软件中导出的)。

  • 从公共镜像库中获取镜像

使用docker pull <image_name>[:tag]命令从公共镜像库中获取镜像:

$ docker pull centos
Using default tag: latest
latest: Pulling from library/centos
d9aaf4d82f24: Pull complete 
Digest: sha256:4565fe2dd7f4770e825d4bd9c761a81b26e49cc9e3c9631c58cfc3188be9505a
Status: Downloaded newer image for centos:latest

不指定tag的会自动选择使用latest标签。

公共镜像库支持查询功能,可以先使用docker search <image_name>查询需要的镜像是否存在:

$ docker search centos
NAME                               DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
centos                             The official build of CentOS.                   3789      [OK]       
ansible/centos7-ansible            Ansible on Centos7                              103                  [OK]
jdeathe/centos-ssh                 CentOS-6 6.9 x86_64 / CentOS-7 7.4.1708 x8...   89                   [OK]
tutum/centos                       Simple CentOS docker image with SSH access      33                   
imagine10255/centos6-lnmp-php56    centos6-lnmp-php56                              31                   [OK]
gluster/gluster-centos             Official GlusterFS Image [ CentOS-7 +  Glu...   21                   [OK]
kinogmt/centos-ssh                 CentOS with SSH                                 17                   [OK]
......
  • 导入镜像

使用docker load < <image_file_name>导入从其他Docker导出的镜像:

$ docker load < centos-sshd
36018b5e9787: Loading layer [==================================================>]  200.1MB/200.1MB
56ab33f0cb6c: Loading layer [==================================================>]  61.48MB/61.48MB
52d118e898dd: Loading layer [==================================================>]  21.99MB/21.99MB
52e44758f62d: Loading layer [==================================================>]  1.678MB/1.678MB
6f88bf69d4eb: Loading layer [==================================================>]  1.707MB/1.707MB
5afae9f25cde: Loading layer [==================================================>]  1.787MB/1.787MB
Loaded image ID: sha256:b8c73db541e787c15f8acdb892cebc41a00e8a1b257b02aa9b0be921f58d6426    

使用cat <openvz_image_file_name> | docker import - <image_name>:<tag>导入从虚拟化软件(OpenVZ)导出的镜像:

$ cat centos-6-x86_64.tar.gz | docker import - centos:6
sha256:54152fdb34278505a2007911a211ccd6d1d78dd946522bf797f2cf971efb89cf

(OpenVZ镜像下载地址)

2. 本地镜像

启动容器的镜像都是在本地镜像库中,对本地镜像库可以进行管理(删除,标签管理等)。

  • 本地镜像列表

管理本地镜像需要了解本地已存在的镜像:

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              6                   54152fdb3427        17 minutes ago      825MB
centos              latest              d123f4e55e12        3 days ago          197MB
centos-sshd         latest              b8c73db541e7        6 months ago        280MB

本地镜像中会列出镜像名称,id及tag(版本)。

  • 删除本地镜像

如果本地镜像过多,有些过时的镜像,或者不再使用的镜像,需要被删除时,可以使用以下命令:

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos-sshd         latest              b8c73db541e7        6 months ago        280MB

#docker rmi <image_name>:<tag> 
$ docker rmi centos-sshd:latest
Untagged: centos-sshd:latest
Deleted: sha256:b8c73db541e787c15f8acdb892cebc41a00e8a1b257b02aa9b0be921f58d6426
Deleted: sha256:5fdcd47722d29774d897562430801f6d1c168a422bcce5de1a6ace65302f900d
Deleted: sha256:4e8a967d0d44bbd801c7787c2f750036988f92f28aeb76feb83293421de32a5d
Deleted: sha256:50691d2b55b131e1ee4ccee1981556c631f55bb9f57269ceb00cf71c0b0e13bd
Deleted: sha256:a84fc4ac805b0593c8e7a61a4d774f261cc4a4de6db1ff812c02b8524127d91b
Deleted: sha256:0f8d19a2914ef598af3cc2dc8861b78b4b0d3b848d4eae97f2c81ba8e9f55015
Deleted: sha256:36018b5e978717a047892794aebab513ba6856dbe1bdfeb478ca1219df2c7e9c

#检查镜像是否已被删除(唯一的一个本地镜像已被删除)
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

如果一个镜像有多个tag的话,只会删除此tag:

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos-sshd         7.2                 b8c73db541e7        6 months ago        280MB
centos-sshd         latest              b8c73db541e7        6 months ago        280MB

$ docker rmi centos-sshd:latest
Untagged: centos-sshd:latest #提示只是删除了镜像的一个tag

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos-sshd         7.2                 b8c73db541e7        6 months ago        280MB     

使用镜像ID删除镜像(无论有多少个tag,都会先删除tag,然后彻底删除镜像):

#dokcer rmi <image_id>
$ docker rmi d123f4e55e12
Untagged: centos-sshd:7.2
Deleted: sha256:b8c73db541e787c15f8acdb892cebc41a00e8a1b257b02aa9b0be921f58d6426
Deleted: sha256:5fdcd47722d29774d897562430801f6d1c168a422bcce5de1a6ace65302f900d
Deleted: sha256:4e8a967d0d44bbd801c7787c2f750036988f92f28aeb76feb83293421de32a5d
Deleted: sha256:50691d2b55b131e1ee4ccee1981556c631f55bb9f57269ceb00cf71c0b0e13bd
Deleted: sha256:a84fc4ac805b0593c8e7a61a4d774f261cc4a4de6db1ff812c02b8524127d91b
Deleted: sha256:0f8d19a2914ef598af3cc2dc8861b78b4b0d3b848d4eae97f2c81ba8e9f55015
Deleted: sha256:36018b5e978717a047892794aebab513ba6856dbe1bdfeb478ca1219df2c7e9c

*注: 如果此镜像被其他镜像依赖,无法删除(后面会介绍依赖关系)。

  • 导出镜像

有时可能需要从一个Docker中导出镜像到另一个Docker中,导出本地镜像的方法如下:

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos-sshd         latest              b8c73db541e7        6 months ago        280MB

#docker save <image_id> > <export_image_name>
$docker save b8c73db541e7 > centos-sshd
$ls
centso-sshd

3. 镜像制作

有时标准镜像的内容无法满足我们的需求,这时就需要自己制作镜像,这里介绍的制作镜像的方法是基于已有镜像,或将一个启动的容器提交为一个镜像。

  • 基于已有镜像制作镜像

使用Dockerfile基于已有镜像制作新的镜像,一个简单的Dockerfile:

# Use an official Python runtime as a parent image
FROM python:2.7-slim

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
ADD . /app

# Install any needed packages specified in requirements.txt
RUN pip install -r requirements.txt

# Make port 80 available to the world outside this container
EXPOSE 80

# Define environment variable
ENV NAME World

# Run app.py when the container launches
CMD ["python", "app.py"]

上面Dockerfile中制作了一个python应用的镜像(Dockerfile中可以同时定义容器的启动的参数,后面会详细介绍),需要requirements.txt(运行这个python应用需要的模块)和app.py(python应用),这两个文件需要和Dockerfile在同一个目录中(ADD . /app定义的):

$ ls
Dockerfile        app.py            requirements.txt

最后使用以下命令制作镜像:

docker build -t firstapp .

在本地镜像库可以看到刚刚生成的镜像:

$ docker images

REPOSITORY            TAG                 IMAGE ID
firstapp         latest              326387cea398
  • 基于容器制作镜像

想对已有镜像做简单修改,或者不习惯于写Dockerfile,可以使用镜像启动一个容器,然后在容器中对系统进行修改,修改后将内容重新提交为一个新的镜像:

$ docker commit <container_id> <image_name>:[<tag>]

4. 镜像推送

将本地镜像(自己制作的镜像),推送到镜像库(多用于私有镜像库,如是公共项目提交到公共镜像库)。

  • 推送到公共镜像库

将自己制作的镜像,推送到公共镜像库,需要有对应镜像库的权限(登录认证),才可以推送到对应的镜像库中。

登录到公共镜像库:

$ docker login
Login with your
Docker ID to push and pull images from Docker Hub. If you don't have a Docker
ID, head over to https://hub.docker.com to
create one.
Username: test #Your login name
Password:
Login Succeeded

*可以到Docker公共镜像库创建账号,建立自己的镜像库(类似于github)。

推送镜像:

$ docker push <login_name>/<image_name>:<tag>

$ docker push test/firstapp:last
The push refers to a
repository [docker.io/test/firstapp]
34e7b85d83e4: Pushed 
last: 
digest:sha256:dafc45b8b533d5ad5564a3821e9e1a252b58f44e69c6052bddcd00139782ee08     
size:529
  • 推送到私有镜像库

有时自己的镜像不想被别人看到,这时可以搭建自己的私有镜像库(后续会介绍),然后将自己的镜像提交到私有的镜像库。

私有镜像库可以不需要登录(如果需要登录,登录过程和提交到公有镜像库一样),先给需要提交的镜像设置一个tagtag中将私有镜像库的地址写入即可(IP,hostname或域名):

$ docker <image_id> <private_registry_address>/<image_name>:<tag>

$ docker tag 34e7b85d83e4 10.236.100.3:5000/firstapp:last
$ docker push 10.236.100.3:5000/firstapp:last
repository [10.236.100.3:5000/firstapp]
acce4ec5f074: Pushed
5d450a8c7e38: Pushed
e8fd5087fa08: Pushed
cf394a2f01e4: Pushed
f16d5ac23cee: Pushed
57861a68f43a: Pushed
97ca462ad9ee: Pushed
last: 
digest:sha256:b0851324bac55083172ed2068dfb388acabdce14dffdb9787f4e6c044b524f19     
size:1764