Certified Kubernetes Administrator (CKA) with Practice Tests (강의 링크, 레퍼런스 노트)
- 평소 강의 할인도 많이 하고, 연습문제도 풀어볼 수 있으니 실제 강의 수강을 추천
- 아래는 강의 내용 번역 및 정리본 (문제 시 댓글로 알려주세요)
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 삭제
YAML
- pod, replicaset, deployment, service 등의 객체를 생성할 때 yaml 파일 사용
- pod-definition.yml
- apiVersion: 쿠버네티스 API 버전 (e.g. v1, apps/v1)
- kind: 객체의 타입 지정 (e.g. Pod)
- metadata: name, labels 등 지정 (dictionary 형태, labels로 그룹화 가능)
- spec: e.g. containers (list/array 형태, -로 구분)
kubectl create -f pod-definition.yml
kubectl apply -f pod-definition.yml
kubectl run [이름] --image=[이미지명] --dry-run=client -o yaml > [파일명].yaml
Replica Set
- 응용 프로그램의 지속적인 수행을 보장하기 위함 (high availability)
- 동일한 서비스를 제공하는 pod 여러 개를 Replication Controller가 관리하거나
- 하나의 pod만 있더라도 Replication Controller가 관리 (서비스 죽으면 바로 복구)
- 사용자가 몰릴 경우에도 원활한 서비스 제공 (load balancing & scaling)
- 사용자가 몰려 로드가 증가할 때 pod를 추가로 만들어 응용 프로그램을 제공
- Replication Controller는 여러 개의 node에 걸칠 수 있음
YAML
Replication Controller
- 이전 버전에서 사용됨
- apiVersion: v1
- kind: ReplicationController
- metadata: name, labels key는 고정
- name: myapp-rc
- labels: labels 하위의 dictionary key는 사용자가 정할 수 있음
- app: myapp
- type: front-end
- spec:
- template: pod에 대한 템플릿을 만듦
- pod.yaml에서 metadata, spec 부분을 옮김
- replicas: 3
kubectl create -f [파일명].yml
kubectl get replicationcontroller
kubectl get pods
Replica Sets
- 최근 버전에서 사용됨
- apiVersion: apps/v1
- kind: ReplicaSet
- metadata: name, labels key는 고정
- name: myapp-replicaset
- labels: labels 하위의 dictionary key는 사용자가 정할 수 있음
- app: myapp
- type: front-end
- spec:
- template: pod에 대한 템플릿을 만듦
- pod.yaml에서 metadata, spec 부분을 옮김
- replicas: 3
- selector: 어떠한 pod가 하위에 있는지 구분 가능 (Replica Set에만 있음)
Labels and Selectors
- Replica Set은 pod를 모니터링하는 프로세스
- 어떠한 pod를 모니터링할지는 레이블링으로 결정
- matchLabels (replicaset yaml) == labels (pod yaml)
- 만약 이미 돌고 있는 pod가 있다면 해당 pod를 포함, 그렇지 않다면 새로 생성
명령어
- replica set 스케일 하는 법
- replicas 숫자 변경 (yaml file) 후
kubectl replace -f [파일명].yml
kubectl scale --replicas=[숫자] -f [파일명].yml
kubectl scale --replicas=[숫자] replicaset[타입] myapp-replicaset[이름]
- 하지만 파일 안의 내용이 자동으로 업데이트되지는 않음
kubectl create -f [파일명].yml
kubectl get replicaset
kubectl get pods
kubectl delete replicaset(rs) [이름]
kubectl edit replicaset(rs) [이름]
- 수정 후에 기존 pod를 삭제해야 변경사항이 반영된 pod가 자동으로 생성됨
Deployment
- Deployment는 아래와 같은 기능을 가능케 함
- 운영환경에 배포 시 여러 개의 인스턴스 필요
- 응용 프로그램의 새로운 버전 등장 시 인스턴스 업그레이드
- 동시에 업그레이드하지 않고 인스턴스를 하나씩 업그레이드할 수도 있음 (rolling update)
- 문제가 발생할 시 롤백 (roll back)
- 환경을 잠시 멈추고 모든 변경사항을 수행한 뒤 재시작
- Deployment는 Replica Set을 감싸고 있는 상위 객체
- Replica Sets
- Pod
- 응용 프로그램의 단일 인스턴스 배포
- 컨테이너를 캡슐화
YAML
- apiVersion: apps/v1
- kind: Deployment
- 여타 부분은 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 [파일명].yml
kubectl get deployments(deploy)
kubectl get all
Service
- 다양한 그룹 사이의 연결성(connectivity) 및 통신 담당
- 프론트엔드과 엔드 유저(사용자)
- 프론트엔드와 백엔드
- 백엔드와 데이터
NodePort
- 노드의 포트로부터 들어오는 요청을 pod에 전달하는 역할
- 사용자가 쿠버네티스 노드 내의 pod에 접속하고자 할 때 사용
- TargetPort
- Port
- Service에 붙어있는 포트
- 클러스터 IP와 함께 존재
- NodePort
- Node에 붙어있는 포트
- 30000-32767 (범위)
- 여러 개의 pod와 연결될 때, 랜덤 알고리즘으로 로드 밸런싱
- 1(pod):1(node), N:1, N:N일 경우 모두 가능
YAML
- apiVersion: v1
- kind: Service
- metadata:
- spec:
- type: NodePort
- ports:
- -targetPort: 80
- port: 80 (필수)
- nodePort: 30008
- selector: replicaset처럼 관련 pod의 정보를 작성 (labels)
- app: myapp
- type: front-end
ClusterIP
- 클러스터 내에 가상의 IP를 생성
- 다른 서비스들 간의 통신을 담당 (e.g. 프론트엔드와 백엔드)
- 여러 개의 서비스 pod(e.g. 백엔드)를 위한 단일한 인터페이스를 제공
YAML
- apiVersion: v1
- kind: Service
- metadata:
- spec:
- type: ClusterIP (서비스의 기본타입)
- ports:
- -targetPort: 80 (백엔드가 노출되는 포트)
- port: 80 (서비스가 노출되는 포트)
- selector: pod의 labels 정보 가져오기
- app: myapp
- type: back-end
LoadBalancer
- 로드 트래픽을 여러 다른 웹서버로 분산하는 역할
- 여러 개의 클러스터 노드 IP에 대해 개별 접속하는 것이 아니라 단일한 경로로 서비스를 사용할 수 있도록 도움
- NodePort 대신 LoadBalancer 사용할 수 있음
- Google Cloud Platform 등에서는 사용 가능
- VirtualBox에서는 사용 불가
명령어
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)
- 네임스페이스마다 다른 정책 사용 가능 (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:
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
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 내에 저장됨
- 어떤 필드가 삭제되었는지 확인 용이
깔끔하고 정성스러운 포스트 감사합니다. CKA를 공부하고 있는데, 도움이 많이 될 것 같아요. 종종 방문하겠습니다! :)