home..

Calico Networking Modes

Docker Container Pod Container Kubernetes Networking

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 네트워크 접근통제

  • 네트워크 정책 소개

    스크린샷 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 대시보드입니다.

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

© 2024 mont kim   •  Powered by Soopr   •  Theme  Moonwalk