前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Docker容器虚拟化(三)—网络管理 原

Docker容器虚拟化(三)—网络管理 原

作者头像
阿dai学长
发布2019-04-03 10:35:11
1.1K0
发布2019-04-03 10:35:11
举报
文章被收录于专栏:阿dai_linux阿dai_linux

Docker网络管理-网络模式

docker有四种网络模式:

  • host模式,使用docker run时使用--net=host指定docker使用的网络实际上和宿主机一样,在容器内看到的网卡ip是宿主机上的ip
  • container模式,使用--net=container:container_id/container_name多个容器使用共同的网络,看到的ip是一样的
  • none模式,使用--net=none指定这种模式下,不会配置任何网络
  • bridge模式,使用--net=bridge指定默认模式,不用指定默认就是这种网络模式。这种模式会为每个容器分配一个独立的Network Namespace。类似于vmware的nat网络模式。同一个宿主机上的所有容器会在同一个网段下,相互之间是可以通信的。

host模式

代码语言:javascript
复制
[root@study ~]# docker run -it --rm --net=host centos-7-x86_64-minimal bash

[root@study /]# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 0.0.0.0
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.8.139  netmask 255.255.255.0  broadcast 192.168.8.255
        
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 0.0.0.0
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.8.139  netmask 255.255.255.0  broadcast 192.168.8.255

即,容器IP和母机IP一样。

container模式

代码语言:javascript
复制
[root@study ~]# docker run -itd --name test centos bash
cf20bbfce47ed505874ec741b3f8bd76b080e20eba4a2773c58f25ce2787d67d
[root@study ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
cf20bbfce47e        centos              "bash"              11 seconds ago      Up 8 seconds                            test
[root@study ~]# docker exec -it test bash
[root@cf20bbfce47e /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 0.0.0.0
        
[root@study ~]# docker run -it --net=container:test --name test2 centos_with_net bash
[root@cf20bbfce47e /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 0.0.0.0

即,容器test2和test的IP一样,且id也一样。

none模式

代码语言:javascript
复制
[root@study ~]# docker run -it --rm --net=none --name test3 centos_with_net bash
[root@043d5e570507 /]# ifconfig
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0

无网络连接。

bridge模式

平时使用的模式。。

Docker网络管理-如何让外部网络访问docker资源

首先使用centos镜像新建一个容器,然后在该容器中安装httpd服务,并启动 ,再把该容器导成一个新的镜像(centos-httpd),然后再使用新镜像创建容器,并指定端口映射:

代码语言:javascript
复制
docker run -itd -p 5123:80 centos-httpd bash //-p

可以指定端口映射,本例中将容器的80端口映射为本地的5123端口

代码语言:javascript
复制
[root@study ~]# docker ps 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
cf20bbfce47e        centos              "bash"              27 hours ago        Up 2 minutes                            test
[root@study ~]# docker exec -it test bash

安装httpd服务:
[root@cf20bbfce47e /]# yum install -y httpd

启动httpd服务:
[root@cf20bbfce47e /]# httpd -k start

将test容器保存为新的镜像:
[root@study ~]# docker commit -m "centos_installd_httpd" -a "adailinux" test centos_with_httpd:adai
[root@study ~]# docker images
REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE
centos_with_httpd            adai                ccd04a9b21a1        9 seconds ago    

做端口映射:
[root@study ~]# docker run -itd --name test2 -p 5123:80 centos_with_httpd:adai bash
##-p:指定映射端口
##将宿主机的某端口映射到容器的80端口
[root@study ~]# docker ps
CONTAINER ID        IMAGE                    COMMAND             CREATED             STATUS              PORTS                  NAMES
641e7f27617e        centos_with_httpd:adai   "bash"              18 seconds ago      Up 16 seconds       0.0.0.0:5123->80/tcp   test2

进入test2容器:
[root@study ~]# docker exec -it test2 bash

启动httpd服务:
[root@641e7f27617e /]# httpd -k start

创建测试文件:
[root@641e7f27617e /]# vi /var/www/html/test.html
adai is here!

测试:
[root@641e7f27617e /]# curl localhost/test.html   
adai is here!

在宿主机测试:
[root@study ~]# curl 192.168.8.139:5123/test.html
adai is here!
##访问成功!

Docker网络管理-容器互联

在同一台母机上的容器可以通过IP连接,配置容器互联后,容器之间可以通过name进行连接。

代码语言:javascript
复制
查看test2的IP:
[root@study ~]# docker exec -it test2 bash
[root@641e7f27617e /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.3  netmask 255.255.0.0  broadcast 0.0.0.0

在test容器中测试test2 的连通性:
[root@study ~]# docker exec -it test bash
[root@cf20bbfce47e /]# curl 172.17.0.3/test.html
adai is here!
##通畅!!!

准备工作

创建一个数据库容器data:

代码语言:javascript
复制
创建容器db:
[root@study ~]# docker run -itd --name db centos_with_net /usr/sbin/init
[root@study ~]# docker exec -it db  bash

安装centos7自带mariadb数据库:
[root@a3254ef9500d /]# yum install -y mariadb mariadb-server

启动mariadb:
[root@d9699f1a028b /]# systemctl start mariadb

[root@d9699f1a028b /]# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      -                   
##启动成功!

保存该容器为新镜像:
[root@study ~]# docker commit -m "centos_with_mariadb" -a "adai" db centos_with_mariadb

创建数据库容器data:
[root@study ~]# docker run -itd --name data -p 13306:3306 centos_with_mariadb /usr/sbin/init

数据库容器创建完成!

排错:

如果你是使用bash创建centos7的docker容器(docker run -itd centos bash),那么在运行systemctl命令时可能会要到如下报错:

代码语言:javascript
复制
[root@study ~]# docker run -itd --name db centos_with_net bash 

[root@a3254ef9500d /]# systemctl start mariadb
Failed to get D-Bus connection: Operation not permitted

原因:dbus-daemon没能启动。其实systemctl并不是不可以使用,需要在启动容器的时候将CMD或者entrypoint设置为/usr/sbin/init,这样才能自动将dbus等服务启动起来,方法如下:

代码语言:javascript
复制
[root@study ~]# docker run -itd --name db centos_with_net /usr/sbin/init

然后再使用systemctl命令就可以了。

有的人说在CentOS7.2中解决了通过systemctl运行报错的问题,但是我在实际操作中还是遇到这样的问题。 还有一种解决办法,就是在通过Dockerfile生成镜像文件的时候通过CMD来执行/usr/sbin/init这条命令,即: CMD [ "/usr/sbin/init"]。

参考:https://github.com/docker/docker/issues/7459 https://github.com/docker/docker/issues/2296

连接数据库容器

代码语言:javascript
复制
新建一个web容器并和data容器互联:
[root@study ~]# docker run -itd -p 18080:80 --name web --link data:webdb centos_with_httpd:adai /usr/sbin/init
## --link:参数中data为数据库容器的名称,webdata为web容器中数据库显示的名称

在web上运行env命令可以查看到关于db的环境变量:
[root@study ~]# docker exec -it web bash
[root@ce08c9da9129 /]# env
WEBDB_PORT_3306_TCP=tcp://172.17.0.4:3306
HOSTNAME=ce08c9da9129
WEBDB_NAME=/web/webdb
TERM=xterm
WEBDB_PORT=tcp://172.17.0.4:3306
WEBDB_PORT_3306_TCP_PROTO=tcp
PWD=/
SHLVL=1
HOME=/root
WEBDB_PORT_3306_TCP_ADDR=172.17.0.4
WEBDB_PORT_3306_TCP_PORT=3306

查看data容器IP:
[root@study ~]# docker exec -it data bash
[root@0e945222f8c0 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.4  netmask 255.255.0.0  broadcast 0.0.0.0

即,两容器完成互连。

Docker网络管理-配置桥接网络(方法一)

建议:在进行该操作前先做快照!!!

为了使本地网络中的机器和Docker容器更方便的通信,我们经常会有将Docker容器配置到和主机同一网段的需求。这个需求其实很容易实现,我们只要将Docker容器和宿主机的网卡桥接起来,再给Docker容器配上IP就可以了。

代码语言:javascript
复制
系统:centos7
宿主机网卡信息:
name:ens33
IP:192.168.8.139
gateway:192.168.8.2
dns:119.29.29.29

停止docker服务

代码语言:javascript
复制
[root@study ~]# systemctl stop docker

删除docker0网卡

代码语言:javascript
复制
安装网桥配置命令:
[root@study ~]# yum install -y bridge-utils

[root@study ~]# ip link set dev docker0 down
[root@study ~]# brctl delbr docker0

新建桥接物理网络虚拟网卡br0

代码语言:javascript
复制
添加网卡br0:
[root@study ~]# brctl addbr br0
[root@study ~]# ip link set dev br0 up

为br0分配物理网络中的ip地址:
[root@study ~]# ip addr add 192.168.8.201/24 dev br0
##此处虚拟机网络可能会中断

将宿主机网卡的IP清空:
[root@study ~]# ip addr del 192.168。8.139/24 dev ens0 

将宿主机网卡挂到br0上:
[root@study ~]# brctl addif br0 ens33

删除原路由:
[root@study ~]# ip route del default 

为br0设置路由:
[root@study ~]# ip route add default via 192.168.8.2 dev br0 

设置docker启动参数

这里要注意,不同的linux操作系统docker的配置文件所在不同,centos7 在/etc/sysconfig/docker,其他操作系统请参考:https://docs.docker.com/installation/#installation

代码语言:javascript
复制
[root@study ~]# vim /etc/sysconfig/docker 
OPTIONS='--selinux-enabled -b=br0'
##添加参数-b=br0,即让docker服务启动时使用br0网卡进行桥接

启动docker:

安装pipework工具

代码语言:javascript
复制
[root@study ~]# git clone https://github.com/jpetazzo/pipework

[root@study ~]# cp pipework/pipework /usr/local/bin/

启动一个手动设置网络的容器

代码语言:javascript
复制
创建容器bridge:
[root@study ~]# docker run -itd --net=none --name bridge centos /bin/bash

bride容器配置IP

代码语言:javascript
复制
[root@study ~]# pipework br0 bridge 192.168.8.110/24@192.168.8.2
##为bridge容器设置一个与桥接物理网络同地址段的ip@网关

注意:执行此操作的时候要保证对应的容器为开启状态。

查看容器IP

代码语言:javascript
复制
[root@study ~]# docker exec -it bridge bash
[root@dba96eac22e7 /]# ifconfig
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.8.110  netmask 255.255.255.0  broadcast 192.168.8..255
[root@dba96eac22e7 /]# ping www.baidu.com
PING www.a.shifen.com (61.135.169.125) 56(84) bytes of data.
64 bytes from 61.135.169.125 (61.135.169.125): icmp_seq=1 ttl=128 time=7.86 ms
64 bytes from 61.135.169.125 (61.135.169.125): icmp_seq=2 ttl=128 time=8.51 ms

配置完成!

Docker网络管理-配置桥接网络(方法二)

该过程中因为br0和ens33配置了同样的IP,所以避免了xshell远程连接的中断。

配置虚拟网卡

代码语言:javascript
复制
添加虚拟网卡:
[root@study ~]# cp /etc/sysconfig/network-scripts/ifcfg-ens33 /etc/sysconfig/network-scripts/ifcfg-br0

配置网卡信息:
[root@study ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
增加参数:
BRIDGE=br0
删除:IPADDR、NETMASK、GATEWAY、DNS1

[root@study ~]# vim /etc/sysconfig/network-scripts/ifcfg-br0
TYPE=Bridge
NAME=br0
DEVICE=br0
删除UUID

重启网络:
[root@study ~]# systemctl restart network
[root@study ~]# ifconfig
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.8.139  netmask 255.255.255.0  broadcast 192.168.8.255

虚拟网卡准备完毕!

配置docker

同样要安装pipework工具。

代码语言:javascript
复制
启动一个手动设置网络的容器:
[root@study ~]# docker run -itd --net=none --name bridge centos /bin/bash

bride容器配置IP:
[root@study ~]# pipework br0 bridge 172.17.0.110/24@192.168.8.2
##为bridge容器设置一个与桥接物理网络同地址段的ip@网关

注意:执行此操作的时候要保证对应的容器为开启状态。

配置结果:

代码语言:javascript
复制
[root@study ~]# pipework br0 bridge 192.168.8.110/24@192.168.8.2
[root@study ~]# docker exec -it bridge bash
[root@dba96eac22e7 /]# ifconfig
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.8.110  netmask 255.255.255.0  broadcast 192.168.8.255

[root@dba96eac22e7 /]# ping 192.168.8.2
PING 192.168.8.2 (192.168.8.2) 56(84) bytes of data.
64 bytes from 192.168.8.2: icmp_seq=1 ttl=128 time=2.31 ms

[root@dba96eac22e7 /]# ping www.baidu.com
PING www.a.shifen.com (61.135.169.121) 56(84) bytes of data.
64 bytes from 61.135.169.121 (61.135.169.121): icmp_seq=1 ttl=128 time=9.26 ms

配置完成!

说明: 两种方法只是配置虚拟网卡的方法不同,推荐使用方法二(避免了远程连接的中断)。

(adsbygoogle = window.adsbygoogle || []).push({});

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017/10/15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Docker网络管理-网络模式
    • host模式
      • container模式
        • none模式
          • bridge模式
          • Docker网络管理-如何让外部网络访问docker资源
          • Docker网络管理-容器互联
            • 准备工作
              • 排错:
            • 连接数据库容器
            • Docker网络管理-配置桥接网络(方法一)
              • 停止docker服务
                • 删除docker0网卡
                  • 新建桥接物理网络虚拟网卡br0
                    • 设置docker启动参数
                      • 安装pipework工具
                        • 启动一个手动设置网络的容器
                          • bride容器配置IP
                            • 查看容器IP
                            • Docker网络管理-配置桥接网络(方法二)
                              • 配置虚拟网卡
                                • 配置docker
                                  • 配置结果:
                                  相关产品与服务
                                  容器服务
                                  腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                                  领券
                                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档