OpenShift 3.11에서 Egress IP를 설정하고 의도적으로 장애를 발생시켜 동작 방식을 테스트 한다.

1. Static IP 할당 방식

Virtual IP와 namespace는 1:1 매칭 방식으로만 사용 가능하다.
EgressIP는 실제 VIP를 가지는 노드에 secondary 방식으로 VIP를 할당하는 구조이다.

netnamespace에 여러개의 VIP를 할당 가능하지만,
hostsubnet에 등록되는 VIP를 서로 다른 노드와 중복하여 사용이 불가능 하다.

즉, egress01, 02 노드에 같은 VIP를 할당하여 사용할 수 없다.

1.1. Egress VIP namespace 할당
egress-test01 namespace에 6.6.6.201, 6.6.6.202 VIP를 2개를 할당 한다.

[root@bastion ~]# oc patch netnamespace egress-test01 -p ‘{“egressIPs”: [“6.6.6.201”, “6.6.6.202”]}’

– 확인
[root@bastion ~]# oc get netnamespace
NAME NETID EGRESS IPS
egress-test01 14188541 [6.6.6.201, 6.6.6.202]

1.2. VIP 노드 할당
실제 VIP가 할당 되는 노드에 적용한다.

– Egress01
[root@bastion ~]# oc patch hostsubnet egress01.ocp3.local -p ‘{“egressIPs”: [“6.6.6.201”]}’

– Egress02
[root@bastion ~]# oc patch hostsubnet egress02.ocp3.local -p ‘{“egressIPs”: [“6.6.6.202”]}’

– 확인
hostsubnet을 조회 해보면 VIP가 반영 된 것을 확인 가능하다.
[root@bastion ~]# oc get hostsubnet | grep egress
NAME HOST HOST IP SUBNET EGRESS CIDRS EGRESS IPS
egress01.ocp3.local egress01.ocp3.local 6.6.6.13 172.40.6.0/23 [] [6.6.6.201]
egress02.ocp3.local egress02.ocp3.local 6.6.6.14 172.40.7.0/23 [] [6.6.6.202]

또한, 실제 egress01,02 노드에 접속하여 네트워크 인터페이스를 확인 해보면,
secondary 형태로 VIP가 할당 된 것을 확인 가능하다.
[root@egress01 ~]# ip a s | grep -v ‘veth’ | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
inet 6.6.6.13/24 brd 6.6.6.255 scope global noprefixroute eth0
inet 6.6.6.201/24 brd 6.6.6.255 scope global secondary eth0:eip

[root@egress02 ~]# ip a s | grep -v ‘veth’ | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
inet 6.6.6.14/24 brd 6.6.6.255 scope global noprefixroute eth0
inet 6.6.6.202/24 brd 6.6.6.255 scope global secondary eth0:eip

2. CIDR 방식

CIDR(Classless Inter-Domain Routing) 방식은 IP 대역 기준으로 사용한다.
즉, 6.6.6.0/24를 갖는 대역에 netnamespace로 지정한 VIP를 자동 할당하여 사용하는 방식이다.

Static IP 방식은 해당 노드에 VIP를 수동 할당 해야 하지만,
CIDR 방식은 해당 노드에 VIP를 따로 설정하지 않아도,
hostsubnet에 설정 된 CIDR과 일치하는 노드에 자동으로 VIP를 할당 하도록 해준다.

netnamespace에 VIP 1개만 할당 가능하다.

2.1. Egress VIP namespace 할당
[root@bastion ~]# oc patch netnamespace egress-test01 -p ‘{“egressIPs”: [“6.6.6.201”]}’

– 확인
[root@bastion ~]# oc get netnamespace
NAME NETID EGRESS IPS
egress-test01 14188541 [6.6.6.201]

2.2. Egress VIP 노드 할당
실제 VIP가 할당 될 노드에 CIDR을 설정 한다.

– Egress Node01
# oc patch hostsubnet egress01.ocp3.local -p ‘{“egressCIDRs”: [“6.6.6.0/24”]}’

– Egress Node02
# oc patch hostsubnet egress02.ocp3.local -p ‘{“egressCIDRs”: [“6.6.6.0/24”]}’

– 확인
[root@bastion ~]# oc get hostsubnet
NAME HOST HOST IP SUBNET EGRESS CIDRS EGRESS IPS
egress01.ocp3.local egress01.ocp3.local 6.6.6.13 172.40.6.0/23 [6.6.6.0/24] [6.6.6.201]
egress02.ocp3.local egress02.ocp3.local 6.6.6.14 172.40.7.0/23 [6.6.6.0/24] []

3. 절체(Failover) 테스트

위 설정을 통해 VIP가 할당 된 노드 중 1대가 장애 발생시, 발생 시점부터 복구까지의 대한 내용이다.

– 장애 재현
egress01 노드를 강제로 shudown 후 failover에 대한 시간을 체크 한다.
기본적으로 링크[1],[2]의 소스코드에서 확인할 수 있듯이 하드코딩 되어있는 시간은 5초이다.
5초 이후 인프라 환경에 따라 지연 시간을 포함한 계산식에 의해 절체시간이 산정 되는 방식이다.

– 테스트 환경
* Linux KVM
* 1Gbps 네트워크
* 서비스 Pod단에서 매 1초마다 외부 서비스로 호출로 파악

– Shudown 시점
6.6.6.201 – – [01/Jul/2019:11:09:00 +0900] “GET / HTTP/1.1” 200 3985 “-” “curl/7.29.0”

– Failover 시점
6.6.6.202 – – [01/Jul/2019:11:09:32 +0900] “GET / HTTP/1.1” 200 3985 “-” “curl/7.29.0”

– 결과
failover 이후까지 약 32초가 걸렸으나, 실제 고객사 환경에서는 10초 내외로 나왔었다.
인프라 환경에 따라서, 결과값의 오차 범위가 넓어, 평균치를 내는 것이 좋음.

또한, netnamespace에 할당 된 EgressIPs는 배열을 기준으로 failover시 VIP가 할당 되는 형태이다.

– RefURL
[1]: https://github.com/openshift/origin/blob/release-3.11/pkg/network/master/egressip.go#L133-L137
[2]: https://github.com/openshift/origin/blob/release-3.11/pkg/network/node/vxlan_monitor.go#L21-L74
[3]: https://docs.openshift.com/container-platform/3.11/admin_guide/managing_networking.html#enabling-static-ips-for-external-project-traffic
[4]: https://docs.openshift.com/container-platform/3.11/admin_guide/managing_networking.html#admin-guide-automatic-egress-ip