Gom3rye

Kubernetes- Pod 본문

현대 오토에버 클라우드 스쿨

Kubernetes- Pod

Gom3rye 2025. 6. 30. 17:34
728x90
반응형

구성 방법

  • 종류
    • Local Kubernetes: 물리 머신 1대에 구축해서 사용한다.
    • Kubernetes 구축 도구 이용: On-Premise나 Cloud 환경에 클러스터를 구축해서 사용한다.
    • 관리형 쿠버네티스: Public Cloud의 관리형 서비스로 제공하는 클러스터를 사용한다.
      • 대부분 여기서 일하게 될 것

Local Kubernetes

  • Docker Desktop 이용: Docker Desktop에 쿠버네티스 동작에 필요한 최소의 컨테이너를 생성해서 사용하는 방식
  • Minikube: 물리 머신에 로컬 쿠버네티스를 쉽게 구축하고 실행할 수 있는 도구
    • 쿠버네티스의 SIG라는 분과회에서 만듦
    • 실행되는 쿠버네티스는 단일 노드 구성이라서 여러 대의 구성이 필요한 쿠버네티스 기능은 사용할 수 없고 사용을 할 때 하이퍼바이저가 필요하다.
    • 운영체제에 맞는 하이퍼바이저를 설치해야 하는데 Docker, Virtual Box 또는 베어메탈 중에 하나면 된다.
    • 설치: https://minikube.sigs.k8s.io/docs/start/?arch=%2Fwindows%2Fx86-64%2Fstable%2F.exe+download
    • 클러스터 관련 명령
      • 단일 노드로 구성된 클러스터 생성
      minikube start
      
      • 여러 개의 워커 노드로 구성된 클러스터 생성
      minikube start [--nodes 워커노드개수] [-p 클러스터이름]
      
      • 생성한 후 노드 추가
      minikube node add
      
      • 노드 확인
      kubectl get nodes
      
      • 클러스터 중지
      minikube stop
      
      • 클러스터 삭제
      minikube delete
      

add node 두 번 한 상태

 

Installation | K3s

This section contains instructions for installing K3s in various environments. Please ensure you have met the Requirements before you begin installing K3s.

docs.k3s.io

  • Kind: Kubernetes IN Docker의 줄임말로 도커 Container를 이용해 손쉽게 Kubernetes Cluster를 구축할 수 있다.
    • 다중 노드 구성이 가능하다.
    • 설치
    • 클러스터 관련 명령
      • 생성
      kind create cluster
      
      • 삭제
      kind delete cluster
      
      • 설정 파일을 이용해서 생성
      kind create cluster --config 설정파일경로 --name 클러스터이름
      
      • 설정 파일 작성 (yaml로 작성)
      kind: Cluster
      nodes:
        - role: control-plan
        - role: worker
        - role: worker
      
       

Kubernetes 구축 도구 이용

  • 구성형 kubernetes
    • 사용하는 시스템에 Kubernetes Cluster를 자동으로 구성해주는 솔루션을 사용
    • 주요 솔루션으로 kubeadm, kops, KRIB, kubespray 등이 있다.
    • kubeadm이 가장 널리 알려진 구성형 kubernetes 도구
    • 비교
                                             KRIB                 kops              kubespray             kubeadm
    정보량 적음 많음 많음 매우 많음
    세부 설정 변경 가능 가능 제한적 가능 다양함
    사전 요구 조건 적음 적음 적음 매우 적음(리눅스만 깔려있음 된다.)
    온프레미스 지원 매우 좋음 안됨 좋음 매우 좋음
    클라우드 지원 안됨 매우 좋음 좋음 좋음
    학습 곡선 어려움 어려움 쉬움 어려움
    자동화 기능 제공됨 제공됨 쉽게 제공됨 제한적 제공

Kubernetes 사용

namespace: 분리성 확보

  • 가상적인 쿠버네티스 클러스터 분리 기능
  • 자바에서 package 역할과 비슷
    • 로그 수집은 common concern에 들어간다.
    • 실제 앱 : Business logic
    • 이렇게 서로 다른 역할을 하는 것들을 분리해주는 것
  • 완전한 분리의 개념은 아니기 때문에 용도는 제한되지만 하나의 쿠버네티스 클러스터를 여러 팀에서 사용하거나 서비스 환경/스테이징 환경/개발 환경으로 구분하는 경우 사용
  • 기본 설정에서 제공하는 namespace
    • kube-system: 쿠버네티스 클러스터 구성 요소와 애드온이 배포되는 namespace
    • kube-public: 모든 사용자가 사용할 수 있는 ConfigMap 등을 배치하는 네임스페이스
    • kube-node-lease: 노드의 하드비트 정보를 저장하기 위한 Lease 리소스가 저장되는 네임스페이스
    • default: 기본 네임스페이스
  • 관리형 서비스나 구축 도구로 구축된 경우 대부분의 클러스터는 RBAC(Role-Based Access Control)가 기본값으로 활성화되어 있으면 일부 환경에서는 네트워크 정책을 사용할 수 있다.
  • 일반적으로 RBAC는 클러스터 조작에 대한 권한을 네임스페이스별로 구분할 수 있고 네트워크 정책과 함께 사용해서 네임스페이스 간의 통신을 제어할 수 있는 구조이다.
  • namespace만으로는 높은 분리성을 확보하기 어렵지만 RBAC나 네트워크 정책을 사용하면 분리성을 높일 수 있다.

kubectl

  • 쿠버네티스에서 클러스터 조작은 쿠버네티스 마스터의 API를 통해 수행한다.
  • API Server에게 명령을 전달하기 위한 CLI 도구가 kubectl이다.
    • → kubectl을 설치하지 않으면 명령을 전달 할 수 없다.

인증 정보와 컨텍스트

인증 정보

  • kubectl이 쿠버네티스 마스터와 통신할 때 서버 정보나 인증 정보가 필요하다.
  • kubectl은 kubeconfig(~/.kube/config)에 쓰여있는 정보를 사용해서 접속한다.
  • 구체적으로 설정이 이루어지는 부분은 clusters/users/contexts
    • clusters에는 접속 대상 클러스터 정보를, users에는 인증 정보를, contexts에는 cluster와 users 그리고 네임스페이스를 지정한 것을 정의한다.
    • 만약에 cluster가 여러 개면 어느 마스터에게 kubectl get nodes 명령이 전달될까? → config에 다 적혀있다. 어디 cluster에 연결되어 있는지 → 원하는 클러스터를 사용하고 싶다면 kubeconfig 안의 내용을 바꾸자.

설정 변경

  • 파일을 직접 수정
  • 명령어 이용
    • 클러스터 정의를 추가(prd-cluster)
    kubectl config set-cluster prd-cluster --server=https://IP:6443
    
    • 인증 정보를 추가하거나 변경
    kubectl config set-credentials admin-user --client-certificate=crt파일경로 --client-key파일경로 --embed-certs=true
    
    • 컨텍스트 정의를 추가 및 변경
    kubectl config set-context 이름 --cluster=prd-cluster --user=admin-user --namespace=default
    
    • 현재 컨텍스트 확인 (내가 지금 어떤 컨텍스트를 쓰는지 확인하고 싶을 때)
    kubectl config current-context
    
    • 명령어를 실행할 때마다 컨텍스트 지정
    kubectl get pods --context minikube
    

리소스 생성/삭제/갱신

kubectl run

  • 가장 간단하게 pod를 만드는 방식
  • 실행 커맨드에 각종 정보를 입력해서 생성
  • 간편하지만 실행 시 입력 정보가 남지 않기 때문에 재실행하기가 어렵고 문제가 발생했을 때 원인을 찾거나 해결 방법을 공유하는 것이 어렵다.
  • 테스트나 간단한 pod를 생성할 때 유용하다.
  • 실습
    • nginx 이미지를 가지고 pod 생성
    kubectl run nginx --image=nginx
    
    • pod 확인
    kubectl get pods
    
  • yaml 파일 이용
apiVersion: v1
kind: Pod
metadata:
  name: sample-pod
spec:
  containers:
    - name: nginx-container
      image: nginx:1.16
  • 리소스가 존재하지 않는 경우
kubectl create -f sample-pod.yaml
# 리소스가 존재하지 않으므로 리소스를 생성
  • 리소스가 존재하는 경우
    • 이미 리소스가 존재하므로 에러 발생
  • 리소스 삭제
kubectl delete -f 리소스파일
kubectl delete -f sample-pod.yaml
# 리소스가 없으면 에러 발생
  • 리소스 이름 대신 --all 사용하면 모든 리소스 삭제
kubectl delete 리소스종류 [리소스이름]
  • kubectl 명령어 실행은 바로 완료되지만 쿠버네티스에 의한 실제 리소스 처리는 비동기로 실행되어 처리가 바로 완료되지 않는다.
  • --wait 옵션을 사용하면 리소스의 실제 완료를 기다렸다가 명령어 실행을 종료할 수 있다.
    • 모든 Finalizer(리소스는 삭제 명령을 내리면 리소스에 삭제 표시를 해서 더 이상 사용이 되지 않도록 하고 특정 조건이 만족할 때까지 기다리도록 kubernetes에게 지시하는 네임스페이스 키) 실행이 완료될 때까지 기다린다.
  • 리소스를 즉시 강제 삭제하고자 하는 경우는 유예 시간을 0으로 하는 --grace-period 0 옵션과 강제로 삭제하는 --force 옵션을 사용하면 된다.
    • 쿠버네티스 1.8 이후부터는 --force 옵션만으로 --grace-period 0 옵션도 자동으로 부여된다.
    • 비슷한 옵션으로 --now가 있지만 이 옵션은 --grace-period 1 옵션과 동일해서 바로 삭제되지 않는 경우가 있다.
  • kubectl delete -f sample-pod.yaml --grace-period 0 --force
  • 리소스 업데이트
    • kubectl apply 명령어는 변경 부분이 있으면 적용하고 없으면 적용하지 않음 (아무 일도 하지 않는다.)
    • 리소스가 없을 때는 kubectl create 명령과 동일 (리소스 생성)
    • 쿠버네티스는 생성한 리소스 상태를 내부에 기록하는데 한 번 기록된 리소스의 필드 대부분은 리소스 업데이트에 따라 변경할 수 있지만 리소스에 따라서는 생성 후에 변경할 수 없는 필드도 존재한다.
  • kubectl apply -f sample-pod.yaml # pod/sample-pod configured
  • 현재 구동 중인 pod의 이미지를 확인
kubectl get pods -o jsonpath='{.items[*].spec.containers[*].image}'
# nginx nginx:1.17 로 변경된거 확인 가능
  • 리소스 생성에도 되도록이면 kubectl apply 사용을 권장한다.
    • 리소스 생성에는 create를 사용하고 업데이트를 할 때는 apply를 사용하면 스크립트나 CI/CD를 적용할 때 분기문을 만들어야 할지도 모르기 때문! (존재하면 apply, 그렇지 않으면 create를 사용하도록)
    • CI/CD나 자동화에서는 조건 분기를 권장하지 않는다.
    • kubectl create와 kubectl apply를 섞어서 사용하면 kubectl apply를 실행할 때 변경 사항을 검출하지 못하는 경우가 있다.
      • kubectl apply로 적용된 변경 사항은 이전에 적용한 매니페스트, 현재 클러스터에 등록된 리소스 상태, 이번에 적용할 매니페스트 이렇게 세 종류에서 산출되는데 이번에 추가되거나 변경될 필드는 현재 리소스 상태와 이번에 적용할 매니페스트를 비교해서 산출되지만 삭제된 필드는 이전에 적용한 매니페스트와 이번에 적용할 매니페스트를 기준으로 산출
      • --save-config 옵션 없이 kubectl create를 사용하여 리소스를 생성한 경우에는 이전 상태가 저장되지 않기 때문에 이번에 적용할 매니페스트에서 특정 필드를 삭제하고 싶은 경우에 변경 사항을 산출하지 못하고 의도한 대로 반영되지 않는 필드가 생성될 수 있다.
      • 이전에 적용한 매니페스트가 저장되지 않는 경우 경고가 발생한다.

Server-Side Apply

리소스 필드 수정

  • 쿠버네티스는 사용자가 사용하는 kubectl 외의 다양한 시스템 구성 요소가 리소스 필드를 자동으로 수정할 수 있다.
  • 현재 변경 사항의 산출은 클라이언트(kubectl)측에서 계산하여 패치 요청을 보내기 때문에 (Client Side Apply) 여러 사용자나 구성 요소가 동시에 같은 필드를 변경하는 경우 경합 현상이 발생할 수 있는데 이 문제를 해결하기 위해 필드를 변경한 구성 요소를 기록하는 기능과 서버 측에서 변경 사항을 계산하는 기능이 도입됐다.
  • kubectl set image 명령어에서는 매니페스트 파일을 사용하지 않고 서버 측 정보를 직접 수정하여 컨테이너 이미지를 변경하는데 이 명령어는 매니페스트를 수정하지 않기 때문에 kubectl apply 명령어를 사용하게 되면 컨테이너 이미지가 원래대로 되돌아 가게 된다.
    • *매니페스트 파일: Kubernetes에 어떤 리소스를 만들고 어떻게 동작시킬지를 선언한 파일 (yaml파일 ex. nginx-pod.yaml)
  • server-side apply를 사용하면 이러한 충돌을 감지할 수 있다. But, 충돌 감지만 하기 때문에 실제 충돌이 발생할 때는 별도로 충돌 내용을 해결해야 한다.
  • 서버 측은 쿠버네티스 1.18 이후 기본값이지만 클라이언트 측은 기본값으로 활성화되어 있지 않는다.
  • 클라이언트 측에서 사용할 때는 --server-side 옵션을 추가해야 한다.
  • 실습
    • sample-pod.yaml 파일의 nginx 버전만 다시 1.16으로 수정 후 이미지 확인
    kubectl get pods -o jsonpath='{.items[*].spec.containers[*].image}'
    # nginx nginx:1.16 로 변경된거 확인 가능
    
    • 이미지 수정
    kubectl set image pod sample-pod nginx-container=nginx:1.17
    

  • 리소스 배포 후 이미지 확인 → 다시 1.16으로 돌아감
kubectl apply -f sample-pod.yaml
kubectl get pods -o jsonpath='{.items[*].spec.containers[*].image}'
  • 이번엔 서버 사이드로 배포하고 이미지 수정 후 확인해보기
kubectl apply -f sample-pod.yaml --server-side
kubectl set image pod sample-pod nginx-container=nginx:1.17
kubectl apply -f sample-pod.yaml
kubectl get pods -o jsonpath='{.items[*].spec.containers[*].image}'
# 변경이 안됨

Pod 재시작

  • Deployment 등의 리소스와 연결되어 있는 모든 파드를 재기동
rollout restart
  • 파드 기동 시 처리를 재실행하고 싶을 때나 시크릿 리소스에서 참조되는 환경 변수를 변경한 경우 사용
  • 리소스에 연결되어 있지 않은 단독 파드에는 사용할 수 없다.
    • kubectl run으로 만든 경우 사용할 수 없다.
  • 실습
    • 2개의 yaml 파일을 이용해서 pod 생성
      • sample-pod.yaml 파일
      • sample-deployment.yaml 파일 작성
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: sample-deployment
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: sample-app
        template:
          metadata:
            labels:
                app: sample-app
          spec:
            containers:
              - name: nginx-container
                image: nginx
      
    • pod를 재실행
    kubectl rollout restart deployment sample-deployment
    
    → 이 경우는 pod를 직접 생성하지 않고 sample-deployment라는 deployment로 생성해서 재시작이 가능하다.→ error: pods “sample-pod” restarting is not supported 에러 발생⇒ 실제 배포를 할 때는 pod 단위로 배포하지 않고 deployment와 같은 리소스를 이용한다.
  • ⇒ 지울 때 kubectl delete deployment --all
  • ⇒ pod를 직접 배포하는 경우는 재시작 할 수 없다.
  • kubectl rollout restart pod sample-pod

generateName

리소스를 만들 때 이름을 자동 생성해주는 기능

  • 기본적으로 kubectl apply 명령을 이용해서 리소스를 생성하지만 kubectl create를 이용하면 난수가 있는 이름의 리소스를 생성할 수 있다.
  • metadata.name 대신에 metadata.generateName을 지정하면 된다.
  • 사용하는 이유
    • 자동화 및 편의성을 위해 - 생성 과정이 간소화되고 오류 발생 가능성이 낮아진다.
    • 충돌을 방지하기 위해
    • 동적 생성 - 자동 확장 기능을 통해 pod가 추가로 생성될 때마다 GenerateName을 사용하면 매번 다른 이름을 가진 파드를 생성할 수 있다.
    • 템플릿 기반 배포 - 동일한 템플릿을 사용해서 여러 개의 유사한 리소스를 만들 때 편리하다.
      • 퍼블릭 클라우드에서는 apply 보다 create를 선호한다.
  • 실습
    • sample-generatename.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      generateName: sample-generatename-
    spec:
      containers:
        - name: nginx-container
          image: nginx
    
    kubectl create -f sample-generatename.yaml
    
    → 이름을 직접 기재하지 않고 자동으로 생성하기 때문에 실행할 때마다 별도의 pod가 생성된다. (replica랑 다른 것, replica는 강한 결합으로 묶어주는 것)

항목                          generateName + create                            replicas + Deployment

리소스 수 실행할 때마다 새로 하나 생성 하나의 리소스가 여러 복제본 관리
이름 자동 생성 내부 Pod는 이름 자동 생성, Deployment 이름은 고정
결합성 없음 (완전 개별 리소스) 강한 결합 (하나의 제어 대상)
관리 각각 따로 관리 컨트롤러가 전체 관리
복제 관리 수동 자동 (replicas, self-healing, scaling)

Pod

Kubernetes의 기본 배포 단위

  • 컨테이너가 모인 집합체와 유사(docker-compose)
  • 하나의 pod에 여러 개의 컨테이너를 포함시켜서 배포할 수 있는데 이런 구조를 sidecar 패턴이라고 한다.
  • 사이드카 패턴은 기본 기능을 하는 컨테이너(작업을 수행하는 애플리케이션)와 부가 기능을 하는 컨테이너(로그 수집이나 모니터링 기능을 수행하는 컨테이너)를 결합해서 배포하는 방식
  • 하나 이상의 컨테이너로 애플리케이션을 구축하다 보면 Nginx 컨테이너와 Go 애플리케이션 컨테이너처럼 서로 강한 결합을 유지하는 쪽이 더 나은 경우가 있는데 쿠버네티스에서는 이런 경우 하나의 pod로 묶어서 배포하는 것을 권장한다.

같은 워커 노드 안에 있는 pod끼리 소통하고 싶다 → cluster ip 사용

같은 pod 안에 있는 컨테이너끼리 소통하고 싶다 → localhost 사용

서로 다른 워커 노드 안에 있는 pod끼리 소통하고 싶다 → CNI Plugin 필요

외부 cluster에 서로 다른 worker → 서로 떨어져 있음 → 서로 다른 ip를 가지고 있을 경우 많다 → 서로 다른 네트워크를 같은 네트워크로 묶어주려면 각각 private IP를 주고 CNI plugin 필요

NodePort: 외부에서 그 컴퓨터의 ip로 직접 접근 하기 위한 포트

yaml에서 배열을 쓰는 방법

  1. [ 8.8.8.8 , 1.1.1.1 ]
    • 8.8.8.8
  • 1.1.1.1
728x90
반응형

'현대 오토에버 클라우드 스쿨' 카테고리의 다른 글

Kubernetes- Deployment  (1) 2025.07.02
Kubernetes- Prune, 로그 확인  (3) 2025.07.01
Kubernetes 개념  (3) 2025.06.27
Docker Swarm  (2) 2025.06.26
Docker Swarm  (1) 2025.06.25