동료 개발자들에게 Kubernetes의 기본 구성을 설명하다보면 Namespace에 대한 질문이 나오곤 한다.
- Namespace를 왜 써야 하는가?
- Namespace를 어떻게 써야 하는가?
Namespace는 Kubernetes 클러스터를 운영하는 개발자들이 정확히 알아야 할 개념이기 때문에 이번 아티클에서 다뤄보려 한다. Namespace와 Service 리소스 관련해 유의할 점도 함께 알아보겠다.
1. Namespace를 왜 써야 할까?
우리가 흔히 알고 있는 Namespace의 사용 목적은 ‘리소스를 논리적으로 나누기 위함’이다.
하지만 이런 설명은 너무 추상적이고 와닿지 않는다. 그래서 Namespace를 고려하지 않고 클러스터를 운영하면 어떤 문제가 일어날 수 있는지를 먼저 살펴보겠다.
참고로 Kubernetes 클러스터는 default Namespace를 가지고 있고 기본값으로 사용된다. 별도의 Context 설정을 하지 않았다면 kubectl get pods 명령어를 실행할 경우 default Namespace에 배포된 Pod의 목록이 출력되는 것도 바로 이 때문이다.
리소스 이름 중복으로 인한 문제

Namespace 안에서는 고유한 이름의 리소스만 배포할 수 있다. 바꿔 말하자면, 이미 리소스가 배포된 상황에서 같은 이름의 리소스를 다시 배포할 경우 문제가 생길 수 있다는 것이다.
특히 우리가 자주 사용하는 kubectl apply 명령어는 기존에 배포된 리소스를 업데이트하기 때문에 의도치 않게 리소스가 덮어씌워지는 문제가 발생할 수 있다.
여러 팀이 Namespce를 고려하지 않고 자신들의 DB를 Kubernetes 클러스터에 배포해서 운영 중이라고 해보자. 즉, 모두 default Namespace에 DB를 올려서 사용하고 있는 상황이다.
DB를 운영하려면 다양한 설정값들을 관리해야 하는데 Kubernetes의 ConfigMap 리소스가 그 역할을 해준다. 여기까진 문제 없다.
A 팀의 DB가 기존에 사용하던 ConfigMap 리소스 이름이 db-config라고 해보자. 이때 B 팀이 자신들이 사용할 DB와 ConfigMap 리소스를 새로 배포했는데 ConfigMap의 이름도 우연히 db-config라면 어떻게 될까?
A 팀이 기존에 배포해서 사용 중이던 ConfigMap이 B 팀이 새로 배포한 ConfigMap에 덮어씌워지고, A 팀의 DB는 예상치 못한 오류가 발생할 것이다.
Namespace는 이런 예상치 못한 리소스 충돌 위험을 줄여준다.
팀별로, 혹은 서비스별로 Namespace를 나눈다면 각 영역별로 필요한 리소스만 모일 수 있기 때문이다.
의도치 않은 실수의 영향 범위 확대

모든 리소스가 동일한 Namespace에 올라가 있을 경우, 의도치 않은 실수 하나도 배포된 모든 리소스를 위협할 수 있다.
특히 kubectl 명령어 실수는 치명적인 결과를 불러일으킬 위험이 있다.
테스트용 Pod를 삭제하려다가 애먼 Pod를 삭제하는 건 의외로 흔히 벌어질 수 있는 실수이다. 그런데 만약 그렇게 삭제된 Pod가 주문 또는 결제 서비스였다면 어떻게 될까?
상상만 해도 끔찍하지만, Namespace의 구분이 없다면 이런 실수 하나가 모든 리소스에 영향을 준다는 것만은 기억하자.
Namespace는 이런 실수가 더 크게 퍼지지 않도록 방화벽 역할을 수행한다.
별도의 Namespace에서 테스트용 Pod를 배포했다가 지울 경우, kubectl 명령어 실수가 일어나더라도 그 Namespace 안의 리소스만 영향을 받기 때문이다.
2. 그렇다면 어떻게 써야 할까?
Namespace를 잘 쓰려면 먼저 우리 조직에 맞는 기준을 세워야 한다.
Namespace 생성 기준은 아래와 같이 조직의 규모로 따져볼 수 있다.
- 소규모 팀:
auth,payment,monitoring처럼 서비스나 도메인 단위로 Namespace를 나눔- 서비스 간 간섭을 줄이고 구조를 한눈에 파악 가능
- 대규모 조직:
- 개발 팀 단위로 Namespace를 나눔
또는, 아래와 같이 환경을 기준으로 분리할 수도 있다. 예상치 못한 실수가 일어나도 운영 중인 리소스에는 영향을 주지 않아 안정적인 운영에 도움이 된다.
- 개발:
dev - 검증:
staging - 운영:
prod
물론 지금까지 알아본 규칙을 조합해서 Namespace의 네이밍 컨벤션을 만들 수도 있다. 예를 들면 아래와 같다.
<팀 이름>-<서비스 이름>-<환경>
가령, Alpha 팀의 Payment 서비스의 검증용 리소스들이 모이는 Namespace는 alpha-payment-staging으로 이름을 지어 운영할 수 있을 것이다.
3. Namespace와 Service 리소스
지금까지 Namespace를 왜 써야 하고, 어떻게 쓰면 좋은지 알아봤다.
Namespace를 나눠 리소스를 배포하는 상황에서 Service를 통해 Pod에 접근할 때의 유의점을 알아보자.
Pod에서 다른 Service 리소스에 접근할 때 해당 Service 이름을 사용할 수 있다는 사실은 많이 알고 있을 것이다.
예를 들어 테스트용 Pod에서 auth-svc라는 이름의 Service 리소스에 접근하려면 아래와 같은 명령어를 사용할 수 있다. (auth-svc의 port 값은 80이라고 하자.)
curl auth-svc하지만 이건 테스트용 Pod와 해당 Service 모두 동일한 Namespace에 있을 때의 이야기이다.
즉, 다른 Namespace에 배포된 Service 리소스를 참조하려면 Service 이름만이 아닌 전체 도메인 주소가 필요하다는 말이다.
만약 다른 Namespace에 있는 Pod가 auth-dev Namespace에 배포된 auth-svc Service 리소스에 접근하고 싶다면 아래와 같은 도메인 주소를 사용해야 한다.
auth-svc.auth-dev.svc.cluster.local.
이걸 FQDN(Fully Qualified Domain Name)이라고 하며, 아래와 같은 양식으로 이루어져있다.
{리소스 이름}.{리소스의 Namespace}.{리소스 유형}.cluster.local.
(양식의 마지막 .은 생략 가능하다.)
FQDN은 Kubernetes 클러스터에 배포된 리소스의 고유한 내부 주소를 의미하는데, Namespace가 다른 Service를 참조할 때엔 그 Namespace도 함께 명시해야 하므로 FQDN을 사용한다.
Service 리소스를 참조할 때 FQDN 전체를 다 쓰지 않고 {Service 리소스 이름}.{Service의 Namespace} 형식으로 줄여쓰는 것도 가능하다.
마무리
Kubernetes의 Namespace는 클러스터에 배포할 리소스를 단순히 논리적으로 나누는 것에서 끝나지 않는다.
조직에서 배포하는 리소스를 그룹화해 혼란을 최소화하고 협업을 용이하게 만들어준다. 게다가 의도치 않은 장애가 다른 리소스에 영향을 주는 것도 막아줘 운영의 안정성을 높여주는 중요한 역할을 수행한다.
이런 Namespace에 대해 제대로 이해하고 FQDN까지 짚어봤으니, 앞으로 Kubernetes 클러스터에서 Namespace를 마주할 때 든든한 기반 지식이 될 것이라 생각한다.
익숙해보였던 개념도 제대로 살펴보면 새롭게 배우는 것들이 있다. Kubernetes를 이해하는 데에 든든한 뒷받침이 되는 주제가 있다면 앞으로도 계속 다뤄보도록 하겠다.