docker网络基础

docker使用到的与linux网络有关的主要技术

  • Network Namespace(网络命名空间)
  • Veth设备对
  • Iptables/NetFilter
  • 网桥
  • 路由

标准的dokcer支持以下4种网络模式

  • host模式: 使用--net=host指定
  • container模式:使用--net=container:NAME_or_ID指定
  • none模式: 使用 --net=none指定
  • bridge模式:使用--net=bridge指定,为默认设置
    • docker第一次启动时会创建一个虚拟网桥,默认为docker0,在私有网络空间中给这个网桥分配一个子网,由docker创建出来的每一个容器,会创建一个虚拟的以太网设备(veth设备对),其中一端关联到网桥,一端使用linux的网络命名空间技术映射为容器内的eth0设备,然后从网桥的地址段内给eth0接口分配一个ip地址  

容器访问外部网络

器要想访问外部网络,需要本地系统的转发支持。在Linux 系统中,检查转发是否打开。

$sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

如果为 0,说明没有开启转发,则需要手动打开。

从外部访问容器

容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P 或 -p 参数来指定端口映射。

当使用 -P 标记时,Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口。
-p(小写的)则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有

ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort。

映射所有接口地址

使用 hostPort:containerPort 格式本地的 5000 端口映射到容器的 5000 端口,可以执行

$ sudo docker run -d -p 5000:5000 training/webapp python app.py

此时默认会绑定本地所有接口上的所有地址。

映射到指定地址的指定端口
可以使用 ip:hostPort:containerPort 格式指定映射使用一个特定地址,比如 localhost 地址 127.0.0.1

$ sudo docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py

映射到指定地址的任意端口

使用 ip::containerPort 绑定 localhost 的任意端口到容器的 5000 端口,本地主机会自动分配一个端口。

$ sudo docker run -d -p 127.0.0.1::5000 training/webapp python app.py

还可以使用 udp 标记来指定 udp 端口

$ sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py

查看映射端口配置

使用 docker port 来查看当前映射的端口配置,也可以查看到绑定的地址

$ docker port nostalgic_morse 5000    #container NAMES
127.0.0.1:49155.

注意:
容器有自己的内部网络和 ip 地址(使用 docker inspect 可以获取所有的变量,Docker 还可以有一个可变的网络配置。)

-p 标记可以多次使用来绑定多个端口,例如:

$ sudo docker run -d -p 5000:5000 -p 3000:80 training/webapp python app.py

容器互联

官网示例

先创建一个新的 Docker 网络。

$ docker network create -d bridge my-net
-d 参数指定 Docker 网络类型,有 bridge overlay。其中 overlay 网络类型用于 Swarm mode\ 连接容器,运行一个容器并连接到新建的 my-net 网络 $ docker run -it --rm --name busybox1 --network my-net busybox sh 打开新的终端,再运行一个容器并加入到 my-net 网络 $ docker run -it --rm --name busybox2 --network my-net busybox sh 进入容器,通过互相ping 容器名称来判断是否互联

  

自己测试示例

#查看所有网络:
docker network ls #创建自己的网络
docker network create -d bridge my-bridge-network #检查网络(如果你检查网络,会发现里面什么都没有)
docker network inspect my-bridge-network

添加一个容器到自定义的网络

#指定网络 运行(将db添加为自定义的网络)
docker run -d --net=my-bridge-network --name db training/postgres     #--name 为定义的名字

#再次检查网络(会发现多了一个容器)
docker network inspect my-bridge-network #查看网络情况
docker inspect --format='{{json .NetworkSettings.Networks}}' db #查看ip地址
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' db #启动另一个容器:并不在一个网段,未加入到自定义的网络 名称为web
docker run -d --name web training/webapp python app.py

进入交互模式,并且ping web的地址进行测试

docker exec -it db bash #此时是ping 不通的

#将web加入自定义的网络
$ docker network connect my-bridge-network web docker exec -it db bash   #然后在去交互模式ping web,就可以通信了

容器互联-linking系统

docker有一个linking 系统可以连接多个容器。它会创建一对父子关系,父容器可以看到所选择的 子容器的信息。

注意:
容器的名 称 是 唯 一的。如果 你 命名了一个 叫 web的容器,当 你 要 再次 使用 web这个名 称 的 时候 , 你 需要用 docker rm来 删 除之前创建的容器,也可以 再 执行 docker run的 时候 加--rm标记来 停止旧 的容器, 并删 除, rm 和 -d 参 数是 不兼 容的。

使用--name标记可以为容器命名

$ sudo docker run -d -P --name web training/webapp python app.py

使用docker ps -l 来验证我们设定的命名

$ sudo docker ps -l

links可以让容器之间安全的交互,使用--link标记。

#先创建一个新的数据库容器,
$ sudo docker run -d --name db training/postgres #创建一个新的web容器,并将它link到db容器
$ docker run -d -P --name web --link db:db training/webapp python app.py # --link标记的格式:--link name:alias,name是我们要链接的容器的名称,alias是这个链接的别名(会在新建的容器中/etc/hosts添加一条记录 ip db 此处的db为指定的alias别名)

使用docker ps来查看容器的链接

可以看到命名的容器,db和web,db容器的names列有db也有web/db。这表示web容 器链接到db容器,他们是一个父子关系。在这个link中,2个容器中有一对父子关系。docker在2个 容器之间创建了一个安全的连接,而且不用映射他们的端口到宿主主机上。在启动db容器的时候也不 用-p和-P标记。使用link之后我们就可以不用暴露数据库端口到网络上。

docker 通过2种方式为父子关系的容器公开连接信息:

• 环境变量
• 更新/etc/hosts文件

#使用env命令来查看容器的环境变量
$ sudo docker run --rm --name web2 --link db:db training/webapp env #除了环境变量,docker还添加host信息到父容器的/etc/hosts的文件。下面是父容器web的hosts文件
$ sudo docker run -t -i --rm --link db:db training/webapp /bin/bash
root@aed84ee21bde:/opt/webapp# cat /etc/hosts

这里有2个hosts,第一个是web容器,web容器用id作为他的主机名,第二个是db容器的ip和主机名

root@aed84ee21bde:/opt/webapp# apt-get install -yqq inetutils-ping
root@aed84ee21bde:/opt/webapp# ping db
PING db (172.17.0.5): data bytes
bytes from 172.17.0.5: icmp_seq= ttl= time=0.267 ms
bytes from 172.17.0.5: icmp_seq= ttl= time=0.250 ms
bytes from 172.17.0.5: icmp_seq= ttl= time=0.256 ms
用ping来ping db容器,它会解析成172.17.0.

注意:官方的ubuntu镜像默认没有安装ping
注意:你可以链接多个子容器到父容器,比如我们可以链接多个web到db容器上。

docker高级网络配置

快速配置指南

下面是一个跟docker网络相关的命令列表,有些命令选项只有 在docker服务启动的时候才可以执行,而且不能马上生效。

• -b BRIDGE or --bridge=BRIDGE —   桥接配置
• --bip=CIDR —              定制docker0的掩码
• -H SOCKET... or --host=SOCKET... — 它告诉docker从哪个通道来接收run container stop container这样的命令,也是docker api的地址 • --icc=true|false           
• --ip-forward=true|false      
• --iptables=true|false        
• --mtu=BYTES —           
• --dns=IP_ADDRESS...         
• --dns-search=DOMAIN...       
• -h HOSTNAME or --hostname=HOSTNAME — 主机名配置
• --link=CONTAINER_NAME:ALIAS     — link 系统
• --net=bridge|none|container:NAME_or_ID|host     —桥接配置
• -p SPEC or --publish=SPEC       — 映射容器端口到宿主主机
• -P or --publish-all=true|false     — 映射容器端口到宿主主机

配置容器dns服务的方法

  • -h HOSTNAME or --hostname=HOSTNAME 设定容器的主机名,它会被写到/etc/hostname,/etc/hosts中的ip地址自动写成分配的ip地址, 在/bin/bash中显示该主机名。但它不会在docker ps中显示,也不会在其他的容器的/etc/hosts中显示。
  • --link=CONTAINER_NAME:ALIAS 这选项会在创建容器的时候添加一个其他容器CONTAINE_NAME的主机名到/etc/hosts文件中, 让新容器的进程可以使用主机名ALIAS就可以连接它。
  • --dns=IP_ADDRESS 添加dns服务器到容器的/etc/resolv.conf中,让容器用这ip地址来解析所有不在/etc/hosts中的主 机名。
  • --dns-search=DOMAIN 设定容器的搜索域,当设定搜索域为.example.com时,会在搜索一个host主机名时,dns不仅搜索 host,还会搜索host.example.com

注意:如果 没 有上 述最 后 2个 选 项, docker会用主机上的 /etc/resolv.conf来配置容器, 它 是 默 认配置。

创建自己的桥接

#停止旧网桥并删除
$ sudo service docker stop
$ sudo ip link set dev docker0 down
$ sudo brctl delbr docker0 # 创建自己的网桥
$ sudo brctl addbr bridge0
$ sudo ip addr add 192.168.5.1/24 dev bridge0
$ sudo ip link set dev bridge0 up
# 确认网桥启动
$ ip addr show bridge0 # 告诉docker桥接设置,并启动docker服务(在ubuntu上)
$ echo 'DOCKER_OPTS="-b=bridge0"' >> /etc/default/docker
$ sudo service docker start

docker服务启动成功并绑定容器到新的网桥,建一个容器,你会看到它的ip是我们的设置的新ip 段,docker会自动检测到它。

用brctl show可以看到容器启动或则停止后网桥的配置变化,在容器中使 用ip a 和ip r 来查看ip地址配置和路由信息

创建一个点到点连接(network namespace)

#创建一个名为nestest的 network namespace
ip netns add netest #列出系统中存在的network namespace
ip netns list #删除一个network namespace
ip netns delete nstest #在network namespace中执行一条命令
ip netns exec <network namespace name > command 如:
ip netns exec <network namespace name > ip addr #在network namespace中启动一个bash
ip netns exec <network namespace name > /bin/bash

默认docker会将所有容器连接到由docker0提供的虚拟子网,你也可以使用自己创建的网桥。但如 果你想要2个特殊的容器之间可以直连通信,而不用去配置复杂的主机网卡桥接。
解决办法很简单:创建一对接口,把2个容器放到这对接口中,配置成点到点链路类型。这2个容 器就可以直接通信了。配置如下:

# 在2个终端中启动2个容器
$ sudo docker run -i -t --rm --net=none base /bin/bash
root@1f1f4c1f931a:/#
$ sudo docker run -i -t --rm --net=none base /bin/bash
root@12e343489d2f:/# #找到他们的process IDs ,然后创建他们的 namespace entries
$ sudo docker inspect -f '{{.State.Pid}}' 1f1f4c1f931a
2989
$ sudo docker inspect -f '{{.State.Pid}}' 12e343489d2f
3004
$ sudo mkdir -p /var/run/netns
$ sudo ln -s /proc/2989/ns/net /var/run/netns/2989
$ sudo ln -s /proc/3004/ns/net /var/run/netns/3004
# 创建”peer“接口,然后配置路由

#在主机上创建虚拟网卡
$ sudo ip link add A type veth peer name B
$ sudo ip link set A netns 2989           #2989为一个network namespace ,此处是将网卡放到network namespace中的命令
$ sudo ip netns exec 2989 ip addr add 10.1.1.1/32 dev A
$ sudo ip netns exec 2989 ip link set A up       #启动网卡
$ sudo ip netns exec 2989 ip route add 10.1.1.2/32 dev A    #分配ip $ sudo ip link set B netns 3004
$ sudo ip netns exec 3004 ip addr add 10.1.1.2/32 dev B
$ sudo ip netns exec 3004 ip link set B up
$ sudo ip netns exec 3004 ip route add 10.1.1.1/32 dev B

现在这2个容器就可以相互ping通,并成功建立连接。点到点链路不需要子网和子网掩码,使用ip route 来连接单个ip地址到指定的网络接口。

如果 没 有 特 殊 需要 你不 需要指定 --net=none来创建点到点 链路 。 还有一个办法就是创建一个只跟主机通信的容器,除非有特殊需求,你可以仅用--icc=false来限制 主机间的通信。

 

docker 基础之网络管理的更多相关文章

  1. docker基础内容讲解

    一.初识docker 1.1 LXC介绍 LXC为LinuX Container的简写.Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提 ...

  2. Docker基础用法篇

    Docker基础用法篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.安装docker 1>.依赖的基础环境 64 bits CPU Linux Kerner 3.10+ ...

  3. Docker基础(下)

    Docker基础(下) 链接:https://pan.baidu.com/s/1u8Tg5qB4ZZHEK6GqCJkjwg 提取码:u8hb 复制这段内容后打开百度网盘手机App,操作更方便哦 5. ...

  4. Docker - Docker基础命令及使用

    Docker Docker - 官网 Docker - Hub GitHub - Docker Docker中文社区 Docker基础命令 Docker 查看帮助信息:docker --help 查看 ...

  5. 【云计算】Docker云平台—Docker基础

    Docker云平台系列共三讲,此为第一讲:Docker基础 参考资料: Docker官方文档:https://docs.docker.com/ Docker从入门到实践:https://yeasy.g ...

  6. Docker基础技术:Linux Namespace(下)

    在 Docker基础技术:Linux Namespace(上篇)中我们了解了,UTD.IPC.PID.Mount 四个namespace,我们模仿Docker做了一个相当相当山寨的镜像.在这一篇中,主 ...

  7. Docker 基础技术:Linux Namespace(下)

    导读 在Docker基础技术:Linux Namespace(上篇)中我们了解了,UTD.IPC.PID.Mount 四个namespace,我们模仿Docker做了一个相当相当山寨的镜像.在这一篇中 ...

  8. Docker基础入门及示例

    Docker近几年的发展可谓一日千里,特别从是2013年随着一个基于LXC的高级容器引擎开源,到现在,其在linux和windows上都有了很好的支持,并且已经有很多公司将docker用于实际的生产环 ...

  9. Docker 基础 : 镜像

    目录 获取镜像 查看镜像信息 搜索镜像 删除镜像 创建镜像 导出和导入镜像 上传镜像 总结 镜像是 Docker 的三大核心概念之一.Docker 运行容器前需要本地存在对应的镜像,如果本地没有对应的 ...

随机推荐

  1. 免费开源的会计软件 GnuCash 3.4 发布

    导读 GnuCash 3.4已经发布,GnuCash是免费和开源的会计软件.GnuCash开发团队宣布推出GnuCash 3.4,这是3.x稳定版系列的第五版. 变化 在3.3和3.4之间,完成了以下 ...

  2. django CBV视图源码分析

    典型FBV视图例子 url路由系统 from django.conf.urls import url from django.contrib import admin from luffycity.v ...

  3. Django实现Rbac权限管理

    权限管理 权限管理是根据不同的用户有相应的权限功能,通常用到的权限管理理念Rbac. Rbac 基于角色的权限访问控制(Role-Based Access Control)作为传统访问控制(自主访问, ...

  4. BZOJ1565[NOI2009]植物大战僵尸——最大权闭合子图+拓扑排序

    题目描述 Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plants防守,而Zombies进攻.该款游戏包含多 ...

  5. python成长之路二

    python的print格式化输出,以及使用format来控制. 1,打印字符串(str),利用%s. >>> print ('My name is %s' % ('TaoXiao' ...

  6. 【Gym 100812C】Story of Princess (走完图所有边)

    BUPT2017 wintertraining(15) #7A 题意 给你一个图,n个点m条边,求走遍所有边,至少经过几次点,及输出依次经过的点.n and m (2 ≤ n ≤ 10^5, 1 ≤  ...

  7. 《App后台开发运维与架构实践》第2章 App后台基础技术

    2.1 從App業務邏輯中提煉API接口 業務邏輯思維導圖 功能-業務邏輯思維導圖 基本功能模塊關系 功能模塊接口UML(設計出API) 在設計稿標注API 編寫API文檔 2.2 設計API的要點 ...

  8. 【BZOJ2940】条纹(博弈论)

    [BZOJ2940]条纹(博弈论) 题面 BZOJ 神TM权限题. 题解 我们把题目看成取石子的话,题目就变成了这样: 有一堆\(m\)个石头,每次可以取走\(c,z,n\)个,每次取完之后可以把当前 ...

  9. LVS搭建负载均衡(一)NAT模型

    应用场景:LVS配置负载均衡方式之一:nat 测试环境: 测试步骤: 1. 在主机lvs上安装ipvsadm lvs~]# yum install ipvsadm -y lvs~]# ipvsadm ...

  10. 黑苹果 技嘉 B250M-DS3H-CF i57500 HD630 EFI引导驱动发布

    1. 鉴于苹果的MacOS OSX系统的优越性,由于现在公司的电脑为windows但是自己用的笔记本又是Mac,导致需要适应两套系统,超级麻烦.故想在电脑上装上黑苹果的计划 相关配置地址:https: ...