dockerコンテナネットワーク構成
8303 ワード
文書ディレクトリ
Linuxカーネルによるネームスペースの作成
Network Namespaceの作成
コマンドを使用してns 0という名前のネーミングスペースを作成します.
[root@docker ~]# ip netns list
[root@docker ~]# ip netns add ns0
[root@docker ~]# ip netns list
ns0
新しく作成したNetwork Namespaceが/var/run/netns/ディレクトリに表示されます.同じ名前のnamespaceが既に存在する場合、コマンドはCannot create namespace file'/var/run/netns/ns 0::File existsのエラーを報告します.
[root@docker ~]# ls /var/run/netns/
ns0
[root@docker ~]# ip netns add ns0
Cannot create namespace file "/var/run/netns/ns0": File exists
各Network Namespaceには、独自のNIC、ルーティングテーブル、ARPテーブル、iptablesなど、ネットワーク関連のリソースがあります.
Network Namespaceの操作
ipコマンドは、ip netns execサブコマンドを提供し、対応するNetwork Namespaceでコマンドを実行できます.
Network Namespaceを新しく作成したNIC情報の表示
root@docker ~]# ip netns exec ns0 ip addr
1: lo: mtu 65536 qdisc noop state DOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
新しく作成したNetwork Namespaceでは、デフォルトでloループNICが作成され、NICがオフになっていることがわかります.このとき、このloループNICをpingしてみると、Network is unreachableにプロンプトが表示されます.
[root@docker ~]# ip netns exec ns0 ping 127.0.0.1
connect: Network is unreachable
次のコマンドでloループNICを有効にします.
[root@docker ~]# ip netns exec ns0 ip link set lo up
[root@docker ~]# ip netns exec ns0 ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.099 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.077 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.078 ms
トランスファデバイス
異なるNetwork Namespace間でデバイス(vethなど)を転送できます.1つのデバイスが1つのNetwork Namespaceにしか属していないため、移行後、このNetwork Namespace内ではこのデバイスが見えなくなります.
ここでvethデバイスは転送可能デバイスに属し、lo、vxlan、ppp、bridgeなどの多くの他のデバイスは転送できない.
veth pairの作成
[root@docker ~]# ip link add type veth
[root@docker ~]# ip a
36: veth0@veth1: mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 42:a8:5e:58:b7:1d brd ff:ff:ff:ff:ff:ff
37: veth1@veth0: mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 8e:4e:f5:7e:7e:b8 brd ff:ff:ff:ff:ff:ff
Network Namespace間通信の実装
次に、veth pairを使用して、2つの異なるNetwork Namespace間の通信を実現します.先ほどns 0という名前のNetwork Namespaceを作成しましたが、次にns 1という名前の情報Network Namespaceを作成します.
[root@docker ~]# ip netns add ns1
[root@docker ~]# ip netns list
ns1
ns0
次にveth 0をns 0に加えveth 1をns 1に加えます
[root@docker ~]# ip link set veth0 netns ns0
[root@docker ~]# ip link set veth1 netns ns1
次にveth pairのipアドレスをそれぞれ構成し、有効にします.
[root@docker ~]# ip netns exec ns0 ip link set veth0 up
[root@docker ~]# ip netns exec ns0 ip addr add 10.0.0.1/24 dev veth0
[root@docker ~]# ip netns exec ns1 ip link set veth1 up
[root@docker ~]# ip netns exec ns1 ip addr add 10.0.0.1/24 dev veth1
[root@docker ~]# ip netns exec ns1 ip link set lo up
このveth pairのステータスを表示
[root@docker ~]# ip netns exec ns0 ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN qlen 1
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
36: veth0@if37: mtu 1500 qdisc noqueue state UP qlen 1000
link/ether 42:a8:5e:58:b7:1d brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet 10.0.0.1/24 scope global veth0
valid_lft forever preferred_lft forever
inet6 fe80::40a8:5eff:fe58:b71d/64 scope link
valid_lft forever preferred_lft forever
[root@docker ~]# ip netns exec ns1 ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN qlen 1
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
37: veth1@if36: mtu 1500 qdisc noqueue state UP qlen 1000
link/ether 8e:4e:f5:7e:7e:b8 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.0.0.1/24 scope global veth1
valid_lft forever preferred_lft forever
inet6 fe80::8c4e:f5ff:fe7e:7eb8/64 scope link
valid_lft forever preferred_lft forever
以上から,このveth pairを有効にし,各vethデバイスに対応するipアドレスを割り当てることに成功したことが分かる.ns 1でns 0のipアドレスにアクセスしてみます.
[root@docker ~]# ip netns exec ns1 ping 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.095 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.086 ms
64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=0.060 ms
vethデバイス名の変更
[root@docker ~]# ip netns exec ns0 ifconfig -a
eth0: flags=4098 mtu 1500
inet 10.0.0.1 netmask 255.255.255.0 broadcast 0.0.0.0
ether 42:a8:5e:58:b7:1d txqueuelen 1000 (Ethernet)
RX packets 8 bytes 648 (648.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73 mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10
loop txqueuelen 1 (Local Loopback)
RX packets 10 bytes 840 (840.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 10 bytes 840 (840.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@docker ~]# ip netns exec ns0 ip link set eth0 up
コンテナの一般的な操作
コンテナホスト名の表示
[root@salt1 ~]# docker run -it --name t1 --network bridge --rm busybox
/ # hostname
2caa42691e68
コンテナ起動時にホスト名を入力
[root@salt1 ~]# docker run -it --name t1 --network bridge --hostname hello --rm busybox
/ # hostname
hello
/ # 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.2 hello // IP
/ # cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 114.114.114.114 //DNS DNS
/ # ping www.baidu.com
PING www.baidu.com (39.156.66.18): 56 data bytes
64 bytes from 39.156.66.18: seq=0 ttl=127 time=63.355 ms
64 bytes from 39.156.66.18: seq=1 ttl=127 time=54.062 ms
64 bytes from 39.156.66.18: seq=2 ttl=127 time=52.691 ms
コンテナで使用するDNSを手動で指定
[root@salt1 ~]# docker run -it --name t1 --network bridge --hostname hello --dns 192.168.174.2 --rm busybox
/ # cat /etc/resolv.conf
nameserver 192.168.174.2
/ # nslookup -type=a www.baidu.com
Server: 192.168.174.2
Address: 192.168.174.2:53
Non-authoritative answer:
www.baidu.com canonical name = www.a.shifen.com
Name: www.a.shifen.com
Address: 39.156.66.14
Name: www.a.shifen.com
Address: 39.156.66.18
IPアドレスへのホスト名のマッピングを/etc/hostsファイルに手動で注入
[root@salt1 ~]# docker run -it --name t1 --network bridge --hostname hello --add-host www.a.com:1.1.1.1 --rm busybox
/ # 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
1.1.1.1 www.a.com
172.17.0.2 hello
オープンコンテナポート
docker runを実行するときに-pオプションがあり、コンテナ内のアプリケーションポートをシンクホストにマッピングし、外部ホストがシンクホストのポートにアクセスすることでコンテナ内のアプリケーションにアクセスできるようにする目的を実現します.
-pオプションは複数回使用できます.露出可能なポートは、コンテナが実際に傍受しているポートである必要があります.
-pオプションの使用形式:
ダイナミックポートとはランダムポートを指し、具体的なマッピング結果はdocker portコマンドで表示できます.