2018년 1월 11일 목요일
ppc64le에서의 flannel 구성 : host 서버 외부로의 docker container network 구성
서로 다른 두대의 물리적 서버에 각각 위치한 docker container들끼리 network 통신을 할 수 있도록 설정하는 방법입니다. 한줄 요약하자면 여기에는 flanneld를 구성해야 하며, 이를 위해서는 먼저 etcd를 구성해야 합니다.
이 테스트에는 아래 site들을 참조했습니다.
http://docker-k8s-lab.readthedocs.io/en/latest/docker/docker-etcd.html
http://docker-k8s-lab.readthedocs.io/en/latest/docker/docker-flannel.html
http://cloudgeekz.com/1016/configure-flannel-docker-power.html
https://www.ibm.com/developerworks/community/blogs/mhhaque/entry/Docker_And_Kubernetes_Cluster_on_Power_with_RHEL7_Part_2_etcd_flanneld_daemons_on_master_node?lang=en
https://www.ibm.com/developerworks/community/blogs/mhhaque/entry/Docker_And_Kubernetes_Cluster_on_Power_with_RHEL7_Part_3_flanneld_docker_daemons_on_Docker_Container_node?lang=en
서버 환경은 IBM POWER8 Ubuntu 16.04 ppc64le이며, 두 대 서버의 hostname과 IP는 다음과 같습니다.
물리적서버 #1 sys-90725 172.29.160.221
물리적서버 #2 sys-90754 172.29.160.207
먼저 etcd를 설치합니다. 이건 flanneld 구성을 위해 필요한 일종의 key-value store입니다. Ubuntu OS에 포함된 것을 그대로 이용하시면 됩니다.
u0017649@sys-90725:~$ sudo apt-get install etcd
설정값은 아래와 같이 /etc/default/etcd에 정리합니다.
u0017649@sys-90725:~$ sudo vi /etc/default/etcd
ETCD_NAME=sys-90725
ETCD_DATA_DIR="/var/lib/etcd/default"
ETCD_LISTEN_CLIENT_URLS="http://172.29.160.221:2379,http://127.0.0.1:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://172.29.160.221:2379"
물론 서버#2에는 거기에 맞는 hostname과 IP를 입력해야 합니다.
u0017649@sys-90754:~$ sudo vi /etc/default/etcd
ETCD_NAME=sys-90754
ETCD_DATA_DIR="/var/lib/etcd/default"
ETCD_LISTEN_CLIENT_URLS="http://172.29.160.270:2379,http://127.0.0.1:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://172.29.160.207:2379"
etcd를 start하고, 제대로 작동 중인지 확인합니다.
u0017649@sys-90725:~$ sudo systemctl enable etcd
u0017649@sys-90725:~$ sudo systemctl start etcd
u0017649@sys-90725:~$ sudo systemctl status etcd
● etcd.service - etcd - highly-available key value store
Loaded: loaded (/lib/systemd/system/etcd.service; enabled; vendor preset: enabl
Active: active (running) since Mon 2018-01-08 03:11:40 EST; 6min ago
Docs: https://github.com/coreos/etcd
man:etcd
Main PID: 6100 (etcd)
CGroup: /system.slice/etcd.service
└─6100 /usr/bin/etcd
이어서, flanneld 구성 정보를 다음과 같이 json 파일로 작성합니다. 두 대의 서버에 동일한 내용으로 작성합니다.
u0017649@sys-90725:~$ vi flannel-config-vxlan.json
{
"Network": "10.172.29.0/16",
"SubnetLen": 24,
"Backend": {
"Type": "vxlan",
"VNI": 1
}
}
이제 이 file을 아래와 같이 etcd에 집어넣습니다. /atomic.io/network/config은 물리적 file name도 아니고 internet 주소도 아님에 유의하세요.
u0017649@sys-90725:~$ sudo etcdctl set /atomic.io/network/config < flannel-config-vxlan.json
제대로 들어갔는지 확인은 아래와 같이 합니다.
u0017649@sys-90725:~$ sudo etcdctl get /atomic.io/network/config
{
"Network": "10.172.29.0/16",
"SubnetLen": 24,
"Backend": {
"Type": "vxlan",
"VNI": 1
}
}
etcd가 정상 작동 중인지는 아래와 같은 방법으로 하실 수 있습니다.
u0017649@sys-90725:~$ curl -L http://sys-90725:2379/v2/keys/atomic.io/network/config
{"action":"get","node":{"key":"/atomic.io/network/config","value":"{\n \"Network\": \"10.172.29.0/16\",\n \"SubnetLen\": 24,\n \"Backend\": {\n \"Type\": \"vxlan\",\n \"VNI\": 1\n }\n}\n","modifiedIndex":4,"createdIndex":4}}
u0017649@sys-90725:~$ etcdctl cluster-health
member ce2a822cea30bfca is healthy: got healthy result from http://0.0.0.0:2379
cluster is healthy
이제 flannel를 설치해야 하는데, 이건 아직 Ubuntu OS에 들어있지 않습니다. 별 수 없이 build를 해야 하는데, 여기에 버전 1.7 이상의 golang을 쓰셔야 합니다. Default로 있는 golang 1.6을 쓰시면 error가 나니 유의하십시요.
u0017649@sys-90725:~$ sudo apt-get install linux-libc-dev golang-1.9 golang-1.9-go
u0017649@sys-90754:~$ sudo rm /usr/bin/go
u0017649@sys-90754:~$ sudo ln -s /usr/lib/go-1.9/bin/go /usr/bin/go
그냥 github의 flannel을 그대로 복제하여 build하면 역시 또 error가 납니다. 해서 다음과 같이 약간의 꼼수가 필요합니다. 즉, src/github.com/coreos라는 directory를 먼저 만들고, 그 속에 들어가서 github을 복제하십시요.
u0017649@sys-90725:~$ export GOPATH=$(pwd)
u0017649@sys-90725:~$ mkdir -p src/github.com/coreos
u0017649@sys-90725:~$ cd src/github.com/coreos
u0017649@sys-90725:~/src/github.com/coreos$ git clone https://github.com/coreos/flannel.git
이제 build 시작하기 전에, Makefile에 손을 좀 대야 합니다. 이유는 Makefile에 ppc64le도 있긴 한데 amd64를 default로 채택하게 되어 있기 때문에, 그를 ppc64le로 바꾸는 작업입니다. 우리는 여기서 make targ.gz을 할 것이니, 많은 entry 중에서 그 부분만 놔두고 #으로 막으면 됩니다.
(또는 그냥 ~/src/github.com/coreos/flannel 에 들어가서 "make dist/flanneld"만 수행해도 됩니다. 필요한 건 flanneld 뿐이거든요.)
u0017649@sys-90725:~/src/github.com/coreos$ cd flannel
u0017649@sys-90725:~/src/github.com/coreos/flannel$ export CGO_ENABLED=1
u0017649@sys-90725:~/src/github.com/coreos/flannel$ vi Makefile
# Default tag and architecture. Can be overridden
#TAG?=$(shell git describe --tags --dirty)
TAG?=v0.9.0-34-gab368026-ppc64le # from https://quay.io/repository/coreos/flannel-git?tab=tags
#ARCH?=amd64
ARCH?=ppc64le
#GO_VERSION=1.8.3
GO_VERSION=1.9.2
...
tar.gz:
# ARCH=ppc64le make dist/flanneld-ppc64le
# tar --transform='flags=r;s|-ppc64le||' -zcvf dist/flannel-$(TAG)-linux-ppc64le.tar.gz -C dist flanneld-ppc64le mk-docker-opts.sh ../README.md
# tar -tvf dist/flannel-$(TAG)-linux-ppc64le.tar.gz
# ARCH=ppc64le make dist/flanneld.exe
# tar --transform='flags=r;s|-ppc64le||' -zcvf dist/flannel-$(TAG)-windows-ppc64le.tar.gz -C dist flanneld.exe mk-docker-opts.sh ../README.md
# tar -tvf dist/flannel-$(TAG)-windows-ppc64le.tar.gz
ARCH=ppc64le make dist/flanneld-ppc64le
tar --transform='flags=r;s|-ppc64le||' -zcvf dist/flannel-$(TAG)-linux-ppc64le.tar.gz -C dist flanneld-ppc64le mk-docker-opts.sh ../README.md
tar -tvf dist/flannel-$(TAG)-linux-ppc64le.tar.gz
# ARCH=arm make dist/flanneld-arm
# tar --transform='flags=r;s|-arm||' -zcvf dist/flannel-$(TAG)-linux-arm.tar.gz -C dist flanneld-arm mk-docker-opts.sh ../README.md
# tar -tvf dist/flannel-$(TAG)-linux-arm.tar.gz
# ARCH=arm64 make dist/flanneld-arm64
# tar --transform='flags=r;s|-arm64||' -zcvf dist/flannel-$(TAG)-linux-arm64.tar.gz -C dist flanneld-arm64 mk-docker-opts.sh ../README.md
# tar -tvf dist/flannel-$(TAG)-linux-arm64.tar.gz
# ARCH=s390x make dist/flanneld-s390x
# tar --transform='flags=r;s|-s390x||' -zcvf dist/flannel-$(TAG)-linux-s390x.tar.gz -C dist flanneld-s390x mk-docker-opts.sh ../README.md
# tar -tvf dist/flannel-$(TAG)-linux-s390x.tar.gz
그 다음에 make tar.gz을 합니다.
u0017649@sys-90725:~/src/github.com/coreos/flannel$ make tar.gz
오래 걸리지 않아 아래와 같이 tar.gz이 만들어집니다.
u0017649@sys-90725:~/src/github.com/coreos/flannel$ ls -l dist/*.tar.gz
-rw-rw-r-- 1 u0017649 u0017649 8179227 Jan 8 23:26 dist/flannel-v0.9.0-34-gab368026-ppc64le-linux-ppc64le.tar.gz
이걸 적절한 위치(여기서는 /usr/local/bin)에 풀어놓습니다.
u0017649@sys-90725:~/src/github.com/coreos/flannel$ cd /usr/local/bin
u0017649@sys-90725:/usr/local/bin$ sudo tar -xvf ~/src/github.com/coreos/flannel/dist/flannel-v0.9.0-34-gab368026-ppc64le-linux-ppc64le.tar.gz
flanneld
mk-docker-opts.sh
README.md
flanneld 구성에 들어가기 전에 먼저 docker daemon을 stop 시키고 docker0도 삭제합니다.
u0017649@sys-90725:~$ sudo systemctl stop docker.service
u0017649@sys-90725:~$ sudo ip link delete docker0
이제 다음과 같이 /lib/systemd/system/flanneld.service 와 /etc/default/flanneld 파일을 만들어 systemctl에 flanneld 서비스를 등록합니다.
u0017649@sys-90725:~$ sudo vi /lib/systemd/system/flanneld.service
[Unit]
Description=Flanneld overlay address etcd agent
After=network.target
After=network-online.target
Wants=network-online.target
After=etcd.service
Before=docker.service
[Service]
Type=notify
EnvironmentFile=-/etc/default/flanneld
ExecStart=/usr/local/bin/flanneld -etcd-endpoints=${FLANNEL_ETCD} -etcd-prefix=${FLANNEL_ETCD_KEY} $FLANNEL_OPTIONS
Restart=on-failure
[Install]
WantedBy=multi-user.target
RequiredBy=docker.service
u0017649@sys-90725:~$ sudo vi /etc/default/flanneld
# Flanneld configuration options
# etcd url location. Point this to the server where etcd runs
FLANNEL_ETCD="http://172.29.160.221:2379"
# etcd config key. This is the configuration key that flannel queries
# For address range assignment
FLANNEL_ETCD_KEY="/atomic.io/network"
# Any additional options that you want to pass
FLANNEL_OPTIONS="-ip-masq=true"
이제 flanneld를 start 하고, 정상 작동하는지 확인합니다.
u0017649@sys-90725:~$ sudo systemctl start flanneld
u0017649@sys-90725:~$ sudo systemctl status flanneld
● flanneld.service - Flanneld overlay address etcd agent
Loaded: loaded (/lib/systemd/system/flanneld.service; disabled; vendor preset: enabled)
Active: active (running) since Wed 2018-01-10 20:21:19 EST; 28s ago
Main PID: 10666 (flanneld)
Tasks: 10
Memory: 8.8M
CPU: 266ms
CGroup: /system.slice/flanneld.service
└─10666 /usr/local/bin/flanneld -etcd-endpoints=http://172.29.160.221:2379 -etcd-prefix=/atomic.io
Jan 10 20:21:19 sys-90725 flanneld[10666]: I0110 20:21:19.761758 10666 main.go:238] Installing signal handl
Jan 10 20:21:19 sys-90725 flanneld[10666]: I0110 20:21:19.764142 10666 main.go:353] Found network config -
Jan 10 20:21:19 sys-90725 flanneld[10666]: I0110 20:21:19.764234 10666 vxlan.go:120] VXLAN config: VNI=1 Po
Jan 10 20:21:19 sys-90725 flanneld[10666]: I0110 20:21:19.830878 10666 local_manager.go:201] Found previous
Jan 10 20:21:19 sys-90725 flanneld[10666]: I0110 20:21:19.859766 10666 local_manager.go:220] Allocated leas
Jan 10 20:21:19 sys-90725 flanneld[10666]: I0110 20:21:19.860247 10666 main.go:300] Wrote subnet file to /r
Jan 10 20:21:19 sys-90725 flanneld[10666]: I0110 20:21:19.860273 10666 main.go:304] Running backend.
Jan 10 20:21:19 sys-90725 systemd[1]: Started Flanneld overlay address etcd agent.
Jan 10 20:21:19 sys-90725 flanneld[10666]: I0110 20:21:19.862149 10666 vxlan_network.go:60] watching for ne
Jan 10 20:21:19 sys-90725 flanneld[10666]: I0110 20:21:19.889547 10666 main.go:396] Waiting for 22h59m59.94
이제 보면 /run/flannel/subnet.env 이라는 파일이 생성되고 그 속에 관련 환경변수 정보가 기록된 것을 보실 수 있습니다.
u0017649@sys-90725:~$ cat /run/flannel/subnet.env
FLANNEL_NETWORK=10.172.0.0/16
FLANNEL_SUBNET=10.172.61.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true
flannel.1이라는 interface도 새로 생성되는데, 다음과 같습니다.
u0017649@sys-90725:~$ ifconfig flannel.1
flannel.1 Link encap:Ethernet HWaddr 66:bc:02:fe:88:b3
inet addr:10.172.61.0 Bcast:0.0.0.0 Mask:255.255.255.255
inet6 addr: fe80::64bc:2ff:fefe:88b3/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1
RX packets:846 errors:0 dropped:0 overruns:0 frame:0
TX packets:679 errors:0 dropped:8 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:77685 (77.6 KB) TX bytes:77345 (77.3 KB)
이제 이 정보를 이용해 docker daemon의 설정값을 바꾸어 줍니다.
u0017649@sys-90725:~$ sudo vi /etc/systemd/system/multi-user.target.wants/docker.service
...
#ExecStart=/usr/bin/dockerd -H fd://
EnvironmentFile=-/run/flannel/subnet.env
ExecStart=/usr/bin/dockerd -H fd:// --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU} --iptables=false --ip-masq=false
그 다음에 docker를 살립니다.
u0017649@sys-90725:~$ sudo systemctl daemon-reload
u0017649@sys-90725:~$ sudo systemctl start docker.service
이제 netstat -rn을 해보면 다음과 같이 flannel.1이라는 interface가 gateway로 뜬 것을 보실 수 있습니다.
u0017649@sys-90725:~$ netstat -rn
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 172.29.128.13 0.0.0.0 UG 0 0 0 ibmveth0
10.172.23.0 10.172.23.0 255.255.255.0 UG 0 0 0 flannel.1
10.172.61.0 0.0.0.0 255.255.255.0 U 0 0 0 docker0
172.29.128.0 0.0.0.0 255.255.192.0 U 0 0 0 ibmveth0
u0017649@sys-90725:~$ ip -4 a|grep inet
inet 127.0.0.1/8 scope host lo
inet 172.29.160.221/18 brd 172.29.191.255 scope global ibmveth0
inet 10.172.61.0/32 scope global flannel.1
inet 10.172.61.1/24 scope global docker0
이제 두 서버#1,#2에서 각각 docker container를 띄우고, ip address를 확인합니다.
서버 #1
u0017649@sys-90725:~$ docker run -ti --rm bsyu/caffe-ibm:v0.2 bash
root@73b40d9d2a5b:/# ifconfig eth0
eth0 Link encap:Ethernet HWaddr 02:42:0a:ac:3d:02
inet addr:10.172.61.2 Bcast:0.0.0.0 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1
RX packets:950 errors:0 dropped:0 overruns:0 frame:0
TX packets:851 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3402207 (3.4 MB) TX bytes:84232 (84.2 KB)
root@73b40d9d2a5b:~# ifconfig eth0
eth0 Link encap:Ethernet HWaddr 02:42:0a:ac:3d:02
inet addr:10.172.61.2 Bcast:0.0.0.0 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1
RX packets:931 errors:0 dropped:0 overruns:0 frame:0
TX packets:838 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
서버 #2
u0017649@sys-90754:~$ docker run -ti --rm bsyu/caffe-ibm:v0.2 bash
root@bfb4da5e6b06:/# ifconfig eth0
eth0 Link encap:Ethernet HWaddr 02:42:0a:ac:05:02
inet addr:10.172.5.2 Bcast:0.0.0.0 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1
RX packets:86 errors:0 dropped:0 overruns:0 frame:0
TX packets:106 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:12926 (12.9 KB) TX bytes:11738 (11.7 KB)
서버 #2의 container에서 서버 #1의 container로 ping을 해보고 이어서 ssh를 해보겠습니다. (물론 서버 #1의 container에는 openssh-server 및 root login 허용 작업을 미리 해놓아야 합니다.)
root@bfb4da5e6b06:/# ping 10.172.61.2
PING 10.172.61.2 (10.172.61.2) 56(84) bytes of data.
64 bytes from 10.172.61.2: icmp_seq=1 ttl=62 time=1.01 ms
64 bytes from 10.172.61.2: icmp_seq=2 ttl=62 time=0.739 ms
^C
--- 10.172.61.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.739/0.877/1.016/0.141 ms
root@bfb4da5e6b06:/# ssh 10.172.61.2
root@10.172.61.2's password:
Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-104-generic ppc64le)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
Last login: Thu Jan 11 01:44:26 2018 from 10.172.5.2
root@73b40d9d2a5b:~# ifconfig eth0
eth0 Link encap:Ethernet HWaddr 02:42:0a:ac:3d:02
inet addr:10.172.61.2 Bcast:0.0.0.0 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1
RX packets:1030 errors:0 dropped:0 overruns:0 frame:0
TX packets:904 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3410576 (3.4 MB) TX bytes:91883 (91.8 KB)
root@73b40d9d2a5b:~# df -h
Filesystem Size Used Avail Use% Mounted on
none 35G 27G 6.6G 80% /
tmpfs 2.0G 0 2.0G 0% /dev
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/sda2 35G 27G 6.6G 80% /etc/hosts
shm 64M 0 64M 0% /dev/shm
tmpfs 2.0G 0 2.0G 0% /sys/firmware
다 잘 되는 것을 확인하실 수 있습니다. 다음과 같이 scp에 의한 파일 전송도 잘 됩니다.
root@73b40d9d2a5b:~# echo "I love donut" > /tmp/docker1
root@73b40d9d2a5b:~# logout
Connection to 10.172.61.2 closed.
root@bfb4da5e6b06:/# scp 10.172.61.2:/tmp/docker1 /tmp
root@10.172.61.2's password:
docker1 100% 13 0.0KB/s 00:00
root@bfb4da5e6b06:/# cat /tmp/docker1
I love donut
2번 container에 traceroute를 설치한 뒤 1번 container로의 route 경로를 살펴보면 다음과 같습니다.
root@bfb4da5e6b06:/# apt-get install traceroute
root@bfb4da5e6b06:/# traceroute 10.172.61.2
traceroute to 10.172.61.2 (10.172.61.2), 30 hops max, 60 byte packets
1 10.172.5.1 (10.172.5.1) 0.215 ms 0.030 ms 0.026 ms
2 10.172.61.0 (10.172.61.0) 3.198 ms 3.390 ms 3.353 ms
3 10.172.61.2 (10.172.61.2) 3.654 ms 3.926 ms 3.890 ms
즉, 먼저 서버 #2의 docker0를 통해 flannel.1으로 나가 서버 #1의 flannel.1을 거쳐 docker0로 들어가는 것입니다.
u0017649@sys-90754:~$ ip -4 a|grep inet
inet 127.0.0.1/8 scope host lo
inet 172.29.160.207/18 brd 172.29.191.255 scope global ibmveth0
inet 10.172.5.0/32 scope global flannel.1
inet 10.172.5.1/24 scope global docker0
u0017649@sys-90725:~$ ip -4 a|grep inet
inet 127.0.0.1/8 scope host lo
inet 172.29.160.221/18 brd 172.29.191.255 scope global ibmveth0
inet 10.172.61.0/32 scope global flannel.1
inet 10.172.61.1/24 scope global docker0
----------------------------------------
참고로 docker container 안에서 sshd를 살리고 root login을 허용하는 방법은 다음과 같습니다.
root@73b40d9d2a5b:/# apt-get install openssh-server
root@73b40d9d2a5b:/# vi /etc/ssh/sshd_config
#PermitRootLogin prohibit-password
PermitRootLogin yes
root@73b40d9d2a5b:/# /etc/init.d/ssh start
피드 구독하기:
댓글 (Atom)
댓글 없음:
댓글 쓰기