Infra/Kubernetes

[K8s] kubectl과 Workload

혬수 2024. 10. 25. 22:50

 

본 글은 한 권으로 배우는 도커&쿠버네티스 책에 대한 정리와 실습 내용입니다.

 

Kubectl 📌

Kubernetes 클러스터를 관리하기 위한 명령어

https://kubernetes.io/ko/docs/reference/kubectl/

 

명령줄 도구 (kubectl)

쿠버네티스는 다음을 제공한다: 쿠버네티스 API를 사용하여 쿠버네티스 클러스터의 컨트롤 플레인과 통신하기 위한 커맨드라인 툴 이 툴의 이름은 kubectl이다. 구성을 위해, kubectl 은 config 파일을

kubernetes.io

 

명령어 

기본 명령어

kubectl cluster-info # 클러스터 조회

kubectl config view # 현재 컨텍스트와 설정 확인

kubectl config current-context # 현재 사용중인 컨텍스트 확인

 

Object 관리

kubectl create pods # 새로운 리소스를 생성할 때 사용 -> 이미 존재하면 에러 발생
kubectl apply (-f FILENAME | -k DIRECTORY) [options] 
# 리소스를 생성하거나 업데이트할 때 사용

kubectl get pods # 현재 네임스페이스에서 실행 중인 모든 Pod의 목록을 조회
# -o wide: 추가적인 정보를 포함하여 출력
kubectl get namespaces # 클러스터에서 사용 가능한 모든 네임스페이스의 목록을 조회
kubectl get <object>

kubectl delete pods <pod-name> # Kubernetes 클러스터에서 특정 Pod 또는 Pod 집합을 삭제

 

Debugging

kubectl logs <pod-name> # 특정 Pod에서 실행 중인 컨테이너의 로그를 조회

kubectl describe <object-name> # Kubernetes 오브젝트의 상세 정보를 조회
# 절차 하나들마다 내부적으로 이벤트적. 쿠버네티스에서 정상적으로 잘 배포 되었는지 과정, 흐름을 확인

kubectl top pod # 클러스터에서 리소스 사용량(CPU, 메모리)을 조회하는 데 사용

 

그 외 자주 사용

kubectl exec <pod-name> -- <command> # 실행 중인 컨테이너에서 명령을 실행하는 데 사용

kubectl expose <object-type> <object-name> --type=<type> --name=<name>
# Kubernetes 오브젝트(Pod, Deployment, ReplicaSet 등)를 노출시키는 Service를 생성하는 데 사용
# --type: Service의 유형을 지정

kubectl run <name> --image=<image> # Pod 또는 Deployment를 생성하는 데 사용

kubectl port-forward <pod-name> <local-port>:<pod-port>
# 로컬 머신에서 Kubernetes 클러스터 내의 특정 Pod나 Service로 네트워크 트래픽을 포워딩

kubectl <command> --kubeconfig=<path-to-kubeconfig-file>
# kubectl 명령어에서 사용할 Kubernetes 클러스터의 설정 파일을 지정하는 데 사용

 

 

매니페스트를 활용한 파드 실행

매니페스트 Manifest : 쿠버네티스 오브젝트를 생성하기 위한 메타 정보를 YAML 혹은 JSON 형식으로 작성한 파일

# ~/work/ch09/ex01/nginx-test01.yml

apiVersion: v1
kind: Pod
metadata:
  name: nginx01
spec:
  containers:
    - name: nginx-test01
      image: nginx:latest
kubectl apply -f nginx-test01.yml

kubectl get pod
## NAME      READY   STATUS    RESTARTS   AGE
## nginx01   1/1     Running   0          38s

kubectl delete -f nginx-test01.yml

 

 

Kubernetes Workload 📌

Workload: 쿠버네티스에서 구동되는 애플리케이션

 

Pod

  • 배포할 수 있는 최소한 단위 → 배포할 모든 오브젝트는 pod로 배포하게 됨.
  • 하나 이상의 컨테이너 그룹; 컨테이너 묶음

Replicaset

  • Pod의 복제본을 유지하는 역할
  • 명시된 동일 Pod 개수에 대한 가용성을 보증
  • 요즘은 별도로 실행하지 않고 Deployment로 합쳐서 사용

Deployment

  • 레플리카셋을 관리하는 컨트롤러
  • 파드 갯수 조절하려면 디플로이먼트 통해서 해야함
# ~/work/ch09/ex02/deploy-test01.yml

apiVersion: apps/v1 # 리소스를 관리하는 오브젝트인 경우 apps/v1
kind: Deployment
metadata:
  name: deploy-test01
spec:
  replicas: 3
  selector: # 파드에 라벨 붙이는 옵션
    matchLabels:
      app.kubernetes.io/name: web-deploy # 디플로이먼트와 파드 묶는 라벨
  template:
    metadata:
      labels:
        app.kubernetes.io/name: web-deploy # 디플로이먼트와 파드 묶는 라벨
    spec:
      containers:
        - name: nginx
          image: nginx:latest
kubectl apply -f deploy-test01.yml

kubectl get deploy,rs,po

kubectl delete -f deploy-test01.yml

 

  • 스케일
    • 디플로이먼트 yaml 파일을 수정해서 파드 갯수를 조정하는 것
# ~/work/ch09/ex03/deploy-test02.yml

apiVersion: apps/v1 
kind: Deployment
metadata:
  name: deploy-test01
spec:
  replicas: 5 # 변경
  selector:
    matchLabels:
      app.kubernetes.io/name: web-deploy
  template:
    metadata:
      labels:
        app.kubernetes.io/name: web-deploy 
    spec:
      containers:
        - name: nginx
          image: nginx:latest
kubectl get po
## pod 3개

kubectl apply -f deploy-test02.yml
## deployment.apps/deploy-test01 configured

kubectl get po
## pod 5개로 변경됨

kubectl delete -f deploy-test02.yml

 

  • 롤아웃
    • 컨테이너 업데이트
# ~/work/ch09/ex04/deploy-test03.yml

apiVersion: apps/v1 
kind: Deployment
metadata:
  name: deploy-test01
spec:
  replicas: 5 # 변경
  selector:
    matchLabels:
      app.kubernetes.io/name: web-deploy
  template:
    metadata:
      labels:
        app.kubernetes.io/name: web-deploy 
    spec:
      containers:
        - name: nginx
          image: nginx:1.24
kubectl apply -f deploy-test03.yml

kubectl describe deployment deploy-test01 # 버전 확인 가능
# ~/work/ch09/ex04/deploy-test04.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-test01
spec:
  replicas: 3
  selector:
    matchLabels:
      app.kubernetes.io/name: web-deploy
  template:
    metadata:
      labels:
        app.kubernetes.io/name: web-deploy
    spec:
      containers:
        - name: nginx
          image: nginx:1.25
diff deploy-test03.yml deploy-test04.yml

kubectl apply -f deploy-test04.yml

kubectl describe deployment deploy-test01 # 버전 확인 가능
## Image: nginx:1.25

 

  • 롤백
    • 롤백: 롤아웃 이전의 컨테이너 상태로 되돌리는 것
kubectl rollout undo deployment deploy-test01

kubectl describe deploy deploy-test01
## Image: nginx:1.25

 

 

Statefulset

  • Deployment와 비슷하지만, 각 파드마다 독자성을 유지하므로, 대체해서 사용할 수 없음
  • 각 파드는 영구적인 식별자 → 스케줄링 다시 할때도 유지
  • PV & PVC 와 결합하여 사용
  • 활용
    • 안정적이고, 고유한 네트워크 식별자
    • 안정적인 퍼시스턴트 스토리지 Persistent Storage
    • 순차적인 원활한 배포 Graceful Deployment와 스케일링
    • 순차적, 자동 롤링 업데이트

 

  • 헤드리스 서비스 → 고유한 네트워크 식별자 예시
    • Pod들의 개별 네트워크를 식별하기 위해 필요한 서비스
    • ClusterIP가 없음
# ~/work/ch09/ex12/statefulset-service.yml

apiVersion: v1
kind: Service
metadata:
  name: sfs-service01
spec:
  selector: # 어떤 statefulset와 연동할지
    app.kubernetes.io/name: web-sfs01
  type: ClusterIP
  clusterIP: None # 헤드리스 서비스는 ClusterIP이므로 해당 타입으로 설정
  ports:
    - protocol: TCP
      port: 80
# ~/work/ch09/ex12/statefulset-web01.yml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: sfs-test01
spec:
  replicas: 3
  selector:
    matchLabels:
      app.kubernetes.io/name: web-sfs01
  serviceName: sfs-service01
  template:
    metadata:
      labels:
        app.kubernetes.io/name: web-sfs01
    spec:
      containers:
        - name: nginx
          image: nginx:latest
# ~/work/ch09/ex12/statefulset-web02.yml

...
spec:
  replicas: 2 # replicas 수 변경
...
k apply -f statefulset-service.yml
k apply -f statefulset-web01.yml

k get pod -o wide
## 3개 Pod 순서대로 0,1,2 붙이며 실행

k apply -f statefulset-web02.yml

k get pod -o wide
## 삭제할 pod 랜덤하게 변하는게 아닌, 가장 최근에 실행되었던(2) 파드 삭제
  • 스테이트풀셋 접속 테스트
    • 스테이트풀셋을 통해 실행한 파드에 접속해 웹페이지에 접속
# ~/work/ch09/ex12/nginx-test01.yml

apiVersion: v1
kind: Pod
metadata:
  name: nginx01
spec:
  containers:
    - name: nginx
      image: nginx:latest
k get all
k get pod -o wide
## sfs-test01-0에 접속 테스트 진행할 것 -> IP 주소 잘 확인 192.168.131.29

k exec -it nginx01 -- /bin/bash
## bash 진입

curl 192.168.131.29

exit
k delete pods --all
k delete services,statefulsets --all

 

  • 스테이트풀셋 볼륨
# ~/work/ch09/ex12/statefulset-vol01-pv.yml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-sfs01
spec:
  accessModes:
    - ReadWriteOnce
  capacity:
    storage: 100Mi
  persistentVolumeReclaimPolicy: Retain
  storageClassName: pv-sfs-test01
  hostPath:
    path: /home/hyesu/work/volhost01
    type: DirectoryOrCreate
# ~/work/ch09/ex12/statefulset-vol02.yml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: sfs-test01
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: web-sfs01 # 관리할 앱
  serviceName: sfs-service01 # 헤드리스 서비스
  template:
    metadata:
      labels:
        app.kubernetes.io/name: web-sfs01 
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          volumeMounts:
            - name: sfs-vol01
              mountPath: /mount01
  volumeClaimTemplates: # PVC 역할
    - metadata:
        name: sfs-vol01
      spec:
        accessModes:
          - ReadWriteOnce
        storageClassName: pv-sfs-test01
        resources:
          requests:
            storage: 20Mi
k apply -f statefulset-service.yml
k apply -f statefulset-vol01-pv.yml
k apply -f statefulset-vol02.yml

k get all -o wide
# work/ch09/ex12/statefulset-vol03.yml

...
spec:
  replicas: 2 # replicas 수 늘림
...
k apply -f statefulset-vol03.yml

k get all -o wide
## 생성된 pod pending

k get pod,pvc,pv
## pvc 하나가 pending

k describe pvc sfs-vol01-sfs-test01-1
## storageclass.storage.k8s.io "pv-sfs-test01" not found
## -> 만들어진 pv-sfs-test01을 sfs-vol01-sfs-test01-0가 사용

 

 

 Daemonset

  • 로깅 시스템같이 특정 폴더나 경로에 있는 모든 로그 관리할 경우 노드 하나하나 배포하지 않고 Daemonset으로 배포
  • 모든 노드에 배포

 

Job / CronJob

  • 잡 Job
    • 쿠버네티스 애플리케이션의 실행 및 종료에 초점을 맞춘 리소스
    • 파드를 생성하고 지정된 수의 파드가 성공적으로 종료될때까지 계속해서 파드의 실행 재시도 → 성공 완료횟수 도달하면 잡 종료
# ~/work/ch09/ex15/job-cronjob01.yml

apiVersion: batch/v1
kind: Job
metadata:
  name: job-test01
spec:
  template:
    spec:
      containers:
        - name: nginx-test01
          image: nginx:1.25
          command: ["echo", "Hello Kubernetes"] # Job을 통해 입력할 명령어
      restartPolicy: Never # 재시작 정책
  backoffLimit: 3 # 실패시 재시도 횟수
k apply -f job-cronjob01.yml

k get job
k describe job job-test01 
# job-controller에 의해 잡이 완료됨 확인

k get pod 
## STATUS Completed

k logs job-test01-cxzss
## Hello Kubernetes

 

 

CronJob

A CronJob starts one-time Jobs on a repeating schedule.

kubernetes.io

# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12)
# │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday)
# │ │ │ │ │                                   OR sun, mon, tue, wed, thu, fri, sat
# │ │ │ │ │
# │ │ │ │ │
# * * * * *

 

# ~/work/ch09/ex15/job-cronjob02.yml

apiVersion: batch/v1
kind: CronJob
metadata:
  name: cronjob-test02
spec:
  schedule: "*/1 * * * *" # 매 1분에 한번씩 실행
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: nginx-test02
              image: nginx:1.25
              command:
                - /bin/sh
                - -c
                - echo Hello Kubernetes!!
          restartPolicy: Never
k apply -f job-cronjob02.yml

k get cronjob
k describe cronjob cronjob-test02 # Events 부분 생성된것 확인

k get pod # STATUS Completed

k logs cronjob-test02-28839035-mn5wk
## Hello Kubernetes!!
k logs cronjob-test02-28839037-8fdk4
## Hello Kubernetes!!