文章目录
容器数据卷
什么是容器数据卷
Docker的理念回顾
将应用和环境打包成一个镜像!
数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化
例如 MySQL,容器删了等于删库跑路!需求:MySQL数据存储在本地
容器之间需要有一个数据共享的技术!Docker 容器中产生的数据同步到本地
这就是卷技术!将容器内的目录,挂载到 Linux 上面!
一句话:容器的持久化和同步操作!容器间数据共享!
使用数据卷
方式一:直接使用命令来挂载 -v
docker run -it -v 主机目录:容器目录
#测试
[root@dinosaur home]# docker run -it -v /home/test:/home centos /bin/bash
#退出之后查看容器内部状态
[root@dinosaur home]# docker inspect 容器ID
#其内Mounts状态
"Mounts": [ #挂载 -v 卷
{
"Type": "bind", #双向绑定
"Source": "/home/test", #主机内地址
"Destination": "/home", #容器内地址
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
]
我们以后修改只需要在本地修改即可,容器内会自动同步
MySQL实战
#获取MySQL
[root@dinosaur home]# docker pull mysql
#运行容器,需要做数据挂载 注意:启动MySQL 需要配置密码的
#官方测试:docker run --name some-mysql -e MYSQL_ROOT_PASSWORD="PASSWORD" -d mysql:tag
#启动我们的 -d 后台运行 -v 数据挂载 -p端口映射 -e 环境配置 -name 容器名称
[root@dinosaur home]# docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=12345xiaoyu --name mysql01 mysql:latest
c1f60ef179d337094fb8cd03d804b7234ca24d040c622349d1fb67edf6da8a10
[root@dinosaur home]# ls
dinosaur mysql www
[root@dinosaur home]# cd mysql/
[root@dinosaur mysql]# ls
conf data
#启动成功之后,可以在本地使用 navicat 测试一下
#使用 docker inspect 查看一下容器状态,发现也已挂载成功
"Mounts": [
{
"Type": "bind",
"Source": "/home/mysql/data",
"Destination": "/var/lib/mysql",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
{
"Type": "bind",
"Source": "/home/mysql/conf",
"Destination": "/etc/mysql/conf.d",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
]
#我们将容器删除,本地的数据也不会丢失
[root@dinosaur mysql]# docker rm -f mysql01
mysql01
[root@dinosaur mysql]# ls
conf data
具名挂载和匿名挂载
#匿名挂载 -v 容器路径
[root@dinosaur home]# docker run -d -p --name nginx01 -v /etc/nginx nginx
#查看所有的 volume 的情况
[root@dinosaur mysql]# docker volume ls
local 9aj4ae9asd564dasdae856d2as3d4567g856rfedg56b
#这种就是匿名挂载,我们在-v只写了容器内路径,没有写容器外路径!
#具名挂载 -v 卷名:容器路径
[root@dinosaur home]# docker run -d -p --name nginx02 -v juming-nginx:/etx/nginx nginx
bb35daaf1bdd0e004433cfa703baaf84230faf12221913e348aef1a826f025b0
[root@dinosaur mysql]# docker volume ls
DRIVER VOLUME NAME
local juming-nginx
#查看一下这个卷
[root@dinosaur mysql]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2020-10-17T13:17:44+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
#进去看一下
[root@dinosaur mysql]# cd /var/lib/docker/
[root@dinosaur docker]# ls
builder buildkit containers image network overlay2 plugins runtimes swarm tmp trust volumes
[root@dinosaur docker]# cd volumes
[root@dinosaur volumes]# ls
juming-nginx metadata.db
[root@dinosaur volumes]# cd juming-nginx/
[root@dinosaur juming-nginx]# ls
_data
所有Docker容器内的卷没指定目录默认都是在 /var/lib/docker/volumes/
下面
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况下使用具名挂载
如何确定是具名、匿名还是指定路径挂载?
-v 容器路径 #匿名挂载
-v 卷名:容器路径 #具名挂载
-v /宿主机路径:容器路径 #指定路径挂载
扩展
# ro:readonly rw:readwrite
#一旦设置了容器权限,容器对我们挂载出来的内容就有限定了
#一旦看到ro,就说明这个路径只能通过宿主机来操作,容器内部无法操作
[root@dinosaur home]# docker run -d -p --name nginx02 -v juming-nginx:/etx/nginx:ro nginx
[root@dinosaur home]# docker run -d -p --name nginx02 -v juming-nginx:/etx/nginx:rw nginx
初识DockerFile
DockerFile就是用来构建 Docker 镜像的构建文件!命令脚本!
通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个一个的命令,每个命令都是一层!
#创建一个 Dockerfile 文件,名字可以随机建议Dockerfile
#官方命名即为Dockerfile,这样命名后docker build命令可以不用指定 -f
#文件中的内容 指令(大写) 参数
FROM centos
VOLUME ["volume01","volume02"] #匿名挂载
CMD echo "---end---"
CMD /bin/bash
#这里的每一个命令就是镜像的一层
#构建过程
[root@dinosaur home]# docker build -f /home/dockerfile -t myimage/centos:1.0 .
Sending build context to Docker daemon 366.7MB
Step 1/4 : FROM centos
---> 0d120b6ccaa8
Step 2/4 : VOLUME ["volume01","volume02"]
---> Running in 1ba0c6a5f7ec
Removing intermediate container 1ba0c6a5f7ec
---> cb0c8b1207f4
Step 3/4 : CMD echo "---end---"
---> Running in 9ad4e7d1b7ed
Removing intermediate container 9ad4e7d1b7ed
---> ce23761bb67b
Step 4/4 : CMD /bin/bash
---> Running in 42c4f7697389
Removing intermediate container 42c4f7697389
---> c8c5f5c3fd79
Successfully built c8c5f5c3fd79
Successfully tagged myimage/centos:1.0
[root@dinosaur home]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myimage/centos 1.0 c8c5f5c3fd79 6 seconds ago 215MB
centos latest 0d120b6ccaa8 2 months ago 215MB
#运行自己的镜像,发现其内有我们新建的两个目录volume01与volume02
#这两个目录就是我们生成镜像时候自动挂载的数据卷目录,这两个卷和外部一定有同步的目录!
[root@dinosaur home]# docker run -it c8c5f5c3fd79
[root@54ef9d9ab7d8 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
#验证
[root@dinosaur home]# docker inspect 54ef9d9ab7d8
"Mounts": [
{
"Type": "volume",
"Name": "41f03054a2b60e0d085b6befe9dc6aacbfd585f7e1a95c194f59015b14b8d232",
"Source": "/var/lib/docker/volumes/41f03054a2b60e0d085b6befe9dc6aacbfd585f7e1a95c194f59015b14b8d232/_data",
"Destination": "volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "0dc40c2ccefa5933a1c6ac7e7eac9d410b34e116bb811fa921d89dcfb8a8c2f4",
"Source": "/var/lib/docker/volumes/0dc40c2ccefa5933a1c6ac7e7eac9d410b34e116bb811fa921d89dcfb8a8c2f4/_data",
"Destination": "volume02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
这种方式未来使用的非常多,因为我们通常会构建自己的镜像
假设构建镜像的时候没有挂载卷,那就要手动具名挂载(常用)
数据卷容器
多个MySQL之间同步数据!
#启动一个容器docker01
[root@dinosaur ~]# docker run -it --name docker01 myimage/centos:1.0
[root@da16c627d338 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
#在docker01的数据卷volume01下创建文件docker01
[root@da16c627d338 /]# touch volume01/docker01
#启动docker02 通过 --volumes-from 继承数据卷容器docker01的数据卷
[root@dinosaur ~]# docker run -it --name docker02 --volumes-from docker01 myimage/centos:1.0
[root@3eedf985ddad /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
#在docker02中可以看到在docker01中添加的文件docker01
[root@3eedf985ddad /]# cd volume01
[root@3eedf985ddad volume01]# ls
docker01
#使用docker inspect来查看一下两个容器的挂载,发现挂载在了宿主机的相同目录
"Mounts": [
{
"Type": "volume",
"Name": "6ddd33d326a17fb7fccc059c6bcf52635efeb43ee22c04d9ea091a85be9ca199",
"Source": "/var/lib/docker/volumes/6ddd33d326a17fb7fccc059c6bcf52635efeb43ee22c04d9ea091a85be9ca199/_data",
"Destination": "volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "1830357c3beb6e218c366747bb92916c219b38aac6a6aacc1f67a2335f5f46fa",
"Source": "/var/lib/docker/volumes/1830357c3beb6e218c366747bb92916c219b38aac6a6aacc1f67a2335f5f46fa/_data",
"Destination": "volume02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
]
DockerFile
DockerFile介绍
dockerfile是用来构建Docker镜像的文件,是个命令参数脚本!
构建步骤
- 编写一个 dockerfile 文件
- docker build 构建成为一个镜像
- docker run 运行镜像
- docker push 发布镜像(DockerHub | 阿里云镜像仓库)
DockerFile构建过程
基础知识
- 每个保留关键字(指令)都必须是大写字母
- 指令是从上到下顺序执行的,#表示注释
- 每一个指令都会创建一个新的镜像层,并且提交
dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!
Docker镜像逐渐成为企业交付的标准
DockerFile:构建文件,定义了一切的步骤,源代码
DockerImages:通过 DockerFile 构建生成的镜像,最终发布和运行的产品,(原来是 jar,war)
DockerContainer:容器就是镜像运行起来提供服务的
DockerFile的指令
FROM #基础镜像,一切从这里开始构建
MAINTAINER #镜像是谁写的 姓名 + 邮箱
RUN #镜像构建的时候需要运行的命令
ADD #其他镜像的压缩包 添加内容
WORKDIR #镜像的工作目录
VOLUME #挂载的目录
EXPOSE #暴露端口配置
CMD #指定容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT #指定容器启动的时候要运行的命令,可以追加命令
ONBUILD #当构建一个被继承的 DockerFile 时候运行 ONBUILD 指令 为触发指令
COPY #类似ADD,将我们的文件拷贝到镜像中
ENV #构建的时候设置环境变量
实战测试
DockerHub中 99% 的镜像都是从这个基础镜像过来的 FROM scratch,然后配置需要的软件和配置来进行构建
创建一个自己的centos
#编写Dockerfile文件
[root@dinosaur dockerfile]# vim mydockerfile-centos
[root@dinosaur dockerfile]# cat mydockerfile-centos
FROM centos
MAINTAINER dinosaur<1098301679@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH$
RUN yum -y install vim
EXPOSE 80
CMD echo $MYPATH$
CMD echo "---end---"
CMD /bin/bash
#通过这个文件构建镜像
[root@dinosaur dockerfile]# docker build -f mydockerfile-centos -t mycentos:0.1 .
Successfully built df7b7a1d7892
Successfully tagged mycentos:0.1
[root@dinosaur dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 0.1 df7b7a1d7892 18 seconds ago 294MB
centos latest 0d120b6ccaa8 2 months ago 215MB
列出镜像的变更历史 docker history
[root@dinosaur dockerfile]# docker history df7b7a1d7892
IMAGE CREATED CREATED BY SIZE COMMENT
df7b7a1d7892 3 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B
b7af65268483 3 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
599ea5c3b05f 3 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
e218bdcea352 3 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B
e4bdd33d9623 3 minutes ago /bin/sh -c yum -y install vim 48.1MB
f62e40fe5dfd 3 minutes ago /bin/sh -c yum -y install net-tools 31.3MB
6d4cce81cd5f 4 minutes ago /bin/sh -c #(nop) WORKDIR /usr/local$ 0B
99e51e3bc386 4 minutes ago /bin/sh -c #(nop) ENV MYPATH=/usr/local 0B
776b1bc6d0ff 4 minutes ago /bin/sh -c #(nop) MAINTAINER dinosaur<10983… 0B
0d120b6ccaa8 2 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 2 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 2 months ago /bin/sh -c #(nop) ADD file:538afc0c5c964ce0d… 215MB
[root@dinosaur dockerfile]# docker history 0d120b6ccaa8
IMAGE CREATED CREATED BY SIZE COMMENT
0d120b6ccaa8 2 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 2 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 2 months ago /bin/sh -c #(nop) ADD file:538afc0c5c964ce0d… 215MB
CMD 和 ENTRYPOINT 区别
CMD 指定容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT 指定容器启动的时候要运行的命令,可以追加命令
CMD测试
#编写dockerfile文件
[root@dinosaur dockerfile]# vim cmdtest
FROM centos
CMD ["ls","-a"]
#构建镜像并运行
[root@dinosaur dockerfile]# docker build -f cmdtest -t cmdtest .
Successfully built 6e8fb1fca17e
Successfully tagged cmdtest:latest
[root@dinosaur dockerfile]# docker run cmdtest
.
..
.dockerenv bin dev etc
home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
#想追加一个命令 -l ls -al
[root@dinosaur dockerfile]# docker run cmdtest -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"-l\": executable file not found in $PATH": unknown.
#cmd的清理下 -l 替换了CMD ["ls","-a"]命令 -l 不是命令所以报错
ENTRYPOINT测试
[root@dinosaur dockerfile]# vim entrypointtest
FROM centos
ENTRYPOINT ["ls","-a"]
[root@dinosaur dockerfile]# docker build -f entrypoingtest -t entrypointtest .
Successfully built 7330d80bd6e6
Successfully tagged entrypointtest:latest
#我们的追加命令是直接在ENTRYPOINT命令后面的
[root@dinosaur dockerfile]# docker run entrypointtest -l
total 0
drwxr-xr-x 1 root root 6 Oct 17 12:21 .
drwxr-xr-x 1 root root 6 Oct 17 12:21 ..
-rwxr-xr-x 1 root root 0 Oct 17 12:21 .dockerenv
lrwxrwxrwx 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x 5 root root 340 Oct 17 12:21 dev
drwxr-xr-x 1 root root 66 Oct 17 12:21 etc
drwxr-xr-x 2 root root 6 May 11 2019 home
........................................................................................................
实战:Tomcat镜像
1、准备镜像文件 tomcat 压缩包,jdk的压缩包
[root@dinosaur mytomcat]# ll
总用量 197452
-rw-r--r-- 1 root root 11282879 10月 17 23:11 apache-tomcat-9.0.39.tar.gz
-rw-r--r-- 1 root root 190903410 10月 17 23:13 jdk-14.0.2_linux-x64_bin.tar.gz
2、编写 dockerfile 文件,官方命名Dockerfile
,在 build 的时候就会自动寻找这个文件,就不需要 -f 指定了
[root@dinosaur mytomcat]# vim Dockerfile
FROM centos
MAINTAINER dinosaur<1098301679@qq.com>
COPY readme.txt /usr/local/readme.txt
ADD jdk-14.0.2_linux-x64_bin.tar.gz /usr/local/
ADD apache-tomcat-9.0.39.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.39
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.39
ENV PATH $PATH:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.39/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.39/bin/logs/catalina.out
3、构建镜像
[root@dinosaur mytomcat]# docker build -t mytomcat .
Successfully built c246353540cd
Successfully tagged mytomcat:latest
[root@dinosaur mytomcat]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mytomcat latest c246353540cd About a minute ago 616MB
centos latest 0d120b6ccaa8 2 months ago 215MB
4、启动镜像
[root@dinosaur mytomcat]# ls
apache-tomcat-9.0.39.tar.gz Dockerfile jdk-14.0.2_linux-x64_bin.tar.gz readme.txt test tomcatlogs
[root@dinosaur mytomcat]# docker run -d -p 8080:8080 --name dinosaurtomcat -v /home/mytomcat/test:/usr/local/apache-tomcat-9.0.39/webapps/test -v /home/mytomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.39/logs mytomcat
583a9dfa6b5ac6ba06bd70d877cd6687bd996ce38f382b82c9e4c9d78f614653
5、发布项目(由于做了卷挂载,可以直接在本地上传项目)
//web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>Dinosaur project</display-name>
</web-app>
//index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<title>lsp</title>
</head>
<body>
<p>asdasd</p>
</body>
</html>
6、访问测试 test 项目
[root@dinosaur ~]# curl localhost:9090/test/index.jsp
<html>
<head>
<title>lsp</title>
</head>
<body>
<p>asdasd</p>
</body>
</html>
发布自己的镜像
Docker Hub
1、在官网 https://hub.docker.com/ 上注册自己的账号
2、在服务器上提交自己的镜像
[root@dinosaur ~]# docker login --help
Usage: docker login [OPTIONS] [SERVER]
Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.
Options:
-p, --password string Password
--password-stdin Take the password from stdin
-u, --username string Username
[root@dinosaur ~]# docker login -u 1098301679
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
3、登录完毕后就可以提交镜像了,就是一步 —— docker push
[root@dinosaur ~]# docker tag 79ae 1098301679/mytomcat
[root@dinosaur ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
1098301679/mytomcat latest 79ae42606fb1 11 hours ago 616MB
mytomcat 1.0 79ae42606fb1 11 hours ago 616MB
mytomcat latest 79ae42606fb1 11 hours ago 616MB
centos latest 0d120b6ccaa8 2 months ago 215MB
[root@dinosaur ~]# docker push 1098301679/mytomcat
The push refers to repository [docker.io/1098301679/mytomcat]
359b8fefae21: Pushing [=============> ] 15.1MB/57.24MB
44cfa82272e2: Pushing [==========================> ] 8.134MB/15.63MB
6c15c70076c1: Pushing [> ] 6.106MB/327.7MB
9de8ef656890: Pushed
291f6e44771a: Pushing [==> ] 12.01MB/215.1MB
#提交的时候也是一层一层的提交的
阿里云镜像服务
1、登录阿里云
2、找到容器镜像服务
3、创建命名空间
4、创建镜像仓库
5、照着文档写的做
小结
Docker网络
理解Docker0
测试ip addr
三个网络
问题:Docker 是如何处理容器网络访问的?
[root@dinosaur ~]# docker run -d -P --name tomcat01 tomcat
#查看容器的内部网络地址 ip addr 发现容器启动的时候会得到一个 eth0@if91 ip地址,docker分配的!
[root@dinosaur ~]# docker exec -it tomcat01 ip addr
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
90: eth0@if91: <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
#思考:Linux能不能ping通容器内部
[root@dinosaur ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.115 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.076 ms
#Linux可以ping通容器内部
原理
我们每启动一个 Docker 容器,Docker 就会给 Docker 容器分配一个 ip ,我们只要安装了 Docker,就会有一个网卡Docker0桥接模式,使用的技术是 veth-pair 技术!
再次测试 ip addr
再启动一个容器测试
我们发现容器带来的网卡,都是一对一对的
veth-pair 就是一对的虚拟设备接口,成对出现,一端连着协议,一端彼此相连
正因为有这个特性, veth-pair充当一个桥梁,连接各种虚拟网络设备
容器间相互ping - 可以ping通
[root@dinosaur ~]# docker exec -it tomcat01 ping 127.0.0.3
PING 127.0.0.3 (127.0.0.3) 56(84) bytes of data.
64 bytes from 127.0.0.3: icmp_seq=1 ttl=64 time=0.033 ms
64 bytes from 127.0.0.3: icmp_seq=2 ttl=64 time=0.031 ms
tomcat01 与 tomcat02 公用一个路由器:docker0
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用 IP
Docker使用的是 Linux 的桥接,宿主机中是一个 Docker 容器的网桥 docker0
Docker中所有的网络接口都是虚拟的,虚拟的转发效率高!
只要容器删除,对应的一堆网桥就没了!
–link
思考一个场景:我们编写了一个微服务,database url=ip:
项目不重启,数据库 ip 换掉了,我们希望可以用容器名字来访问容器
[root@dinosaur ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known
#如何解决呢? --link
[root@dinosaur ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known
[root@dinosaur ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
e2049995e9a599f62480fd3b4131b359d8054db9876d91562a89cea64a6e8936
[root@dinosaur ~]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.152 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.112 ms
#可以看到成功的ping通
#那反向能够ping通吗?
[root@dinosaur ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known
探究docker0
[root@dinosaur ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
e34da6dc2442 bridge bridge local
8d2f39d313bc host host local
#发现其内的Containers信息!
[root@dinosaur ~]# docker network inspect e34da6dc2442
"Containers": {
"8e4875b09a86301f65bbb7157f98817c0470807852b40f858cc2c8dc03980a5f": {
"Name": "tomcat01",
"EndpointID": "fc8a775c182bb3f1504bf5f96ac228d2234ef7d7d9d257acd7eb531990ef76d6",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
},
"bf5b9cd64cff0dcf5f20d10c686a70b88735ce5de207eee5d3807182be77fd25": {
"Name": "tomcat02",
"EndpointID": "a3216c5f0edb9f9aef0253f381db9acdec41e21aec77f02d3403c04f8d21c083",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"e2049995e9a599f62480fd3b4131b359d8054db9876d91562a89cea64a6e8936": {
"Name": "tomcat03",
"EndpointID": "0b4533c1cf1ef63324519632ede5a182c0cc21b7dec8187837a00f2f5db81e2e",
"MacAddress": "02:42:ac:11:00:04",
"IPv4Address": "172.17.0.4/16",
"IPv6Address": ""
}
},
查看 tomcat03 的 host 配置
[root@dinosaur ~]# docker exec -it tomcat03 cat /etc/hosts
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 tomcat02 bf5b9cd64cff
172.17.0.4 e2049995e9a5
本质:–link 其实就是在 hosts 配置中增加了一个172.17.0.3 tomcat02 bf5b9cd64cff
我们现在使用 Docker 已经不建议使用 --link 了!
自定义网络,不使用 docker0
docker0问题:不支持容器名连接访问!
自定义网络
查看所有的 Docker 网络
[root@dinosaur ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
e34da6dc2442 bridge bridge local
8d2f39d313bc host host local
6b394fe570e4 none null local
网络模式
bridge:桥接 docker (默认,自己创建也使用这个)
none:不配置网络
host:和宿主机共享网络
container:容器内网络联通(用的少!局限很大)
测试
#我们之前直接启动的命名 默认有 --net bridge 就是我们的docker0
[root@dinosaur ~]# docker run -d -P --name tomcat01 --net bridge tomcat
#docker0特点:默认,域名不能访问, --link可以打通
#自定义网络
[root@dinosaur ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
5bd77f33861f8710aa3f60d4de201ea9271d7d25314c21b7194d51f6121f19d7
[root@dinosaur ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
e34da6dc2442 bridge bridge local
8d2f39d313bc host host local
5bd77f33861f mynet bridge local
6b394fe570e4 none null local
#查看mynet
[root@dinosaur ~]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "5bd77f33861f8710aa3f60d4de201ea9271d7d25314c21b7194d51f6121f19d7",
"Created": "2020-10-18T14:31:50.028661585+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
#使用我们自己的网络启动两个容器
[root@dinosaur ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
399532d9a95a03ec7daad7792b7e0fec94d12e71bfc4db9bf5584249b998425d
[root@dinosaur ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
88df9e42910fde45fbb74a5515ed83a96e2f3f4db8e87d210fda76302282d144
#查看网络内Containers
[root@dinosaur ~]# docker network inspect mynet
"Containers": {
"399532d9a95a03ec7daad7792b7e0fec94d12e71bfc4db9bf5584249b998425d": {
"Name": "tomcat-net-01",
"EndpointID": "f020077e74ab0071583e2f337b0d5789b138008f46bc9a2fb927a0f20842b6c2",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
"88df9e42910fde45fbb74a5515ed83a96e2f3f4db8e87d210fda76302282d144": {
"Name": "tomcat-net-02",
"EndpointID": "ccb0978702d32af33833d82796d729c21903e9d11bf7b4c2df9905c64d85843e",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
}
},
#再次测试ping 不使用 --link 也可以ping容器名字
[root@dinosaur ~]# docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.144 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.083 ms
结论:我们自定义的网络 Docker 都已经帮我们维护好了对应的关系,推荐平时这样使用网络!
好处:
redis ——不同的集群使用不同的网络,保证集群是健康和安全的
mysql ——不同的集群使用不同的网络,保证集群是健康和安全的
网络连通
[root@dinosaur ~]# docker network --help
Commands:
connect Connect a container to a network #连接一个容器到一个网络
[root@dinosaur ~]# docker network connect --help
Usage: docker network connect [OPTIONS] NETWORK CONTAINER
Connect a container to a network
Options:
--alias strings Add network-scoped alias for the container
--driver-opt strings driver options for the network
--ip string IPv4 address (e.g., 172.30.100.104)
--ip6 string IPv6 address (e.g., 2001:db8::33)
--link list Add link to another container
--link-local-ip strings Add a link-local address for the container
测试打通 docker0上的容器 tomcat01 -> mynet
[root@dinosaur ~]# docker run -d -P --name tomcat01 tomcat
446c7804cefff48188ef3b76ca59a022f7b875faedd225a5447a52129dc79997
[root@dinosaur ~]# docker network connect mynet tomcat01
[root@dinosaur ~]# docker network inspect mynet
"Containers": {
"399532d9a95a03ec7daad7792b7e0fec94d12e71bfc4db9bf5584249b998425d": {
"Name": "tomcat-net-01",
"EndpointID": "f020077e74ab0071583e2f337b0d5789b138008f46bc9a2fb927a0f20842b6c2",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
"446c7804cefff48188ef3b76ca59a022f7b875faedd225a5447a52129dc79997": {
"Name": "tomcat01",
"EndpointID": "ddee3f0dabe7225002c3ee053be833737de0c55509fdd0ab1ff873ae434410e6",
"MacAddress": "02:42:c0:a8:00:04",
"IPv4Address": "192.168.0.4/16",
"IPv6Address": ""
},
"88df9e42910fde45fbb74a5515ed83a96e2f3f4db8e87d210fda76302282d144": {
"Name": "tomcat-net-02",
"EndpointID": "ccb0978702d32af33833d82796d729c21903e9d11bf7b4c2df9905c64d85843e",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
}
}
#连通之后就是将我们的 tomcat01 放置到我们 mynet 网络下
#一个容器 两个ip地址
#ping
[root@dinosaur ~]# docker exec -it tomcat01 ping tomcat-net-01
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.139 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.110 ms
结论:假设要跨网络操作别人,就需要使用 docker network conect 连通!