1. 背景

  Docker 服务启动后默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。

  Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信,它还给出了 MTU(接口允许接收的最大传输单元),通常是 1500 Bytes,或宿主主机网络路由上支持的默认值。这些值都可以在服务启动的时候进行配置。

 

2. 环境

[root@docker ~]# cat /etc/redhat-release 
CentOS Linux release 7.2.1511 (Core) 

[root@docker ~]# uname -r
3.10.0-327.36.3.el7.x86_64

[root@docker ~]# docker version
Client:
 Version:         1.12.6
 API version:     1.24
 Package version: docker-1.12.6-28.git1398f24.el7.centos.x86_64
 Go version:      go1.7.4
 Git commit:      1398f24/1.12.6
 Built:           Fri May 26 17:28:18 2017
 OS/Arch:         linux/amd64

Server:
 Version:         1.12.6
 API version:     1.24
 Package version: docker-1.12.6-28.git1398f24.el7.centos.x86_64
 Go version:      go1.7.4
 Git commit:      1398f24/1.12.6
 Built:           Fri May 26 17:28:18 2017
 OS/Arch:         linux/amd64

 

 

 

3. 实战

 * 默认docker0 网桥信息

docker 桥街物理网卡 docker0网桥_Docker

 

 * 修改文件 /etc/docker/daemon.json 添加内容 "bip": "ip/netmask" [ 切勿与宿主机同网段 ]

docker 桥街物理网卡 docker0网桥_Docker_02

 

  * 重启 docker 服务

[root@docker ~]# systemctl restart docker

 

 

 

  * 查看修改后的 docker0 网桥信息

docker 桥街物理网卡 docker0网桥_git_03

 

 

4. 总结

 

 

以需求驱动技术,技术本身没有优略之分,只有业务之分。

 

参考:

https://blog.51cto.com/lisea/1940023

 

Docker修改hosts

Docker修改hosts?这还不简单,打开vim直接敲就完事儿了!然而事与愿违,事情没有我们想的那么简单。在很多场景中,比如我们需要搭建一个集群,这时候容器要识别集群内的节点,就需要添加相应的host解析。这时就需要修改容器的hosts文件,下面我们将会看到在Docker中自动化实现修改hosts不是那么简单的事。 问题的由来 hosts文件其实并不是存储在Docker镜像中的,/etc/hosts, /etc/resolv.conf和/etc/hostname,是存在主机上的/var/lib/docker/containers/(docker_id)目录下,容器启动时是通过mount将这些文件挂载到容器内部的。因此如果在容器中修改这些文件,修改部分不会存在于容器的top layer,而是直接写入这3个文件中。容器重启后修改内容不存在的原因是Docker每次创建新容器时,会根据当前docker0下的所有节点的IP信息重新建立hosts文件。也就是说,你的修改会被Docker给自动覆盖掉。 解决办法 修改hosts一眼看上去是一件很容易的事,根据上面的分析其实不是那么简单的,如果一个分布式系统在数十个节点上,每次重新启动都要去修改hosts显得很麻烦,如何解决这一问题,目前有以下办法。 1.开启时加参数 开启容器时候添加参数–add-host machine:ip可以实现hosts修改,在容器中可以识别machine主机。缺点是很多个节点的话命令会很长,有点不舒服(当然,你可以写一个脚本了)。

例如:

# docker run -it --name alpine-test1 --add-host=test.baidu.com:192.168.1.37 docker.io/alpine

进入容器之后,直接ping 一次test.baidu.com

/ # ping -c 1 test.baidu.com
PING testgitlab.baidu.com (192.168.1.37): 56 data bytes
64 bytes from 192.168.1.37: seq=0 ttl=64 time=0.215 ms

--- testgitlab.baidu.com ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.215/0.215/0.215 ms
/ #

注意:

特别注意--add-host参数的位置,在某些位置,启动会报错的。最好在--name后面

上面这种方法适合手动方式,如果自动部署,就不适合了

2.自定义Dockerfile

# mkdir /opt/docker/test
# cd /opt/docker/test
# vim Dockerfile

内容如下:

FROM docker.io/alpine

RUN echo "#aliyun" > /etc/apk/repositories
RUN echo "https://mirrors.aliyun.com/alpine/v3.6/main/" >> /etc/apk/repositories
RUN echo "https://mirrors.aliyun.com/alpine/v3.6/community/" >> /etc/apk/repositories
RUN apk update
#自己安装的软件,不需要可以注视掉
RUN apk add openssh-client rsync

RUN mkdir /data
COPY run.sh /data/
RUN chmod +x /data/run.sh
 
ENTRYPOINT /bin/sh -c /data/run.sh

编辑脚本

# vim run.sh

内容如下:

# 向hosts文件追加内容
#cat /data/myhosts >> /etc/hosts
echo "192.168.1.37 testgitlab.kuaidihelp.com"  >> /etc/hosts
 
# 其他命令
 
# 保留终端,防止容器自动退出
/bin/sh

build镜像

# cd ../
# docker build -t test test/

使用test镜像启动一个docker

[root@testgitlab kb-test]#  docker run -it kb-test sh
/ # 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.3    58068006c8b5
192.168.1.37 testgitlab.kuaidihelp.com
/ #

如上,说明hosts写入进去了。