Calico
나는 왜 Calico를 사용했을까
쿠버네티스 클러스터를 구축을 하고 상태를 확인했을 때.
노드들의 상태가 NotReady상태, 즉 서로 통신도 안되고 엉망진창인 상태였다.
NetworkPluginNotReay
로그를 살펴보니 네트워크 플러그인이 필요하다고 한다. 네트워크 플러그인이 뭘까?
네트워크 플러그인(CNI)
네트워크 플러그인이란
쿠버네티스 클러스터에서 Pod 생성 시 Pod의 IP할당 및 IP자원에 대한 할당, 관리, 회수
노드 간 통신을 위한 라우팅 테이블 수집 및 관리.
Pod에게 통신을 위한 Veth Pair 할당 등의 작업을 해주게 된다.
즉 Pod 끼리 통신을 하기 위해 필수적인 요소이다.
쿠버네티스는 설치 시 CNI를 자동으로 설치해주지 않고,
사용자가 상황에 맞게 사용하도록 인터페이스를 만들어 놓는 방식으로 되어 있어 네트워크 플러그인을 사용자가 수동으로 설치를 해야 한다.
CNI를 따로 설치를 하지 않으면
- Pod들이 IP를 할당받지 못한다.
- 가상 네트워크 인터페이스를 할당을 받지 못하기 때문에 통신이 밖으로 나가지 못한다.
- 여러 노드의 Pod 간 라우팅 경로를 수집하지 못해 Pod들이 통신을 할 때 참고 할 라우팅 테이블이 없어 경로를 찾아가지 못한다.
위와 같은 이유로 오류가 발생한 것이었다...!
Calico 설치
설치 후 구성요소들
설치 후 calico-system 네임스페이스를 가진 파드들을 출력을 해보았다.
Calico-kube-controller
Kubernetes API 서버와 통합하며, 네트워크 정책을 관리 (단일 노드에 존재함)
- 네트워크 정책 생성: Kubernetes API를 통해 네트워크 정책이 생성되면, calico-kube-controllers는 이를 감지하고 Calico의 네트워크 설정을 업데이트.
- 파드 생성/삭제: 파드가 생성되거나 삭제되면, calico-kube-controllers는 이를 감지하고 Calico의 엔드포인트를 업데이트.
CSI-node-driver
Kubernetes 클러스터에서 스토리지 리소스를 관리 (모든 노드에 존재)
⇒ 노드의 디스크 공간을 파티셔닝 후 파드 혹은 컨테이너와 마운트 시킴으로 스토리지 리소스를 사용하도록 함.
Calico-node
⇒ 아래에 이어서 설명
Calico-typha
아래에서 설명.
Calico의 구성요소들
IPAM
Pod에 IP를 할당 및 관리해주는 플러그인으로.
컨테이너나 파드에 고유한 IP 주소를 동적으로 할당.
사용 가능한 IP 주소 범위를 관리.
컨테이너나 파드가 삭제될 때 할당된 IP 주소를 회수.
등의 역할을 담당한다.
kubectl-calico ipam show --show-block
init --pod-network-cidr=192.168.0.0/16 --apiserver-advertise-address=172.168.0.201
처음 쿠버네티스 클러스터를 초기화할 때 입력했던 CIDR을 기반으로 아이피를 할당을 해준다
노란색 부분으로 블록처리 해 놓은 부분은 IP pool에서 만든 Block을 나타내는데
Block은 각 노드당 최소 1개씩 할당이 되고, IP가 고갈될 시 IpPool에서 블록을 새로 만들어 할당을 받는다.
확인
Control plane, node01, node02를 각각 다른 색으로 표기를 해놓았는데,
Pod의 IP를 Block의 CIDR이랑 비교하면 한 개씩 배정되어 있는 부분을 볼 수 있다.
CNI Plugin
CNI가 하는 일:
- Pod가 생성되면 Kubelet이 CNI 플러그인을 실행
- CNI 플러그인이 IPAM을 호출해서 IP를 받아옴
- Pod 네트워크 인터페이스(veth)를 생성하고 IP를 할당
- Pod가 네트워크를 사용할 수 있도록 라우팅 및 NAT 설정
- Pod 간 통신을 가능하게 함
Pod가 네트워크를 사용할 수 있도록 veth를 만들고 IP를 설정한 뒤, 라우팅을 구성하는 것
CNI Plugin의 동작 구조.
- 파드 생성: 쿠버네티스가 새 파드를 생성하면 Calico CNI 플러그인이 호출.
- IP 할당: Calico는 IPAM을 사용하여 파드에 IP 주소를 할당.
- 인터페이스 생성: Calico는 할당된 IP에 기반하여 새로운 veth Pair 생성.
- 이름 지정: 호스트 측 veth 인터페이스의 이름은 'cali' + 무작위 문자열로 생성
5. 연결: 생성된 veth 쌍은 특정 파드와 1:1로 연결됨
Typha
Felix가 라우팅 테이블 관리 및 네트워크 인터페이스를 관리할 때 Datastore에 접근 후 네트워크 정책 등을 살펴보고 결정을 하게 되는데. Felix가 본인의 임무를 수행할 때마다 Datastore에 접근을 하게 된다면 부하 및 시간이 걸리기 때문에. 이를 줄이고자 Typha가 Datastore에 접근 후 데이터를 캐싱, Felix가 해당 데이터를 받아 쓰는 형식이다.
DataStore
클러스터 내부 노드의 상태, 파드의 수, 리소스에 대한 정보 등은 etcd에 저장이 되어있다.
Calico도 마찬가지로 CNI Plugin에 의해 Pod에 네트워크 관련 작업을 진행 후 네트워크 정책 및 라우팅 정보 ip자원의 현황등을 datastore에 저장을 해놓는다.
추후 Calico가 무언갈 생성하거나 수정하려고 할 때 해당 Datastore를 참고 후 작업을 하게 된다.
Kubernetes Datastore Mode
기본적으로 해당 설정을 따름.
Pod가 생성이 되게 되면 해당 Pod에 대한 정보들이 kube-api-server를 통해 컨트롤 플래인에 etcd에 저장이 되게 되는데.
Pod가 생성이 될 때, 해당 파드의 IP정보 및 네트워크 인터페이스 생성등을 CNI Plugin이 해주고
그 후 해당 정보를 Kube-Api-Server에게 전달
Kube-Api-Server 가 etcd에 해당 정보 저장 방식으로 동작을 한다
etcd Datastore Mode
쿠버네티스의 etcd가 아닌 Calico 자체적으로 데이터 저장소로 설정하여 네트워크 상태를 관리를 하게 된다.
Calico의 구성요소들: Calico-Node 의 구성요소
Felix
Calico의 Felix 컴포넌트는 iptables의 규칙을 생성 및 관리를 한다.
Felix 프로세스가 직접 Datastore(예: etcd, K8s API)에서 데이터를 가져오면 부하가 커짐
iptable은 쿠버네티스 calico와 독립적으로 리눅스 운영체제 안에 있음
ip -c route
라우트 테이블 관리
운영체제의 커널에서 해당 노드(컴퓨터)의 routing 테이블을 출력을 했을 때
192.168 대역은 Pod의 아이피 대역이고
172.16.0.0/24의 대역대는 노드의 대역 대이다.
이처럼 라우팅 테이블 또한 관리해주고 있음을 볼 수 있다.
DataStore와 상호작용 하면서 네트워크 정책 등을 참고해서 라우팅 규칙을 생성한다.
정확히는 Felix가 Datastore에 직접 접근을 하게 된다면 부하가 커질 수 있기 때문에.
Typha가 Datastore에 접근 후 데이터를 캐싱해 오고, 해당 데이터를 Felix가 참고하는 형식이다.
네트워크 인터페이스 관리
Confd
calico global 설정과 BGP 설정 변경 시(트리거) BIRD에 적용
BIRD
BIRD는 서로의 경로를 BGP프로토콜을 이용, 서로가 알고 있는 라우팅 테이블 정보를 교환하면서 라우팅 경로 및 라우팅 테이블을 계산하는 데몬이다.
예를 들면
Node01과 Node02가 BGP를 통해 통신하는 과정에서,
각각의 노드에 Bird 데몬이 실행되고, 이 Bird 데몬들이 서로 BGP 피어로 설정되어 경로 정보를 교환을 하게 된다.
https://www.cloudflare.com/ko-kr/learning/security/glossary/what-is-bgp/
BGP 프로토콜 상태 확인
node to node mesh 방식으로 BGP연결이 된 것을 확인할 수 있다.
현제 워커 노드 2개가 있는데.
만약 A, B, C, D 노드가 있었다면 6개의 연결이 있는 것이다.