쿠버네티스(kubernetes) (3) - 네임 스페이스 - 파드 - 서비스

Share

Last Updated on 10월 21, 2021 by Jade(정현호)

 

안녕하세요 
이번 포스팅에서는 이전 포스팅에 이어서 리소스, 네임 스페이스, 파드, 서비스에 대해서 확인해보도록 하겠습니다.

해당 포스팅은 아래 포스팅에서 이어지는 글 입니다. 

        

Resource

쿠버네티스에는 수 많은 리소스가 있습니다.
많은 리소스 중에서 자주 사용하는 리소스 위주로 사용법이나 내용을 확인 할 필요가 있습니다.

Resource 에 대한 정보 확인은 kubectl api-resources 를 통해서 확인 할 수 있으며 버전 정보 등도 확인 할 수 있습니다.

[devops@master ~]$ kubectl api-resources
NAME                              SHORTNAMES   APIVERSION                             NAMESPACED   KIND
bindings                                       v1                                     true         Binding
componentstatuses                 cs           v1                                     false        ComponentStatus
configmaps                        cm           v1                                     true         ConfigMap
endpoints                         ep           v1                                     true         Endpoints
events                            ev           v1                                     true         Event
limitranges                       limits       v1                                     true         LimitRange
namespaces                        ns           v1                                     false        Namespace
nodes                             no           v1                                     false        Node
persistentvolumeclaims            pvc          v1                                     true         PersistentVolumeClaim
persistentvolumes                 pv           v1                                     false        PersistentVolume
pods                              po           v1                                     true         Pod
                                    < ... 중략 ... >


리소스 중에서 객체(object) 는 파드(pod), 서비스(service), 볼륨(volume), 네임스페이스(Namespaces) 입니다.
            
       

Namespaces(네임스페이스)

쿠버네티스의 주요 오브젝트 인 네임스페이스에 대한 기본 개념과 생성 과 사용에 대해서 확인 해 보도록 하겠습니다.
      

기본 개념

Namespaces 란 동일한 물리 클러스터를 기반으로 하는 여러 가상 클러스터를 지원하며, 이런 가상 클러스터를 네임스페이스라고 합니다.

쿠버네티스 클러스터내에서 논리적인 분리 단위 이며 쿠버네티스의 Namespace 별로 리소스를 구분되어 있습니다.

Namespace 에 대한 리스트는 아래와 같이 조회 할 수 있습니다.

~$ kubectl get ns
또는 
~$ kubectl get namespace

/home/devops:$ kubectl get ns
NAME              STATUS   AGE
default           Active   55d
kube-node-lease   Active   55d
kube-public       Active   55d
kube-system       Active   55d


기본 네임스페이스는 default 입니다.

모든 리소스를 kubectl 에서 줄여 쓸수는 없고 정해진 리소스만 줄여서 위와 같이 사용할수 있습니다.
해당 목록과 정보는 kubectl api-resources 에서 SHORTNAMES 항목을 참조하면 됩니다.

devops@master ~]$ kubectl api-resources
NAME                              SHORTNAMES   APIVERSION   NAMESPACED   KIND
bindings                                       v1           true         Binding
componentstatuses                 cs           v1           false        ComponentStatus
configmaps                        cm           v1           true         ConfigMap
endpoints                         ep           v1           true         Endpoints
events                            ev           v1           true         Event
limitranges                       limits       v1           true         LimitRange
namespaces                        ns           v1           false        Namespace
                < ... 중략 ... >


namespace 내 같은 이름의 파드는 불가능 하며 다른 네임스페이스라면 같은 이름의 파드를 생성할 수 있습니다.

/home/devops:$ kubectl run mynginx --image=nginx:latest
pod/mynginx created

/home/devops:$ kubectl get pods -o wide
NAME      READY   STATUS              RESTARTS   AGE   IP       NODE      NOMINATED NODE   READINESS GATES
mynginx   0/1     ContainerCreating   0          10s   <none>   worker1   <none>           <none>

/home/devops:$ kubectl run mynginx --image=nginx:latest
Error from server (AlreadyExists): pods "mynginx" already exists
<-- 네임스페이스 안에 같은 이름의 파드는 생성 불가함


네임스페이스 별로 구분 되며, 네임스페이스를 한개의 클러스터로 봐도 될 것 같습니다.

그리고 네임스페이스를 새로 생성 후 그 안에 파드를 만들어서 사용하다가 해당 네임스페이스를 삭제하면 그 안에 있는 파드도 모두 삭제가 되게 됩니다.

네임스페이스 내 리소스는 get all 로 확인 할 수 있습니다.

/home/devops:$ kubectl get all 
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   55d


/home/devops:$ kubectl get all -o wide
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE   SELECTOR
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   55d   <none>



/home/devops:$ kubectl get all -o wide -n default
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE   SELECTOR
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   55d   <none>

-n 은 네임스페이스 약자로 네임스페이스를 지정하는 옵션


다른 네임스페이스의 더 많은 리소스 정보를 확인하고자 할 때는 아래와 같이 네임스페이스를 기재하여 조회 하면 됩니다.

/home/devops:$ kubectl get all -o wide -n kube-system
NAME                                  READY   STATUS    RESTARTS   AGE   IP              NODE      NOMINATED NODE   READINESS GATES
pod/coredns-558bd4d5db-lxkxt          1/1     Running   3          28d   10.38.0.2       master    <none>           <none>
pod/coredns-558bd4d5db-xldsf          1/1     Running   3          28d   10.38.0.1       master    <none>           <none>
pod/etcd-master                       1/1     Running   6          55d   192.168.56.55   master    <none>           <none>
pod/kube-apiserver-master             1/1     Running   6          55d   192.168.56.55   master    <none>           <none>
pod/kube-controller-manager-master    1/1     Running   8          55d   192.168.56.55   master    <none>           <none>
pod/kube-proxy-4ftkg                  1/1     Running   4          55d   192.168.56.56   worker1   <none>           <none>
pod/kube-proxy-f5pk5                  1/1     Running   5          55d   192.168.56.55   master    <none>           <none>
pod/kube-proxy-xqfsx                  1/1     Running   4          55d   192.168.56.57   worker2   <none>           <none>
pod/kube-scheduler-master             1/1     Running   7          55d   192.168.56.55   master    <none>           <none>
pod/metrics-server-75899fbcd5-9zx8t   1/1     Running   1          26d   10.32.0.4       worker2   <none>           <none>
pod/weave-net-hvrkl                   2/2     Running   8          55d   192.168.56.56   worker1   <none>           <none>
pod/weave-net-s9w4h                   2/2     Running   10         55d   192.168.56.55   master    <none>           <none>
pod/weave-net-xnhnz                   2/2     Running   8          55d   192.168.56.57   worker2   <none>           <none>

NAME                     TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                  AGE   SELECTOR
service/kube-dns         ClusterIP   10.96.0.10     <none>        53/UDP,53/TCP,9153/TCP   55d   k8s-app=kube-dns
service/metrics-server   ClusterIP   10.97.38.193   <none>        443/TCP                  48d   k8s-app=metrics-server

NAME                        DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE   CONTAINERS        IMAGES                                                                       SELECTOR
daemonset.apps/kube-proxy   3         3         3       3            3           kubernetes.io/os=linux   55d   kube-proxy        k8s.gcr.io/kube-proxy:v1.21.2                                                k8s-app=kube-proxy
daemonset.apps/weave-net    3         3         3       3            3           <none>                   55d   weave,weave-npc   docker.io/weaveworks/weave-kube:2.8.1,docker.io/weaveworks/weave-npc:2.8.1   name=weave-net

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS       IMAGES                                            SELECTOR
deployment.apps/coredns          2/2     2            2           55d   coredns          k8s.gcr.io/coredns/coredns:v1.8.0                 k8s-app=kube-dns
deployment.apps/metrics-server   1/1     1            1           48d   metrics-server   k8s.gcr.io/metrics-server/metrics-server:v0.5.0   k8s-app=metrics-server

NAME                                        DESIRED   CURRENT   READY   AGE   CONTAINERS       IMAGES                                            SELECTOR
replicaset.apps/coredns-558bd4d5db          2         2         2       55d   coredns          k8s.gcr.io/coredns/coredns:v1.8.0                 k8s-app=kube-dns,pod-template-hash=558bd4d5db
replicaset.apps/metrics-server-75899fbcd5   1         1         1       48d   metrics-server   k8s.gcr.io/metrics-server/metrics-server:v0.5.0   k8s-app=metrics-server,pod-template-hash=75899fbcd5


현재 기본 네임스페이스는 default 이기 때문에 -n 옵션 없이 조회시 default 네임스페이스만 조회됩니다.
또한 이 상태에서 별도 옵션 없이 파드 나 네임스페이스와 종속관게를 가지는 리소스를 생성하면 default 네임스페이스에 생성되게 됩니다.


기본 생성된 네임스페이스는 아래와 같은 기능과 목적을 가지고 있습니다.

default : 다른 네임스페이스가 없는 오브젝트를 위한 기본 네임스페이스

kube-system : 쿠버네티스 시스템에서 생성한 오브젝트를 위한 네임스페이스

kube-public
: 모든 사용자(인증되지 않은 사용자 포함)가 읽기 권한으로 접근할 수 있으며 이 네임스페이스는 주로 전체 클러스터 중에 공개적으로 확인되어 읽을 수 있는 리소스를 위해 예약되어 있습니다.
       

네임스페이스 생성

네임스페이스의 생성은 명령어로 바로 할 수 있으며 또는 yaml 파일 작성하여 생성 할 수도 있습니다.

명령어)
kubectl create namespace[or ns] namespace_이름

~$ kubectl create namespace testns;

네임스페이스 의 이름에는 _(언더바) 사용시 아래와 같이 에러가 발생되며 소문자에 RFC 1123 규칙을 따른다고 되어 있습니다.

The Namespace "...." is invalid: metadata.name: Invalid value: "....":
a lowercase RFC 1123 label must consist of lower case alphanumeric characters
or '-', and must start and end with an alphanumeric character
(e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')

              

yaml 파일을 통해 생성

네임스페이스는 yaml 파일을 통해서도 생성이 가능합니다.

vim 으로 yaml 파일을 작성할 때 2칸(스페이스 2칸) 으로 들여쓰기를 한다던지 몇가지 yaml 파일 작성에 필요한 vim 환경 설정이 있습니다.
그래서 포스팅에서는 먼저 아래와 같이 사용하는 일반 유저의 vimrc 환경설정 파일에 설정을 하고 진행하도록 하겠습니다.

/home/devops:$ vim ~/.vimrc


autocmd FileType yaml setlocal ts=2 sts=2 sw=2 expandtab paste


.vimrc 에서 위의 내용을 입력 합니다

포스팅 환경에서는 work 디렉토리를 생성하고 work 디렉토리 안에 파일을 생성하여 사용하였습니다.
yaml 파일은 아래와 같이 작성을 하면 됩니다.

/home/devops:$ mkdir -p work
/home/devops:$ cd work


/home/devops:$ vi workns.yaml


---
apiVersion: v1
kind: Namespace
metadata: 
  name: workns


yaml 파일은 대소문자를 구분 하기 때문에 지켜야 합니다. 또한 들여쓰기(tab) 을 잘 지켜야 합니다.
그리고 yaml 파일에는 딕셔너리 와 리스트 타입이 있습니다.


• 딕셔너리

콜론(:) 기준으로 왼쪽을 키(key) 라고 하고 오른쪽은 값(value) 라고 하며 딕셔너리 라고 합니다.
또는 해시, 연관 배열 이라고도 합니다.

딕셔너리는 중괄호를 사용 합니다.
key : value
{"key": "value", "key2": "value2}


• List
list => [ "unix","linux","ms"]
대괄호를 사용합니다.

-(대시) 는 list 이며, 일반 배열 입니다.
- unix
- linux
- ms

기본적으로 4가지가 들어가며 대소문자를 구별하고 apiVersion, kind , metadata 는 필수로 들어가며 spec 은 리소스에 따라서 달라집니다.


yaml 파일 작성시 조회 결과에서 APIVERSION 의 버전 값이 yaml 파일의 키 apiVersion 의 value 에 들어가게 되고 KIND 컬럼 값이 yaml 파일에서 키 kind 의 value 에 들어가면 됩니다.

api-resources 는 아래와 같이 조회할 수 있습니다.

/home/devops/work:$ kubectl api-resources | grep -i namespace
NAME        SHORTNAMES   APIVERSION  NAMESPACED   KIND
namespaces  ns           v1          false        Namespace


metadata:
  name: testns

name 은 생성할 네임스페이스 이름 을 기재 하면 됩니다.

yaml 파일로 객체나 리소스 생성시 kubectl create 와 apply 를 사용할 수 있으며, 수정 하고 실행을 할 경우 apply 를 사용 해야 합니다.

create 는 생성하는 것이라서 수정하고 다시 생성시 create 를 사용하면 에러가 발생됩니다. 수정한 것을 다시 적용할 때는 apply 를 사용해야 합니다.

/home/devops/work:$ kubectl create -f testns.yaml
namespace/testns created


/home/devops/work:$ kubectl get ns
NAME              STATUS   AGE
default           Active   56d
kube-node-lease   Active   56d
kube-public       Active   56d
kube-system       Active   56d
testns            Active   10s
workns            Active   11h

                 

네임스페이스 삭제

네임스페이스 삭제는 아래와 같이 할 수 있습니다.

명령어)
kubectl delete namespace[or ns] namespace_이름

kubectl delete namespace testns;

네임스페이스를 삭제하면 그 안에 있는 파드나 속해있는 리소스나 객체 등은 모두 삭제가 되게 됩니다.

네임스페이스 삭제시 주의 할 점은 쿠버네티스 설치시 같이 생성되는 kube-system namespace 를 삭제하게 되면 쿠버네티스 클러스터 사용이 불가함으로 삭제를 해서는 안됩니다.
             

활성화 네임스페이스 변경

쿠버네티스에서 네임스페이스 생성 및 삭제는 어려운 것은 아니지만, 현재 사용중인(활성화된) 기본 네임스페이스를 변경하는 커맨드가 조금은 길고 어려운 부분이 있습니다.

아래와 같이 활성화 선호 네임스페이스를 변경할 수 있습니다.

명령어 예시)
kubectl config set-context --current --namespace=<insert-namespace-name-here>

-- workns 네임스페이스로 변경
~$ kubectl config set-context --current --namespace=workns
Context "kubernetes-admin@kubernetes" modified.


이후 kubectl 의 명령 처리 시 변경한 네임스페이스에서 수행되게 됩니다.(리소스의 생성 등)

현재 활성화된 네임스페이스 확인은 config view 를 통해서 할 수 있습니다.

/home/devops:$ kubectl config view | grep namespace
    namespace: workns


위에서 기본 네임스페이스를 변경 하였고 다시 파드를 조회를 해봅니다.

/home/devops:$ kubectl get pods -o wide
No resources found in workns namespace.


이전에 생성한 mynginx 라는 파드가 보이지 않는 이유는 설명한 내용과 같이 네임스페이스 별로 리소스(파드를 포함한 여러가지)가 논리적으로 구분되기 때문 입니다.
그래서 새로 생성한 workns 라는 네임스페이스 에서 파드를 생성한 적이 없기 때문에 당연히 파드가 없는 상태 인 것 입니다.

-n 으로 해서 default 네임스페이스 지정해서 조회하면 이전에 생성한 파드가 조회되는 것을 확인 할 수 있습니다.

/home/devops:$ kubectl get pods -o wide -n default
NAME      READY   STATUS    RESTARTS   AGE    IP          NODE      NOMINATED NODE   READINESS GATES
mynginx   1/1     Running   0          5h8m   10.40.0.1   worker1   <none>           <none>

                

네임스페이스와 리소스 연관성

리소스 중에서는 네임스페이스에 영향을 받는 리소스와 영향을 받지 않는 리소스로 나눌수 있습니다.

kubectl api-resources 로 리소스를 조회해보면 아래와 같은 조회 결과에서 NAMESPACED 컬럼 값을 확인 하면 됩니다.

/home/devops:$ kubectl api-resources
NAME                              SHORTNAMES   APIVERSION                             NAMESPACED   KIND
bindings                                       v1                                     true         Binding
componentstatuses                 cs           v1                                     false        ComponentStatus
configmaps                        cm           v1                                     true         ConfigMap
endpoints                         ep           v1                                     true         Endpoints
events                            ev           v1                                     true         Event
limitranges                       limits       v1                                     true         LimitRange
namespaces                        ns           v1                                     false        Namespace
nodes                             no           v1                                     false        Node
persistentvolumeclaims            pvc          v1                                     true         PersistentVolumeClaim
persistentvolumes                 pv           v1                                     false        PersistentVolume
pods                              po           v1                                     true         Pod


true 로 되어있는 리소스는 네임스페이스에 연관 되어있는 것이며 영향을 받는 리소스이고, false 는 영향 받지 않는 리소스 입니다.

대표적인 리소스인 pods 를 보면 NAMESPACED=true 로 되어있기 때문에 네임스페이스에 영향을 받는 연관이 되어있는 리소스이고 그렇기 때문에 네임스페이스를 구분하여 실행 할 수 있습니다.

false 되어있는 리소스는 네임스페이스에 영향받지 않기 때문에 어느 네임스페이스에서 작업하더라도 같다 라는 것 입니다.

네임스페이스는 자유롭게 사용하여도 됩니다 다만 선택해서 사용하지 않아야 할 네임 스페이스가 있습니다.
아래 3개의 네임스페이스는 사용하지 않는 것이 좋습니다.

kube-node-lease
kube-public
kube-system
               

파드(pods)

이번에는 쿠버네티스의 주요 객체인 파드(pods) 에 대해서 확인 해보도록 하겠습니다
                   

파드 개요

파드(Pod) 는 쿠버네티스에서 생성하고 관리할 수 있는 배포 가능한 가장 작은 컴퓨팅 단위 입니다.

파드 (고래 떼(pod of whales)나 콩꼬투리(pea pod)와 마찬가지로)는 하나 이상의 컨테이너의 그룹입니다.
즉 파드안에 컨테이너가 1개 또는 1개 이상이 포함되어 있다는 의미 입니다.

이 그룹은 스토리지 및 네트워크를 공유하고, 해당 컨테이너를 구동하는 방식에 대한 명세 또는 정의를 갖게 됩니다.
파드의 콘텐츠는 항상 함께 배치되고, 함께 스케줄되며, 공유 콘텍스트에서 실행되게 됩니다.

쿠버네티스에서 애플리케이션을 사용하게 되는 객체(object) 이고 기본이자 가장 중요 객체 입니다.
[참고] 도커(Docker)가 가장 일반적으로 잘 알려진 컨테이너 런타임이지만, 쿠버네티스는 도커 외에도 다양한 컨테이너 런타임을 지원합니다.


쿠버네티스 클러스터의 파드는 두 가지 주요 방식으로 사용 됩니다

단일 컨테이너를 실행하는 파드

"파드 당 하나의 컨테이너" 모델은 가장 일반적인 쿠버네티스 유스케이스입니다. 이 경우는 파드를 단일 컨테이너를 둘러싼 래퍼(wrapper)로 생각할 수 있습니다. 쿠버네티스는 컨테이너를 직접 관리하는 대신 파드를 관리합니다.


함께 작동해야 하는 여러 컨테이너를 실행하는 파드

파드는 밀접하게 결합되어 있고 리소스를 공유해야 하는 함께 배치된 여러 개의 컨테이너로 구성된 애플리케이션을 캡슐화할 수 있습니다
이런 함께 배치된 컨테이너는 하나의 결합된 서비스 단위를 형성하게 됩니다.

예를 들어, 하나의 컨테이너는 공유 볼륨에 저장된 데이터를 퍼블릭에 제공하는 반면, 별도의 사이드카 컨테이너는 해당 파일을 새로 고치거나 업데이트 합니다.
파드는 이러한 컨테이너, 스토리지 리소스, 임시 네트워크 ID를 단일 단위로 함께 래핑 합니다.
       

파드 생성/실행

파드 실행은 명령어로 직접 실행 하는 것 과 yaml 파일을 통한 실행 방법이 있습니다.

먼저 커맨드 라인에서 실행하는 방법에 대해서 확인 해보도록 하겠습니다.

     

명령어로 실행

명령어)
kubectl run 파드이름 --image=도커이미지


/home/devops/work:$ kubectl run mynginx --image=nginx:latest

/home/devops/work:$ kubectl get pods -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP          NODE      NOMINATED NODE   READINESS GATES
mynginx   1/1     Running   0          14s   10.40.0.1   worker1   <none>           <none>


[참고] 현재 활성화 네임스페이스 확인은 config view 를 통해서 할 수 있습니다.

~$ kubectl config view | grep namespace
    namespace: workns


worker1 노드에서 docker 에서 조회하면 아래와 같이 생성한 mynginx 컨테이너를 확인 할 수 있습니다.

[devops@worker1 ~]$ docker ps
CONTAINER ID   IMAGE   COMMAND                  CREATED          STATUS         PORTS  NAMES
af3a5189e2f7   nginx   "/docker-entrypoint.…"   16 minutes ago   Up 16 minutes         k8s_mynginx_mynginx_workns_6d92e9fd-f7ed-421b-adce-af337dc4c7bf_0


다른 네임스페이스에 파드를 실행 할 때에는 아래와 같이 실행 하면 됩니다.

명령어)
kubectl run 파드이름 --image=이미지명 --namespace=<insert-namespace-name-here>
kubectl get pods --namespace=<insert-namespace-name-here>


~$ kubectl run mynginx2 --image=nginx:latest --namespace=testns
~$ kubectl get pods --namespace=testns


모든 네임스페이스 내 모든 파드의 목록 조회는 아래와 같이 할 수 있습니다.

~$ kubectl get pods --all-namespaces

                

yaml 파일로 실행

위와 같이 명령어 와 옵션을 직접 입력 하여 파드를 실행 할 수도 있지만 yaml 파일을 작성하여 파드를 실행 할 수 있습니다.

이번에는 yaml 파일로 생성 하여 파드를 실행해 보도록 하겠습니다.
포스팅에서는 nginx_pod.yaml 라는 파일명으로 nginx 컨테이너 이미지를 통한 파드를 실행 해보도록 하겠습니다.

/home/devops/work:$ vi nginx_pod.yaml


apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: myweb
spec:
  containers:
  - name: myweb-container
    image: nginx:latest 
    ports:
    - containerPort: 80


대소문자를 구별하고 apiVersion, kind , metadata 는 필수로 들어가며 spec 은 리소스에 따라서 달라집니다.

metadata 에 종속 관계에는 name, labels 이 있으며 app 는 labels 에 종속 관계 입니다

labels 에서는 자유롭게 key : value 를 지정하여 사용할 수 있습니다.
- 는 종속 관계를 의미 합니다.

containerPort 는 정해진 것이라 변경 할 수 없습니다.
spec 에는 컨테이너 정보를 입력 합니다.

파일로 생성시 create 나 apply 로 하면 되며 -f 뒤에는 파일명을 입력 합니다.

/home/devops/work:$ kubectl apply -f nginx_pod.yaml

/home/devops/work:$ kubectl get pods -o wide
NAME        READY   STATUS    RESTARTS   AGE    IP          NODE      NOMINATED NODE   READINESS GATES
mynginx     1/1     Running   0          101m   10.40.0.1   worker1   <none>           <none>
nginx-pod   1/1     Running   0          8m6s   10.40.0.2   worker1   <none>           <none>


실행되는 워커노드에서 도커로 확인을 해보도록 하겠습니다.

[devops@worker1 ~]$ docker ps
CONTAINER ID   IMAGE  COMMAND                  CREATED         STATUS         PORTS  NAMES
23b0c3be04a8   nginx  "/docker-entrypoint.…"   8 minutes ago   Up 8 minutes          k8s_myweb-container_nginx-pod_workns_3cd5466c-40d5-4dde-b816-d800527d4f6f_0


위에서 작성한 yaml 파일에서 spec 항목에 입력한 name: myweb-container 이 컨테이너 이름으로 사용되는 것을 확인 할 수 있습니다.
           

파드의 라이프사이클(Lifecycle)

파드는 정의된 라이프사이클 을 따르게 됩니다.

Pending 단계에서 시작해서, 기본 컨테이너 중 적어도 하나 이상이 OK로 시작하면 Running 단계를 통과하고, 그런 다음 파드의 컨테이너가 실패로 종료되었는지 여부에 따라 Succeeded 또는 Failed 단계로 이동하게 됩니다.


Pending 단계에서 다음 단계로 넘어가야 하며 넘어가지 못하면 계속 Pending 상태로 남아있게 되고 문제가 있는 것임으로 로그 등을 확인이나 체크를 해봐야 합니다.
Pending 단계에서 문제가 없다면 Running 단계로 넘어가게 됩니다.

Running 단계에서도 다시 failed 상태가 될 수도 있습니다. 그럼 Running 상태로 만들기 위해서 failed 에서 실행을 하여 Running 단계를 만들게 됩니다.
Running 단계라도 지속 가능한 상태가 되어야 하나 어떠한 경우에는 2-3초 가량만 지속 가능 상태로 인하여 failed 되는 경우도 있습니다.

문제가 있다면 failed 상태가 되게 되고 Running 단계에서 Succeeded 로 되기전까지 이 과정이 계속 반복 될 수 있습니다
(Running -> failed -> Running -> failed ... 반복)

파드의 status 필드는 phase value 가 표기되고 파드의 phase는 파드가 라이프사이클 중 어느 단계에 해당하는지 그리고 의미는 아래의 상세내용을 확인 하시면 됩니다.


Pending
파드가 쿠버네티스 클러스터에서 승인 되었지만, 하나 이상의 컨테이너가 설정되지 않았고 실행할 준비가 되지 않았습니다.
여기에는 파드가 스케줄되기 이전까지의 시간 뿐만 아니라 네트워크를 통한 컨테이너 이미지 다운로드 시간도 포함됩니다.


Running
파드가 노드에 바인딩되었고, 모든 컨테이너가 생성되었습니다. 적어도 하나의 컨테이너가 아직 실행 중이거나, 시작 또는 재시작 중임을 의미 합니다.

Succeeded
파드에 있는 모든 컨테이너들이 성공적으로 종료 되었고, 재시작되지 않을 것입니다.

Failed
파드에 있는 모든 컨테이너가 종료되었고, 적어도 하나 이상의 컨테이너가 실패로 종료되었습니다.
즉, 해당 컨테이너는 non-zero 상태로 빠져나왔거나(exited) 시스템에 의해서 종료(terminated) 되었음을 의미합니다.


Unknown
어떤 이유에 의해서 파드의 상태를 얻을 수 없는 상태 입니다. 이 단계는 일반적으로 파드가 실행되어야 하는 노드와의 통신 오류로 인해 발생 하게 됩니다.
             

파드 접속

먼저 docker 와 동일하게 터미널에서 파드 내부로 들어갈 수 있습니다.

docker 에서도 exec -it 명령어를 통해서 도커 컨테이너 내부로 들어갈 수 있는 것처럼 쿠버네티스 에서도 동일하게 파드 내부로 들어갈 수 있습니다.

아래 명령어 를 통해 파드 내부로 들어갈 수 있습니다.

명령어)
/home/devops/work:$ kubectl exec -it 파드명 /bin/bash 


/home/devops/work:$ kubectl exec -it nginx-pod /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. 
Use kubectl exec [POD] -- [COMMAND] instead.

root@nginx-pod:/# 
root@nginx-pod:/# exit


이제 생성한 파드에 네트워크로 접속이 가능한지 curl 로 확인 해보겠습니다.
접속 하기 위해서는 IP를 알아야 하며 get pods 를 통해서 확인 할 수 있습니다.

/home/devops/work:$ kubectl get pods -o wide
NAME         READY   STATUS    RESTARTS   AGE   IP          NODE      NOMINATED NODE   READINESS GATES
nginx-pod    1/1     Running   1          28d   10.40.0.2   worker1   <none>           <none>


/home/devops/work:$ curl 10.40.0.2
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
< ... 중략 ...>


80포트로 정상적으로 접속되어 html 내용이 확인 되고 있습니다.
하지만 지금의 설정에서는 외부(마스터,워커노드가 아닌) 에서 접속을 하면 접속이 되지 않습니다.
접속을 위해서는 다음 과정에서 확인 할 수 있는 서비스 오브젝트를 통해서 가능 합니다.
                 

파드 수정

실행 중인 파드에 대해서 이름이나 label 이나 컨테이너 이름 또는 변경 가능한 항목에 대해서 수정을 하려고 할 경우 2가지 방법을 통해서 진행할 수 있습니다.
             

yaml 파일을 통한 수정

yaml 파일을 통해 생성한 파드라면 생성에 사용한 yaml 파일을 통해서 수정할 수 있습니다.

예제에서는 label 이 app: mynginx 인 파드 정보에서 label 정보를 변경 해보도록 하겠습니다.

/home/devops/work:$ kubectl describe pods mynginx
Name:         mynginx
Namespace:    workns
Priority:     0
Node:         worker1/192.168.56.56
Labels:       app=mynginx  <--


yaml 파일을 편집기(vim 등) 로 수정 합니다.

/home/devops/work:$ vi nginx.yaml

labels:
  app: mynginx

to

labels:
  app: mynginx2


yaml 파일을 수정하였다면 apply 를 실행 하면 되며, descibe 다시 조회해보면 label 이 변경된 것을 확인 할 수 있습니다.

/home/devops/work:$ kubectl apply -f nginx.yaml
pod/mynginx configured

/home/devops/work:$ kubectl describe pods mynginx
Name:         mynginx
Namespace:    workns
Priority:     0
Node:         worker1/192.168.56.56
Labels:       app=mynginx2

              

kubectl edit 로 수정

kubectl edit 명령어로도 수정 할 수 있습니다.
edit 옵션으로 수정 시에는 yaml 파일 형식 또는 json 형식으로 수정 할 수 있습니다.

~$ kubectl edit pods mynginx

또는 

~$ kubectl edit pods mynginx -o json


명령어를 수행하여 편집기에서 다시 label 값을 app: mynginx 으로 변경 후 저장하였습니다.
kubectl edit 명령어 옵션은 편집기에서 수정 후 저장하고 종료하면 바로 적용(반영) 됩니다.

/home/devops/work:$ kubectl describe pods mynginx
Name:         mynginx
Namespace:    workns
Priority:     0
Node:         worker1/192.168.56.56
Labels:       app=mynginx

                        

파드 삭제

사용중인 파드 삭제는 delete 옵션을 통해서 할 수 있습니다.

명령어)
kubectl delete pod 파드명


~$ kubectl delete pod mynginx

or

~$ kubectl delete pod mynginx -n default

or

~$ kubectl delete pod mynginx -n default --force


삭제시 수행중인 작업 중이 있다면 gracefully 가 되도록 시간이 부여가 되며 그 기본값은 30초 입니다.
그 시간 전에(30초 전에) 또는 30초 이후에도 종료가 되지 않을 경우 --force 플래그를 사용하여 강제로 삭제를 할 수 있습니다.

yaml 파일로 생성한 리소스는 yaml 파일명으로 삭제도 가능 합니다.

~$ kubectl delete -f nginx.yaml 
pod "nginx-pod" deleted


yaml 파일을 지정하여 삭제 할 경우 당연히 명령어를 실행하는 디렉토리에 위치에 yaml 파일이 존재 해야 합니다.
                 

서비스(Service)

파드 집합에서 실행중인 애플리케이션을 네트워크 서비스로 노출하는 추상화 방법으로 쿠버네티스에서 서비스는 파드의 논리적 집합과 그것들에 접근할 수 있는 정책을 정의하는 추상적 개념 입니다.

쿠버네티스는 파드에게 고유한 IP 주소와 파드 집합에 대한 단일 DNS 명을 부여하고, 그것들 간에 로드-밸런스를 수행할 수 있습니다.

이전 단계에서 네임스페이스와 파드를 생성하였고 지정된 파드 IP 에 대해서 curl 명령어를 사용하여 접속이 되는 것을 확인 하였습니다.

현재 설정에서는 쿠버네티스 클러스터 내에서만 접속이 가능한 상태로 외부에서 접속을 하기 위해서는 서비스 오브젝트를 생성해서 사용을 해야 합니다.

그리고 서비스를 통해서 파드가 외부와 통신을 하려면 파드 실행시 label 정보가 입력 되어야 합니다. label 이 없다면 외부에서 접속을 할수가 없습니다.

명령어로 파드를 실행하면 run: 파드이름 형태로 label 이 지정 됩니다.
yaml 로 생성시 명시적으로 label 을 지정하지 않으면 label 정보가 없어서 접속을 할 수 없습니다. 

/home/devops/work:$ kubectl describe pods test-nginx
Name:         test-nginx
Namespace:    workns
Priority:     0
Node:         worker1/192.168.56.56
Labels:       <none>  <-- yaml 파일에서 label 정보 미입력시


테스트를 위해서 이전 단계에서 사용한 파드 실행 yaml 파일을 복사 후 수정하여 파드를 1개 더 추가 하도록 하겠습니다.

home/devops/work:$ cp -rp nginx.yaml nginx2.yaml

/home/devops/work:$ vi nginx2.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod2
  labels:
    app: myweb
spec:
  containers:
  - name: myweb-container
    image: nginx:latest 
    ports:
    - containerPort: 80


metadata 에서 name 만 변경 하였습니다. 파드를 실행하도록 하겠습니다.

/home/devops/work:$ kubectl create -f nginx2.yaml

/home/devops/work:$ kubectl get pods -o wide
NAME         READY   STATUS    RESTARTS   AGE   IP          NODE      NOMINATED NODE   READINESS GATES
nginx-pod    1/1     Running   1          27d   10.40.0.2   worker1   <none>           <none>
nginx-pod2   1/1     Running   0          73s   10.32.0.3   worker2   <none>           <none>

              

서비스 생성 - 클러스터IP

yaml 파일을 작성하여 서비스를 생성 하도록 하겠습니다.

/home/devops/work:$ vi nginx_service.yaml


---
apiVersion: v1
kind: Service
metadata:
  name: mynginx-service
spec:
  ports:
  - name : mynginx-service-port
    port: 8001


yaml 파일 설명

--- 는 1개의 yaml 파일에 여러개 내용을 기재 할 경우 구분하기 위해서 사용 합니다.
1개만 정의 할 때는 생략해서 사용할 수 있습니다.

spec 에 기재된 port 는 컨테이너에서 오픈된 포트가 아니고 서비스 오브젝트의 오픈 포트 번호 입니다.
Port 에 대해서 이름을 지정 할 수 있으며, 어떤 용도 등인지 식별이나 확인을 하는 용도로 이름을 지정하는 것을 사용할 수 있습니다.
이름(name)은 필수는 아닙니다.

yaml 파일 작성이 완료 되었다면 서비스를 생성 합니다.

/home/devops/work:$ kubectl create -f nginx_service.yaml
service/mynginx-service created


생성한 서비스를 조회해 보도록 하겠습니다.

/home/devops/work:$ kubectl get svc -o wide
NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE   SELECTOR
mynginx-service   ClusterIP   10.109.144.129   <none>        8001/TCP   25s   <none>


kubectl get 또는 get service 를 통해서 조회 해볼 수 있으며 Cluster-IP 정보 와 Port 정보를 확인 할 수 있습니다.
여기서 조회되는 IP 는 클러스터 IP 입니다.

그런데 이렇게 생성한 서비스로는 파드에 접속할 수 없습니다.
이유는 위에서 생성한 서비스에는 연결되는 파드 정보가 없어서 입니다.

/home/devops/work:$ curl 10.109.144.129:8001
curl: (7) Failed connect to 10.109.144.129:8001; Connection refused


다시 yaml 파일을 수정 해보도록 하겠습니다.

/home/devops/work:$ vi nginx_service.yaml


---
apiVersion: v1
kind: Service
metadata:
  name: mynginx-service
spec:
  ports:
  - name : mynginx-service-port
    port: 8001
    targetPort: 80
  selector:
    app: myweb


이전 yaml 파일과의 차이점은 아래와 같은 내용이 추가 되었습니다.

  targetPort: 80
selector:
  app: myweb


먼저 서비스에서 접속하는 파드의 Listen 포트 번호를 지정하는 targetPort 내용이 더 추가 되었으며, selector 내용이 추가 되었습니다.
 

selector 에는 서비스에서 연결을 원하는 파드의 label 명을 지정하면 됩니다.
서비스에서 파드와 연결 될 때 label 을 보고 식별하여 연결되게 됩니다.

/home/devops/work:$ kubectl get pods --show-labels
NAME        READY   STATUS    RESTARTS   AGE   LABELS
nginx-pod   1/1     Running   1          27d   app=myweb


수정한 yaml 파일을 통해서 서비스를 수정하도록 합니다. apply 옵션을 사용하면 됩니다.

/home/devops/work:$ kubectl apply -f nginx_service.yaml


apply 시 발생되는 경고는 무시하셔도 됩니다.

서비스를 다시 한번 조회해 보겠습니다.

/home/devops/work:$ kubectl get svc -o wide
NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE   SELECTOR
mynginx-service   ClusterIP   10.109.144.129   <none>        8001/TCP   17m   app=myweb


kubectl get svc 에서는 targetPort 정보나 기타 정보는 확인 되지 않습니다. 자세한 정보는 describe 를 통해서 확인 할 수 있습니다.

/home/devops/work:$ kubectl describe svc mynginx-service 
Name:              mynginx-service
Namespace:         workns
Labels:            <none>
Annotations:       <none>
Selector:          app=myweb
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.109.144.129
IPs:               10.109.144.129
Port:              mynginx-service-port  8001/TCP
TargetPort:        80/TCP
Endpoints:         10.32.0.3:80,10.40.0.2:80
Session Affinity:  None
Events:            <none>


describe svc 를 통해서 확인 해보면 targetPort 정보가 확인되며, Endpoints 는 최종 접속 되는 파드 ip 를 의미 합니다.
위에서 라벨이 같은 파드를 2개 실행 하였습니다.

labels:
  app: myweb

Endpoints 에 2개의 IP 가 보이는 것은 라벨이 같은 2개의 파드로 접속이 된다는 의미 이고 라운드로빈 방식으로 접속하게 됩니다.
서비스를 다시 생성 하였음으로 curl 을 통해서 접속이 되는지를 확인 해보겠습니다.

/home/devops/work:$ curl 10.109.144.129:8001
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
< ... 중략 ...>

               

클러스터IP 와 Endpoint IP

위에서 curl 로 조회를 한 것은 마스터 노드에서 실행을 한 것이고 쿠버네티스 클러스트가 아닌 외부 서버나 PC 등에서는 여전히 접속이 불가능한 상태 입니다.

curl 로 조회한 10.109.144.129 IP 는 클러스터 IP 입니다 즉 쿠버네티스 클러스터 내 노드에 접속을 하기 위한 IP 로 여러 노드를 접속 하는데 사용 합니다.

describe 에서 endpoints 가 여러개 확인 되는 것 처럼 클러스터 IP는 다수의 파드를 접속하기 위한 단일 접속 IP 라고 생각 하면 됩니다.

[theithollow.com/kubernetes-service-publishing]


현재 구성과 접속한 내용은 위의 이미지에서 User Request 가 Cluster IP 로 접속을 할 수 있게 설정된 상태이고 curl 명령어를 통해서 Cluster IP 와 설정된 Port 8001 로 접속을 한 것 입니다.

클러스터 IP 와 지정된 포트 번호로 접속을 하게 되면 서비스에서 정의된 파드의 label 과 targetPort 정보를 따라서 endpoint 로 접속을 하게 되는 것 입니다.
그래서 현재는 클러스터에서는 접속이 되지만 여전히 외부에서는 접속이 되지 않은 상태 입니다.


yaml 파일을 수정하면서 추가 된 내용과 같이 selector 가 필요하며 selector 에서 지정된 label 을 확인하여 해당 label 의 파드의 Endpoint 로 접속을 하는 내용을 아래 그림에서는 표현되어 있습니다.


[kubernetes.io/expose-intro]

                     

NodePort

쿠버네티스 클러스트가 아닌 외부에서 파드로 접속이 가능하도록 다시 설정을 변경 해보도록 하겠습니다.

생성한 서비스의 수정을 위해서 yaml 파일을 수정 후 kubectl apply 를 통해 적용 하였습니다.

kubectl apply 를 통해 변경할 수 있지만 kubectl edit 명령어 옵션을 통해서도 실행 중인 서비스를 변경 할 수 있으며, 리소스의 메타데이터 정보를 가져와서 yaml 형식 출력 및 수정 할 수 있게 해줍니다(또는 옵션에 따라서 json 으로 출력)

kubectl edit 를 통해 수정 하도록 하겠습니다 yaml 형식이나 json 형식으로 수정 할 수 있습니다.

~$ kubectl edit svc mynginx-service


json 파일 형식으로 하고자 할 때는 아래와 같이 -o 를 사용하면 됩니다.
~$ kubectl edit svc mynginx-service -o json


selector:
  app: myweb
sessionAffinity: None
type: NodePort
  <---- ClusterIP 에서 NodePort 로 변경 하였습니다.


vi 에서 저장 및 종료 한 다음 다시 서비스를 조회를 해봅니다

/home/devops/work:$ kubectl get svc -o wide
NAME              TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE   SELECTOR
mynginx-service   NodePort   10.109.144.129   <none>        8002:31188/TCP   10h   app=myweb


클러스터IP 와 포트는 그대로 이고 새로운 31188 라는 포트가 새로 보입니다.

31188 포트는 노드포트가 되는 것 입니다.

8002               :    31188
클러스터 포트   :    노드포트


describe 명령어로 확인 해보도록 하겠습니다.

/home/devops/work:$ kubectl describe svc mynginx-service 
Name:                     mynginx-service
Namespace:                workns
Labels:                   <none>
Annotations:              <none>
Selector:                 app=myweb
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.109.144.129
IPs:                      10.109.144.129
Port:                     mynginx-service-port  8002/TCP
TargetPort:               80/TCP
NodePort:                 mynginx-service-port  31188/TCP <-- 추가되었음
Endpoints:                10.32.0.3:80,10.40.0.2:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>


이제 외부에서 접속하기 위해서는 NodeIP 를 통해서 접속하면 되며 포트는 31188 를 사용하면 됩니다.
포스팅에서는 마스터 1대, 워커노드2대 총 3대 이며 3개의 노드에서 어떤 IP 를 통해서도 접속 할 수 있습니다.

마스터의 IP는 192.168.56.55 로 파드가 실행되지 않고 있으나 클러스터로 묶여 있기 때문에 접속을 하여도 접속이 됩니다.
3대(마스터1,워커노드2) 중 어떠한 노드 IP 를 사용하여 접속하면 접속이 됩니다

물론 포트번호는 확인되는 31188 로 접속 해야 합니다.


마스터, 워커노드 2대 모두에서 접속이 가능 한 것을 확인 할 수 있습니다.

이렇게 외부에서 접속 가능한 방법은 NodePort 이외 몇 가지 방법이 더 있으며 다음 포스팅 에서 계속 확인 해보도록 하겠습니다.

                         

Reference

Reference Link
 • kubernetes.io/pods
 • kubernetes.io/service
 • kubernetes.io/expose-intro
 • theithollow.com/kubernetes-service-publishing



연관된 다른 글

              

0
글에 대한 당신의 생각을 기다립니다. 댓글 의견 주세요!x