(一)使用docker commit命令。
(二)使用docker build命令和 Dockerfile 文件。
在这里并不推荐使用docker commit来构建镜像,而应该使用更灵活、更强大的Dockerfile来构建Docker镜像。但是为了对Docker有一个更全面的了解,还是会先介绍以下如何使用docker commit构建Docker镜像。之后将重点介绍Docker所推荐的镜像构建方法:编写Dockerfile之后使用docker build命令。
一般来说,我们不是真正的“创建”新镜像,而是基于一个已有的基础镜像,如ubuntu或centos等,构建新镜像而已。如果真的想从零构建一个全新的镜像,也可以参考https://docs.docker.com/engine/userguide/eng-image/baseimages/
1.通过commit命令创建镜像
docker commit 构建镜像可以想象为是在往版本控制系统里提交变更。我们先创建一个容器,并在容器里做出修改,就像修改代码一样,最后再将修改提交为一个镜像。
# docker run -it centos:latest /bin/bash [root@248a52042af3 /]# yum -y update [root@248a52042af3 /]# yum -y install httpd
我们启动了一个容器,并在里面安装了Apache。我们会将这个容器作为一个Web服务器来运行,所以我们想把它的当前状态保存下来。这样我们就不必每次都创建一个新容器并再次在里面安装Apache了。为了完成此项工作,需要先使用exit命令从容器里退出,之后再运行docker commit命令:
[root@248a52042af3 /]# exit exit [root@node-01 /]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 248a52042af3 centos "/bin/bash" 7 minutes ago Exited (0) 6 seconds ago reverent_khayyam ebf6c7f46823 centos:latest "/bin/bash" 9 minutes ago Exited (130) 7 minutes ago nervous_shtern 4012820796df jenkins:v1 "/bin/tini -- /usr/l…" 2 weeks ago Exited (137) 2 days ago jenkins [root@node-01 /]# docker commit 248a52042af3 test/httpd sha256:62376af145b65e6531a57fd84ac1254741231b78ac328cef872087b7279ed11e [root@node-01 /]# docker images test/httpd REPOSITORY TAG IMAGE ID CREATED SIZE test/httpd latest 62376af145b6 23 seconds ago 312MB
在使用docker commit命令中,指定了要提交的修改过的容器的ID(可以通过docker ps命令得到刚创建的容器ID),以及一个目标镜像仓库和镜像名,这里是test/httpd。需要注意的是,docker commit提交的只是创建容器的镜像与容器的当前状态之间有差异的部分,这使得该更新非常轻量。通过docker images 可以查看新创建的镜像信息。
也可以在提交镜像时指定更多的数据(包括标签)来详细描述所做的修改。
[root@node-01 /]# docker commit -m="a new custom images" --author="caoshousong" 248a52042af3 test/httpd:webserver sha256:83509d95a8bd3f6d0b6d9dd4f0c073caa5610d25d8ecc6e8af13c889ca7629c8
这条命令里,我们指定了更多的信息选项:
-m 用来指定创建镜像的提交信息;
--author 用来列出该镜像的作者信息;
最后在test/httpd后面增加了一个webserver标签。
通过使用docker inspect命令来查看新创建的镜像的详细信息:
[root@node-01 /]# docker inspect test/httpd:webserver [ { "Id": "sha256:83509d95a8bd3f6d0b6d9dd4f0c073caa5610d25d8ecc6e8af13c889ca7629c8", "RepoTags": [ "test/httpd:webserver" ], "RepoDigests": [], "Parent": "sha256:9f38484d220fa527b1fb19747638497179500a1bed8bf0498eb788229229e6e1", "Comment": "a new custom images", "Created": "2019-03-15T03:13:09.355691268Z", "Container": "248a52042af34024f9cc4f938d14d7dd55b296cf229f28b5b2c48766e1a5be11", "ContainerConfig": { "Hostname": "248a52042af3", "Domainname": "", "User": "", "AttachStdin": true, "AttachStdout": true, "AttachStderr": true, "Tty": true, "OpenStdin": true, "StdinOnce": true, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Cmd": [ "/bin/bash" ], "ArgsEscaped": true, "Image": "centos", "Volumes": null, "WorkingDir": "", "Entrypoint": null, "OnBuild": null, "Labels": { "org.label-schema.build-date": "20190305", "org.label-schema.license": "GPLv2", "org.label-schema.name": "CentOS Base Image", "org.label-schema.schema-version": "1.0", "org.label-schema.vendor": "CentOS" } }, "DockerVersion": "18.09.2", "Author": "caoshousong", "Config": { "Hostname": "248a52042af3", "Domainname": "", "User": "", "AttachStdin": true, "AttachStdout": true, "AttachStderr": true, "Tty": true, "OpenStdin": true, "StdinOnce": true, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Cmd": [ "/bin/bash" ....................................以下省略........................................
2.创建Dockerfile文件
下面将介绍如何通过Dockerfile的定义文件和docker build命令来构建镜像。
Dockerfile使用基本的基于DSL语法的指令来构建一个Docker镜像,之后使用docker build命令基于该Dockerfile中的指令构建一个新的镜像。
# mkdir /home/wwwroot # cd /home/wwwroot # vim Dockerfile
首先创建一个名为wwwroot的目录用来保存Dockerfile,这个目录就是我们的构建环境(build environment),Docker则称此环境为上下文(context)或者构建上下文(build context)。Docker会在构建镜像时将构建上下文和该上下文中的文件和目录上传到Docker守护进程。这样Docker守护进程就能直接访问你想在镜像中存储的任何代码、文件或者其他数据。这里我们还创建了一个Dockerfile文件,我们将用它构建一个能作为Web服务器的Docker镜像。
# Version: 1.0.0 FROM centos:latest MAINTAINER Caoshousong "caoshousong@163.com" RUN yum -y update RUN yum -y install httpd RUN echo ‘Hello, This is My Apache Container‘ > /var/www/html/index.html EXPOSE 80
Dockerfile由一系列指令和参数组成。每条指令都必须为大写字母,切后面要跟随一个参数。Dockerfile中的指令会按照顺序从上到下执行,所以应该根据需要合理安排指令的顺序。每条指令都会创建一个新的镜像层并对镜像进行提交。Docker大体上按照如下流程执行Dockerfile中的指令。
Docker从基础镜像运行一个容器。
执行第一条指令,对容器进行修改。
执行类似docker commit的操作,提交一个新的镜像层。
Docker再基于刚提交的镜像运行一个新的容器。
执行Dockerfile中的下一条命令,直到所有指令都执行完毕。
Dockerfile也支持注释。以#开头的行都会被认为是注释,# Version: 1.0.0这就是个注释
FROM:
每个Dockerfile的第一条指令都应该是FROM。FROM指令指定一个已经存在的镜像,后续指令都是将基于该镜像进行,这个镜像被称为基础镜像(base image)。在这里centos:latest就是作为新镜像的基础镜像。也就是说Dockerfile构建的新镜像将以centos:latest操作系统为基础。在运行一个容器时,必须要指明是基于哪个基础镜像在进行构建。
MAINTAINER:
MAINTAINER指令,这条指令会告诉Docker该镜像的作者是谁,以及作者的邮箱地址。这有助于表示镜像的所有者和联系方式
RUN:
在这些命令之后,我们指定了三条RUN指令。RUN指令会在当前镜像中运行指定的命令。这里我们通过RUN指令更新了APT仓库,安装nginx包,并创建了一个index.html文件。像前面说的那样,每条RUN指令都会创建一个新的镜像层,如果该指令执行成功,就会将此镜像层提交,之后继续执行Dockerfile中的下一个指令。
默认情况下,RUN指令会在shell里使用命令包装器/bin/sh -c 来执行。如果是在一个不支持shell的平台上运行或者不希望在shell中运行(比如避免shell字符串篡改),也可以使用exec格式的RUN指令,通过一个数组的方式指定要运行的命令和传递给该命令的每个参数:
RUN ["yum", "install", "-y", "httpd"]
EXPOSE:
EXPOSE指令是告诉Docker该容器内的应用程序将会使用容器的指定端口。这并不意味着可以自动访问任意容器运行中服务的端口。出于安全的原因,Docker并不会自动打开该端口,而是需要你在使用docker run运行容器时来指定需要打开哪些端口。
可以指定多个EXPOSE指令来向外部公开多个端口,Docker也使用EXPOSE指令来帮助将多个容器链接,在后面的学习过程中我们会接触到。
3.基于Dockerfile 构建新镜像
执行docker build命令时,Dockerfile中的所有指令都会被执行并且提交,并且在该命令成功结束后返回一个新镜像。
[root@node-01 /]# cd /home/wwwroot/ [root@node-01 wwwroot]# docker build -t="test/httpd-2.4" . Sending build context to Docker daemon 2.048kB Step 1/6 : FROM centos:latest ---> 9f38484d220f Step 2/6 : MAINTAINER Caoshousong "caoshousong@163.com" ---> Running in 3204208707e4 Removing intermediate container 3204208707e4 ---> bb80a24affe8 Step 3/6 : RUN yum -y update ---> Running in 5522ef5af279 Loaded plugins: fastestmirror, ovl Determining fastest mirrors * base: mirrors.aliyun.com * extras: mirrors.163.com * updates: mirrors.aliyun.com No packages marked for update Removing intermediate container 5522ef5af279 ---> 4c028d629a59 Step 4/6 : RUN yum -y install httpd ---> Running in f1977f7bfa48 Loaded plugins: fastestmirror, ovl Loading mirror speeds from cached hostfile * base: mirrors.aliyun.com * extras: mirrors.163.com * updates: mirrors.aliyun.com Resolving Dependencies --> Running transaction check ---> Package httpd.x86_64 0:2.4.6-88.el7.centos will be installed --> Processing Dependency: httpd-tools = 2.4.6-88.el7.centos for package: httpd-2.4.6-88.el7.centos.x86_64 --> Processing Dependency: system-logos >= 7.92.1-1 for package: httpd-2.4.6-88.el7.centos.x86_64 --> Processing Dependency: /etc/mime.types for package: httpd-2.4.6-88.el7.centos.x86_64 --> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.4.6-88.el7.centos.x86_64 --> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.4.6-88.el7.centos.x86_64 --> Running transaction check ---> Package apr.x86_64 0:1.4.8-3.el7_4.1 will be installed ---> Package apr-util.x86_64 0:1.5.2-6.el7 will be installed ---> Package centos-logos.noarch 0:70.0.6-3.el7.centos will be installed ---> Package httpd-tools.x86_64 0:2.4.6-88.el7.centos will be installed ---> Package mailcap.noarch 0:2.1.41-2.el7 will be installed --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Installing: httpd x86_64 2.4.6-88.el7.centos base 2.7 M Installing for dependencies: apr x86_64 1.4.8-3.el7_4.1 base 103 k apr-util x86_64 1.5.2-6.el7 base 92 k centos-logos noarch 70.0.6-3.el7.centos base 21 M httpd-tools x86_64 2.4.6-88.el7.centos base 90 k mailcap noarch 2.1.41-2.el7 base 31 k Transaction Summary ================================================================================ Install 1 Package (+5 Dependent packages) Total download size: 24 M Installed size: 31 M Downloading packages: warning: /var/cache/yum/x86_64/7/base/packages/apr-1.4.8-3.el7_4.1.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY Public key for apr-1.4.8-3.el7_4.1.x86_64.rpm is not installed -------------------------------------------------------------------------------- Total 6.3 MB/s | 24 MB 00:03 Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 Importing GPG key 0xF4A80EB5: Userid : "CentOS-7 Key (CentOS 7 Official Signing Key) <security@centos.org>" Fingerprint: 6341 ab27 53d7 8a78 a7c2 7bb1 24c6 a8a7 f4a8 0eb5 Package : centos-release-7-6.1810.2.el7.centos.x86_64 (@CentOS) From : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : apr-1.4.8-3.el7_4.1.x86_64 1/6 Installing : apr-util-1.5.2-6.el7.x86_64 2/6 Installing : httpd-tools-2.4.6-88.el7.centos.x86_64 3/6 Installing : centos-logos-70.0.6-3.el7.centos.noarch 4/6 Installing : mailcap-2.1.41-2.el7.noarch 5/6 Installing : httpd-2.4.6-88.el7.centos.x86_64 6/6 Verifying : mailcap-2.1.41-2.el7.noarch 1/6 Verifying : apr-util-1.5.2-6.el7.x86_64 2/6 Verifying : httpd-tools-2.4.6-88.el7.centos.x86_64 3/6 Verifying : httpd-2.4.6-88.el7.centos.x86_64 4/6 Verifying : apr-1.4.8-3.el7_4.1.x86_64 5/6 Verifying : centos-logos-70.0.6-3.el7.centos.noarch 6/6 Installed: httpd.x86_64 0:2.4.6-88.el7.centos Dependency Installed: apr.x86_64 0:1.4.8-3.el7_4.1 apr-util.x86_64 0:1.5.2-6.el7 centos-logos.noarch 0:70.0.6-3.el7.centos httpd-tools.x86_64 0:2.4.6-88.el7.centos mailcap.noarch 0:2.1.41-2.el7 Complete! Removing intermediate container f1977f7bfa48 ---> a0ee183d6166 Step 5/6 : RUN echo ‘Hello, This is My Apache Container‘ > /var/www/html/index.html ---> Running in 90aba7bfc237 Removing intermediate container 90aba7bfc237 ---> 7d2f1c4858f8 Step 6/6 : EXPOSE 80 ---> Running in 9aa19b507707 Removing intermediate container 9aa19b507707 ---> 890b7ee94082 Successfully built 890b7ee94082 Successfully tagged test/httpd-2.4:latest
原文:https://www.cnblogs.com/caoshousong/p/10536042.html