前段时间,我一直在研究如何给docker分配静态ip,主要的用途是让thrift进来和出来都走一个ip,还有就是爬虫可以独立ip地址,这样就很好的实现了爬虫的多ip方式… 但是随着nginx tcp的加入和开发了一个基于python socket的ip轮询访问模块解决了这两个问题… 当然也不能因为这两问题,就丢弃这问题了….
在docker run的时候,咱们可以添加-p参数来控制他的source来源ip。 下面的命令,对外来说,开放了192.168.1.200:9200的端口… 但是我们不仅仅满与此。 docker run -p 端口的实现,就是借用iptables来实现的… 我们iptables -t nat -L 的时候,就能看到docker帮我做好的nat关系…. docker做iptables的prerouting的时候,是追加了名叫docker的自定义链条… 差点又跑题了,如果是桥接模式,那么就致使当我们如果容器里面端口的变动比较大的时候,那么就会造成改动端口映射的操作的复杂性,需要每次的变更,做一个iptables prerouting映射… 但是如果你选择HOST网络模式,那么你又不好确定你的app绑定的是哪个ip地址,不是什么服务端都支持bind ip地址的… 有些搓蛋的服务端就默认绑定第一个ip地址… 这个时候,为docker容器分配一个独立的静态ip地址就显得很有必要了…. 反正就一个ip地址,你可劲的折腾…..
Python
docker run - it - p 192.168.1.200 : 9200 : 9200 redis _cluster 9200
Python
root @ ubuntu : ~ # iptables -t nat -L -n
Chain PREROUTING ( policy ACCEPT )
target prot opt source destination
DOCKER all -- 0.0.0.0 / 0 0.0.0.0 / 0 ADDRTYPE match dst - type LOCAL
Chain INPUT ( policy ACCEPT )
target prot opt source destination
Chain OUTPUT ( policy ACCEPT )
target prot opt source destination
DOCKER all -- 0.0.0.0 / 0 ! 127.0.0.0 / 8 ADDRTYPE match dst - type LOCAL
Chain POSTROUTING ( policy ACCEPT )
target prot opt source destination
MASQUERADE all -- 172.17.0.0 / 16 0.0.0.0 / 0
MASQUERADE all -- 172.17.0.0 / 16 ! 172.17.0.0 / 16
MASQUERADE tcp -- 172.17.0.1 172.17.0.1 tcp dpt : 9200
Chain DOCKER ( 2 references )
target prot opt source destination
DNAT tcp -- 0.0.0.0 / 0 0.0.0.0 / 0 tcp dpt : 9200 to : 172.17.0.1 : 9200
需要注意的是,docker run创建一个容器的时候,一定要把他的网卡模式改成docker的none… 一般在docker自定义网络的时候,都会把–net=none,再通过后期的一顿折腾让docker的容器有网络…..
接着,我如果想给容器,彻底的分配一个外网ip,或者管理ip,反正就一个静态的独立ip,怎么破? 用pipework是可以实现的。 但这东西稍复杂些,我们就先用系统的ip netns来解决…. 通过inspect我们知道了他的state pid .
Python
root @ ubuntu : ~ # docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
232621e9e9fb redis _cluster "/app/manage.sh 9000 41 minutes ago Up 41 minutes agitated_blackwell
root@ubuntu:~# docker inspect -f " { { . State . Pid } }" 232621e9e9fb
4777
root @ ubuntu : ~ # pid=4777
那么我们来开始绑定静态ip地址,先别看原理,暂时照着做…
Python
mkdir - p / var / run / netns
ln - s / proc / $ pid / ns / net / var / run / netns / $ pid ip link add A type veth peer name B
brctl addif docker0 A
ip link set A up
ip link set B netns $ pid
ip netns exec $ pid ip link set dev B name eth0
ip netns exec $ pid ip link set eth0 up
ip netns exec $ pid ip addr add 192.168.1.200 / 24 dev eth0
ip netns exec $ pid ip route add default via 192.168.1.1
这些都结束了后,我们会发现容器的网卡里面从一个lo,多出一个eth0网卡,网卡的ip地址正是我们刚才绑定的192.168.1.200
Python
bash - 4.1 # ip a
1 : lo : < LOOPBACK , UP , LOWER_UP > mtu 65536 qdisc noqueue state UNKNOWN
link / loopback 00 : 00 : 00 : 00 : 00 : 00 brd 00 : 00 : 00 : 00 : 00 : 00
inet 127.0.0.1 / 8 scope host lo
valid_lft forever preferred_lft forever
inet6 :: 1 / 128 scope host
valid_lft forever preferred_lft forever
22 : eth0 : < BROADCAST , MULTICAST , UP , LOWER_UP > mtu 1500 qdisc pfifo_fast state UP qlen 1000
link / ether ca : aa : 87 : 05 : c9 : 5a brd ff : ff : ff : ff : ff : ff
inet 192.168.1.200 / 24 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80 :: c8aa : 87ff : fe05 : c95a / 64 scope link
valid_lft forever preferred_lft forever
bash - 4.1 #
到此为止,docker绑定固定的静态ip的方法已经说明白了…. 看了文章后,会发现docker绑定ip是比较的简单.. docker的网络是不怎么好理解的,这两天我多专供下docker分配ip的整个流程 (docker iptables)