이쿠의 슬기로운 개발생활

함께 성장하기 위한 보안 개발자 EverNote 내용 공유

클라우드/Kubernetes

04. Kubernetes Pod 더 자세히 알아보기

이쿠우우 2020. 8. 7. 12:36
반응형

Kubernetes Pod 더 자세히 알아보기

 

1. Pod 구조

Kubernetes를 처음 접하시면 가장 먼저 드는 의문점이

그냥 Container를 실행시키면 되지 뭐하러 번거롭게 Container를 Pod라는 Obejct로 감싸서 배포할까? 임.

상위 그림은 1개의 pod 안에 사용자가 생성한 3개의 Container가 실행되고 있는 상태의 그림.

분명 사용자가 생성한 3개의 Container가 실행되고 있다고 했는데 

상위 그림에는 4개가 있는것을 볼 수가 있음, 

오타가 아님 실수가 아님

4개의 Container가 있는 이유는 사용자가 생성하지 않은 Pause라는 Container가 있기 때문.

Kubernetes 에서 Pod를 생성하면 가장 먼저 생성되는 Container가 바로 이 Pause Container.

Pause container는 Pod 내부의 사용자가 생성한 Container들을 위한 일종의 '부모 container' 로서의 역할을 수행하는

Pod 내부의 인프라를 담당하는 핵심 Container.

사용자가 생성한 모든 Container들은 이 pause Container 통해 자원도 공유하고 localhost로 통신할 수가 있음.

그렇면 Pause Container가 어떻게 동작하길래 이런 역할을 수행할 수 있을지 궁금하실 탠데

Pause Container를 이해하기 위해서는 Container에 대해 이해할 필요가 있음

 

 

 

1.1. Pause Container

pause container는 Pod 내부의 container들을 위한 일종의 '부모 container' 로서의 역할을 수행

Pod 내부의 Container들은 네트워크와 볼륨을 공유하고 서로 localhost로 통신할 수 있음

좀 더 자세히 들어가면 Pod이 실행될 때 pause라는 이름의 Container가 먼저 실행되고

이 pause container의 "리눅스 namespace"를 Pod내부의 모든 Container들이 상속받아서 사용하게 됨

즉 한 Pod 안에 생성되는 모든 Container 들은 부모 프로세스가 pause container인

리눅스의 namespace에 속하기 때문에 localhost 통신이 가능해짐

 

1.2. 리눅스 namespace 란?

리눅스 커널에서 제공 기능으로 Container의 기반이 되는 기술.

하나의 시스템에서 프로세스를 격리시킬 수 있는 가상화 기술.

 

1.3. Pause Container 가 등장하게 된 배경

Docker를 통해 생성된 Container는 OS가 관리하는 영역과는 별개로

OS의 일부 자원을 할당받은 격리된 공간에서 리소스를 사용할 수 있는 상태로 동작하여

Application의 운영 및 관리의 편의성을 제공함.

 

이런 Container 가 동작할 때 적은 수의 Container는 관리하기가 쉬운 반면

 

Container의 수가 증가할수록 복잡성이 점점 증가함.

 

그렇기 때문에 개발자들은 부분적으로 환경을 공유할 수 있는

Container 그룹을 만들어야 할 필요성을 느낌.

그래서 나온 최초의 Container 그룹의 방법이 바로 linux namespace 상속 방법임.

최초로 부모 Container 의미를 가지는 Container를 1개 생성함

그 이후 생성될 Container는 부모 Container의 IPC, Network, Pid를 상속받아서 생성.

 

예)

  • 부모 Container 생성 

  • 상속받는 Container 생성

 

 

그렇게 되면 생성된 Container 는 모두 linux의 격리된 namespace 안에 그룹화되어 동작함.

이로 인해 자원을 공유할 수 있고 Network 또한 localhost로 통신이 가능해짐.

이런 개념에서 나온 것이 바로 kubernetes의 Pod 임.

그리고 부모 Container 역할을 수행하는 것이 Pause Container 임.

 

 

 

 


 

 

2. Pod안에서 사용자가 Container는 Pause Container의 NameSpace를 상속받았다는 증거자료

 

 

네트워크로 알아보기

참고) 사용자가 생성한 Container의 Network

"container:f2250f04b1bcb7469b030ff03~ = pause Container의 Hash 값.

아래와 같이 NetworkMode 가

host or Nat 가 아닌 Container 임을 확인할 수 있음

 

참고) pause Container의 Network

 

 

 

SandBox Key로 알아보기

worker Node의

경로 : /var/lib/docker/container/

로 이동하면 kubernetes를 통해 생성된 각종 container의 ID로 된 directory 가 있음

해당 directory로 이동해서 config.v2.json 파일을 확인하면 container의 모든 정보를 알 수 있음

 

[Pause Container의 config.v2.json 파일 정보]

 

파란색 부분으로 Pause Container의 ID를 확인

빨간색 부분으로 Pause Container 에는 SandBox Key와 ID를 확인할 수 있음

더보기

{

    "AppArmorProfile": "",

    "Args": [],

    "Config": {

        "AttachStderr": false,

        "AttachStdin": false,

        "AttachStdout": false,

        "Cmd": null,

        "Domainname": "",

        "Entrypoint": [

            "/pause"

        ],

        "Env": [

            "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

        ],

        "Hostname": "iksoon-deployment-66d46db549-qhxbs",

        "Image": "k8s.gcr.io/pause:3.2",

        "Labels": {

            "annotation.kubernetes.io/config.seen": "2020-08-05T08:40:26.901585777+09:00",

            "annotation.kubernetes.io/config.source": "api",

            "app": "iksoon-pod",

            "io.kubernetes.container.name": "POD",

            "io.kubernetes.docker.type": "podsandbox",

            "io.kubernetes.pod.name": "iksoon-deployment-66d46db549-qhxbs",

            "io.kubernetes.pod.namespace": "iksoon-ns",

            "io.kubernetes.pod.uid": "3e7400f5-0bd5-44a5-b6d9-52be0ab203f4",

            "pod-template-hash": "66d46db549"

        },

        "OnBuild": null,

        "OpenStdin": false,

        "StdinOnce": false,

        "Tty": false,

        "User": "",

        "Volumes": null,

        "WorkingDir": "/"

    },

    "Created": "2020-08-04T23:40:27.304439994Z",

    "Driver": "overlay2",

    "HasBeenManuallyStopped": false,

    "HasBeenStartedBefore": true,

    "HostnamePath": "/var/lib/docker/containers/ec1a38e949089e36269a87199c98ab64676ad1306eef4e14e0b4bebb664f9807/hostname",

    "HostsPath": "/var/lib/docker/containers/ec1a38e949089e36269a87199c98ab64676ad1306eef4e14e0b4bebb664f9807/hosts",

    #### 이 정보가 해당 Pause Container의 Container ID ####

    "ID": "ec1a38e949089e36269a87199c98ab64676ad1306eef4e14e0b4bebb664f9807", 

    "Image": "sha256:80d28bedfe5dec59da9ebf8e6260224ac9008ab5c11dbbe16ee3ba3e4439ac2c",

    "LogPath": "",

    "Managed": false,

    "MountLabel": "",

    "MountPoints": {},

    "Name": "/k8s_POD_iksoon-deployment-66d46db549-qhxbs_iksoon-ns_3e7400f5-0bd5-44a5-b6d9-52be0ab203f4_0",

    "NetworkSettings": {

        "Bridge": "",

        "HairpinMode": false,

        "HasSwarmEndpoint": false,

        "IsAnonymousEndpoint": false,

        "LinkLocalIPv6Address": "",

        "LinkLocalIPv6PrefixLen": 0,

        "Networks": {

            "none": {

                "Aliases": null,

                "EndpointID": "fd4b4947a260c500ad0096c4877ccd93cdd8da0531d9bdca643340d88e3de4ea",

                "Gateway": "",

                "GlobalIPv6Address": "",

                "GlobalIPv6PrefixLen": 0,

                "IPAMConfig": null,

                "IPAMOperational": false,

                "IPAddress": "",

                "IPPrefixLen": 0,

                "IPv6Gateway": "",

                "Links": null,

                "MacAddress": "",

                "NetworkID": "03bd379a3deb0905fe8af97ec84516bcf520bae97c22dc0b9badbd6a9a3e968e"

            }

        },

        "Ports": {},

        #### Pause Container의 경우 SandBox ID,Key 정보를 확인 할 수 있음 ####

        "SandboxID": "c49cd99b3b89bee46441bddd59f491599c40d2f74b948fd7ee9775103bd5e7ee",

        "SandboxKey": "/var/run/docker/netns/c49cd99b3b89",

        "SecondaryIPAddresses": null,

        "SecondaryIPv6Addresses": null,

        "Service": null

    },

    "NoNewPrivileges": false,

    "Path": "/pause",

    "ProcessLabel": "",

    "ResolvConfPath": "/var/lib/docker/containers/ec1a38e949089e36269a87199c98ab64676ad1306eef4e14e0b4bebb664f9807/resolv.conf",

    "RestartCount": 0,

    "SeccompProfile": "unconfined",

    "SecretReferences": null,

    "ShmPath": "/var/lib/docker/containers/ec1a38e949089e36269a87199c98ab64676ad1306eef4e14e0b4bebb664f9807/shm",

    "State": {

        "Dead": false,

        "Error": "",

        "ExitCode": 0,

        "FinishedAt": "0001-01-01T00:00:00Z",

        "Health": null,

        "OOMKilled": false,

        "Paused": false,

        "Pid": 17622,

        "RemovalInProgress": false,

        "Restarting": false,

        "Running": true,

        "StartedAt": "2020-08-04T23:40:27.735064933Z"

    },

    "StreamConfig": {}

}

 

[사용자가 생성한 Container의 config.v2.json 파일 정보]

파란색 부분으로 

Pause Container의 ID를 확인하여 Pause Container의 리눅스 커널 namespace를 상속받아서 생성됨을 확인할 수 있음

빨간색 부분으로 사용자가 생성한 Container에는 SandBox Key와 ID가 공백임을 알 수 있음

더보기

{

    "AppArmorProfile": "",

    "Args": [

        "run"

    ],

    "Config": {

        "ArgsEscaped": true,

        "AttachStderr": false,

        "AttachStdin": false,

        "AttachStdout": false,

        "Cmd": [

            "catalina.sh",

            "run"

        ],

        "Domainname": "",

        "Entrypoint": null,

        "Env": [

            "KUBERNETES_SERVICE_HOST=10.96.0.1",

            "KUBERNETES_SERVICE_PORT=443",

            "KUBERNETES_SERVICE_PORT_HTTPS=443",

            "KUBERNETES_PORT=tcp://10.96.0.1:443",

            "KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443",

            "KUBERNETES_PORT_443_TCP_PROTO=tcp",

            "KUBERNETES_PORT_443_TCP_PORT=443",

            "KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1",

            "PATH=/usr/local/tomcat/bin:/usr/local/openjdk-8/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",

            "LANG=C.UTF-8",

            "JAVA_HOME=/usr/local/openjdk-8",

            "JAVA_VERSION=8u242",

            "JAVA_BASE_URL=https://github.com/AdoptOpenJDK/openjdk8-upstream-binaries/releases/download/jdk8u242-b08/OpenJDK8U-jdk_",

            "JAVA_URL_VERSION=8u242b08",

            "CATALINA_HOME=/usr/local/tomcat",

            "TOMCAT_NATIVE_LIBDIR=/usr/local/tomcat/native-jni-lib",

            "LD_LIBRARY_PATH=/usr/local/tomcat/native-jni-lib",

            "GPG_KEYS=05AB33110949707C93A279E3D3EFE6B686867BA6 07E48665A34DCAFAE522E5E6266191C37C037D42 47309207D818FFD8DCD3F83F1931D684307A10A5 541FBE7D8F78B25E055DDEE13C370389288584E7 61B832AC2F1C5A90F0F9B00A1C506407564C17A3 713DA88BE50911535FE716F5208B0AB1D63011C7 79F7026C690BAA50B92CD8B66A3AD3F4F22C4FED 9BA44C2621385CB966EBA586F72C284D731FABEE A27677289986DB50844682F8ACB77FC2E86E29AC A9C5DF4D22E99998D9875A5110C01C5A2F6059E7 DCFD35E0BF8CA7344752DE8B6FB21E8933C60243 F3A04C595DB5B6A5F1ECA43E3B7BBB100D811BBE F7DA48BB64BCB84ECBA7EE6935CD23C10D498E23",

            "TOMCAT_MAJOR=8",

            "TOMCAT_VERSION=8.5.50",

            "TOMCAT_SHA512=ffca86027d298ba107c7d01c779318c05b61ba48767cc5967ee6ce5a88271bb6ec8eed60708d45453f30eeedddcaedd1a369d6df1b49eea2cd14fa40832cfb90"

        ],

        "ExposedPorts": {

            "8080/tcp": {}

        },

        "Healthcheck": {

            "Test": [

                "NONE"

            ]

        },

        "Hostname": "iksoon-deployment-66d46db549-qhxbs",

        "Image": "sha256:51821aad3f0f7c703342355052e8f796e0c99b509c491af98a100174981d72b5",

        "Labels": {

            "annotation.io.kubernetes.container.hash": "1defe9e0",

            "annotation.io.kubernetes.container.ports": "[{\"containerPort\":8080,\"protocol\":\"TCP\"}]",

            "annotation.io.kubernetes.container.restartCount": "0",

            "annotation.io.kubernetes.container.terminationMessagePath": "/dev/termination-log",

            "annotation.io.kubernetes.container.terminationMessagePolicy": "File",

            "annotation.io.kubernetes.pod.terminationGracePeriod": "30",

            "io.kubernetes.container.logpath": "/var/log/pods/iksoon-ns_iksoon-deployment-66d46db549-qhxbs_3e7400f5-0bd5-44a5-b6d9-52be0ab203f4/iksoon-tomcat/0.log",

            "io.kubernetes.container.name": "iksoon-tomcat",

            "io.kubernetes.docker.type": "container",

            "io.kubernetes.pod.name": "iksoon-deployment-66d46db549-qhxbs",

            "io.kubernetes.pod.namespace": "iksoon-ns",

            "io.kubernetes.pod.uid": "3e7400f5-0bd5-44a5-b6d9-52be0ab203f4",

#### pause container의 container ID와 동일한 것을 확인 ####

            "io.kubernetes.sandbox.id": "ec1a38e949089e36269a87199c98ab64676ad1306eef4e14e0b4bebb664f9807" 

        },

        "OnBuild": null,

        "OpenStdin": false,

        "StdinOnce": false,

        "Tty": false,

        "User": "0",

        "Volumes": null,

        "WorkingDir": "/usr/local/tomcat"

    },

    "Created": "2020-08-04T23:40:27.875725311Z",

    "Driver": "overlay2",

    "HasBeenManuallyStopped": false,

    "HasBeenStartedBefore": true,

    "HostnamePath": "/var/lib/docker/containers/ec1a38e949089e36269a87199c98ab64676ad1306eef4e14e0b4bebb664f9807/hostname",

    "HostsPath": "/var/lib/kubelet/pods/3e7400f5-0bd5-44a5-b6d9-52be0ab203f4/etc-hosts",

    "ID": "328d5dd26738707109d6e89972b66158143255e99215d52df51cab33364d8a4e",

    "Image": "sha256:51821aad3f0f7c703342355052e8f796e0c99b509c491af98a100174981d72b5",

    "LogPath": "",

    "Managed": false,

    "MountLabel": "",

    "MountPoints": {

        "/dev/termination-log": {

            "Destination": "/dev/termination-log",

            "Driver": "",

            "Name": "",

            "Propagation": "rprivate",

            "RW": true,

            "Source": "/var/lib/kubelet/pods/3e7400f5-0bd5-44a5-b6d9-52be0ab203f4/containers/iksoon-tomcat/2ab67168",

            "Spec": {

                "Source": "/var/lib/kubelet/pods/3e7400f5-0bd5-44a5-b6d9-52be0ab203f4/containers/iksoon-tomcat/2ab67168",

                "Target": "/dev/termination-log",

                "Type": "bind"

            },

            "Type": "bind"

        },

        "/etc/hosts": {

            "Destination": "/etc/hosts",

            "Driver": "",

            "Name": "",

            "Propagation": "rprivate",

            "RW": true,

            "Source": "/var/lib/kubelet/pods/3e7400f5-0bd5-44a5-b6d9-52be0ab203f4/etc-hosts",

            "Spec": {

                "Source": "/var/lib/kubelet/pods/3e7400f5-0bd5-44a5-b6d9-52be0ab203f4/etc-hosts",

                "Target": "/etc/hosts",

                "Type": "bind"

            },

            "Type": "bind"

        },

        "/var/run/secrets/kubernetes.io/serviceaccount": {

            "Destination": "/var/run/secrets/kubernetes.io/serviceaccount",

            "Driver": "",

            "Name": "",

            "Propagation": "rprivate",

            "RW": false,

            "Relabel": "ro",

            "Source": "/var/lib/kubelet/pods/3e7400f5-0bd5-44a5-b6d9-52be0ab203f4/volumes/kubernetes.io~secret/default-token-ndzh5",

            "Spec": {

                "ReadOnly": true,

                "Source": "/var/lib/kubelet/pods/3e7400f5-0bd5-44a5-b6d9-52be0ab203f4/volumes/kubernetes.io~secret/default-token-ndzh5",

                "Target": "/var/run/secrets/kubernetes.io/serviceaccount",

                "Type": "bind"

            },

            "Type": "bind"

        }

    },

    "Name": "/k8s_iksoon-tomcat_iksoon-deployment-66d46db549-qhxbs_iksoon-ns_3e7400f5-0bd5-44a5-b6d9-52be0ab203f4_0",

    "NetworkSettings": {

        "Bridge": "",

        "HairpinMode": false,

        "HasSwarmEndpoint": false,

        "IsAnonymousEndpoint": false,

        "LinkLocalIPv6Address": "",

        "LinkLocalIPv6PrefixLen": 0,

        "Networks": null,

        "Ports": null,

        ##### SandBox ID와 Key 가 공백임을 확인할 수 있음 ####

        "SandboxID": "",

        "SandboxKey": "",

        "SecondaryIPAddresses": null,

        "SecondaryIPv6Addresses": null,

        "Service": null

    },

    "NoNewPrivileges": false,

    "Path": "catalina.sh",

    "ProcessLabel": "",

    "ResolvConfPath": "/var/lib/docker/containers/ec1a38e949089e36269a87199c98ab64676ad1306eef4e14e0b4bebb664f9807/resolv.conf",

    "RestartCount": 0,

    "SeccompProfile": "unconfined",

    "SecretReferences": null,

    "ShmPath": "/var/lib/docker/containers/ec1a38e949089e36269a87199c98ab64676ad1306eef4e14e0b4bebb664f9807/shm",

    "State": {

        "Dead": false,

        "Error": "",

        "ExitCode": 0,

        "FinishedAt": "0001-01-01T00:00:00Z",

        "Health": null,

        "OOMKilled": false,

        "Paused": false,

        "Pid": 17687,

        "RemovalInProgress": false,

        "Restarting": false,

        "Running": true,

        "StartedAt": "2020-08-04T23:40:28.196694051Z"

    },

    "StreamConfig": {}

}

 

 


제 글을 복사할 시 출처를 명시해주세요.
글에 오타, 오류가 있다면 댓글로 알려주세요! 바로 수정하겠습니다!


 

 

 

 

 

 

참고

pause container

https://blog.naver.com/PostView.nhn?blogId=alice_k106&logNo=221495126401&parentCategoryNo=&categoryNo=20&viewDate=&isShowPopularPosts=false&from=postView

https://timewizhan.tistory.com/entry/Kubernetes-Running-Pods

 

 

 

 

반응형

'클라우드 > Kubernetes' 카테고리의 다른 글

06. Kubernetes Network (ClusterIP, NodePort)  (0) 2020.08.09
05. Kuberentes Network 이론  (2) 2020.08.09
03. Kubernetes 설치 과정  (0) 2020.08.07
02. Kubernetes Addon  (0) 2020.08.05
01. Kubernetes 이론  (8) 2020.08.05