docker 指定IP地址、與主機同網段IP
首先講一下docker的網路模式:
我們使用docker run建立容器時,可以使用--net選項指定容器的網路模式,docker一共有4中網路模式:
1:bridge模式,--net=bridge(預設)。
這是dokcer網路的預設設定。安裝完docker,系統會自動新增一個供docker使用的網橋docker0,我們建立一個新的容器時,容器通過DHCP獲取一個與docker0同網段的IP地址。並預設連線到docker0網橋,以此實現容器與宿主機的網路互通。如下:
2:host模式,--net=host。
這個模式下建立出來的容器,將不擁有自己獨立的Network Namespace,即沒有獨立的網路環境。它使用宿主機的ip和埠。
3:container模式,--net=container:NAME_or_ID。
這個模式就是指定一個已有的容器,共享該容器的IP和埠。除了網路方面兩個容器共享,其他的如檔案系統,程式等還是隔離開的。
4:none模式,--net=none。
這個模式下,dokcer不為容器進行任何網路配置。需要我們自己為容器新增網路卡,配置IP。
因此,若想使用pipework配置docker容器的ip地址,必須要在none模式下才可以
以下是幾種分配IP的方式:
一、pipework
首先講一下docker的網路模式:
我們使用docker run建立容器時,可以使用--net選項指定容器的網路模式,docker一共有4中網路模式:
1:bridge模式,--net=bridge(預設)。
這是dokcer網路的預設設定。安裝完docker,系統會自動新增一個供docker使用的網橋docker0,我們建立一個新的容器時,容器通過DHCP獲取一個與docker0同網段的IP地址。並預設連線到docker0網橋,以此實現容器與宿主機的網路互通。如下:
2:host模式,--net=host。
這個模式下建立出來的容器,將不擁有自己獨立的Network Namespace,即沒有獨立的網路環境。它使用宿主機的ip和埠。
3:container模式,--net=container:NAME_or_ID。
這個模式就是指定一個已有的容器,共享該容器的IP和埠。除了網路方面兩個容器共享,其他的如檔案系統,程式等還是隔離開的。
4:none模式,--net=none。
這個模式下,dokcer不為容器進行任何網路配置。需要我們自己為容器新增網路卡,配置IP。
因此,若想使用pipework配置docker容器的ip地址,必須要在none模式下才可以。
pipework安裝:
# wget https://github.com/jpetazzo/pipework/archive/master.zip
# unzip pipework-master.zip
# cp pipework-master/pipework /usr/local/bin/
# chmod +x /usr/local/bin/pipework
建立none模式的容器,為其分配IP。
#ip a show docker0
#docker run -idt --name test --net=none resin
#pipework docker0 test 172.17.42.100/16@172.17.42.1
#docker attach test
以上操作給新建的test容器分配了一個172.17.42.100的IP地址。
=============================================================================
二、 docker預設使用'bridge'來設定container的網路模式(即從與docker0同網段的未使用的IP中取一個作為container的IP),我們這裡使用'none'來實現自己手動配置container的網路。
首先我們以**--net='none'**的方式啟動一個container
[yaxin@cube2x ~]$docker run -i -t --rm --net='none' ubuntu /bin/bash
root@db84e747c362:/# ifconfig -a
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
root@db84e747c362:/#
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
root@db84e747c362:/#
可以看到,由於我們使用'none'模式,container中沒有獲取到IP,甚至連網路卡都沒有,下面我們開始給container配置IP
首先獲取container的pid(我們需要通過pid獲取file descriptor)
[yaxin@cube2x ~]$docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
db84e747c362 docker.cn/docker/ubuntu:latest "/bin/bash" 4 minutes ago Up 4 minutes sharp_kirch
[yaxin@cube2x ~]$docker inspect -f "{{.State.Pid}}" sharp_kirch
23090
23090
ip-netns的man page中有這樣一句
By convention a named network namespace is an object at /var/run/netns/NAME that can be opened. The file descriptor resulting from opening/var/run/netns/NAME refers to the specified network namespace
因而我們需要建立一個連結
[yaxin@cube2x ~]$sudo ln -s /proc/23090/ns/net /var/run/netns/23090
然後建立一對端到端的網路卡,將veth_db84e747c3繫結到docker0網橋,並啟動。將另一塊網路卡X放到container內部
[yaxin@cube2x ~]$sudo ip link add veth_db84e747c3 type veth peer name X
[yaxin@cube2x ~]$sudo brctl addif docker0 veth_db84e747c3
[yaxin@cube2x ~]$sudo ip link set veth_db84e747c3 up
[yaxin@cube2x ~]$sudo ip link set X netns 23090
這時檢視container的IP,會發現多了一個名為X的網路卡
root@db84e747c362:/# ifconfig -aX Link encap:Ethernet HWaddr 5a:7e:4d:ba:63:1c
BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
然後對container內部新新增的網路卡進行配置(可以通過man ip-netns更詳細檢視)
[yaxin@cube2x ~]$sudo ip netns exec 23090 ip link set dev X name eth0
[yaxin@cube2x ~]$sudo ip netns exec 23090 ip link set eth0 up
[yaxin@cube2x ~]$sudo ip netns exec 23090 ip addr add 172.17.111.10/16 dev eth0
[yaxin@cube2x ~]$sudo ip netns exec 23090 ip route add default via 172.17.42.1
注意: 指定給container的IP必須跟docker0在同一網段,且給container的閘道器應該為docker0的IP
最後,寫成shell指令碼如下:
#!/usr/bin/env bash# filename: bind_addr.sh
if [ `id -u` -ne 0 ];then
echo '必須使用root許可權'
exitfi
if [ $# != 2 ]; then
echo "使用方法: $0 容器名字 IP"
exit 1fi
container_name=$1bind_ip=$2
container_id=`docker inspect -f '{{.Id}}' $container_name 2> /dev/null`
if [ ! $container_id ];then
echo "容器不存在"
exit 2fibind_ip=`echo $bind_ip | egrep '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$'`
if [ ! $bind_ip ];then
echo "IP地址格式不正確"
exit 3fi
container_minid=`echo $container_id | cut -c 1-10`
container_netmask=`ip addr show docker0 | grep "inet\b" | awk '{print $2}' | cut -d / -f2`
container_gw=`ip addr show docker0 | grep "inet\b" | awk '{print $2}' | cut -d / -f1`
bridge_name="veth_$container_minid"
container_ip=$bind_ip/$container_netmask
pid=`docker inspect -f '{{.State.Pid}}' $container_name 2> /dev/null`
if [ ! $pid ];then
echo "獲取容器$container_name的id失敗"
exit 4fi
if [ ! -d /var/run/netns ];then
mkdir -p /var/run/netns
fi
ln -sf /proc/$pid/ns/net /var/run/netns/$pid
ip link add $bridge_name type veth peer name X
brctl addif docker0 $bridge_name
ip link set $bridge_name up
ip link set X netns $pid
ip netns exec $pid ip link set dev X name eth0
ip netns exec $pid ip link set eth0 up
ip netns exec $pid ip addr add $container_ip dev eth0
ip netns exec $pid ip route add default via $container_gw
執行並寫入ip和容器名稱
配置容器與主機IP同一網段
先配置主機br0
vi /etc/sysconfig/network-scripts/ifcfg-br0
DEVICE=br0
TYPE=Bridge
BOOTPROTO=static
ONBOOT=yes
DELAY=0
STP=yes
IPADDR=192.168.2.111
NETMASK=255.255.255.0
GATEWAY=192.168.2.1
/etc/init.d/network restart
docker run -itd --name test centos /bin/bash
pipework br0 test 192.168.2.201/24@192.168.2.1
相關文章
- IP地址、子網掩碼、網路號、主機號、網路地址、主機地址
- 將虛擬機器IP與主機IP設定在同一網段的方法虛擬機
- docker 指定 ipDocker
- IP地址網段求解題(轉)
- yandexbot ip 地址段
- 計算機網路知識總結:有關IP地址、子網掩碼、網路號、主機號、網路地址、主機地址以及ip段/數字的概念及筆試題計算機網路筆試
- IP地址網段表示法總結
- solaris 主機修改主機名 ip地址 步驟
- 識別主機名和IP地址
- HP-UX修改主機IP地址UX
- 14IP地址、主機名、域名
- 計算機網路之二:IP地址與MAC地址計算機網路Mac
- docker 指定ip開容器,並且和內網在同一個網段薦Docker內網
- 11gr2 rac改IP系列之一:修改公網IP為同網段其它IP
- 更改solaris主機名及ip地址(zt)
- 更改solaris IP地址和主機名(轉)
- 網路裝置配置與管理————11、配置主機名、時鐘、IP地址
- MAC 地址與IP地址Mac
- 徹底弄懂ip掩碼中的網路地址、廣播地址、主機地址
- 11gr2 rac改IP系列之三:修改SCAN IP為同網段其它IP
- docker檢視容器IP地址Docker
- Oracle中獲取主機名和IP地址Oracle
- linux22-IP地址和主機名Linux
- 《網路IP地址管理》IP地址重要性薦
- 同網段不同網段主機間通訊原理
- 得到計算機的主機名和IP地址 (轉)計算機
- 檢視Google Cloud的IP地址段GoCloud
- gethostbyname() -- 用域名或主機名獲取IP地址
- 在cmd中獲取ip地址和主機名
- 【TCP/IP】IP地址分類和特殊IP地址TCP
- 通過IP地址和子網掩碼,如何計算出網路地址、廣播地址和主機數?
- 11gr2 rac改IP系列之二:修改VIP為同網段其它IP
- IP地址分類與子網劃分
- 電腦ip地址在哪看 電腦本地ip地址和網際網路ip地址有什麼區別
- docker固定IP地址重啟不變Docker
- IP地址的概念及IP子網劃分
- Solaris 10.5配置主機名、IP地址、閘道器
- 將某一主機域名解析為IP地址。 (轉)