
Mumshad Mannambeth 님의 Certified Kubernetes Administrator (CKA) with Practice Tests 강의를 들으며 정리한 내용들입니다.
Udemy Mumshad님- CKA 강의 들으러 가기

⚠️ 쿠버네티스는 워커노드에 직접 배포하지 않음
→ 컨테이너는 Pod 라는 객체(Object)로 캡슐화됨
Pod는 Application의 단일 인스턴스
일반적으로 Application을 실행하는 컨테이너 : 파드 = 1 : 1
네트워크 공유자원 공유로그 수집기 (Log Shipper)데이터 동기화 (Data Sync)프록시 (Proxy)# 이미지를 사용하여 파드 생성하기
kubectl run nginx-image nginx
# 파드 목록 확인하기
kubectl get pods
# Pod-definition.yml
apiVersion: "k8s API 버전" # Strings
kind: "객체의 종류" # Strings
metadata: "이름표" # Dictionary
name: # String
labels: # - Dictionary
app: # - Dictionary
type: # - Dictionary
spec: # Dictionary
containers: # - List / Array
- name: # 목록의 첫번째 요소 앞에 '-'작성
image:
최상위 / 루트 수준의 속성 → 필수
apiVersionkindmetadataK8s API 버전
# 파드 생성
kubectl create -f pod-definition.yml
# 파드 상태 확인
kubectl get pods
# 파드의 상세 정보 확인
kubectl describe pod myapp-po
kube createkube applykubectl run nginx --image=nginx --dry-run=client -o yaml > pod.yaml
# 파드 개수 확인
kubectl get pods
# 파드가 0개일 때 >>> No resources found in default namespace.
# nginx image를 사용하여 새로운 파드 생성하기
# kubectl run [이름] --image=[이미지명]
kubectl run nginx --image=nginx
# newpods-xxxx 파드들이 어떤 컨테이너 이미지를 사용해서 만들었는지 확인
kubectl describe pods newpods-
# 어떠한 노드에 파드가 위치하는지 확인
kubectl describe pods <pod name>
# >>> Node: 항목 확인
# webapp 파드 삭제하기
kubectl delete pod webapp
# 잘못된 이미지를 사용하여 파드를 생성한 경우
kubectl run redis --image=redis123123
# kubectl get pods > STATUS: ErrImagePull
# 이미지를 수정하는 법
# 1) set image 사용
# kubectl set image pod/[파드이름] [컨테이너이름]=[새로운이미지]
kubectl set image pod/redis redis=redis
# 2) 에디터를 열어서 설정 파일을 직접 수정
# kubectl edit pod [파드이름]
kubectl edit pod redis
kubectl get pods 의 실행 결과 중 READY 열에 있는 숫자들의 의미는?rc-definition.yamlapiVersion: v1
kind: ReplicationController
metadata: # -->> Replication Controller
name: myapp-rc
labels:
app: myapp
type: front-end
spec: # -->> Replication Controller
template:
metadata: # -->> Pod
name: myapp-pod
labels:
app: myapp
type: front-end
spec: # -->> Pod
containers:
- name: nginx-container
image: nginx
replicas: 3
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
selector 정의가 필요함쿠버네티스에서 파드와 오브젝트에 레이블을 지정하는 이유는 무엇일까?
- 클러스터에는 서로 다른 애플리케이션을 실행하는 수백 개의 다른 파드가 있을 수 있음. → 레이블을 통해 ReplicaSet 이 모니터링할 파드를 알 수 있음
definition.yaml 파일의 replicas 항목을 변경# 입력으로 제공하는 파일에 따라 Replicaset 등 쿠버네티스의 모든 오브젝트 생성
kubectl create -f replicaset-definition.yaml
# 생성된 레플리카셋의 정보 확인
kubectl get replicaset
# 레플리카셋 삭제
kubectl delete replicaset myapp-replicaset
# 레플리카셋 교체 및 업데이트
kubectl replace -f replicaset-definition.yaml
# 레플리카셋 확장
kubectl scale --replicas=6 -f [파일 이름]
# 현재 존재하는 파드의 수
kubectl get pods
# 현재 존재하는 레플리카셋의 수
kubectl get replicasets
# 특정 레플리카셋에서 DESIRED 상태의 파드 개수 조회
kubectl get replicaset new-replica-set
# 특정 레플리카셋에서 사용된 이미지 정보
kubectl describe replicaset new-replica-set
# 레플리카셋을 생성하기
kubectl create -f replicaset-def.yaml
Deployment 는 ReplicaSet 의 상위 객체로, RollingUpdate 를 통해 무중단 배포를 가능하게 하고 장애 시 손쉽게 Rollback 할 수 있게 해주는 배포 관리자.
Deployment : 배포 전략(업데이트, 롤백)을 결정하는 두뇌ReplicaSet : 지정된 개수의 파드가 항상 떠 있도록 유지하는 관리자Pod : 실제 애플리케이션이 돌아가는 최소 단위방식 : 새 버전의 파드를 하나 만들고, 확인이 되면 구 버전의 파드를 하나 죽임. 이를 반복함장점 : 사용자가 서비스가 끊기는 것을 전혀 느끼지 못함 (Zero Downtime)Rollback : 만약 새 버전에 버그가 있다면, 즉시 이전 상태의 ReplicSet으로 되돌릴 수 있음추상화 : 파드나 레플리카셋을 직접 만지는 대신, 더 높은 수준의 객체인 Deployment 를 통해 모든 것을 제어배포 전략 제어 : RollingUpdate 뿐만 아니라 한 번에 싹 다 바꾸는 Recreate 방식도 선택 가능버전 관리(History) : 배포 기록이 남기 때문에 언제든 과거의 특정 시점으로 복구할 수 있음# Deployment 정보 조회
kubectl get deployment
# Deployment 상세 정보 조회
kubectl describe deployment <Deployment Name>
# Deployment 생성
kubectl create -f <deployment-file.yaml>
# Name, Replicas 수, Image 정보가 주어졌을 때 새로운 디플로이먼트 생성
kubectl create deployment httpd-frontend --image=httpd:2.4-alpine --replicas=3 --dry-run=client -o yaml > httpd-frontend.yaml
Service는 동적으로 변하는 파드들에게
고정된 IP와DNS 이름을 제공하는 네트워크 객체
| 유형 | 용도 | 특징 |
|---|---|---|
ClusterIP(기본값) | 내부 통신용 | 클러스터 내부에서만 접근 가능. 프론트엔드가 백엔드를 찾을 때 사용 |
NodePort | 외부 접속용 (테스트) | 모든 노드의 특정 포트(30000~32767)를 열어 외부 접속 허용 |
LoadBalancer | 운영 접속용 | CSP의 로드밸런서를 생성하여 외부와 연결 |
NodePort (30008)
Port (80)
TargetPort (80)
실제 파드(컨테이너) 안에서 애플리케이션이 리스닝하는 포트 (실제 방)
단일 서비스 내에 포트 매핑을 여러 개 가질 수 있음
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
type: NodePort
ports:
- targetPort: 80 # 파드의 포트
port: 80 # 서비스의 포트
nodePort: 30008 # 외부 접속 포트
selector:
app: myapp
type: front-end
selectorEndpoints 라는 객체로 관리# 생성 명령
kubectl create -f service-definition.yml
📌 하나의 노드에 동일한 레이블을 갖는 파드가 여러 개 존재하는 경우
- 애플리케이션을 여러 인스턴스로 실행하는 경우(ex: 3개)
- 서비스를 생성하는 동안 동일한 레이블이 selector로 사용됨.
- 서비스가 생성되면 레이블과 일치하는 파드를 찾고 그 중 3개를 찾음
- 서비스는 자동으로 3개의 파드를 모두 엔드포인트로 선택하여 외부 요청을 전달
- 3개의 서로 다른 파드 간에 부하를 분산하기 위해서
랜덤 알고리즘을 사용
📌 파드가 여러 노드에 분산되어 있는 경우
- 서비스를 생성하면 쿠버네티스는 클러스터의 모든 노드에 걸쳐 서비스를 자동으로 생성하고 대상 포트를 클러스터의 모든 노드에 있는 동일한 노드 포트에 매핑
고정된 대표 IP를 하나 만들어 줌apiVersion: v1
kind: Service
metadata:
name:back-end
spec:
type: ClusterIP # 생략 시 자동으로 ClusterIP 할당
ports:
- targetPort: 80
port: 80
selector:
app: myapp
type: back-end
targetPortport단일 진입점 : 노드가 100개라도 사용자는 클라우드 업체가 준 IP 하나로만 접속할 수 있음부하 분산 : 외부 로드밸런서가 여러 노드로 트래픽을 골고루 나눠줌보안 : 사용자가 노드의 개별 IP나 3만 번대 포트를 알 필요가 없음 (보통 80, 443 포트 사용 가능)apiVersion: v1
kind: Service
metadata:
name: frontend-lb
spec:
type: LoadBalancer # 클라우드 업체에 LB 생성을 요청함
ports:
- port: 80 # 사용자가 접속할 외부 포트 (LB의 포트)
targetPort: 80 # 파드 내부의 포트
selector:
app: myapp
| 구분 | ClusterIP | NodePort | LoadBalancer |
|---|---|---|---|
| 주요 용도 | 내부 통신용 | 외부 접속용 (테스트/개발) | 외부 접속용 (운영/실서비스) |
| 접근 범위 | 클러스터 내부에서만 가능 | 노드 IP + 포트를 통해 외부 가능 | 단일 외부 IP를 통해 외부 가능 |
| 포트 할당 | 서비스 내부 포트만 사용 | 모든 노드에 동일 포트(30000~32767) 개방 | CSP가 제공하는 포트(80, 443 등) 사용 |
| IP 특징 | 클러스터 내부 가상 IP | 노드 각각의 실제 IP 사용 | 클라우드가 할당한 고정 외부 IP |
| 계층 관계 | (가장 기본) | ClusterIP를 포함 | ClusterIP + NodePort를 모두 포함함 |
| 환경 제약 | 모든 환경 지원 | 모든 환경 지원 | CSP 환경 필수 |
Namespace 는 하나의 물리적 클러스터를 여러 개의 논리적인 가상 클러스터로 나누는 ‘방 나누기’ 개념
리소스 격리 및 할당량(Resource Quota)보안 및 정책엔터프라이즈 확장성defaultkube-systemkube-public<서비스명>.<네임스페이스>.<서비스종류(svc)>.<도메인(cluster.local)>
# ex
mysql.dev.svc.cluster.local
# 현재 네임스페이스의 파드만 보기
kubectl get pods
# 특정 네임스페이스의 파드 보기
kubectl get pods -n <네임스페이스명>
# 전체 네임스페이스의 파드 보기
kubectl get pods -A
kubectl get pods --all-namespaces
# 새 네임스페이스 만들기
kubectl create namespace <네임스페이스명>
# 특정 네임스페이스에 파드 바로 띄우기
kubectl run <파드명> --image=<이미지> -n <네임스페이스명>
# Dry-run 으로 설계도 뽑기
kubectl run redis --image=redis -n finance --dry-run=client -o yaml > redis-pod.yaml
# 기본 네임스페이스 변경하기
kubectl config set-context $(kubectl config current-context) --namespace=<네임스페이스명>
Imperative
Declarative
kubectl apply -f 명령으로 쿠버네티스가 스스로 작업을 결정하여 진행kubectl runkubectl createkubectl exposekubectl editkubectl scalekubectl set오브젝트 정의 파일, 구성 파일 또는 매니페스트 파일을 생성하면 오브젝트의 모양을 YAML 형식으로 정확히 기록하고 kubectl create 명령을 사용하여 오브젝트를 생성하는데 도움이 될 수 있다.
# Create Objects
kubectl create -f nginx.yaml
# Update Objects
kubectl edit deployment nginx
kubectl replace -f nginx.yaml
kubectl replace --force -f nginx.yaml
# Create Objects
kubectl apply -f nginx.yaml
kubectl apply -f /path/to/config-files
# Update Objects
kubectl apply -f nginx.yaml
NAMESHORTNAMESAPIVERSIONNAMESPACEDtruefalseKINDkubectl explains <리소스명>kubectl explain pods.spec.containerskubectl explain pods --recursive# 파드 생성 / 파드명, 이미지명
kubectl run <파드명> --image=<이미지명>
# 파드 생성 / 파드명, 이미지명, 라벨
kubectl run <파드명> --image=<이미지명> --labels="<레이블명>"
# 서비스 생성 / 서비스명, 이미 존재하는 파드 연결, 클러스터 내부에서 노출, 포트 설정
kubectl expose pod <파드명> --port=<포트번호> --name=<서비스명>
# 디플로이먼트 생성 / 디플로이먼트명, 이미지명, 레플리카 수
kubectl create deployment <디플로이먼트명> --image=<이미지명> --replicas=<레플리카수>
# 파드 생성 / 파드명, 이미지명, 포트번호
kubectl run <파드명> --image=<이미지명> --port=<포트번호>
# 네임스페이스 생성 / 네임스페이스명
kubectl create ns <네임스페이스명>
# 디플로이먼트 생성 / 디플로이먼트명, 네임스페이스명, 이미지명, 레플리카수
kubectl create deployment <디플로이먼트명> --image=<redis> --replicas=2 -n <네임스페이스명>
# 파드 생성 / 파드명, 이미지명, 서비스 타입, 포트번호, 네임스페이스=default
# 1. default 네임스페이스에 이미지명을 명시한 파드 생성
kubectl run <파드명> --image=<이미지명>
# 2. 서비스 생성
kubectl expose pod <파드명> --port=<포트번호> --name=<서비스명> --type=<서비스타입>
# 클러스터에서 사용할 수 있는 모든 API 리소스 목록 조회
kubectl api-resources
# 리소스의 SHORTNAME 조회
kubectl api-resources | grep <리소스명>
# 리소스의 정의와 상세 명세 확인
kubectl explain pods
# 실행 중인 인스턴스의 상태 확인
kubectl describe pods
# YAML 명세서(Manifest)를 작성할 때, containers 항목 아래에 어떤 필드를
# 사용할 수 있는지 확인하는 법
kubectl explain pods.spec.containers
# kubectl explain 과 함께 --recursive 플래그를 사용하면?
-> 하위 필드의 하위 필드까지(Nested fields) 모든 구조를 한 번에 펼쳐서 보여줌
📌 Cluster-scoped Resources
→ 특정 네임스페이스에 할당되지 않으며, 클러스터 전체 인프라 및 관리 정책을 정의
Nodes
- 클러스터를 구성하는 물리적 또는 가상 머신 객체로, 모든 네임스페이스의 파드가 스케줄링 되는 기반 리소스
Namespaces
- 리소스를 논리적으로 격리하는 최상위 추상화 객체 자체
- 다른 네임스페이스에 포함될 수 없음
PersistentVolumes (PV)
- 스토리지 클래스에 의해 할당된 실제 물리적 스토리지 리소스
- 클러스터 수준에서 관리되며 특정 네임스페이스의 PVC(PersistentVolumeClaim)에 바인딩 되어 사용
ClusterRoles / ClusterRoleBindings
- 특정 네임스페이스에 국한되지 않고 클러스터 전체 리소스에 대한 권한 제어(RBAC)를 정의하는 보안 객체
APIService / CustomResourceDefinition (CRD)
- API 서버의 기능을 확장하거나 새로운 리소스 타입을 정의하는 메타 데이터 성격의 리소스
📌 Namespaced Resources
→ 특정 네임스페이스 내에서만 고유한 이름을 가지며, 해당 네임스페이스의 정책과 할당량(Resource Quota)의 제한을 받음
Workload Resources (Pods, Deployments, ReplicaSets, StatefilSets)
- 실제 컨테이너가 실행되는 단위로, 네임스페이스 단위의 스케줄링 및 관리가 이루어짐
Discovery & LB Resources (Services, Endpoints, Ingress)
- 파드 집합에 대한 네트워크 접근 지점을 정의하며, 동일 네임스페이스 내 리소스와 우선적으로 통신함
Config & Storage Resources (ConfigMaps, Secretes, PVCs)
- 애플리케이션 설정 정보나 민감 정보, 그리고 특정 네임프세이스 내 파드가 요청한 스토리지 볼륨 요청서
Local FileLive Object ConfigurationLast Applied ConfigurationLast Applied Configuration 을 저장하는 장소
저장 위치
Live Object 의 metadata.annotations 필드 안에 kubectl.kubernetes.io/last-applied-configuration 라는 키로 저장됨저장 형식
→ 왜 필요할까?