- 전편에 이어서 -


이번에는 아래 그림에서와 같이 L3 network로 연결된 Docker 호스트간 L2 통신 방법(2)에 대해 다룬다. 네트워크가 다른 2개의 호스트 사이에 인터넷이 있든, 여러 개의 라우터가 존재하든, 호스트간의 연결이 가능하다면 이 방법을 쓸 수 있다. 예를 들어 아마존 SWS의 가상머신과 사무실의 인터넷이 연결된 Docker 호스트 내부의 Docker 사이의 연결도 물론 가능할 것이다.




사전 준비

  • 라우터로 연결된 서로 다른 네트워크를 가지는 Docker Host(VM) 2대
  • Docker Host #1: CentOS 7.3 Minimal Server(1611 ver), 10.255.20.10/24
  • Docker Host #2: CentOS 7.3 Minimal Server(1611 ver), 10.255.30.10/24



Docker & Open vSwitch 설치와 firewall 설정


* Docker 호스트에 EPEL 리포지터리와 RDO 프로젝트를 통해서 Docker와 Open vSwitch를 설치

(Open vSwich의 별도 설치 방법에 대해서는 http://bryan.wiki/276 참고)

yum clean all
yum install -y epel-release https://www.rdoproject.org/repos/rdo-release.rpm
yum install -y firewalld docker openvswitch bridge-utils
yum update -y
systemctl start openvswitch firewalld
systemctl enable openvswitch firewalld


* VxLAN 터널링을 위한 패킷은 UDP 4789, 8472 포트를 통해 전송된다. firewall 설정에서 이 2개 포트를 모두 개방

firewall-cmd --add-port=4789/udp --add-port=8472/udp
firewall-cmd --permanent --add-port=4789/udp --add-port=8472/udp


* trusted 영역에 대해 10.*.*.* 대역의 통신이 모두 가능하도록 개방(docker0 네트워크 10.x.0.0/16 을 서브넷으로 포함하는 상위 네트워크의 예: 10.0.0.0/8)

* 다른 예: docker0 네트워크를 172.17.0.0/16 이나 172.18.0.0/16 ... 등으로 할 경우에는 상위 네트워크를 172.16.0.0/12 로 하면 된다

firewall-cmd --permanent --zone=trusted --add-source=172.16.0.0/12


각각의 도커 호스트에서 Default Docker 네트워크 설정


2개의 Docker 호스트의 Docker 네트워크를 기본으로 설정해 둔다. 본 과정에서는 큰 의미가 없으며, 별도 옵션을 주지 않고 컨테이너를 만들면 여기서 지정된 네트워크를 Docker 엔진이 자동으로 설정해 주게 될 것이다(본 포스팅과는 직접 연관 없는 부분으로, 이 과정은 생략 가능).

[root@dockerhost-1 ~#] /etc/sysconfig/docker-network

DOCKER_NETWORK_OPTIONS="--bip=172.17.0.1/16 --iptables=false --ip-masq=false --ip-forward=true"

[root@docker01 ~#] systemctl restart docker



[root@dockerhost-2 ~#] /etc/sysconfig/docker-network

DOCKER_NETWORK_OPTIONS="--bip=172.17.0.2/16 --iptables=false --ip-masq=false --ip-forward=true"

[root@docker02 ~#] systemctl restart docker



접속 경로의 연결을 위한 Open vSwitch Bridge와 VxLAN 설정


* dockerhost-1, dockerhost-2 에서 다음의 bash 스크립트를 작성해 두자(앞서 #1회의 내용을 스크립트 방식으로 바꾸어 보았다). 스크립트 내부의 커멘트를 참고하고, 붉은 표시된 부분을 잘 구분해서 사용해야 한다.

* 양쪽 호스트의 연결 방식은 네트워크 정보가 바뀐 것 외에는 전 편 #1에서의 방식과 거의 유사하다.


[root@dockerhost-1 ~]# vi set-vxlan-all.sh 

#!/bin/bash

#

# Making VxLAN L2 tunnel over L3 network

#

# 1. Lower part - OVS bridge & VxLAN tunnel to remote

#

if [ $# != 2 ]; then

  echo "Check params..."

  echo "Usage: $0 ovs_sw_ip/cidr target_host_ip"

  exit 1

fi

ovs-vsctl add-br ovs_sw0

ip addr add $1 dev ovs_sw0 && ip link set dev ovs_sw0 up

ovs-vsctl add-port ovs_sw0 vtep0 -- set interface vtep0 type=vxlan options:remote_ip=$2

#

# 2. VETH pair between OVS bridge and Linux bridge(docker0)

#

ip link add veth_sw0 type veth peer name veth_d0

ovs-vsctl add-port ovs_sw0 veth_sw0

brctl addif docker0 veth_d0

ip link set dev veth_sw0 up

ip link set dev veth_d0 up

#

echo "Done."

[root@dockerhost-1 ~]# chmod a+x set-vxlan-all.sh 

[root@dockerhost-1 ~]# ./set-vxlan-all.sh 172.31.0.1/12 10.255.30.10


[root@dockerhost-2 ~]# vi set-vxlan-all.sh 

내용은 dockerhost-1 와 같음

[root@dockerhost-2 ~]# chmod a+x set-vxlan-all.sh 

[root@dockerhost-2 ~]# ./set-vxlan-all.sh 172.31.0.2/12 10.255.20.10



여기까지 설정하였다면 그림에서의 하단(Open vSwitch 브리지간)의 터널 개통(VxLAN L2 터널)이 정상적으로 되었는지 확인해 보기로 하자

[root@dockerhost-1 ~]# ping 172.31.0.2

PING 172.31.0.2 (172.31.0.2) 56(84) bytes of data.

64 bytes from 172.31.0.2: icmp_seq=1 ttl=64 time=2.15 ms

64 bytes from 172.31.0.2: icmp_seq=2 ttl=64 time=3.47 ms

64 bytes from 172.31.0.2: icmp_seq=3 ttl=64 time=2.17 ms

^C

--- 172.31.0.2 ping statistics ---

3 packets transmitted, 3 received, 0% packet loss, time 2019ms

rtt min/avg/max/mdev = 2.157/2.599/3.471/0.618 ms

[root@dockerhost-1 ~]#


[root@dockerhost-2 ~]# ping 172.31.0.1

PING 172.31.0.1 (172.31.0.1) 56(84) bytes of data.

64 bytes from 172.31.0.1: icmp_seq=1 ttl=64 time=1.95 ms

64 bytes from 172.31.0.1: icmp_seq=2 ttl=64 time=6.44 ms

64 bytes from 172.31.0.1: icmp_seq=3 ttl=64 time=1.80 ms

^C

--- 172.31.0.1 ping statistics ---

3 packets transmitted, 3 received, 0% packet loss, time 2027ms

rtt min/avg/max/mdev = 1.809/3.400/6.440/2.150 ms

[root@dockerhost-2 ~]# 



컨테이너와 Linux Bridge 간의 Veth Pair를 통한 연결 


하단의 터널이 뚫렸으므로 상단의 연결선을 만들어 보자. 전 편 #1 에서와 다른 점은, 2개의 Docker 컨테이너가 동일한 네트워크(여기서의 예를 들면 172.17.0.0/16)를 가져야 하므로, 컨테이너의 IP를 직접 지정해 주어야 한다는 것이다.


하지만 아쉽게도 Docker 환경에서 기본적으로는 컨테이너의 IP를 직접 지정할 수 있는 방법은 User Defined Network(docker network create ... & docker run --net=myown --ip=... 형식) 외에는 따로 없으므로, 다음에 제공되는 스크립트를 이용해서 컨테이너의 내부 인터페이스(eth0)를 docker0 브리지와 직접 연결해 주어야 한다(Docker network namespace 영역을 직접 다룸). 처리 내용은 아래의 스크립트 내용에 담겨 있으니 자세히 보고 이해해 두자. 각 Docker 호스트에서 동일하게 set-docker-network.sh 라는 이름으로 스크립트 파일을 만들고 chmod a+x 로 실행 가능하게 설정해 둔다.


#!/bin/bash
# $1: Docker ID
# $2: Docker0 IP/CIDR
# $3: Docker0 Gateway
#
# Checking params
#
if [ $# != 3 ]; then
  echo "Check params..."
  echo "Usage: $0 docker-id-or-name docker-ip/cidr gateway"
  exit 1
fi
echo "Seting docker $1's network to... " $2", GW:" $3

#
# get pid of the docker
#
pid=$(sudo docker inspect -f '{{.State.Pid}}' $1)
# echo $pid

#
# Prepare docker network namespace
#
mkdir -p /var/run/netns
ln -s /proc/$pid/ns/net /var/run/netns/$pid
echo "Network namespace created"

#
# VETH pair create, link to docker0 linux bridge side
#
ip link add veth_doc$pid type veth peer name veth_con$pid
brctl addif docker0 veth_doc$pid
ip link set veth_doc$pid up
echo "Created veth pair and linked veth_doc$pid to docker0"

#
# Link VETH pair end-point to container's eth0
#
ip link set veth_con$pid netns $pid
ip netns exec $pid ip link set dev veth_con$pid name eth0
ip netns exec $pid ip link set eth0 up
echo "Linked veth_con$pid to container's eth0"

#
# Set network information of container's eth0
#
ip netns exec $pid ip addr add $2 dev eth0
ip netns exec $pid ip route add default via $3
echo "Set container's eth0 network ... Done"

 

dockerhost-1 호스트에서 새로운 Docker 컨테이너를 --net=none 으로 즉, 네트워크 없이 생성한다. 

[root@dockerhost-1 ~]# docker run -i -t --name=docker1 --net=none busybox /bin/sh

/ # ctrl+p, ctrl+q 로 빠져나온다


[root@dockerhost-1 ~]# ./set-docker-network.sh docker1 172.17.0.10/16 172.17.0.1

[root@dockerhost-1 ~]# docker attach docker1

/ # ifconfig

eth0      Link encap:Ethernet  HWaddr EA:88:7E:B1:E5:08  

          inet addr:172.17.0.10  Bcast:0.0.0.0  Mask:255.255.0.0

          inet6 addr: fe80::e888:7eff:feb1:e508/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:71 errors:0 dropped:0 overruns:0 frame:0

          TX packets:47 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000 

          RX bytes:5743 (5.6 KiB)  TX bytes:4016 (3.9 KiB)


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:1 

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)


/ # 

* docker1 부분은 이름 없이 생성한 경우는  docker ps 로 보이는 컨테이너 ID를 사용해도 된다



dockerhost-2 호스트에서 새로운 Docker 컨테이너를 같은 방식으로 생성하되 IP 부분만, 같은 네트워크의 다른 IP 주소로 바꾼다. 

[root@dockerhost-2 ~]# docker run -i -t --name=docker2 --net=none busybox /bin/sh

/ # ctrl+p, ctrl+q 로 빠져나온다


[root@dockerhost-2 ~]# ./set-docker-network.sh docker2 172.17.0.11/16 172.17.0.2

[root@dockerhost-2 ~]# docker attach docker2

/ # ifconfig

eth0      Link encap:Ethernet  HWaddr 2E:69:95:56:52:FA  

          inet addr:172.17.0.11  Bcast:0.0.0.0  Mask:255.255.0.0

          inet6 addr: fe80::2c69:95ff:fe56:52fa/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:74 errors:0 dropped:0 overruns:0 frame:0

          TX packets:70 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000 

          RX bytes:6206 (6.0 KiB)  TX bytes:5262 (5.1 KiB)


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:1 

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)


/ # ping 172.17.0.10

PING 172.17.0.10 (172.17.0.10): 56 data bytes

64 bytes from 172.17.0.10: seq=0 ttl=64 time=2.427 ms

64 bytes from 172.17.0.10: seq=1 ttl=64 time=2.061 ms

64 bytes from 172.17.0.10: seq=2 ttl=64 time=1.767 ms

64 bytes from 172.17.0.10: seq=3 ttl=64 time=2.203 ms

^C

--- 172.17.0.10 ping statistics ---

4 packets transmitted, 4 packets received, 0% packet loss

round-trip min/avg/max = 1.767/2.114/2.427 ms

/ #

* docker2 컨테이너에서 docker1 컨테이너로 ping 연결이 가능한지 확인



컨테이너간 연결 최종 확인


마지막으로, 실제로 2개의 컨테이너간의 연결이 확실한지를 nc(NetCat)을 통해서 테스트해 보자.


dockerhost-1 호스트의 컨테이너에서 라우팅 상태 확인 후, 80 포트로 nc 리스닝

/ # route -n

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

0.0.0.0         172.17.0.1      0.0.0.0         UG    0      0        0 eth0

172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 eth0

/ # nc -l -p 8080 0.0.0.0

Test from docker2 container...

/ # 


dockerhost-2 호스트의 컨테이너에서 라우팅 상태 확인 후, docker1 컨테이너로 nc 접속(메시지 전송)

/ # route -n

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

0.0.0.0         172.17.0.2      0.0.0.0         UG    0      0        0 eth0

172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 eth0

/ # echo "Test from docker2 container..." | nc 172.17.0.10 80

/ #




Linux 브리지, OVS 브리지 & VxLAN 설정 초기화를 위한 스크립트


Bonus: 생성된 브리지와 인터페이스 등의 설정 정보를 초기화하는 스크립트가 필요해 보인다. 생성된 순서를 되짚어 가며 삭제 등의 처리를 일일이 해야 하므로, 테스트 과정을 수정, 반복하는 경우의 귀찮은 일을 해결해 보려는 것으로 필수 과정은 아니니 참고로 보아 두면 좋겠다(스크립트 파일명은, 위의 set-vxlan-all.sh 의 설정 정보를 삭제해 주는 의미이므로 del-vxlan-all.sh 정도로 하면 되겠다).


#!/bin/bash
if [ $# != 1 ]; then
  echo "Check params..."
  echo "Usage: $0 ovs_sw_ip/cidr"
  exit 1
fi
# Turn off each port of veth pair
ip link set dev veth_d0 down
ip link set dev veth_sw0 down
# Detach port veth_d0 on docker0 linux-bridge
brctl delif docker0 veth_d0
# Detach port veth_sw0 on ovs_sw0 OVS-bridge, then remove it
ovs-vsctl del-port ovs_sw0 veth_sw0
ip link del veth_sw0
# vtep0, ovs_sw0
ovs-vsctl del-port ovs_sw0 vtep0
ip addr del $1 dev ovs_sw0
ip link set dev ovs_sw0 down
ovs-vsctl del-br ovs_sw0

* 17번째 라인의 $1 파라미터 부분은 해당 Docker 호스트에서 설정한 ovs_sw0 브리지에 할당된 IP/CIDR(여기서는 172.31.0.1/12 또는 172.31.0.2/12) 부분을 지정한다



- Barracuda -



[관련 글]


저작자 표시 비영리 변경 금지
신고
블로그 이미지

Barracuda

Bryan의 MemoLog. 쉽게 익혀 보는 IT 실습과 개념원리, 코딩 세계의 얕은 맛보기들, 평범한 삶 주변의 현상 그리고 進上, 眞想, 진상들


제목이 다소 길지만 앞으로 2회에 걸쳐서 정리할 내용은 Open vSwitch의 VxLAN 터널링을 이용하여 L2 network로 연결된 Docker 호스트의 Docker 컨테이너간 L3 통신 방법(1)과, L3 network로 연결된 Docker 호스트간 L2 통신 방법(2)에 대해 다루고자 한다. 본 1편에서 다루고자 하는 내용을 그림으로 나타내면 다음 그림과 같다. 도커/컨테이너에 대한 기본적인 개념 설명은 여기서는 다루지 않으며, 이후에 도커의 네트워크에 대해 간략히 따로 다룰 예정이다.




그림을 보면, 2개의 호스트가 Flat한 L2 Network로 연결되어 있고(SDN: Software-Defined-Network 개념으로 보면 Underlay) 각각의 호스트 내에 Docker Container 들은 서로 다른 네트워크를 가지며, VxLAN 터널을 통한 L3 연결(SDN 개념으로 보면 Overlay)가 가능한 구조임을 알 수 있다. 그림과 같은 네트워크를 설계할 때에 특히 주의해야 할 점은, 하단의 OVS Bridge의 네트워크(10.0.0.0/8)가 상단의 Linux Bridge(docker0)의 네트워크(10.x.0.0/16)를 포함하는 구조를 가져야 한다는 것이다(참고: http://www.ipaddressguide.com/cidr).



사전 준비

  • Flat Network로 연결된 Docker Host(VM) 2대
  • Docker Host #1: CentOS 7.3 Minimal Server(1611 ver), 192.168.10.163/16
  • Docker Host #2: CentOS 7.3 Minimal Server(1611 ver), 192.168.10.164/16



Docker & Open vSwitch 설치와 firewall 설정


* Docker 호스트에 EPEL 리포지터리와 RDO 프로젝트를 통해서 Docker와 Open vSwitch를 설치

(Open vSwich의 별도 설치 방법에 대해서는 http://bryan.wiki/276 참고)

yum clean all
yum install -y epel-release https://www.rdoproject.org/repos/rdo-release.rpm
yum install -y firewalld docker openvswitch bridge-utils
yum update -y
systemctl start openvswitch firewalld
systemctl enable openvswitch firewalld


* VxLAN 터널링을 위한 패킷은 UDP 4789, 8472 포트를 통해 전송된다. firewall 설정에서 이 2개 포트를 모두 개방

firewall-cmd --add-port=4789/udp --add-port=8472/udp
firewall-cmd --permanent --add-port=4789/udp --add-port=8472/udp


* trusted 영역에 대해 10.*.*.* 대역의 통신이 모두 가능하도록 개방(docker0 네트워크 10.x.0.0/16 을 서브넷으로 포함하는 상위 네트워크의 예: 10.0.0.0/8)

* 다른 예: docker0 네트워크를 172.17.0.0/16 이나 172.18.0.0/16 ... 등으로 할 경우에는 상위 네트워크를 172.16.0.0/12 로 하면 된다

firewall-cmd --permanent --zone=trusted --add-source=10.0.0.0/8


각각의 도커 호스트에서 Docker 네트워크 설정


* Docker 에서 네트워크가 가능하려면 --net=bridge(기본 모드) 또는 --net=host 옵션으로 컨테이너를 생성하게 된다. 컨테이너 생성시에 별도의 옵션을 지정하지 않으면 bridge 모드가 사용되는데, 여기서는 기본 모드인 bridge 모드를 사용할 것이며, /etc/sysconfig 디렉토리의 docker-network 설정 파일을 다음과 같이 설정한다.

[root@docker01 ~#] /etc/sysconfig/docker-network

DOCKER_NETWORK_OPTIONS="--bip=10.1.0.1/16 --iptables=false --ip-masq=false --ip-forward=true"

[root@docker01 ~#] systemctl restart docker


[root@docker02 ~#] /etc/sysconfig/docker-network

DOCKER_NETWORK_OPTIONS="--bip=10.2.0.1/16 --iptables=false --ip-masq=false --ip-forward=true"

[root@docker02 ~#] systemctl restart docker

--bip 는 Bridge IP 를 뜻하며, 컨테이너의 네트워크에서 자동적으로 10.1.0.1, 10.2.0.1 을 default gateway 로 바라보게 된다.

  


위와 같이 설정하고 Docker 컨테이너를 생성하면, docker01 호스트에서 첫 번째로 만들어지는 컨테이너의 IP는 10.1.0.2 가 될 것이다(docker02 에서는 10.2.0.2).


여기까지 끝이라면 좋겠지만 아쉽게도 그렇지 않다. 2개의 호스트에서 만든 각각의 컨테이너에서 서로 다른 컨테이너로 접속하려 하면? 당연히, 안된다. 서로 다른 네트워크간의 연결은 통로가 열려 있지 않으면 당연히 통신이 되지 않는다(아직 컨테이너 생성까지 진도는 나가지 않았지만, busybox 컨테이너를 docker01, docker02 에서 각각 만들고 docker01 호스트에서 ping 10.2.0.2 해보자. 당연히 안된다).



접속 경로의 연결을 위한 Open vSwitch Bridge와 VxLAN 설정


* docker01 에서는 다음과 같이 Open vSwitch 를 설정

[root@docker01 ~#] ovs-vsctl add-br ovs_sw0

[root@docker01 ~#] ip addr add 10.100.0.1/8 dev ovs_sw0 && ip link set dev ovs_sw0 up

[root@docker01 ~#] ovs-vsctl add-port ovs_sw0 vxlan0 -- set Interface vxlan0 type=vxlan options:remote_ip=192.168.10.164


* docker02 에서는 다음과 같이 Open vSwitch 를 설정

[root@docker02 ~#] ovs-vsctl add-br ovs_sw0

[root@docker02~#] ip addr add 10.100.0.2/8 dev ovs_sw0 && ip link set dev ovs_sw0 up

[root@docker02 ~#] ovs-vsctl add-port ovs_sw0 vxlan0 -- set Interface vxlan0 type=vxlan options:remote_ip=192.168.10.163


위의 그림에서 보듯이 각 Docker 호스트에 sw0 라는 Open vSwitch 브리지간의 터널을 개통하는 과정이다. 주의 깊게 보아야 하는 부분은 vxlan0 라는 VTEP(VxLAN Terminal End Point)가 상대편 Docker 호스트의 네트워크 IP를 바라보게 설정하는 것이다.


여기까지 설정하였다면 그림에서의 하단(Open vSwitch 브리지간)의 터널 개통이 정상적으로 되었는지 확인해 보기로 하자

[root@docker01 ~]# ping 10.100.0.2

PING 10.100.0.2 (10.100.0.2) 56(84) bytes of data.

64 bytes from 10.100.0.2: icmp_seq=1 ttl=64 time=2.43 ms

64 bytes from 10.100.0.2: icmp_seq=2 ttl=64 time=0.418 ms

64 bytes from 10.100.0.2: icmp_seq=3 ttl=64 time=0.333 ms

64 bytes from 10.100.0.2: icmp_seq=4 ttl=64 time=0.354 ms

64 bytes from 10.100.0.2: icmp_seq=5 ttl=64 time=0.410 ms

^C

--- 10.100.0.2 ping statistics ---

5 packets transmitted, 5 received, 0% packet loss, time 4001ms

rtt min/avg/max/mdev = 0.333/0.790/2.438/0.824 ms

10.100.0.1/8 과 10.100.0.2/8 은 동일한 네트워크 대역이고, VxLAN 터널을 통해 서로 연결이 잘 되고 있음을 확인할 수 있다.



Linux Bridge와 Open vSwitch Bridge 간의 연결선, Veth Pair


하단의 터널이 뚫렸으므로 상단의 연결선을 만들어 보자. Docker container(브리지 모드일 경우)는 기본적으로 Linux Bridge와 자동으로 연결이 맺어 진다. 즉, Docker 엔진이 docker0 라는 디폴트 브리지(Linux Bridge)에 Docker 컨테이너의 네트워크 디바이스를 내부적으로 연결시켜 주게 된다.


그렇다면 우리는, 그 아래의 docker0와 sw0 사이의 연결을 맺어 주기만 하면 되는데, 이를 위해 VETH pair 라고 하는, 양쪽 끝이 연결되어 있는 연결 쌍(pair)이라는 도구를 사용해서 위 아래의 접점에 붙여 주면 된다.


그림에서 처럼, docker0(Linux Bridge)와 sw0(Open vSwitch Bridge)간의 연결을, Veth Pair 라고 하는 연결선을 통해서 맺어 줄 수 있다. 다음과 같이 해 보자. 이 연결선의 End Point(끝점) 들 중에서 veth_d0는 docker0 쪽으로, veth_sw0는 sw0 쪽으로 연결한다.

[root@docker01 ~]# ip link add veth_sw0 type veth peer name veth_d0

[root@docker01 ~]# ovs-vsctl add-port ovs_sw0 veth_sw0

[root@docker01 ~]# brctl addif docker0 veth_d0

[root@docker01 ~]# ip link set dev veth_sw0 up

[root@docker01 ~]# ip link set dev veth_d0 up


docker02 에서도 위와 같이 설정해 주자. End Point 들의 이름은 docker01 에서와 다르게 주어도 무관하지만 script 작성 등의 자동화를 위해서는 최대한 일관성 유지를 하는 것이 좋다.

[root@docker02 ~]# ip link add veth_sw0 type veth peer name veth_d0

[root@docker02 ~]# ovs-vsctl add-port ovs_sw0 veth_sw0

[root@docker02 ~]# brctl addif docker0 veth_d0

[root@docker02 ~]# ip link set dev veth_sw0 up

[root@docker02 ~]# ip link set dev veth_d0 up


각각의 Docker 호스트에서 다음과 같이 실행해서 브리지 설정을 확인한다.

[root@docker01 ~]# ovs-vsctl show

f3c8825d-73ba-4ee5-a136-3db14a32e990

    Bridge "ovs_sw0"

        Port "veth_sw0"

            Interface "veth_sw0"

        Port "ovs_sw0"

            Interface "ovs_sw0"

                type: internal

        Port "vxlan0"

            Interface "vxlan0"

                type: vxlan

                options: {remote_ip="192.168.10.164"}

    ovs_version: "2.5.2"


[root@docker01 ~]# brctl show

bridge name bridge id   STP enabled interfaces

docker0   8000.0242f84de852 no    veth_d0



Docker 컨테이너를 만들고 L3 연결 확인


docker01, docker02 호스트에서 각각 컨테이너 생성, 네트워크 확인

[root@docker01 ~]# docker run -i -t busybox /bin/sh

/ # ifconfig

eth0      Link encap:Ethernet  HWaddr 02:42:0A:01:00:02  

          inet addr:10.1.0.2  Bcast:0.0.0.0  Mask:255.255.0.0

          inet6 addr: fe80::42:aff:fe01:2/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:88 errors:0 dropped:0 overruns:0 frame:0

          TX packets:51 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:0 

          RX bytes:7240 (7.0 KiB)  TX bytes:4470 (4.3 KiB)


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:1 

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)


[root@docker02 ~]# docker run -i -t busybox /bin/sh

/ # ifconfig

eth0      Link encap:Ethernet  HWaddr 02:42:0A:02:00:03  

          inet addr:10.2.0.3  Bcast:0.0.0.0  Mask:255.255.0.0

          inet6 addr: fe80::42:aff:fe02:3/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:24 errors:0 dropped:0 overruns:0 frame:0

          TX packets:20 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:0 

          RX bytes:1880 (1.8 KiB)  TX bytes:1656 (1.6 KiB)


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:1 

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)


docker01 호스트의 컨테이너에서 docker02 호스트의 컨테이너와 ping 테스트

/ # ping 10.2.0.2

PING 10.2.0.2 (10.2.0.2): 56 data bytes

64 bytes from 10.2.0.2: seq=0 ttl=63 time=1.730 ms

64 bytes from 10.2.0.2: seq=1 ttl=63 time=0.528 ms

64 bytes from 10.2.0.2: seq=2 ttl=63 time=0.321 ms



마지막으로, 실제로 2개의 컨테이너간의 연결이 확실한지를 nc(NetCat)을 통해서 테스트해 보자. busybox 에 기본적으로 있는 기능이다.


docker01 호스트의 컨테이너에서 8080 포트로 nc 리스닝

/ # nc -l -p 8080 0.0.0.0

Test from docker02 container...

/ # 


docker02 호스트의 컨테이너에서 docker01 호스트의 컨테이너로 nc 접속(메시지 전송)

/ # echo "Test from docker02 container..." | nc 10.1.0.2 8080

/ #




컨테이너에서 외부 네트워크로 접속하려면?


서로 다른 호스트에 각각 분리되어 있는 컨테이너간의 네트워크 연결은 가능해 졌지만, 원래의 Docker 네트워크 구조를 바꿔 버렸기 떄문에 현재의 설정으로는 컨테이너 사이의 네트워크만 가능할 뿐이다. 즉 외부 네트워크(192.168.10.* 를 벗어난)으로의 접속은 불가능한 상태다.


이 때에는 다음과 같이 firewall-cmd 를 통해서 목적지가 다를 경우 masquerading(NATting)이 되도록 설정해 주면 된다(각 docker 호스트에서 실행).


* (참고) 컨테이너 prompt 에서 exit 또는 ctrl-d 로 빠져나오게 되면 컨테이너가 생성되면서 실행된 터미널이 종료되면서 컨테이너는 STOP 상태로 빠지게 된다. 이 컨테이너에 재접속 하려면 "docker start" 로 다시 동작시켜야 하는데, STOP 되지 않도록 빠져나오려면 ctrl-p 와 ctrl-q 를 차례로 누르면 되며, 이후에 "docker attach" 로 재접속할 수 있게 된다.

[root@docker01 ~]# firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.0.0.0/8 ! -d 10.0.0.0/8 -j MASQUERADE

success

[root@docker01 ~]# firewall-cmd --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.0.0.0/8 ! -d 10.0.0.0/8 -j MASQUERADE

success

[root@docker01 ~]# 

[root@docker01 ~]# docker ps

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

871a0f2765b6        busybox             "/bin/sh"           3 days ago          Up 3 days                               ecstatic_hopper

[root@docker01 ~]# docker attach 871a0f2765b6

/ # ping yahoo.com

PING yahoo.com (206.190.36.45): 56 data bytes

64 bytes from 206.190.36.45: seq=0 ttl=48 time=158.904 ms

64 bytes from 206.190.36.45: seq=1 ttl=48 time=159.080 ms

64 bytes from 206.190.36.45: seq=2 ttl=48 time=159.194 ms

64 bytes from 206.190.36.45: seq=3 ttl=48 time=164.183 ms

^C

--- yahoo.com ping statistics ---

4 packets transmitted, 4 packets received, 0% packet loss

round-trip min/avg/max = 158.904/160.340/164.183 ms



- Barracuda -



[관련 글]

2017/06/08 - [Technical/Cloud, 가상화] - Open vSwitch, VxLAN을 이용한 분산 Docker 컨테이너 간의 네트워크 연결(2/2)


저작자 표시 비영리 변경 금지
신고
블로그 이미지

Barracuda

Bryan의 MemoLog. 쉽게 익혀 보는 IT 실습과 개념원리, 코딩 세계의 얕은 맛보기들, 평범한 삶 주변의 현상 그리고 進上, 眞想, 진상들



2회(#2/3) 에서 이어지는 내용이다 


  • GitHub 를 사용한 개발과정 맛보기 #2 - WordPress Sample & MySQL(PHP)

이번에는 OpenShift GUI Console 이 아닌 명령어 방식으로 oc(OpenShift Client)를 사용해 보겠다. Master Node로 ssh 로그인을 하고 새로운 프로젝트를 생성한다. OpenShift Console에서 실시간으로 확인 가능하다


GitHub.com의 Wordpress project URL(https://github.com/DragOnMe/WordPress.git)을 복사한다


oc 명령으로 php:latest 도커이미지와 WordPress 소스 repository를 지정하여 새로운 App 서비스를 프로젝트에 추가한다. 진행 상황은 텍스트에 나온 설명대로 'oc logs -f bc/어플리케이션이름' 을 수행해 보거나, 앞서와 마찬가지로 GUI를 통해 Build Log 상태를 확인할 수도 있다 


OpenShift Console 화면에서 새로 만든 프로젝트 클릭


WordPress 실행을 위한 PHP 웹서버 부분은 Build & Deploy 가 완료되었고 하나의 Pod가 기동되어 있다


GUI console에서와 달리, 명령어 방식에서는 서비스에 접속 가능하도록 expose 명령으로 주소를 할당해야 한다. 이제 MySQL DB를 준비해 보자


상단의 프로젝트 타이틀 우측 'Add to project' 클릭


Technologies 부분의 'Data Stores' 클릭


'MySQL (Ephemeral)' 선택


계정, 암호 등은 자동 생성되도록 비워 두고 'Create' 클릭(기억할 수 있는 암호와 계정을 정하고 직접 입력해도 된다)


계정, 암호 등은 MySQL 컨테이너 기동 시에 정확히 입력해야 하므로 잘 기억 또는 메모해 둔다(긁어서 복사해 두자). 'Continue to overview' 클릭


위쪽에 새로 만든 MYSQL EPHEMERAL 컨테이너 서비스가 기동되어 pod 1개가 만들어져 있다. 이제 PHP 웹을 실행해 보기 위해 Route(접속 URL)을 클릭


WordPress 초기 셋업(설치) 화면이 연결되었다. 'Let's go!' 클릭


Database Host 에는 OpenShift 프로젝트에 존재하는 서비스명(mysql)을 입력한다. 'Submit' 클릭


'Run the install' 클릭


제목 등을 적당히 입력하고 'Install WordPress' 클릭. 다음 화면에서 'Log In' 클릭, 입력한 로그인 계정으로 로그인


WordPress 대쉬보드 화면 접속 성공!



  • Auto-Scaling 의 사용(Hawkular Metrics)

#1. 수동 scaling - 새로운 프로젝트 생성(Create) 


Autoscale 테스트를 위한 PHP web 을 구동할 예정이다. PHP 선택


언어는 크게 상관이 없다. PHP 5.6 으로 선택하고 'Select'


github.com 프로젝트로 간단한 PHP 페이지 프로젝트를 준비한다. 단순히 phpinfo() 를 수행하는 웹사이트이다. Clone or download 를 통해 URL(https://github.com/DragOnMe/php_for_autoscale.git) 복사


Git Repository URL에 위에서 복사한 URL을 paste(Create)


Continue to overview 로 Overview 화면으로 이동


서비스 내에 Pod 가 하나 만들어지고 Web 서비스 준비 완료. 상단 Routes 주소 클릭


웹서비스 정상 접속 완료


Pod 를 수동으로 Scaling 해보자. Overview 로 돌아와서 Pod 를 클릭


현재 기동되어 있는 단 하나의 Pod 가 보일 것이다. Pod 이름 클릭


동일한 Pod가 여러 개 생길 수 있으므로 Pod 이름은 '서비스명-빌드번호-b9t2h' 와 같은 형태로 자동으로 생성된다. Pod의 상태를 확인해 보면 내부 사설 IP 10.130.0.27 이며 node02 에서 동작하고 있음을 볼수 있다


Pod 우측의 위아래 버튼을 누르면 Pod의 갯수가 증가/감소하는 것을 볼 수 있다


Pod를 2개로 만든 상태에서 Pod 버튼을 클릭하면 2개의 Pod 가 기동되어 있음을 볼 수 있다


새로 만들어진 Pod 를 클릭해 보면, IP 10.129.0.13 이며 node01 에서 동작하고 있다



#2. 자동 scaling, HPA(Horizontal Pod autoscale) 라고 하며, 본 글 작성시 사용중인 Origin 1.4 버전에서는 Hawkular Metrics 가 비교적 안정적으로 통합되어 오토스케일을 위한 추가 설정의 부담이 많이 줄어들었다 - 새로운 프로젝트 생성(Create), 앞서 #1 과 마찬가지로  https://github.com/DragOnMe/php_for_autoscale.git 저장소 주소를 사용하는데, 이번에는 프로젝트 이름만 Auto-2 로 구분가능하도록 진행하자


* 여기서 중요하게 확인해야 할 것은 위의 터미널에 나와 있는 oc get pods 명령어의 결과에서처럼, metric 모니터링을 위한 3개의 기본 pod(hawkular metrics/cassandra, heapster) 가 반드시 Running 상태가 되어 있어야 한다는 것이다 


서비스를 추가하는 화면에서 아래로 스크롤해 내려간다


Scaling 타이틀 아래에 Strategy 부분을 Automatic 으로 바꾸고, 아래의 설정 값들을 적당히 입력한다


조금 더 아래로 내려 가면 Resource Limits 부분이 나온다. 여기에 세부 Metric 설정 값들을 입력해야만(자세한 설정 방법은 여기 참고), 비로소 해당 서비스를 자동으로 Scale-out/in 할 수 있게 된다(Create 클릭)


이전 프로젝트들의 Summary 화면과 다른 부분을 볼 수 있다. 우측 상단의 서비스 URL을 클릭해서 해당 서비스 페이지를 접속해보고, 화면 refresh 를 연속으로 몇 차례 시도한 후, 이 화면으로 돌아오면 Pod 왼쪽의 그래프 부분이 바뀌어 부하 발생에 바뀌어 나타나는 것을 볼 수 있다


osmaster 내부가 아닌 외부 시스템의 터미널 창에서 Apache ab 를 실행하여, 서비스 URL 페이지에 대해 다량의 접속 부하를 발생시키면, OpenShift Summary 화면의 그래프가 바뀌며, Pod가 최대 갯수인 4개까지 자동으로 늘어나는(scaled-out) 것을 볼 수 있다


웹페이지 부하를 멈춘 상태에서 몇 분 정도 지나면 자동으로 최소 Pod 갯수인 1개까지 줄어(scaled-in) 있는 것을 볼 수 있다



  • Persistent-Volume 의 사용

#1. github.com 에서 simple-file-manager 리포리터리의 URL 복사


새로운 프로젝트를 만들고 PHP 언어를 선택. Git URL에 위에서 복사한 주소 paste


빌드 / 배포가 완료 되면 오픈소스로 공개된 간단한 파일 업다운로드 서비스가 기동될 것이다. 새로운 파일을 업로드해 보자


Overview를 통해 Pod를 선택하고 Terminal 로 들어가 보면 새로 업로드한 파일이 보인다. 그러나 이 파일은 Pod(또는 컨테이너)가 없어지면 같이 사라지게 된다(/tmp 아래의 일회용 스토리지 공간에 저장)


* Overview 화면에서 Pod를 1개 늘리고, Terminal 로 들어가서 ls 를 해 보면 새로 만들어진 Pod에는 위에서 업로드한 파일이 보이지 않을 것이다. Pod 별로 각각 일회용 스토리지 영역이 할당되기 때문이다


 

#2 이번에는 OpenShift 내에서 미리 설정된 Persistent Volume(NFS 볼륨)을 사용하여 컨테이너에 직접 마운트해서 사용해 본다. 위 #1과 마찬가지로 새로운 프로젝트를 만들고 https://github.com/DragOnMe/simple-file-manager.git 리포지토리를 연결한다


Deployments 화면 아래의 Add storage 클릭


"프로젝트의 배포 설정에 추가할 persistent volume 요청이 없으니 추가" 하라고 한다(Create storage 클릭)


[Volume Claim 단계] 앞서 Persistent Volume을 ReadWriteMany 모드로 만들었으므로 Access Mode는 RWX 를 선택하고 볼륨 크기를 적당히 지정(미리 만든 각 PV들은 400M 이므로 그 이하의 크기)하고 Create


[Add Storage: 스토리지 할당 단계] 앞의 Volume Claim 에 대해 pv010 볼륨이 자동으로 할당되었다. Mount Path 는 컨테이너 Application 내부에서 사용하는 Mount Point의 Path(simple-file-manager에서 사용하는 data path는 /opt/app-root/src 이다) 를 입력한다


다시 위로 스크롤 해서 Deploy 를 수행한다


Pod 에 터미널로 접속해서 새로운 파일을 하나 만들자. 파일 업로드를 흉내 내 보는 것


Overview 로 돌아가서 Pod 를 하나 늘려두자


새로이 만들어진 Pod 에서 터미널 접속 후 ls 로 확인해 보면 앞에 만들어져 있던 Pod 에서 생성한 파일이 보인다. 두개의 Pod 가 OpenShift 가 제공하는  PV를 공유하고 있음을 알 수 있다


좌측 Storage 메뉴를 통해, 현재 프로젝트에 할당된 스토리지 정보를 확인할 수 있느. 명령어 방식으로 system:admin 계정으로 oc get pv 명령어를 통해서 전체 시스템에서 사용 가능한 PV 정보를 확인힐 수도 있다



이로써 3회에 걸친 OpenShift Origin v3 에 대한 설치와 소프트웨어 엔지니어 입장에서의 간단한 설정 & 사용 방법에 대해 알아 보았습니다. 되도록 간단히 요점 위주로 작성해 두려 했으나, 직접 수행해 본 내용을 꼼꼼히 빠짐 없이 기재하고 설명을 달다 보니 분량이 제법 늘어나 있어서 다소 읽기에 부담이 될지도 모르겠습니다. 불필요한 부분은 알아서 스킵하시고 참고해 주시길~ ^^


혹시 궁금한 점이 있거나, 지적할 부분이 있다면 언제든 댓글로 컨택해 주시기 부탁 드립니다. - Barracuda -





[연관되는 글]

[OpenShift v3 #1] Origin all-in-one, CentOS 7 기반 단일서버 설치 사용법(1/3)

[OpenShift v3 #2] Origin 3-node, CentOS 7 기반 3노드 설치, 사용 방법(2/3)


- Barracuda -



저작자 표시 비영리 변경 금지
신고
블로그 이미지

Barracuda

Bryan의 MemoLog. 쉽게 익혀 보는 IT 실습과 개념원리, 코딩 세계의 얕은 맛보기들, 평범한 삶 주변의 현상 그리고 進上, 眞想, 진상들


지난 회에서 OpenShift Origin v3의 단일서버 구성 설치와 간단한 사용법을 정리하였다, 이번 회에서는 3-노드 구성의 OpenShift v3 설치 과정과와 Kubernetes, OpenShift console 및 CLI를 통한 Orchestration과 몇가지의 Use Case를 정리해 두고자 한다(이 글을 마지막으로 업데이트하는 시점에 OpenShift 릴리즈가 1.5.0으로 바뀌었다. 아래 설정 파일에서 v1.5.0으로 표시된 부분 참고=>1.5.0에 버그가 아직 많아 보이고, 결정적으로 1.5.1이 나온 시점에 docker 기반 설치에 오류가 발생하여 1.4.1 버전 기준으로 긴급히 되돌림 2017-05-27).



사전 설정(Pre-requisites)

  • 서버 구성(권장 최소 스펙)
    - OS는 CentOS 7.3(64bit r1611), Minimal Server 버전
    - Master: 4 CPU, 6 G memory, 20G+40G(추가디스크) Disk, 추가디스크는 /mnt/persistent-volumes 에 마운트
    - Node01: 2 CPU, 4 G memory, 20G
    - Node02: 2 CPU, 4 G memory, 20G 

  • Release v1.5.0 부터는 Master부터 순서대로 16G/8G/8G 메모리를 권고하며 충족이 안될 경우 fail 되게 바뀌었다(ansible-playbook 실행시 -e openshift_disable_check=memory_availability 옵션 추가 필요)
  •  내부 테스트 또는 외부 서비스용 별도 DNS 서버 필요(DNS 설정 방식은 이전 포스팅(#1) 참조
    - 단일 노드가 아닌 3-노드 구성에 대한 DNS 설정 부분의 차이점 확인 필요
  • 도메인, IP 주소에 대한 부분은 설치 환경과 요구 사항에 맞게 꼼꼼하게 대조하여 오류가 없도록 진행하는 것이 중요



  • DNS forwarding 을 위한 설정 내용(192.168.0.0/16 네트워크 사용시).


[root@dns ~]# cat /etc/named.conf 

options {

listen-on port 53 { any; };

directory  "/var/named";

dump-file  "/var/named/data/cache_dump.db";

statistics-file "/var/named/data/named_stats.txt";

memstatistics-file "/var/named/data/named_mem_stats.txt";


allow-query     { any; };

recursion yes;


// For non-internal domains

forwarders {

168.126.63.1;

8.8.8.8;

};

auth-nxdomain no; # conform to RFC1035

dnssec-enable yes;

// dnssec-validation yes;

dnssec-lookaside auto;


/* Path to ISC DLV key */

bindkeys-file "/etc/named.iscdlv.key";


managed-keys-directory "/var/named/dynamic";


pid-file "/run/named/named.pid";

session-keyfile "/run/named/session.key";

};


logging {

        channel default_debug {

                file "data/named.run";

                severity dynamic;

        };

};


zone "." IN {

type hint;

file "named.ca";

};


include "/etc/named.rfc1912.zones";

include "/etc/named.root.key";


[root@dns ~]# cat /etc/named.rfc1912.zones

...(생략)...

zone "0.in-addr.arpa" IN {

type master;

file "named.empty";

allow-update { none; };

};


zone "test.local" IN {

        type master; // server type

        file "test.local.zone"; // zone file

        allow-update {none;}; // none: no slave to sync

};


zone "168.192.in-addr.arpa" IN { // Reverse

        type master;

        file "/var/named/rev.168.192.in-addr.arpa";

};


[root@dns ~]# cat /var/named/test.local.zone

$ORIGIN .

$TTL 10


test.local.    IN    SOA    dns.test.local.    root.test.local. (

2017031402    ; serial

1D       ; refresh

1H       ; retry

1W      ; expire

3H )    ; min(Negative cache TTL)

test.local.          IN    NS    dns.test.local.

dns.test.local.    IN    A    192.168.0.3


$ORIGIN    test.local.


osmaster        IN      A       192.168.10.160

osnode01        IN      A       192.168.10.161

osnode02        IN      A       192.168.10.162

*.apps          IN      CNAME   osmaster.test.local.


[root@dns ~]# cat /var/named/rev.168.192.in-addr.arpa 

$TTL 10


@    IN    SOA    dns.test.local.    root.test.local. (

2017031403 ; serial

1D ; refresh

1H ; retry

1W ; expire

3H ) ; min(Negative cache TTL)

test.local.          IN    NS    dns.test.local.

dns.test.local.    IN    A    192.168.0.3


@      IN NS      dns.test.local.

3.0    IN PTR    dns.test.local.


160.10    IN PTR    osmaster.test.local.

161.10    IN PTR    osnode01.test.local.

162.10    IN PTR    osnode02.test.local.



  • 준비된 각각의 노드에서 다음과 같은 사전설치 과정을 따른다
[Master노드: osmaster]

# vi /etc/sysconfig/network-scripts/ifcfg-eth0

...

NETMASK=255.255.0.0

DNS1=192.168.0.3

DNS2=8.8.8.8

# hostnamectl set-hostname osmaster

# yum install -y bind-utils

# nslookup osmaster.test.local

# dig yahoo.com a


# cat /etc/selinux/config 

...

SELINUX=enforcing

...

SELINUXTYPE=targeted


# vi /etc/hosts

...

192.168.10.160 osmaster osmaster.test.local

192.168.10.161 osnode01 osnode01.test.local

192.168.10.162 osnode02 osnode02.test.local


# ssh-keygen

# ssh-copy-id root@osmaster.test.local

# ssh-copy-id root@osmaster

# ssh-copy-id root@osnode01.test.local

# ssh-copy-id root@osnode01

# ssh-copy-id root@osnode02.test.local

# ssh-copy-id root@osnode02


[root@osmaster ~]# domain="test.local"


[root@osmaster ~]# for node in {osmaster.$domain,osnode01.$domain,osnode02.$domain}; do ssh root@$node "yum clean all; yum install -y git bind-utils iptables-services net-tools wget bash-completion chrony; yum update -y"; done


[root@osmaster ~]# systemctl enable iptables

[root@osmaster ~]# systemctl start iptables

[root@osmaster ~]# systemctl enable firewalld

[root@osmaster ~]# systemctl start firewalld

[root@osmaster ~]# firewall-cmd --add-service=ntp --permanent

[root@osmaster ~]# firewall-cmd --reload


[root@osmaster ~]# for node in {osnode01.$domain,osnode02.$domain}; do scp /etc/hosts root@$node:/etc/hosts; done

hosts                                                                                               100%  230     0.2KB/s   00:00    

hosts                                                                                               100%  230     0.2KB/s   00:00    

* 만약 iptables 설치시 "Failed to start iptables.service: Unit is masked." 와 같은 오류가 발생하면 'systemctl unmask iptables" 로 해결한다



[root@osmaster ~]# vi /etc/chrony.conf

server time.bora.net iburst

...

# Allow NTP client access from local network.

allow 192.168.0.0/16

...

# Serve time even if not synchronized to any NTP server.

local stratum 10

...


[root@osmaster ~]# systemctl enable chronyd

[root@osmaster ~]# systemctl restart chronyd

[root@osmaster ~]# chronyc tracking

[root@osmaster ~]# chronyc sources -v


[Node01노드: osnode01]

[root@osnode01 ~]# hostnamectl set-hostname osnode01

[root@osnode01 ~]# vi /etc/chrony.conf

server 192.168.10.160 iburst

...

# Serve time even if not synchronized to any NTP server.

local stratum 10

...


[root@osnode01 ~]# systemctl enable chronyd

[root@osnode01 ~]# systemctl restart chronyd

[root@osnode01 ~]# chronyc tracking

[root@osnode01 ~]# chronyc sources -v



[Node02노드: osnode02]

[root@osnode01 ~]# hostnamectl set-hostname osnode02

[root@osnode02 ~]# vi /etc/chrony.conf

server 192.168.10.160 iburst

...

# Serve time even if not synchronized to any NTP server.

local stratum 10

...


[root@osnode02 ~]# systemctl enable chronyd

[root@osnode02 ~]# systemctl restart chronyd

[root@osnode02 ~]# chronyc tracking

[root@osnode02 ~]# chronyc sources -v



OpenShift v3 설치 시작


  • EPEL repo를 설정하고 필요한 패키지 설치(여기서부터는 모든 설정 작업을 Master node 에서만 수행)
[Master노드: osmaster]

# yum install -y epel-release

# yum install -y docker

# yum install -y python-cryptography pyOpenSSL.x86_64 java-1.8.0-openjdk-headless python-passlib

# yum install -y python-pip python-devel

# pip install --upgrade pip

# pip install ansible


  • NFS를 persistent storage 로 설치하기 위해 nfs-server 설치, 설정
    - Persistent Volume은 iSCSI, Ceph RBD, GlusterFS, OpenStack Cinder, AWS EBS, Google Cloud Persistent Disk, Fibre Channel 등을 모두 지원
    - 여기서는 여러 인스턴스(컨테이너)들의 공유 사용이 가능함을 확인하기 위해 대표적인 Shared File System인 NFS를 사용

[root@osmaster ~]# yum groupinstall -y file-server

[root@osmaster ~]# systemctl enable rpcbind

[root@osmaster ~]# systemctl enable nfs-server

[root@osmaster ~]# systemctl start rpcbind

[root@osmaster ~]# systemctl start nfs-server

[root@osmaster ~]# iptables-save > pre-nfs-firewall-rules-server

[root@osmaster ~]# iptables -I INPUT -m state --state NEW -p tcp -m multiport --dport 111,892,2049,32803 -s 0.0.0.0/0 -j ACCEPT

[root@osmaster ~]# iptables -I INPUT -m state --state NEW -p udp -m multiport --dport 111,892,2049,32769 -s 0.0.0.0/0 -j ACCEPT

[root@osmaster ~]# service iptables save

[root@osmaster ~]# setsebool -P virt_use_nfs 1


  • Persistent Metrics Volume for Hawkular Metrics
    - Volume 설정 후 nfs-server 서비스가 정상 작동하는지 확인 필요

[root@osmaster ~]# DIR=/mnt/persistent-volumes/metrics

[root@osmaster ~]# mkdir -p $DIR; chmod 777 $DIR

[root@osmaster ~]# chown nfsnobody:nfsnobody $DIR

[root@osmaster ~]# echo "$DIR 192.168.0.0/16(rw,all_squash)" >> /etc/exports

[root@osmaster ~]# systemctl restart nfs-server

[root@osmaster ~]# systemctl status nfs-server


  • OpenShift Ansible 패키지와 configuration 소스 설치, 설정
    - Auto-scale을 위한 hawkular metrics 설치/설정 포함

# git clone https://github.com/DragOnMe/openshift-ansible.git

# git clone https://github.com/DragOnMe/playbook-allinone-cfg.git

# # v1.5 기준, 아래 내용 삭제

# cd openshift-ansible

# git branch -a

* master

  remotes/origin/HEAD -> origin/master

  remotes/origin/master

  remotes/origin/release-1.1

  remotes/origin/release-1.2

  remotes/origin/release-1.3

  remotes/origin/release-1.4

  remotes/origin/release-1.5

  remotes/origin/stage

  remotes/origin/stage-130

  remotes/origin/stage-131

# git checkout remotes/origin/release-1.4

Note: checking out 'remotes/origin/release-1.4'.


You are in 'detached HEAD' state. You can look around, make experimental

changes and commit them, and you can discard any commits you make in this

state without impacting any branches by performing another checkout.


If you want to create a new branch to retain commits you create, you may

do so (now or later) by using -b with the checkout command again. Example:


  git checkout -b new_branch_name


HEAD is now at 7493438... Automatic commit of package [openshift-ansible] release [3.4.1.29-1].

# cd .. 

# vi playbook-allinone-cfg/centos7-3node-playbook.cfg

[OSEv3:children]

masters

nodes


[OSEv3:vars]

ansible_ssh_user=root

deployment_type=origin

containerized=true


# Examples

openshift_install_examples=true


# Persistent metrics over NFS or Dynamic storage

openshift_hosted_metrics_deploy=true

openshift_hosted_metrics_storage_kind=nfs

openshift_hosted_metrics_storage_access_modes=['ReadWriteMany']

openshift_hosted_metrics_storage_nfs_directory=/mnt/persistent-volumes

openshift_hosted_metrics_storage_nfs_options='*(rw,root_squash)'

openshift_hosted_metrics_storage_volume_name=metrics

openshift_hosted_metrics_storage_volume_size=5Gi

openshift_hosted_metrics_storage_host=osmaster.test.local

openshift_hosted_metrics_public_url=https://hawkular-metrics.apps.test.local/hawkular/metrics


# htpasswd authentication

openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider', 'filename': '/etc/origin/master/htpasswd'}]


# release and image tag

openshift_release=v1.5

openshift_image_tag=v1.5.0

#openshift_pkg_version=-1.5.0


# router node

openshift_hosted_router_selector='region=infra'


# subdomain

openshift_master_default_subdomain="apps.test.local"


# pods placement

osm_default_node_selector='region=primary'


[masters]

osmaster.test.local openshift_public_hostname="osmaster.test.local" openshift_schedulable=true


[nodes]

osmaster.test.local openshift_node_labels="{'region': 'infra', 'zone': 'default'}"

osnode01.test.local openshift_node_labels="{'region': 'primary', 'zone': 'datacenter1'}" openshift_schedulable=true

osnode02.test.local openshift_node_labels="{'region': 'primary', 'zone': 'datacenter2'}" openshift_schedulable=true


[root@osmaster ~]# ansible-playbook -i ./playbook-allinone-cfg/centos7-3node-playbook.cfg ./openshift-ansible/playbooks/byo/config.yml -e openshift_disable_check=memory_availability,disk_availability


PLAY [Create initial host groups for localhost] **************************************************************************************


TASK [include_vars] ******************************************************************************************************************

ok: [localhost]


TASK [Evaluate group l_oo_all_hosts] *************************************************************************************************

ok: [localhost] => (item=osmaster.test.local)

ok: [localhost] => (item=osnode01.test.local)

ok: [localhost] => (item=osnode02.test.local)


PLAY [Create initial host groups for all hosts] **************************************************************************************


TASK [include_vars] ******************************************************************************************************************

ok: [osmaster.test.local]

ok: [osnode01.test.local]

ok: [osnode02.test.local]


PLAY [Populate config host groups] ***************************************************************************************************


TASK [fail] **************************************************************************************************************************

 [WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: {{ g_etcd_hosts is not

defined }}


skipping: [localhost]

...

...

...

TASK [openshift_excluder : Enable docker excluder] ***********************************************************************************

changed: [osmaster.test.local]

changed: [osnode02.test.local]

changed: [osnode01.test.local]


TASK [openshift_excluder : Check for openshift excluder] *****************************************************************************

ok: [osmaster.test.local]

ok: [osnode01.test.local]

ok: [osnode02.test.local]


TASK [openshift_excluder : Enable openshift excluder] ********************************************************************************

changed: [osnode01.test.local]

changed: [osnode02.test.local]

changed: [osmaster.test.local]


PLAY RECAP ***************************************************************************************************************************

localhost                  : ok=9    changed=0    unreachable=0    failed=0   

osmaster.test.local      : ok=617  changed=104  unreachable=0    failed=0   

osnode01.test.local      : ok=275  changed=41   unreachable=0    failed=0   

osnode02.test.local      : ok=272  changed=39   unreachable=0    failed=0   



  • Containerized 방식의 ansible-playbook을 통한 자동 설치 과정은 하드웨어 성능에 따라 다르겠지만, 대략 10~20분 정도 소요된다
  • [nodes] 영역의 master 부분에서 openshift_schedulable=true 로 하지 않으면 registry 등의 필수적 docker container가 deploy 되지 않아서 OpenShift Cluster가 정상 작동하지 않음에 유의  
  • 오류 없이 성공적으로 수행 된 경우, 최종 출력되는 라인들에서 각 노드 별로 failed=0 값이 출력되어야 한다.
  • 실행 도중 오류가 나는 경우, 진행되었던 설치 과정의 흔적을 다음과 같은 명령으로 Clear 한 후, 각종 문제(주로 selinux 설정, firewalld-iptables, nfs 마운트, URL 오류 관련 문제 등)을 해결하고, 위의 ansible-playbook 명령으로 다시 설치를 시도해야 한다
  • 진행된 모든 과정을 이전 상태로 되돌리기 위해서는 아래 과정을 참고한다

[root@osmaster ~]# ansible-playbook -i ./playbook-allinone-cfg/centos7-3node-playbook.cfg ./openshift-ansible/playbooks/adhoc/uninstall.yml

[root@osmaster ~]# iptables -t nat -F; iptables -F

[root@osmaster ~]# rm -rf /mnt/persistent-volumes/*

[root@osmaster ~]# rm -f /etc/exports


  • 최초 OpenShift 계정으로 guest 계정 생성, 접속 테스트

[root@osmaster ~]# cd /etc/origin/master/

[root@osmaster ~]# cat htpasswd

[root@osmaster ~]# htpasswd -b /etc/origin/master/htpasswd guest openshift

[root@osmaster ~]# oc login

Authentication required for https://osmaster:8443 (openshift)

Username: guest

Password: 

Login successful.


You don't have any projects. You can try to create a new project, by running


    oc new-project <projectname>


[root@osmaster ~]# oc status

Error from server: User "guest" cannot get projects in project "default"

[root@osmaster ~]# oc logout

Logged "guest" out on "https://osmaster:8443"


  • OpenShift용 Persistent Volume 생성(2GB * 15)
    - 사전에 만들어 두고 인스턴스들이 가져다 쓰는 개념으로, 개별 볼륨의 크기와 갯수는 스토리지의 크기와 상황에 맞게 조정
    - Persistent(지속적인) 스토리지에 반대되는 개념은 Ephemeral(일회용의, 단명하는) 스토리지로, Docker가 기본적으로 사용하는 스토리지는 /tmp/ 영역을 사용하는 AUFS(Union 파일시스템) 방식이며, Docker 컨테이너가 삭제되면 이 영역의 데이터도 같이 사라짐
    - 볼륨의 크기 지정 방법과 옵션에 대해서는 Kubernetes Resource Model 을 참고

[root@osmaster ~]# vi playbook-allinone-cfg/pv.json

{

 "apiVersion": "v1",

 "kind": "PersistentVolume",

 "metadata": {

 "name": "pv001"

},

"spec": {

   "capacity": {

   "storage": "2Gi"

   },

   "accessModes": [ "ReadWriteMany" ],

   "nfs": {

      "path": "/mnt/persistent-volumes/pv001",

      "server": "192.168.10.160"

   },

   "persistentVolumeReclaimPolicy": "Recycle"

   }

}


[root@osmaster ~]# oc login -u system:admin

[root@osmaster ~]# for i in `seq -w 001 015`; do \

SHARE=/mnt/persistent-volumes/pv$i; \

mkdir -p $SHARE; chmod 777 $SHARE; \

chown nfsnobody:nfsnobody $SHARE; \

echo "$SHARE 192.168.0.0/16(rw,all_squash)" >>/etc/exports; \

sed s/pv001/pv$i/g /root/playbook-allinone-cfg/pv.json | oc create -f -; \

done

persistentvolume "pv001" created

persistentvolume "pv002" created

persistentvolume "pv003" created

persistentvolume "pv004" created

persistentvolume "pv005" created

persistentvolume "pv006" created

persistentvolume "pv007" created

persistentvolume "pv008" created

persistentvolume "pv009" created

persistentvolume "pv010" created

persistentvolume "pv011" created

persistentvolume "pv012" created

persistentvolume "pv013" created

persistentvolume "pv014" created

persistentvolume "pv015" created

[root@osmaster ~]# oc get pv

NAME      CAPACITY   ACCESSMODES   RECLAIMPOLICY   STATUS      CLAIM     REASON    AGE

pv001     2Gi        RWX           Recycle         Available                       9s

pv002     2Gi        RWX           Recycle         Available                       8s

pv003     2Gi        RWX           Recycle         Available                       8s

pv004     2Gi        RWX           Recycle         Available                       8s

pv005     2Gi        RWX           Recycle         Available                       8s

pv006     2Gi        RWX           Recycle         Available                       7s

pv007     2Gi        RWX           Recycle         Available                       7s

pv008     2Gi        RWX           Recycle         Available                       7s

pv009     2Gi        RWX           Recycle         Available                       7s

pv010     2Gi        RWX           Recycle         Available                       6s

pv011     2Gi        RWX           Recycle         Available                       6s

pv012     2Gi        RWX           Recycle         Available                       6s

pv013     2Gi        RWX           Recycle         Available                       6s

pv014     2Gi        RWX           Recycle         Available                       5s

pv015     2Gi        RWX           Recycle         Available                       5s


## Openshift 재설치 등을 위한 삭제시에는 oc delete pv <pv-name> 으로 개별 볼륨을 삭제하거나 다음과 같이 한번에 삭제할 수도 있다(데이터 유실에 유의해야 함)
[root@osmaster ~]# for i in `seq -w 001 015`; do oc delete pv pv$i; done
[root@osmaster ~]# rm -rf /mnt/persistent-volumes/metrics

  • Openshift 재시작, Guest 및 관리자 계정(admin) 생성

[root@osmaster ~]# systemctl restart origin-master reboot

[root@osmaster ~]# htpasswd -b /etc/origin/master/htpasswd admin openshift

[root@osmaster ~]# oc login -u system:admin

[root@osmaster ~]# oadm policy add-cluster-role-to-user cluster-admin admin

[root@osmaster ~]# oc get all 



기능 테스트 단계


  • 웹브라우저를 통해 https://osmaster.test.local:8443 으로 접속하면 Origin 로그인 화면이 나타나고 guest 계정으로 로그인이 정상적인지 확인해 보자


이게 전부라면 얼마나 좋을까만, 기쁘게도 확인하고 알아둬야 할 내용들이 더 있다(실은 아주 더 많다). 참고로 OpenShift 를 익숙하게 사용하기 위해서는 OpenShift Console Web(GUI)를 통한 기본 사용법, 프로젝트의 구성 현황/상태 확인 방법과 함께 CLI(oc, oadm 등 명령. → 참고) 사용과 빌드/배포 자동화를 위한 yaml 파일 수정/편집과 OpenShift 의 Architecture에 대한 이해가 필요할 듯 싶다. 



  • OpenShift 사용과 활용에 앞서


여기서는 

  • 먼저, Googling으로 쉽게 접해볼 수 있는 오픈소스 프로젝트 2가지를 GibHub 를 통해 연동하여 환경 구축을 한 후, OpenShift로 개발/운영을 수행하는 과정(프로젝트 생성, GitHub연동, Build & Deploy, 테스트 과정)을 살펴본 뒤, 
  • 두 번 째로 Auto-scaling metric 설정을 통한 부하(cpu/memory)에 따른 자동 scale-up/down  을 테스트 해 보고 
  • 세 번 째로 persistent volume 이 없을 때(docker의 ephemeral 특성)와 있을 때(persistent 기능 확보) 각각에 대해 어떤 차이가 보이는지 확인해 본 다음, 위에서 생성한 NFS server를 통한 persistent volume을 공유 스토리지로 사용해 볼 것이다, 



4가지 대표적인 Use Case 경험하기


  • GibHub 를 사용한 개발과정 맛보기 #1 - Spring MVC Showcase(Java)
  • GibHub 를 사용한 개발과정 맛보기 #2 - WordPress Sample & MySQL(PHP)
  • Auto-Scaling 의 사용(Hawkular Metrics)
  • Persistent-Volume 의 사용



  • GibHub 를 사용한 개발과정 맛보기 #1 - Spring MVC Showcase(Java)


spring-mvc-showcase 프로젝트를 포크하고 URL을 복사해 둔다. pom.xml 파일이 있는 Maven 프로젝트(Clone or download 클릭 & URL 복사)


OpenShift 콘솔에 로그인(설치 직후에 생성한 guest 계정 정보 guest / openshift 로 로그인)


New Project 를 선택하고 새로운 프로젝트를 생성(Create)


프로젝트를 생성하면 자동적으로 Add to Project 과정이 실행되고 프로젝트에 추가할 컴포넌트를 선택할 수 있게 된다. 여기서는 Java 선택


OpenShift 는 Java 를 구동할 수 있는 컴포넌트로 WildFly(WAS인 Jboss의 Open 버전) Docker Container를 기본으로 제공한다(Select)


Resource 이름을 적당히 지정하고, 위에서 복사해 둔 GitHub 프로젝트의 URL을 복사(Create)


"Application created." 라는 메시지와 함께 Continue to overview 링크를 누르고 싶게 만드는 화면이 나타난다. 아래에 Command Line Tool인 oc(OpenShift Client) 의 간단한 사용법이 보이는데, 현재 GUI상에서 수행하는 모든 작업들은 oc 명령어로 가능하며, GUI방식보다 디테일한 작업을 위해서는 oc 명령어를 익혀두어야 할 때가 올 수도 있다(일단 클릭)


다음 단계인 Build 과정으로, Summary 탭 내에서 Application의 빌드가 수행되고 있다는 표시로 동적아이콘이 빙빙 돌아가고 있다(View Log 클릭) 


터미널 창에서 oc logs 를 수행한 결과와 동일한 로그 내용이 실시간으로 확인 가능하다. 'Status: ' 우측에 역시 동적아이콘이 빙빙 돌아가고 있으며, Build가 완료되면 'Complete' 로 바뀐다.


Build가 완료되었다. 콘솔 창을 가장 아래로 스크롤해 보면 "Push successful" 이라고 메시지가 나올 것이다. Build가 완료된 직후, OpenShift는 Build된 바이너리 파일들이 담긴 Docker Image를 새로 생성된 Pod에 밀어 넣고 Application 이 실행 가능한 상태로 Deploy를 완료한다


왼쪽 메인 아이콘 목록에서 'Overview' 를 클릭, 프로젝트내 리소스를 확인한다. 하단 직사각형 Box 부분이 하나의 Service 이며, 'sample-01-mvc' 라는 서비스 내에 pod가 1개 위치하고, 해당 컨테이너의 Build 이미지 정보가 왼쪽에 표시된다. 상단에 서비스에 접속할 수 있는 URL(서비스 Routes)이 자동으로 생성되어 있음을 볼수 있다(URL 클릭) 


마지막으로, 현재까지 빌드&배포된 Application의 정상 동작을 확인해 본다. 앞에서 URL을 클릭하면 새로운 탭에서 OpenShift 가 만들어준 Application이 동작하는 웹페이지가 나타난다. 주소 끝에 'spring-mvc-showcase/' 경로를 입력하고 엔터 


Java 개발자에게 친숙한 MVC Showcase 페이지가 성공적으로 수행되었다. 각 탭을 클릭해서 정상 작동하는지 테스트 해보자


     GitHub 프로젝트의 소스를 개발자가 수정하는 경우를 따라가 보자. 일반적으로는 개발자가  git client 로 프로그램을 수정하고, 최종적으로 Origin의 Master Branch 에 수정이 가해지겠지만, 여기서는 단순히 테스트를 위한 것이므로 GitHub에서 Master를 직접 수정하는 것으로 진행한다.  'home.jsp' 파일을 위와 같이 수정하자


수정된 내용을 commit


메인 아이콘을 통해 'Builds > Builds' 클릭


Build 리스트의 빌드명 클릭


'Start Build' 클릭, 아래에 Build 진행 상태가 표시되며, 나머지는 앞서 최초 빌드 진행 과정과 거의 동일하며, 앞서와 마찬가지로 'View Log' 를 통해 진행 상황을 확인할 수 있다. 최종 수행 결과에 대한 확인 과정은 위와 반복되는 내용이므로 생략한다



아래에 이어지는 나머지 3가지 Case는, 페이지 분량이 많은 관계로 3편으로 이어서 연재한다. 


  • GibHub 를 사용한 개발과정 맛보기 #2 - WordPress Sample & MySQL(PHP)
  • Auto-Scaling 의 사용(Hawkular Metrics)
  • Persistent-Volume 의 사용



[연관되는 글]

[OpenShift v3 #1] Origin all-in-one, CentOS 7 기반 단일서버 설치 사용법(1/3)

[OpenShift v3 #3] Origin 3-node, CentOS 7 기반 3노드 설치, 사용 방법(3/3)


- Barracuda -


저작자 표시 비영리 변경 금지
신고
블로그 이미지

Barracuda

Bryan의 MemoLog. 쉽게 익혀 보는 IT 실습과 개념원리, 코딩 세계의 얕은 맛보기들, 평범한 삶 주변의 현상 그리고 進上, 眞想, 진상들


OpenShift 를 설치 하기위한 구성은 싱글 서버(All-In-One)부터 10대 이상의 구성까지 다양하다. 이번 포스팅에서는 단일서버에 OpenShift 를 설치하는 과정을 기록하고 관리하도록 한다. OpenShift 는 v3로 넘어오면서 Kubernetes 의 Container, Storage, SDN 오케스트레이션을 완성도 있게 구현하여, 한층 단순하고 안정적으로 다룰 수 있게 되었다. 즉 기존의 Gear/Broker/Cartridges 의 생소한 개념들을 걷어내고 Docker/Kubernetes/Docker Images 개념으로 재정립하여 구조적으로 간단해지고, 널리 알려진 인프라 기술이 적용되었으며, 더 나은 UX를 제공하게 된 것이다. 


최근에 들어서 기존의 rpm 설치 방식을 간결하게 만든 dockerized 설치 방식이 일반화되고 있으며, 여기서 설치할 OpenShift는 v3 Origin 버전의 경우도, Dockerized 설치 방식으로 Ansible-playbook 을 통해  로컬서버에 호스팅되는 형식으로 구현되어 있다.


참고로 본 글은, OpenShift 설치와 사용법에 관련한 총 2개의 시리즈 중 첫 번째로, 다음 회에서는 1 Master 2 Node 설치 과정과 Kubernetes를 통한 Docker/Container, Storage, Network의 Orchestration과 Build/Deploy 에 대해 실제 사용 사례(Use Case)별 구현과 체험을 간략히 진행해 보는 것으로 예정하고 있다. 



  • OpenShift v3 Concepts



사전 설정(Pre-requisites)

  • 서버 구성(최소 사양) : 2 CPU, 8 G memory, 20G+20G(추가디스크) Disk
    - OS는 CentOS 7.3, Minimal Server 버전
    - 추가디스크는 Persistent Storage를 위한 NFS 용 스토리지로, /mnt/persistent-volumes 에 마운트
  •  내부 테스트 또는 외부 서비스용 별도 DNS 서버 필요
    - 여기서는 내부 테스트용 test.local 도메인을 named 를 통해서 존파일 설정(DNS forwarding 사용)



  • DNS forwarding 을 위한 설정 내용을 일단 정리해두고 넘어가자(192.168.0.0/16 네트워크 사용시).


[root@dns ~]# cat /etc/named.conf 

options {

listen-on port 53 { any; };

directory "/var/named";

dump-file "/var/named/data/cache_dump.db";

statistics-file "/var/named/data/named_stats.txt";

memstatistics-file "/var/named/data/named_mem_stats.txt";


allow-query     { any; };

recursion yes;


// For non-internal domains

forwarders {

168.126.63.1;

8.8.8.8;

};

auth-nxdomain no; # conform to RFC1035

dnssec-enable yes;

// dnssec-validation yes;

dnssec-lookaside auto;


/* Path to ISC DLV key */

bindkeys-file "/etc/named.iscdlv.key";


managed-keys-directory "/var/named/dynamic";


pid-file "/run/named/named.pid";

session-keyfile "/run/named/session.key";

};


logging {

        channel default_debug {

                file "data/named.run";

                severity dynamic;

        };

};


zone "." IN {

type hint;

file "named.ca";

};


include "/etc/named.rfc1912.zones";

include "/etc/named.root.key";


[root@dns ~]# cat /etc/named.rfc1912.zones

...(생략)...

zone "0.in-addr.arpa" IN {

type master;

file "named.empty";

allow-update { none; };

};


zone "test.local" IN {

        type master; // server type

        file "test.local.zone"; // zone file

        allow-update {none;}; // none: no slave to sync

};


zone "168.192.in-addr.arpa" IN { // Reverse

        type master;

        file "/var/named/rev.168.192.in-addr.arpa";

};


[root@dns ~]# cat /var/named/test.local.zone

$ORIGIN .

$TTL 10


test.local.    IN    SOA    dns.test.local.    root.test.local. (

2017031402    ; serial

1D       ; refresh

1H       ; retry

1W      ; expire

3H )    ; min(Negative cache TTL)

test.local.          IN    NS    dns.test.local.

dns.test.local.    IN    A    192.168.0.3


$ORIGIN    test.local.


openshift3    IN    A    192.168.10.145

*.openshift3  IN    A    192.168.10.145


[root@dns ~]# cat /var/named/rev.168.192.in-addr.arpa 

$TTL 10


@    IN    SOA    dns.test.local.    root.test.local. (

2017031403 ; serial

1D ; refresh

1H ; retry

1W ; expire

3H ) ; min(Negative cache TTL)

test.local.          IN    NS    dns.test.local.

dns.test.local.    IN    A    192.168.0.3


@      IN NS      dns.test.local.

3.0    IN PTR    dns.test.local.


145.10    IN PTR    openshift3.test.local.



  • 준비된 노드에서 다음과 같은 사전설치 과정을 따른다

# vi /etc/sysconfig/network-scripts/ifcfg-eth0

...

NETMASK=255.255.0.0

DNS1=192.168.0.3

DNS2=8.8.8.8

# hostnamectl set-hostname openshift14-allinone

# yum install -y bind-utils git iptables-services

# systemctl enable iptables

# systemctl start iptables

# nslookup openshift3.test.local

# dig yahoo.com a


# ssh-keygen

# ssh-copy-id root@openshift3.test.local

# ssh root@openshift3.test.local



OpenShift v3 설치 시작


  • EPEL repo를 설정하고 필요한 패키지 설치

# yum install -y epel-release

# yum install -y docker wget ansible 

# yum install -y python-cryptography pyOpenSSL.x86_64


  • OpenShift Ansible 패키지와 configuration 소스 설치, 설정

# git clone https://github.com/DragOnMe/openshift-ansible.git

# git clone https://github.com/DragOnMe/playbook-allinone-cfg.git

# vi playbook-allinone-cfg/centos7-1node-playbook.cfg

[OSEv3:children]

masters

nodes


[OSEv3:vars]

ansible_ssh_user=root

deployment_type=origin

openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider', 'filename': '/etc/origin/master/htpasswd'}]

containerized=true

openshift_release=v1.4.1

openshift_image_tag=v1.4.1

openshift_public_hostname=openshift3.test.local

openshift_master_default_subdomain=apps.openshift3.test.local

openshift_hosted_metrics_deploy=false



[masters]

openshift3.test.local openshift_schedulable=true


[nodes]

openshift3.test.local openshift_node_labels="{'region': 'infra', 'zone': 'default'}" openshift_schedulable=true


# ansible-playbook -i ./playbook-allinone-cfg/centos7-1node-playbook.cfg ./openshift-ansible/playbooks/byo/config.yml


  • 실행 도중 오류가 나는 경우 진행되었던 설치 과정의 흔적을 Clear 한 후, 각종 문제(주로 selinux 설정, firewalld-iptables 관련 문제 등)을 해결하고 다시 설치를 시도해야 한다

# ansible-playbook -i ./playbook-allinone-cfg/centos7-1node-playbook.cfg ./openshift-ansible/playbooks/adhoc/uninstall.yml


  • 최초 OpenShift 계정으로 guest 계정 생성, 접속 테스트

# cd /etc/origin/master/

# cat htpasswd

# htpasswd -b /etc/origin/master/htpasswd guest openshift

# oc login

# oc status

# oc logout


  • NFS를 persistent storage 로 설치하기 위해 nfs-server 설치, 설정

# yum groupinstall -y file-server

# systemctl enable rpcbind

# systemctl enable nfs-server

# systemctl start rpcbind

# systemctl start nfs-server

# iptables-save > pre-nfs-firewall-rules-server

# iptables -I INPUT -m state --state NEW -p tcp -m multiport --dport 111,892,2049,32803 -s 0.0.0.0/0 -j ACCEPT

# iptables -I INPUT -m state --state NEW -p udp -m multiport --dport 111,892,2049,32769 -s 0.0.0.0/0 -j ACCEPT

# service iptables save

# setsebool -P virt_use_nfs 1


  • OpenShift용 Persistent Volume 생성(1GB * 15)

# vi playbook-allinone-cfg/pv.json

{

 "apiVersion": "v1",

 "kind": "PersistentVolume",

 "metadata": {

 "name": "pv001"

},

"spec": {

   "capacity": {

   "storage": "1Gi"

   },

   "accessModes": [ "ReadWriteOnce" ],

   "nfs": {

      "path": "/mnt/persistent-volumes/pv0001",

      "server": "192.168.10.145"

   },

   "persistentVolumeReclaimPolicy": "Recycle"

   }

}


# oc login -u system:admin

# for i in `seq -w 001 015`; do \

SHARE=/mnt/persistent-volumes/pv$i; \

mkdir -p $SHARE; chmod 777 $SHARE; \

chown nfsnobody:nfsnobody $SHARE; \

echo "$SHARE 192.168.0.0/16(rw,all_squash)" >>/etc/exports; \

sed s/pv001/pv$i/g /root/playbook-allinone-cfg/pv.json | oc create -f -; \

done

# oc get pv

# oc version

# oc get user

# oc config view

# oc get all


  • Guest 및 관리자 계정(admin) 생성

# htpasswd -b /etc/origin/master/htpasswd admin openshift

# oc login -u system:admin

# oadm policy add-cluster-role-to-user cluster-admin admin



마무리 & 테스트 단계


  • 웹브라우저를 통해 https://openshift3.test.local:8443 으로 접속하면 Origin 로그인 화면이 나타난다




다음 회를 기약하며


이번 회에서는 단일 서버 구성의 설치 과정에 대해서만 간단히 정리하고, 다음 #2 회에서 3-노드 설치, 설정과 함께, 3가지의 OpenShift 사용 Use Case를 직접 다뤄 보면서 조금 더 사용법과 개념에 익숙해 지는 기회를 만들고자 한다.


참고로 OpenShift Origin을 VirtualBox 등의 단일 VM내에서 작동시킬 수 있는 MiniShift 도 있으니 한 번 설치, 사용해 볼 만하다. DNS를 통하지 않는 IP 주소 기반의 사용 방식이지만 OpenShift의 대다수 기능들을 그대로 사용할 수 있게 만들어져 있다. 참조 주소는 다음과 같다.




[연관되는 글]

[OpenShift v3 #2] Origin 3-node, CentOS 7 기반 3노드 설치, 사용 방법(2/3)

[OpenShift v3 #3] Origin 3-node, CentOS 7 기반 3노드 설치, 사용 방법(3/3)



- Barracuda -



저작자 표시 비영리 변경 금지
신고
블로그 이미지

Barracuda

Bryan의 MemoLog. 쉽게 익혀 보는 IT 실습과 개념원리, 코딩 세계의 얕은 맛보기들, 평범한 삶 주변의 현상 그리고 進上, 眞想, 진상들