容器部署经验总结


docker网络简介

      docker的网络部分是非常重要的一个分支。 docker安装好后宿主机增加多了两个虚拟网卡接口(docker0,br-1d3799005cb5),用ip addr命令看到如下,docker0网段172.17.0.0,br-1d3799005cb5网段172.18.0.0

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
   ......
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:66:d2:4f brd ff:ff:ff:ff:ff:ff
    inet 192.168.228.44/24 brd 192.168.228.255 scope global noprefixroute ens33
   ......
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:14:95:53:83 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
    ......
5: br-1d3799005cb5: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:47:f9:d3:b2 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 brd 172.18.255.255 scope global br-1d3799005cb5
    ......

 

      对docker-engine默认会有4个网桥(或者说是交换机),用docker network ls命令查看如下,名为bridge的网桥对应到docker0虚拟网卡172.17.0.0,名为docker-default的对应br-1d3799005cb5虚拟网卡接口172.18.0.0。

 

docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
704ee94879e3        bridge              bridge              local
1d3799005cb5        docker_default      bridge              local
e6cc2af3037d        host                host                local
3144be175a0e        none                null                local

 有没注意到DRIVER,这是网络模式,docker里面预定义了4种模式,分别如下

 

  1. bridge
    注意引用‘bridge’的词地方不少,都是不同代表的,就像上面取名NAME是bridge,DRIVER也有个bridge,不要混在一起哦;这里是后者,代表是桥接,和vmare里nat一样,与宿主机物理网络是隔离的,如果要访问外面的internet,要经过NAT地址转换;容器没显式指定--net=?时默认采用bridge模式。两个不同bridge间是隔开的,譬如上面的bridge和docker_default,在容器内部互相ping不通,即容器ip为172.18.0.x ping 172.17.0.x会失败。
  2. host
    共享宿主机网络
  3. container
    使用某个已存在的容器的网络namespace,注意是和配置的目标容器共享网络资源,端口不要冲突。
  4. null
    无网络,一般不需要通过网络通信的容器可以使用这种,节省开销。


自定义网桥

      在一个宿主机上有多组容器,组与组之间要进行隔离或者某些加入多个组,这情况下需要自行通过docker network create命令去创建自定义网桥,创建成功后docker network ls会看到多出一项接口(非host/null模式时宿主机也会多块虚拟网卡); 创建时要选择模式--driver=参数指定,这个参数除了上面说的4个模式外,还有bridge,overlay,主要针对跨宿主机间的容器通信。用docker-compose启动的容器默认会创建一个名为dir_default的网桥(yml里没指定网络),而直接用docker run启动的容器默认会加入docker0网桥。

docker-compose配置参考

      下面示例定义了3个命名网络,如果当前目录是dir,则启动后产生NAME为dir_front,dir_back这2个网桥(虚拟网卡接口),default配置是当容器配置(services)当中无显式指出networks时,将使用的网络,这里是配置成使用外部网桥,名字是cppcloud_default,可以在docker network ls查看。 容器间的访问配置取别名,同一个docker-compose.yml配置的用links,不同要用external_links。

networks:
  front:
    drive: bridge

  default:
    external:
      name: cppcloud_default
  back:
    drive: bridge

 

部署过程问题  

  1. 宿主机网络出问题  

    现象:宿主机不能访问外部网络,ping 域名/ip都失败,network unreachable;
    排查:这是由于docker某些操作导致宿主机路由表被破坏了,ip route看到默认网关没有了,那肯定访问外网会有问题;至于什么操作破外了,不得知了;
    解决:手动添加一条默认网关,ip route add default via <gw_ip> dev ens33;// 你要事先查出宿主机的出口网关是什么。
  2. 运行脚本出错

    现象:出现OCI runtime exec failed: exec failed: container_linux.go:348: starting container process caused "no such file or directory": unknown;
    解决:虽然提示信息不明显,经网上找答案,这是执行到某shell脚本是存在win换行符\r,应sed -i'' "s//r//" file;
  3. dockerfile RUN合并问题

    现象:dockerfile里用一个RUN命令执行多个命令正常,拆开成多个RUN时失败;
    排查:docker build时某些RUN命令生成层时需要会启动一些临时容器去执行并生成层(layer),这也是为什么经常看到有none名字的image;如果RUN里面开启了一些tcp服务或某些进程,那么RUN结束后临时容器会关闭,后面的RUN命令将新开启新的临时容器,所以后RUN操作就不能依赖前RUN操作启动的服务了。
  4. volume映射问题

    现象:数据库遇到Error: could not exec /usr/lib/postgresql/9.3/bin/pg_ctl;
    排查:因为做volume映射时一般是root所有者,postgresql的db目录下的文件默认是postgres。
    解决:在容器里面执行chown -R postgres:postgres dir; 
    引申出docker volume文件/目录映射时,如果容器里面需要用非root用户访问时需注意;volume映射是以宿主机为主,如果想找容器里已存在的目录映射出去到一个宿主机目录,不能volume做,而应该先使用docker cp命令,再映射; window上作volume有问题,特别是非C盘下的映射,需要配置共享权限比较麻烦,建议还是在linux下做。
  5. dockerfile COPY/ADD

    dockerfile命令COPY/ADD命令的第一个参数(即原path)不能使用相对路径../xx;

 

 

 

 

 

 

/latefirstcmt/1