목차
7 장

Namespace와 라벨

한 클러스터를 네임스페이스로 갈라 두는 모델과 라벨 · 셀렉터의 문법을 정리합니다. default의 한계, 시스템 네임스페이스 넷, RBAC · ResourceQuota · NetworkPolicy의 단위로서의 네임스페이스, kubens 운영 팁, app.kubernetes.io/* 표준 라벨, kubectl -l의 selector 문법까지 다루며 1부를 마무리합니다.

1부의 마지막 챕터입니다. 본 책을 따라오면서 한 가지 사실이 조용히 지나갔습니다 — 지금까지 만든 Pod, Deployment, Service, ConfigMap, Secret이 전부 default 네임스페이스 한 곳에 들어갔다는 점입니다. 그리고 4장 Deployment와 ReplicaSet의 selector부터 라벨도 계속 만나고 있었지만 한자리에 정리하지는 않았습니다. 이번 챕터에서는 그 두 도구 — Namespace와 라벨 — 로 클러스터를 사람이 읽을 수 있는 모양으로 정리하는 법을 다룹니다. 마지막에는 1부 7장의 목표에서 다음 부 (2부 워크로드와 운영)를 짧게 예고합니다.

이번 챕터의 끝에서는 한 클러스터를 환경별 · 팀별로 깨끗이 가른 모양이 손에 들어옵니다. 같은 매니페스트를 dev / staging / prod 어디에 넣어도 자기 자리에서 서로 충돌 없이 동작하고, 권한 · 자원 · 네트워크 정책도 그 칸 단위로 갈라 둘 수 있는 토대가 됩니다.

default 네임스페이스의 한계 #

-A 옵션을 붙이고 클러스터의 모든 객체를 한 번 들여다보면, 우리가 안 만든 것들이 잔뜩 떠 있는 게 보입니다.

모든 네임스페이스의 객체 보기
kubectl get all -A
출력 예시 — 발췌
NAMESPACE     NAME                                   READY   STATUS    RESTARTS   AGE
kube-system   pod/coredns-5d78c9869d-2xvlw           1/1     Running   0          3d
kube-system   pod/etcd-minikube                      1/1     Running   0          3d
kube-system   pod/kube-apiserver-minikube            1/1     Running   0          3d
kube-system   pod/kube-controller-manager-minikube   1/1     Running   0          3d
kube-system   pod/kube-proxy-7gbdn                   1/1     Running   0          3d
kube-system   pod/kube-scheduler-minikube            1/1     Running   0          3d
default       pod/web-7f8b6c8f7d-abcde               1/1     Running   0          1h

kube-system은 K8s가 자기 자신을 굴리기 위한 컨트롤플레인 컴포넌트들이 모여 있는 네임스페이스입니다. coredns (클러스터 DNS), etcd, apiserver, controller-manager, scheduler, kube-proxy — 1장 쿠버네티스란에서 그림으로 본 그 컴포넌트들이 모두 여기에 살아 있습니다. 2장 로컬 환경부터 만나 왔지만 이름을 짚지 않았던 격리 공간입니다.

네임스페이스 목록
kubectl get ns
출력 예시
NAME              STATUS   AGE
default           Active   3d
kube-node-lease   Active   3d
kube-public       Active   3d
kube-system       Active   3d

기본으로 만들어지는 시스템 네임스페이스 넷 — default, kube-system, kube-public, kube-node-lease — 이 항상 떠 있습니다. 한 줄씩 짚어 둡니다.

  • default-n 옵션 없이 만든 객체가 들어가는 곳입니다. 1~6장의 모든 객체가 여기에 모였습니다.
  • kube-system — K8s 컨트롤플레인 컴포넌트가 사는 곳입니다. 일반 사용자가 직접 손대지 않습니다.
  • kube-public — 인증 없이도 읽을 수 있는 객체를 위한 곳입니다. 클러스터 정보 공개용으로 거의 쓰지 않습니다.
  • kube-node-lease — 노드 하트비트를 효율적으로 관리하기 위해 1.13부터 분리된 곳입니다. 운영자가 직접 만질 일은 없습니다.

여기까지는 시스템이 알아서 굴리니 큰 문제가 없는데, 한 클러스터에서 dev / staging / prod를 함께 굴리거나, 팀 A · B가 같은 클러스터를 나눠 쓰거나, 어떤 앱은 한 묶음으로 어떤 앱은 다른 묶음으로 갈라 두고 싶을 때부터 default 한 곳에 다 넣는 모양이 깨집니다. 같은 이름의 Service가 환경마다 따로 있어야 하고, 권한도 환경별로 갈라야 하고, 한쪽 환경의 사고가 다른 쪽으로 새지 않아야 하기 때문입니다.

Namespace가 풀어 주는 것 #

Namespace는 한 줄로 요약하면 한 클러스터 안의 가상 클러스터입니다. 리눅스의 user 계정이나 git의 branch와 비슷한 결의 분리입니다 — 같은 물리 자원 위에 논리적인 칸을 갈라 두는 도구입니다. 풀어 주는 일은 다음 넷이 핵심입니다.

  • 이름 공간 분리 — 같은 이름의 객체를 다른 네임스페이스에 따로 둘 수 있습니다. web이라는 Service가 dev와 prod 양쪽에 별개로 존재할 수 있고, 서로 충돌하지 않습니다.
  • RBAC의 단위 — 권한을 네임스페이스 단위로 나눠 줄 수 있습니다. “팀 A는 team-a 네임스페이스 안에서만 읽고 쓰기 가능, 그 밖은 못 본다” 같은 정책의 기본 단위입니다.
  • 리소스 쿼터의 단위ResourceQuotaLimitRange 객체로 네임스페이스마다 CPU · 메모리 · 객체 개수의 상한을 둘 수 있습니다. dev가 prod의 자원을 잡아먹지 않도록 막는 도구입니다.
  • NetworkPolicy의 단위 — 네임스페이스 사이의 트래픽을 차단하거나 허용하는 정책을 적을 수 있습니다. 기본은 모든 네임스페이스가 서로 트래픽이 통하는 상태이고, 이걸 좁히려면 NetworkPolicy를 써야 합니다.

여기서 한 가지를 분명히 짚어 둘 가치가 있습니다 — Namespace 자체는 보안 경계가 아닙니다. 단순히 객체 이름을 갈라 주는 논리 칸일 뿐입니다. 진짜 격리는 위 네 항목 중 뒤의 셋 (RBAC, 리소스 쿼터, NetworkPolicy)이 따로 합니다. Namespace만 만들어 두고 RBAC도 NetworkPolicy도 안 적었다면, 권한 있는 사용자는 아무 네임스페이스의 객체나 보고 만질 수 있고 Pod 끼리도 서로 통신합니다. 본 챕터에서는 매니페스트 모양까지만 다루고, RBAC / NetworkPolicy / ResourceQuota의 깊이는 14장 RBAC / NetworkPolicy / ResourceQuota에서 본격적으로 다룹니다.

클러스터 스코프 vs 네임스페이스 스코프 #

객체에는 두 갈래가 있습니다. 네임스페이스 스코프 (namespaced) 인 객체는 어떤 네임스페이스에 속해야 하고, 클러스터 스코프 (cluster-scoped) 인 객체는 네임스페이스 없이 클러스터 전역에 하나로 존재합니다. 1~6장에서 본 객체로 갈라 보면 다음과 같습니다.

스코프예시
네임스페이스 스코프Pod, Deployment, ReplicaSet, Service, ConfigMap, Secret, Job, Ingress
클러스터 스코프Node, PersistentVolume, Namespace 자체, ClusterRole, StorageClass

Node가 네임스페이스에 속하지 않는 건 직관적입니다 — 노드는 물리 · 가상 머신이고 한 클러스터의 자원이지, 어느 환경에 속하지 않기 때문입니다. 객체가 어느 쪽에 속하는지 명령으로 확인할 수도 있습니다.

네임스페이스 스코프 객체 목록
kubectl api-resources --namespaced=true
클러스터 스코프 객체 목록
kubectl api-resources --namespaced=false

운영하다가 “이 객체에 -n을 붙여야 하나?“가 헷갈릴 때 한 번 돌려 보면 답이 바로 나옵니다.

Namespace 만들기 #

명령형으로 한 줄에 만들 수 있습니다.

명령형으로 만들기
kubectl create namespace dev
출력 예시
namespace/dev created

git에 의도를 남기고 싶으면 매니페스트로 적습니다.

dev-ns.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: dev
  labels:
    env: dev
apply
kubectl apply -f dev-ns.yaml

apiVersion은 ConfigMap · Secret과 마찬가지로 코어 그룹의 **v1**입니다. Namespace 자체는 클러스터 스코프 객체라서 그 metadata 안에 namespace: 필드를 적지 않습니다 (적을 수 없습니다).

객체를 특정 네임스페이스에 넣는 길은 두 가지입니다.

  • 매니페스트에 적기metadata.namespace: dev 한 줄을 객체의 metadata에 직접 적습니다.
  • 명령에 옵션으로kubectl apply -f web.yaml -n dev처럼 -n으로 지정합니다.
metadata.namespace로 적은 경우
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: dev
  labels:
    app: web
spec:
  # ... 이하 [4장](./deployment-and-replicaset/) 과 동일

둘이 같이 있으면 매니페스트의 값이 우선합니다 (명령 옵션은 매니페스트에 namespace가 없을 때만 적용됩니다). 혼동을 줄이려면 둘 중 한쪽만 쓰는 게 좋습니다. git에 의도를 남기는 관점에서는 매니페스트에 적어 두는 편이 다음 사람에게 친절합니다 — 명령 옵션은 셸 히스토리에만 남고, 다음에 같은 매니페스트를 보면 “이게 어디로 가는 거지?“가 다시 의문이 되기 때문입니다.

NS 별로 둘러보기 #

-n 옵션으로 한 네임스페이스의 객체만 봅니다.

dev 네임스페이스의 Pod
kubectl get pods -n dev
kube-system의 모든 객체
kubectl get all -n kube-system

-A 옵션은 모든 네임스페이스를 한 번에 봅니다.

모든 네임스페이스 한꺼번에
kubectl get pods -A

-n을 매번 적기 번거롭습니다. 현재 컨텍스트의 기본 네임스페이스를 바꾸면 그 다음부터는 옵션 없이도 그 네임스페이스로 가게 됩니다.

기본 네임스페이스 전환
kubectl config set-context --current --namespace=dev
현재 컨텍스트 확인
kubectl config view --minify | grep namespace:

이 명령은 ~/.kube/config의 현재 컨텍스트에 기본 네임스페이스를 적어 둡니다. 그 뒤 kubectl get pods만 쳐도 dev의 Pod가 나옵니다.

kubens — 한 줄로 네임스페이스 전환 #

위 명령이 길어서, 운영자들이 거의 다 쓰는 도구가 kubens (kubectx 패키지의 짝꿍)입니다. 한 줄에 네임스페이스를 갈아탈 수 있습니다.

kubens 사용
kubens                  # 현재 네임스페이스 출력 + 후보 목록
kubens dev              # dev 로 전환
kubens -                # 직전 네임스페이스로 돌아가기

kubectx가 클러스터 (컨텍스트) 전환용이라면 kubens는 네임스페이스 전환용입니다. 둘 다 한 패키지에서 옵니다 — Homebrew, apt, scoop 어디든 kubectx를 깔면 같이 들어옵니다. 매일 K8s를 만지는 사람에게는 거의 필수에 가까운 편의 도구입니다.

NS 안 객체가 어떻게 서로 부르나 #

5장 Service의 DNS 절에서 본 흐름을 한 번 더 짚을 차례입니다. 같은 네임스페이스 안에 사는 Pod 끼리는 Service 이름만으로 서로 부를 수 있었습니다.

같은 네임스페이스 안
http://web/api          # web 이라는 Service 를 짧은 이름으로

다른 네임스페이스의 Service를 부르려면 이름 뒤에 네임스페이스를 붙입니다.

다른 네임스페이스의 Service
http://web.prod/api                     # 짧게
http://web.prod.svc.cluster.local/api   # FQDN

K8s 클러스터 안의 모든 Service는 <service>.<namespace>.svc.cluster.local이라는 FQDN으로 풀립니다. 짧게 줄여 web.prod만 적어도 클러스터 DNS가 알아서 채워 줍니다. 한 줄로 정리하면 DNS가 네임스페이스 사이의 다리입니다 — 네임스페이스가 객체 이름을 갈라 두는 칸이라면, DNS는 그 칸 너머로 객체를 부를 수 있게 해 주는 통로 역할을 합니다.

라벨 vs 어노테이션 #

여기서 시점을 바꿔, 클러스터 정리의 또 다른 축인 라벨로 넘어갑니다. 라벨은 4장의 selector부터 사실 계속 만나고 있었습니다 — Deployment의 spec.selector.matchLabels, Pod 템플릿의 metadata.labels, 5장 Service의 spec.selector가 모두 라벨로 객체를 묶고 골라내는 메커니즘입니다.

라벨과 자주 헷갈리는 것이 **어노테이션 (annotation)**입니다. 둘 다 metadata 아래에 키-값으로 적는 모양은 같지만, 쓰임새가 분명히 갈립니다.

비교 항목라벨 (label)어노테이션 (annotation)
K8s가 매칭에 사용예 (selector)아니오
길이 · 내용짧고 의미 있는 키-값 (수십 자)임의 — 길어도 OK, JSON · base64 등
용도객체 분류 · 선택도구 · 운영자가 붙이는 메모
키 예시app=web, env=prod, tier=backendprometheus.io/scrape: "true", kubectl.kubernetes.io/last-applied-configuration

한 줄 차이는 — 라벨은 검색 키, 어노테이션은 메모지입니다. K8s의 컨트롤러 (Deployment, Service, NetworkPolicy 등)가 어떤 객체를 다룰지 고를 때 보는 것이 라벨이고, 외부 도구 (Prometheus, Helm, ArgoCD, Ingress 컨트롤러 등)나 운영자가 객체에 메타데이터를 덧붙일 때 쓰는 것이 어노테이션입니다.

키와 값의 제약도 살짝 다릅니다. 라벨은 selector에 쓰이는 만큼 형식이 좁습니다 — 키는 ASCII 영숫자에 -, _, . 정도, 값도 비슷하게 짧은 문자열만 들어갑니다 (둘 다 수십 자 안). 어노테이션은 그 제약이 풀려 있어 임의의 텍스트 · JSON도 들어갈 수 있습니다. kubectl.kubernetes.io/last-applied-configuration 어노테이션이 통째로 매니페스트 JSON을 들고 있는 게 그 예입니다.

라벨과 어노테이션이 같이 적힌 metadata
metadata:
  name: web
  labels:
    app: web
    env: prod
    tier: backend
  annotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "8080"
    kubernetes.io/change-cause: "bump nginx 1.27 -> 1.28"

표준 라벨 컨벤션 — app.kubernetes.io/* #

라벨에 app=web 같은 자체 키를 자유롭게 붙여도 되지만, K8s 커뮤니티가 권장하는 표준 라벨 셋이 있습니다. 키 접두사가 app.kubernetes.io/로 시작하는 여섯 가지입니다.

의미예시 값
app.kubernetes.io/name앱 이름nginx, web, kafka
app.kubernetes.io/instance이 배포 인스턴스 식별자web-prod, kafka-shop
app.kubernetes.io/version버전1.27, 2.4.1
app.kubernetes.io/component역할frontend, backend, database
app.kubernetes.io/part-of상위 시스템shop-platform, analytics
app.kubernetes.io/managed-by관리 도구Helm, argocd, kubectl

이 키들을 쓰는 이유는 운영 도구 · 대시보드가 표준으로 인식하기 때문입니다. Lens, k9s, Datadog, Helm 같은 도구들이 이 키를 보고 객체를 묶어 보여 줍니다. 자체 키만 쓰는 것보다 호환성이 분명히 좋습니다. 자체 키 (예: env, team)를 함께 써도 무방하고, 표준 라벨 셋과 자체 라벨을 같이 적는 게 일반적인 모양입니다.

표준 라벨이 붙은 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: prod
  labels:
    app.kubernetes.io/name: nginx
    app.kubernetes.io/instance: web-prod
    app.kubernetes.io/version: "1.27"
    app.kubernetes.io/component: frontend
    app.kubernetes.io/part-of: shop-platform
    app.kubernetes.io/managed-by: kubectl
    env: prod
spec:
  replicas: 3
  selector:
    matchLabels:
      app.kubernetes.io/name: nginx
      app.kubernetes.io/instance: web-prod
  template:
    metadata:
      labels:
        app.kubernetes.io/name: nginx
        app.kubernetes.io/instance: web-prod
        app.kubernetes.io/version: "1.27"
        app.kubernetes.io/component: frontend
        env: prod
    spec:
      containers:
        - name: nginx
          image: nginx:1.27
          ports:
            - containerPort: 80

selector의 matchLabels와 Pod 템플릿의 labels에는 표준 라벨 중에서도 변하지 않는 것들만 넣는 편이 안전합니다. version 같은 키를 selector에 넣어 두면 버전을 올릴 때 selector도 같이 바꿔야 해서 4장에서 본 selector immutability 함정에 걸리기 쉽습니다.

라벨로 골라내기 — kubectl -l #

라벨이 붙어 있으면 kubectl-l 옵션으로 객체를 골라낼 수 있습니다. selector 문법은 단순한 등호부터 집합 표현까지 몇 가지가 있습니다.

등호 매칭
kubectl get pods -l app=web
kubectl get pods -l env=prod,tier=backend         # AND

쉼표로 이어 붙이면 AND입니다. OR은 다음의 집합 표현으로 적습니다.

집합 표현
kubectl get pods -l 'env in (dev,staging)'
kubectl get pods -l 'env notin (prod)'
kubectl get pods -l 'tier'                         # tier 라벨이 있는 것
kubectl get pods -l '!debug'                       # debug 라벨이 없는 것

여러 객체 종류에 같이 쓸 수도 있습니다.

라벨로 여러 종류 한꺼번에
kubectl get deploy,svc,cm -l app.kubernetes.io/instance=web-prod
라벨로 일괄 삭제 — 위험
kubectl delete pods -l env=dev

마지막 명령은 강력합니다 — 매칭되는 모든 Pod를 한 번에 지웁니다. 운영 클러스터에서 라벨을 잘못 넣었다가 의도보다 많은 객체를 지우는 사고가 종종 납니다. 일괄 삭제 전에는 같은 selector로 get을 먼저 돌려 대상이 의도한 그것인지 확인하는 게 안전합니다. 진단 트리의 완성된 버전은 27장 kubectl 디버깅 패턴에서 정리합니다.

-l 셀렉터의 문법이 중요한 이유는 — 같은 문법이 Service의 spec.selector, Deployment의 spec.selector.matchLabels, NetworkPolicy의 podSelector, ResourceQuota의 scopeSelector 등 K8s 안의 거의 모든 객체 매칭에 그대로 쓰이기 때문입니다. 라벨 한 번 익혀 두면 그 위에 얹히는 객체들의 selector가 자연스럽게 읽힙니다.

가상의 운영 한 컷 — 이걸 다 합치면 #

지금까지의 도구를 한 매니페스트 묶음으로 맞춰 보면, 운영 클러스터의 기본 모양이 드러납니다. dev / staging / prod 세 네임스페이스, 그 안에 같은 이름의 Deployment · Service · ConfigMap · Secret이 있고, 라벨로 환경과 버전이 붙어 있습니다.

prod 네임스페이스의 Deployment + Service
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: prod
  labels:
    app.kubernetes.io/name: nginx
    app.kubernetes.io/instance: web-prod
    app.kubernetes.io/version: "1.27"
    app.kubernetes.io/component: frontend
    app.kubernetes.io/part-of: shop-platform
    env: prod
spec:
  replicas: 3
  selector:
    matchLabels:
      app.kubernetes.io/name: nginx
      app.kubernetes.io/instance: web-prod
  template:
    metadata:
      labels:
        app.kubernetes.io/name: nginx
        app.kubernetes.io/instance: web-prod
        app.kubernetes.io/component: frontend
        env: prod
    spec:
      containers:
        - name: nginx
          image: nginx:1.27
          ports:
            - containerPort: 80
          envFrom:
            - configMapRef:
                name: web-config
            - secretRef:
                name: db-secret
---
apiVersion: v1
kind: Service
metadata:
  name: web
  namespace: prod
  labels:
    app.kubernetes.io/name: nginx
    app.kubernetes.io/instance: web-prod
    env: prod
spec:
  selector:
    app.kubernetes.io/name: nginx
    app.kubernetes.io/instance: web-prod
  ports:
    - port: 80
      targetPort: 80

dev와 staging도 거의 같은 매니페스트입니다 — metadata.namespace, instance, version, env 라벨 정도만 환경마다 다르고 나머지는 그대로입니다. 이 모양이 한 클러스터 안에서 환경별로 객체가 깨끗이 갈라지는 운영 클러스터의 기본기입니다.

운영에서 같은 매니페스트를 환경별로 약간씩 바꿔서 적용해야 할 때, 매번 손으로 갈아 두면 실수가 잦습니다. 그래서 등장하는 도구가 Helm (템플릿 + 값 분리)과 Kustomize (베이스 + 오버레이)입니다. 본 챕터 범위 밖이고, 22장 앱 배포 골격20장 GitOps에서 EKS 위 실전 배포와 함께 본격적으로 다룹니다.

정리·치우기 #

이번 챕터에서 만든 dev 네임스페이스를 정리합니다.

네임스페이스 삭제
kubectl delete ns dev
출력 예시
namespace "dev" deleted

이 한 줄이 무서운 이유는 그 네임스페이스 안의 모든 객체가 같이 사라진다는 점입니다. Deployment, Service, Pod, ConfigMap, Secret, PVC 모두 비동기로 삭제됩니다. 운영 클러스터에서 네임스페이스 삭제는 거의 마지막 카드라고 봐야 합니다 — 한 번 누르면 그 안의 데이터까지 날아갈 수 있고, 9장 PV / PVC / StorageClass에서 다룰 영속 볼륨의 reclaimPolicy 설정에 따라서는 디스크 자체도 같이 사라질 수 있습니다.

현재 네임스페이스 기본값 되돌리기
kubectl config set-context --current --namespace=default

kubens를 설치해 둔 환경이라면 kubens default로 한 줄입니다.

1부 회고 — 7장으로 손에 들어온 것 #

1부의 마지막 챕터이므로 한 번 정리합니다.

  • 1장 쿠버네티스란왜 K8s 인가. 컨테이너 한 호스트의 한계, 오케스트레이터가 풀어 주는 것, 컨트롤플레인과 워커의 그림.
  • 2장 로컬 환경로컬 클러스터. minikube / kind / Docker Desktop 셋의 쓰임새와 차이, kubectl 컨텍스트.
  • 3장 kubectl과 첫 Pod첫 Pod. 매니페스트의 척추 (apiVersion / kind / metadata / spec), kubectl apply / get / describe / logs / exec.
  • 4장 Deployment와 ReplicaSetDeployment와 ReplicaSet. 선언형 배포, 롤링 업데이트, kubectl rollout, selector immutability.
  • 5장 ServiceService. ClusterIP / NodePort / LoadBalancer의 세 단계, 클러스터 내부 DNS.
  • 6장 ConfigMap과 SecretConfigMap과 Secret. 12-factor의 “설정은 환경에 둔다”, env / envFrom / volume 세 가지 주입 방식.
  • 7장 Namespace와 라벨 (이번 챕터) — 클러스터 정리법. 네임스페이스의 RBAC · 쿼터 · NetworkPolicy 단위, 표준 라벨 컨벤션, kubectl -l 셀렉터.

이 정도면 K8s 매니페스트 한 장을 처음 보고도 무엇을 의미하는지 읽고 쓸 수 있는 수준입니다. 회사 클러스터의 매니페스트 디렉터리를 열어도 객체 종류와 그 안의 필드 이름이 낯설지 않을 것입니다. 그 위에 얹힐 더 깊은 주제들이 2부 (워크로드와 운영)의 줄거리입니다.

연습문제 #

  1. kubectl create namespace dev로 새 네임스페이스를 만들고, 6장의 web Deployment + ConfigMap + Secret 매니페스트를 metadata.namespace: dev로 통째 옮겨 kubectl apply 해 보세요. kubectl get all -n devkubectl get all -n default 출력을 나란히 적어 두고, 같은 이름의 객체가 두 네임스페이스에 동시에 존재할 수 있다는 점을 확인합니다. 그 다음 dev의 web Pod 안에서 curl http://web.default/curl http://web/가 어떤 결과를 주는지 비교합니다.
  2. 4장의 web Deployment에 §“표준 라벨 컨벤션"의 app.kubernetes.io/* 키 여섯 개를 모두 붙여 보세요. selector의 matchLabels에는 nameinstance만 넣고 version은 라벨로만 두는 이유를 §“selector immutability 함정"과 연결해 한 단락으로 메모합니다. 그 다음 kubectl get pods,svc,cm -l app.kubernetes.io/instance=<...>가 어떤 객체들을 한 번에 묶어 보여 주는지 확인합니다.
  3. 자체 라벨 team=ateam=b를 가진 Pod 두 개를 같은 네임스페이스에 띄우고, kubectl get pods -l 'team in (a)', kubectl get pods -l 'team notin (a)', kubectl get pods -l '!team' 세 명령의 출력을 차례로 기록합니다. 같은 selector 문법이 14장 RBAC / NetworkPolicy / ResourceQuotapodSelector에 어떻게 그대로 적용될지 한 줄로 추론합니다.

한 줄 요약: Namespace는 한 클러스터 안의 가상 클러스터로, 이름 공간을 갈라 두고 RBAC · ResourceQuota · NetworkPolicy의 단위가 된다. 라벨은 selector가 객체를 묶고 골라내는 검색 키이고, 어노테이션은 도구 · 운영자의 메모지다. 매니페스트의 본체는 환경에 무관하게 한 벌로 두고, 환경마다 다른 부분은 네임스페이스와 라벨 · ConfigMap · Secret로 분리한다.

다음 챕터 #

1부가 끝났습니다. 2부 워크로드와 운영의 첫 챕터인 8장 StatefulSet / DaemonSet / Job / CronJob에서는 Deployment가 아닌 다른 컨트롤러들을 다룹니다. 데이터베이스처럼 각 인스턴스가 자기 이름과 자기 디스크를 가져야 하는 워크로드 (StatefulSet), 로그 수집기 · 노드 모니터처럼 노드마다 한 개씩 떠야 하는 워크로드 (DaemonSet), 한 번 돌고 끝나는 배치 작업 (Job · CronJob)의 모양과 선택 기준을 정리합니다.

2부 전체의 줄거리는 다음과 같습니다.

챕터주제
8장StatefulSet · DaemonSet · Job · CronJob — Deployment가 아닌 컨트롤러들
9장PV · PVC · StorageClass — 영속 데이터 모델
10장Ingress와 Ingress Controller — 외부 진입점
11장resources.requests / limits — Pod의 자원 요청과 상한
12장Health check — liveness · readiness · startup probe
13장오토스케일링 — HPA · VPA · Cluster Autoscaler
14장RBAC · NetworkPolicy · ResourceQuota — 보안과 자원 정책

2부를 마치면 클러스터 위의 다양한 워크로드를 안정적으로 운영할 수 있는 수준에 도달합니다. 그 다음 3부 (깊이)에서는 CNI · Admission Controller · CRD · 옵저버빌리티 · GitOps 같은 운영자의 시야로 확장하는 주제를 다룹니다.

X