K8S系列文章 之 容器网络基础 Docker0

这篇具有很好参考价值的文章主要介绍了K8S系列文章 之 容器网络基础 Docker0。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

什么是Docker0

使用ip addr命令看一下网卡:

root@KitDevVps:~# 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
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet xxx.xxx.xxx.xxx/23 brd xxx.xxx.xxx.xxx scope global dynamic ens3
       valid_lft 55158sec preferred_lft 55158sec
    inet6 xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/64 scope global dynamic mngtmpaddr noprefixroute 
       valid_lft 2591896sec preferred_lft 604696sec
    inet6 xxxx::xxxx:xxxx:xxxx:xxxx/64 scope link 
       valid_lft forever preferred_lft forever
3: ens7: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:8c:85:1a:f3 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:8cff:fe85:1af3/64 scope link 
       valid_lft forever preferred_lft forever
30: vethxxcaxxa@if29: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 xxxx::xxxx:xxxx:xxxx:xxxx/64 scope link 
       valid_lft forever preferred_lft forever

其中lo是本地回环地址,docker0就是docker0地址,也就是docker的地址172.17.0.1。

docker使用的是桥接模式,使用的技术是evth-pair技术,后面会解释。

Docker如何处理容器的网络访问

比如有两个容器,容器A要去访问容器B,该如何访问?使用127.0.0.1吗?还是写docker0地址?

我们运行起一个centos01来,并且在它内部执行命令ip addr

root@KitDevVps:~# docker run -d -it --name centos01 centos
d07fb4674ffe04e7ef60540485c1c890faccffeb8f40c401ccf59965f1cb8760
root@KitDevVps:~# docker sp
docker: 'sp' is not a docker command.
See 'docker --help'
root@KitDevVps:~# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
d07fb4674ffe        centos              "/bin/bash"              7 seconds ago       Up 6 seconds                             centos01
1cdd55fd90c5        nginx               "/docker-entrypoint.…"   2 days ago          Up 47 hours         0.0.0.0:80->80/tcp   nginx1
root@KitDevVps:~# docker exec -it centos01 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
115: eth0@if116: <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

可以看到里面除了lo之外还有个115: eth0@if116,这是什么东西?可以发现我们每个容器启动的时候会得到一个eth0,这个容器就是eth0@if116,这是Docker给它分配的。

尝试在本机能否ping通容器内部,我们在本地ping一下eth0@if116,也就是172.17.0.3:

root@KitDevVps:~# ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.104 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.093 ms
64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.076 ms
64 bytes from 172.17.0.3: icmp_seq=4 ttl=64 time=0.073 ms
64 bytes from 172.17.0.3: icmp_seq=5 ttl=64 time=0.087 ms
...
...
^C
--- 172.17.0.3 ping statistics ---
22 packets transmitted, 22 received, 0% packet loss, time 21508ms
rtt min/avg/max/mdev = 0.064/0.085/0.114/0.019 ms

发现是可以ping通的。现在已经得知主机可以ping通容器,那容器能否ping通容器?再run一个centos02试试:

root@KitDevVps:~# docker exec -it centos02 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
117: eth0@if118: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
failed to resize tty, using default size

用它来ping centos01(172.17.0.3):

[root@1ebe741425b2 /]# ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.103 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.112 ms
64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.075 ms
64 bytes from 172.17.0.3: icmp_seq=4 ttl=64 time=0.089 ms
64 bytes from 172.17.0.3: icmp_seq=5 ttl=64 time=0.108 ms
64 bytes from 172.17.0.3: icmp_seq=6 ttl=64 time=0.146 ms
64 bytes from 172.17.0.3: icmp_seq=7 ttl=64 time=0.076 ms
^C
--- 172.17.0.3 ping statistics ---
7 packets transmitted, 7 received, 0% packet loss, time 129ms
rtt min/avg/max/mdev = 0.075/0.101/0.146/0.024 ms

到现在,docker0的地址是172.17.0.1,centos01的地址是172.17.0.3,centos02的地址是172.17.0.4。docker0就像是一个路由器,centos01和02就像是路由器下的设备,它们在同一个网段内,可以互相ping通。

此时再在本机使用ip addr

K8S系列文章 之 容器网络基础 Docker0,网络,kubernetes,linux

发现多了两个这种网卡,而我们run起来的centos01和02的网卡分别为 115: eth0@if116 和
117: eth0@if118。它们似乎有某种关联。

可以发现容器的网卡都是一对一对的,这就是前面说的evth-pair技术。evth-pair就是一对虚拟设备接口,它们都是成对出现的,一端连着协议,一端彼此相连,所以可以通信。evth-pair可以充当一个桥梁。

K8S系列文章 之 容器网络基础 Docker0,网络,kubernetes,linux

这是B站up主狂神画的简单示意图,本来linux是ping不通容器的,但利用evth-pair在两边都搞了一个接口,接口通过一种协议可以通信,所以相当于架了一个桥,让它们可以通信。

K8S系列文章 之 容器网络基础 Docker0,网络,kubernetes,linux

两个容器看似是直接ping通的,实际是通过docker0来ping通的。docker0就像路由器,每run出一个容器来,就把它的地址在这个路由器上注册。

K8S系列文章 之 容器网络基础 Docker0,网络,kubernetes,linux

--link与docker network

如果服务宕机重启,分配的ip地址发生了改变,如何进行通信?最好是可以不指定ip地址,而使用服务名称这个标识来进行通信。比如有很多mssql服务,服务名就叫mssql,但它们的ip地址都不一样,如果可以通过服务名来ping,就很好了。一个服务挂了重启,整个项目就不用重启。就是做到项目不重启,还能把数据库替换掉。因为docker重启是会更换ip的。我们希望能够通过名字访问,解决这个问题。

可以通过比较老的--link来解决。

先尝试centos01能否直接通过名字ping通centos02:

root@KitDevVps:~# docker exec -it centos01 ping centos02
ping: centos02: Name or service not known

是ping不通的。我们将两个网络进行连接就可以解决了。我们run一个centos03,使用--link连接上centos02,然后直接在centos03中ping centos02这个名字:

root@KitDevVps:~# docker run -d -it --name centos03 --link centos02 centos
ad50e83c3041eb76d4905670a8cc91bc23c60d3933b5d5f51f702983e9f5711d
root@KitDevVps:~# docker exec -it centos03 ping centos02
PING centos02 (172.17.0.4) 56(84) bytes of data.
64 bytes from centos02 (172.17.0.4): icmp_seq=1 ttl=64 time=0.146 ms
64 bytes from centos02 (172.17.0.4): icmp_seq=2 ttl=64 time=0.097 ms
64 bytes from centos02 (172.17.0.4): icmp_seq=3 ttl=64 time=0.128 ms
64 bytes from centos02 (172.17.0.4): icmp_seq=4 ttl=64 time=0.097 ms
^C
--- centos02 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 45ms
rtt min/avg/max/mdev = 0.097/0.117/0.146/0.021 ms

发现是可以ping通的。但是02ping不通03:

root@KitDevVps:~# docker exec -it centos02 ping centos03
ping: centos03: Name or service not known

因为centos02根本不知道centos03是什么东西,没有给它配置。想让02ping通03,肯定要对02进行一些配置。

我们使用命令docker network ls来查看当前的网络。先看一下docker network怎么用:

root@KitDevVps:~# docker network -h
Flag shorthand -h has been deprecated, please use --help

Usage:	docker network COMMAND

Manage networks

Commands:
  connect     Connect a container to a network
  create      Create a network
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks

Run 'docker network COMMAND --help' for more information on a command.

然后docker network ls

root@KitDevVps:~# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
1375b7ef4bbc        bridge              bridge              local
b29eab4db971        host                host                local
acfcd6eaf888        none                null                local

可以看到上面有个bridge,我们可以使用docker network inspect 1375b7ef4bbc来查看这个bridge的详细信息:

root@KitDevVps:~# docker network inspect 1375b7ef4bbc

...

"Name": "bridge",
        "Id": "1375b7ef4bbcf53a812fc8397787f17f2b47ea412292daea3324e016c48f5738",
        "Created": "2020-07-03T02:06:46.264143987Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
"Containers": {
    "1cdd55fd90c550de6b2ad1544df5ae08b50c85d06d2a9f2e416bf0dbd0ac164d": {
        "Name": "nginx1",
        "EndpointID": "16c89d4f905cb8437a5a539064358a37d6ca09e46d5af653db09e639d2ff56ef",
        "MacAddress": "02:42:ac:11:00:02",
        "IPv4Address": "172.17.0.2/16",
        "IPv6Address": ""
    },
    "1ebe741425b2c80226fe265d170ed0567a6321ea7d7c4b3f4ab787985b2a6308": {
        "Name": "centos02",
        "EndpointID": "6f468d178b612079095203cd0df4e58705069ead019ab72011646259dac67cec",
        "MacAddress": "02:42:ac:11:00:04",
        "IPv4Address": "172.17.0.4/16",
        "IPv6Address": ""
    },
    "ad50e83c3041eb76d4905670a8cc91bc23c60d3933b5d5f51f702983e9f5711d": {
        "Name": "centos03",
        "EndpointID": "f54109b911f200c1afaad50d5459bb67a778fd5e64358f6344d2891e463d0598",
        "MacAddress": "02:42:ac:11:00:05",
        "IPv4Address": "172.17.0.5/16",
        "IPv6Address": ""
    },
    "d07fb4674ffe04e7ef60540485c1c890faccffeb8f40c401ccf59965f1cb8760": {
        "Name": "centos01",
        "EndpointID": "89a3ea298b219971b9aa477efe67506e333a4d410083d56659fce3a6edbc259e",
        "MacAddress": "02:42:ac:11:00:03",
        "IPv4Address": "172.17.0.3/16",
        "IPv6Address": ""
    }
},

...

可以看到上面这一部分的containers中有我们正在运行的所有容器和他们的ip。运行容器不指定ip的时候它就会随机分配一个ip。

docker03实际上就是在本地配置了docker02的配置。

然后我们使用docker inspect 容器id来查看我们的centos03,因为我们用它link了02,我们看一下03里面有没有什么link的线索:

结果我就不放了,因为没有什么线索。

我们cat一下03中的/etc/hosts文件,看看是不是在这里面配置了。这个就跟windows的hosts文件性质是一样的:

root@KitDevVps:~# docker exec -it centos03 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.4	centos02 1ebe741425b2
172.17.0.5	ad50e83c3041

在倒数第二行我们看到了centos02和它的ip地址以及它的id。这样我们就了解它的原理了,直接写在了hosts文件中,所以我们ping centos02或者02的id,可以直接ping到。02中的hosts文件是没有03的,我们可以手动写入,但这样就要重启容器才能生效,太麻烦,不弄了。

实际上这种--link的方式已经不推荐使用了。docker0不支持容器名,我们需要自定义网络,不使用docker0。文章来源地址https://www.toymoban.com/news/detail-630966.html

到了这里,关于K8S系列文章 之 容器网络基础 Docker0的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • K8S系列文章之 部署MySQL数据库

    1 编写 mysql.yaml文件 2 执行如下命令创建 3 通过如下命令查看创建结果 使用如下命令查看 如: [root@master ~]# kubectl get pod -n devops | grep mysql devops-mysql-59b68c47d4-ttbng               1/1     Running   0          23h [root@master ~]# 4 命令行进入Pod并登录mysql 至此,数据库已经安装完成,

    2024年02月11日
    浏览(50)
  • K8S系列文章之 Docker安装使用Kafka

    通过Docker拉取镜像的方式进行安装 照例先去DockerHub找一下镜像源,看下官方提供的基本操作(大部分时候官方教程比网上的要清晰一些,并且大部分教程可能也是翻译的官方的操作步骤,所以直接看官方的就行) 老实说Kafka的参数配置项太多了,比较繁琐。 如果是Linux环境下

    2024年02月13日
    浏览(41)
  • K8S系列文章之 开源的堡垒机 jumpserver

    一、jumpserver作为一款开源的堡垒机,不管是企业还是个人,我觉得都是比较合适的,而且使用也比较简单。 二、这里记录一下安装和使用过程。 1、安装,直接docker不是就行 目前没有看到3版本的,3版本的功能更加强大,可以官网学习一下。 2、使用 资产添加不用细讲,主要

    2024年02月14日
    浏览(42)
  • K8S系列文章之 Shell批处理脚本应用

    1、批处理脚本介绍 命令批处理脚本:/usr/shell/all.sh 文件批量分发脚本:/usr/shell/scp.sh 2、 批处理命令脚本原理 读取/usr/shell/hosts文件中的ip列表 使用$*接收脚本所有参数 for循环遍历hosts文件中的ip地址 通过ssh host cmd 实现目的ip命令 eval命令判断并打印命令执行结果 for循环遍历

    2024年02月13日
    浏览(42)
  • K8S系列文章之 自动化运维利器 Fabric

    Fabric 主要用在应用部署与系统管理等任务的自动化,简单轻量级,提供有丰富的 SSH 扩展接口。在 Fabric 1.x 版本中,它混杂了本地及远程两类功能;但自 Fabric 2.x 版本起,它分离出了独立的 Invoke 库,来处理本地的自动化任务,而 Fabric 则聚焦于远程与网络层面的任务。 为了

    2024年02月14日
    浏览(66)
  • K8S系列文章之 自动化运维利器 Ansible

    第一步:安装我们的epel扩展源 我这里会报/var/run/yum.pid 已被锁定,如果没有直接进行下一步 解决方法:删除/var/run/yum.pid,即 rm -rf /var/run/yum.pid ,重新执行第一步 第二步:安装 ansible 如果还报/var/run/yum.pid 已被锁定,还是直接进行删除,然后重新执行 yum -y install ansible 第三

    2024年02月13日
    浏览(69)
  • K8S系列文章之 离线安装自动化工具Ansible

    参考 文档 离线安装 Ansible - DevOps - dbaselife 一、Ansible简介 Ansible是一款开源的IT配置管理工具,常被IT界的小伙伴们用于自动化的场景,多用在服务部署、配置管理方面。配置文件采用最常见的yaml格式,学习起来也是比较容易,Ansible并不需要也没有agent,只有一个控制端。该

    2024年02月14日
    浏览(52)
  • 微服务系列文章之 Springboot应用在k8s集群中配置的使用

    Docker部署其实也可以再docker run或者dockerfile里面,将配置文件目录映射到宿主机,然后通过宿主机配置文件修改参数。 很多时候Dockerfile文件中需要定义变量,减少对Dockerfile文件的修改,在编译的时候从外部传入参数,这种情况可使用  ARG 参数,然后通过 --build-arg 进行赋值。

    2024年02月16日
    浏览(39)
  • 【K8S系列】深入解析k8s网络之—网络故障

    你只管努力,其他交给时间,时间会证明一切。 文章标记颜色说明: 黄色 :重要标题 红色 :用来标记结论 绿色 :用来标记一级论点 蓝色 :用来标记二级论点 Kubernetes (k8s) 是一个容器编排平台,允许在容器中运行应用程序和服务。今天学习一下k8s网络故障相关的的内容

    2024年02月08日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包