Post

Calico 알아보기

Calico 이해하기

💡 KANS 스터디
CloudNet에서 주관하는 KANS(Kubernetes Advanced Networking Study)으로 쿠버네티스 네트워킹 스터디입니다. 아래의 글은 스터디의 내용을 기반으로 작성했습니다.

스터디에 관심이 있으신 분은 CloudNet Blog를 참고해주세요.

실습환경

AWS에서 ec2 x 4ea, Calico 네트워크 모드 테스트를 위해 워커 노드 하나는 별도의 서브넷에 구성한다.

**(AWS는 내부 라우터가 있기에, BGP↔라우터 연동 실습은 진행불가)

image.png

스터디에서 제공해주신 CloudFormation 파일은 아래에서 확인할 수 있고 주요 특이점은 아래와 같습니다.

  • Calico가 k8s v1.31에 대한 stables이 확인되지 않아, v1.30으로 진행
  • Calico Default에서 기본 IPv4 pool CIDR 변경함
1
curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/kans/**kans-3w.yaml**

Calico란

GitHub에 나와있는 설명을 보면, Tigera에 의해 생성되고 관리되고 있는 CNI 프로젝트이다. 현재 가장 널리 사용되고 있는 솔루션으로 166개국에서 매일 8백만 개 이상의 노드에서 사용되고 있다고 한다.

*Tigera는 컨테이너 네트워킹 보안을 전문으로 하는 기업이고 Calico 기반 Cloud 서비스와 EnterPrise 서비스를 제공한다.

아키텍처

image.png

그림 출처: https://docs.tigera.io/calico/latest/reference/architecture/overview

Component

주요 요소들을 간단히 정리하면 아래와 같다.

  • Bird(오픈소스 라우팅 데몬): 자기 노드의 파드 CIDR을 BGP 라우팅을 통해 다른 노드들에게 광고
    • Bird는 죽기전에도 신호를 날려 다른 노드에게 알려준다.
  • Felix: Bird를 통해 파악한 다른 노드의 파드 CIDR을 호스트 라우팅 테이블에 업데이트 (iptables)
  • Confd: calico 설정, BGP 설정 변경이 Bird에 적용해주는 역할
  • calico datastore: Calico 관련 정보 저장
  • calico-IPAM: IPAM(IP address management)이다. k8s 내장 IPAM을 사용하지 않고 별도 IPAM을 사용한다.
  • calico-kube-controllers: calico 동작 관련 감시(watch)

*Calico에서 라우팅 테이블을 업데이트하는 과정에 대한 그림입니다.

image.png

실습 진행

CloudFormation YAML을 배포한다.

1
aws cloudformation deploy --template-file kans-3w.yaml --stack-name mylab --parameter-overrides KeyName={자신의 key} SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 --region ap-northeast-2

배포 후 k8s-m에 해당되는 ec2에 ssh로 접속한다.

1
ssh -i {key 경로} ubuntu@{k8s-m public ip}

설정이 완료되었으면, calicoctl 명령어를 통해 현재 정보를 확인한다.

아래의 사진과 같이 IPIPMODE와 Pod CIDR을 확인할 수 있다.

image.png

datastore

datastore로 kubernetes를 사용한다는 것은 kubernetes api와 연결하여 CRD 형식으로 etcd에 저장한다는 표현이다. 반면 etcd를 사용한다는 말은 etcd 클러스터와 직접 연결하여 설정을 key-value 형식으로 저장한다.

현재는 kubernetes 모드이니 CRD를 조회하면 아래와 같이 나온다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
k get crd
NAME                                                  CREATED AT
bgpconfigurations.crd.projectcalico.org               2024-09-15T11:25:53Z
bgpfilters.crd.projectcalico.org                      2024-09-15T11:25:53Z
bgppeers.crd.projectcalico.org                        2024-09-15T11:25:53Z
blockaffinities.crd.projectcalico.org                 2024-09-15T11:25:53Z
caliconodestatuses.crd.projectcalico.org              2024-09-15T11:25:53Z
clusterinformations.crd.projectcalico.org             2024-09-15T11:25:53Z
felixconfigurations.crd.projectcalico.org             2024-09-15T11:25:53Z
globalnetworkpolicies.crd.projectcalico.org           2024-09-15T11:25:53Z
globalnetworksets.crd.projectcalico.org               2024-09-15T11:25:53Z
hostendpoints.crd.projectcalico.org                   2024-09-15T11:25:53Z
ipamblocks.crd.projectcalico.org                      2024-09-15T11:25:53Z
ipamconfigs.crd.projectcalico.org                     2024-09-15T11:25:53Z
ipamhandles.crd.projectcalico.org                     2024-09-15T11:25:53Z
ippools.crd.projectcalico.org                         2024-09-15T11:25:53Z
ipreservations.crd.projectcalico.org                  2024-09-15T11:25:53Z
kubecontrollersconfigurations.crd.projectcalico.org   2024-09-15T11:25:53Z
networkpolicies.crd.projectcalico.org                 2024-09-15T11:25:53Z
networksets.crd.projectcalico.org                     2024-09-15T11:25:53Z

etcd 모드로 설정하는 법은 여기를 참고하면 된다.

IPAM

CNI 요구사항 중에 하나는 IPAM이다. 여기서 calico에 IPAM을 확인한다.

calicoctl을 통해 ipam 설정을 확인할 수 있다.

1
2
3
4
5
6
7
8
9
10
calicoctl ipam show --show-blocks
+----------+-----------------+-----------+------------+--------------+
| GROUPING |      CIDR       | IPS TOTAL | IPS IN USE |   IPS FREE   |
+----------+-----------------+-----------+------------+--------------+
| IP Pool  | 172.16.0.0/16   |     65536 | 7 (0%)     | 65529 (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.184.0/24 |       256 | 1 (0%)     | 255 (100%)   |
| Block    | 172.16.34.0/24  |       256 | 1 (0%)     | 255 (100%)   |
+----------+-----------------+-----------+------------+--------------+

이것은 k8s 내부 IPAM 정보와 다르다. 위에서 언급했듯이 calico는 별도의 IPAM 플러그인을 사용한다.

1
2
kubectl get node k8s-m -o json | jq '.spec.podCIDR'
"172.16.0.0/24"

물론 내부 local IPAM 플러그인을 사용할 순 있는데, 현재 어떤 플러그인을 사용하는 지 아래 명령어를 통해 알 수 있다.

1
2
3
4
root@k8s-m:~# cat /etc/cni/net.d/10-calico.conflist | jq '.plugins[0].ipam'
{
  "type": "calico-ipam"
}

파드 하나 생성 후 iptables 확인

파드를 하나 생성하고 network interface 정보를 확인한다.

image.png

아래와 같이 chain하나가 생성되고, chain하나당 아래와 같은 iptables 설정이 생긴다.

1
2
3
4
5
6
7
8
9
10
11
iptables -v --numeric --table filter --list cali-tw-calic9f294a6bbf
Chain cali-tw-calic9f294a6bbf (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* cali:gdGCd7pAItfwyTLA */ ctstate RELATED,ESTABLISHED
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* cali:JPvEc7l-QoWNA6WQ */ ctstate INVALID
    0     0 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* cali:JBLdNQgG6AU0aBoD */ MARK and 0xfffcffff
    0     0 cali-pri-kns.default  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* cali:FxDPE7nrp1ZsAMQa */
    0     0 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* cali:VQd-z8yw78VeSlXp */ /* Return if profile accepted */
    0     0 cali-pri-ksa.default.default  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* cali:_3kBlEdzM5JBdsV3 */
    0     0 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* cali:zQmrLF4vo1Sil_cI */ /* Return if profile accepted */
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* cali:D-XKZRe8N6NYhdLa */ /* Drop if no profiles matched */

정리

여기서는 Calico의 아키텍처와 요소들에 대해 살펴봤다.

  1. Calico는 Bird를 통해 각 노드마다 호스트에 위치한 파드의 IP 대역을 다른 노드들에게 알려준다.
  2. 별도의 IPAM을 사용한다.
  3. Datastore로는 CRD를 이용하여 kubernetes API를 통해 저장한다. (etcd에 직접 저장할수도 있다.)
This post is licensed under CC BY 4.0 by the author.