IT/Kubernetes

[Kubernetes] Kubernetes Study: "기본 오브젝트 - Pod"

wookiist 2021. 6. 27. 13:56

Prologue

본 포스트는 인프런 쿠버네티스 스터디 그룹에서 진행하는 스터디 자료의 일환으로 작성하였습니다. 기본적으론 [대세는 쿠버네티스] 강의를 보고 내용을 정리합니다. 그리고 제 경험이나 이해를 곁들여 포스트를 작성했습니다. 그동안 공식 문서나 블로그 포스트, CKA 강의 등 다양한 경로로 쿠버네티스를 익혀왔지만, 한국어로 잘 정리된 강좌를 한번 듣고 깔끔하게 다듬어보는 시간을 가지면 좋겠다는 생각이 들었습니다.

강의와는 조금 다를 수 있지만, 쿠버네티스 공식 문서를 보고 내용을 정리해보겠습니다.

이번 포스트에선 "기본 오브젝트 - Pod"를 다뤄봅니다.

Kubernetes Object

공식 문서에 따르면 쿠버네티스 오브젝트는 쿠버네티스 시스템에서 영속성을 가지는 오브젝트이며, 쿠버네티스는 클러스터의 상태를 나타내기 위해 이 오브젝트를 사용한다 정의합니다.

영속성을 가지는 오브젝트라는 것은 무엇일까요? 우리가 배포하고자 하는 모든 애플리케이션이 영속성을 갖는 오브젝트가 될 수 있습니다. 일반적으로 애플리케이션을 배포할 때는 애플리케이션을 제거할 계획을 갖고 배포하지 않습니다. 또한 애플리케이션을 배포할 땐, 어떠한 상황에도 이 애플리케이션이 멈추지 않고 잘 동작하기를 바랍니다.

쿠버네티스 오브젝트는 바로 이런 애플리케이션 하나 하나를 의미합니다. 작게는 애플리케이션을 구성하는 모든 서비스들(볼륨, 네트워크, 시스템 자원) 부터 크게는 애플리케이션 그 자체를 나타냅니다.

쿠버네티스 시스템은 생성된 오브젝트가 정상 동작함을 보장하기 위해 지속적으로 작동합니다. 영속성을 가진다는 의미는 여기에서 알 수 있습니다.

Pod

파드는 쿠버네티스에서 생성하고 관리할 수 있는 배포 가능한 가장 작은 컴퓨팅 단위입니다.(참고) 파드는 독립적인 서비스를 구동할 수 있는 한 개 이상의 컨테이너로 구성됩니다. 같은 파드 안에 속한 컨테이너들은 서로 스토리지, 네트워크를 공유합니다.

강의 내용

Container

같은 파드 안에 위치한 컨테이너는 서로 다른 포트를 가져야 합니다. 같은 파드 안에 위치한 컨테이너들은 서로를 [localhost] 로 인식할 수 있으며, 접근할 때 포트로 통신할 수 있습니다. 따라서 서로 다른 컨테이너가 같은 포트를 갖게 된다면 포트가 충돌하게 됩니다.

또, 파드가 새로 생성되면, 쿠버네티스 클러스터에서만 접근이 가능한 IP가 하나 생성됩니다. 이 IP는 외부에서는 접근이 불가능하며, 파드가 재생성되면 IP도 변경됩니다.

Label

레이블은 파드 뿐만 아니라 모든 오브젝트에 달 수 있습니다. 레이블을 사용하는 이유는 목적에 따라 오브젝트를 분류하고, 분류된 오브젝트끼리 따로 연결을 하기 위해서 설정합니다. 오로지 사용자의 편의성을 위한 기능으로, 쿠버네티스 시스템에 직접적인 영향을 주지는 않습니다. 레이블은 Key : Value 로 구성됩니다. 단, 오브젝트에 사용되는 레이블의 키는 언제나 고유해야 합니다.

레이블을 이용하면 같은 레이블을 갖는 오브젝트만을 선택적으로 볼 수 있습니다. 예를 들자면, 배포 환경(environment)이 production 인 오브젝트만을 관리하고 싶다면, 레이블을 environment: production 으로 두고 명령어 등을 통해 작업을 수행하시면 되는 형태입니다. 쿠버네티스 시스템에 직접적인 영향을 주지 않기 때문에 오브젝트를 배포할 때 레이블을 사용하지 않아도 아무런 문제가 없습니다. 그러나 나중에 클러스터의 크기가 커지고, 관리해야 하는 오브젝트가 많아지면, 사용자의 입장에서 레이블이 큰 역할을 하게 됩니다. 따라서 초기부터 레이블을 잘 활용하는 것이 좋습니다.

일반적으로 자주 사용되는 레이블은 다음과 같습니다.

  • "release" : "stable", "release" : "canary"
  • "environment" : "dev", "environment" : "qa", "environment" : "production"
  • "tier" : "frontend", "tier" : "backend", "tier" : "cache"
  • "partition" : "customerA", "partition" : "customerB"
  • "track" : "daily", "track" : "weekly"

레이블을 파드에 정의하는 예시를 한번 보겠습니다.

apiVersion: v1
kind: Pod
metadata:
  name: label-demo
  labels:
    **environment: production
    app: nginx**
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

metadata.labels 하위 항목을 살펴보면, environment: production , app: nginx 라는 이름으로 레이블이 정의되어 있는 것을 볼 수 있습니다. 추후 이 파드와 서비스를 연결하려면, 서비스의 명세에 spec.selector에 우리가 연결하고 싶은 오브젝트의 레이블을 넣어주면 됩니다.

apiVersion: v1
kind: Service
metadata:
    name: label-demo
    labels:
        environment: production
        app: nginx
spec:
    selector:
        **app: nginx**
    ports:
    - port: 80

Node Schedule

노드 스케줄은 이름 그대로 오브젝트를 어떤 노드에 배포할 지 스케줄링하는 것을 의미합니다. 위에서 사용했던 Pod 매니페스트 파일을 보시면, 어디에도 어떤 노드에 배포해야하는지 지정하지 않았음을 알 수 있습니다. 이는 쿠버네티스 스케줄러 컴포넌트가 알아서 가장 최적의 노드에 파드를 배포해주기 때문입니다. 만약 배포하고 싶은 노드를 직접 선택하고 싶다면 파드 명세를 다음처럼 수정하면 됩니다. 배포하고 싶은 노드의 이름이 node-0 라 가정해보겠습니다.

apiVersion: v1
kind: Pod
metadata:
  name: label-demo
  labels:
    environment: production
    app: nginx
spec:
    **nodeSelector:
      hostname: node-0**
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

이외에도 우리는 파드 명세에 이 파드가 얼만큼의 메모리와 CPU를 최소한 할당받아야 하는지(requests), 얼만큼의 메모리, CPU를 넘게 할당받으면 안되는지(limits) 를 정의해줄 수 있습니다. 즉, 파드가 실행 중인 노드에 사용 가능한 리소스가 충분하면, 컨테이너가 해당 리소스에 지정한 requests 보다 더 많은 리소스를 사용할 수 있도록 허용되지만, 리소스 limit 보다 더 많은 리소스를 사용할 수는 없다는 것입니다. 이 명세가 있다면 쿠버네티스 스케줄러가 이 파드에 맞는 노드를 더 효율적으로 지정할 수 있습니다. 이 두 명세를 넣은 매니페스트 파일을 보여드리겠습니다.

apiVersion: v1
kind: Pod
metadata:
  name: label-demo
  labels:
    **environment: production
    app: nginx**
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80
        **resources:
            requests:
                memory: "128Mi"
                cpu: "250m"
            limits:
                memory: "256Mi"
                cpu: "500m"**

마무리

이렇게 해서 인프런 강의의 "기본 오브젝트 - Pod"를 다뤄봤습니다. 내용이 많이 부실하고, 설명이 어렵게 되어 있는 등의 문제가 있을 것으로 보입니다. 추후 수정을 통해 다듬어보겠습니다.

여기까지 따라오시느라 고생이 많으셨습니다. 만약 이 글이 도움이 되셨다면 글 좌측 하단의 하트❤를 눌러주시면 감사하겠습니다.

혹시라도 글에 이상이 있거나, 이해가 가지 않으시는 부분, 또는 추가적으로 궁금하신 내용이 있다면 주저 마시고 댓글💬을 남겨주세요! 빠른 시간 안에 답변을 드리겠습니다 😊

반응형