docker-proxy #02
dockerでサービスを公開する場合、次2パターンがある
- 通信をコンテナに転送する
- ホストで動いているdocker-proxyを利用する
後者はdocker-proxyが仲介する分、パフォーマンス的に劣ると思われる。
docker-proxyの無効化は特定のコンテナに対しては行えず、docker-daemonのグローバルなオプション設定になる。
# vi /etc/docker/daemon.json
{
~省略~
"userland-proxy": false
}
# ss -lp | grep docker-proxy
tcp LISTEN 0 128 *:https *:* users:(("docker-proxy",pid=17639,fd=4))
tcp LISTEN 0 128 *:http *:* users:(("docker-proxy",pid=17651,fd=4))
# systemctl restart docker
# docker ps
~省略~
# ss -lp | grep docker-proxy
#
IPv6アクセスの場合はdocker-proxyを利用していた場合、IPv6の転送ルールを設定しないとIPv6によるアクセスが行えなくなる。
まずはコンテナのIPv6を有効化する。docker-composeを編集し、コンテナを再起動する。
version: '2.3'
services:
httpd:
image: nginx:1.19.0-alpine
container_name: 'httpd'
init: true
networks:
nw:
ipv4_address: "192.168.10.10"
ipv6_address: "fd00:abcd:abcd:abcd::10"
ports:
- 80:80/tcp
- 443:443/tcp
restart: unless-stopped
networks:
nw:
enable_ipv6: true
driver: bridge
ipam:
driver: default
config:
- subnet: "192.168.10.0/24"
gateway: "192.168.10.1"
- subnet: "fd00:abcd:abcd:abcd::/64"
gateway: "fd00:abcd:abcd:abcd::1"
driver_opts:
com.docker.network.bridge.name: docker_httpd
Firewalldにルールを追加する。
# vi ipv6_nat.sh
====================================================
#!/bin/bash -eux
LANG=C
add_chain="firewall-cmd --permanent --direct --add-chain "
add_rule="firewall-cmd --permanent --direct --add-rule "
### PREROUTING(dnat)
${add_chain} ipv6 nat DOCKER_DNAT
${add_rule} ipv6 nat DOCKER_DNAT 100 -p tcp --dport 80 -j DNAT --to-destination fd00:abcd:abcd:abcd::10
${add_rule} ipv6 nat DOCKER_DNAT 110 -p tcp --dport 443 -j DNAT --to-destination fd00:abcd:abcd:abcd::10
${add_rule} ipv6 nat PREROUTING 100 -i eth0 -j DOCKER_DNAT
### POSTROUTING(snat)
${add_chain} ipv6 nat DOCKER_SNAT
${add_rule} ipv6 nat DOCKER_SNAT 100 -o eth0 -s fd00:abcd:abcd:abcd::64 -j MASQUERADE
${add_rule} ipv6 nat POSTROUTING 100 -o eth0 -j DOCKER_SNAT
作成したスクリプトを適用し、コンテナ内部から外部へのIPv6通信確認を行う。今回は公開されているDNSサーバへのpingテストとしている。
# sh ipv6_nat.sh
# firewall-cmd --reload
success
# docker exec -it httpd /bin/sh
/ # ip a | grep fd00
inet6 fd00:abcd:abcd:abcd::20/64 scope global flags 02
/ #
/ # ping 2606:4700:4700::1111
PING 2606:4700:4700::1111 (2606:4700:4700::1111): 56 data bytes
64 bytes from 2606:4700:4700::1111: seq=0 ttl=55 time=9.830 ms
外部からの通信確認も行う。
# curl -gv "http://[ホストのIPv6アドレス]"
* Trying ホストのIPv6アドレス:80...
* Connected to ホストのIPv6アドレス (ホストのIPv6アドレス) port 80 (#0)
上手くいかない場合はパケット転送の有効化が出来ているかを確認する。openSUSEの場合はyastから設定可能。
# sysctl -a | grep forward
~省略~
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.all.mc_forwarding = 0
~省略~
v6の転送周りの設定は未だ安定しない感じがする。今回はraspberry pi4+openSUSE Tumbleweedで設定ができたが、同じくopenSUSEのLeapを使っている別サーバではNICの転送設定を行うとDHCPv6がうまく動かなくなり、期待通りの動きをしなかった。