Skip to Content
ArchiveCalico Networking Modes

Calico 네트워크 모드

calico는 다양한 네트워크 통신방법(모드) 를 지원합니다.

CNI들을 통해 파드 혹은 Namespace 레벨의 In/Out 트래픽에 대한 통제가 가능합니다.

Calico 라우팅 모드

Untitled

IPIP 모드

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

IP 는 예시

IP 는 예시

  • 다른 노드 간의 파드 통신은 tunl0 인터페이스를 통해 IP 헤더에 감싸져서 상대측 노드로 도달 후 tunl0 인터페이스에서 Outer 헤더를 제거하고 내부의 파드와 통신
  • 다른 노드의 파드 대역은 BGP로 전달 받아 호스트 라우팅 테이블에 업데이트됨
# 모드 정보 확인 calicoctl get ippool -o wide # 노드(BGP) Peer 정보 확인 calicoctl node status IPv4 BGP status +----------------+-------------------+-------+----------+-------------+ | PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO | +----------------+-------------------+-------+----------+-------------+ | 192.168.20.100 | node-to-node mesh | up | 10:03:45 | Established | | 192.168.10.101 | node-to-node mesh | up | 10:05:26 | Established | | 192.168.10.102 | node-to-node mesh | up | 10:07:16 | Established | +----------------+-------------------+-------+----------+-------------+ # BGP 로 전달 받은 파드 네트워크 대역이 호스트 라우팅 테이블에 적용되었는지 확인 route -n | egrep '(Destination|tunl0)' Destination Gateway Genmask Flags Metric Ref Use Iface 172.16.8.128 192.168.20.100 255.255.255.192 UG 0 0 0 tunl0 172.16.46.0 192.168.10.102 255.255.255.192 UG 0 0 0 tunl0 172.16.228.64 192.168.10.101 255.255.255.192 UG 0 0 0 tunl0 calicoctl ipam show --show-blocks +----------+-----------------+-----------+------------+--------------+ | GROUPING | CIDR | IPS TOTAL | IPS IN USE | IPS FREE | +----------+-----------------+-----------+------------+--------------+ | IP Pool | 172.16.0.0/16 | 65536 | 6 (0%) | 65530 (100%) | | Block | 172.16.116.0/24 | 256 | 4 (2%) | 252 (98%) | | Block | 172.16.158.0/24 | 256 | 1 (0%) | 255 (100%) | | Block | 172.16.34.0/24 | 256 | 1 (0%) | 255 (100%) | +----------+-----------------+-----------+------------+--------------+ # 워커 노드마다 할당된 dedicated subnet (podCIDR) 확인 kubectl get nodes -o jsonpath='{.items[*].spec.podCIDR}' kubectl get node k8s-m -o json | jq '.spec.podCIDR' "172.16.0.0/24" kubectl get node k8s-w1 -o json | jq '.spec.podCIDR' "172.16.1.0/24" ... # 기본제공 cat /etc/cni/net.d/10-calico.conflist ... "ipam": { "type": "calico-ipam" }, ...

image.png

Direct 모드

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

Untitled

CleanShot 2024-09-08 at 16.30.31.png

서브넷이 다른 노드간 통신이 이루어져야 하는 상황일때

pod 간 네트워크 트래픽은 어떻게 흐를까??

image.png

설정 변경

Virtualbox 설정 - **노드(VM)**에 네트워크 NIC 2 번에 **무작위 모드**를 모두 허용 설정이 vagrant file 에 의해 되어 있음

스크린샷

# VVagrantfile 중 vnic 2번에 무작위 설정 v.customize ["modifyvm", :id, "--nicpromisc2", "allow-all"]

설정 변경 후,

vagrant reload

명령어로 변경된 config을 다시 반영합니다

Direct 모드 설정

Direct 모드 설정 및 확인

# Calico 모드 정보 확인 calicoctl get ippool -o wide NAME CIDR NAT IPIPMODE VXLANMODE DISABLED SELECTOR default-ipv4-ippool 172.16.0.0/16 true Always Never false all() # (옵션) 모니터링 watch -d "route -n | egrep '(Destination|UG)'" # 설정 calicoctl get ippool default-ipv4-ippool -o yaml calicoctl get ippool default-ipv4-ippool -o yaml | sed -e "s/ipipMode: Always/ipipMode: Never/" | calicoctl apply -f - # 모드 정보 확인 : IPIPMODE 가 Never 로 변경! calicoctl get ippool -o wide root@k8s-m:~/yaml# calicoctl get ippool -o wide NAME CIDR NAT IPIPMODE VXLANMODE DISABLED SELECTOR default-ipv4-ippool 172.16.0.0/16 true Never Never false all() # BGP 로 전달 받은 파드 네트워크 대역이 호스트 라우팅 테이블에 적용되었는지 확인 : Iface 가 tunl0 에서 ens5 혹은 enp0s8 로 변경! route -n | egrep '(Destination|UG)' root@k8s-w1:~# route -n | egrep '(Destination|UG)' Destination Gateway Genmask Flags Metric Ref Use Iface **172.16.29.0** 192.168.100.10 255.255.255.192 UG 0 0 0 ens5 혹은 enp0s8 **172.16.46.0** 192.168.100.102 255.255.255.192 UG 0 0 0 ens5 혹은 enp0s8 **172.16.197.0** 192.168.100.103 255.255.255.192 UG 0 0 0 ens5 혹은 enp0s8

info

calico config 설정 변경 확인을 위한 리소스버전 정보입니다

Router상 동작 확인

# 파드 생성 curl -s -O https://raw.githubusercontent.com/gasida/NDKS/main/5/node3-pod3.yaml kubectl apply -f node3-pod3.yaml

router vm 접속 후 정보 확인

vagrant ssh router # 라우팅 정보 확인 ip -c route router -n # router 장비에 직접 각 노드의 파드 대역 라우팅 정보를 추가 ## 아래 대역은 k8s-m 에서 calicoctl ipam show --show-blocks 출력되는 각 노드가 관리하는 파드의 대역 ip route add 172.16.34.0/24 via 192.168.57.100 ip route add 172.16.116.0/24 via 192.168.56.10 ip route add 172.16.158.0/24 via 192.168.56.101 ip route add 172.16.184.0/24 via 192.168.56.102 # 라우팅 정보 확인 ip -c route router -n # 아래 '파드 간 ping 통신' 시 확인 tcpdump -i any icmp -nn

CrossSubnet 모드

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

# CrossSubnet 모드 설정 calicoctl patch ippool default-ipv4-ippool -p '{"spec":{"ipipMode":"CrossSubnet"}}' # 모드 확인 calicoctl get ippool -o wide NAME CIDR NAT IPIPMODE VXLANMODE DISABLED SELECTOR default-ipv4-ippool 172.16.0.0/16 true CrossSubnet Never false all() # 파드 생성 kubectl apply -f node3-pod3.yaml calicoctl get wep # 호스트 라우팅 정보 확인 route -n | grep UG root@ip-172-20-63-146:~# route -n | grep UG 100.105.79.128 172.20.61.184 255.255.255.192 UG 0 0 0 ens5 # 노드간 같은 네트워크 대역 - Direct 모드 100.125.78.64 172.20.59.153 255.255.255.192 UG 0 0 0 ens5 # 노드간 같은 네트워크 대역 - Direct 모드 100.127.64.128 172.20.64.181 255.255.255.192 UG 0 0 0 tunl0 # 노드간 다른 네트워크 대역 - IPIP 모드 # 파드 Shell 접속(zsh) kubectl exec -it pod1 -- zsh ## 파드 Shell 에서 아래 입력 ping <pod2 혹은 pod3 IP>

워커노드1(파드)워커노드2(파드) or 워커노드0(파드)통신 확인해보자! (확인) router VM 에서 tcpdump -i any proto 4 -nn 로 정보 확인해보자!

BGP 연동 모드

K8S 클러스터 내부 네트워크와 IDC 내부망 네트워크 간 직접 라우팅이 가능합니다.

K8S 클러스터 네트워크 대역과 IDC 내부망 네트워크 대역간 직접 통신BGP 로 네트워크 대역을 전파

Untitled

  • IDC망을 관리하는 네트워크 팀과 협조하여 K8S 클러스터와의 통신 간 효율적인 네트워크 환경을 구성하시길 권장합니다
  • IDC 라우터는 실습 환경에서 vagrant router VM 에서 역할 동작함

클러스터 외부와의 네트워크 통신을 AWS VPC CNI와 비슷한 개념으로 직접 라우팅하는 방법입니다.

네트워크 기본 정보

IDC과 K8S 클러스터 사용 네트워크 대역

image.png

Kubernetes Controlplane 노드

image.png

라우터의 내부 네트워크 대역은 10.1.1.0/2410.1.2.0/24입니다.

그리고 쿠버네티스에서 사용하는 네트워크 대역은

서비스용 : 10.200.1.0/24

클러스터 CIDR : 172.16.0.0/16을 사용합니다.

라우터의 FRRouting 정보를 더 상세히 확인해봅니다.

vtysh show ip route show bgp ipv4 unicast summary show running-config

명령어등을 통해 정보를 조회해봅니다.

image.png

FRRouting 직접 설치하기

Router에 구현된 FRR을 직접 구현해보는 과정입니다.

# ip forwarding sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g' /etc/sysctl.conf sysctl -p # dummy interface : IDC 내부망 구현 modprobe dummy ip link add loop1 type dummy ip link set loop1 up ip addr add 10.1.1.254/24 dev loop1 ip link add loop2 type dummy ip link set loop2 up ip addr add 10.1.2.254/24 dev loop2 # FRRouting install apt-get update apt-get install frr -y # FRRouting 설정 파일 수정 sed -i 's/^pimd=no/pimd=yes/' /etc/frr/daemons sed -i 's/^bgpd=no/bgpd=yes/' /etc/frr/daemons sed -i 's/^#MAX_FDS=1024/MAX_FDS=1024/' /etc/frr/daemons # FRRouting BGP 라우팅 설정 cat <<EOF > /etc/frr/frr.conf frr version 8.1 frr defaults traditional hostname localhost.localdomain log syslog informational no ipv6 forwarding ! router bgp 64512 no bgp ebgp-requires-policy neighbor k8s peer-group neighbor k8s remote-as 64512 bgp listen range 192.168.0.0/16 peer-group k8s ! address-family ipv4 unicast network 10.1.1.0/24 network 10.1.2.0/24 neighbor k8s soft-reconfiguration inbound maximum-paths 4 maximum-paths ibgp 4 exit-address-family ! line vty ! EOF # FRRouting 재시작으로 변경 설정 적용 systemctl restart frr

Calico 의 NAT Disable 설정

calicoctl get ippool default-ipv4-ippool -o yaml | sed -e "s/natOutgoing: true/natOutgoing: false/" | calicoctl apply -f - #파드 생성 kubectl apply -f https://raw.githubusercontent.com/gasida/KANS/main/kans3/pod3-traefik.yaml # 파드 IP주소를 변수에 지정 WPOD1=$(calicoctl get workloadEndpoint | grep pod1 | awk '{print $3}' | cut -d "/" -f 1) echo $WPOD1 WPOD2=$(calicoctl get workloadEndpoint | grep pod2 | awk '{print $3}' | cut -d "/" -f 1) echo $WPOD2 WPOD3=$(calicoctl get workloadEndpoint | grep pod3 | awk '{print $3}' | cut -d "/" -f 1) echo $WPOD3 # 접속 확인 ping -i 1 -W 1 -c 1 $WPOD1 ping -i 1 -W 1 -c 1 $WPOD2 ping -i 1 -W 1 -c 1 $WPOD3 curl -s --connect-timeout 1 $WPOD1 | grep Hostname curl -s --connect-timeout 1 $WPOD2 | grep Hostname curl -s --connect-timeout 1 $WPOD3 | grep Hostname

image.png

K8S Calico BGP 구성 및 파드와 통신 설정

BGP 로 라우팅 정보 전파 → 내부망과 K8S 파드간 직접 통신

Calico 에 IDC 라우터와 BGP Peer(이웃) 설정

  • 기본적으로 Calico 는 BGP(as 64512)로 동작 중이므로, 다른(사내) 라우터와 Peer 설정이 가능하다
  • 아래 peerIP 는 다른(사내) 라우터의 IP이다
# [router] 모니터링 watch -d 'route -n' # [router] (옵션) 패킷 덤프, 트래픽 모니터링 tcpdump -i any icmp -nn iptraf-ng # [k8s-m] calico 에 IDC 라우터와 BGP 설정 cat <<EOF | calicoctl apply -f - apiVersion: projectcalico.org/v3 kind: BGPPeer metadata: name: bgppeer-rtr spec: peerIP: 192.168.10.254 asNumber: 64512 EOF # 확인 calicoctl get bgppeer NAME PEERIP NODE ASN bgppeer-rtr 192.168.10.254 (global) 64512 calicoctl node status Calico process is running. IPv4 BGP status +----------------+-------------------+-------+----------+-------------+ | PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO | +----------------+-------------------+-------+----------+-------------+ | 192.168.20.100 | node-to-node mesh | up | 12:32:24 | Established | | 192.168.10.101 | node-to-node mesh | up | 12:32:31 | Established | | 192.168.10.102 | node-to-node mesh | up | 12:41:12 | Established | | 192.168.10.254 | global | up | 12:43:29 | Established | +----------------+-------------------+-------+----------+-------------+

모든 노드에 추가된 내부 네트워크 대역 정보를 확인 할 수 있습니다.

# K8S 모든 노드에서 IDC 내부 네트워크 대역 정보가 추가되었다 ip -c route | grep bird 10.1.1.0/24 via 192.168.10.254 dev enp0s8 proto bird 10.1.2.0/24 via 192.168.10.254 dev enp0s8 proto bird # 노드에서 IDC 내부 네트워크 대역과 통신 확인! : 물론 파드 Shell 에서도 가능하다! ping -c 1 10.1.1.254 ping -c 1 10.1.2.254

image.png

네트워크 짬뽕모드

바로 위에 설명한 VPC CNI와 같은 BGP 연동모드등을 이용해

제가 되게 재밌게 봤던 자료가 하나있는데,

카카오의 내부 아키텍처 구성에서 network hop을 줄이기 위한 방법들로,

image.png

출처 : 7K_Cluster

7K

카카오같은 IDC 에서 직접 클러스터 운영을 하다보면, Cross AZ간 통신 등을 고려해서 아키텍처를 짜야합니다.

최근에는 Network Topology등에 대해서 많은 고민들을 시작했는데, 그중 하나라고 생각됩니다.

topology-aware-hint

초창기에는 노드간 통신에서의 트래픽을 초소화 하는 고민부터 이제는 노드가 위치해있는 IDC 간 통신을 ‘가급적 해당 존 안에서’ 해결하기 위해 고민들을 하는 차례인듯 합니다.

아마도 쿠버네티스 Major 버전이 2 로 올라갈때쯤이면, 지금보다 더 성숙한 플랫폼이 되지않을까 라는 생각이 드네요

Calico 네트워크 접근통제

  • 네트워크 정책 소개

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

    </aside>

    스크린샷 2021-11-09 오전 2.19.29.png

네트워크 정책 구성

네트워크 정책은 **인그레스(Ingress 수신)**과 **이그레스(Egrss 송신)**로 구성되어 있다. 인그레스는 인바운드 방향의 트래픽 룰을 설정하고, 이그레스는 아웃바운드 방향의 트래픽 룰을 설정한다. 설정 범위podSelector 로 지정한다. 네트워크 정책은 네임스페이스별로 생성해야 한다.

네트워크 정책 예시 sample-networkpolicy.yaml

apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: sample-networkpolicy namespace: default # 보안 정책을 생성할 네임스페이스 지정 spec: podSelector: # 설정할 대상 파드를 여기에 기입 # 레이블 셀렉터이므로 복수의 파드를 대상으로 할 수 있음. policyTypes: - Ingress # 인그레이스 룰을 생성하는 경우 명시 - Egress # 이그레스 룰을 생성할 경우 명시 ingress: - from: # 인그레스 룰을 여기에 기입(이그레스 룰과 형식은 동일) ports: # 이 인그레스 룰로 허가할 수신 포트 번호와 프로토콜 기입 egress: - to: # 이그레스 룰을 여기에 기입(인그레스 룰과 형식은 동일) ports: # 이 이그레스 룰로 허가할 송신 포트 번호와 프로토콜 기입

정책 지정 방법

인그레스 룰과 이그레스 룰의 지정 방법은 동일하다.

Untitled

  1. podSelector 는 특정 파드에서의 통신을 제어하는 정책이다.
  2. namespaceSelector 는 특정 네임스페이스상에 있는 파드에서의 통신을 제어하는 정책이다. namespaceSelector 는 podSelector 에 비해 제한 범위가 넓기 때문에 podSelector 와 namespaceSelector 는 네트워크 제한 범위에 따라 선택하면 된다.
  3. 마지막으로 ipBlock 은 특정 CIDR에서의 통신을 제한하는 정책이다. 쿠버네티스 클러스터 내부에서 사용되는 통신 제어는 podSelector 와 namespaceSelector 를 사용하는 것이 좋지만, 클러스터 외부 네트워크 제어는 ipBlock 을 사용하는 것이 좋다.

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

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

네트워크 정책 예시

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

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

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

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

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

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

EKS에서의 Network Policy

과거의 EKS에서는 Network Policy 를 사용할 수 없어 Calico를 CNI가 아닌 network policy 용 애드온으로 이용하기도 했었습니다.

networkpolicy-calico

하지만 2023.10 부터는 vpc cni 자체적으로 k8s의 network policy를 지원합니다.

VPC_CNI의_networkpolicy_지원

근데 아직 미숙한 부분이있는지, 악분님 블로그에서도 일부 버그가있다고 하네요

VPC_CNI_NP_버그

제가 있는 조직에서는 EKS가 메인이 아니기때문에, 온프레미스 기반의 Calico CNI의 Network Policy를 획일화 하여 관리하기위해 EKS에서도 Calico 의 Network Policy를 그대로 사용중입니다.

Calico TIPS

CNI의 IPAM 관리

쿠버네티스에서는 pod의 ip와 mac을 매번 무작위로 만들지만, static하게 고정 할 수 있습니다.

apiVersion: v1 kind: Pod metadata: name: example-pod annotations: cni.projectcalico.org/ipAddrs: "[\"192.168.1.100\"]" cni.projectcalico.org/mac: "EE:EE:EE:EE:EE:EE" spec: containers: - name: example image: nginx

이런식으로 말이죠.

물론 저 대역은 calico에서 관리하는 영역이여야하겠지만, 저런식으로 구성을하면 저 pod가 뜰때 항상 같은 pod ip와 mac 주소를 갖게 할 수 있습니다.

그럼 어떻게 중복을 방지할까요?

정답은 CNI에서 관리하는 IPAM에 있는데,

IPAM configuration은 다음 문서에서 참조가 가능합니다.

IPAM_Configurations

별도 설정이 존재하지만, strictAffinity 를 활성화하면 특정 pod들에 해당해둔 pod ip , mac을 고정할경우, 해당 대역들을 무작위로 배치하는 IPAM 대역에서 제외합니다.

이로서 중복으로 같은 IP 할당을 방지할수있습니다.

Visualizing metrics via Grafana

Docs

CNI Configuration

# Felix configuration calicoctl get felixconfiguration -o yaml calicoctl patch felixconfiguration default --patch '{"spec":{"prometheusMetricsEnabled": true}}'

관련 Component 배포 및 RBAC 설정

# Creating a service to expose Felix metrics : Felix by default uses port 9091 TCP to publish its metrics. kubectl apply -f - <<EOF apiVersion: v1 kind: Service metadata: name: felix-metrics-svc namespace: kube-system spec: clusterIP: None selector: k8s-app: calico-node ports: - port: 9091 targetPort: 9091 EOF # kube-controllers configuration : Prometheus metrics are enabled by default on TCP port 9094 for calico-kube-controllers ## Creating a service to expose kube-controllers metrics calicoctl get kubecontrollersconfiguration default -o yaml kubectl apply -f - <<EOF apiVersion: v1 kind: Service metadata: name: kube-controllers-metrics-svc namespace: kube-system spec: clusterIP: None selector: k8s-app: calico-kube-controllers ports: - port: 9094 targetPort: 9094 EOF # Namespace creation kubectl create -f -<<EOF apiVersion: v1 kind: Namespace metadata: name: calico-monitoring labels: app: ns-calico-monitoring role: monitoring EOF kubectl get ns # Service account creation kubectl apply -f - <<EOF apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: calico-prometheus-user rules: - apiGroups: [""] resources: - endpoints - services - pods verbs: ["get", "list", "watch"] - nonResourceURLs: ["/metrics"] verbs: ["get"] --- apiVersion: v1 kind: ServiceAccount metadata: name: calico-prometheus-user namespace: calico-monitoring --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: calico-prometheus-user roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: calico-prometheus-user subjects: - kind: ServiceAccount name: calico-prometheus-user namespace: calico-monitoring EOF

Prometheus Metric 활성화

kubectl apply -f - <<EOF apiVersion: v1 kind: ConfigMap metadata: name: prometheus-config namespace: calico-monitoring data: prometheus.yml: |- global: scrape_interval: 15s external_labels: monitor: 'tutorial-monitor' scrape_configs: - job_name: 'prometheus' scrape_interval: 5s static_configs: - targets: ['localhost:9090'] - job_name: 'felix_metrics' scrape_interval: 5s scheme: http kubernetes_sd_configs: - role: endpoints relabel_configs: - source_labels: [__meta_kubernetes_service_name] regex: felix-metrics-svc replacement: $1 action: keep - job_name: 'felix_windows_metrics' scrape_interval: 5s scheme: http kubernetes_sd_configs: - role: endpoints relabel_configs: - source_labels: [__meta_kubernetes_service_name] regex: felix-windows-metrics-svc replacement: $1 action: keep - job_name: 'typha_metrics' scrape_interval: 5s scheme: http kubernetes_sd_configs: - role: endpoints relabel_configs: - source_labels: [__meta_kubernetes_service_name] regex: typha-metrics-svc replacement: $1 action: keep - job_name: 'kube_controllers_metrics' scrape_interval: 5s scheme: http kubernetes_sd_configs: - role: endpoints relabel_configs: - source_labels: [__meta_kubernetes_service_name] regex: kube-controllers-metrics-svc replacement: $1 action: keep EOF # Create Prometheus pod kubectl apply -f - <<EOF apiVersion: v1 kind: Pod metadata: name: prometheus-pod namespace: calico-monitoring labels: app: prometheus-pod role: monitoring spec: nodeSelector: kubernetes.io/os: linux serviceAccountName: calico-prometheus-user containers: - name: prometheus-pod image: prom/prometheus resources: limits: memory: "128Mi" cpu: "500m" volumeMounts: - name: config-volume mountPath: /etc/prometheus/prometheus.yml subPath: prometheus.yml ports: - containerPort: 9090 volumes: - name: config-volume configMap: name: prometheus-config EOF #Dashboard kubectl apply -f - <<EOF apiVersion: v1 kind: Service metadata: name: prometheus-dashboard-svc namespace: calico-monitoring spec: type: NodePort selector: app: prometheus-pod role: monitoring ports: - protocol: TCP port: 9090 targetPort: 9090 nodePort: 30001 EOF

image.png

Grafana Dashboard 배포

  • Use Grafana dashboard to view Calico component metrics.
# Provisioning datasource kubectl apply -f - <<EOF apiVersion: v1 kind: ConfigMap metadata: name: grafana-config namespace: calico-monitoring data: prometheus.yaml: |- { "apiVersion": 1, "datasources": [ { "access":"proxy", "editable": true, "name": "calico-demo-prometheus", "orgId": 1, "type": "prometheus", "url": "http://**prometheus-dashboard-svc.calico-monitoring.svc:9090**", "version": 1 } ] } EOF # Provisioning Calico dashboards : Here you will create a configmap with Felix and Typha dashboards. kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.1/manifests/grafana-dashboards.yaml # Creating Grafana pod kubectl apply -f - <<EOF apiVersion: v1 kind: Pod metadata: name: grafana-pod namespace: calico-monitoring labels: app: grafana-pod role: monitoring spec: nodeSelector: kubernetes.io/os: linux containers: - name: grafana-pod image: grafana/grafana:latest resources: limits: memory: "128Mi" cpu: "500m" volumeMounts: - name: grafana-config-volume mountPath: /etc/grafana/provisioning/datasources - name: grafana-dashboards-volume mountPath: /etc/grafana/provisioning/dashboards - name: grafana-storage-volume mountPath: /var/lib/grafana ports: - containerPort: 3000 volumes: - name: grafana-storage-volume emptyDir: {} - name: grafana-config-volume configMap: name: grafana-config - name: grafana-dashboards-volume configMap: name: grafana-dashboards-config EOF # kubectl apply -f - <<EOF apiVersion: v1 kind: Service metadata: name: grafana namespace: calico-monitoring spec: type: NodePort selector: app: grafana-pod role: monitoring ports: - protocol: TCP port: 3000 targetPort: 3000 nodePort: 30002 EOF # 그라파나 접속 주소 : 초기 계정 ( admin , admin ) echo -e "Grafana URL = http://$(curl -s ipinfo.io/ip):30002" # [실습환경 A Type] echo -e "Grafana URL = http://192.168.10.10:30002" # [실습환경 B Type]
  • 그라파나 웹 접속 후 Felix 대시보드 확인

image.png

Kubeskoop : Network monitoring & diagnosis suite for Kubernetes

작성 중, EC2 타입 SpecUp 필요 - Github , Youtube

KubeSkoop is a kubernetes networking diagnose tool for different 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.

  • 제공 기능

    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…
    • Support IaaS network probe for cloud providers.

    In-Depth Kernel Monitor

    • eBPF seamless kernel monitor
    • CO-RE scripts on series kernel by BTF
    • export metrics to standard Prometheus metric API

    Network Anomaly Event

    • support dozens of anomy scenes recognition
    • export anomy event to Grafana Loki or Web Console

    User-friendly Web Console

    • Integrating all capabilities of KubeSkoop, provides network diagnosis, event monitoring, packet capturing, latency detection, etc.
  • 설치

    # You can quickly deploy KubeSkoop, Prometheus, Grafana and Loki to your cluster via skoopbundle.yaml. kubectl apply -f https://raw.githubusercontent.com/alibaba/kubeskoop/main/deploy/skoopbundle.yaml # When installation is done, you can acess the KubeSkoop Web Console by service webconsole. kubectl get svc,ep -n kubeskoop webconsole kubectl patch service -n kubeskoop webconsole -p '{"spec": {"type": "NodePort"}}' kubectl get svc -n kubeskoop webconsole kubectl get svc -n kubeskoop webconsole -o jsonpath={.spec.ports[0].nodePort} # 계정 ( admin , kubeskoop ) echo -e "kubeskoop URL = http://$(curl -s ipinfo.io/ip):$(kubectl get svc -n kubeskoop webconsole -o jsonpath={.spec.ports[0].nodePort})" # [실습환경 A Type] echo -e "kubeskoop URL = http://192.168.10.10:$(kubectl get svc -n kubeskoop webconsole -o jsonpath={.spec.ports[0].nodePort})" # [실습환경 B Type]

image.png

image.png

skoop 내에서 자체적으로 사용하는 prometheus metric / grafana 대시보드입니다.

로우레벨 네트워크 레벨에서의 문제들이 발생된다면 이런 메트릭 기반의 네트워크 트러블슈팅이 가능할것이라 보입니다.