메타 데이터의 끝으로 건너뛰기
메타 데이터의 시작으로 이동

You are viewing an old version of this content. View the current version.

현재와 비교 View Version History

« 이전 버전 10 다음 »


1. 서비스

1.1 서비스 개념

파드를 통해 사용자에게 서비스를 제공을 할 수 있으나, 파드에 장애가 발생했을 경우 서비스에 가용성을 보장할 수가 없기 때문에, Service를 통해 가용성을 보장합니다

image-20230310-042952.png

Kubernetes Service를 통해 파드의 로드밸런싱이 가능하며, 파드에 문제가 발생하여 정상적으로 구동시킬 수 없는 경우에는 Service가 자동으로 문제가 발생한 파드는 Service의 EndPoint에서 제외됩니다.

image-20230310-043128.png

문제가 생겼던 Pod는 Deployment를 통해 다른 IP, Name으로 다시 구동되며, Service의 EndPoint에 자동으로 추가되어, 기존상태를 유지합니다.

image-20230310-043159.png

1.2 서비스 타입

  • 쿠버네티스 클러스터 외부에서 내부로 트래픽을 받는 방법

Nodeport

0fd0c795-7056-4d12-8c6d-4fdaa0b6c796.png

Load Balancer

f9ecd753-5b3e-45ae-8b79-006bba457411.png

Ingress

a14fa09f-03a3-49eb-8c7b-b324cdf5b78b.png

(1) ClusterIP

  • 서비스를 클러스터 내부 IP에 노출합니다.

  • 클러스터 내에서만 서비스에 도달할 수 있으며, 서비스 타입의 기본값입니다.

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app.kubernetes.io/name: proxy
spec:
  containers:
  - name: nginx
    image: nginx:stable
    ports:
      - containerPort: 80
        name: http-web-svc

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app.kubernetes.io/name: proxy
  ports:
  - name: name-of-service-port
    protocol: TCP
    port: 80
    targetPort: http-web-svc

(2) NodePort

  • 고정포트로 각 노드의 IP에 서비스를 노출합니다.

  • NodePort 서비스가 라우팅되는 ClusterIP가 자동으로 생성되며 NodeIP:NodePort를 요청하며, 서비스 외수에서 NodePort 서비스에 접속할 수 있습니다.

---                                                                                           
apiVersion: apps/v1                                                                           
kind: Deployment                                                                              
metadata:                                                                                     
  name: nginx-deployment                                                                      
  labels:                                                                                     
    app: nginx                                                                                
spec:                                                                                         
  replicas: 1                                                                                 
  selector:                                                                                   
    matchLabels:                                                                              
      app: nginx                                                                              
  template:                                                                                   
    metadata:                                                                                 
      labels:                                                                                 
        app: nginx                                                                            
    spec:                                                                                     
      containers:                                                                             
      - name: nginx                                                                           
        image: nginx                                                                          
        ports:                                                                                
        - containerPort: 80                                                                   
---                                                                                           
apiVersion: v1                                                                                
kind: Service                                                                                 
metadata:                                                                                     
  name: my-service-nodeport                                                                   
spec:                                                                                         
  type: NodePort                                                                              
  selector:                                                                                   
    app: nginx                                                                                
  ports:                                                                                      
      # 기본적으로 그리고 편의상 `targetPort` 는 `port` 필드와 동일한 값으로 설정된다.                           
    - port: 80                                                                                
      targetPort: 80                                                                          
      # 선택적 필드                                                                               
      # 기본적으로 그리고 편의상 쿠버네티스 컨트롤 플레인은 포트 범위에서 할당한다(기본값: 30000-32767)                   
      nodePort: 30007

(3) LoadBalancer

  • 클라우드 공급자의 로드 밸런서를 사용하여 서비스를 외부에 노출시킵니다.

  • 클러스터 외부 IP를 가지고 있기 때문에, 클러스터 외부에서 접근 가능합니다.

  • 외부 로드 밸런서가 라우팅되는 NodePort와 ClusterIP 서비스가 자동으로 생성됩니다.

  • 프라이빗 클라우드 환경에서는 MetalLB를 이용하여 LoadBalancer 타입의 서비스를 이용 할 수 있습니다.

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx2-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx2-service
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 8088
      targetPort: 80

(4) ExternalName

  • 값과 함께 CNAME 레코드를 리턴하여, 서비스를 externalName 필드의 콘텐츠(ex. foo.bar.example.com) 에 매핑합니다.


2. Ingress

2.1 Ingress Controller

2.2 Ingress

  • 클러스터 내의 서비스에 대한 외부 접근을 관리하는 API 오브젝트이며, 일반적으로 HTTP를 관리합니다.

  • 인그레스는 클러스터 외부에서 클러스터 내부 서비스로 HTTP와 HTTPS 경로를 노출시킵니다.

  • 인그레스 컨트롤러가 있어야 인그레스를 충족할 수 있으며, 인그레스 리소스만 생성한다면 효과가 없습니다.

    • 대표적인 인그레스 컨트롤러: ingress-nginx

image-20221020-022157.png

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: rewrite
  namespace: default
spec:
  ingressClassName: nginx
  rules:
  - host: sllee.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80


3. 네트워크

3.1 파드 네트워크

문서 상 노드 이름 및 역할

sung-ubuntu01 - Control Plane #1

sung-ubuntu02 - Control Plane #2

sung-ubuntu03 - Control Plane #3

sung-ubuntu04 - Worker Node #1

sung-ubuntu05 - Worker Node #2

(1) 파드 네트워크 흐름

image-20220929-070437.png

  • 도커에서 POD 네트워크 설명할 경우와 인터페이스 이름이 다릅니다.

  • 도커의 역할

참고1) https://www.docker.com/products/container-runtime/

(2) 파드 네트워크 실습

목표

  • Pod (Single Container)의 네트워크 설정 확인

root@sung-ubuntu01:~/tmp# cat ubuntu.yaml
apiVersion: v1
kind: Pod
metadata:
  name: ubuntu-test
spec:
  containers:
  - name: ubuntu
    image: ubuntu:20.04
    command: ["/bin/sleep", "3650d"]
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}
  restartPolicy: Always
  dnsConfig:
    nameservers:
      - 8.8.8.8


root@sung-ubuntu01:~/tmp# kubectl get pod -o wide
NAME          READY   STATUS    RESTARTS   AGE     IP            NODE            NOMINATED NODE   READINESS GATES
ubuntu-test   1/1     Running   0          6m20s   10.233.99.1   sung-ubuntu04   <none>           <none>


###POD 접속
root@sung-ubuntu01:~/tmp# kubectl exec -it ubuntu-test -- bash
root@ubuntu-test:/#


root@ubuntu-test:/# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=54 time=39.6 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=54 time=38.1 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=54 time=38.8 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=54 time=39.3 ms


# apt update
# apt install -y net-tools iputils-ping


**# 컨테이너의 네트워크 인터페이스 확인**
# root@ubuntu-test:/# ifconfig -a
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1480
        inet 10.233.99.1  netmask 255.255.255.255  broadcast 0.0.0.0
        ether 06:55:84:5a:ac:6b  txqueuelen 0  (Ethernet)
        RX packets 5718  bytes 24026416 (24.0 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3690  bytes 250168 (250.1 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0



#설명추가
tunl0: flags=128<NOARP>  mtu 1480
        tunnel   txqueuelen 1000  (IPIP Tunnel)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


* loopback ip : host 자신을 가리키는 논리적인 인터페이스


**#노드 네트워크 확인**
root@sung-ubuntu04:~# ifconfig -a
...
tunl0: flags=193<UP,RUNNING,NOARP>  mtu 1480
        inet 10.233.99.0  netmask 255.255.255.255
        tunnel   txqueuelen 1000  (IPIP Tunnel)
        RX packets 60  bytes 8528 (8.5 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 66  bytes 4476 (4.4 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


*mtu 1480인 이유?
IPIP 터널을 사용하고 있기 때문에, 캡슐화된 패킷의 크기는 원래 패킷보다 더 크기 때문에 MTU 조절이 필요하다
1480인 이유는 캡슐화된 패킷이 Ethernet 패킷에 포함될 때 전체 크기가 1500을 초과하지 않도록 하기 위해서이다.

1.3 멀티 컨테이너 네트워크 실습

목표

  • Pod (Multi Container)의 네트워크 설정 확인

root@sung-ubuntu01:~/tmp# cat multi-con.yaml
apiVersion: v1
kind: Pod
metadata:
  name: multi-container
spec:
  containers:
  - name: ubuntu
    image: ubuntu:20.04
    command: ["/bin/sleep", "3650d"]
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
  volumes:
  - name: cache-volume
    emptyDir: {}
  restartPolicy: Always
  dnsConfig:
    nameservers:
      - 8.8.8.8

root@sung-ubuntu01:~/tmp# kubectl get pod -o wide
NAME              READY   STATUS    RESTARTS   AGE   IP            NODE            NOMINATED NODE   READINESS GATES
multi-container   2/2     Running   0          25m   10.233.78.3   sung-ubuntu05   <none>           <none>
ubuntu-test       1/1     Running   0          57m   10.233.99.1   sung-ubuntu04   <none>           <none>

**#ubuntu 컨테이너 접속**
root@sung-ubuntu01:~/tmp# kubectl exec -it multi-container -c ubuntu -- bash

### POD 안에서
# apt update
# apt install -y net-tools iputils-ping

root@multi-container:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1480
        inet 10.233.78.3  netmask 255.255.255.255  broadcast 0.0.0.0
        ether ce:de:b3:90:c1:a7  txqueuelen 0  (Ethernet)
        RX packets 5206  bytes 23989810 (23.9 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3160  bytes 213900 (213.9 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

**# nginx 컨테이너 접속**
root@sung-ubuntu01:~/tmp# kubectl exec -it multi-container -c nginx -- bash

### POD 안에서 실행
# apt update
# apt install -y net-tools iputils-ping

root@multi-container:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1480
        inet 10.233.78.3  netmask 255.255.255.255  broadcast 0.0.0.0
        ether ce:de:b3:90:c1:a7  txqueuelen 0  (Ethernet)
        RX packets 6287  bytes 33013014 (31.4 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3935  bytes 267591 (261.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

노드 네트워크 확인

root@sung-ubuntu05:~# ifconfig -a
calib4cfe5eb958: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1480
        inet6 fe80::ecee:eeff:feee:eeee  prefixlen 64  scopeid 0x20<link>
        ether ee:ee:ee:ee:ee:ee  txqueuelen 0  (Ethernet)
        RX packets 3935  bytes 267591 (267.5 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6287  bytes 33013014 (33.0 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:6a:17:c5:80  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.110.104  netmask 255.255.0.0  broadcast 192.168.255.255
        inet6 fe80::f816:3eff:fe54:bc4  prefixlen 64  scopeid 0x20<link>
        ether fa:16:3e:54:0b:c4  txqueuelen 1000  (Ethernet)
        RX packets 1353299  bytes 1304887824 (1.3 GB)
        RX errors 0  dropped 88603  overruns 0  frame 0
        TX packets 191206  bytes 20789350 (20.7 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

kube-ipvs0: flags=130<BROADCAST,NOARP>  mtu 1500
        inet 10.233.0.1  netmask 255.255.255.255  broadcast 0.0.0.0
        ether 66:2d:b3:6c:50:9a  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 162061  bytes 22298211 (22.2 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 162061  bytes 22298211 (22.2 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

nodelocaldns: flags=130<BROADCAST,NOARP>  mtu 1500
        inet 169.254.25.10  netmask 255.255.255.255  broadcast 0.0.0.0
        ether 16:84:53:46:fe:65  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

tunl0: flags=193<UP,RUNNING,NOARP>  mtu 1480   #터널 인터페이스
        inet 10.233.78.0  netmask 255.255.255.255
        tunnel   txqueuelen 1000  (IPIP Tunnel)
        RX packets 69  bytes 9380 (9.3 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 76  bytes 5125 (5.1 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

multi-container 관련 컨테이너 확인

root@sung-ubuntu05:~# docker ps | grep multi-container
64c1938850a2   nginx                  "/docker-entrypoint.…"   26 minutes ago   Up 25 minutes             k8s_nginx_multi-container_default_1d0e0776-18b1-4c7f-b05f-20b8c54fb230_0
b4c4045ac777   ubuntu                 "/bin/sleep 3650d"       26 minutes ago   Up 26 minutes             k8s_ubuntu_multi-container_default_1d0e0776-18b1-4c7f-b05f-20b8c54fb230_0
1eaedb9c9d55   k8s.gcr.io/pause:3.5   "/pause"                 27 minutes ago   Up 26 minutes             k8s_POD_multi-container_default_1d0e0776-18b1-4c7f-b05f-20b8c54fb230_0

Pause Container

  • 파드 내부의 container들을 위한 일종의 '부모 container' 로서의 역할을 수행합니다.

  • 파드가 실행될 때 Pause Container가 먼저 실행되고 Pause Container의 리눅스 네임스페이스를 파드 내부의 모든 컨테이너들이 상속받아서 사용합니다.

  • Container들의 부모 프로세스가 Pause Container인 리눅스 네임스페이스에 속하기 때문에 localhost 통신이 가능합니다.

리눅스 namespace

  • 리눅스 커널에서 제공 기능으로 Container의 기반이 되는 기술. 하나의 시스템에서 프로세스를 격리시킬 수 있는 가상화 기술입니다.

1.4 파드 간 통신

Pod 간 route 경로 확인

root@sung-ubuntu01:~/tmp# kubectl get pod -o wide
NAME              READY   STATUS    RESTARTS   AGE   IP            NODE            NOMINATED NODE   READINESS GATES
multi-container   2/2     Running   0          25m   10.233.78.3   sung-ubuntu05   <none>           <none>
ubuntu-test       1/1     Running   0          57m   10.233.99.1   sung-ubuntu04   <none>           <none>

#ubuntu-test 
root@ubuntu-test:/# apt install traceroute

root@ubuntu-test:/# traceroute 10.233.78.3
traceroute to 10.233.78.3 (10.233.78.3), 30 hops max, 60 byte packets
 1  192.168.110.103 (192.168.110.103)  0.202 ms  0.032 ms  0.028 ms  #sung-ubuntu04 ens3
 2  10.233.78.0 (10.233.78.0)  1.169 ms  0.990 ms  0.928 ms          #sung-ubuntu05 tunl0
 3  10.233.78.3 (10.233.78.3)  1.096 ms  1.111 ms  1.087 ms          #multi-container IP

노드 route table 확인

root@sung-ubuntu04:~# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         _gateway        0.0.0.0         UG    100    0        0 ens3
10.233.78.0     sung-ubuntu05.c 255.255.255.0   UG    0      0        0 tunl0
10.233.91.0     sung-ubuntu02.c 255.255.255.0   UG    0      0        0 tunl0
10.233.95.0     sung-ubuntu01.c 255.255.255.0   UG    0      0        0 tunl0
10.233.99.0     0.0.0.0         255.255.255.0   U     0      0        0 *
10.233.99.1     0.0.0.0         255.255.255.255 UH    0      0        0 calie3df4d89b13
10.233.99.2     0.0.0.0         255.255.255.255 UH    0      0        0 calia85a668c715
10.233.112.0    sung-ubuntu03.c 255.255.255.0   UG    0      0        0 tunl0
169.254.169.254 192.168.51.110  255.255.255.255 UGH   100    0        0 ens3
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.0.0     0.0.0.0         255.255.0.0     U     0      0        0 ens3

root@sung-ubuntu04:~# cat /etc/hosts
...
# Ansible inventory hosts BEGIN
192.168.110.100 sung-ubuntu01.cluster.local sung-ubuntu01
192.168.110.101 sung-ubuntu02.cluster.local sung-ubuntu02
192.168.110.102 sung-ubuntu03.cluster.local sung-ubuntu03
192.168.110.103 sung-ubuntu04.cluster.local sung-ubuntu04
192.168.110.104 sung-ubuntu05.cluster.local sung-ubuntu05
  • 참고

https://kubernetes.io/ko/docs/concepts/cluster-administration/networking/


2. kube-proxy

2.1 kube-proxy 개요

  • 노드로 들어오는 네트워크 트래픽을 파드에 로드밸런싱 알고리즘을 사용하여 포워딩합니다.

    • Network Proxy, Load Balancer 역할을 수행합니다.

kube proxy 특징

  • 각 노드에서 실행됩니다.

  • UDP, TCP, SCTP를 이용하여 Proxy합니다.

  • HTTP는 이해하지 못합니다.

  • 로드밸런싱을 제공합니다.

  • 서비스에 도달하는데만 사용됩니다.

출처 - https://kubernetes.io/ko/docs/concepts/cluster-administration/proxies/

2.1.1 쿠버네티스 아키텍처

2.1.2 kube-proxy 파드 확인

root@sung-ubuntu01:~# kubectl -n kube-system get all -o wide | grep kube-proxy
pod/kube-proxy-7xwmt                              1/1     Running            1 (6d1h ago)       6d3h    192.168.110.101   sung-ubuntu02   <none>           <none>
pod/kube-proxy-8kdx9                              1/1     Running            1 (6d1h ago)       6d3h    192.168.110.103   sung-ubuntu04   <none>           <none>
pod/kube-proxy-ktr52                              1/1     Running            5                  6d3h    192.168.110.104   sung-ubuntu05   <none>           <none>
pod/kube-proxy-l44dw                              1/1     Running            1 (6d1h ago)       6d3h    192.168.110.100   sung-ubuntu01   <none>           <none>
pod/kube-proxy-ssbsg                              1/1     Running            1 (6d1h ago)       6d3h    192.168.110.102   sung-ubuntu03   <none>           <none>
daemonset.apps/kube-proxy    5  5  5  5  5    kubernetes.io/os=linux   6d19h   kube-proxy    k8s.gcr.io/kube-proxy:v1.22.8   k8s-app=kube-proxy

2.1.3 kube-proxy 모드 옵션 설정

vi kubespray/inventory/sample/group_vars/k8s_cluster/k8s-cluster.yml
...
# Kube-proxy proxyMode configuration.
# Can be ipvs, iptables
kube_proxy_mode: ipvs
...

IPVS(IP Virtual Server): Netfilter Framework 기반으로 구현된 리눅스 커널 레벨에서 동작하는 Layer-4 로드밸런싱 도구입니다. (Netfilter에 포함)

2.1.4 kube-proxy 모드 별 작동방법

iptables 모드 작동 방법

(1) K8s 서비스 생성

(2) control-plane에서 가상 IP주소를 서비스에 할당

(3) 클러스터의 모든 kube-proxy에서 서비스 관찰

(4) 가상IP 주소→서비스로 리다이렉션하는 iptables 규칙 설정

(5) 서비스 규칙과 엔드포인트 규칙 연결

→ 대규모 클러스터(ex. 10,000 서비스)에서 크게 느려집니다.

IPVS 모드 작동 방법

(1) 로드 밸런싱을 위해 설계되었고, 커널-내부 해시 테이블(IPVS 테이블)을 기반으로 합니다.

→ 많은 개수의 서비스에서 일관성 있는 성능을 가질 수 있습니다.

→ 보다 정교한 로드 밸런싱 알고리즘을 가집니다. (least conns, locality, weighted, persistence)

2.1.5 IPVS모드 & iptables 모드 성능 비교

출처 - https://www.tigera.io/blog/comparing-kube-proxy-modes-iptables-or-ipvs/

2.2 kube-proxy 동작방법

가상 IP와 서비스 프록시

  • 쿠버네티스 클러스터의 모든 노드는 kube-proxy를 실행합니다.

  • kube-proxy는 ExternalName 이외의 유형의 서비스에 대한 가상 IP 형식을 구현합니다.

2.2.1 iptables 모드

kube-proxy iptables 모드 (출처 - https://kubernetes.io/ko/docs/concepts/services-networking/service/ )

2.2.2 ipvs 모드

*hash table로 데이터 저장

2.2.3 IPVS 모드 확인

**kube-proxy IPVS mode를 사용하기 위해서는 OS에서 IPVS를 사용할 수 있는 상태이어야 하며,
클러스터 내 노드에 설치되어야 합니다.**

root@sung-ubuntu01:/lib/modules/5.4.0-124-generic/build# systemctl status ipvsadm
● ipvsadm.service - LSB: ipvsadm daemon
     Loaded: loaded (/etc/init.d/ipvsadm; generated)
     Active: active (exited) since Thu 2022-08-25 15:29:25 KST; 4 days ago
       Docs: man:systemd-sysv-generator(8)
      Tasks: 0 (limit: 9507)
     Memory: 0B
     CGroup: /system.slice/ipvsadm.service

Aug 25 15:29:24 sung-ubuntu01 systemd[1]: Starting LSB: ipvsadm daemon...
Aug 25 15:29:25 sung-ubuntu01 ipvsadm[617]:  * ipvsadm is not configured to run. Please edit /etc/default/ipvsadm
Aug 25 15:29:25 sung-ubuntu01 systemd[1]: Started LSB: ipvsadm daemon.

root@sung-ubuntu01:~# ipvsadm --help
ipvsadm v1.31 2019/12/24 (compiled with popt and IPVS v1.2.1)
Usage:
  ipvsadm -A|E virtual-service [-s scheduler] [-p [timeout]] [-M netmask] [--pe persistence_engine] [-b sched-flags]
  ipvsadm -D virtual-service
  ipvsadm -C
  ipvsadm -R
  ipvsadm -S [-n]
  ipvsadm -a|e virtual-service -r server-address [options]
  ipvsadm -d virtual-service -r server-address
  ipvsadm -L|l [virtual-service] [options]
  ipvsadm -Z [virtual-service]
  ipvsadm --set tcp tcpfin udp
  ipvsadm --start-daemon {master|backup} [daemon-options]
  ipvsadm --stop-daemon {master|backup}
  ipvsadm -h
...

root@sung-ubuntu01:~# ipvsadm --list
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  kubernetes.default.svc.clust rr
  -> sung-ubuntu01:6443           Masq    1      0          0
  -> sung-ubuntu02:6443           Masq    1      5          0
  -> sung-ubuntu03:6443           Masq    1      0          0
TCP  coredns.kube-system.svc.clus rr
  -> 10-233-95-1.coredns.kube-sys Masq    1      0          0
  -> 10-233-112-0.coredns.kube-sy Masq    1      1          0
TCP  coredns.kube-system.svc.clus rr
  -> 10-233-95-1.coredns.kube-sys Masq    1      0          0
  -> 10-233-112-0.coredns.kube-sy Masq    1      0          0
UDP  coredns.kube-system.svc.clus rr
  -> 10-233-95-1.coredns.kube-sys Masq    1      0          0
  -> 10-233-112-0.coredns.kube-sy Masq    1      0          0

* ip로 결과 보기 - ipvsadm -L -n


3. Calico

3.1 CNI

3.1.1 CNI 요구사항

  • veth 페어 생성 및 컨테이너 네트워크 인터페이스와 연결

  • Pod 네트워크 대역 확인 후 IP 설정

  • CNI 설정 파일 작성

  • IP 설정 및 관리

  • 컨테이너 내 기본 라우팅 정보 삽입 (default route rule)

  • 동료 노드들에게 IP 라우팅 정보 전달(advertising the routes)

  • 호스트 서버에 라우팅 정보 삽입

  • 네트워크 정책에 따라 트래픽 처리

3.2 칼리코 개요

  • 컨테이너 통신을 자유롭게 해주는 CNI - Calico

root@sung-ubuntu01:~/tmp# calicoctl version
Client Version:    v3.21.2
Git commit:        17461419
Cluster Version:   v3.21.2
Cluster Type:      kubespray,bgp,kubeadm,kdd,k8s

# 모든 노드가 mesh 형태로 연결되어 있는 것을 확인
root@sung-ubuntu01:~/tmp# calicoctl node status 
Calico process is running.
IPv4 BGP status
+-----------------+-------------------+-------+----------+-------------+
|  PEER ADDRESS   |     PEER TYPE     | STATE |  SINCE   |    INFO     |
+-----------------+-------------------+-------+----------+-------------+
| 192.168.110.101 | node-to-node mesh | up    | 02:45:04 | Established |
| 192.168.110.103 | node-to-node mesh | up    | 02:40:50 | Established |
| 192.168.110.104 | node-to-node mesh | up    | 02:41:00 | Established |
| 192.168.110.102 | node-to-node mesh | up    | 02:44:42 | Established |
+-----------------+-------------------+-------+----------+-------------+

root@sung-ubuntu04:~# calicoctl node status
Calico process is running.
IPv4 BGP status
+-----------------+-------------------+-------+----------+-------------+
|  PEER ADDRESS   |     PEER TYPE     | STATE |  SINCE   |    INFO     |
+-----------------+-------------------+-------+----------+-------------+
| 192.168.110.100 | node-to-node mesh | up    | 02:40:49 | Established |
| 192.168.110.101 | node-to-node mesh | up    | 02:45:02 | Established |
| 192.168.110.104 | node-to-node mesh | up    | 02:40:59 | Established |
| 192.168.110.102 | node-to-node mesh | up    | 02:44:42 | Established |
+-----------------+-------------------+-------+----------+-------------+

*master 서버에서만 출력
# 생성된 파드에 대한 위치, 정보 확인
root@sung-ubuntu01:~/tmp# calicoctl get workloadEndpoint
WORKLOAD           NODE            NETWORKS         INTERFACE
multi-container    sung-ubuntu05   10.233.78.3/32   calib4cfe5eb958
multi-container2   sung-ubuntu04   10.233.99.2/32   calia85a668c715
ubuntu-test        sung-ubuntu04   10.233.99.1/32   calie3df4d89b13

# BGP 피어링은 179번 포트를 사용합니다.
root@k8s-master01:~# netstat -antlp | grep 179
tcp        0      0 0.0.0.0:179             0.0.0.0:*               LISTEN      831313/bird
tcp        0      0 192.168.110.111:179     192.168.110.115:54063   ESTABLISHED 831313/bird
tcp        0      0 192.168.110.111:179     192.168.110.112:40507   ESTABLISHED 831313/bird
tcp        0      0 192.168.110.111:179     192.168.110.113:52189   ESTABLISHED 831313/bird
tcp        0      0 192.168.110.111:179     192.168.110.114:51323   ESTABLISHED 831313/bird

Q. multi-container2 파드를 삭제하면 sung-ubuntu04 노드 인터페이스는 어떻게 변할까요?

BGP(Border Gateway Protocol)

  • 네트워크 BGP, AS(Autonomous System, 자율 시스템)을 설명할 때, 기업의 사내망과 인터넷 또는 국가 간 통신 방법에 비유합니다.

  • K8s에서는 각 노드 내 파드들과 노드 간의 통신으로 범위를 줄여서 적용할 수 있습니다.

3.3 칼리코 동작방식

3.3.1 Direct 방식

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

  • 성능적으로 가장 우수합니다.

  • 공식 용어는 아닌 것으로 보이며, Overlay 방식을 사용하지 않는 것을 Direct 방식이라고 칭합니다.

3.3.2 Overlay 방식 (터널링)

  • Pod의 네트워크 정보를 노드에서 Encapsulation(캡슐화)하여 목적지 노드로 전달합니다.

  • IP 기반의 터널링 방식으로 파드의 패킷 전달합니다.

  • 각 노드 패킷에 대한 Encapsulation / Decapsulation 과정 실행합니다.

  • IPIP 모드

    • IP-in-IP라고 불리우는 Overlay 방식으로, Calico의 기본 모드입니다.

    • Pod의 네트워크 패킷의 기존 IP헤더 앞에 IP헤더를 하나 더 덧붙여 통신합니다.

    • 다른 노드간 Pod 통신은 tunl0 인터페이스를 통해 IP 헤더에 감싸져서 상대 노드로 도달 후 tunl0 인터페이스에서 Outer 헤더를 제거하고 내부의 파드와 통신합니다.

  • VXLAN 모드

    • POD간 통신이 노드 구간에 VXLAN Encapsultation을 통해 이루어 집니다.

#Calico NAT 정책 확인 (true)
root@sung-ubuntu01:~/tmp# calicoctl get ippool -o wide
NAME           CIDR             NAT    IPIPMODE   VXLANMODE   DISABLED   DISABLEBGPEXPORT   SELECTOR
default-pool   10.233.64.0/18   true   Always     Never       false      false              all()

#워커 노드에서 iptables nat 확인
root@sung-ubuntu04:~# iptables -n -t nat --list cali-nat-outgoing
Chain cali-nat-outgoing (1 references)
target     prot opt source               destination
MASQUERADE  all  --  0.0.0.0/0            0.0.0.0/0            /* cali:flqWnvo8yq4ULQLa */ match-set cali40masq-ipam-pools src ! match-set cali40all-ipam-pools dst random-fully
=> cali-nat-outgoing 정책으로 외부로 나가는 패킷은 모두 MASQUERADE하여 처리됩니다. (=외부로 나가는 트래픽은 MASQURADE 정책을 통해 나갈 수 있습니다.)

IP Masquerade

  • NAT 기술 안에 속한 기술로 가면이라는 의미입니다.

  • NAT와 다르게 주소변환만 하는것이 아닌 포트번호까지 포트포워딩시켜주는 기능을 가지고 있습니다.

  • SNAT(Source NAT)와 같다고 합니다.

3.4 칼리코 모듈

3.4.1 칼리코 배포방식

  • The calico/node container is deployed to every node (on Kubernetes, by a DaemonSet), and runs three internal daemons

3.4.2 칼리코 구성요소

  • Felix(필릭스)

    • calico-node 파드 안에 위치하며, 모든 노드의 endpoint 제공합니다.

    • K8s ETCD 정보를 읽습니다.

    • 라우팅 테이블 생성합니다.

    • kube-proxy가 iptables 모드인 경우, iptables 컨트롤합니다.

    • kube-proxy가 ipvs 모드인 경우, ipvs 컨트롤합니다.

  • BIRD(버드)

    • 다른 노드에 있는 BGP 데몬들과 라우팅 정보 교환합니다.

    • TCP 179를 이용해서 mesh 형태로 연결합니다.

  • confd

    • Calico 데이터 저장소의 구성 변경을 감시하고 BIRD의 구성 파일을 업데이트하는 데몬 입니다.

# calico-node는 daemonset으로 배포되어있습니다.
root@sung-ubuntu01:/var/lib/cni# kubectl -n kube-system get all | grep cali
pod/calico-kube-controllers-6bc8445c8-kptbp   1/1     Running   48               2d23h
pod/calico-node-ckvhb                         1/1     Running   4 (2d23h ago)    2d23h
pod/calico-node-d2pr7                         1/1     Running   5 (2d23h ago)    2d23h
pod/calico-node-fnmg9                         1/1     Running   5 (2d23h ago)    2d23h
pod/calico-node-gqr27                         1/1     Running   9 (2d23h ago)    2d23h
pod/calico-node-gzrt9                         1/1     Running   8 (2d23h ago)    2d23h
daemonset.apps/calico-node    5         5         5       5            5           kubernetes.io/os=linux   2d23h
deployment.apps/calico-kube-controllers   1/1     1            1           2d23h
replicaset.apps/calico-kube-controllers-6bc8445c8   1         1         1       2d23h

3.4.3 kube-proxy iptables와 Calico iptables 서비스 개수별 룰 개수 비교

출처 - https://www.tigera.io/blog/comparing-kube-proxy-modes-iptables-or-ipvs/

  • 레이블 없음