docker基础篇(一)补

  经过一个星期的加班到9点,终于将docker的网络部分小小的总结了一下,小编在这之前也发布过关于docker的内容,本来想就此结束,但是总感觉少了些什么,只会docker的命令,仿佛不能深入的理解docker强大之处,所以小编决定在补充一下关于docker的网络部分,包括docker的网络模式、容器通信、以及相应的实战操作。虽然这部分有些难以理解,但是细细研读之后,一定会有所收获。

1.docker的网络模式

  安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络,也就是在不使用--network参数时)、 none 、host。还有以后一种自定义模式,自定义模式有三种:bridge、overlay、macvlan。
我们可以使用一下命令,查看本机容器间通信的几种方式:

 docker network ls


  我们可以在docker run的时候使用--net= none/ host/ bridge来设置容器具体使用哪种模式。

(1)默认网络通信模式bridge网桥

  默认情况下docker运行容器时,宿主机会创建一个bridge网桥,是一个名叫docker 0的虚拟网桥 ,默认docker 0 IP为172.17.0.1,网桥再给容器分配虚拟子网IP,并且以网桥IP作为网关。在不指定网络的情况下,容器之间的通信都是通过bridge网桥进行通信。然后网桥在与宿主机镜像进行IP转换,端口映射等通信。
  这种bridge网桥与容器,与宿主机之间的通信,有点类似与三层路由交换:
    

(2) host宿主机模式

  如果容器指定网络模式为host,容器不会有自己的network namespace,而是和宿主机共用一个network网络及IP,容器不会有虚拟出自己的网卡、IP等,当然除了网络通信这一块和宿主机绑定了,其余的容器内容还是和宿主机安全隔离了。这种在做容器迁移时,很不方便,不推荐使用。

(3) none模式

  容器指定网络模式-net为none时,docker容器不再拥有自己的network namespace,但是所有网络配置都得自行配置,如IP、网卡等,这种方式很麻烦。(关闭了容器的网络功能)

这里补充两个docker服务运行时参数
-b BRIDGE or--bridge=BRIDGE ——指定容器挂载的网桥;
--fixed-cidr=10.200.55.64/26 #定制容器的IP地址范围

2.单机间的容器通信

  单机间的通信,就是同一宿主机中的不同容器之间的通信,容器之间可通过 IP,Docker DNS Server 和joined 容器三种方式通信。

(1)IP通信

  两个容器要能通信,必须要有属于同一个网络的网卡。满足这个条件后,容器就可以通过 IP 交互了。这也是默认的方式,我们在使用--net= bridge,docker虚拟出来的一个docker0网桥,会给每一个容器在docker0网桥的网段中分配一个IP,这样同主机中的容器的IP是同一网段的自然可以通过IP相互访问。
演示:

[[email protected] ~]# ifconfig


这里看到我的这台机器中的docker0的网桥的地址为172.17.0.1,这台机器中启动的所有的docker的容器的IP都是这个网段的。

[[email protected] ~]# docker ps  #查看正在运行的docker容器


我这里有两个一个是registry一个是MySQL。

[[email protected] ~]# docker inspect 28b2c91d4be4|grep -i ipaddress #查看容器的IP

[[email protected] ~]# docker inspect 5708c1dcbdd7|grep -i ipaddress #查看容器的IP


可以发现这两个容器的IP地址果然都是172.17.0.1网段的。

(2)docker DNS server

  通过 IP 访问容器虽然满足了通信的需求,但还是不够灵活。因为我们在部署服务之前可能不能确定IP。比如:现在部署一个Nginx web服务,但是每次容器启动分配的IP地址都会改变,我们无法通过固定的IIP地址去访问web服务,这样每次访问时都要查看IP,非常麻烦,对于这个问题,可以通过 docker 自带的 DNS 服务解决。
  从 Docker 1.10 版本开始,docker daemon 实现了一个内嵌的 DNS server,使容器可以直接通过"容器名"通信。方法很简单,只要在启动时用 --name 为容器命名就可以了。
演示:

#下面在同主机启动两个Ubuntu系统并指定--name:
[[email protected] ~]#docker run -it --network=brideg2 --name box1 ubuntu:net /bin/bash
[[email protected] ~]#docker run -it --name --network= brideg2 box2 ubuntu:net /bin/bash


我们发现使用--name,的容器名称可以ping通其他容器。
注意:使用 docker DNS 有个限制:只能在 user-defined 网络中使用。也就是说,默认的 bridge 网络是无法使用 DNS 的。

(3) joined 容器

  joined 容器是另一种实现容器间通信的方式。它可以使两个或多个容器共享一个网络栈,共享网卡和配置信息,joined 容器之间可以通过 127.0.0.1 直接通信。
演示:

#启动一个http服务
[[email protected] ~]# docker run -dit --name my-apache-app  -p 8099:80 -v "/http":/usr/local/apache2/htdocs/ httpd
#创建一个Ubuntu容器容器并通过 --network=container: my-apache-app指定 jointed 容器为 my-apache-app
[[email protected] ~]# docker run -it --network=container:my-apache-app ubuntu:net /bin/bash
#使用命令去访问my-apache-app容器中的web页面
[email protected]:/# curl 127.0.0.1


此时我们发现访问成功!原因是:我们分别查看着两个容器的IP:
Ubuntu:

http:

我们发现两个容器的网卡 mac 地址与 IP 完全一样,它们共享了相同的网络栈。所以Ubuntu容器可以使用127.0.0.1直接访问http容器的web服务。

(4) 补充

docker run 命令的参数介绍:

    -h 运行容器时指定主机名,这样我们可以使用主机名去与容器通信。
    --link=容器名 别名  ,这样使用--link连接的容器间就可以使用主机名进行通信。
    -p host_port:container_port 端口映射,容器的服务端口映射到宿主机。
    -P  container_port    端口映射,映射到宿主机的任意空闲端口。

容器的访问控制
容器访问外部网络:两种方法:
  - sysctl -w net.ipv4.ip_forward=1 (设置宿主机的开启数据转发)
  - 启动Docker服务的时候设定--ip-forward=true,docker会自动打开宿主机系统的转发服务
外部访问容器:这里很简单,通过docker run -h hostname -p 端口映射,来实现外部访问容器。

3.跨主机间的容器通信

(1)Docker网桥实现跨主机容器连接

  在同一宿主机下docker容器之间是可以相同连通的。这是因为默认的docker容器在同一宿主机下,所有容器分配的IP处于同一个地址段的,相互之间可以ping通;当我们使用ifconfig命令查看IP时会发现,其中有一个docker0的网桥,docker容器通过docker0 网桥实现同一主机间中,容器的IP地址分配和访问,这就保证了所有的容器在同一地址段。
  虽然这些IP地址在同一宿主机中是处于同一网段并且相互之间可以通信,但是如果在不同宿主机之间,如果网桥的网段不同,容器之间还是不可能实现跨住进的通信,那么我们可以将每个主机下的容器的网段都处于同一网段,这样,就可以实现跨主机的访问啦,这也是Docker容器默认跨主机之间的连接方法的第一种:网桥实现。

  上图就是网桥方式实现跨主机的连接,但是缺点也很明显,宿主机和容器的IP处于同一网段,如果在局域网下,IP地址是有限的,那么一个容器占据一个IP地址,IP地址很快就会被用光,这就是个不友好的现象,所以这种方式仅仅只用来学习测试使用。
实战操作:
实验环境:

主机名 IP Gateway Netmask
Host1 192.168.130.130 192.168.130.2 255.255.255.0
Host2 192.168.130.131 192.168.130.2 255.255.255.0

① 下载网桥管理工具

yum install -y bridge-utils

② 分别在docker主机上建立网桥

Host1: $ sudo brctl addbr br0
Host2: $ sudo brctl addbr br0

③ 为网桥分配一个同网段IP

Host1: $ sudo ifconfig br0 192.168.130.10 netmask 255.255.255.0
Host2: $ sudo ifconfig br0 192.168.130.20 netmask 255.255.255.0

④ 桥接本地网卡

Host1: $ brctl addif br0 eth0
Host2: $ brctl addif br0 eth0

⑤ 修改docker配置文件

$ Host1 vim /etc/default/docker
$ Host2 vim /etc/default/docker

改成:Host1: DOCKER_OPTS=” -b=br0 –fixed-cidr=‘192.168.130.64/26“
Host2: DOCKER_OPTS=” -b=br1 –fixed-cidr=‘192.168.130.128/26“
这里的:
-b :用来指定容器连接的网桥的名字。
--fixed-cidr :用来限定容器分配的IP地址的范围。
⑥重启docker

$ Host1 systemctl daemon-reload
$ Host1 systemctl restart docker
$ Host2 systemctl daemon-reload
$ Host2 systemctl restart docker

⑦ 测试
这里在host1和host2中各启动一个容器,然后相互ping对方容器IP,如果可以ping桶表示配置成功。

(2)Open vSwitch 实现跨主机容器通信

  Open vSwitch是一个高质量、多层虚拟交换机。使用Apache2.0许可协议,旨在通过编程扩展,使庞大的网络自动化(配置、管理、维护),同时还支持标准的管理接口和协议。

实战操作:

实验环境:

主机名 IP Gateway Netmask
Host1 192.168.130.130 192.168.130.2 255.255.255.0
Host2 192.168.130.131 192.168.130.2 255.255.255.0

虚拟机网段:

主机名 网段
Host1 192.168.1.1
Host2 192.168.2.1

操作步骤:

  • 在虚拟机中建立ovs网桥
  • 添加gre连接
  • 配置docker容器虚拟网桥接
  • 为虚拟网桥添加ovs接口
  • 添加不同Docker容器网段路由
    ① 安装Open vSwitch并启动

    [[email protected] Host1~]#yum install -y openvswitch.x86_64
    [[email protected] Host1~]#systemctl start openvswitch

② 安装网桥

[[email protected] Host1~]# yum install -y bridge-utils

③ 建立ovs网桥并添加GRE接口

[[email protected] Host1~]# ovs-vsctl add-br obr0
[[email protected] Host1~]# ovs-vsctl add-port obr0 gre0

④ 设置远程的网桥连接

[[email protected] Host1~]#ovs-vsctl set interface gre0 type=gre options:remote_ip=192.168.130.131
#查看osv网桥配置
[[email protected] Host1~]#ovs-vsctl show

⑤ 设置docker的虚拟网桥

[[email protected] Host1~]#brctl addbr br0
[[email protected] Host1~]#ifconfig br0 192.168.1.1 netmask 255.255.255.0
[[email protected] Host1~]#brctl addif br0 obr0
[[email protected] Host1~]#brctl show

⑥ 设置路由规则

[[email protected] Host1~]#ip route add 192.168.2.0/24 via 192.168.130.131 dev ens33

同理host2也需要按照上述方式配置。最后两个容器之间就可以通信。

(3)Weave实现跨主机容器通信

   Weave是由weaveworks公司开发的解决Docker跨主机网络的解决方案,它能够创建一个虚拟网络,用于连接部署在多台主机上的Docker容器,这样容器就像被接入了同一个网络交换机,那些使用网络的应用程序不必去配置端口映射和链接等信息。
  外部设备能够访问Weave网络上的应用程序容器所提供的服务,同时已有的内部系统也能够暴露到应用程序容器上。Weave能够穿透防火墙并运行在部分连接的网络上,另外,Weave的通信支持加密,所以用户可以从一个不受信任的网络连接到主机。
原理:


  Weave会在主机上创建一个网桥,每一个容器通过 veth pair 连接到该网桥上,同时网桥上有个 Weave router 的容器与之连接,该router会通过连接在网桥上的接口来抓取网络包(该接口工作在Promiscuous模式)。
  在每一个部署Docker的主机(可能是物理机也可能是虚拟机)上都部署有一个W(即Weave router),它本身也可以一个容器的形式部署。Weave run的时候就可以给每个veth的容器端分配一个ip和相应的掩码。veth的网桥这端就是Weave router容器,并在Weave launch的时候分配好ip和掩码。
  Weave网络是由这些weave routers组成的对等端点(peer)构成,每个对等的一端都有自己的名字,其中包括一个可读性好的名字用于表示状态和日志的输出,一个唯一标识符用于运行中相互区别,即使重启Docker主机名字也保持不变,这些名字默认是mac地址。
  每个部署了Weave router的主机都需要将TCP和UDP的6783端口的防火墙设置打开,保证Weave router之间控制面流量和数据面流量的通过。控制面由weave routers之间建立的TCP连接构成,通过它进行握手和拓扑关系信息的交换通信。 这个通信可以被配置为加密通信。而数据面由Weave routers之间建立的UDP连接构成,这些连接大部分都会加密。这些连接都是全双工的,并且可以穿越防火墙。
实战操作:
实验环境:

主机名 IP Gateway Netmask
Host1 192.168.130.130 192.168.130.2 255.255.255.0
Host2 192.168.130.131 192.168.130.2 255.255.255.0

① 下载复制weave二进制执行文件

[[email protected] Host1~]#git clone https://github.com/weaveworks/weave
[[email protected] Host1~]#cp -p /root/weave/weave  /usr/bin/
[[email protected] Host1~]#cd /usr/bin/
#查看weave版本
[[email protected] Host1~]#weave version


② 启动weave服务

[[email protected] Host1~]# weave launch --no-detect-tls  #注意第一次启动会在docker中拉取相应的镜像

③ 运行一个容器

[[email protected] Host1~]#docker run -it ubuntu:net /bin/bash  

然后Ctrl+p+q退出容器,并且让容器后台运行
④ 进入容器

[[email protected] Host1~]#weave attach 192.168.2.1/24 c45932ef7da4

注意:这里的192.168.2.1/24 是默认的给当前容器分配的一个weaveIP

之后再host2宿主机中也执行以上的命令,并且在“weave attach 192.168.2.1/24 容器ID” 这里分配一相同网段的不同IP。

此时通过这个ethwe中的IP,去相同ping对方容器,这里就可以相同访问:

原文地址:https://blog.51cto.com/14048416/2384509

时间: 2024-10-11 07:13:34

docker基础篇(一)补的相关文章

docker基础篇(一)

为了能很好的了解k8s,这里小编写大致的将docker的基础做一些介绍,这里小编将会以2篇博文的形式,详细的介绍一下docker的基础部分,这一篇是docker的概念以及docker的基本使用,后续会在发布一篇关于docker的官网上的quick-start的实战案例,让大家能更好的了解docker. 一.docker的介绍 1.什么是docker? ??Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.开发者在笔记本上编译测试通过的容器可以批量地在生

Docker基础入门 (一)—— 简介

Docker -- 简介 1. Doker是个什么玩意 说Docker是什么之前,先来看一看Docker为什么会出现.我们知道,在学习过程中我们需要频繁地安装配置一些软件,不管是在Windows下还是在Linux,这些东西的配置过程都是非常费时费力的,稍有不慎就得删了重来,换一台机器,还得重来一次,更讨厌的是经常出现一些环境的兼容性问题(比如一些软件只兼容win7).那么有没有这样一种解决方式:软件带环境安装,省去麻烦的安装配置过程,并且完全不用考虑环境兼容问题,因为自带环境嘛.也就是说,安装的

Docker之基础篇

系列文章: 小白学Docker之基础篇 小白学Docker之Compose 小白学Docker之Swarm PS: 以下是个人作为新手小白学习docker的笔记总结 1. docker是什么 百科上的解释是这样的: Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何接口. 知乎上的很多理解是将其理解成集装箱,彼此之间互相不影响,各自运行在各自的环境

Docker虚拟化实战学习——基础篇(转)

Docker虚拟化实战学习--基础篇 2018年05月26日 02:17:24 北纬34度停留 阅读数:773更多 个人分类: Docker Docker虚拟化实战和企业案例演练 深入剖析虚拟化技术概念和应用场景 虚拟化,一是项技术--,是一种资源解决方案. 虚拟化技术是将物理资源转变为逻辑上可以管理的资源,以打破物理结构之间的壁垒,使计算元件运行在虚拟的基础上,而不是真实的物理资源上. 通过虚拟化技术,可以将物理资源转变为逻辑资源(虚拟机),应用程序服务运行在虚拟资源上,而不是真实的物理机上.

Docker 基础知识-入门篇

1. Docker简介和KVM区别 1.1 docker的三大理念 构建 运输 运行 ps:有点类似于java代码,一次构建到处运行 1.2 docker结构 相关说明:image: 和虚拟机的镜像类似container: 用镜像创建的实例repository: 类似于yum仓库docker client: 命令行输入的docker命令docker server: 启动的docker进程 1.3 docker和kvm的区别 1.虚拟机需要hypervisor这个中间层来进行支持,上面跑的每一个虚

php面试题汇总二(基础篇附答案)

介绍一些php常见面试题及答案,都是平时面试的时候经常会遇到的,小伙伴们仔细了解下吧.接着上一篇php面试题汇总一(基础篇附答案) 1.在PHP中,当前脚本的名称(不包括路径和查询字符串)记录在预定义变量(1)中:而链接到当前页面的URL记录在预定义变量(2)中. 答:echo $_SERVER['PHP_SELF']; echo $_SERVER["HTTP_REFERER"]; 2:数组函数 arsort 的作用是(6):语句 error_reporting(2047)的作用是(7

Javascript基础篇小结

Javascript基础篇小结 字数9973 阅读3975 评论7 喜欢28 转载请声明出处 博客原文 随手翻阅以前的学习笔记,顺便整理一下放在这里,方便自己复习,也希望你有也有帮助吧 第一课时 入门基础 知识点: 操作系统就是个应用程序 只要是应用程序都要占用物理内存 浏览器本身也是一个应用程序 浏览器本身只懂得解析HTML 调用浏览器这个应用程序的一个功能绘制 1.javascript介绍 JavaScript操作DOM的本质是=获取+触发+改变 目的:就是用来操作内存中的DOM节点 修改D

C++:位操作基础篇之位操作全面总结

位操作篇共分为基础篇和提高篇,基础篇主要对位操作进行全面总结,帮助大家梳理知识.提高篇则针对各大IT公司如微软.腾讯.百度.360等公司的笔试面试题作详细的解答,使大家能熟练应对在笔试面试中位操作题目. 下面就先来对位操作作个全面总结,欢迎大家补充. 在计算机中所有数据都是以二进制的形式储存的.位运算其实就是直接对在内存中的二进制数据进行操作,因此处理数据的速度非常快. 在实际编程中,如果能巧妙运用位操作,完全可以达到四两拨千斤的效果,正因为位操作的这些优点,所以位操作在各大IT公司的笔试面试中

WebBug靶场基础篇 — 02

本篇以第一人称记录这个关卡的第 1-5 关. 由于我记录的过程有点偏向于思考,所以截图截的多 = =!所以文章有点长... 下午一觉醒来,已经 4 点多了,然后开电脑,在虚拟机里,铺了铺靶场,但是毕竟我本子太卡了....所以只好在主机上玩了... 打开关卡的首页. 点击第一个关卡,普通的 get 注入,get 注入就是普通的注入,咱们常见的浏览网页都是属于 get 型的方式 . 进入第一关 ... 继续点击 ... 我第一眼注意到了上面给的提示 ,搜索型 ... 如果是搜索型的那注入的 sql