栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

【docker】win10系统下docker容器安装及使用(二):docker通过commit及dockerfile进行创建

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【docker】win10系统下docker容器安装及使用(二):docker通过commit及dockerfile进行创建

base镜像

base镜像有两层含义:(1)不依赖其他镜像,从scratch构建;(2)其他镜像可以以之为基础进行扩展。能称作base镜像的通常都是各种Linux发行版的Docker镜像,比如Ubuntu、Debian、CentOS等。

对于base镜像来说,底层直接用Host的kernel,自己只需要提供rootfs就行了。
不同Linux发行版的区别主要就是rootfs。比如Ubuntu 14.04使用upstart管理服务,apt管理软件包;而CentOS 7使用systemd和yum。这些都是用户空间上的区别,Linux kernel差别不大。
所有容器都共用host的kernel,在容器中没办法对kernel升级。如果容器对kernel版本有要求(比如应用只能在某个kernel版本下运行),则不建议用容器,这种场景虚拟机可能更合适。

有多个镜像都从相同的base镜像构建而来,那么Docker Host只需在磁盘上保存一份base镜像;同时内存中也只需加载一份base镜像,就可以为所有容器服务了,而且镜像的每一层都可以被共享
所有对容器的改动,无论添加、删除,还是修改文件都只会发生在容器层中。只有容器层是可写的,容器层下面的所有镜像层都是只读的。

镜像共享原理

(1)添加文件。在容器中创建文件时,新文件被添加到容器层中。
(2)读取文件。在容器中读取某个文件时,Docker会从上往下依次在各镜像层中查找此文件。一旦找到,打开并读入内存。
(3)修改文件。在容器中修改已存在的文件时,Docker会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之。
(4)删除文件。在容器中删除文件时,Docker也是从上往下依次在镜像层中查找此文件。找到后,会在容器层中记录下此删除操作。只有当需要修改时才复制一份数据,这种特性被称作Copy-on-Write。可见,容器层保存的是镜像变化的部分,不会对镜像本身进行任何修改

自发构建镜像

Docker提供了两种构建镜像的方法: docker commit命令与Dockerfile构建文件。
docker commit命令是创建新镜像最直观的方法,其过程包含三个步骤:● 运行容器。● 修改容器。● 将容器保存为新的镜像。
首先进入容器内,使用/bin/bash命令:
docker exec -it 156e0b738207 /bin/bash
更新下载列表并安装sudo:
apt-get update
apt-get install sudo

通过commit方法提交一个新的镜像。

可以查看镜像构建的历史:

missing表示无法获取IMAGE ID,通常从Docker Hub下载的镜像会有这个问题。

dockerfile构建方法:
其中-t指定上下文目录,上下文目录中的全部内容会被发送给docker进行构建。用-f指定构建用的dockerfile。

docker build -t ImageName:TagName dir
-t - 提到镜像的标签
ImageName - 这是您要为镜像指定的名称。
TagName - 这是您要为镜像指定的标签。
dir - Dockerfile所在的目录,也是当前的工作目录。

Dockerfile构建镜像的过程:
(1)从base镜像运行一个容器。
(2)执行一条指令,对容器做修改。
(3)执行类似docker commit的操作,生成一个新的镜像层。
(4)Docker再基于刚刚提交的镜像运行一个新容器。
(5)重复2~4步,直到Dockerfile中的所有指令执行完毕。

Dockerfile支持以“#”开头的注释。

● FROM指定base镜像。
● MAINTAINER设置镜像的作者,可以是任意字符串。
● COPY将文件从build context复制到镜像。COPY支持两种形式: COPY src dest与COPY [“src”, “dest”]。注意:src只能指定build context中的文件或目录。
● ADD与COPY类似,从build context复制文件到镜像。不同的是,如果src是归档文件(tar、zip、tgz、xz等),文件会被自动解压到dest。
● ENV设置环境变量,环境变量可被后面的指令使用。
● EXPOSE指定容器中的进程会监听某个端口,Docker可以将该端口暴露出来。
● VOLUME将文件或目录声明为volume。我们会在容器存储部分详细讨论。
● WORKDIR为后面的RUN、CMD、ENTRYPOINT、ADD或COPY指令设置镜像中的当前工作目录。
● RUN在容器中运行指定的命令。
● CMD容器启动时运行指定的命令。Dockerfile中可以有多个CMD指令,但只有最后一个生效。CMD可以被dockerrun之后的参数替换。
●ENTRYPOINT
Dockerfile中可以有多个ENTRYPOINT指令,但只有最后一个生效。CMD或docker run之后的参数会被当作参数传递给ENTRYPOINT。

注:目录映射 docker run -t -i -v D:/ubuntu:/home ubuntu_sudo 将image名放在最后。

通过dockerfile创建docker:
volume与-v指令一样,容器被删除以后映射在主机上的文件不会被删除。

FROM java:8
VOLUME ["/tmp","/home/docker/gkzy/cert"]
COPY ./cert /home/docker/gkzy/cert
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
ADD rz-api-sh-0.0.1.jar app.jar
RUN sh -c 'touch /app.jar'
ENV JAVA_OPTS=""
EXPOSE 6758
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]

对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中
#test
FROM ubuntu
MAINTAINER helloword
VOLUME /data
这里的 /data 目录就会在运行时自动挂载为匿名卷,任何向 /data 中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化。当然,运行时可以覆盖这个挂载设置。比如:
$ docker run -d -v mydata:/data xxxx
在这行命令中,就使用了 mydata 这个命名卷挂载到了 /data 这个位置,替代了 Dockerfile 中定义的匿名卷的挂载配置。

实例:

在D:ubuntu 下放入一个useforinfo.txt 及 dockerfile,其中 dockerfile内容如下:

FROM ubuntu_sudo
COPY ./useforinfo.txt ./home
RUN echo "hello">./home/useforinfo.txt
CMD echo "this is the first echo file!"
CMD "bin/bash"

运行过程如下:

PS C:Users104005162> cd D:ubuntu                                                                                     PS D:ubuntu> docker build -t ubuntu_sudo:test -f ./dockerfile .                                                        PS D:ubuntu> docker build -t ubuntu_sudo:test -f ./dockerfile .                                                        [+] Building 1.2s (8/8) FINISHED
 => [internal] load build definition from dockerfile                                                               0.4s
 => => transferring dockerfile: 184B                                                                               0.0s
 => [internal] load .dockerignore                                                                                  0.5s
 => => transferring context: 2B                                                                                    0.0s
 => [internal] load metadata for docker.io/library/ubuntu_sudo:latest                                              0.0s
 => [internal] load build context                                                                                  0.2s
 => => transferring context: 33B                                                                                   0.0s
 => [1/3] FROM docker.io/library/ubuntu_sudo                                                                       0.0s
 => CACHED [2/3] COPY ./useforinfo.txt ./home                                                                      0.0s
 => CACHED [3/3] RUN echo "hello">./home/useforinfo.txt                                                            0.0s
 => exporting to image                                                                                             0.2s
 => => exporting layers                                                                                            0.0s
 => => writing image sha256:0163e2c9f22c0e96340d7251496f65605bc80d215ab73c856144ee4221fa28bd                       0.1s
 => => naming to docker.io/library/ubuntu_sudo:test                                                                0.0s
PS D:ubuntu>                                              

运行即可。
dockerfile内运行命令的三种模式:
(1)RUN:执行命令并创建新的镜像层,RUN经常用于安装软件包。
(2)CMD:设置容器启动后默认执行的命令及其参数,但CMD能够被dockerrun后面跟的命令行参数替换。
(3)ENTRYPOINT:配置容器启动时运行的命令
ENTRYPOINT看上去与CMD很像,它们都可以指定要执行的命令及其参数。不同的地方在于ENTRYPOINT不会被忽略,一定会被执行,即使运行docker run时指定了其他命令。

ENTRYPOINT中的参数始终会被使用,而CMD的额外参数可以在容器启动时动态替换掉。
如:

ENRTYPOINT ["/bin/eche","Hello"] CMD["world"]
在docker run -it [image]显示为hello world
而使用 docker run -it [image] !
显示为 hello!

shell格式,不带[]的ENRTYPOINT调用方法,忽略一切CMD

最佳实践:
(1)使用RUN指令安装应用和软件包,构建镜像。
(2)如果Docker镜像的用途是运行应用程序或服务,比如运行一个MySQL,应该优先使用Exec格式的ENTRYPOINT指令。CMD可为ENTRYPOINT提供额外的默认参数,同时可利用docker run命令行替换默认参数。
(3)如果想为容器设置默认的启动命令,可使用CMD指令。用户可在docker run命令行中替换此默认命令。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/974180.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号