系列文章目录
docker常用方法之dockerfile入门指令用法2
docker
- 系列文章目录
- 一、 Dockerfile写法详解
- 1.1 copy指令用法
- 1.2 ADD指令用法
- 1.3ENV指令用法
- 1.4EXPOSE指令用法
- 1.5VOLUME指令用法
- 1.6WORKDIR指令用法
- 1.7将数据存入宿主机原因
- 1.8RUN指令的用法
- 1.9CMD与ENTRYPOINT指令的用法
- 1.10Shell 和exec格式的区别
- 1.11ENTRYPOINT与CMD混合使用
一、 Dockerfile写法详解
看docker官方的网站学习docker具体指令
常用指令:
FROM 指定base镜像,如果本地不存在会从远程仓库下载 | MAINTAINER 设置镜像的作者,比如用户邮箱等 |
COPY 把文件从build context 复制到镜像 支持两种形式:COPY src dest 和 COPY 【“src,”“dest”】 src必须指定build context 中的文件或目录 |
1.1 copy指令用法
src必须指定build context 中的文件或目录即当前目录
实验环境:
[root@docker1 docker]# vim index.html
[root@docker1 docker]# cat index.html
www.yan.com
编写Dockerfile:
[root@docker1 docker]# vim Dockerfile
[root@docker1 docker]# cat Dockerfile
FROM busybox
RUN touch file1
RUN mkdir dir1
RUN mv file1 dir1
COPY index.html /
前面镜像用的cache,因为之前编译过,Dockerfile没有改变都是用缓存来执行,加速构建过程
[root@docker1 docker]# docker build -t test:v2 .
Sending build context to Docker daemon 3.072kB
Step 1/5 : FROM busybox
---> beae173ccac6
Step 2/5 : RUN touch file1
---> Using cache
---> 884a1d2fcbd4
Step 3/5 : RUN mkdir dir1
---> Using cache
---> 3f7259a48bfc
Step 4/5 : RUN mv file1 dir1
---> Using cache
---> b6b7f570cc47
Step 5/5 : COPY index.html /
---> 317f587b99ce
Successfully built 317f587b99ce
Successfully tagged test:v2
拷贝文件到容器中
[root@docker1 docker]# docker history test:v2
IMAGE CREATED CREATED BY SIZE COMMENT
317f587b99ce 2 minutes ago /bin/sh -c #(nop) COPY file:d88a99d823b18eab… 12B
b6b7f570cc47 34 minutes ago /bin/sh -c mv file1 dir1 0B
3f7259a48bfc 34 minutes ago /bin/sh -c mkdir dir1 0B
884a1d2fcbd4 34 minutes ago /bin/sh -c touch file1 0B
beae173ccac6 3 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ADD file:6db446a57cbd2b7f4… 1.24MB
执行的指令,ls /接在镜像的后面会覆盖掉镜像原有的操作指令。
–rm帮助运行完容器指令后自动删除该容器
[root@docker1 docker]# docker run --rm test:v2 ls /
bin
dev
dir1
etc
home
index.html
proc
root
sys
tmp
usr
var
[root@docker1 docker]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@docker1 docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1.2 ADD指令用法
ADD用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以自动下载URL并拷贝到镜像:
实验环境:
[kiosk@foundation38 lamp]$ scp nginx-1.18.0.tar.gz root@172.25.254.1:/root/docker
[root@docker1 docker]# ls
Dockerfile index.html nginx-1.18.0.tar.gz
编写Dockefile:
[root@docker1 docker]# cat Dockerfile
FROM busybox
RUN touch file1
RUN mkdir dir1
RUN mv file1 dir1
COPY index.html /
ADD nginx-1.18.0.tar.gz /
[root@docker1 docker]# docker build -t test:v3 .
Sending build context to Docker daemon 1.043MB
Step 1/6 : FROM busybox
---> beae173ccac6
Step 2/6 : RUN touch file1
---> Using cache
---> 884a1d2fcbd4
Step 3/6 : RUN mkdir dir1
---> Using cache
---> 3f7259a48bfc
Step 4/6 : RUN mv file1 dir1
---> Using cache
---> b6b7f570cc47
Step 5/6 : COPY index.html /
---> Using cache
---> 317f587b99ce
Step 6/6 : ADD nginx-1.18.0.tar.gz /
---> 88b81d3d9f28
Successfully built 88b81d3d9f28
Successfully tagged test:v3
解压后放入,基础镜像没有解压命令,所以在构建前用ADD构建。
[root@docker1 docker]# docker run --rm test:v3 ls /
bin
dev
dir1
etc
home
index.html
nginx-1.18.0
proc
root
sys
tmp
usr
var
1.3ENV指令用法
设置环境变量,变量可以被后续的指令使用:
变量名大写
Dockerfile写法:
[root@docker1 docker]# cat Dockerfile
ENV HOSTNAME docker1
1.4EXPOSE指令用法
用于应用容器,要发布一个服务的容器。
如果容器中运行应用服务,可以把服务端口暴露出去:
EXPOSE 80
[root@docker1 docker]# cat Dockerfile
EXPOSE 80
1.5VOLUME指令用法
应用容器的数据需要持久化
申明数据卷,通常指定的是应用的数据挂载点:
[root@docker1 docker]# cat Dockerfile
VOLUME ["/data"]
1.6WORKDIR指令用法
为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在会自动创建。即,容器内切换目录。
前面3个用法的运行结果:
[root@docker1 docker]# cat Dockerfile
FROM busybox
RUN touch file1
RUN mkdir dir1
RUN mv file1 dir1
COPY index.html /
ADD nginx-1.18.0.tar.gz /
ENV HOSTNAME docker1
EXPOSE 80
VOLUME ["/data"]
WORKDIR /dir1
运行结果就不写在代码块了
[root@docker1 docker]# docker build -t test:v4 .
data是前面定义的数据卷
[root@docker1 docker]# docker run -it test:v4
/dir1 # cd /data/
/data #
这个卷挂载你宿主机的上面
/data # mount |grep data
/dev/mapper/rhel-root on /data type xfs (rw,relatime,attr2,inode64,noquota)
docker里面看到的是宿主机的信息,磁盘、cpu、内存这些信息存在/proc,/proc是文件系统里面的不会被隔离。
/data # df
Filesystem 1K-blocks Used Available Use% Mounted on
overlay 17811456 1594500 16216956 9% /
tmpfs 65536 0 65536 0% /dev
tmpfs 1023468 0 1023468 0% /sys/fs/cgroup
shm 65536 0 65536 0% /dev/shm
/dev/mapper/rhel-root
17811456 1594500 16216956 9% /data
/dev/mapper/rhel-root
17811456 1594500 16216956 9% /etc/resolv.conf
/dev/mapper/rhel-root
17811456 1594500 16216956 9% /etc/hostname
/dev/mapper/rhel-root
17811456 1594500 16216956 9% /etc/hosts
tmpfs 1023468 0 1023468 0% /proc/asound
tmpfs 1023468 0 1023468 0% /proc/acpi
tmpfs 65536 0 65536 0% /proc/kcore
tmpfs 65536 0 65536 0% /proc/keys
tmpfs 65536 0 65536 0% /proc/timer_list
tmpfs 65536 0 65536 0% /proc/timer_stats
tmpfs 65536 0 65536 0% /proc/sched_debug
tmpfs 1023468 0 1023468 0% /proc/scsi
tmpfs 1023468 0 1023468 0% /sys/firmware
docker运行的主机:
[root@docker1 ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/rhel-root 17811456 1594500 16216956 9% /
devtmpfs 1011400 0 1011400 0% /dev
tmpfs 1023468 0 1023468 0% /dev/shm
tmpfs 1023468 17076 1006392 2% /run
tmpfs 1023468 0 1023468 0% /sys/fs/cgroup
/dev/vda1 1038336 135172 903164 14% /boot
tmpfs 204696 0 204696 0% /run/user/0
overlay 17811456 1594500 16216956 9% /var/lib/docker/overlay2/0d9fe361ffa5bec1667b38b2dc660e093a1dd319d69a23a6e498683163971fc5/merged
这个便是容器挂载在宿主机上面的卷
/dev/mapper/rhel-root 17811456 1594500 16216956 9% /
查看一下该容器的具体信息
docker inspect 后面可以加容器也可以镜像
[root@docker1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c626bd8688f test:v4 "sh" 14 seconds ago Up 13 seconds 80/tcp romantic_bhabha
999fd34ca89f test:v4 "sh" 4 hours ago Exited (255) About a minute ago 80/tcp peaceful_wing
[root@docker1 ~]# docker inspect 4c626bd8688f
inspect查询部分信息:
Gateway是宿主机上面的地址,docker 0的地址。所以容器会通过桥接的模式到达宿主机的网关
所有容器的数据会放在宿主机的/var/lib/docker,如果把这个删掉,所有的镜像容器全没了。
[root@docker1 docker]# ls
builder buildkit containers image network overlay2 plugins runtimes swarm tmp trust volumes
容器的卷的目录在/var/lib/docker/volumes
"Gateway": "172.17.0.1"
"IPAddress": "172.17.0.2",
"Mounts": [
{
"Type": "volume",
"Name": "a780ebed1de6be544711f18a254682fc4f018ce2f7058b0a23f6f16a3eb73171",
"Source": "/var/lib/docker/volumes/a780ebed1de6be544711f18a254682fc4f018ce2f7058b0a23f6f16a3eb73171/_data",
"Destination": "/data",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
]
这个路径就被挂载在容器的目录里面
"Source": "/var/lib/docker/volumes/a780ebed1de6be544711f18a254682fc4f018ce2f7058b0a23f6f16a3eb73171/_data",
容器里面:
/data # touch file1
/data # ls
file1
宿主机上:
[root@docker1 ~]# cd /var/lib/docker/volumes/a780ebed1de6be544711f18a254682fc4f018ce2f7058b0a23f6f16a3eb73171/_data
[root@docker1 _data]# ls
file1
宿主机docker0的地址:
[root@docker1 ~]# ip addr | grep 172.17.0.1
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
容器里面查询ip的结果:
/dir1 # ip addr
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
1.7将数据存入宿主机原因
1.容器的文件系统性能比宿主机差
2.数据过大放在容器不合适,不小心删掉容器,数据就丢失了
同理存在宿主机上面:
宿主机删掉该数据,容器里面的数据就没有了
宿主机:
[root@docker1 ~]# cd /var/lib/docker/volumes/a780ebed1de6be544711f18a254682fc4f018ce2f7058b0a23f6f16a3eb73171/_data
[root@docker1 _data]# ls
file1
[root@docker1 _data]# rm -fr file1
容器里面:
/data # ls
file1
/data # ls
/data #
1.8RUN指令的用法
在容器中运行命令并创建新的镜像层,常用于安装软件包:
RUN yum install -y vim
1.9CMD与ENTRYPOINT指令的用法
这两个指令都是用于设置容器后执行的命令,但CMD会被docker run 后面的命令行覆盖(比如docker run -it /ls会覆盖掉),而ENTRYPOINT不会被忽略,一定会被执行
docker run 后面的参数可以传递给ENTRYPOINT指令当作参数
Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效
CMD当用户进入后自动执行的指令,像busybox这个镜像第二层,意思就是当用户进去后,自动执行sh
官方推荐CMD用exec格式写
[root@docker1 docker]# docker history test:v1
beae173ccac6 3 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0B
1.10Shell 和exec格式的区别
Shell格式底层会调用/bin/sh -c来执行命令,可以解析变量,而exec格式不会
而用exec格式写的话:[“/bin/sh”,“-c”,“echo $变量名”]
Shell格式:
[root@docker1 docker]# vim Dockerfile
[root@docker1 docker]# cat Dockerfile
FROM busybox
RUN touch file1
RUN mkdir dir1
RUN mv file1 dir1
COPY index.html /
ADD nginx-1.18.0.tar.gz /
ENV HOSTNAME docker1
EXPOSE 80
VOLUME ["/data"]
WORKDIR /dir1
CMD echo $HOSTNAME
[root@docker1 docker]# docker build -t test:v5 .
[root@docker1 docker]# docker run --rm test:v5
docker1
exec格式:
[root@docker1 docker]# vim Dockerfile
[root@docker1 docker]# cat Dockerfile
FROM busybox
RUN touch file1
RUN mkdir dir1
RUN mv file1 dir1
COPY index.html /
ADD nginx-1.18.0.tar.gz /
ENV HOSTNAME docker1
EXPOSE 80
VOLUME ["/data"]
WORKDIR /dir1
CMD ["echo $HOSTNAME"]
[root@docker1 docker]# docker build -t test:v6 .
[root@docker1 docker]# docker run --rm test:v6
docker: Error response from daemon: OCI runtime create failed: container_linux.go:367: starting container process caused: exec: "echo $HOSTNAME": executable file not found in $PATH: unknown.
[root@docker1 docker]# docker rmi test:v6
[root@docker1 docker]# vim Dockerfile
FROM busybox
RUN touch file1
RUN mkdir dir1
RUN mv file1 dir1
COPY index.html /
ADD nginx-1.18.0.tar.gz /
ENV HOSTNAME docker1
EXPOSE 80
VOLUME ["/data"]
WORKDIR /dir1
CMD ["/bin/echo","echo $HOSTNAME"]
[root@docker1 docker]# docker build -t test:v6 .
[root@docker1 docker]# docker run --rm test:v6
echo $HOSTNAME
用exec格式写:
[root@docker1 docker]# vim Dockerfile
[root@docker1 docker]# cat Dockerfile
FROM busybox
RUN touch file1
RUN mkdir dir1
RUN mv file1 dir1
COPY index.html /
ADD nginx-1.18.0.tar.gz /
ENV HOSTNAME docker1
EXPOSE 80
VOLUME ["/data"]
WORKDIR /dir1
CMD ["/bin/echo","-c","echo $HOSTNAME"]
[root@docker1 docker]# docker build -t test:v7 .
[root@docker1 docker]# docker run --rm test:v7
docker1
Exec格式时,ENTRYPOINT可以通过CMD提供额外的参数,CMD的额外参数可以在容器启动时动态替换。在shell格式时ENTRYPOINT会忽略任何CMD或docker run提供的参数。即ENTRYPOINT与CMD混合使用
1.11ENTRYPOINT与CMD混合使用
[root@docker1 docker]# vim Dockerfile
[root@docker1 docker]# cat Dockerfile
FROM busybox
RUN touch file1
RUN mkdir dir1
RUN mv file1 dir1
COPY index.html /
ADD nginx-1.18.0.tar.gz /
ENV HOSTNAME docker1
EXPOSE 80
VOLUME ["/data"]
WORKDIR /dir1
ENTRYPOINT ["/bin/echo","hello"]
CMD ["world"]
[root@docker1 docker]# docker build -t test:v8 .
[root@docker1 docker]# docker run --rm test:v8
hello world
[root@docker1 docker]# docker run --rm test:v8 linux
hello linux
[root@docker1 docker]# docker run --rm test:v8 yan
hello yan
END