개발팀이 테스트 리소스를 정리하려다 운영 리소스까지 같은 클러스터에서 건드릴 뻔했습니다. 여러 팀과 환경이 한 클러스터를 공유하면 논리적 경계가 없을 때 작은 명령 하나가 큰 장애가 됩니다. Namespace는 권한, 비용, 리소스를 나누는 첫 번째 안전 울타리입니다.
Namespace — 환경 분리와 자원 제한
단일 Kubernetes 클러스터에 개발팀, 스테이징, 운영 환경을 모두 올리고 싶지만 서로 영향을 주면 안 됩니다. 개발팀이 실수로 배포한 리소스가 운영 파드와 자원을 경쟁하거나, 개발팀의 kubectl delete all이 운영 리소스를 날리는 사고가 실제로 발생합니다. 클러스터를 환경마다 따로 구축하면 비용과 관리 부담이 급증합니다. Namespace는 하나의 클러스터 안에서 논리적 구획을 만들어 이 문제를 해결합니다. RBAC으로 팀별 접근 권한을 제어하고, ResourceQuota로 Namespace별 자원 상한을 설정하면, 개발팀이 운영 Namespace에 접근하지 못하고 리소스를 독점하지도 못합니다. 대부분의 운영 조직이 이 방식으로 멀티팀 클러스터를 운영합니다.
Namespace로 팀과 환경을 논리적으로 분리하고, 자원 제한으로 안정적인 멀티팀 클러스터를 운영하는 방법을 실습합니다.
- 1Namespace 개념과 기본 제공 Namespace를 설명할 수 있다
- 2개발·스테이징·운영 환경을 Namespace로 분리할 수 있다
- 3ResourceQuota로 Namespace 전체 자원 상한을 설정할 수 있다
- 4LimitRange로 컨테이너별 기본값과 최댓값을 설정할 수 있다
- 5DNS 네이밍 규칙으로 다른 Namespace 리소스에 접근할 수 있다
- 6다른 Namespace 리소스 접근 실패를 진단할 수 있다
kubectl 기본 사용법(kubectl-basics)을 익혔다면 바로 시작할 수 있습니다. 별도 환경 설치 없이 기존 클러스터에서 진행합니다.
kubectl cluster-infokubectl get namespaceskubectl config current-contextkubectl config view --minify | grep namespaceNamespace — 클러스터 안의 클러스터
하나의 클러스터에서 여러 팀이 작업하다 보면 개발 환경의 리소스가 운영 환경 파드와 같은 네임스페이스에 뒤섞입니다. kubectl delete all을 개발 환경 정리용으로 실행했는데 운영 파드까지 삭제되는 사고가 발생합니다. Kubernetes는 기본적으로 네임스페이스를 지정하지 않으면 모든 리소스가 default에 쌓입니다. Namespace는 하나의 클러스터 안에서 논리적 구획을 만들어 팀과 환경을 분리하고, RBAC으로 각 구획의 접근 권한을 제어합니다. 이 CB에서는 Kubernetes 기본 제공 Namespace의 역할과, 사용자 정의 Namespace 생성 및 관리 방법을 다룹니다.
확대
기본 제공 Namespace
kubectl get namespaces
# NAME STATUS AGE
# default Active 30d ← namespace 미지정 시 사용되는 기본 공간
# kube-system Active 30d ← Kubernetes 시스템 컴포넌트 (CoreDNS, kube-proxy 등)
# kube-public Active 30d ← 인증 없이 읽기 가능 (클러스터 정보 공개용)
# kube-node-lease Active 30d ← 노드 heartbeat용 Lease 오브젝트 저장
- kubectl get namespaces에서 STATUS 열 먼저 확인 — Active이면 정상, Terminating이면 삭제 중으로 finalizer가 남아 있는 것. kubectl get all -n <ns>로 남은 리소스 확인 후 강제 finalizer 제거 필요
- kubectl get pods -n <namespace>로 각 네임스페이스의 리소스를 분리 조회 — 네임스페이스를 지정하지 않으면 현재 context의 기본 네임스페이스(default) 리소스만 나옴
- Terminating 상태가 5분 이상 지속되면 → finalizer 때문. kubectl get namespace <ns> -o json | grep finalizers로 남은 finalizer 목록 확인 후 해당 리소스(PVC, 파드 등)를 먼저 삭제
kube-system은 절대 건드리지 않는 것이 원칙입니다. CoreDNS나 kube-proxy 같은 핵심 컴포넌트가 여기 있습니다.
Namespace 생성
# 명령어로 생성
kubectl create namespace development
kubectl create namespace staging
kubectl create namespace production
# YAML로 생성 (팀 정보, 환경 정보를 label로 관리)
# namespaces.yaml
---
apiVersion: v1
kind: Namespace
metadata:
name: development
labels:
environment: dev
team: backend
---
apiVersion: v1
kind: Namespace
metadata:
name: staging
labels:
environment: staging
team: backend
---
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
environment: prod
team: backend
kubectl apply -f namespaces.yaml
kubectl get namespaces --show-labels
# NAME STATUS LABELS
# development Active environment=dev,team=backend
# staging Active environment=staging,team=backend
# production Active environment=prod,team=backend
Namespace 범위 오브젝트 vs 클러스터 범위 오브젝트
| Namespace 범위 (격리됨) | 클러스터 범위 (공유) |
|---|---|
| Pod, Deployment, Service | Node, PersistentVolume |
| ConfigMap, Secret | StorageClass |
| PersistentVolumeClaim | ClusterRole, ClusterRoleBinding |
| ServiceAccount | Namespace 자체 |
# 어떤 리소스가 Namespace 범위인지 확인
kubectl api-resources --namespaced=true | head -10
kubectl api-resources --namespaced=false | head -10
환경 분리 실습 — 개발·스테이징·운영
같은 이름의 Deployment를 개발 환경과 운영 환경에 따로 운영해야 하는데 단일 클러스터라면 이름이 충돌합니다. 개발팀이 실수로 운영 Deployment를 롤백하거나, 스테이징 테스트가 운영 서비스에 영향을 주는 사고가 발생합니다. 환경마다 별도 클러스터를 쓰면 비용과 관리 부담이 세 배가 됩니다. Namespace를 환경별로 분리하면 같은 이름의 리소스를 독립적으로 관리하고, RBAC으로 각 환경의 접근 권한을 팀별로 제한할 수 있습니다. 이 CB에서는 development, staging, production 세 환경을 Namespace로 분리하고 같은 앱을 각각 독립적으로 배포하는 실습을 다룹니다.
동일 앱을 다른 Namespace에 각각 배포
# dev-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: development # 개발 환경
spec:
replicas: 1 # 개발: 1개 레플리카
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: hashicorp/http-echo
args: ["-text=Hello from DEVELOPMENT"]
ports:
- containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
name: my-app-svc
namespace: development
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 5678
# prod-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: production # 운영 환경 — 같은 이름이지만 다른 Namespace
spec:
replicas: 3 # 운영: 3개 레플리카
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: hashicorp/http-echo
args: ["-text=Hello from PRODUCTION"]
ports:
- containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
name: my-app-svc
namespace: production
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 5678
kubectl apply -f dev-deployment.yaml
kubectl apply -f prod-deployment.yaml
# 각 Namespace에서 파드 수와 내용이 다름
kubectl get deployments -n development
# NAME READY UP-TO-DATE AVAILABLE
# my-app 1/1 1 1
kubectl get deployments -n production
# NAME READY UP-TO-DATE AVAILABLE
# my-app 3/3 3 3
# 전체 Namespace 조회
kubectl get pods -A | grep my-app
기본 Namespace 변경
# 매번 -n 플래그 입력이 번거로울 때
kubectl config set-context --current --namespace=development
# 이후 명령어는 development Namespace가 기본
kubectl get pods # development 파드만 표시
kubectl get pods -n production # production 파드 확인 시 -n 명시
# 원래대로 복원
kubectl config set-context --current --namespace=default
ResourceQuota — Namespace 전체 자원 상한
개발팀이 테스트 목적으로 수십 개의 파드를 배포하면서 클러스터 전체 CPU와 메모리를 잠식합니다. 운영 파드가 자원을 확보하지 못해 Pending 상태가 되고 배포가 지연됩니다. 팀에게 클러스터 접근 권한을 주되 전체 자원을 무제한으로 쓸 수는 없습니다. ResourceQuota는 Namespace 단위로 자원 예산을 설정하는 메커니즘입니다. Namespace 안에서 생성할 수 있는 리소스의 총합을 제한합니다. 팀별로 자원 예산을 배정하는 개념입니다.
확대
ResourceQuota 설정
# resource-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: dev-quota
namespace: development
spec:
hard:
# 컨테이너 수준 CPU/메모리 합계 제한
requests.cpu: "4" # 이 Namespace 전체 CPU request 합계 ≤ 4코어
requests.memory: 8Gi # 전체 메모리 request 합계 ≤ 8Gi
limits.cpu: "8" # 전체 CPU limit 합계 ≤ 8코어
limits.memory: 16Gi # 전체 메모리 limit 합계 ≤ 16Gi
# 오브젝트 수 제한
pods: "20" # 최대 파드 수
services: "10" # 최대 서비스 수
persistentvolumeclaims: "5" # 최대 PVC 수
secrets: "20" # 최대 Secret 수
configmaps: "20" # 최대 ConfigMap 수
kubectl apply -f resource-quota.yaml
# ResourceQuota 사용량 확인
kubectl describe resourcequota dev-quota -n development
# Name: dev-quota
# Namespace: development
# Resource Used Hard
# -------- ---- ----
# limits.cpu 500m 8
# limits.memory 512Mi 16Gi
# pods 2 20
# requests.cpu 250m 4
# requests.memory 256Mi 8Gi
ResourceQuota가 있으면 requests/limits 필수
ResourceQuota에 CPU/메모리 제한이 있는 Namespace에서는, 파드의 모든 컨테이너가 resources.requests와 resources.limits를 명시해야 합니다. 없으면 파드 생성이 거부됩니다.
# ResourceQuota가 있는 Namespace에서 resources 없이 파드 생성 시
kubectl run test-pod --image=nginx -n development
# Error from server (Forbidden): pods "test-pod" is forbidden:
# failed quota: dev-quota: must specify limits.cpu for: test-pod
# resources를 명시한 올바른 파드
spec:
containers:
- name: app
image: nginx
resources:
requests:
cpu: "100m" # 0.1 CPU 코어
memory: "128Mi"
limits:
cpu: "500m" # 0.5 CPU 코어
memory: "256Mi"
LimitRange — 컨테이너별 기본값과 최댓값 설정
ResourceQuota를 설정했는데 resources 필드 없이 파드를 배포하면 CPU와 메모리 요청이 0으로 처리되어 Quota 검사가 제대로 동작하지 않습니다. 반대로 모든 파드에 일일이 requests와 limits를 작성하도록 강제하면 개발자 부담이 늘고 누락 사고가 생깁니다. LimitRange는 이 문제를 해결합니다. 개별 파드/컨테이너 수준에서 기본값과 상한·하한을 설정하여, resources를 명시하지 않은 파드에 자동으로 적절한 값을 주입합니다. 이 CB에서는 LimitRange 설정과 ResourceQuota와의 적용 순서를 다룹니다. resources 필드를 명시하지 않은 파드에 자동으로 기본값을 적용합니다.
LimitRange 설정
# limit-range.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: dev-limits
namespace: development
spec:
limits:
- type: Container
default: # resources 미설정 시 자동 적용되는 limits 기본값
cpu: "500m"
memory: "256Mi"
defaultRequest: # requests 기본값
cpu: "100m"
memory: "128Mi"
max: # 컨테이너 하나의 최대 한도
cpu: "2"
memory: "1Gi"
min: # 컨테이너 하나의 최소 한도
cpu: "50m"
memory: "64Mi"
- type: Pod
max: # 파드 전체(컨테이너 합산) 최대 한도
cpu: "4"
memory: "2Gi"
- type: PersistentVolumeClaim
max:
storage: "50Gi" # PVC 최대 용량
min:
storage: "1Gi" # PVC 최소 용량
kubectl apply -f limit-range.yaml
# LimitRange 확인
kubectl describe limitrange dev-limits -n development
# Name: dev-limits
# Namespace: development
# Type Resource Min Max Default Request Default Limit
# ---- -------- --- --- --------------- -------------
# Container cpu 50m 2 100m 500m
# Container memory 64Mi 1Gi 128Mi 256Mi
# resources를 명시하지 않은 파드가 LimitRange 기본값을 받는지 확인
kubectl run no-limits-pod --image=nginx -n development
kubectl get pod no-limits-pod -n development -o jsonpath='{.spec.containers[0].resources}' | jq
# {
# "limits": {"cpu": "500m", "memory": "256Mi"}, ← LimitRange 기본값 자동 적용
# "requests": {"cpu": "100m", "memory": "128Mi"}
# }
ResourceQuota vs LimitRange 적용 순서
확대
문제 상황
# frontend 파드(development Namespace)에서 api-service에 접근 시도
kubectl exec -it frontend-pod -n development -- \
curl http://api-service/users
# curl: (6) Could not resolve host: api-service
# 또는
# curl: (7) Failed to connect to api-service port 80: Connection refused
api-service는 실제로 존재하고 Running 상태인데 접근이 안 됩니다.
진단: 서비스가 어느 Namespace에 있는지 확인
# 모든 Namespace에서 api-service 찾기
kubectl get service -A | grep api-service
# NAMESPACE NAME TYPE CLUSTER-IP PORT(S)
# production api-service ClusterIP 10.96.45.100 80/TCP
# ↑ production Namespace에 있음!
원인 분석
같은 Namespace에서는 서비스 이름만으로 접근 가능합니다. 다른 Namespace의 서비스에는 Namespace가 포함된 DNS 이름을 사용해야 합니다.
클러스터 내부 DNS 해석 순서:
1. <service-name> → <service-name>.<현재-namespace>.svc.cluster.local
2. <service-name>.<ns> → <service-name>.<ns>.svc.cluster.local
3. FQDN → <service-name>.<ns>.svc.cluster.local (직접 지정)
"api-service"로 조회 → development.svc.cluster.local에서 찾음 → 없음 → 실패!
해결: Namespace 포함한 DNS 이름 사용
# 방법 1: <service>.<namespace> 형식 (자주 쓰는 축약형)
kubectl exec -it frontend-pod -n development -- \
curl http://api-service.production
# 방법 2: 전체 FQDN
kubectl exec -it frontend-pod -n development -- \
curl http://api-service.production.svc.cluster.local
# 정상 응답 확인
# {"users": [...]}
코드/환경변수에서 수정
# 파드의 환경변수에서 서비스 URL을 FQDN으로 설정
env:
- name: API_URL
value: "http://api-service.production.svc.cluster.local"
# value: "http://api-service" ← 같은 Namespace에서만 동작
DNS 동작 확인 도구
# 특정 서비스 DNS 해석 테스트
kubectl run dns-debug --image=busybox -it --rm --restart=Never \
-n development -- nslookup api-service.production
# Server: 10.96.0.10
# Name: api-service.production.svc.cluster.local
# Address 1: 10.96.45.100
# 현재 파드의 resolv.conf 확인 (어떤 search domain이 설정되어 있는지)
kubectl exec -it frontend-pod -n development -- cat /etc/resolv.conf
# nameserver 10.96.0.10
# search development.svc.cluster.local svc.cluster.local cluster.local
# ↑ 현재 namespace가 첫 번째 search domain
심화 — 네임스페이스 삭제는 왜 멈추는가
심화: Namespace 삭제의 실제 — finalizer와 네임스페이스 컨트롤러 reconcile
kubectl delete namespace는 리소스를 곧바로 지우는 명령처럼 보이지만, 실제로는 "삭제해도 좋다"는 표시만 남기는 요청입니다. 네임스페이스가 Terminating에서 오래 멈추는 사고를 이해하려면, 삭제가 어떤 컨트롤 루프를 거치는지 알아야 합니다.
- 삭제는 두 단계다: API 서버는 네임스페이스에 deletionTimestamp를 찍고
kubernetesfinalizer를 남깁니다. finalizer가 붙어 있는 한 오브젝트는 실제로 사라지지 않습니다. - 네임스페이스 컨트롤러가 정리한다: 컨트롤러는 이 finalizer를 붙잡고, API discovery로 "네임스페이스 범위 리소스 종류"를 전부 열거한 뒤 종류마다 남은 오브젝트를 삭제합니다. 파드·PVC·Secret이 모두 비워졌음을 확인해야 finalizer를 떼고 네임스페이스가 사라집니다.
- discovery가 실패하면 멈춘다: 이 열거는 aggregated APIService(예: metrics.k8s.io를 제공하는 metrics-server, 커스텀 metrics 어댑터)까지 물어봅니다. 그 API가 Available=False면 컨트롤러는 아직 못 지운 종류가 남았을 수 있다고 판단해 finalizer를 떼지 않습니다. 안이 텅 비어 보여도 Terminating이 끝나지 않는 이유입니다.
- 리소스 자체 finalizer도 흔한 원인: 특정 오브젝트에 붙은 finalizer(PVC의 pv-protection 등)가 안 떨어지면 그 리소스가 남아 네임스페이스도 못 지웁니다.
그래서 Terminating이 안 끝날 때 spec.finalizers를 강제로 비우는 것은 마지막 수단입니다 — 남은 리소스를 고아로 만들고, 진짜 원인(깨진 확장 API)을 덮어버립니다.
상황: team-a 네임스페이스를 지웠는데 STATUS가 계속 Terminating입니다. kubectl get all -n team-a, kubectl get pvc,secret -n team-a 모두 비어 있고, 다른 네임스페이스 삭제는 정상입니다.
원인: 네임스페이스 컨트롤러가 삭제를 끝내려면 "이 네임스페이스에 어떤 종류의 리소스가 있는지"를 API discovery로 다 물어봐야 합니다. 그런데 클러스터에 등록된 aggregated APIService 하나(예: v1beta1.metrics.k8s.io)가 Available=False였습니다. metrics-server가 죽어 그 API 응답이 끊기자 discovery가 실패했고, 컨트롤러는 리소스 종류 열거를 끝내지 못해 kubernetes finalizer를 떼지 못한 것입니다.
진단: 죽은 확장 API와 네임스페이스 조건을 확인합니다.
kubectl get apiservice | grep -v True
# v1beta1.metrics.k8s.io ... False (MissingEndpoints)
kubectl get namespace team-a -o json | jq '.status.conditions'
# NamespaceDeletionDiscoveryFailure ... "Discovery failed for some groups"
status.conditions에 NamespaceDeletionDiscoveryFailure가 뜨면 discovery 문제로 확정입니다.
해결: 근본 원인인 확장 API를 고칩니다 — metrics-server를 되살리거나, 더 이상 안 쓰는 APIService면 kubectl delete apiservice v1beta1.metrics.k8s.io로 제거합니다. discovery가 다시 성공하면 컨트롤러가 스스로 삭제를 완료합니다. spec.finalizers를 직접 비우는 우회는 남은 리소스를 고아로 만들고 원인을 가리므로 마지막 수단으로만 씁니다.
실무에서 Namespace를 어떻게 구분하는가
팀마다 다르지만 가장 많이 쓰이는 두 가지 패턴입니다.
패턴 1: 환경별 분리
production ← 운영 환경 (인프라 팀 관리)
staging ← 스테이징 (QA 팀 접근)
development ← 개발 환경 (개발 팀 자유롭게 사용)
패턴 2: 팀별 분리
team-backend ← 백엔드 팀
team-frontend ← 프론트엔드 팀
team-data ← 데이터 팀
infra ← 공유 인프라 (Ingress Controller, 모니터링)
규모가 커지면 두 패턴을 조합합니다: backend-prod, backend-dev, frontend-prod 등.
RBAC으로 Namespace 접근 제어
# 개발팀에게 development Namespace만 접근 권한 부여
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-team-binding
namespace: development # 이 Namespace에서만 유효
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: edit # edit = 조회, 생성, 수정 가능 (삭제 불가)
subjects:
- kind: Group
name: dev-team # OIDC 그룹 또는 ServiceAccount
apiGroup: rbac.authorization.k8s.io
Namespace 삭제 시 주의
Namespace 삭제
안전한 실행 조건: 학습용 Namespace이거나 소유 리소스를 모두 확인한 뒤 정리할 때만 실행하세요.
실행 전 반드시 확인
- 현재 컨텍스트와 Namespace가 의도한 대상인지 확인했는가
- 운영 트래픽이나 상태 저장 데이터에 미치는 영향을 확인했는가
- 되돌릴 매니페스트, 백업, 또는 복구 절차가 준비되어 있는가
kubectl delete namespace development위 항목을 모두 확인한 후 복사할 수 있습니다
# Namespace 삭제는 그 안의 모든 리소스를 삭제함
kubectl delete namespace development
# 삭제 전 반드시 내부 리소스 확인
kubectl get all -n development
kubectl get pvc -n development # PVC는 데이터 포함
# Namespace가 Terminating 상태에 멈추는 경우 (finalizer 문제)
kubectl get namespace development -o json | jq '.spec.finalizers'
# 비어 있어야 정상 삭제됨
공유 서비스를 위한 Namespace 패턴
monitoring ← Prometheus, Grafana (전체 팀이 읽기 접근)
ingress-nginx ← Ingress Controller (인프라 팀 관리)
cert-manager ← 인증서 자동화
logging ← Loki, ELK (전체 로그 집중)
이런 공유 Namespace는 ClusterRole로 특정 팀에 읽기 권한만 부여하고, 수정은 인프라 팀만 가능하게 제한합니다.
정리
Namespace 삭제
안전한 실행 조건: 학습용 Namespace이거나 소유 리소스를 모두 확인한 뒤 정리할 때만 실행하세요.
실행 전 반드시 확인
- 현재 컨텍스트와 Namespace가 의도한 대상인지 확인했는가
- 운영 트래픽이나 상태 저장 데이터에 미치는 영향을 확인했는가
- 되돌릴 매니페스트, 백업, 또는 복구 절차가 준비되어 있는가
kubectl delete namespace <name> # 안의 모든 리소스도 삭제됨!위 항목을 모두 확인한 후 복사할 수 있습니다
# Namespace 관련 주요 명령어
# Namespace 목록
kubectl get namespaces
kubectl get ns # 축약형
# Namespace 생성/삭제
kubectl create namespace <name>
kubectl delete namespace <name> # 안의 모든 리소스도 삭제됨!
# 특정 Namespace에서 명령어 실행
kubectl get pods -n <namespace>
kubectl get all -n <namespace>
# 모든 Namespace에서 조회
kubectl get pods -A
kubectl get pods --all-namespaces
# 기본 Namespace 변경 (매번 -n 생략하려면)
kubectl config set-context --current --namespace=<namespace>
# ResourceQuota 확인
kubectl describe resourcequota -n <namespace>
# LimitRange 확인
kubectl describe limitrange -n <namespace>
# 다른 Namespace 서비스 접근 (DNS)
# http://<service-name>.<namespace>.svc.cluster.local
네임스페이스 생성 및 확인
kubectl create namespace development
kubectl create namespace staging
kubectl create namespace production
kubectl get namespaces | grep -E 'development|staging|production'예상 출력
development Active 5s production Active 5s staging Active 5s
ResourceQuota 적용
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: ResourceQuota
metadata:
name: dev-quota
namespace: development
spec:
hard:
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
pods: "5"
EOF예상 출력
resourcequota/dev-quota created
쿼터 현황 확인
kubectl describe resourcequota dev-quota -n development예상 출력
Name: dev-quota Namespace: development Resource Used Hard -------- ---- ---- limits.cpu 0 2 limits.memory 0 2Gi pods 0 5 requests.cpu 0 1 requests.memory 0 1Gi
다른 네임스페이스 서비스 DNS 이름 확인
kubectl run dns-test --image=busybox:1.36 -it --rm --restart=Never -n development -- nslookup kubernetes.default.svc.cluster.local예상 출력
Server: 10.96.0.10 Name: kubernetes.default.svc.cluster.local Address 1: 10.96.0.1
실습 리소스 정리
kubectl delete namespace development staging production예상 출력
namespace "development" deleted namespace "staging" deleted namespace "production" deleted
명령어·단축키 빠른 참조
이 모듈에서 다룬 네임스페이스 조회·자원 제한·크로스 네임스페이스 DNS·삭제 진단 명령을 실전 옵션과 함께 모았습니다.
| 명령어/단축키 | 용도 | 자주 쓰는 예 |
|---|---|---|
kubectl get ns | 네임스페이스 목록·STATUS 확인 | kubectl get ns --show-labels(env/team 레이블) |
kubectl create/delete namespace | 네임스페이스 생성·삭제 | kubectl delete namespace dev(안의 모든 리소스도 삭제) |
kubectl get ... -n / -A | 특정/전체 네임스페이스 리소스 조회 | kubectl get pods -A(= --all-namespaces) |
kubectl config set-context | 기본 네임스페이스 변경(매번 -n 생략) | kubectl config set-context --current --namespace=development |
kubectl config view --minify | 현재 컨텍스트의 기본 네임스페이스 확인 | kubectl config view --minify | grep namespace |
kubectl describe resourcequota | 네임스페이스 총량 Used/Hard 확인 | kubectl describe resourcequota dev-quota -n development |
kubectl describe limitrange | 컨테이너 기본값·min/max 확인 | kubectl describe limitrange dev-limits -n development |
kubectl api-resources | 네임스페이스 범위 vs 클러스터 범위 구분 | kubectl api-resources --namespaced=true |
| 크로스 네임스페이스 DNS | 다른 네임스페이스 서비스 접근 | curl http://api-service.production.svc.cluster.local |
kubectl run ... -- nslookup | 서비스 DNS 해석 테스트 | kubectl run dns-test --image=busybox -it --rm -- nslookup api-service.production |
kubectl get ns -o json | jq | Terminating 멈춤 시 finalizer·조건 확인 | kubectl get ns team-a -o json | jq '.status.conditions' |
kubectl get apiservice | 삭제 교착 유발하는 죽은 확장 API 탐지 | kubectl get apiservice | grep -v True |
관련 모듈로 더 깊이:
- RBAC(Role-based Access Control) 기반 다중 사용자 보안 — 네임스페이스 경계 위에 Role/RoleBinding으로 팀별 접근 권한을 부여하는 법
- requests와 limits 적정 값 계산과 CPU 스로틀링 대처 — 네임스페이스 단위로 CPU·메모리 쿼터를 걸어 팀 간 자원 독점을 막는 법
- NetworkPolicy를 활용한 특정 파드 간 통신 차단 및 제한 — 같은 클러스터의 다른 네임스페이스 파드 간 통신을 격리하는 L3/L4 정책
다음 모듈 rbac에서는 네임스페이스와 연계한 접근 제어를 다룹니다. Role과 RoleBinding으로 특정 네임스페이스에만 권한을 부여하고, ServiceAccount에 최소 권한을 적용해 멀티팀 클러스터 보안 경계를 구성하는 방법을 실습합니다.