Dockerfile与Docker网络
一、Dockerfile
1、概念:
Dockerfile是用来构建docker镜像的文本文件,是由构建镜像所需要的指令和参数构建的脚本。
2、构建步骤:
① 编写Dockerfile文件
② docker build命令构建镜像
③ docker run依据镜像运行容器实例
Dockerfile 是构建 docker 镜像的指令集,docker 镜像是容器运行的静态模板,而 docker 容器是基于 docker 镜像创建的可运行实例。
3、Dockerfile基础知识:
① 每条保留字指令都必须为大写字母,且后面要跟随至少一个参数
② 指令按照从上到下顺序执行
③ #表示注释
④ 每条指令都会创建一个新的镜像层并对镜像进行提交
二、Dockerfile常用保留字指令
1、概念:
在 Dockerfile 中,保留字 (Reserved Keywords) 是指一些特定的指令或关键字,用于描述镜像的构建过程。
2、常用保留字:
(1) FROM:当前新镜像是基于哪个镜像的,指定一个已存在的镜像作为模版。Dockerfile 第一条必须是FROM。
(2) MAINTAINER:镜像维护者和邮箱。
(3) RUN:容器构建时需要运行的命令,RUN 在 docker build 时运行。
两种格式:
① shell 格式:
#等同于在终端操作的shell命令 格式:
RUN <命令行命令> RUN yum -y install vim
② exec 格式:
#格式:RUN ["可执行文件" , "参数1", "参数2"]
RUN ["./test.php", "dev", "offline"] #等同于 RUN ./test.php dev offline
(4) EXPOSE:当前容器对外端口。
(5) WORKDIR:创建容器后,终端默认登录进来的工作目录。
(6) USER:指定该镜像以哪个用户执行,如果没有指定则默认是root。
(7) ENV:在构建镜像过程中设置环境变量。这个环境变量可以在后续的RUN指令中使用。
(8) VOLUME:容器数据卷,用于数据存储和持久化工作。
(9) COPY:拷贝文件和目录到镜像中。
COPY src dest
COPY ["src", "dest"]
# <src源路径>:源文件或者源目录 ;<dest目标路径>:容器内的指定路径
(10) ADD:将宿主机目录下的文件拷贝进镜像,且自动处理URL和解压tar包。
COPY + 解压
(11) CMD:指定容器启动后要做的事。
① CMD 指令格式也是 shell 和 exec 两种;
② Dockerfile中如果出现多个CMD指令,只有最后一个生效。CMD会被docker run之后的参数替换。
# 因为tomcat的Dockerfile中指定了 CMD ["catalina.sh", "run"]
# 所以直接docker run 时,容器启动后会自动执行 catalina.sh run
docker run -it -p 8080:8080 tomcat
# 指定容器启动后执行 /bin/bash
# 此时指定的/bin/bash会覆盖掉Dockerfile中指定的 CMD ["catalina.sh", "run"]
docker run -it -p 8080:8080 tomcat /bin/bash
(12) ENTRYPOINT:用来指定容器启动后要做的事,但不会被docker run后面的命令覆盖。
① ENTRYPOINT 可以和 CMD 一起用,当指定了 ENTRYPOINT 后,CMD 的含义就发生了变化,不再是直接运行命令,而是将 CMD 的内容作为参数传递给 ENTRYPOINT 指令,组合成 <ENTRYPOINT> "<CMD>"。
② 示例:
FROM
nginx ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参
3、案例:自定义镜像 centosjava8:
① 需求:
使 centos7.6 镜像具备 vim + ifconfig + jdk8
jdk 镜像下载地址:Java Downloads | Oracle
② 编写:
准备 Dockerfile 文件
FROM centos:7
#基础镜像
MAINTAINER bean<123@123.com>
#维护者和联系方式
ENV MYPATH /usr/local
WORKDIR $MYPATH
#以变量的形式给到一个落脚点
RUN yum -y install vim
#安装vim编辑器
RUN yum -y install net-tools
#安装ifconfig命令查看网络IP
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java
#安装java8及lib库
ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/
#ADD 是相对路径jar,把jdk-8u171-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
#配置java环境变量
EXPOSE 80
CMD echo $MYPATH
CMD echo "success-----------ok"
CMD /bin/bash
③ 构建:
docker build -t 新镜像名:TAG .
④ 运行:
4、虚悬镜像:
(1) 概念:构建镜像时出现错误,导致仓库和标签都是<none>
(2) 查看命令:docker image ls -f dangling=true
(3) 删除命令:docker image prune
三、Docker网络
1、简介:
启动docker服务后,docker服务器会创建一个docker0网桥,该网桥的网络名称为docker0,宿主机和容器可以通过该网桥相互通信。
2、docker network 常用命令:
(1) 查看网络模式:
docker network ls
安装docker后默认会自动创建三个网络。
(2) 创建网络:
docker network create 网络名
(3) 删除网络:
docker network rm 网络名
(4) 查看网络元数据:
docker network inspect 网络名
3、docker网络模式:
(1) 种类:
(2) bridge:
① Docker在宿主机虚拟一个Docker容器网桥(docker0),Docker启动容器时会根据Docker网桥的网段分配给容器一个IP地址,同时Docker网桥是每个容器的默认网关。因为在同一个宿主机内的容器接入同一个网桥,容器之间能通过docker0网桥直接通信。
② 网桥docker0创建的虚拟设备接口叫veth,每个容器实例内部也有一块网卡,网卡接口叫做eth0,每个veth匹配某个容器实例内部的eth0,两两配对。
③ 示例:
● 启动两个tomcat实例:
docker run -d -p 8081:8080 --name tomcat81 billygoo/tomcat8-jdk8
docker run -d -p 8082:8080 --name tomcat82 billygoo/tomcat8-jdk8
● 查看宿主机网络接口信息:ip addr
● 进入容器查看网络接口信息:
(3) host:
① 容器将不会虚拟出自己的网卡,而是直接使用宿主机的 IP 和端口,和宿主机共用一个 Network space。
② 示例:
● 启动一个tomcat实例:
docker run -d -p 8083:8080 --network host --name tomcat83 billygoo/tomcat8-jdk8
docker启动时指定--network host,如果还指定-p映射端口,则docker服务器会给出警告信息,且-p所设置的参数不会生效。
● 正确启动:去掉-p端口映射
docker run -d --network host --name tomcat83 billygoo/tomcat8-jdk8
● 查看容器网络模式:docker inspect tomcat83
● 进入容器查看网络接口信息:
与宿主机网络接口信息相似。
(4) none:
禁用网络功能。在none模式下,docker服务器并不会为容器进行网络配置,在容器中查看网络信息,只能查看到 lo (本地回环网络127.0.0.1网卡),需要自行为容器添加网卡,配置 IP。
(5) container:
① 新创建的容器不会创建自己的网卡、IP,也不是和宿主机共享网络配置,而是和一个已经存在的一个容器共享配置。两个容器除了网络共享,其他的如文件系统、进程列表依然是隔离的。
② 示例:
● 新建两个 alpine 容器实例:
docker run -it --name alpine1 alpine /bin/sh
docker run -it --network container:alpine1 --name alpine2 alpine /bin/sh
● 验证共用网桥:
● 停止 alpine1 运行,观察 alpine2 网络接口状态:
alpine1停止运行后,alpine2只剩本地环回网络。
4、自定义网络
(1) 以 bridge 模式启动两个tomcat容器:
docker run -d -p 8081:8080 --name tomcat81 billygoo/tomcat8-jdk8
docker run -d -p 8082:8080 --name tomcat82 billygoo/tomcat8-jdk8
测试网络连通性:按照 ip 地址能 ping 通 ;按照服务名 ping 不通。
(2) 以自定义网络模式启动tomcat容器:
① 新建一个自定义网络:
② 新建容器加入自定义网络:
docker run -d -p 8081:8080 --network bean_network --name tomcat81 billygoo/tomcat8-jdk8
docker run -d -p 8082:8080 --network bean_network --name tomcat82 billygoo/tomcat8-jdk8
● 测试网络连通性,以服务器也能ping通:
结论:自定义网络本身就维护好主机名和 ip 的对应关系