Docker进阶(容器数据卷起)

容器数据卷


什么是容器数据卷

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 连通!

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大恐龙的小弟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值