티스토리 뷰

Infra Structure/.system

Kubernetes Networking #1

가그린민트 2020. 3. 15. 16:23

이번 포스팅에서는 Kubernetes in Action, 매니징 쿠버네티스 을 활용하였습니다.

 

이 포스팅과 더불어 한우형님의 블로그, Rancher Labs 자료 등을 함께 보시면 더 좋습니다.

1. 기본적인 특징 

* 네트워크 구성방식과 관계없이 파드간의 통신

- 모든 Pods는 다른 Pod와 NAT(Network Address Translation)을 사용하지 않고 통신할 수 있다.

- 모든 Nodes는 NAT를 사용하지 않고 모든 Pods와 통신할 수 있다.

 


2. Container-to-Container Networking

* NET namespace가 외부와 통신하는 방식

veth interface를 이용하여 두 개의 interface가 Pair를 맺은 후, 한쪽 Interface에 패킷이 들어오면 자신에게 연결된 다른 네트워크 인터페이스로 패킷을 보내주는 식으로 동작한다. 

즉,  container가 생성되면, 이 pair interface 의 한 쪽은 container 내부 namespace에 할당(eth0)되며, 나머지 하나는 vethXXXX 라는 이름으로 docker0 bridge에 binding된다. docker0는 docker 실행시 자동으로 생성되는 가상 브릿지로 Container는 외부와 통신할 때 docker0 브릿지를 거쳐 통신을 하며, docker0 브릿지에 할당된 IP 대역에 맞춰 컨테이너 IP가 할당된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
$ brctl show docker0
bridge name     bridge id               STP enabled     interfaces
docker0         8000.02422a674d39       no              veth6bb114e
                                                        veth9517b99
                                                        vetha06291d
                                                        vethaf42c95
$ ip link ls
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 02:42:ac:11:00:0f brd ff:ff:ff:ff:ff:ff
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
    link/ether 02:42:2a:67:4d:39 brd ff:ff:ff:ff:ff:ff
7: vetha06291d@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
    link/ether 5a:0d:71:6c:7d:2f brd ff:ff:ff:ff:ff:ff link-netnsid 1
 
 
$ ethtool -S vetha06291d
NIC statistics:
     peer_ifindex: 6
 
$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
11f19f488ad3        bridge              bridge              local
0e4b12c5d30e        host                host                local
f2d26841d49a        none                null                local
 
 
$ docker network inspect bridge
[
    {
        "Name""bridge",
        "Id""11f19f488ad3e93c199ceb1e9b22b9541a4777fe4916f1c7b379e93773ce26cf",
        "Created""2019-11-28T06:15:22.406695801Z",
        "Scope""local",
        "Driver""bridge",
        "EnableIPv6"false,
        "IPAM": {
            "Driver""default",
            "Options": null,
            "Config": [
                {
                    "Subnet""172.18.0.1/24",
                    "Gateway""172.18.0.1"
                }
            ]
        },
        "Internal"false,
        "Attachable"false,
        "Ingress"false,
        "ConfigFrom": {
            "Network"""
        },
        "ConfigOnly"false,
        "Containers": {
            "09e556688ac65de82dbc4b08fe442853bbd3d2a2418e6564d9feb1677edf712e": {
                "Name""k8s_POD_kubernetes-bootcamp-5b48cfdcbd-qzcsm_default_00dbb354-dc17-469c-a586-d5bd4d8158a9_0",
                "EndpointID""7b8a3c0f47db0c39673fc1e5a82610cd094f3669d4b210f2c76796dfa2525222",
                "MacAddress""02:42:ac:12:00:04",
                "IPv4Address""172.18.0.4/24",
                "IPv6Address"""
            },
 
$ docker ps -a
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS               NAMES
09e556688ac6        k8s.gcr.io/pause:3.1   "/pause"                 About an hour ago   Up About an hour                        k8s_POD_kubernetes-bootcamp-5b48cfdcbd-qzcsm_default_00dbb354-dc17-469c-a586-d5bd4d8158a9_0

Kubernetes의 경우 실제 동작하는 컨테이너 외에도 pause 컨테이너가 생성되는 것을 확인할 수 있다. pause 명령으로 실행된 Container는 실제로도 쿠버네티스가 SIGTERM 명령을 내리기 전까지는 아무것도 하지 않고 Sleep 상태로 존재한다. 

pause container의 역할을 파악하기 위해서는, 우선 Container network 방식 중 container 방식을 이해할 필요가 있다. [자세한건 여기]

 

Kubernetes는 Pod 내에서 컨테이너 생성시 Bridge 모드가 아닌 Container모드로 띄우는데, Container 모드는 아래와 같이 다른 컨테이너를 지정하여 띄울 수 있어 지정한 Container간 네트워크를 공유하는 형태로 생성할 수 있다.

1
$ docker run --net=container:{container_id} -d {image_name}

 

즉, 각 Container의 IP가 같으므로 외부에서 같은 IP로 접근하며, Container들은 서로 같은 port를 사용하는 것은 불가능하다.

pause 컨테이너는 pod의 컨테이너들이 namespace를 공유하여 컨테이너 간에는 localhost로 통신할 수 있게 한다. (IPC 통신도 가능)

그리고 Pod에서 init process 역할을 하여 좀비 프로세스를 거둬들이는 기능도 수행한다.  [자세한건 여기]

 

 


3. Pod-to-Pod Networking

CNI(Container Network Interface) plug in은 Virtual device (switch, router, tunnel 등)을 생성하는 등 Kubernetes의 가상 네트워크를 구성한다. 구체적으로는, 1) veth pair를 만들어 pod와 가상 네트워크를 연결, 2) pod의 routing table을 설정(IPAM), 3) Proxy ARP 기능 등을 수행한다.

 

1) intra node

 

Pod에서 실행되는 컨테이너는 Pod의 네트워크 네임스페이스를 사용한다. Container 관점에서 Pod는 하나의 네트워크 인터페이스를 가지고 있는 물리 머신으로 보인다. 각 Container의 localhost는 Pod를 통해 노드의 물리적 네트워크 인터페이스(예: root의 eth0)에 연결된다. 하나의 Node안에서 Pod간의 통신은 동일 네트워크 대역대에 있으므로 ARP을 사용하여 이루어진다. 

 

2) inter node 

다른 Node간의 통신의 경우, 다른 네트워크 대역대(IPAM에 의해 네트워크 대역을 나누므로 Pod들은 고유의 IP를 가질 수 있게 되는 것이다. [Calito의 IP할당] 그렇지 않을 경우 아래와 같이 docker0 IP가 중복일 수 있다.)이므로 Default Gateway인 root의 eth0을 통해 외부로 패킷을 송신한다. (즉, OSI 7 Layer상 3계층 이상의 통신이 이루어진다)

 

 

 

Kubernetes는 이처럼 각 Node의 Bridge가 서로 겹치지 않게 주소 대역을 할당한 수 routing table을 작성한다. 이렇게 Virtual Network Interface와 Bridge, Routing Rule의 조합을 일컬어 overlay network라 한다.

 

 /24 범위의 노드에서는 256개가 아닌 최대 110개의 Pod를 실행할 수 있다. 이렇게 하면 여유가 생겨서 지정된 노드의 Pod IP 범위에 일시적으로 IP 주소가 없어서 Pod를 예약하지 못하는 상황이 발생하지 않는다. /24보다 작은 범위의 경우 약 절반의 Pod를 해당 범위의 IP 주소로 예약할 수 있다. 물론 노드당 CIDR 범위를 줄여 IP 주소할당을 최적화하여 더 많은 클러스터를 생성할 수도 있다.

오리뎅이님의 쿠버네티스 네트워킹 장표 중 일부

 

 

 

 

2편에서 'Pod-to-Service', 'Internet-to-Service' Networking이 이어집니다

댓글
링크
최근에 달린 댓글
«   2024/03   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
Total
Today
Yesterday