본문으로 건너뛰기
Kubernetes 로고

생성 수정

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. 네임스페이스와 할당량

quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-a-quota
  namespace: team-a
spec:
  hard:
    requests.cpu: "2"
    requests.memory: 4Gi
    pods: "20"

2. 읽기 전용 권한 만들어 붙이기

rbac.yaml
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) 중에도 최소 몇 개는 살아 있게 보장한다

배치 규칙이 들어간 파드 스펙

scheduling.yaml (일부)
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은 동일하다 — 다음 장의 헬름도 마찬가지다

배포판 정리

구분도커 데스크톱미니쿠베K3skubeadm관리형(EKS 등)
설치 난이도체크박스 하나매우 낮음낮음높음낮음(콘솔·CLI)
버전 선택불가(도커가 정함)가능가능가능제한적
기본 포함단일 노드 클러스터애드온으로 선택CNI·인그레스·LB·스토리지거의 없음클라우드 통합
컨트롤 플레인 운영불필요(로컬)불필요(로컬)직접직접클라우드가 담당
쓰는 자리첫 실습·로컬 개발학습·로컬 개발엣지·소규모 운영학습·온프레미스 운영규모 있는 운영