CloudNet 가시다님이 진행하는 Kubernetes Advanced Networking Study 3주차 정리입니다.

[ Calico 네트워크 모드 ]

  • Calico는 다양한 네트우크 통신 방법(모드)를 제공합니다.
  • Calico나 Cilium에서 파드 혹은 네임스페이스의 레벨에서 IN/OUT 트래픽에 대한 통제가 가능합니다.

0. Calico Mode 요약

- IPIP 모드 

- Direct 모드

- VXLAN 모드

- Pod 패킷 암호화

1. IPIP모드

1.1 통신 흐름

요약 : 파드 간 통신이 노드와 노드 구간에서는 IPIP 인캡슐레이션을 통해서 이루어 집니다

  • 다른 노드 간의 파드 통신은 tunl0 인터페이스를 통해 IP 헤더에 감싸져서 상대측 노드로 도달 후 tunl0 인터페이스에서 Outer 헤더를 제거하고 내부의 파드와 통신
  • 다른 노드의 파드 대역은 BGP로 전달 받아 호스트 라우팅 테이블에 업데이트 됨
  • Azure 네트워크에서는 IPIP 통신이 불가능하여 IPIP 모드 대신 VXLAN 모드 사용
    - 멀티 캐스트, 브로드캐스트, IPIP 캡슐화 패킷 및 GRE(일반 라우팅 캡슐화) 패킷은 Azure VNet 내에서 차단됩니다.

1.2 기본 설정 확인

▶ calicoctl 및 네트워크 정보 확인

모드 정보 확인
노드(BGP) peer 정보 확인
BGP로 전달받은 파드 네트워크 대역이 호스트 라우팅 테이블에 적용되었는지 확인
워커노드마다 할당된 dedicated subnet 확인

 

 

1.3 동작 확인

▶ node3-pod3.yaml : 동작 확인을 위한 파드

▶ 파드 생성 및 패킷 캡쳐 확인

파드 IP 정보 확인
파드 접속하여 통신 확인

 

2. Direct 모드

2.1 통신 흐름

요약 : 파드 통신 패킷이 출발지 노드의 라우팅 정보를 보고 목적지 노드로 원본 패킷 그대로 전달합니다

( 클라우드 사업자 네트워크의 경우 NIC에 매칭되지 않는 IP 패킷은 차단되니, NIC에 Source/Destination Check 기능을 Disable 해야합니다 )

 

2.2 Direct 모드 설정

▶ Direct 모드 설정 및 확인

IPIPMODE 정보 확인
IPIP모드 Never 확인
라우팅 확인

 

 

2.3 동작 확인

▶ 파드 생성

파드 생성 후 정보 확인

 

▶ 파드간 ping 통신 실행 및 패킷 캡쳐 확인

워커노드 1,2 번 확인

★ 워커노드1(파드) -> 워커노드2(파드) or 워커노드0(파드)와 통신 확인! [ Overlay 네트워크 기법 필요 ]

: 워커 노드 0번은 네트워크 대역이 다름

: 라우팅 정보가 없어서 통신 불가

 

2.4 CrossSubnet 모드

동작 : 노드 간 같은 네트워크 대역(Direct 모드로 동작), 노드 간 다른 네트워크 대역(IPIP 모드로 동작)

▶ 설정 및 확인

CrossSubnet 모드 설정 확인

 

2.4 별도 IP Pool 생성 제공 > IP 대역 관리를 편하게 할 수 있다

▶ 별도 IP Pool 생성

# 모니터링
watch -d "route -n | egrep '(Destination|UG)'"
watch -d 'ip route | grep zebra' # k8s-rtr

# Create externally routable IP Pool
cat <<EOF | calicoctl apply -f - 
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: external-pool
spec:
  cidr: 172.18.0.0/16
  blockSize: 24
  ipipMode: CrossSubnet
  natOutgoing: false
  nodeSelector: "!all()"
EOF

# 확인
calicoctl get ippools
NAME                  CIDR            SELECTOR
default-ipv4-ippool   172.16.0.0/16   all()
external-pool         172.18.0.0/16   !all()

calicoctl ipam show
calicoctl ipam show --show-blocks

 

▶ 별도 IP Pool을 기본으로 사용할 수 있는 네임스페이스 생성 및 확인

# Create the namespace
cat <<EOF| kubectl apply -f - 
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    cni.projectcalico.org/ipv4pools: '["external-pool"]'
  name: external-ns
EOF

# 확인
kubectl get ns
kubectl describe ns external-ns

 

▶ 생성한 네임스페이스에 파드 생성 및 확인

# 모니터링
watch -d "route -n | egrep '(Destination|UG)'"
watch -d 'ip route | grep zebra' # k8s-rtr

# 디플로이먼드(파드) 생성
cat <<EOF| kubectl apply -f - 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: external-ns
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
        version: v1
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
      terminationGracePeriodSeconds: 0
EOF

# 네임스페이스 변경
kubens external-ns

# 생성 확인
kubectl get pod
calicoctl get wep -n external-ns

# 라우팅 정보 확인
route -n | egrep '(Destination|UG)'
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
172.18.158.0    192.168.10.101  255.255.255.0   UG    0      0        0 tunl0
172.18.184.0    192.168.10.102  255.255.255.0   UG    0      0        0 tunl0
...

ip route | grep zebra
172.18.34.0/24 via 192.168.20.100 dev enp0s9 proto zebra metric 20
172.18.158.0/24 via 192.168.10.101 dev enp0s8 proto zebra metric 20
172.18.184.0/24 via 192.168.10.102 dev enp0s8 proto zebra metric 20
...

# k8s-rtr 에서 파드로 ping 테스트
# 파드 IP를 변수 지정
POD1=172.18.158.0
POD2=172.18.184.0
POD3=172.18.34.0

# K8S 파드 네트워크 대역과 통신 확인!
ping -c 1 -I 10.1.1.254 $POD1
ping -c 1 -I 10.1.2.254 $POD2
ping -c 1 -I 10.1.1.254 $POD3
curl -s --interface 10.1.1.254 $POD1 | grep Welcome
curl -s --interface 10.1.2.254 $POD2 | grep Welcome
curl -s --interface 10.1.1.254 $POD3 | grep Welcome

 

5. Pod 패킷 암호화 (네트워크 레벨)

5.1 통신 흐름

요약 : Calico의 다양한 네트워크 모드 환경 위에서 WireGuard 터널을 자동 생성 및 파드 트래픽을 암호화하여 노드간 전달합니다.

▶ WireGuard 소개

  • IPsec 및 OpenVPN의 대항마로 등장한 open source VPN project이며 작년, Linux 5.6 커널에 WireGuard 1.0.0 기본 패키지로 탑재되었다
  • 정말 간결한 코드 구조와 빠른 성능(모든 것이 Kernel에서 동작하고, 주요 암호 알고리즘에 대해서 병렬처리하므로써 빠른 속도를 자랑함)

  • WireGuard는 보시다시피 경쟁자들인 IPSec, SoftEther VPN, OpenVPN 등과 비교할 때, 코드 size가 현격하게 작다
    그말은 코드량이 많지 않으니 그만큼 철저히 검증될 가능성이 높고, 예상치 못한 곳에서의 버그로 인한 취약점이 발생할 가능성이 상대적으로 작다
  • WireGuard는 Noise Protocol Framework을 기초로하여 상호 인증 및 키 교환(ECDH의 변형된 형태로 보면 됨 - Curve25519 ECC 공개키 암호 알고리즘 사용)이 이루어지고 있으며, ChaCha20(Stream Cipher 알고리즘), Poly1305(무결성 검사 알고리즘), BLAKE2s, SipHash24, HKDF 등 가장 빠르고 최신의 암호 및 해쉬 알고리즘을 사용한다
  • wireguard는 망 변경으로 peer의 ip주소가 변경되더라도 tunnel이 유지되는 특징이 있다. 이것이 가능한 이유는 idnex 기반으로 peer hash table이 운용되기 때문이다. 

 

5.2 WireFGuard 설정

▶ 노드에 WireGuard 설치

설치 및 버전 확인
WireGuard 설정 확인
키 확인
Wireguard.cali 인ㅌ페이스 확인
wireguard.cali 설정 확인 - 통신 포트, peer/endpoint 정보, 패킷 암호화를 위한 공개키/사설키 정보
Peer의 정보(고유한 index)
키 정보 확인

5.3 동작 확인

▶ 파드간 ping 통신 실행 및 패킷 캡쳐 확인

6. Calico 네트워크 접근 통제

  • 네트워크 정책 소개
    : 네트워크 정책(Network Policy)은 쿠버네티스 클러스터 내부에서 파드 간에 통신할 경우 트래픽 룰을 규정하는 것이다. 네트워크 정책을 사용하지 않을 경우 클러스터 내부의 모든 파드는 서로 통신이 가능하다. 그러나 네트워크 정책을 사용할 수 있다면, 네임스페이스별로 트래픽을 전송하지 못하게 하거나 기본적으로 모든 파드 간 통신을 차단하고 특정 파드 간 통신만 허용하는 화이트리스트 방식을 사용할 수 있다. 또한 CNI(Calico, Cilium 등)에서 네트워크 정책을 지원해야 한다

▶ 네트워크 정책 구성

네트워크 정책은 인그레스(Ingress 수신)과 이그레스(Egrss 송신)로 구성되어 있다.

인그레스는 인바운드 방향의 트래픽 룰을 설정하고, 이그레스는 아웃바운드 방향의 트래픽 룰을 설정한다.

설정 범위를 podSelector로 지정한다. 네트워크 정책은 네임스페이스별로 생성해야 한다.

 

▶ 정책 지정 방법(3가지) : 인그레스 룰과 이그레스 룰의 지정 방법은 동일하다

정책 종류 인그레스 룰의 경우 이그레스 룰의 경우
podSelector 특정 파드에서 들어오는 통신 허가 특정 파드로 나가는 통신 허가
namespaceSelector 특정 네임스페이스상에 있는 파드에서 들어오는 통신 허가 특정 네임스페이스상에 있는 파드로 나가는 통신 허가
ipBlock 특정 CIDR(IP주소)에서 들어오는 통신 허용 특정 CIDR(IP주소)에서 나가는 통신 허용

1. podSelector는 특정 파드에서의 통신을 제어하는 정책이다

2. namespaceSelector는 특정 네임스페이스상에 있는 파드에서의 통신을 제어하는 정책이다. namespaceSelector는 podSelector에 비해 제한 범위가 넓기 때문에 podSelector와 namespaceSelector는 네트워크 제한 범위에 따라 선택하면 된다

3. 마지막으로 ipBlock은 특정 CIDR에서의 통신을 제한하는 정책이다. 쿠버네티스 클러스터 내부에서 사용되는 통신 제어는 podSelector와 namespaceSelector를 사용하는 것이 좋지만, 클러스터 외부 네트워크 제어는 ipBlock을 사용하는 것이 좋다.

 

▶ 화이트리스트 방식과 블랙리스트 방식

  • 화이트리스트 방식은 미리 모든 트래픽을 차단해 두고 특정 트래픽만 허가하는 형식이다.
  • 블랙리스트 방식은 그 반대로 미리 모든 트래픽을 허가해 두고 특정 트래픽만 차단하는 형식이다.

▶ 네트워크 정책 예시

1. 모든 트래픽을 차단하는 네트워크 정책

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-networkpolicy
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

 

2. 모든 인바운드/아웃바운드 트래픽을 허가하는 정책

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-networkpolicy
spec:
  podSelector: {}
  egress:
  - {}
  ingress:
  - {}
  policyTypes:
  - Ingress
  - Egress

 

3. 클라우드에 적합한 인바운드는 모두 차단하고, 아웃바운드는 모두 허용하는 정책

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: cloud-networkpolicy
spec:
  podSelector: {}
  egress:
  - {}
  policyTypes:
  - Ingress
  - Egress

 

 

[ 네트워크 정책 실습 ]

▶ 실습을 위해서 Calico 설정 변경
- 현재 설정 확인

 

- calico nat true 설정 및 calico wireguard 끄기

 

- 변경 설정 적용을 위해서 calico 파드 삭제 후 재생성

 

- 모든 노드에서 ens5 down 후 up (라우팅 테이블 갱신)

 

▶ 파드 생성 및 확인 : default ns에 파드 2개, nptest ns에 파드 2개 - 각각 파드는 레이블을 지정

 

[ Calico Tip - 파드에 고정 IP를 직접 지정해서 배포 ]

  • 배포 후 확인 : annotations에 지정한 IP를 파드에 직접 할당 확인

 

[ 운영 - Monitor Calico component metrics ]

  • Use Prometheus configured for Calico components to get valuable metrics about the health of Calico.
  • For Calico, the "jobs" that Prometheus can harvest metrics from are the Felix and Typha
  • You can configure Felix, Typha, and/or kube-controllers to provide metrics to prometheus.
  • 설정
    1. Configure Calico to enable the metrics reporting.
    2. Create the namespace and service account that Prometheus will need.
    3. Deploy and configure Prometheus.
    4. View the metrics in the Prometheus dashboard and create a simple graph.

 

[ 운영 -  Kubeskoop] 
: Network monitoring & diagnosis sutie for Kubernetes

KubeSkoop is a kubernetes networking diagnose tool for diffrent CNI plug-ins and IAAS providers. KubeSkoop automatic construct network traffic graph of Pod in the Kubernetes cluster, monitoring and analysis of the kernel's critical path by eBPF, to resolve most of Kubernetes cluster network problems.

  • 제공기능
    1. One-Shot Diagnose For Network Broken
    - Diagnose in-cluster traffic between Pod, Service, Node and Ingress/Egress Traffic.
    - Cover whole linux network stack: Socket, Bridge, Veth, Netfilter, sysctls..
    - Supports IaaS Network probe for cloud providers.
    2. In-Depth Kernel Monitor
    - eBPF seamless kernel monitor
    - CO-RE scripts on series kernel by BTF
    - export metrics to standard Prometheus metric API
    3. Network Anomaly Event
    - support dozens of anomy scenses recognition
    - export anomy event to Grafana Loki or Web Console
    4. User-friendly Web Console
    - Integrating all capabilities of KubeSkoop, provides network diagnosis, event monitoring, packet capturing, latency detection, etc..