Dockerfile与网络基本操作
2020-07-11 本文已影响0人
攻城老狮
一.Dockerfile相关操作
1.Dockerfile指令
FROM # 基础镜像,从此文件开始构建镜像
MAINTAINER # 镜像维护者 姓名+邮箱
RUN # 镜像构建时运行的命令
ADD # 添加文件,会自动解压
WORKDIR # 工作目录
VOLUME # 挂载目录
EXPOSE # 暴露端口
CMD # 指定容器启动时候运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定容器启动时候运行的命令,可以追加命令
ONBUILD # 当构建一个继承的Dockerfile时,父镜像会运行其ONBUILD的指令
COPY # 类似ADD,将文件拷贝到镜像,但不会解压
ENV # 设置环境变量
2. Dockerfile构建centos并发布到DockerHub
# 1.编写Dockerfile文件
FROM centos
MAINTAINER yqj<yaoqijun@outlook.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD /bin/bash
# 2.构建镜像 若文件不叫Dockerfile需要添加 -f 文件名
docker build -t yqj/centos:1.0 .
# 3.可以查看一下镜像的构建过程
docker history yqj/centos:1.0
# 4.启动容器
docker run -it --name mycentos01 yqj/centos:1.0
exit
# 5.登录dockerhub
docker login -u yaokuku123
# 6.修改标签,改为自己账号名下
docker tag yqj/centos:1.0 yaokuku123/centos:1.0
# 7.发布镜像
docker push yaokuku123/centos:1.0
# 8.退出登录
docker logout
3.Dockerfile构建tomcat
# 1.准备jdk,tomcat压缩包以及readme文件
ls
apache-tomcat-8.5.53.tar.gz Dockerfile jdk-13.0.2_linux-x64_bin.tar.gz readme.txt
# 2.编写Dockerfile文件
FROM centos
MAINTAINER yqj<yaoqijun@outlook.com>
#把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下
COPY readme.txt /usr/local/
#把java与tomcat添加到容器中
ADD jdk-13.0.2_linux-x64_bin.tar.gz /usr/local/
ADD apache-tomcat-8.5.53.tar.gz /usr/local/
#设置工作访问时候的WORKDIR路径,登录落脚点
ENV MYPATH /usr/local
WORKDIR $MYPATH
#配置java与tomcat环境变量
ENV JAVA_HOME /usr/local/jdk-13.0.2
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.53
ENV CATALINA_BASE /usr/local/apache-tomcat-8.5.53
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器运行时监听的端口
EXPOSE 8080
#启动时运行tomcat
CMD /usr/local/apache-tomcat-8.5.53/bin/startup.sh && tail -F /usr/local/apche-tomcat-8.5.53/logs/catalina.out
# 3.构建镜像
docker build -t yqj/tomcat:1.0 .
# 4.运行容器
docker run -d -p 8080:8080 --name mytomcat01 yqj/tomcat:1.0
二. Docker网络
1. docker的默认网络
原理:每次启动一个docker容器,docker就会给该容器分配一个ip地址,默认安装docker后会有一个docker0网卡。采用桥接模式,使用的是veth-pair技术。
veth-pair技术就是一对虚拟设备接口,成对出现。利用该技术充当一个桥梁,连接虚拟网络设备
# 1.创建一个tomcat容器查看容器内部的网络ip
docker run -d -p 8080:8080 --name mytomcat01 tomcat:9.0
docker exec -it mytomcat01 ip addr
# 查看输出结果,发现除了本身的回环地址外,额外增加了478: eth0@if479
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
478: eth0@if479: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
# 2.在主机上查看此时的网络
ip addr
# 查看输出,发现在主机也多了一个额外的ip地址
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:64:4e:34:c4 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:64ff:fe4e:34c4/64 scope link
valid_lft forever preferred_lft forever
479: veth3ade909@if478: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 02:e3:97:92:52:e0 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::e3:97ff:fe92:52e0/64 scope link
valid_lft forever preferred_lft forever
# 3.尝试在主机ping容器的ip,发现可以ping通
ping 172.17.0.2
# 4.再启动一个容器,查看其内部的ip地址
docker run -d -p 8081:8080 --name mytomcat02 tomcat:9.0
docker exec -it mytomcat02 ip addr
# 查看输出结果,发现除了本身的回环地址外,额外增加了480: eth0@if481
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
480: eth0@if481: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
# 5.在主机上再次查看此时的网络
ip addr
# 查看输出,发现在主机又多了一个额外的ip地址
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:64:4e:34:c4 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:64ff:fe4e:34c4/64 scope link
valid_lft forever preferred_lft forever
479: veth3ade909@if478: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 02:e3:97:92:52:e0 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::e3:97ff:fe92:52e0/64 scope link
valid_lft forever preferred_lft forever
481: veth916ff39@if480: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether fe:e6:f6:f7:c3:86 brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::fce6:f6ff:fef7:c386/64 scope link
valid_lft forever preferred_lft forever
# 6.尝试在主机ping容器的ip,发现可以ping通
ping 172.17.0.3
# 7.尝试不同容器之间是否可以ping通,发现两个容器之间均可以相互ping通
docker exec -it mytomcat01 ping 172.17.0.3
docker exec -it mytomcat02 ping 172.17.0.2
# 结论:容器与容器间,主机与容器间均可以相互ping通
2. --link 容器互联
由于使用ip地址不方便,若地址变更,则编写的项目必须重启。需要设计一种机制,将容器名或者容器id与ip地址相互关联。(该方法已经不建议使用,比较笨拙)
# 1.在上一节的测试基础上,再启动一个容器,将该容器与mytomcat02互联
docker run -d -p 8082:8080 --name mytomcat03 --link mytomcat02 tomcat:9.0
# 2.发现在03中可以直接通过容器名ping通,而不用使用ip地址
docker exec -it mytomcat03 ping mytomcat02
# 3.但是不可以通过02反向ping03,因为没有配置
docker exec -it mytomcat03 cat /etc/hosts
# 可以发现--link实际上就是在该容器的hosts文件中增添了与link容器的映射关系
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3 mytomcat02 58fd8151c077
172.17.0.4 cda17937d62e
# 4.查看02的hosts配置
docker exec -it mytomcat02 cat /etc/hosts
# 可以发现在02中并没有配置与03的互联映射关系,故而无法通过容器名ping通
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3 58fd8151c077
3.自定义网络
在创建不同的集群,例如 redis集群,mysql集群时候,可以实现网络之间的相互隔离
# 1.查看当前网卡情况
docker network ls
NETWORK ID NAME DRIVER SCOPE
fadc2303e81c bridge bridge local # 桥接模式
756eeb1985eb host host local # 和宿主机共享
547d72589745 none null local # 不配置网络
# 2.创建自定义网络
docker network create --driver bridge --subnet 192.167.0.0/16 --gateway 192.167.0.1 mynet
# 查看当前网络发现已经创建成功
NETWORK ID NAME DRIVER SCOPE
fadc2303e81c bridge bridge local
756eeb1985eb host host local
7dde80cf160c mynet bridge local
547d72589745 none null local
# 3.查看自定义网络的配置信息
docker network inspect mynet
[
{
"Name": "mynet",
"Id": "7dde80cf160c4526e37f0d5bd76d30c6c6fe80046d631eaa42852b846202f02c",
"Created": "2020-07-11T09:55:01.962552613+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.167.0.0/16",
"Gateway": "192.167.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
# 4.使用自定义的网络创建两个tomcat容器,若不指定 --net 则默认为bridge(docker0的网络)
docker run -d -P --name mytomcat-net-01 --net mynet tomcat:9.0
docker run -d -P --name mytomcat-net-02 --net mynet tomcat:9.0
# 再次查看自定义网络的配置信息,可以发现已经将两个容器的信息配置到该网络下
docker network inspect mynet
[
{
"Name": "mynet",
"Id": "7dde80cf160c4526e37f0d5bd76d30c6c6fe80046d631eaa42852b846202f02c",
"Created": "2020-07-11T09:55:01.962552613+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.167.0.0/16",
"Gateway": "192.167.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"67308eb3f177f9d14f718e0507eaaaf2088c76f229bfde7da15620af01f348f4": {
"Name": "mytomcat-net-02",
"EndpointID": "b636d43051f7abc791df8ae8213e6aac7a6d3769109291b0272ea1fba66c4611",
"MacAddress": "02:42:c0:a7:00:03",
"IPv4Address": "192.167.0.3/16",
"IPv6Address": ""
},
"a1c5e7a59d25f130a422a6356cd2005ffab247cc8d92af99e2ccaad0de0b127a": {
"Name": "mytomcat-net-01",
"EndpointID": "87f65a4164398c9354d4d22c8d4c1a87c5739b632aa3647081b97cd0b974768f",
"MacAddress": "02:42:c0:a7:00:02",
"IPv4Address": "192.167.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
# 5.在自定义网络下,可以直接使用容器名来ping通网络
docker exec -it mytomcat-net-01 ping mytomcat-net-02
# 6.测试打通网络,将位于docker0和mynet两个网络下的容器打通
# 具体来说,测试打通docker0网络下的mytomcat01容器和mynet网络
docker network connect mynet mytomcat01
# 查看mynet的配置信息,发现实际上将mytomcat01再映射出一个ip地址到mynet网络中(一个容器两个ip地址)
docker network inspect mynet
[
{
"Name": "mynet",
"Id": "7dde80cf160c4526e37f0d5bd76d30c6c6fe80046d631eaa42852b846202f02c",
"Created": "2020-07-11T09:55:01.962552613+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.167.0.0/16",
"Gateway": "192.167.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"67308eb3f177f9d14f718e0507eaaaf2088c76f229bfde7da15620af01f348f4": {
"Name": "mytomcat-net-02",
"EndpointID": "b636d43051f7abc791df8ae8213e6aac7a6d3769109291b0272ea1fba66c4611",
"MacAddress": "02:42:c0:a7:00:03",
"IPv4Address": "192.167.0.3/16",
"IPv6Address": ""
},
"a1c5e7a59d25f130a422a6356cd2005ffab247cc8d92af99e2ccaad0de0b127a": {
"Name": "mytomcat-net-01",
"EndpointID": "87f65a4164398c9354d4d22c8d4c1a87c5739b632aa3647081b97cd0b974768f",
"MacAddress": "02:42:c0:a7:00:02",
"IPv4Address": "192.167.0.2/16",
"IPv6Address": ""
},
"dfa3c4a48de5581f22c6b9fc47dfe906e4e40047b54cdeba533a22e03ad8c382": {
"Name": "mytomcat01",
"EndpointID": "8033a85b503549504ba8e8aa18a3b23c65cf843af6877606795af12073b20995",
"MacAddress": "02:42:c0:a7:00:04",
"IPv4Address": "192.167.0.4/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
# 7.测试不同网络下的容器可否ping通,发现成功互联
docker exec -it mytomcat01 ping mytomcat-net-01
# 8.删除网络
docker network rm mynet