Kubernetes는 컨테이너 오케스트레이션 플랫폼 중 하나로 다수의 컨테이너 어플리케이션을 운영 및 관리하고, 배포하고, 확장할 수 있는 여러 자동화된 기능들을 제공하고 있습니다. 본 포스팅에서는 Kubernetes의 기본 개념부터, kubectl, helm 등에 대해 기록합니다.
Kubernetes Components
쿠버네티스 클러스터를 갖기 위해 필요한 요소들은 다음과 같습니다.
-
컨트롤 플레인 컴포넌트
- kube-apiserver: Kubernetes API 서버로서 클러스터의 모든 요청을 처리하고 인증, 권한 부여, API 검증/설정을 담당
- etcd: 모든 클러스터 데이터를 저장하는 고가용성 키-값 저장소로, Kubernetes의 상태를 유지
- kube-scheduler: 새로 생성된 Pod에 적합한 노드를 선택하는 스케줄링 작업을 수행
- kube-controller-manager: 노드, 레플리카, 엔드포인트 등의 상태를 지속적으로 관리하고 조정하는 컨트롤러들을 실행
- cloud-controller-manager: 클러스터 자원을 관리하고 조정
-
노드 컴포넌트
-
kubelet: 각 노드에서 실행되며 Pod 및 컨테이너의 상태를 관리하고 보고
-
kube-proxy: 네트워크 프록시로서 네트워킹을 관리하고 Kubernetes 서비스 간의 통신을 처리
-
컨테이너 런타임 (Kubernetes CRI - containerd, CRI-O...): 컨테이너를 실행하고 관리하는 소프트웨어
-
-
애드온
-
DNS: Kubernetes 서비스 간의 이름 해석을 제공하여 네트워킹을 간소화
-
웹 UI (대시보드): 클러스터의 상태를 모니터링하고 관리하기 위한 사용자 인터페이스를 제공
-
컨테이너 리소스 모니터링: 각 컨테이너의 리소스 사용량을 추적하고 모니터링
-
클러스터-레벨 로깅: 클러스터 내의 로그 데이터를 수집하고 저장하여 문제 해결과 감사에 사용
-
Kubernetes Objects
쿠버네티스 시스템에서 영속성을 가지는 오브젝트 kubernetes objects라고 말하는데, 공식 홈페이지에서는 '하나의 의도를 담은 레코드'라고 설명하고 있습니다.
- 어떤 애플리케이션이 동작 중이고, 어느 노드에서 위치하는지 기술
- 해당 애플리케이션이 이용할 수 있는 리소스 기술
- 해당 애플리케이션의 재구동 정책, 업그레이드 정책 등 여러 정책적 요소는 어떤지 기술
Object spec
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80-
apiVersion: 오브젝트를 생성에 사용되는 쿠버네티스 API 버전- POD: v1
- Service: v1
- ReplicaSet: apps/v1
- Deployment: apps/v1
-
kind: 오브젝트 종류 -
metadata: 클러스터 내에서 오브젝트를 구분지어 주기 위한 정보- name: 오브젝트의 이름
- labels: 비슷한 오브젝트들을 연결지어주는 레이블
-
spec: 오브젝트에 대해 어떤 상태를 의도하는지에 대한 정보
Resources
-
Workloads
-
Pod: 하나 이상의 컨테이너를 포함하는 가장 작은 배포 단위
-
ReplicationController: 원하는 수의 Pod를 유지하도록 관리 (거의 사용되지 않고 ReplicaSet으로 대체)
-
ReplicaSet: 특정 수의 Pod를 유지하도록 관리
-
Deployment: 애플리케이션의 선언적 업데이트를 제공
-
StatefulSet: 고유하고 안정적인 네트워크 식별자와 스토리지의 순서를 보장하는 애플리케이션을 관리
-
DaemonSet: 모든 (또는 일부) 노드에서 실행되는 Pod를 보장
-
Job: 일회성 작업을 관리하고 완료를 보장
-
CronJob: 일정에 따라 주기적으로 작업을 수행
-
-
Network
-
Service: Pod 간의 네트워크 접속을 관리
-
Ingress: 외부 HTTP 및 HTTPS 트래픽을 클러스터 내의 서비스로 라우팅
-
NetworkPolicy: Pod의 네트워크 트래픽을 제어
-
이 외, Endpoint, Network policy, Port forwarding...
-
-
Config
-
ConfigMap: 애플리케이션 설정 데이터를 저장하고 관리
-
Secret: 민감한 데이터(예: 비밀번호, 토큰, 키)를 저장하고 관리
-
ResourceQuota: 네임스페이스 내에서 리소스 사용량을 제한
-
LimitRange: 네임스페이스 내의 리소스 사용량을 제한하고 요청과 한계를 정의
-
-
Access Control
-
ServiceAccount: Pod에 권한을 부여하기 위한 사용자 계정
-
Role: 네임스페이스 내 리소스에 대한 권한을 정의
-
ClusterRole: 클러스터 전체에 걸쳐 리소스에 대한 권한을 정의
-
RoleBinding: 네임스페이스 내의 사용자/그룹에 역할을 부여
-
ClusterRoleBinding: 클러스터 전체의 사용자/그룹에 역할을 부여
-
-
Storage
-
PersistentVolume (PV): 클러스터 내의 스토리지 리소스를 나타냄
-
PersistentVolumeClaim (PVC): 사용자와 Pod가 사용할 스토리지를 요청
-
StorageClass: 스토리지 제공자의 스토리지 설정을 정의
-
VolumeAttachment: 외부 스토리지 시스템의 볼륨을 클러스터의 노드에 연결
-
-
etc.
-
Namespace: 논리적으로 클러스터 리소스를 그룹화
-
PodSecurityPolicy: Pod 보안 정책을 정의하여 Pod의 보안 설정을 제어
-
HorizontalPodAutoscaler: 애플리케이션의 부하에 따라 Pod의 수를 자동으로 조정
-
VerticalPodAutoscaler: Pod의 리소스 요청을 자동으로 조정
-
PodDisruptionBudget: 클러스터 관리 중에 서비스 가용성을 보장하기 위한 최소 Pod 수를 정의
-
CustomResourceDefinition (CRD): 사용자 정의 리소스를 정의하여 Kubernetes API를 확장
-
Kubectl
Kubernetes API를 사용하여 쿠버네티스 클러스터의 컨트롤 플레인과 통신하기 위한 커맨드라인 툴을 kubectl 이라고 합니다. kubectl 관련 명령어, 지원 리소스 타입, 출력 설정 등에 대한 더 자세한 설명은 공식 홈페이지에 기술되어 있습니다.
kubectl [command] [TYPE] [NAME] [flags]-
command: 수행할 작업을 지정get: 리소스 조회create: 새로운 리소스 생성apply: YAML 파일을 이용해 리소스를 생성 또는 업데이트delete: 리소스 삭제describe: 리소스의 상세 정보를 표시edit: 리소스 편집logs: 특정 Pod의 로그 조회
-
TYPE: 리소스 타입을 지정. 리소스 유형은 단수형과 복수형을 모두 사용할 수 있음pod,pods,deployment,deployments,service,services,node,nodes,configmap, etc.
-
NAME: 작업할 리소스의 유형을 지정. 이름 생략시, 해당 리소스 유형의 모든 인스턴스를 대상으로 명령 적용-
리소스가 모두 동일한 타입인 경우:
TYPE1 name1 name2 name<#>:kubectl get pod example-pod1 example-pod2 -
여러 리소스 타입을 개별적으로 지정하고 싶은 경우:
TYPE1/name1 TYPE1/name2 TYPE2/name3 TYPE<#>/name<#>:kubectl get pod/example-pod1 replicationcontroller/example-rc1 -
하나 이상의 파일로 리소스를 지정하려는 경우:
-f file1 -f file2 -f file<#>
-
-
flags: 선택적 플래그-s또는--server: 쿠버네티스 API 서버의 주소와 포트를 지정-n또는--namespace: 명령을 실행할 네임스페이스를 지정-o또는--output: 출력 형식을 지정 (-o yaml,-o json,-o wide)--kubeconfig: 특정 kubeconfig 파일을 사용하도록 지정--context: 명령을 실행할 kubeconfig 컨텍스트를 지정
YAML
-
데이터 표현: 데이터는 key, value 형태로 표현됨
-
Indentation: 기본적으로는 2칸을 권장(helm에서는 2칸만 지원)하며 4칸도 가능
-
Boolean: true, false 뿐만 아니라 yes, no도 지원
-
List: 하이픈('-')으로 표현
- dict와 list를 abbrviate 형태로 표현도 가능함
- e.g.,
martin: {name: Martin D'vloper, job: Developer, skill: Elite} - e.g.,
fruits: ['Apple', 'Orange', 'Strawberry', 'Mango']
-
Multiline string
|: 블록 내 줄바꿈 문자를 유지>: 블록 내 줄바꿈 문자를 스페이스로 변환|-: 마지막 줄바꿈을 제외하고 인식
-
---: 문서의 시작 (optional) -
...: 문서의 끝 (optional)
Core Concepts for CKA
- k8s에서 pod을 yaml 기반으로 선언하는 간단한 예제
kubectl apply -f pod.yaml를 통해 적용 가능
# pod definition
apiVersion: v1
kind: Pod
metadata:
name: my-simple-pod
labels:
app: my-app
spec:
containers:
- name: my-container
image: nginx:latest
ports:
- containerPort: 80- RepicaSets: 특정 개수의 동일한 Pod이 항상 실행되도록 보장. 그러나 보통 Deployment를 통해 관리
- 라벨 셀렉터를 사용해 관리할 Pod을 식별
- 수동으로 업데이트 필요하며, 롤백 지원하지 않음
- Deployments: ReplicaSet의 상위 개념으로, Pod과 ReplicaSet에 대한 선언적 업데이트를 제공. 애플리케이션의 배포를 쉽게 관리하며, 무중단 업데이트를 보장
- 롤링 업데이트 및 롤백 기능 제공
# k8s yaml definition for ReplicaSet
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: my-replicaset
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template: # 위의 pod.yaml에서 내용 거의 그대로 가져오면 됨
metadata:
labels:
app: my-app
spec:
containers:
- name: my-container
image: nginx:latest- Service: Pod의 네트워크를 노출하고, 로드밸런싱을 제공하여 클러스터 내부와 외부에서 안정적으로 애플리케이션에 접근할 수 있도록 도와줌
| Type | Internal | External | Description |
|---|---|---|---|
| ClusterIP | O | X | 클러스터 내부에서만 접근 가능한 내부 IP를 생성 |
| NodePort | O | O | 테스트 또는 간단한 외부 노출을 위해, 클러스터 외부에서 접근 가능하도록 각 노드의 특정 포트를 열어즘 (노드의 IP 사용) |
| LoadBalancer | O | O | '클라우드 환경'에서 외부 로드밸런서를 자동으로 생성해 외부 접근을 제공. 클라우드 제공 업체(AWS, GCP, Azure 등)의 네트워크 로드밸런서를 사용하며, NodePort와 ClusterIP를 내부적으로 사용 |
| ExternalName | - | O | DNS 이름을 사용해 클러스터 외부 서비스로 요청을 라우팅. 클러스터 외부의 데이터베이스나 API 서버를 Kubernetes 네임스페이스 내부에서 사용할 수 있도록 설정하여 외부 서비스와의 통합 가능 |
| Headless | O | X | Stateful 애플리케이션 또는 Pod 직접 접근 |
- Namespace: 하나의 클러스터를 논리적으로 분리하여 여러 애플리케이션, 팀, 환경(예: 개발, 테스트, 프로덕션)을 독립적으로 관리할 수 있도록 하는 가상 클러스터
- default: 특별히 지정하지 않은 리소스가 생성되는 기본 namespace
- kube-system: Kubernetes 시스템 구성 요소(Pod, Service 등)가 포함된 namespace
- kube-public: 모든 사용자가 읽기 가능한 공개 namespace
- kube-node-lease: 각 노드의 상태를 추적하기 위해 사용
- yaml apply 혹은
kubectl create namespace my-namespace통해 생성 가능
# kubectl apply -f namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: my-namespaceScheduling
- Manual Scheduling
- k8s에서 이미 생성된 pod의 nodeName 변경은 불가
- 따라서 이미 생성된 pod에 node를 할당하려면, Binding object를 생성하고 binding API에 요청 보내기
- Label: 기본 형식은
<prefix>/<name>형태인데 prefix는 선택사항이고, 일반적으로 도메인 이름 형식을 따름 (예:example.com/mylabel).kubectl get pods --selector app=App1과 같은 형태로 필터링 가능app: 애플리케이션 이름.env: 환경 정보 (예:production,staging,dev).tier: 애플리케이션 계층 (예:frontend,backend,database).role: 역할 정보 (예:web-server,data-store).function: 특정 기능을 나타내는 라벨.
apiVeision: v1
kind: Pod
metadata:
name: simple-webapp
labels:
app: App1
function: Front-End- Taints: 노드에 적용되어 특정 파드가 해당 노드에 스케줄링되지 못하게 하는 메커니즘입니다. 노드에 Taint(오염)가 설정되면, 해당 Taint를 "참을 수 있는" 파드(Toleration)가 아니면 그 노드에 배치되지 않습니다.
- Key: Taint의 이름 또는 속성 / Value: 선택 사항으로, Key에 대한 추가 정보 제공 / Effect: Taint의 효과를 정의하며, 아래 중 하나를 사용
NoSchedule: Taint를 참을 수 없는 파드는 이 노드에 배치되지 않음PreferNoSchedule: 가능한 한 이 노드에 배치되지 않으나, 강제하지 않음NoExecute: 즉시 노드에서 파드를 제거하며, 새 파드도 스케줄링되지 않음- 흥미로운 사실: Master node는 NoSchedule taints가 걸려있고, 어떠한 application pod도 뜨지 않음
key=value:effect- Toleration: 파드가 특정 Taint를 "참을 수 있도록" 허용하는 설정입니다. Toleration이 없는 파드는 Taint가 있는 노드에 스케줄링될 수 없습니다.
- Key: Taint의 Key와 일치해야 함
- Operator:
Equal는 Key와 Value가 일치해야 Toleration 인정 /Exists는 Key만 일치하면 Toleration 인정 - Value: Taint의 Value와 일치해야 함 (Equal인 경우에만 사용)
- Effect: Taint의 Effect와 일치해야 함
apiVersion: v1
kind: Pod
metadata:
name: toleration-example
spec:
tolerations:
- key: "dedicated"
operator: "Equal"
value: "web"
effect: "NoSchedule"
containers:
- name: nginx
image: nginx- Node Selector: Pod를 특정 Node에 스케줄링하기 위한 가장 간단한 메커니즘. Pod의 스펙에
nodeSelector필드를 정의하여 특정 라벨을 가진 Node에만 Pod를 스케줄링하도록 제한- 복잡한 조건이나 논리 연산(예: OR, NOT)을 지원하지 않음
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
nodeSelector:
disktype: ssd- Node Affinity: Node Selector의 한계를 보완하며, 더 유연하고 고급 스케줄링 옵션을 제공
requiredDuringSchedulingIgnoredDuringExecution: 필수 조건, 만족하지 않으면 스케줄링되지 않음preferredDuringSchedulingIgnoredDuringExecution: 선호 조건, 가능하면 스케줄링하되 반드시 만족할 필요는 없음- 다중 조건 지원 (예: AND, OR)
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: region
operator: In
values:
- us-west-1
containers:
- name: my-container
image: nginx- Requirements & Limits
- no request & no limit: 하나의 pod이 너무 많은 node cpu 차지할 수 있음
- no request & limit: 이 경우는 k8s에서 자동으로 request = limit으로 설정
- request & limit: 특정 pod이 cpu 많이 필요한 작업을 할 때, limit 때문에 최고 효율 내지 못할 수 있음
- request & no limit: 기본적인 cpu 보장 받으면서도 필요할 때 효율도 낼 수 있음
- 대신 메모리의 경우엔, cpu와 달리 memory가 꽉 차면 pod을 일부 죽이는 수 밖에 없다.
- DemonSets: 클러스터의 모든 (또는 선택된) node에 특정 pod를 하나씩 실행하도록 보장하는 리소스
- monitoring solution & logs viewer에 사용
- kube-proxy나 weave-set도 DemonSet 중 하나임
- Static Pods: api server를 거치지 않고, 특정 node에서 직접 kubelet에 의해 관리되는 pod
- 사용 예제: 클러스터의 기본 컴포넌트 실행(예: etcd, kube-apiserver, kube-controller-manager), API 서버 없이 동작해야 하는 고가용성 환경, 등
- 장점: api server가 다운되더라도 pod를 유지 가능, Kubernetes 외부에서 독립적으로 실행 가능.
- 단점: 중앙에서 관리할 수 없으며 수동 작업 필요, 상태나 변경 사항을 Kubernetes 클러스터에서 쉽게 확인하거나 수정할 수 없음.
- Scheduling Plugins: 아래 플러그인 외에도 커스텀 가능
- Scheduling queue: PrioritySort
- Filtering: NodeResourcesFit, NodeName, NodeUnschedulable, ...
- Scroing: NodeResourcesFit, ImageLocality, ...
- Binding: DefaultBinder
Application Lifecycle Management
-
Rolling Update:
kubectl apply명령어를 사용하여 deployment를 업데이트하면, rollout update가 자동으로 수행됨-
kubectl rollout status deployment <deployment-name>: rollout 상태 확인 -
kubectl rollout restart deployment <deployment-name>: deployment 업데이트하지 않고, rollout 방식으로 pod restart
-
-
Rollback: Deployment를 이전 상태로 복구하는 작업
kubectl rollout undo deployment <deployment-name>: 바로 이전의 상태로 복구kubectl rollout history deployment <deployment-name>: revision 기록 확인 (revision-number 확인 가능)kubectl rollout undo deployment <deployment-name> --to-revision=<revision-number>: 특정 버전으로 복구- Kubernetes는 기본적으로 Deployment의 최대 10개 Revision을 기록. 이 제한은
revisionHistoryLimit필드로 설정할 수 있음
-
ConfigMap: 환경설정 데이터를 관리하기 위한 리소스
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
data:
key1: value1
key2: value2apiVersion: v1
kind: Pod
metadata:
name: pod-using-configmap
spec:
containers:
- name: my-container
image: nginx
env:
- name: MY_KEY1
valueFrom:
configMapKeyRef:
name: my-config
key: key1- Secret: 민감한 데이터를 안전하게 저장하고 관리하기 위한 리소스. 기본적으로 Base64로 인코딩되어 저장되지만, 암호화되어 있지는 않음
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
data:
username: bXktdXNlcg== # "my-user"의 Base64 값
password: bXktcGFzcw== # "my-pass"의 Base64 값apiVersion: v1
kind: Pod
metadata:
name: pod-using-secret
spec:
containers:
- name: my-container
image: nginx
env:
- name: USERNAME
valueFrom:
secretKeyRef:
name: my-secret
key: username-
Multi-Container Pods: 앱과 logger를 함께 들고다니고 싶을 때, 이런 경우 multi-contianer 형태의 pod 활용해봐도 좋음. localhost로 통신 가능
-
Sidecar 패턴: 애플리케이션 컨테이너와 이를 보조하는 컨테이너를 함께 실행 (e.g., 애플리케이션 컨테이너와 로그를 수집하는 Fluentd 컨테이너)
-
Ambassador 패턴: 특정 서비스와의 통신을 처리하는 컨테이너(프록시 역할)를 포함
-
initContainer: 애플리케이션 컨테이너가 시작되기 전에 실행되는 컨테이너. InitContainer는 초기화 작업을 수행하고 종료된 후에 애플리케이션 컨테이너 실행 (예시: 애플리케이션 컨테이너의 실행 전 데이터 준비, 권한 설정, 네트워크 연결 테스트, 디펜던시 다운로드 등)
-
apiVersion: v1
kind: Pod
metadata:
name: init-container-pod
spec:
initContainers:
- name: init-container
image: busybox
command: ["sh", "-c", "echo 'Initializing...' && sleep 5"]
volumeMounts:
- name: shared-data
mountPath: /app/data
containers:
- name: app-container
image: nginx
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
volumes:
- name: shared-data
emptyDir: {}Cluster Maintenance
-
OS Upgrades
-
Drain:
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data, 노드에서 실행 중인 모든 pod을 다른 노드로 이동시키는 작업 -
Cordon:
kubectl cordon <node-name>, 노드를 스케줄링 대상으로 지정하지 않도록 설정. 새로운 pod이 해당 노드에 할당되지 않도록 하기 위해 사용 -
Uncordon:
kubectl uncordon <node-name>, cordon 상태를 해제하여 노드가 다시 pod을 받을 수 있도록 함
-
-
Cluster Upgrades
-
전략 1. Master node를 업데이트한 뒤에, worker node를 하나씩 업그레이드. 이 때, 업그레이드 할 worker node는 다른 node로 drain & uncordon
-
전략 2. Master node를 업데이트한 뒤에, worker node를 하나씩 업그레이드. 이 때, 업그레이드시 대용으로 사용할 새로운 node 추가
-
-
Backup & Restore
- 전략 1. Resource Configuration Backup: 모든 Kubernetes 리소스의 YAML 또는 Helm 차트를 GitHub 같은 버전 관리 시스템에 저장,
kubectl get all --all-namespaces -o yaml > cluster-backup.yaml - 전략 2. ETCD Cluster Backup,
ketcdctl snapshot save <snapshot.db> ...이후에ketcdctl snapshot restore <snapshot.db> --data-dir=<new-data-dir>
- 전략 1. Resource Configuration Backup: 모든 Kubernetes 리소스의 YAML 또는 Helm 차트를 GitHub 같은 버전 관리 시스템에 저장,
Security
-
Basics
- Authentication: "누가" 접근 가능한지
- Authorization: 그들이 "어떤 행위"를 할 수 있는지
- TLS(Transport Layer Security): 클라이언트와 서버 간의 통신을 암호화하여 데이터의 기밀성과 무결성을 보장하는 프로토콜
- Certificate API: 클러스터 내에서 TLS 인증서를 관리하는 메커니즘을 제공
-
KubeConfig: KubeConfig 파일을 사용하여 클러스터와 사용자 간의 인증 및 연결을 설정
- clusters: 클러스터의 API 서버 정보를 포함. URL과 인증서 데이터가 주요 정보
- contexts: 클러스터와 사용자 간의 연결을 정의
- users: 클러스터에 접근하는 사용자 정보를 포함. 인증 토큰, 클라이언트 인증서 및 키가 주요 정보
-
API Groups: Kubernetes 리소스(예: Pods, Services, Deployments 등)를 그룹으로 나누어 API 요청을 관리하는 구조
- Core Group (Legacy API):
https://<k8s-apiserver>/api/v1형태로, Kubernetes에서 가장 기본적인 리소스를 포함, Pod, Service, Node, Namespace, ConfigMap, Secret, PersistentVolume (PV), PersistentVolumeClaim (PVC) 등 - Named API Groups:
https://<k8s-apiserver>/apis/<group>/v1형태로, Core Group 외의 기능을 추가하거나 확장하기 위해 사용 - Named API Groups에는 apps (
/apis/apps/v1): Deployment, StatefulSet, DaemonSet, ReplicaSet / batch (/apis/batch/v1): Job, CronJob / autoscaling (/apis/autoscaling/v1): HorizontalPodAutoscaler (HPA) / networking.k8s.io (/apis/networking.k8s.io/v1): Ingress, NetworkPolicy / rbac.authorization.k8s.io (/apis/rbac.authorization.k8s.io/v1): Role, ClusterRole, RoleBinding, ClusterRoleBinding 등 존재
- Core Group (Legacy API):
-
Authorization mode: Node, ABAC, RBAC, Webhook, AlwaysAllow, AlwaysDeny가 존재
-
RBAC (Role-Based Access Control)
- Role을 먼저 생성하고, RoleBinding 통해 유저를 Role에 연결하는 방식
- Namespaced: roles, rolebindings, pods, replicasets, jobs, deployments, serviced, secrets, configmaps, PVC
- Cluster Scoped: clusterroles, cluterrolebindings, nodes, PV, namespaces
-
Accounts
- User account: 실제 사람이 사용하는 계정 (admin, developer, ...)
- Service account: 머신이 사용하는 계정 (prometheus, jenkins, ...)
-
Network Policy
- 기본적으로 Kubernetes에서는 모든 pod 간의 네트워크 트래픽이 허용. Network Policy를 사용하면 특정 pod에 대한 트래픽 허용/차단 규칙을 정의 가능
podSelector: 정책이 적용될 pod를 선택policyTypes: 정책의 유형, ingress, egress 또는 둘 다 설정 가능ingress: 들어오는 트래픽 규칙 정의egress: 나가는 트래픽 규칙 정의rules: 트래픽을 허용할 조건을 정의,from,to,ports기입
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: mixed-policy
namespace: default
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
egress:
- to:
- ipBlock:
cidr: 172.16.0.0/12
ports:
- protocol: TCP
port: 3306
Storage
| 스토리지 유형 | 설명 | 사용 사례 |
|---|---|---|
| EmptyDir | Pod 라이프사이클 동안 유지. Pod이 삭제되거나 재시작되면 데이터 소멸 | 캐시, 임시 파일 저장 |
| HostPath | 노드 파일 시스템 경로 사용. 노드와 강하게 결합되어 Pod의 이동성이 제한됨 | 디버깅, 로그 저장 |
| PersistentVolume (PV) | 클러스터 관리자에 의해 관리. 클러스터 외부의 실제 스토리지를 Kubernetes 리소스로 추상화 | 지속적 데이터 저장, 스토리지 백엔드 연결 |
| PersistentVolumeClaim (PVC) | 애플리케이션이 PV를 요청할 때 사용하는 리소스. 요청 스토리지 크기 및 액세스 모드를 지정 | 애플리케이션-스토리지 연결 |
| StorageClass | PV를 동적으로 프로비저닝하기 위한 템플릿 역할. 관리자 설정에 따라 PV를 자동으로 생성하며 reclaimPolicy(삭제, 보존 등) 설정 가능 |
다양한 백엔드 스토리지 지원 |
- PV로 사용 가능한 볼륨 유형: HostPath, NFS (Network File System), AWS EBS (Elastic Block Store), GCE Persistent Disk (PD), CSI (Container Storage Interface) 등
- Static Provisioning: 클러스터 관리자가 직접 PersistentVolume(PV)을 생성하고 구성한 다음, 이를 애플리케이션에서 PersistentVolumeClaim(PVC)으로 요청하여 사용하는 방식
- Dynamic Provisioning: PVC가 생성될 때 Kubernetes가 자동으로 적합한 PersistentVolume(PV)을 프로비저닝하는 방식. StorageClass를 사용하여 동작하며, 사용자는 스토리지 유형, 크기, 접근 모드만 지정하면 됨
# PersistentVolume
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-example
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
nfs:
path: /nfs/share
server: 192.168.1.1# PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-example
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi# PVC와 PV 연결:
volumes:
- name: persistent-storage
persistentVolumeClaim:
claimName: pvc-exampleNetwork
- Ingress: 클러스터 외부에서 내부 서비스로 HTTP 및 HTTPS 트래픽을 라우팅하는 Kubernetes 리소스
ingressClassName: NGINX와 같은 Ingress Controller를 지정tls: TLS를 설정하고 example.com에 대한 HTTPS 지원을 활성화.secretName은 TLS 인증서가 저장된 Kubernetes Secret의 이름rules: 호스트(example.com)와 경로(/)를 정의하여 트래픽을 example-service로 전달nginx.ingress.kubernetes.io/rewrite-target: 트래픽을 특정 경로로 리다이렉트nginx.ingress.kubernetes.io/ssl-redirect: HTTP를 HTTPS로 강제 리다이렉트
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
namespace: default
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true" # HTTP를 HTTPS로 리다이렉트
spec:
ingressClassName: nginx # 사용하는 Ingress Controller
tls:
- hosts:
- example.com
secretName: example-tls-secret # TLS 인증서
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: example-service
port:
number: 80ETC.
- Probe: 컨테이너에서 kubelet에 의해 주기적으로 수행되는 진단
-
Liveness Probe: 컨테이너가 "정상적으로 실행 중"인지 확인. 애플리케이션이 교착 상태(deadlock)에 빠질 가능성이 있을 때 활용 가능. 장기 실행 프로세스에서 특정 조건이 충족되지 않으면 복구가 필요한 경우 활용 가능
-
Readiness Probe: 컨테이너가 "트래픽을 처리할 준비"가 되었는지 확인. 애플리케이션 초기화(예: 데이터 로드)가 완료된 후 트래픽을 받도록 설정할 때 활용 가능. 외부 서비스(예: DB 연결)가 준비될 때까지 트래픽을 차단하고 싶을 때 활용 가능
-
Startup Probe: 애플리케이션의 "초기화 완료 여부"를 확인. 컨테이너가 처음 시작될 때만 사용되며, 초기화 시간에 따라 Liveness Probe보다 더 긴 대기 시간이 허용 (e.g., Triton Inference Server). 초기화 시간이 긴 애플리케이션(예: 복잡한 데이터 초기화 작업)이 있는 경우 활용 가능. 기존 Liveness Probe가 너무 일찍 실패를 반환해 컨테이너가 재시작되는 것을 방지하고 싶을 때 활용 가능
-
Helm
Helm chart는 Kubernetes 애플리케이션을 정의하는 템플릿화된 YAML 파일들의 모음입니다. 하나의 chart는 애플리케이션을 배포하는 데 필요한 모든 Kubernetes 리소스를 포함하고 있습니다. 기본적인 구조는 다음과 같습니다.
- Chart.yaml: chart에 대한 메타데이터(이름, 버전, 설명 등)를 포함하는 파일
- values.yaml: chart에서 사용되는 기본값들을 정의하는 파일
- templates/: 실제 Kubernetes 리소스를 정의하는 템플릿 파일들이 위치한 디렉토리
values는 chart의 '템플릿 파일'들에 전달되는 변수 값들을 정의합니다. 기본값은 values.yaml 파일에 정의되며, 사용자 정의 값은 설치 시 --values 또는 -f 플래그를 사용하여 추가할 수 있습니다. values 파일을 통해 동일한 chart를 다양한 환경에서 재사용할 수 있습니다(가장 쉬운 예로는 dev, prod 분리)
# values.yaml
replicaCount: 2
image:
repository: nginx
tag: stableTemplate은 Kubernetes 리소스 정의를 동적이고 유연하게 만들기 위해 사용하는 템플릿 파일입니다. 정의된 변수들은 values 파일에서 정의된 값들로 치환되며, 이를 통해 Kubernetes 매니페스트를 동적으로 생성할 수 있습니다.
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-deployment
spec:
replicas: {{ .Values.replicaCount }}
template:
spec:
containers:
- name: nginx
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"결과적으로, 전체적인 동작은 다음과 같습니다.
- Helm chart는 Kubernetes 애플리케이션을 배포하는 데 필요한 모든 리소스 정의를 포함합니다.
- values 파일을 통해 애플리케이션 배포에 사용할 값들을 설정합니다.
- template 파일은 values 파일의 값들을 사용하여 Kubernetes 리소스 매니페스트를 동적으로 생성합니다.
- 최종적으로 Helm은 템플릿을 렌더링하여 완전한 Kubernetes 매니페스트 파일을 생성하고 이를 클러스터에 적용합니다. 미리 적용될 값을 확인해보기 위해서는
--dry-run옵션을 사용해볼 수 있습니다 (helm install NAME . --dry-run --values=values.yaml).
다양한 helm 커맨드들은 공식 사이트의 cheat sheet 항목에서 확인 가능합니다.
Local Development
도커 데스크탑의 설정에서 k8s 항목에 들어간 뒤, 'Enable Kubernetes'을 클릭하면 로컬 환경에 k8s 클러스터를 구축할 수 있습니다. 그럼 자동으로 k8s config인 ~/.kube/config에 docker-desktop이라는 이름의 cluster가 추가된 것을 확인할 수 있습니다. 만약 'Show system containers' 버튼을 누르셨다면, 도커 데스크탑의 container 목록에서 k8s의 시스템 컨테이너(kube-apiserver, etcd, kube-scheduler, kube-controller-manager...)들이 추가된 것 또한 확인할 수 있습니다.