기본적인 구성은 아래와 같이 worker3대가 10.10.2.0/24의 인터페이스가 연결되어 있으며, 같은 네트워크에 BGP를 사용할 L3SW가 연결 되어 있다.
그리고 Client 는 172.16.100.0 대역대로 L3SW와 연결 되어 있다.
NXOS-9K로 구성된 상단 스위치의 인터페이스 설정은 아래와 같다.
interface Ethernet1/1
no switchport
ip address 10.10.2.210/24
no shutdown
interface Ethernet1/2
no switchport
ip address 172.19.100.210/24
no shutdown
...
metallb 구성을 위하여 kubernetes 에서 kube-proxy strictARP true로 변경 해야 한다.
$ kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl diff -f - -n kube-system
$ kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl apply -f - -n kube-system
아래와 같이 metallb의 매니페스트를 등록 한다.
$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.5/manifests/namespace.yaml
$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.5/manifests/metallb.yaml
$ kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"
배포된 metallb pod는 1개의 controller 와 각 노드 별로 speaker pod 가 동작하는것을 확인할 수 있다.
root@cy01-net114:~# kubectl get pod -n metallb-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
controller-65db86ddc6-9nvk9 1/1 Running 0 126m 10.233.64.23 cy01-net114 <none> <none>
speaker-k5tvq 1/1 Running 1 18h 10.10.2.112 cy01-net112 <none> <none>
speaker-lhwmb 1/1 Running 1 18h 10.10.2.114 cy01-net114 <none> <none>
speaker-q9dhp 1/1 Running 2 18h 10.10.2.113 cy01-net113 <none> <none>
이제 상단의 L3스위치와 각노드에 있는 speaker가 eBGP peer가 연결되도록 한다.
L3스위치에서는 65210 AS번호를 사용 하고 각 worker 노드의 speaker 는 65211 AS로 연결 하도록 한다.
BGP연결을 위한 ConfigMap 을 작성 한다. 여기서 external IP 로 사용할 대역대를 172.19.100.0/24 대역대로 사용 하도록 한다.
root@cy01-net112:~# cat bgp.yaml
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
peers:
- peer-address: 10.10.2.210
peer-asn: 65210
my-asn: 65211
address-pools:
- name: default
protocol: bgp
avoid-buggy-ips: true
addresses:
- 172.19.100.0/24
root@cy01-net112:~# kubectl create -f bgp.yaml
이제 L3스위치에서 bgp 설정을 해준다 .
...
router bgp 65210
router-id 1.1.1.1
address-family ipv4 unicast
maximum-paths 3
neighbor 10.10.2.112
remote-as 65211
address-family ipv4 unicast
neighbor 10.10.2.113
remote-as 65211
address-family ipv4 unicast
neighbor 10.10.2.114
remote-as 65211
address-family ipv4 unicast
...
설정이 완료 되면 아래와 같이 각 worker 노드에 있는 speaker의 bgp와 peer를 확인할 수 있다.
switch# show ip bgp sum
BGP summary information for VRF default, address family IPv4 Unicast
BGP router identifier 1.1.1.1, local AS number 65210
BGP table version is 41, IPv4 Unicast config peers 3, capable peers 0
1 network entries and 3 paths using 500 bytes of memory
BGP attribute entries [1/160], BGP AS path entries [1/6]
BGP community entries [0/0], BGP clusterlist entries [0/0]
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
10.10.2.112 4 65211 1764 1773 42 0 0 00:00:30 1
10.10.2.113 4 65211 2132 2151 42 0 0 00:00:30 1
10.10.2.114 4 65211 1198 1208 42 0 0 00:00:30 1
BGP Peer 연결은 다른 장비와 장비 간의 Peer 연결과 거의 동일하다. 아래 10.10.2.114 에 있는 speaker 기준으로 초기 상단 l3 장비에 BGP 포트인 179 포트로 Syn 패킷을 보내기 시작 하여 세션을 연결한다.
세셩연결이 완료 되면 Open Message 와 Keepalve 패킷을 주면서 세션 연결을 유지 한다.
Metallb 에서 VIP 사용된 아이피 정보가 업데이트 되면 상단에 Update Message 에 해당 VIP 정보인 17219.10.1 에대한 NLRI 정보를 추가 하여 Nexthop 과 함께 전달하여 상단 L3 에서 BGP Routing 정보를 추가해준다.
당연하지만 Speaker 가 있는 호스트에는 57811 포트로 상단 L3 장비의 10.10.2.210 179포트로 세션이 연결된것이 확인 된다.
root@cy01-net114:~# netstat -atunp | grep speaker
tcp 0 0 10.10.2.114:7472 0.0.0.0:* LISTEN 1684866/speaker
tcp 0 0 10.10.2.114:7946 0.0.0.0:* LISTEN 1684866/speaker
tcp 0 0 10.10.2.114:57811 10.10.2.210:179 ESTABLISHED 1684866/speaker
tcp 0 0 10.233.0.1:57500 10.233.0.1:443 ESTABLISHED 1684866/speaker
udp 0 0 10.10.2.114:7946 0.0.0.0:* 1684866/speaker
간단하게 Loadbalancer 타입의 Service로 동작 하도록 pod 를 배포한다.
root@cy01-net112:~# vi test.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: ng-test-rs
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: con-test
template:
metadata:
labels:
app: con-test
spec:
containers:
- image: 'stenote/nginx-hostname'
name: ng-con
---
apiVersion: v1
kind: Service
metadata:
name: ng-svc
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: con-test
type: LoadBalancer
root@cy01-net112:~# kubectl create -f test.yaml
Metallb에 의하여 172.19.100.1 라는 External IP를 확인한다.
root@cy01-net112:~# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 2d1h
ng-svc LoadBalancer 10.233.58.33 172.19.100.1 80:31265/TCP 3s
root@cy01-net112:~# curl 172.19.100.1
ng-test-rs-wktfr
root@cy01-net112:~# curl 172.19.100.1
ng-test-rs-v7gcr
이제 L3스위치에서는 172.19.100.1 아이피에대한 라우팅 정보를 Speaker 에서 eBGP로 받은 경로로 라우팅이 추가 된것을 볼수 있다.
switch# show ip route bgp
IP Route Table for VRF "default"
'*' denotes best ucast next-hop
'**' denotes best mcast next-hop
'[x/y]' denotes [preference/metric]
'%<string>' in via output denotes VRF <string>
172.19.100.1/32, ubest/mbest: 3/0
*via 10.10.2.112, [20/0], 00:00:41, bgp-65210, external, tag 65211
*via 10.10.2.113, [20/0], 00:00:41, bgp-65210, external, tag 65211
*via 10.10.2.114, [20/0], 00:00:41, bgp-65210, external, tag 65211
switch# show ip bgp
BGP routing table information for VRF default, address family IPv4 Unicast
BGP table version is 45, Local Router ID is 1.1.1.1
Status: s-suppressed, x-deleted, S-stale, d-dampened, h-history, *-valid, >-best
Path type: i-internal, e-external, c-confed, l-local, a-aggregate, r-redist, I-i
njected
Origin codes: i - IGP, e - EGP, ? - incomplete, | - multipath, & - backup
Network Next Hop Metric LocPrf Weight Path
*|e172.19.100.1/32 10.10.2.113 0 65211 ?
*>e 10.10.2.112 0 65211 ?
*|e 10.10.2.114 0 65211 ?
client 노드에서 172.19.100.1 아이피로 접속하면 통신이 되는것을 알수 있다.
root@cy01-ceph231:~# curl 172.19.100.1
ng-test-rs-7flkj
root@cy01-ceph231:~# curl 172.19.100.1
ng-test-rs-wktfr
kubernetes 상에서 LoadBalancer 타입의 service의 External IP 는 speaker 가 있는 노드의 ipvs0 이름의 인터페이스로 172.19.100.1아이피가 바인딩 된것을 알수 있다. 해당 인터페스는 ipvs로 배포된 pod 의 아이피로 연결 되는것을 알수 있다.
root@cy01-net114:~# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 47h
ng-svc LoadBalancer 10.233.54.73 172.19.100.1 80:30418/TCP 46h
root@cy01-net114:~# ip a
6: kube-ipvs0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default
link/ether c2:82:30:81:1a:16 brd ff:ff:ff:ff:ff:ff
inet 10.233.48.121/32 scope global kube-ipvs0
valid_lft forever preferred_lft forever
inet 172.19.100.1/32 scope global kube-ipvs0
valid_lft forever preferred_lft forever
inet 10.233.0.3/32 scope global kube-ipvs0
valid_lft forever preferred_lft forever
...
root@cy01-net114:~# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
...
TCP 172.19.100.1:80 rr
-> 10.233.64.16:80 Masq 1 0 0
-> 10.233.93.2:80 Masq 1 0 0
-> 10.233.119.2:80 Masq 1 0 0
...
root@cy01-net114:~# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ng-test-rs-8cdqc 1/1 Running 0 5h33m 10.233.119.2 cy01-net113 <none> <none>
ng-test-rs-blq89 1/1 Running 0 5h33m 10.233.64.16 cy01-net114 <none> <none>
ng-test-rs-rp42j 1/1 Running 0 5h33m 10.233.93.2 cy01-net112 <none> <none>
Client 에서 Pod까지의 흐름을 확인하면 아래 그림의 1번 부분에서 Client 가 curl 을 이용하여 요청을 보내게 되는데 Client 입장에서 Default Route로 설정된 L3SW의 172.16.100.210으로 패킷이 들어 간다. L3스위치에서는 BGP로 수신 받은 172.19.100.1의 라우팅 정보에 의하여 Best Path인 10.10.2.112 노드의 worker 노드로 들어 오게 된다.
그뒤 Worker 노드의 각 pod로 Service 에 의하여 분산 되는 구조 이다.
이제 Best Path 로 가고 사용 되는 node 를 reboot 해본다.
기존 노드에대한 라우팅 정보가 반영되어 다른 노드로 라우팅 되는것을 볼수 있다.
switch# show ip bgp
BGP routing table information for VRF default, address family IPv4 Unicast
BGP table version is 46, Local Router ID is 1.1.1.1
Status: s-suppressed, x-deleted, S-stale, d-dampened, h-history, *-valid, >-best
Path type: i-internal, e-external, c-confed, l-local, a-aggregate, r-redist, I-i
njected
Origin codes: i - IGP, e - EGP, ? - incomplete, | - multipath, & - backup
Network Next Hop Metric LocPrf Weight Path
*>e172.19.100.1/32 10.10.2.113 0 65211 ?
x e 10.10.2.112 0 65211 ?
*|e 10.10.2.114 0 65211 ?
'CNCF > Kubernetes' 카테고리의 다른 글
ExternalTrafficPolicy 설정을 위한 kubernetes service 분석 (0) | 2021.03.24 |
---|---|
Antrea Overview (0) | 2020.07.30 |
Kubernetes1.17 Hard Way (Libvirt) using docker,flannel (0) | 2020.03.22 |