Certification

[CKA] Udemy CKA 강의 Core Concepts02 - Pod, Replica set, Deployment, Service, Namespace

유자바 2024. 12. 13. 20:13

Pod

  • 응용 프로그램을 컨테이너의 형태로 워커 노드(worker node)에 배포할 때 pod로 캡슐화
    • pod는 응용 프로그램(application)의 단일 인스턴스(instance)
    • 쿠버네티스에서 만들 수 있는 가장 작은 객체(object)
  • pod는 일반적으로 컨테이너와 1:1 관계
    • 스케일업을 할 때 pod를 생성, 스케일다운을 할 때 pod를 삭제
    • 기존 pod에 컨테이너를 추가로 생성하지 않음
  • 멀티 컨테이너 pod
    • 헬퍼 컨테이너가 필요할 때 동일 pod 내에 여러 개의 컨테이너를 가질 수 있음
    • 동일한 네트워크 공간 및 저장 공간 사용

 

명령어

  • pod 생성해 도커 컨테이너 배포
    • kubectl run nginx --image nginx
    • 도커 허브에서 도커 이미지 다운로드 (--image)
  • pod 확인
    • kubectl get pods
    • kubectl get pods -o wide
  • pod 자세하게 확인
    • kubectl describe pod [이름]
  • pod 삭제
    • kubectl delete pod [이름]

 

yaml

쿠버네티스에서 YAML 기반의 configuration 파일을 사용해 파드를 생성하는 방법을 설명합니다. 기본적인 구조와 설정 방법은 아래와 같습니다:

  1. ApiVersion: 오브젝트 생성에 사용하는 Kubernetes API 버전입니다. 현재 파드 작업이므로 v1으로 설정합니다.
  2. kind: 생성하려는 오브젝트의 유형으로, 파드를 만들려면 Pod로 설정합니다.
  3. metadata: 오브젝트에 대한 정보를 담는 곳입니다. 여기에는 name(파드 이름)과 labels(오브젝트 식별을 위한 key-value 쌍) 같은 속성이 포함됩니다. metadata 하위에는 미리 정의된 속성만 사용할 수 있습니다.
  4. spec: 생성할 오브젝트에 필요한 추가 정보를 정의하는 곳입니다. containers라는 속성을 사용해 컨테이너를 정의하며, 각 컨테이너의 name과 image를 지정합니다.
// pod-definition.yaml
apiVersion: v1
kind: Pod
metadata: 
  name: nginx
  labels:
    app: myapp
    tier: frontend
spec:
  containers:
  - name: nginx
    image: nginx //이미지 레포지토리(도커허브)의 이미지 이름

 

구조가 완성되면 kubectl create -f pod-definition.yml 명령어로 파드를 생성할 수 있습니다.

 

  • kubectl create -f pod-definition.yml
  • kubectl apply -f pod-definition.yml
  • kubectl run [이름] --image=[이미지명] --dry-run=client -o yaml > [파일명].yaml

 

요약: Kubernetes YAML 파일의 최상위 속성인 ApiVersion, kind, metadata, spec을 이해하고, 오브젝트에 맞는 추가 설정을 통해 파드를 생성합니다.


Replica Set

  • 응용 프로그램의 지속적인 수행을 보장하기 위함 (high availability)
    • 동일한 서비스를 제공하는 pod 여러 개를 Replication Controller가 관리하거나
    • 하나의 pod만 있더라도 Replication Controller가 관리 (서비스 죽으면 바로 복구)
  • 사용자가 몰릴 경우에도 원활한 서비스 제공 (load balancing & scaling)
    • 사용자가 몰려 로드가 증가할 때 pod를 추가로 만들어 응용 프로그램을 제공
    • Replication Controller는 여러 개의 node에 걸칠 수 있음

YAML

Replication Controller

  • 이전 버전에서 사용됨
// rc-definition.yaml

apiVersion: v1
kind: ReplicationController
metadata: // for rc
  name: myapp-rc
  labels:
    app: myapp
    type: front-end
spec:
  template: // rc가 포드 템플릿을 보고 포드를 복제
    metadata: // for pod
      name: myapp-pod
      labels:
        app: myapp
        type: front-end
      spec:
        containers:
        - name: nginx-container
          image: nginx
  replicas: 3
  • kubectl create -f rc-definition.yml
  • kubectl get replicationcontroller
  • kubectl get pods

Replica Sets

  • 최근 버전에서 사용됨
// replicaset-definition.yaml

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myapp-replicaset
  labels:
    app: myapp
    type: front-end
spec:
  template:
    metadata:
      name: myapp-pod
      labels:
        app: myapp
        type: front-end
      spec:
        containers:
        - name: nginx-container
          image: nginx
  replicas: 3
  selector: // 파드들을 식별할 수 있게 해줌
    matchLabels:
      type: front-end

 

  • kubectl create -f replicaset-definition.yml
  • kubectl get replicaset
  • kubectl get pods

Labels and Selectors

  • Replica Set은 pod를 모니터링하는 프로세스
  • 어떠한 pod를 모니터링할지는 레이블링으로 결정
    • matchLabels (replicaset yaml) == labels (pod yaml)
    • 만약 이미 돌고 있는 pod가 있다면 해당 pod를 포함, 그렇지 않다면 새로 생성

명령어

  • replica set 스케일 하는 법
    • 1. 직접 yaml 파일 replicas 숫자 업데이트 후 kubectl replace -f replicaset-definition.yml
    • 2. 명령어 이용하기 
      • kubectl scale --replicas=6 -f replicaset-definition.yml
      • kubectl scale --replicas=6 replicaset myapp-replicaset
        • 하지만 파일 안의 내용이 자동으로 업데이트되지는 않음 -> 나중에 다룰 것
  • kubectl create -f replicaset-definition.yml
  • kubectl get replicaset
  • kubectl get pods
  • kubectl delete replicaset(rs) myapp-replicaset
  • kubectl edit replicaset(rs) myapp-replicaset
    • 수정 후에 기존 pod를 삭제해야 변경사항이 반영된 pod가 자동으로 생성됨

 

실습

  • 1) k get pods
  • 2) k get rs
  • 3,4)  k get rs
  • 5,6) k describe rs new-replica-set
  • 7) k  describe pod new-tab
  • 8) k delete pod  new-tab
  • 9) k get pods
  • 11) k create -f replicaset-definition-1.yaml -> error: v1 | k explain rs -> apiVersion: app/v1
  • 12) k create -f replicaset-definition-2.yaml -> error: spec.template.metadata.labels, invalid value: selector does not match template labels  -> spec.selector.matchLabels.tier와 spec.template.metadata.labels.tier가 일치해야함 아니면 복제본을 관리할 수 없음
  • 13) k get rs | k delete rs replicaset-1 replicaset-2
  • 14) k get rs | k edit rs new-replicaset-set -> 직접 spec.template.spec.container로 가서 Image 고치기 -> image 고쳐도 자동으로 업데이트 안되니까 파드를 다 지워서 새로운 파드가 만들어지게 하거나, rs를 지우고 다시 create해야함
  • 15) k scale rs new-replica-set --replicas=5
  • 16) k scale rs new-replica-set --replicas=2

 


Deployment

  • Deployment는 아래와 같은 기능을 가능케 함
    • 운영환경에 배포 시 여러 개의 인스턴스 필요
    • 응용 프로그램의 새로운 버전 등장 시 인스턴스 업그레이드
      • 동시에 업그레이드하지 않고 인스턴스를 하나씩 업그레이드할 수도 있음 (rolling update)
      • 문제가 발생할 시 롤백 (roll back)
    • 환경을 잠시 멈추고 모든 변경사항을 수행한 뒤 재시작
  • Deployment는 Replica Set을 감싸고 있는 상위 객체
    • Replica Sets
      • 여러 개의 pod를 배포
    • Pod
      • 응용 프로그램의 단일 인스턴스 배포
      • 컨테이너를 캡슐화

YAML

// deployment-definition.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-replicaset
  labels:
    app: myapp
    type: front-end
spec:
  template:
    metadata:
      name: myapp-pod
      labels:
        app: myapp
        type: front-end
      spec:
        containers:
        - name: nginx-container
          image: nginx
  replicas: 3
  selector:
    matchLabels:
      type: front-end
  • apiVersion과 kind를 제외한 다른 부분은 Replica Set과 동일

kubectl run으로 yaml file 간편하게 만들기

  • nginx pod 만들기
    • kubectl run nginx --image=nginx
  • POD manifest yaml 파일 (-o yaml) 작성
    • kubectl run nginx --image=nginx --dry-run=client -o yaml
    • dry-run 사용 시 파일만 생성될 뿐 실제 pod가 생성되지는 않음
  • Deployment yaml 파일 작성
    • kubectl create deployment --image=nginx nginx --dry-run=client -o yaml > nginx-deployment.yaml
    • kubectl create deployment --image=nginx nginx --replicas=4 --dry-run=client -o yaml > nginx-deployment.yaml
      • 1.19 버전 이상에서는 --replicas 옵션으로 deployment 생성 가능
  • 파일 수정 후 Deployment 생성
    • kubectl create -f nginx-deployment.yaml

명령어

  • kubectl create -f deployment-definition.yml
  • kubectl get deployments(deploy)
  • kubectl get all

실습

  • 1,6) k get pods
  • 2,5,7) k get rs
  • 3,4) k get deploy
  • 8,9) k describe pod frontend-tab -> 파드 중에 하나만 골라서 image 보기
  • 10)  k create -f deployment-definition-1.yaml -> error: no kind deployment is registered -> kind: Deployment
  • 11) k create deployment httpd-frontend --replicas=3 --image=httpd:2.4-alpine

 

Deployment와 Replicaset의 관계

Deployment는 내부적으로 ReplicaSet을 관리하여 파드를 생성하고 유지합니다.
Deployment를 사용하면 직접 ReplicaSet을 관리할 필요 없이, 롤링 업데이트와 롤백과 같은 기능을 통해 애플리케이션을 더 유연하게 운영할 수 있습니다.

 


Service

  • 다양한 파드 그룹 사이의 연결성(connectivity) 및 통신 담당
    • 프론트엔드과 엔드 유저(사용자)
    • 프론트엔드와 백엔드
    • 백엔드와 데이터
  • 애플리케이션의 msa 간에 낮은 결합도로 연결가능하게 해줌
  • 노트북에서 ssh 연결 없이 쿠버네티스 노드의 ip에 접근하고 웹 서버에 접속하고 싶다면
    • 노트북에서 노드로, 노드에서 파드로 중간에 요청을 매핑하는 service가 필요
  • service type
    • 1. node port: 서비스가 내부 파드를 노드의 파드에 액세스할 수 있도록 있게 함
    • 2. clusterip: 클러스터 안에 가상 ip를 만들어 다른 서비스 간의 통신을 가능하게 함
    • 3. loadbalancer: 클라우드 제공자에 있는 응용 프로그램을 위해 프로비저닝

NodePort

  • 워커 nodeport에서 외부 애플리케이션을 사용할 수 있도록 함
  • 노드의 포트로부터 들어오는 요청을 pod에 전달하는 역할
  • 사용자가 쿠버네티스 노드 내의 pod에 접속하고자 할 때 사용
    • 1) TargetPort: Pod에 붙어있는 포트
    • 2) Port: Service에 붙어있는 포트, 클러스터 IP와 함께 존재
    • 3) NodePort: Node에 붙어있는 포트, 30000-32767 (범위)
  • 여러 개의 pod와 연결될 때, 랜덤 알고리즘으로 로드 밸런싱 -> 서비스는 파드 간 부하를 분산하면서 기본적으로 lb 역할을 함
  • 1(pod):1(node), N:1, N:N일 경우 모두 가능
  • 만약 파드가 여러 노드에 분산되어 있으면?
    • 서비스는 자동으로 클러스터의 모든 노드에서 대상 포트를 매핑하도록 만들고, 이때 클러스터의 모든 노드는 동일한 포드 번호를 사용

YAML

//service-definition.yaml

apiVersion: v1
kind: Service
metadata: 
  name: myapp-service
  
spec: // 실제 서비스를 정의하는 부분
  type: NodePort
  ports:
  - targetPort: 80 // 안 적으면 port와 동일하다고 간주
    port: 80 // 필수 필드
    nodePort: 30008 // 지정 안하면 자동으로 배정됨
  selector: // 연결할 파드의 labels 정보를 입력하면 파드와 연결 
    app: myapp
    type: front-end

 

ClusterIP

  • 클러스터 내에 가상의 IP를 생성
  • 다른 서비스들 간의 통신을 담당 (e.g. 프론트엔드와 백엔드)
  • 여러 개의 서비스 pod(e.g. 백엔드)를 위한 단일한 인터페이스를 제공

YAML

// service-definition.yaml

apiVersion: v1
kind: Service
metadata:
  name: back-end
spec:
  type: ClusterIP
  ports:
  - targetPort: 80 // 백엔드가 노출되는 포트
    port: 80 // 서비스가 노출되는 포트
  selector: // 파드의 Labels 정보 가져오기
    app: myapp
    type: back-end
  • k create -f service-definition.yaml
  • k get services

LoadBalancer

  • 로드 트래픽을 여러 다른 웹서버로 분산하는 역할
  • 여러 개의 클러스터 노드 IP에 대해 개별 접속하는 것이 아니라 단일한 경로로 서비스를 사용할 수 있도록 도움
  • NodePort 대신 LoadBalancer 사용할 수 있음
    • Google Cloud Platform 등에서는 사용 가능
    • VirtualBox에서는 사용 불가

YAML

// service-definition.yaml

apiVersion: v2
kind: Service
metadata:
  name: myapp-service
spec:
  type: LoadBalancer
  ports:
  - targetPort: 80
    port: 80
    nodePort: 30008

명령어

  • kubectl create -f [파일명].yaml
  • kubectl get services(svc)
  • curl http://192.168.1.2:30008
    • NodePort의 IP, port 정보 (접속 시)
  • kubectl expose pod [pod명] --port=[포트번호] --name [service명] --dry-run=client -o yaml
    • pod를 포트에 노출시키는 ClusterIP 타입의 서비스 파일 생성
    • pod의 레이블을 자동으로 selector로 사용
  • kubectl create service clusterip [pod명] --tcp=6379:6379 --dry-run=client -o yaml
    • 위와 동일하게 서비스 파일을 생성하는 명령어
    • selector를 자동으로 선택하는 것이 아니라 app=redis로 설정하기 때문에 주의 필요 (수정 필요할 수 있음)
  • kubectl run [pod명] --image=[이미지명] --port=[포트번호] --expose=true
    • Service와 Pod를 동시에 생성할 수 있음

Namespace

  • 자동 생성 네임스페이스
    • Default
      • 클러스터가 셋업될 당시 자동으로 만들어짐
    • kube-system
      • 네트워킹, DNS 등 사용자가 실수로 삭제해서는 안 될 것들을 모아놓음
    • kube-public
      • 모든 사용자들이 이용 가능한 자원
  • 서비스와 자원들을 고립시킬 때 유용 (isolation)
    • e.g. 개발환경과 운영환경을 분리할 때
  • 네임스페이스마다 다른 정책 사용 가능 (policies)
  • 사용 가능한 자원의 한계를 지정 가능 (resource limit)

명령어

  • 기본 네임스페이스 내 명령어 (pod 확인, 생성)
    • kubectl get pods
    • kubectl create -f [파일명].yaml
  • 네임스페이스 지정 명령어 (pod 확인, 생성)
    • kubectl get pods --namespace=kube-system(-n=)
    • kubectl create -f [파일명].yaml --namespace=dev
      • 혹은 yaml file metadata 하위에 namespace: dev와 같이 작성
  • 네임스페이스 확인
    • kubectl get namespaces(ns)
  • 네임스페이스 생성
    • kubectl create namespace [이름]
  • 네임스페이스 전환 (기본에서 변경)
    • kubectl config set-context $(kubectl config current-context) --namespace=dev
  • 모든 네임스페이스 확인
    • kubectl get pods --all-namespaces(-A)

YAML

  • apiVersion: v1
  • kind: Namespace
  • metadata:
    • name: dev

DNS

  • 같은 네임스페이스 안에서는 이름으로 호출 가능
    • e.g. mysql.connect("db-service")
  • 다른 네임스페이스에 있는 서비스를 호출할 때는 서비스명.네임스페이스.svc.cluster.local 형태로 호출
    • e.g. mysql.connect("db-service.dev.svc.cluster.local")
    • cluster.local은 기본 도메인명 (쿠버네티스 클러스터)
    • svc는 서브도메인 (서비스)

Resource Quota

apiVersion: v1
kind: ResourceQuota
metadata:
	name: compute-quota
	namespace: dev
spec:
	hard:
		pods: '10'
		requests.cpu: '4'
		requests.memory: 5Gi
		limits.cpu: '10'
		limits.memory: 10Gi
  • kubectl create -f [파일명].yaml

 

실습

1) k get ns

2) k get pods -n=research(or --namespace=research)

3) k run redis --image=redis -n=finance

4) k get pods -A(or --all-namespaces)
5) just click open button

6) k get pods -n=marketing | k get svc -n=marketing

7) k get pods -n=dev -> db-service.dev.svc.cluster.local


Imperative vs. Declarative

  •  Imperative - 시험 준비 시 이거를 연습해야함
    • 무엇이 필요한지, 어떻게 해야 하는지 단계적 설명 제공
    • 직접적으로 객체의 생성, 변경, 삭제 등을 진행
      • YAML 파일을 변경하지 않고 명령어로 생성, 수정 시에 쿠버네티스 메모리에는 기록이 남으나 로컬 파일에는 변경되지 않으므로 주의 필요
    • kubectl run --image=nginx nginx
    • kubectl create deployment --image=nginx nginx
    • kubectl expose deployment nginx --port=80
    • kubectl edit deployment nginx
    • kubectl scale deployment nginx --replicas=5
    • kubectl set image deployment nginx nginx=nginx:1.18
    • kubectl create -f nginx.yaml
    • kubectl replace -f nginx.yaml
    • kubectl delete -f nginx.yaml
  • Declarative
    • 필요한 것들만 명시, 시스템이 알아서 진행
    • configuration을 시스템이 확인하고 알아서 생성, 변경, 삭제 등을 진행
    • kubectl apply -f nginx.yaml
      • 쿠버네티스의 live object configuration에 정보 저장됨 (다른 명령어와 동일)
      • json 포맷으로 변경되어 마지막으로 적용된 configuration 저장 (다른 명령어와 다름)
        • live object configuration 내에 저장됨
        • 어떤 필드가 삭제되었는지 확인 용이

 

💡 Certfication Tips - Imperative Commans with Kubectl
1. --dry-run=client: 명령어가 어떻게 수행될지에 대한 정보만 먼저 알려줌
2. -o yaml: 출력 형식을 yaml 형태로 지정

Example)
1. k run nginx --image=nginx --dry-run=client -o yaml
    : 생성될 nginx 파드의 yaml을 출력
2. k create deployment --image=nginx nginx --dry-run=client -o yaml
    : 생성될 nginx deployment의 yaml을 출력
3. k create deployment --image=nginx nginx --dry-run=client -o yaml > nginx-deployment.yaml
    : yaml 파일 저장도 가능

Service
1. k expose pod redis --port=6379 --name=redis-service --dry-run=client -o yaml
    : redis-service라는 이름의 ClusterIP 타입의 svc로 노출시키는 시뮬레이션
2. kubectl create service clusterip redis --tcp=6379:6379 --dry-run=client -o yaml
    : 1번과 같은 역할을 하는 명령어
    : 다만, selector를 자동으로 사용하지 않고, 기본적으로 app=redis 선택자가 사용됨. 즉, redis 파드가 app=redis 라벨을 가져야지 연결됨
3. kubectl expose pod nginx --type=NodePort --port=80 --name=nginx-service --dry-run=client -o yaml
    : nginx-service라는 이름의 nodeport 타입의 svc로 노출시키는 시뮬레이션
4. kubectl create service nodeport nginx --tcp=80:80 --node-port=30080 --dry-run=client -o yaml
    : 3번과 같은 역할이고, 30080포트를 노드에서 사용할 수 있게 지정함. 선택자를 자동으로 설정하지 않아 기본적으로 app=nginx라벨을 사용함

 

 

실습

1) k run nginx-pod --image=nginx:alpine

2) k run redis --image=redis:alpine --labels="tier=db"

4) k expose pod redis --name=redis-service --port=6379

5) k create deployment webapp --image=kodekloud/webapp-color --replicas=3

6) k run custom-nginx --image=nginx --port=8080

7) k create namespace dev-ns

8) k create deployment redis-deploy -n=dev-ns --image=redis --replicas=2

9) k run httpd --port=80 --image=httpd:alpine --namespace=default && k expose pod httpd 
service/httpd exposed