docker学习笔记(六):自定义镜像

168人浏览 / 0人评论

docker自定义镜像有两种方式:

  • 通过导出容器然后生成镜像
  • 使用Dockerfile文件制作镜像

导入容器

这种方法在我看来是最直观的方法,主要的命令如下:

# 导出容器
docker export c1 > c1.tar

# 生成镜像
cat c1.tar | docker import - c1:v1

这种方式操作简单,只需要创建C1容器,然后在该容器中进行相关操作,比如组件安装、环境搭建等。

操作完后,导出容器再生成镜像即可。

但是这种方式生成的镜像没有默认的执行程序,所以在创建新的容器的时候需要指定执行程序。

另外,这种方式生成的镜像从表象上看占用的空间比较少,从更深层次的角度看,生成的镜像层数只有一层,在对应的容器执行效率上会优于使用Dockerfile制作的镜像(当然,也是有办法优化的)。

案例

制作一个已安装net-tools的centos镜像:

# 创建容器并打开终端
[root@localhost ~]# docker run -it --rm  docker.io/centos /bin/bash
[root@7e652487e57f /]# 

# 在容器中安装net-tools
[root@7e652487e57f /]# yum install net-tools
Loaded plugins: fastestmirror, ovl
......
Installed:
  net-tools.x86_64 0:2.0-0.24.20131004git.el7
Complete!

另外打开一个终端:

# 导出容器
[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
7e652487e57f        docker.io/centos    "/bin/bash"         2 minutes ago       Up 2 minutes                            festive_goodall
# 如果容器有名字,可以使用名字进行导出操作
[root@localhost ~]# docker export 7e652487e57f > centos.tar
[root@localhost ~]# ls
anaconda-ks.cfg  centos.tar

# 创建容器,并测试
[root@localhost ~]# cat centos.tar | docker import - centos:v1
sha256:515cf5dc07190096d1441a28684f4e7404be887be1802c32bffd3799c6ac8b72
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              v1                  515cf5dc0719        6 seconds ago       291 MB
docker.io/centos    latest              67fa590cfc1c        12 days ago         202 MB
docker.io/ubuntu    latest              a2a15febcdf3        2 weeks ago         64.2 MB
docker.io/mysql     latest              62a9f311b99c        2 weeks ago         445 MB
[root@localhost ~]# docker run -it --rm centos:v1 /bin/bash
[root@417d0b19ee91 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.3  netmask 255.255.0.0  broadcast 0.0.0.0
        inet6 fe80::42:acff:fe11:3  prefixlen 64  scopeid 0x20<link>
        ether 02:42:ac:11:00:03  txqueuelen 0  (Ethernet)
        RX packets 6  bytes 516 (516.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6  bytes 516 (516.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

使用Dockerfile

这种方法是docker比较推荐的制作方式,因为这种方式制作镜像比较容器与其他的开发IDE结合在一起。

主要命令是:

docker build -t ccc:v1 .

这种方式中最重要的是如何编写Dockerfile。

Dockerfile的相关指令

FROM

用于说明当前镜像的基镜像,语法如下:

FROM centos:v1

MAINTAINER

用于说明当前镜像的作者,语法如下:

MAINTAINER iuuxx.com

RUN

制作镜像中需要执行的指令,比如需要安装ip指令:

RUN yum install ipu*

ADD

该指令是将本地文件文件拷贝到镜像中,如果该文件是压缩文件,将自动被解压,例如:

ADD test.tar /data/

COPY

这个命令也是将本地文件拷贝到镜像中,但与ADD不同的是这个命令拷贝操作不会自动解压压缩文件,使用方法如下:

COPY test.html /usr/share/nginx/html

CMD

支持三种格式:

# 使用exec执行,这是推荐的方式。
CMD ["executable","param1","param2"]
# 在/bin/sh中执行。
CMD command param1 param2 
# 提供给ENTERYPOINT的默认参数。
CMD ["param1","param2"] 

CMD用于指定容器启动时执行的命令,每个Dockerfile只能有一个CMD命令,多个CMD命令只执行最后一个。若容器启动时指定了运行的命令,则会覆盖掉CMD中指定的命令。

USER

指定容器运行时的用户名或UID,后续的RUN也会使用指定的用户。要临时使用管理员权限可以使用sudo。在USER命令之前可以使用RUN命令创建需要的户。

格式:

USER username

EXPOSE

这条指令告诉Docker服务器暴露一个或多个端口,供容器外部连接使用。具体指令如下:

EXPOSE port [port2,port3,...]

ENV

用于指定环境变量,这些环境变量,后续可以被RUN指令使用,容器运行起来之后,也可以在容器中获取这些环境变量。 例如

ENV word hello
RUN echo $word

VOLUME

作用是创建在本地主机或其他容器可以挂载的数据卷,用来存放数据。 格式如下:

VOLUME ["/data"]

更多

Dockerfile reference

Dockerfile指令详解

案例

使用Dockerfile的方式创建centos相同功能的镜像,并指定执行/bin/bash命令。

Dockerfile如下:

FROM docker.io/centos
MAINTAINER iuuxx.com
RUN yum install net-tools -y
CMD ["/bin/bash"]

制作镜像:

[root@localhost ~]# docker build -t centos:v2 .
Sending build context to Docker daemon 299.5 MB
Step 1/4 : FROM docker.io/centos
 ---> 67fa590cfc1c
Step 2/4 : MAINTAINER iuuxx.com
 ---> Using cache
 ---> aec725d0c584
Step 3/4 : RUN yum install net-tools -y
 ---> Running in 0bbba61c6655

Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
 * base: mirrors.cn99.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
Resolving Dependencies
......
Installed:
  net-tools.x86_64 0:2.0-0.24.20131004git.el7
Complete!
 ---> 10e5729569c1
Removing intermediate container 0bbba61c6655
Step 4/4 : CMD /bin/bash
 ---> Running in bc4458c5b16d
 ---> 853a8a82ae5d
Removing intermediate container bc4458c5b16d
Successfully built 853a8a82ae5d

验证并测试:

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              v2                  853a8a82ae5d        51 seconds ago      314 MB
centos              v1                  515cf5dc0719        44 minutes ago      291 MB
docker.io/centos    latest              67fa590cfc1c        12 days ago         202 MB
docker.io/ubuntu    latest              a2a15febcdf3        2 weeks ago         64.2 MB
docker.io/mysql     latest              62a9f311b99c        2 weeks ago         445 MB
[root@localhost ~]# docker run -it --rm  centos:v2
[root@d50f101c23b1 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 0.0.0.0
        inet6 fe80::42:acff:fe11:2  prefixlen 64  scopeid 0x20<link>
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 6  bytes 516 (516.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6  bytes 516 (516.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

其他操作

在学习本章的过程中,还遇到了一些与docker无关的内容。

安装epel

在centos中安装nginx,默认是找不到相关的包。

[root@localhost ~]# yum install nginx
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.aliyun.com
* extras: mirror.bit.edu.cn
* updates: mirror.bit.edu.cn
No package nginx available.
Error: Nothing to do

需要安装epel的源才行,安装指令如下:

[root@localhost ~]# yum install epel*
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.aliyun.com
* extras: mirrors.163.com
* updates: mirrors.cn99.com
Resolving Dependencies
--> Running transaction check
---> Package epel-release.noarch 0:7-11 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=================================================================================================================
Package                        Arch                     Version                  Repository                Size
=================================================================================================================
Installing:
epel-release                   noarch                   7-11                     extras                    15 k

Transaction Summary
=================================================================================================================
Install  1 Package

Total download size: 15 k
Installed size: 24 k
Is this ok [y/d/N]: y
Downloading packages:
epel-release-7-11.noarch.rpm                                                              |  15 kB  00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
 Installing : epel-release-7-11.noarch                                                                      1/1
 Verifying  : epel-release-7-11.noarch                                                                      1/1

Installed:
 epel-release.noarch 0:7-11

Complete!

取消epel的key验证

如果想要直接复制epel的源文件到其他地方使用,epel默认需要验证key相关问题件,直接拷贝会导致文件验证不通过。

可以通过修改默认设置,取消key验证:

[root@localhost ~]# cd /etc/yum.repos.d/
[root@localhost yum.repos.d]# ls
CentOS-Base.repo  CentOS-Debuginfo.repo  CentOS-Media.repo    CentOS-Vault.repo  epel-testing.repo
CentOS-CR.repo    CentOS-fasttrack.repo  CentOS-Sources.repo  epel.repo

# 将所有的gpgcheck=1修改为gpgcheck=0
[root@localhost yum.repos.d]# vi epel.repo
[epel]
name=Extra Packages for Enterprise Linux 7 - $basearch
#baseurl=http://download.fedoraproject.org/pub/epel/7/$basearch
metalink=https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch
failovermethod=priority
enabled=1
# gpgcheck=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7

[epel-debuginfo]
name=Extra Packages for Enterprise Linux 7 - $basearch - Debug
#baseurl=http://download.fedoraproject.org/pub/epel/7/$basearch/debug
metalink=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-7&arch=$basearch
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
# gpgcheck=1
gpgcheck=0

[epel-source]
name=Extra Packages for Enterprise Linux 7 - $basearch - Source
#baseurl=http://download.fedoraproject.org/pub/epel/7/SRPMS
metalink=https://mirrors.fedoraproject.org/metalink?repo=epel-source-7&arch=$basearch
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
# gpgcheck=1
gpgcheck=0

全部评论