
생성 수정
Kubernetes · 8장
K8s
축약판이 아닌 표준 쿠버네티스를 kubeadm으로 직접 세우고, 컨트롤 플레인 부품·네임스페이스·RBAC·스케줄링·오토스케일링까지 운영 관점으로 내려간다.
8장 · 총 6개 절 · 전체 9개 장 중 8번째
kubeadm으로 세우는 표준 클러스터
8장 · 01
K3s가 부품을 하나로 묶어 감춰뒀다면, kubeadm은 표준 부품을 그대로 조립합니다. 손이 더 가는 대신 컨트롤 플레인·CNI·런타임이 각각 무엇이고 어떻게 맞물리는지 눈으로 확인할 수 있습니다.
- 사전 조건 — 스왑 비활성화, 커널 모듈(br_netfilter)과 sysctl 설정, 컨테이너 런타임(containerd)
- kubeadm·kubelet·kubectl 세 패키지를 같은 마이너 버전으로 맞춰 설치한다
- kubeadm init 이 컨트롤 플레인을 세우고 join 명령(토큰 포함)을 출력한다
- CNI 플러그인(Calico·Flannel 등)을 따로 설치해야 노드가 Ready 로 바뀐다 — kubeadm은 네트워크를 고르지 않는다
- 워커 노드는 kubeadm join 으로 붙인다. 토큰은 기본 24시간 뒤 만료된다
- K3s와의 차이 — K3s는 CNI·인그레스·로드밸런서·스토리지가 기본 포함이고, kubeadm은 전부 선택이다
1. 노드 공통 준비
스왑을 끄고 브리지 트래픽이 iptables를 지나가도록 커널 설정을 잡는다.
2. kubeadm · kubelet · kubectl 설치
3. 컨트롤 플레인 초기화와 CNI 설치
워커 노드에서는 init 이 출력한 join 명령을 그대로 실행한다. 토큰을 잃었다면 아래로 다시 만든다.
컨트롤 플레인 부품 뜯어보기
8장 · 02
kubeadm으로 세운 클러스터에서는 컨트롤 플레인 부품들이 kube-system 네임스페이스의 스태틱 파드로 떠 있습니다. 1장에서 그림으로 본 부품들을 실제로 열어 확인하는 절입니다.
- /etc/kubernetes/manifests/ 의 YAML이 스태틱 파드다 — kubelet이 이 디렉터리를 직접 감시해 띄운다
- kube-apiserver — 모든 요청의 관문. 인증·인가·어드미션 컨트롤을 차례로 통과시킨다
- etcd — 상태 저장소. etcdctl snapshot save 로 백업하는 습관이 운영의 기본이다
- kube-scheduler — 필터링(조건에 맞는 노드 추리기) → 스코어링(점수 매기기) 두 단계로 노드를 고른다
- kube-controller-manager — 노드·레플리카셋·엔드포인트 등 수십 개 컨트롤러가 한 프로세스 안에서 돈다
- kubelet 은 파드가 아니라 systemd 서비스다 — 문제가 나면 journalctl -u kubelet 부터 본다
부품 들여다보기
etcd 스냅샷 백업
클러스터 상태 전부가 여기 있다 — 복구 훈련까지 해봐야 백업이라 할 수 있다.
네임스페이스와 RBAC
8장 · 03
한 클러스터를 여럿이 나눠 쓰기 시작하면 경계가 필요해집니다. 네임스페이스가 객체의 구획을 나누고, RBAC이 "누가 무엇에 무엇을 할 수 있는가"를 정합니다.
- 네임스페이스 — 이름 충돌을 막는 구획. 자원 할당량(ResourceQuota)과 기본 제한(LimitRange)도 여기에 건다
- 노드·PV·스토리지클래스처럼 네임스페이스에 속하지 않는 클러스터 범위 객체도 있다
- Role / ClusterRole — 무엇에 어떤 동작을 허용할지(권한의 정의)
- RoleBinding / ClusterRoleBinding — 그 권한을 누구에게 줄지(주체와의 연결)
- 주체는 사람(User·Group)과 워크로드(ServiceAccount) 두 갈래다 — 파드는 항상 서비스어카운트로 API를 부른다
- 권한은 최소로 준다 — 곤란하면 kubectl auth can-i 로 실제 허용 여부를 확인한다
1. 네임스페이스와 할당량
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-a-quota
namespace: team-a
spec:
hard:
requests.cpu: "2"
requests.memory: 4Gi
pods: "20"2. 읽기 전용 권한 만들어 붙이기
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: team-a
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: team-a
subjects:
- kind: ServiceAccount
name: viewer
namespace: team-a
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io스케줄링 — 요청·제한·테인트·어피니티
8장 · 04
"어느 노드에 놓을지"는 스케줄러가 정하지만, 그 판단의 재료는 우리가 줍니다. 자원 요청·제한이 가장 큰 재료이고, 테인트와 어피니티로 배치 규칙을 직접 걸 수 있습니다.
- requests — 스케줄링의 기준. 이 값의 합이 노드 용량을 넘으면 그 노드에는 배치되지 않는다
- limits — 실행 중 상한. CPU는 스로틀링되고, 메모리는 초과 시 컨테이너가 OOMKilled 된다
- QoS 클래스 — Guaranteed / Burstable / BestEffort. 자원이 부족할 때 밀려나는 순서가 갈린다
- 테인트(taint)와 톨러레이션(toleration) — 노드가 "아무나 오지 마라"고 표시하고, 견딜 수 있는 파드만 들어간다
- 노드 셀렉터·어피니티 — 라벨을 기준으로 특정 노드군에 배치를 유도한다(GPU 노드 등)
- 파드 안티어피니티 — 같은 앱의 복제본을 서로 다른 노드로 흩어 장애 도메인을 나눈다
- PodDisruptionBudget — 노드 정비(drain) 중에도 최소 몇 개는 살아 있게 보장한다
배치 규칙이 들어간 파드 스펙
spec:
nodeSelector:
disktype: ssd
tolerations:
- key: "gpu"
operator: "Equal"
value: "true"
effect: "NoSchedule"
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: web
topologyKey: kubernetes.io/hostname
containers:
- name: web
image: nginx:1.27
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi노드에 표시 걸고 비우기
오토스케일링과 모니터링
8장 · 05
부하에 맞춰 개수를 자동으로 조절하려면 먼저 지표가 있어야 합니다. metrics-server가 CPU·메모리를 수집하고, HPA가 그 값을 보고 레플리카 수를 늘리고 줄입니다.
- metrics-server — kubectl top 과 HPA의 전제 조건. kubeadm 클러스터에는 기본으로 없어 직접 설치한다
- HPA(수평 파드 오토스케일러) — 파드 개수를 조절한다. 가장 먼저 손댈 오토스케일링이다
- VPA(수직) — 파드의 requests/limits 자체를 조정한다. HPA와 같은 지표로 함께 쓰면 충돌한다
- Cluster Autoscaler — 노드 자체를 늘리고 줄인다. 클라우드 환경에서만 실질적인 의미가 있다
- HPA가 동작하려면 대상 컨테이너에 resources.requests 가 반드시 있어야 한다 — 없으면 사용률을 계산할 수 없다
- 관측은 지표(Prometheus)·로그(Loki 등)·추적 세 갈래로 나눠 생각한다
1. metrics-server 설치
2. HPA 걸어보기
관리형 쿠버네티스와 무엇이 다른가
8장 · 06
실무에서 컨트롤 플레인을 직접 운영할지 맡길지는 비용과 인력의 문제입니다. 이 절은 직접 세운 클러스터와 관리형 서비스가 실제로 무엇이 다른지 정리하며 장을 닫습니다.
- 관리형은 컨트롤 플레인(API 서버·etcd·업그레이드)을 클라우드가 책임진다 — 우리는 워커와 워크로드만 본다
- 직접 운영하면 etcd 백업·인증서 갱신·버전 업그레이드가 전부 우리 몫이다(인증서는 1년 만료가 기본)
- 관리형은 IAM·로드밸런서·스토리지가 클라우드 서비스와 직접 맞물려 편하지만, 그만큼 종속이 생긴다
- 온프레미스 데이터 요건이 강한 조직에서는 kubeadm·K3s로 직접 세우는 선택이 여전히 유효하다
- 어느 쪽이든 매니페스트와 kubectl은 동일하다 — 다음 장의 헬름도 마찬가지다
배포판 정리
| 구분 | 도커 데스크톱 | 미니쿠베 | K3s | kubeadm | 관리형(EKS 등) |
|---|---|---|---|---|---|
| 설치 난이도 | 체크박스 하나 | 매우 낮음 | 낮음 | 높음 | 낮음(콘솔·CLI) |
| 버전 선택 | 불가(도커가 정함) | 가능 | 가능 | 가능 | 제한적 |
| 기본 포함 | 단일 노드 클러스터 | 애드온으로 선택 | CNI·인그레스·LB·스토리지 | 거의 없음 | 클라우드 통합 |
| 컨트롤 플레인 운영 | 불필요(로컬) | 불필요(로컬) | 직접 | 직접 | 클라우드가 담당 |
| 쓰는 자리 | 첫 실습·로컬 개발 | 학습·로컬 개발 | 엣지·소규모 운영 | 학습·온프레미스 운영 | 규모 있는 운영 |
LangTailor