当前位置:主页 > 查看内容

当下最火的Docker容器(二)《Java-2021面试谈资系列》

发布时间:2021-06-15 00:00| 位朋友查看

简介:Docker Docker 五、Docker镜像讲解 1.镜像是什么 2.Docker镜像加载原理 3.分层理解 4.commit镜像 六、容器数据卷 1.什么是容器数据卷 2.使用数据卷 3.Mysql数据同步 4.具名和匿名挂载 5.初始Dockerfile 6.数据卷容器 七、DockerFile 1.DockerFile介绍 2.Dock……

Docker

五、Docker镜像讲解

1.镜像是什么

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,他包含运行某个软件所需的所有内容,包括代码、运行时库、环境变量和配置文件。

所有应用,直接打包docker镜像,就可以直接跑起来!

如何得到镜像:

  • 从远程仓库下载
  • 朋友拷贝给你
  • 自己制作

2.Docker镜像加载原理

UnionFS (联合文件系统)

**UnionFs(联合文件系统):**Union文件系统(UnionFs)是一种分层、轻量级并且高性能的文件系统,他支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下( unite several directories into a single virtual filesystem)。Union文件系统是 Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
**特性:**一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

Docker镜像加载原理

Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
**boots(boot file system)😗*主要包含 bootloader和 Kernel, bootloader主要是引导加 kernel, Linux刚启动时会加bootfs文件系统,在 Docker镜像的最底层是 boots。这一层与我们典型的Linux/Unix系统是一样的,包含boot加載器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs转交给内核,此时系统也会卸载bootfs。
rootfs(root file system),在 bootfs之上。包含的就是典型 Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。 rootfs就是各种不同的操作系统发行版,比如 Ubuntu, Centos等等。

img

平时我们安装进虚拟机的CentOS都是好几个G,为什么Docker这里才200M?
在这里插入图片描述
对于个精简的OS,rootfs可以很小,只需要包合最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的Linux发行版, boots基本是一致的, rootfs会有差別,因此不同的发行版可以公用bootfs.

虚拟机是分钟级别,容器是秒级!

3.分层理解

分层的镜像

我们可以去下载一个镜像,注意观察下载的日志输出,可以看到是一层层的在下载
在这里插入图片描述
思考:为什么Docker采用这种分层的结构呢?

最大的好处,我觉得莫过于资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。

查看镜像分层的方式可以通过docker image inspect 命令

[root@zjdzka ~]# docker image inspect redis
[
    {
        "Id": "sha256:621ceef7494adfcbe0e523593639f6625795cc0dc91a750629367a8c7b3ccebb",
        "RepoTags": [
            "redis:latest"
        ],
        "RepoDigests": [
            "redis@sha256:0f97c1c9daf5b69b93390ccbe8d3e2971617ec4801fd0882c72bf7cad3a13494"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2021-01-13T09:45:41.527587343Z",
        "Container": "16535cfaf84a4049b6c02840219e8473787d5610e29409049df3a41bbf77a333",
        "ContainerConfig": {
            "Hostname": "16535cfaf84a",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "6379/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.12",
                "REDIS_VERSION=6.0.10",
                "REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.0.10.tar.gz",
                "REDIS_DOWNLOAD_SHA=79bbb894f9dceb33ca699ee3ca4a4e1228be7fb5547aeb2f99d921e86c1285bd"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"redis-server\"]"
            ],
            "Image": "sha256:222c0cecc006d8c73a04a58b5fa15ebae171a6e82a8ee8650ae616f6f1798ef4",
            "Volumes": {
                "/data": {}
            },
            "WorkingDir": "/data",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {}
        },
        "DockerVersion": "19.03.12",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "6379/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.12",
                "REDIS_VERSION=6.0.10",
                "REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.0.10.tar.gz",
                "REDIS_DOWNLOAD_SHA=79bbb894f9dceb33ca699ee3ca4a4e1228be7fb5547aeb2f99d921e86c1285bd"
            ],
            "Cmd": [
                "redis-server"
            ],
            "Image": "sha256:222c0cecc006d8c73a04a58b5fa15ebae171a6e82a8ee8650ae616f6f1798ef4",
            "Volumes": {
                "/data": {}
            },
            "WorkingDir": "/data",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": null
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 104285909,
        "VirtualSize": 104285909,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/4ea64043cf121b3633eca9ba2cb2a85682c62a1c6f074c501569766c1e0ce945/diff:/var/lib/docker/overlay2/2c49976e43d1f9bb6ce97a8edf287e418e46a99e454ea95a6a443ea2973f18ad/diff:/var/lib/docker/overlay2/782c232af88b85bb60cf2f6e36b958e699367045fe7bea2ac770818270571b1d/diff:/var/lib/docker/overlay2/9606bb1f1b3ff06a56813d192546dd20ed5f9f6fd2384c4b28ed0cdc1becab15/diff:/var/lib/docker/overlay2/42ff0bd2b7e0e2c6cd1a5d856eeca813dd1414fcba4864fb87f62a87344c10a0/diff",
                "MergedDir": "/var/lib/docker/overlay2/a5609f3560fc767cca20491b9814fd52cedbe4a7ce2cd330d04bd320d6f4c5b7/merged",
                "UpperDir": "/var/lib/docker/overlay2/a5609f3560fc767cca20491b9814fd52cedbe4a7ce2cd330d04bd320d6f4c5b7/diff",
                "WorkDir": "/var/lib/docker/overlay2/a5609f3560fc767cca20491b9814fd52cedbe4a7ce2cd330d04bd320d6f4c5b7/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:cb42413394c4059335228c137fe884ff3ab8946a014014309676c25e3ac86864",
                "sha256:8e14cb7841faede6e42ab797f915c329c22f3b39026f8338c4c75de26e5d4e82",
                "sha256:1450b8f0019c829e638ab5c1f3c2674d117517669e41dd2d0409a668e0807e96",
                "sha256:f927192cc30cb53065dc266f78ff12dc06651d6eb84088e82be2d98ac47d42a0",
                "sha256:a24a292d018421783c491bc72f6601908cb844b17427bac92f0a22f5fd809665",
                "sha256:3480f9cdd491225670e9899786128ffe47054b0a5d54c48f6b10623d2f340632"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

理解:

所有的 Docker镜像都起始于一个基础镜像层,当进行修改或培加新的内容时,就会在当前镜像层之上,创建新的镜像层。

举一个简单的例子,假如基于 Ubuntu Linux16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包,
就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创健第三个镜像层该像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。

在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点.

img

在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。

img

上图中的镜像层跟之前图中的略有区別,主要目的是便于展示文件
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版。

img

文种情況下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中

Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统

Linux上可用的存储引撃有AUFS、 Overlay2、 Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于 Linux中对应的
件系统或者块设备技术,井且每种存储引擎都有其独有的性能特点。

Docker在 Windows上仅支持 windowsfilter 一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW [1]。

下图展示了与系统显示相同的三层镜像。所有镜像层堆并合井,对外提供统一的视图。
img

特点

Docker 镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部!

这一层就是我们通常说的容器层,容器之下的都叫镜像层!

img

4.commit镜像

docker commit 提交容器成为一个新的副本

# 命令和git原理类似
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[版本TAG]

实战测试

# 1、启动一个默认的tomcat
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker run -d -p 8080:8080 tomcat
de57d0ace5716d27d0e3a7341503d07ed4695ffc266aef78e0a855b270c4064e

# 2、发现这个默认的tomcat 是没有webapps应用,官方的镜像默认webapps下面是没有文件的!
#docker exec -it 容器id /bin/bash
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker exec -it de57d0ace571 /bin/bash
root@de57d0ace571:/usr/local/tomcat# 

# 3、从webapps.dist拷贝文件进去webapp
root@de57d0ace571:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@de57d0ace571:/usr/local/tomcat# cd webapps
root@de57d0ace571:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager

# 4、将操作过的容器通过commit调教为一个镜像!我们以后就使用我们修改过的镜像即可,而不需要每次都重新拷贝webapps.dist下的文件到webapps了,这就是我们自己的一个修改的镜像。
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]
docker commit -a="zjdzka" -m="add webapps app" 容器id tomcat02:1.0

[root@iz2zeak7sgj6i7hrb2g862z ~]# docker commit -a="csp提交的" -m="add webapps app" de57d0ace571 tomcat02:1.0
sha256:d5f28a0bb0d0b6522fdcb56f100d11298377b2b7c51b9a9e621379b01cf1487e

[root@iz2zeak7sgj6i7hrb2g862z ~]# docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
tomcat02.1.0          latest              d5f28a0bb0d0        14 seconds ago      652MB
tomcat                latest              1b6b1fe7261e        5 days ago          647MB
nginx                 latest              9beeba249f3e        5 days ago          127MB
mysql                 5.7                 b84d68d0a7db        5 days ago          448MB
elasticsearch         7.6.2               f29a1ee41030        8 weeks ago         791MB
portainer/portainer   latest              2869fc110bf7        2 months ago        78.6MB
centos                latest              470671670cac        4 months ago        237MB
hello-world           latest              bf756fb1ae65        4 months ago        13.3kB

如果你想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,就好比我们我们使用虚拟机的快照。

六、容器数据卷

1.什么是容器数据卷?

Docker的理念:将应用和环境打包成一个镜像!

数据?如果都在容器中,那么我们删除容器,数据就会丢失!

数据可以持久化

例如:Mysql,容器删了=删库跑路!===>Mysql的数据可以存储在本地!

**容器之间可以有一个数据共享的技术!**Docker容器中产生的数据,同步到本地!

这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上!
在这里插入图片描述
**总结:**容器的持久化和同步操作!容器间也是可以数据共享的!

2.使用数据卷

方式一:直接使用命令挂载 -v

docker run -it -v 主机目录:容器内目录

#测试绑定数据卷
docker run -it -v /home/ceshi:/home centos /bin/bash

#用另一个会话测试:查看信息
docker inspect a0d694176556

在这里插入图片描述

测试文件同步
在这里插入图片描述
再次测试:

容器关闭,在本地更新文件,再将文件开启,发现数据仍然同步
在这里插入图片描述

3.Mysql数据同步

思考:Mysql的数据持久化问题

#1.获取镜像
docker pull mysql:5.7
#2.运行容器,需要做数据挂载
# -d 后台运行
# -p 端口映射
# -v 卷挂载
# -e 环境配置
#--name 名字
docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

#3.启动成功后,测试连接mysql
#sqlyog-连接到服务器的3310---3310和容器内的3306映射,这个时候,我们就可以连接上!

如果我们将容器删除,我们挂载到本地的数据依旧存在,这就是数据卷持久化!

4.具名和匿名挂载

# 匿名挂载
-v 容器内路径!
docker run -d -p --name nginx01 -v /etc/nginx nginx

#查看所有卷的情况
docker volume ls

#具名挂载
-v 卷名:容器内目录
-v juming-nginx:/etc/nginx

所有的docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxx/_data

#如何确定是哪种形式的挂载?
-v 容器内路径 #匿名
-v 卷名:容器内路径 #具名
-v /宿主机路径/..:容器内路径 #指定路径

扩展:

docker run -d -p -m --name nginx01 -v juming-nginx:/etc/nginx:ro nginx

#ro 或者 rw
ro:read only
rw:read write
#一旦设置了容器权限,容器对我们挂载出来的内容就有限定了!

5.初始Dockerfile

Dockerfile就是用来构建docker镜像的构建文件!-----命令脚本

方式二:通过脚本生成镜像

#1.创建一个docker文件
#2.编写Dockerfile
FROM centos

VOLUME ["volume01","volume02"]

CMD echo "----end----"
CMD /bin/bash

#3.构建镜像

在这里插入图片描述

#4.测试一下自己写的镜像

在这里插入图片描述
这个卷一定和外部有一个同步的目录!

在这里插入图片描述
在这里插入图片描述
测试文件是否同步?
在这里插入图片描述

6.数据卷容器

多个Mysql数据同步!
在这里插入图片描述

#启动三个容器,通过我们自己写的镜像测试

如果把其中一个数据卷删除了,其他数据卷文件依旧存在!
在这里插入图片描述

结论:

容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。

但是一旦你持久化到了本地,本地的数据是不会删除的!

七、DockerFile

1.DockerFile介绍

Dockerfile是用来构建docker镜像文件!

构建步骤:

  • 编写一个dockerfile文件
  • docker build构建成一个镜像
  • docker run 运行镜像
  • docker push 发布镜像(DockerHub、阿里云镜像仓库!)

2.DockerFile构建过程:

基础知识:

1.每个保留关键字(指令)都必须是大写字母

2.执行顺序从上到下

3.#表示注释

4.每一个指令都会创建提交一个新的镜像层,并提交!
在这里插入图片描述
dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!

Docker镜像逐渐成为企业交付的标准!

DockerFile:构建文件,定义了一切的步骤,源代码

DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品

Docker容器:容器就是镜像运行起来提供服务的

3.DockerFile指令

FROM #基础镜像,一切从这里开始
MAINTAINER #镜像的作者,名字+邮箱
RUN #镜像构建的时候运行的命令
ADD #步骤:tomcat镜像,这个tomcat压缩包!添加内容
WORKDIR #镜像的工作目录
VOLUME #挂载的目录
EXPORT #暴露端口配置= -p
CMD #指定容器启动的时候,运行的命令==>只要最后一个会生效,可替代
ENTRYPOINT #指定容器启动的时候,运行的命令==>可以追加命令
ONBUILD #当构建一个被继承DockerFile 这个时候就会运行这个指令,触发指令
COPY #类似ADD,拷贝
ENV #构建的时候,设置环境变量

图示:
在这里插入图片描述

4.实战:构建自己的Centos

第一步:编写dockerfile

[root@zjdzka dockerfile]# vim mydockerfile-centos
[root@zjdzka dockerfile]# cat mydockerfile-centos 
FROM centos
MAINTAINER zjdzka<245821335@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH

RUN yum -y install vim
RUN yum -y install net-tools

EXPOSE 80 

CMD echo $MYPATH
CMD echo "----end----"
CMD /bin/bash

第二步:通过文件构建镜像

[root@zjdzka dockerfile]# docker build -f mydockerfile-centos -t zjdzkacentos:0.1 .

在这里插入图片描述

第三步:测试运行

测试成功!
在这里插入图片描述

我们可以列出本地镜像的历史
在这里插入图片描述
CMD和ENTRYPOINT区别

CMD #指定容器启动的时候,运行的命令==>只要最后一个会生效,可替代
ENTRYPOINT #指定容器启动的时候,运行的命令==>可以追加命令

Dockrfile中很多命令十分相似,我们要对比学习,测试效果!

测试CMD
# 1. 编写dockerfile文件
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# vim dockerfile-cmd-test 
FROM centos
CMD ["ls", "-a"]
 
# 2. 构建镜像
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest .
 
# 3. run运行, 发现我们的ls -a 命令生效
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run ebe6a52bb125
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
 
# 想追加一个命令 -l 变成 ls -al
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run ebe6a52bb125 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\": executable file not found in $PATH": unknown.
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run ebe6a52bb125 ls -l
 
# cmd的情况下 -l替换了CMD["ls", "-a"]命令, -l不是命令,所以报错了
测试ENTRYPOINT
# 1. 编写dockerfile文件
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# vim dockerfile-entrypoint-test 
FROM centos
ENTRYPOINT ["ls", "-a"]
 
# 2. 构建文件
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker build -f dockerfile-entrypoint-test -t entrypoint-test .
 
# 3. run运行 发现我们的ls -a 命令同样生效
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run entrypoint-test
.
..
.dockerenv
bin
dev
etc
home
lib
 
# 4. 我们的追加命令, 是直接拼接到ENTRYPOINT命令的后面的!
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run entrypoint-test -l
total 56
drwxr-xr-x  1 root root 4096 Aug 13 07:52 .
drwxr-xr-x  1 root root 4096 Aug 13 07:52 ..
-rwxr-xr-x  1 root root    0 Aug 13 07:52 .dockerenv
lrwxrwxrwx  1 root root    7 May 11  2019 bin -> usr/bin
drwxr-xr-x  5 root root  340 Aug 13 07:52 dev
drwxr-xr-x  1 root root 4096 Aug 13 07:52 etc
drwxr-xr-x  2 root root 4096 May 11  2019 home
lrwxrwxrwx  1 root root    7 May 11  2019 lib -> usr/lib
lrwxrwxrwx  1 root root    9 May 11  2019 lib64 -> usr/lib64
drwx------  2 root root 4096 Aug  9 21:40 lost+found

5.小结:

在这里插入图片描述

八、Docker网络

1.理解Docker0

  • 清空所有环境

测试
在这里插入图片描述
三个网络

# docker 是如何处理容器的网络访问的?

在这里插入图片描述
测试:

#1.启动tomcat
docker run -d -P --name tomcat01 tomcat
#2.查看容器的内网地址 ip addr
#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
26: eth0@if27: <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通docker容器?
# 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.076 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.042 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.052 ms
#linux可以ping通容器内部

分析原理

1.我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0桥接技术,使用的技术是evth—pair技术!

再次测试ip addr 发现又多了一对网卡
在这里插入图片描述

#我们发现这个容器带来的网卡,都是一对对的
#evth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连
#正因为有这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备的

2.我们测试tomcat01 和tomcat02 是否可以ping通

#测试成功,ping通!
docker exec -it tomcat02 ping 172.17.0.2

在这里插入图片描述

总结:

容器和容器之间是可以互相ping通的!
在这里插入图片描述

  • tomcat01和tomcat02共用的一个路由器:docker0

  • 所有的容器不知道网络的情况下,都是docker0路由的,docker会给我们容器分配一个默认的可用ip

  • 只要容器删除,对应的网桥也随之没了

小结

Docker 使用的是Linux的桥接网卡,宿主机中是一个Docker容器的网桥 docker0。
在这里插入图片描述
Docker中的所有的网络接口都是虚拟的,虚拟的转发效率高!

2.–link

思考一个场景,我们编写了一个微服务,database url=ip:,项目不重启,数据库ip换掉了,我们希望可以处理这个问题:通过名字来访问容器
在这里插入图片描述
我们发现直接ping,并不能解决问题

测试:

[root@zjdzka ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
e1cfed7c63e87d6b74eb0a17fc23270881d9f7258d9bd5497ec5158157176a78
[root@zjdzka ~]# 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.103 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.070 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.085 ms
#发现通过--link就可解决问题,但是反向可以嘛? tomcat02 ping tomcat03
[root@zjdzka ~]# docker exec -it tomcat02 ping tomcat 03
ping: tomcat: Name or service not known
探究:

tomcat03和tomcat02通过–link建立连接,其中发生了什么?
在这里插入图片描述
原理:其实就是在我们的hosts配置中添加了一个映射

docker0问题:不支持容器名连接访问!

3.自定义网络

查看所有的docker网络
在这里插入图片描述

网络模式:

bridge:桥接 docker(默认)

none:不配置网络

host: 和宿主机共享网络

container:容器网络连通(用到少!)

测试:
#w我们直接启动的命令 --net bridge,而这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat

#自定义网络
# --driver bridge
# --subnet 192.168.0.0/16 
# --gateway 192.168.0.1
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

在这里插入图片描述
查看自己的网络配置:

docker network inspect mynet

在这里插入图片描述
将tomcat发布到自己的网络进行测试:

[root@zjdzka ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat  
70cef0b1886e7488e9f1bbcdebcddad27e0c8b95e3008499051977e45a5baaea
[root@zjdzka ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat  
ee6882df470433c46df318634b83f912aabb0c08562e50503f52c7ca5a490a09
[root@zjdzka ~]# docker exec -it tomcat-net-01 ping tomcat-net-02

在这里插入图片描述
我们可以发现这种自定义网络,直接可以ping连接成功!

好处:

redis-不同的集群使用不同的网络,保证集群是安全和健康的

mysql-不同的集群使用不同的网络,保证集群是安全和健康的

4.网络连通

实现这种方式的连通,用啥方法呢?
在这里插入图片描述

测试:
#打通tomcat01---tomcat-net-01
docker network connect mynet tomcat01
#连通之后,将我们的tomcat01放到了mynet网络下

#一个容器两个ip:公网ip,私网ip

在这里插入图片描述

docker exec -it tomcat01 ping tomcat-net-01

在这里插入图片描述

;原文链接:https://blog.csdn.net/zjdzka/article/details/115601709
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文


随机推荐