본문 바로가기
개발/docker, k8s, CNCF

docker, k8s 네트워크 뜯기(5) - pod 내부의 container와 다른 pod 내부의 container는 어떻게 서로 통신할까?

by 앗가 2023. 3. 5.
728x90
반응형

사용한 코드입니다. 

https://github.com/atgane/docker-k8s-network-tutorial/tree/main/blog5

 

GitHub - atgane/docker-k8s-network-tutorial

Contribute to atgane/docker-k8s-network-tutorial development by creating an account on GitHub.

github.com

 

이번에는 클러스터 내부에서 pod가 어떻게 통신하는지 확인하겠습니다. 

 

flask이미지를 만들어서 로컬 이미지 저장소에 배포하고 k8s에 pod를 만들고 배포해 보겠습니다. 배포 후 다른 pod로 요청을 보내면 도달하는지 확인해 봅시다. 로컬 이미지 저장소를 이용한 kind k8s 클러스터 배포방법은 https://atgane.tistory.com/182 이 포스팅에서 다루고 있습니다. 

 

docker, k8s 네트워크 뜯기(4) - local registry로 kind k8s cluster에 배포하기

클러스터내부에서 pod가 어떻게 통신하는지 확인하기 위한 사전작업을 진행하겠습니다. 컨테이너 이미지를 직접 만들어서 로컬 환경에 이미지 저장소를 만들고 로컬 이미지 저장소로부터 pod를

atgane.tistory.com

시작하기 전에 create-kind-cluster.sh을 작업 디렉토리에 복사해서 실행시켜 주겠습니다. 

./create-kind-cluster.sh

 

실습 환경은 다음과 같습니다(리눅스에 docker, kind가 설치된 환경이면 상관없지만 wsl은 다를 수 있습니다).

- virtualbox 7.0.6

- ubuntu 22.04.2 LTS

- docker

- kind 0.17.0

 

순서는 다음과 같습니다. 

1. flask Dockerfile만들기

2. myflask 이미지 k8s 클러스터로 배포하기

3. node와 pod

4. pod의 컨테이너간 포트 충돌


1. flask Dockerfile만들기

하나의 파드에 두 개의 flask 컨테이너를 띄워보겠습니다. 굳이 두 개를 띄우는 이유는 포트를 같게 했을 때 제대로 띄워지는지를 보기 위함입니다. 그래서 작업 디렉토리를 다음처럼 구성하였습니다. 

 

create-kind-cluster.sh은 이전 포스팅 https://atgane.tistory.com/182 에 사용했던 파일을 그대로 이용했습니다. 

tree
# .
# ├── create-kind-cluster.sh
# ├── deploy-docker-image.sh
# ├── deployment.yaml
# └── dockerfile
#     ├── myflask1
#     │   ├── app.py
#     │   └── Dockerfile
#     └── myflask2
#         ├── app.py
#         └── Dockerfile

먼저  myflask1/app.py입니다. flask로 8000번 포트로 호스팅 합니다. 

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return "hello myflask1 1.0"

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=8000)

다음은 myflask2/app.py입니다. flask로 8001번 포트로 호스팅 합니다. 

# myflask2/app.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return "hello myflask2 1.0"

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=8001)

myflask1/Dockerfile과 myflask2/Dockerfile은 같게 설정했습니다. 

# Dockerfile은 myflask1, 2 모두 동일
FROM python:3.9-slim
COPY . /app
RUN pip3 install flask
WORKDIR /app
CMD ["python3", "app.py"]

쉘 스크립트로 docker 이미지를 빌드하고 로컬 레지스트리에 넣어주기 위해 deploy-docker-image.sh을 다음처럼 작성해 주었습니다. 

# deploy-docker-image.sh

docker build -t 127.0.0.1:5001/myflask1:1.0 dockerfile/myflask1
docker build -t 127.0.0.1:5001/myflask2:1.0 dockerfile/myflask2

docker push 127.0.0.1:5001/myflask1:1.0
docker push 127.0.0.1:5001/myflask2:1.0

이제 작업 위치에서 해당 쉘을 실행시켜 봅시다. 

./deploy-docker-image.sh

다음 명령어로 로컬 레지스트리에 저장된 이미지를 확인할 수 있습니다. nginx는 없어도 됩니다!

curl localhost:5001/v2/_catalog
# {"repositories":["myflask1","myflask2"]}

2. myflask 이미지 k8s 클러스터로 배포하기

빌드한 2개의 이미지를 이번에는 pod가 아닌 deployment로 묶어서 배포해 보겠습니다. deployment로 pod를 2개의 replica로 배포하는 파일을 다음과 같이 작성했습니다. 

 

deployment.yaml파일입니다. 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myflask-deployment
  labels:
    app: myflask
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myflask
  template:
    metadata:
      labels:
        app: myflask
    spec:
      containers:
      - name: myflask1
        image: localhost:5001/myflask1:1.0
        ports:
        - containerPort: 8000
      - name: myflask2
        image: localhost:5001/myflask2:1.0
        ports:
        - containerPort: 8001

replicas를 2개로, containers는 myflask1, myflask2를 각각 8000. 8001 포트로 배포해 보겠습니다.

kubectl apply -f deployment.yaml

k9s를 이용한다면 다음처럼 pod가 제대로 떠있음을 확인할 수 있습니다. 

한편 k9s를 이용하지 않는 경우 kubectl을 이용하여 확인할 수 있습니다. 

kubectl get all
# NAME                                       READY   STATUS    RESTARTS   AGE
# pod/mygflask-deployment-5df795f9f6-6pjm5   2/2     Running   0          12m
# pod/mygflask-deployment-5df795f9f6-b6tg6   2/2     Running   0          12m
# 
# NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
# service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   20m
# 
# NAME                                  READY   UP-TO-DATE   AVAILABLE   AGE
# deployment.apps/mygflask-deployment   2/2     2            2           12m
# 
# NAME                                             DESIRED   CURRENT   READY   AGE
# replicaset.apps/mygflask-deployment-5df795f9f6   2         2         2       12m

pod의 세부정보를 보려면 describe 명령어를 이용하여 확인합니다. pod의 IP를 확인하기 위해 아래의 명령어를 입력해 보겠습니다. pod이름은 kubectl get all로 확인한 pod의 name입니다. 

kubectl describe pod mygflask-deployment-5df795f9f6-6pjm5
# Name:             mygflask-deployment-5df795f9f6-6pjm5
# Namespace:        default
# Priority:         0
# Service Account:  default
# Node:             kind-worker/172.18.0.3
# Start Time:       Sun, 05 Mar 2023 20:47:21 +0900
# Labels:           app=myflask
#                   pod-template-hash=5df795f9f6
# Annotations:      <none>
# Status:           Running
# IP:               10.244.1.2
# IPs:
#   IP:           10.244.1.2
# Controlled By:  ReplicaSet/mygflask-deployment-5df795f9f6
# ~

kubectl describe pod mygflask-deployment-5df795f9f6-b6tg6 
# Name:             mygflask-deployment-5df795f9f6-b6tg6
# Namespace:        default
# Priority:         0
# Service Account:  default
# Node:             kind-worker2/172.18.0.2
# Start Time:       Sun, 05 Mar 2023 20:47:21 +0900
# Labels:           app=myflask
#                   pod-template-hash=5df795f9f6
# Annotations:      <none>
# Status:           Running
# IP:               10.244.2.2
# IPs:
#   IP:           10.244.2.2
# Controlled By:  ReplicaSet/mygflask-deployment-5df795f9f6
# ~

분명 docker에서 network를 확인할 때 컨테이너마다 IP가 부여되었습니다. 그런데 pod는 여러 컨테이너가 포함되어 있는데 pod자체에 IP가 고정되어 있습니다. 또한 Node라고 되어있는 정보도 보이는데, 이 Node는 해당 pod가 띄워져 있는 머신을 의미합니다. 옆에 나온 IP주소는 당연히 Node의 IP주소를 의미합니다. 

 

만약 host머신이라면, 이 상태에서 pod의 IP인 10.244.1.2:8000에 요청을 보내도 어떤 응답을 받을 수 없습니다.

curl 10.244.1.2
# curl: (28) Failed to connect to 10.244.1.2 port 80 after 129818 ms: Connection timed out

host 머신에서 pod의 IP와 연결되기 위한 어떠한 정의도 없기 때문입니다. 따라서 host머신에서는 pod가 제대로 동작하는지 확인할 수 없습니다. 따라서 클러스터 내부의 노드로 접속해 보겠습니다. 

 

여기서 제대로 flask 서버가 동작하는지 확인하기 위해 worker node로 접속해 보겠습니다. kind는 노드를 도커 컨테이너로 배포하기 때문에 docker ps -a 명령으로 노드를 확인해 볼 수 있습니다. 

docker ps -a
# CONTAINER ID   IMAGE                  COMMAND                  CREATED          STATUS          PORTS                       NAMES
# 29d5d09497db   kindest/node:v1.25.3   "/usr/local/bin/entr…"   23 minutes ago   Up 23 minutes                               kind-worker
# 3dd6c5506cab   kindest/node:v1.25.3   "/usr/local/bin/entr…"   23 minutes ago   Up 23 minutes                               kind-worker2
# 7d182158d2ca   kindest/node:v1.25.3   "/usr/local/bin/entr…"   23 minutes ago   Up 23 minutes   127.0.0.1:35799->6443/tcp   kind-control-plane
# 40272643544e   registry:2             "/entrypoint.sh /etc…"   7 hours ago      Up 3 hours      127.0.0.1:5001->5000/tcp    kind-registry

docker exec -it kind-worker /bin/bash

kind-worker에 접속한 상태에서 pod에 요청을 보내봅니다. 

# kind-worker 내부입니다

curl 10.244.1.2:8000
# hello myflask1 1.0

curl 10.244.1.2:8001
# hello myflask2 1.0

curl 10.244.2.2:8000
# hello myflask1 1.0

curl 10.244.2.2:8001
# hello myflask2 1.0

3. node와 pod

k8s의 여러 개념 중에 node와 pod가 있습니다. node는 컨테이너가 올라가기 위한 가상 머신이든, 물리 머신이든 컴퓨터 자체를 의미합니다. 

 

pod는 여러 컨테이너가 묶여서 배포되는 k8s의 가장 작은 단위를 의미합니다. 

 

kind는 docker를 이용하여 worker node를 도커 컨테이너를 이용하여 가상으로 만들어줍니다. 실습한 환경에서는 worker node를 2대를 띄워서 myflask1과 myflask2의 이미지로부터 배포되는 pod를 2대를 생성하여 배포했습니다. 

 

pod의 상세정보를 보면, pod는 분명 다른 node에 띄워져 있습니다. 그렇지만, 임의의 node에 접속해서 컨테이너의 주소로 요청을 보냈을 때 제대로 요청이 도달함을 확인할 수 있었습니다. 어떻게 이게 가능했을까요?


지금까지 kind cluster를 생성했을 때의 네트워크를 그려보면 다음처럼 그릴 수 있습니다. 

이 상태에서 myflask1과 2를 각각의 node에 pod로 띄운다면 아래와 같이 표현할 수 있습니다. 

먼저 1번의 연결을 확인해 보겠습니다. 1번은 이전 포스팅에서 docker network와 라우트 테이블로 확인할 수 있었습니다. 호스트 머신에서 확인해 보겠습니다. 

docker network ls
# NETWORK ID     NAME      DRIVER    SCOPE
# 9b690d040473   bridge    bridge    local
# 5a2e39f8645a   host      host      local
# 38ab5c69257d   kind      bridge    local
# c0c50e70f0f8   none      null      local

docker network inspect kind
# [
#     {
#         "Name": "kind",
#         "Id": "38ab5c69257d91c3c8bc96b71cc04716b1c6800cfa73adba9f4027210848b5e7",
#         "Created": "2023-03-01T23:50:47.046527387+09:00",
#         "Scope": "local",
#         "Driver": "bridge",
#         "EnableIPv6": true,
#         "IPAM": {
#             "Driver": "default",
#             "Options": {},
#             "Config": [
#                 {
#                     "Subnet": "172.18.0.0/16",
#                     "Gateway": "172.18.0.1"
#                 },
#                 {
#                     "Subnet": "fc00:f853:ccd:e793::/64",
#                     "Gateway": "fc00:f853:ccd:e793::1"
#                 }
#             ]
#         },
#         "Internal": false,
#         "Attachable": false,
#         "Ingress": false,
#         "ConfigFrom": {
#             "Network": ""
#         },
#         "ConfigOnly": false,
#         "Containers": {
#             "29d5d09497db7c7c8ce120c4082e97da38da0b580b5ec4f139c504107a7536ce": {
#                 "Name": "kind-worker",
#                 "EndpointID": "8b92e8695c908fa56d701eb3180737ae3991941d056cd7512739ec952979d295",
#                 "MacAddress": "02:42:ac:12:00:03",
#                 "IPv4Address": "172.18.0.3/16",
#                 "IPv6Address": "fc00:f853:ccd:e793::3/64"
#             },
#             "3dd6c5506cab23adc68d6aefa60e4d63dc3add89e0f54ed7c6363dc7902a34b9": {
#                 "Name": "kind-worker2",
#                 "EndpointID": "52dad7fa70c4fe91d12038ed975910f1d12423d762c5541945cc1b31129c0823",
#                 "MacAddress": "02:42:ac:12:00:02",
#                 "IPv4Address": "172.18.0.2/16",
#                 "IPv6Address": "fc00:f853:ccd:e793::2/64"
#             },
#             "40272643544eac5ddeed33893d8c1c2701be207ec8cbc8907212c149f9759b29": {
#                 "Name": "kind-registry",
#                 "EndpointID": "c0aa340320c20100004a65983af29870849b402f9bea6737df52763b75b10ee6",
#                 "MacAddress": "02:42:ac:12:00:05",
#                 "IPv4Address": "172.18.0.5/16",
#                 "IPv6Address": "fc00:f853:ccd:e793::5/64"
#             },
#             "7d182158d2cab969ca4bd684f2bcf025a7c893f45eec1b731e86588adbbf7b9e": {
#                 "Name": "kind-control-plane",
#                 "EndpointID": "7409a463dcc1792cc41df5919b65c2a5be71df4166111f3dfeabfa9ae27d2d66",
#                 "MacAddress": "02:42:ac:12:00:04",
#                 "IPv4Address": "172.18.0.4/16",
#                 "IPv6Address": "fc00:f853:ccd:e793::4/64"
#             }
#         },
#         "Options": {
#             "com.docker.network.bridge.enable_ip_masquerade": "true",
#             "com.docker.network.driver.mtu": "1500"
#         },
#         "Labels": {}
#     }
# ]

또 라우트 테이블과 브리지 네트워크는 다음과 같습니다. 

route
# Kernel IP routing table
# Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
# default         _gateway        0.0.0.0         UG    100    0        0 enp0s3
# default         192.168.200.1   0.0.0.0         UG    20101  0        0 enp0s8
# 10.0.2.0        0.0.0.0         255.255.255.0   U     100    0        0 enp0s3
# link-local      0.0.0.0         255.255.0.0     U     1000   0        0 enp0s8
# 172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
# 172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-38ab5c69257d
# 192.168.200.0   0.0.0.0         255.255.255.0   U     101    0        0 enp0s8

brctl show
# bridge name     bridge id               STP enabled     interfaces
# br-38ab5c69257d         8000.02426e23f32c       no              veth0c5f545
#                                                         vetha35c1e7
#                                                         vethe6d03da
#                                                         vethfc9f2dc
# docker0         8000.0242b7985d16       no              veth499144f

 kind의 클러스터 대역은 172.18을 사용하므로 br-38~~의 네트워크 인터페이스로 전달됩니다. 이 인터페이스는 가상 네트워크 인터페이스인 컨테이너의 네트워크 인터페이스에 연결되어 통신이 가능함을 확인할 수 있습니다. 

 

이제는 node와 pod내부로 들어가서 동작을 살펴보겠습니다. 먼저  docker exec -it kind-worker /bin/bash명령어로 kind-worker 내부에서 route 테이블을 확인해 보겠습니다. 결과로 나온 값을 확인하면 10.244 대역의 IP의 경우 각각의 k8s node로 전달함을 확인할 수 있습니다. 유일하게 다른 것은 10.244.1.2로 그림의 2번의 자신 위에서 동작하는 pod의 대역은 vethfa~~~ 인 인터페이스에 전달하는 것을 확인할 수 있습니다. 다른 pod는 eth0 인터페이스를 타고 밖으로 트래픽이 전달될 것입니다. 

docker exec -it kind-worker /bin/bash
# root@kind-worker:/# route
# Kernel IP routing table
# Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
# default         172.18.0.1      0.0.0.0         UG    0      0        0 eth0
# 10.244.0.0      kind-control-pl 255.255.255.0   UG    0      0        0 eth0
# 10.244.1.2      0.0.0.0         255.255.255.255 UH    0      0        0 vethfa9f1726
# 10.244.2.0      kind-worker2.ki 255.255.255.0   UG    0      0        0 eth0
# 172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 eth0

ip a
# 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
#     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
#     inet 127.0.0.1/8 scope host lo
#        valid_lft forever preferred_lft forever
#     inet6 ::1/128 scope host 
#        valid_lft forever preferred_lft forever
# 2: vethfa9f1726@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
#     link/ether 8e:e0:70:36:f1:c5 brd ff:ff:ff:ff:ff:ff link-netns cni-76341e7a-b79c-ed5a-898c-e7e8dd5d4e08
#     inet 10.244.1.1/32 scope global vethfa9f1726
#        valid_lft forever preferred_lft forever
# 26: eth0@if27: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
#     link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
#     inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0
#        valid_lft forever preferred_lft forever
#     inet6 fc00:f853:ccd:e793::3/64 scope global nodad 
#        valid_lft forever preferred_lft forever
#     inet6 fe80::42:acff:fe12:3/64 scope link 
#        valid_lft forever preferred_lft forever

그러면 node에서 임의의 pod에 띄워져 있는 컨테이너에 트래픽을 전달했을 때 응답을 받는 것은 당연해 보입니다. 마찬가지로 pod 내부의 컨테이너에서도 가능할 것 같습니다. 한번 kind-worker위에 올라가 있는 myflask1 컨테이너에서도 다른 컨테이너 주소로 트래픽을 보내봅시다. 먼저 다음 명령어로 접속할 수 있습니다. 

kubectl exec -it mygflask-deployment-5df795f9f6-6pjm5 -c myflask1 -- /bin/bash

내부에 들어가서 다음 명령어를 입력해 주겠습니다. 

# 컨테이너 내부입니다

apt update -y   
apt install net-tools
apt install bridge-utils
apt install -y iproute2
apt install -y iptables
apt install -y curl

route
# Kernel IP routing table
# Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
# default         10.244.1.1      0.0.0.0         UG    0      0        0 eth0
# 10.244.1.0      10.244.1.1      255.255.255.0   UG    0      0        0 eth0
# 10.244.1.1      0.0.0.0         255.255.255.255 UH    0      0        0 eth0

ip a
# 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
#     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
#     inet 127.0.0.1/8 scope host lo
#        valid_lft forever preferred_lft forever
#     inet6 ::1/128 scope host 
#        valid_lft forever preferred_lft forever
# 2: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
#     link/ether f6:2d:a6:17:47:77 brd ff:ff:ff:ff:ff:ff link-netnsid 0
#     inet 10.244.1.2/24 brd 10.244.1.255 scope global eth0
#        valid_lft forever preferred_lft forever
#     inet6 fe80::f42d:a6ff:fe17:4777/64 scope link 
#        valid_lft forever preferred_lft forever

 

10.244.1의 IP 대역은 게이트웨이, kind-worker에서 확인할 수 있는 가상 네트워크 인터페이스인 veth로 전달됨을 확인할 수 있습니다. 그래서 10.244.2.2의 주소를 입력해도 10.244.1.1의 네트워크 인터페이스에 전달되기 때문에 curl이 동작하지 않을까요? 확인해 보겠습니다. 

curl 10.244.1.2:8000
# hello myflask1 1.0

curl 10.244.1.2:8001
# hello myflask2 1.0

curl 10.244.2.2:8000
# hello myflask1 1.0

curl 10.244.2.2:8001
# hello myflask2 1.0

이를 그림으로 그려보면 다음과 같습니다. 


4. pod의 컨테이너 간 포트 충돌

이제 pod내부에서 container가 동일한 포트를 사용할 수 있는지 확인해 보겠습니다. myflask2의 app.py를 다음과 같이 포트를 8000으로 수정해 줍니다. 

# myflask2/app.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return "hello myflask2 1.0"

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=8000)

그리고 다시 docker 이미지를 빌드하고 배포해 봅시다.

kind delete cluster
./create-kind-cluster.sh
./deploy-docker-image.sh 
kubectl apply -f deployment.yaml

kubectl get pod
# NAME                                  READY   STATUS             RESTARTS      AGE
# myflask-deployment-5df795f9f6-7h8f4   1/2     CrashLoopBackOff   1 (10s ago)   31s
# myflask-deployment-5df795f9f6-jsnpv   1/2     CrashLoopBackOff   1 (10s ago)   31s

 

사용할 수 없는 이유는 pod의 컨테이너에 직접 접속하면 확인할 수 있습니다. ip a 명령어로 네트워크 인터페이스를 확인해 보면 네트 eth0가 서로 같음을 확인할 수 있습니다. MAC주소와 IP주소가 모두 같습니다. 즉, 동일한 네트워크 인터페이스 위에 올라가 있는 것입니다. 

 

docker 컨테이너는 서로 다른 인터페이스를 사용했는데 왜 pod의 컨테이너는 같은 인터페이스를 사용할까요? 이 이유는 pod가 생성될 때 제일 먼저 생성되는 컨테이너로 pause라는 컨테이너가 뜨고 pod의 인프라를 담당해 주기 때문입니다. 이 컨테이너는 pod 내부의 컨테이너에게 network namespace을 공유합니다. 그렇기에 pod 내부의 컨테이너는 같은 네트워크 인터페이스를 사용하여 통신하게 됩니다. 심지어 컨테이너 내부에서 localhost로 다른 컨테이너에 접근할 수 있습니다. 


실습 환경 제거

kind delete cluster
docker rm -f kind-registry

 

지금까지 확인해 봤을 때 얻을 수 있는 결론은 다음과 같습니다. 

- pod와 node에 k8s가 알아서 다른 pod에 접근할 수 있는 주소를 세팅해 준다. 

- pod 내부의 컨테이너는 자원을 공유할 수 있도록 설계되어 있다. 

- pod는 이렇게 공유되는 자원이 있는 단위로 묶인다. 

- 한 pod내에 동일 포트를 사용할 수 없는데 pause 컨테이너가 인터페이스를 공유해 주기 때문이다. 

 

궁금한 점

- 어떻게 k8s의 내부에서 알아서 IP와 인터페이스를 세팅해 주는가?

- pause 컨테이너는 어떻게 인터페이스를 공유해 주는가? -> 이것도 ns의 느낌이...

- 그러면 pod가 제거되고 다시 생성되면 IP가 달라질 수 있는데? -> service

 

참고자료

- https://coffeewhale.com/k8s/network/2019/04/19/k8s-network-01/

728x90

댓글