coredot.today
쿠버네티스 첫걸음 6편 — 네임스페이스와 Git으로 팀과 협업하기: context 규칙, Kustomize, 권한까지
블로그로 돌아가기
Kubernetes네임스페이스kubeconfigcontextKustomizeGitOpsRBAC협업compose매니페스트튜토리얼

쿠버네티스 첫걸음 6편 — 네임스페이스와 Git으로 팀과 협업하기: context 규칙, Kustomize, 권한까지

혼자 쓰던 쿠버네티스를 팀과 함께 쓰면 새 문제가 생깁니다. 동료의 파드를 지우고, 운영 클러스터에서 실습 명령을 치고, 누가 무엇을 바꿨는지 아무도 모릅니다. 네임스페이스로 공간을 나누고, context 이름 규칙과 프롬프트 표시로 실수를 막고, 매니페스트를 Git에 두고 kubectl diff·apply만으로 바꾸는 원칙, Kustomize로 개발·운영의 차이를 한 저장소에서 다루는 법, 기본 제공 view 역할로 동료에게 읽기 권한만 주는 RBAC까지 실습합니다. 도커 compose.yaml 각 줄이 쿠버네티스에서 무엇이 되는지 보여 주는 대응 위젯과 팀 README 템플릿으로 시리즈를 마무리합니다.

코어닷투데이2026-09-2731분

들어가며 — 혼자일 때는 없던 문제들

쿠버네티스로 협업하기크게 보기

1~5편은 내 노트북의 클러스터에서 혼자 실습했습니다. 무엇을 지워도, 무엇을 망가뜨려도 괜찮았습니다. 그런데 팀이 같은 클러스터를 쓰기 시작하면 이런 일이 생깁니다.

💥
실제로 자주 일어나는 사고
① 둘 다 hello-api라는 이름으로 배포해 서로 덮어썼다 ② 로컬인 줄 알고 운영 클러스터에서 kubectl delete를 쳤다 ③ 누군가 kubectl edit로 설정을 바꿔 놓았는데 아무도 모르고, 다음 배포 때 원래대로 돌아가 장애가 재발했다
🧭
이 글의 해법 네 가지
네임스페이스로 공간을 나누고, context 규칙으로 어디 있는지 늘 알고, Git + apply로만 바꾸고, 권한(RBAC)으로 할 수 있는 일을 제한한다.

1. 먼저, 이미 아는 것에서 출발 — compose와 쿠버네티스

도커 첫걸음 5편에서 팀과 협업하는 compose.yaml을 만들었습니다. 쿠버네티스 협업도 같은 원칙(파일을 공유하고, 비밀은 분리하고, 같은 명령으로 띄운다) 위에 있습니다. compose.yaml의 각 줄을 눌러 쿠버네티스에서 무엇이 되는지 확인해 보세요. 대부분 이름만 바뀐 같은 개념입니다.

2. 네임스페이스 — 한 클러스터를 여러 칸으로

클러스터 하나를 개발·스테이징·운영 네임스페이스로 나눈 모습크게 보기

네임스페이스는 클러스터 안의 폴더입니다. 같은 이름의 리소스도 네임스페이스가 다르면 공존할 수 있고, 권한과 자원 한도를 네임스페이스 단위로 줄 수 있습니다. 지금까지 우리가 쓴 곳은 default 네임스페이스였습니다.

bash
kubectl get namespaces
kubectl create namespace dev-kim
kubectl apply -f k8s/ -n dev-kim
kubectl get pods -n dev-kim

매번 -n을 붙이기 귀찮다면 현재 context의 기본 네임스페이스를 바꿉니다(5편의 kubens dev-kim과 같음).

bash
kubectl config set-context --current --namespace=dev-kim
네임스페이스 나누는 방식예시언제
환경별dev, staging, prod작은 팀이 클러스터 하나를 쓸 때. 단, 운영은 별도 클러스터로 떼는 것이 더 안전하다
팀·서비스별payments, search여러 팀이 한 클러스터를 나눠 쓸 때
사람·기능별 (임시)dev-kim, pr-142개인 실험, PR 미리보기. 끝나면 네임스페이스째 삭제
🧹
정리가 한 줄. kubectl delete namespace dev-kim을 치면 그 안의 디플로이먼트·서비스·ConfigMap·Secret이 전부 사라집니다. 개인 실험을 전용 네임스페이스에서 하면 "뭘 만들었더라?" 하며 찾아 지울 일이 없습니다. 반대로 말하면 네임스페이스 삭제는 가장 강력한 삭제이니 이름을 꼭 두 번 확인하세요.
🖥️
팀이 함께 쓸 클러스터가 아직 없다면? 사내 리눅스 서버나 VM 한 대에 k3s를 설치하면 명령 한 줄로 팀 공용 개발 클러스터가 생깁니다. 설치, 워커 추가, 노트북에서 접속, Traefik으로 도메인 열기까지 2편 9장에 정리했습니다. 이 글의 네임스페이스·권한 규칙을 그 클러스터에 그대로 적용하면 됩니다.

다른 네임스페이스의 서비스는 서비스이름.네임스페이스로 부릅니다. dev-kim의 앱이 shared 네임스페이스의 DB에 접속하려면 db.shared 또는 db.shared.svc.cluster.local입니다.

3. context 규칙 — "지금 어디지?"를 없애기

2편에서 kubeconfig와 context를 봤습니다. 팀에서는 로컬 클러스터 외에 개발·운영 클러스터의 context가 추가됩니다. 사고의 대부분은 엉뚱한 context에서 명령을 치는 것입니다.

이름을 읽히게
자동 생성된 긴 이름(arn:aws:eks:ap-northeast-2:1234...:cluster/prod-x)을 짧고 분명한 이름으로 바꾼다: kubectl config rename-context <긴이름> prod
늘 보이게
5편의 kube-ps1이나 k9s로 프롬프트·화면에 현재 context를 항상 표시한다. 운영 context는 빨간색으로 설정하는 팀이 많다.
스크립트는 명시적으로
배포 스크립트에서는 현재 context에 기대지 말고 kubectl --context=staging apply -k ...처럼 매번 적는다.
운영은 기본값이 아니게
일이 끝나면 로컬 context로 돌아온다(kubectx -). 운영 kubeconfig를 별도 파일로 두고 필요할 때만 KUBECONFIG=~/.kube/prod kubectl ...로 쓰는 방법도 있다.
🔒
kubeconfig 파일을 서로 주고받지 마세요. 한 사람의 kubeconfig를 복사해 여럿이 쓰면 누가 무엇을 했는지 기록이 남지 않고, 퇴사자 권한을 회수할 수도 없습니다. 클라우드 클러스터는 각자 자기 계정으로 kubeconfig를 받습니다 — 예를 들어 EKS는 aws eks update-kubeconfig --name 클러스터 --region ap-northeast-2, GKE는 gcloud container clusters get-credentials 클러스터. 자세한 것은 관리형 쿠버네티스 가이드를 참고하세요.

4. Git이 원본이다 — 매니페스트 저장소 규칙

도커 5편의 원칙 "컨테이너 안에서 손으로 설치한 것은 없는 것"이 쿠버네티스에서는 이렇게 바뀝니다. 클러스터에서 손으로 바꾼 것은 없는 것. 원하는 상태의 원본은 Git의 YAML이고, 클러스터는 그 YAML을 반영한 결과일 뿐입니다.

하지 말 것왜대신
kubectl edit deployment ...변경 기록이 없고, 다음 apply 때 원래대로 돌아간다YAML 수정 → PR → 리뷰 → apply
kubectl scale, kubectl set image (공유 환경)같은 이유. 4편에서 본 "파일은 3인데 클러스터는 5" 불일치YAML의 숫자·태그를 바꿔 커밋
kubectl create ...로 리소스 만들기어떤 옵션으로 만들었는지 아무도 모른다--dry-run=client -o yaml로 YAML을 뽑아 커밋
Secret YAML 커밋base64는 암호화가 아니다 (4편)Sealed Secrets·External Secrets, 또는 CI의 비밀 변수
👀
apply 전에 diff. kubectl diff -f k8s/는 지금 클러스터와 파일의 차이를 git diff처럼 보여 주고, 아무것도 바꾸지 않습니다. 공유 환경에 apply 하기 전에는 항상 diff로 "내가 바꾸려는 것만 바뀌는지" 확인하세요. 누군가 손으로 바꿔 둔 것도 여기서 드러납니다.

GitOps는 이 원칙을 끝까지 밀어붙인 방식입니다. 사람이 apply 하지 않고, Argo CD나 Flux 같은 도구가 Git 저장소를 지켜보다가 바뀌면 자동으로 클러스터에 반영하고, 누가 손으로 바꾸면 되돌립니다. 팀이 커지면 자연스럽게 가는 다음 단계입니다.

5. Kustomize — 개발과 운영의 차이를 한 저장소에서

개발에서는 파드 1개·로컬 이미지, 운영에서는 파드 3개·레지스트리 이미지처럼 환경마다 조금씩 다른 값이 필요합니다. YAML을 환경마다 통째로 복사하면 금방 서로 어긋납니다. Kustomize는 공통 YAML(base) 위에 환경별 차이(overlay)만 덧씌웁니다. kubectl에 내장되어 있어 따로 설치할 필요가 없습니다.

4편의 k8s/ 폴더를 이렇게 정리합니다.

  • k8s/base/ — 공통 부품
    • deployment.yaml · service.yaml (4편의 것 그대로)
    • kustomization.yaml
  • k8s/overlays/dev/kustomization.yaml — 개발 환경의 차이
  • k8s/overlays/prod/kustomization.yaml — 운영 환경의 차이
bash
mkdir -p k8s/base k8s/overlays/dev k8s/overlays/prod
mv k8s/deployment.yaml k8s/service.yaml k8s/base/

k8s/base/kustomization.yaml — 공통 부품 목록입니다.

yaml
resources:
  - deployment.yaml
  - service.yaml

k8s/overlays/dev/kustomization.yaml — 개발 환경의 차이만 적습니다.

yaml
namespace: dev
resources:
  - ../../base
images:
  - name: hello-api
    newTag: "0.3"
replicas:
  - name: hello-api
    count: 1

k8s/overlays/prod/kustomization.yaml — 운영은 레지스트리 이미지와 3개.

yaml
namespace: prod
resources:
  - ../../base
images:
  - name: hello-api
    newName: ghcr.io/myteam/hello-api
    newTag: "0.3"
replicas:
  - name: hello-api
    count: 3

결과 YAML을 미리 보고, 차이를 확인하고, 적용합니다. -f 대신 -k(Kustomize)를 씁니다.

bash
kubectl kustomize k8s/overlays/dev
kubectl create namespace dev
kubectl diff -k k8s/overlays/dev
kubectl apply -k k8s/overlays/dev

이미지 태그를 올리는 배포는 이제 overlay 파일의 newTag 한 줄을 바꾸는 PR입니다. 리뷰어는 "무엇이, 어느 환경에서 바뀌는지"를 정확히 볼 수 있습니다. CI가 kubectl apply -k를 대신 실행하게 하면(또는 GitOps 도구가 지켜보면) 사람이 운영 클러스터에 직접 명령을 칠 일이 거의 사라집니다.

💡
Kustomize와 Helm, 무엇을 쓸까? 우리 앱은 Kustomize(평범한 YAML + 환경별 덧씌우기)로 시작하는 것이 이해하기 쉽고 리뷰하기도 좋습니다. 남이 만든 소프트웨어(모니터링, DB 운영 도구 등)는 5편의 Helm 차트로 설치합니다. 많은 팀이 이 두 가지를 함께 씁니다.

6. 권한 — 필요한 만큼만 (RBAC)

모두가 클러스터 관리자 권한을 가지면 실수 하나가 전체 장애가 됩니다. 쿠버네티스의 RBAC(역할 기반 접근 제어)은 "누가, 어느 네임스페이스에서, 무엇을 할 수 있나"를 정합니다. 처음부터 역할을 직접 설계할 필요는 없습니다. 쿠버네티스가 기본 역할을 제공합니다.

기본 역할 (ClusterRole)할 수 있는 일누구에게
view대부분의 리소스 읽기 (Secret은 제외)QA·기획·신규 입사자, 운영 클러스터의 대부분 개발자
edit대부분의 리소스 만들기·고치기·지우기 (권한 설정은 제외)그 네임스페이스를 담당하는 개발자
admin네임스페이스 안의 모든 것, 권한 부여 포함팀 리드
cluster-admin클러스터 전체의 모든 것플랫폼 운영자 극소수

역할을 사람(또는 그룹)에게 연결하는 것이 RoleBinding입니다. QA 팀에 dev 네임스페이스 읽기 권한만 주는 예입니다.

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: qa-view
  namespace: dev
subjects:
  - kind: Group
    name: qa-team
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: view
  apiGroup: rbac.authorization.k8s.io

권한이 의도대로인지는 auth can-i로 확인합니다. --as로 다른 사람인 척 물어볼 수 있습니다(관리자만 가능).

bash
kubectl auth can-i delete pods -n dev --as=qa-user --as-group=qa-team
kubectl auth can-i list pods -n dev --as=qa-user --as-group=qa-team

첫 줄은 no, 둘째 줄은 yes가 나와야 합니다. 5편의 팀 공용 Headlamp도 이런 읽기 권한과 함께 쓰면, 비개발 동료가 안심하고 상태를 들여다볼 수 있습니다.

ℹ️
"그룹 qa-team"은 어디서 오나? 쿠버네티스는 사용자 계정을 직접 관리하지 않고, 클라우드 IAM(EKS의 Access Entry, GKE의 Google 그룹 등)이나 회사 SSO가 알려 주는 사용자·그룹 이름을 씁니다. 로컬 클러스터에서는 이 부분을 실습하기 어려우니, 개념만 잡고 실제 연결은 클러스터 운영자와 함께 하세요.

7. 라벨 규칙 — 모두가 같은 이름표를

4편에서 서비스가 라벨로 파드를 찾는 것을 봤습니다. 라벨은 검색·권한·비용 집계·대시보드 필터에도 쓰이므로, 팀 전체가 같은 규칙을 쓰면 좋습니다. 쿠버네티스가 권장하는 공통 라벨이 있습니다.

yaml
metadata:
  labels:
    app.kubernetes.io/name: hello-api
    app.kubernetes.io/version: "0.3"
    app.kubernetes.io/component: backend
    app.kubernetes.io/part-of: hello
    app.kubernetes.io/managed-by: kustomize

이렇게 해 두면 kubectl get all -l app.kubernetes.io/part-of=hello -A처럼 서비스 하나에 속한 모든 것을 한 번에 찾을 수 있고, Headlamp·k9s 같은 도구도 이 라벨로 앱을 묶어 보여 줍니다.

8. 팀 규칙 체크리스트

공간
실험은 개인 네임스페이스(dev-이름)에서, 끝나면 네임스페이스째 삭제. 운영은 가능하면 별도 클러스터.
위치
context 이름은 짧고 분명하게(local·dev·prod). 프롬프트에 항상 표시. 스크립트는 --context를 명시.
변경
공유 환경은 Git의 YAML만이 원본. diff → apply. edit·scale·set image는 로컬에서만.
비밀
Secret YAML·kubeconfig는 커밋·공유 금지. 각자 자기 계정으로 접속.
권한
기본은 view, 담당 네임스페이스만 edit. cluster-admin은 극소수.

9. 복사해서 쓰는 README 절

markdown
## 쿠버네티스 로컬 개발

### 준비물
- 로컬 클러스터 하나 (맥: OrbStack 또는 Rancher Desktop / 윈도우: Rancher Desktop)
- kubectl, (선택) k9s · Headlamp
- 확인: `kubectl config current-context` 가 로컬 클러스터인지, `kubectl get nodes` 가 Ready 인지

### 실행
```bash
docker build -t hello-api:0.3 .
kubectl create namespace dev
kubectl apply -k k8s/overlays/dev
kubectl -n dev port-forward svc/hello-api 8080:80
```
- API: http://localhost:8080/docs

### 규칙
- 공유 클러스터(dev·prod)는 PR로만 변경한다. `kubectl edit` 금지
- apply 전에 `kubectl diff -k k8s/overlays/<환경>`
- 명령 전에 현재 context 확인. 운영은 `--context=prod` 명시

10. 시리즈를 마치며 — 전체 지도

1편
클러스터·노드·파드, 원하는 상태
→
2편
무료 로컬 클러스터, kubeconfig
→
3편
kubectl 문법, 파드 진단
4편
디플로이먼트·서비스 배포
→
5편
k9s·Headlamp·Freelens·Helm
→
6편
네임스페이스·Git·권한으로 협업
🧠
6편 요약
· compose의 대부분은 이름만 바뀌어 쿠버네티스로 온다 — 새로운 건 build 없음·depends_on 없음·자가 치유
· 네임스페이스로 공간을 나누고, 실험은 개인 네임스페이스에서
· context는 짧은 이름 + 늘 보이게 + 스크립트에선 명시
· Git이 원본 — diff → apply, 손으로 edit 금지. 다음 단계는 GitOps
· Kustomize로 base + 환경별 overlay, kubectl apply -k
· RBAC 기본 역할(view·edit·admin)과 RoleBinding, 확인은 kubectl auth can-i

쿠버네티스를 어렵게 만드는 것은 기능의 개수가 아니라 그림이 없는 상태에서 명령부터 외우는 것입니다. 클러스터는 회사, 노드는 현장 사무실, 파드는 책상, 디플로이먼트는 "책상 3개 유지"라는 약속, 서비스는 대표 전화번호, 네임스페이스는 층. 이 그림 위에서는 처음 보는 YAML도 "아, 이건 무엇을 몇 개, 어디에 원하는지 적은 거구나" 하고 읽힙니다. 이제 팀 저장소에 k8s/ 폴더 하나를 만드는 것으로 시작해 보세요.


참고 자료