비유로 시작해보겠습니다. Mark라는 두 소년이 있습니다. 그들은 각자 Smith와 Williams라는 가문에서 왔기 때문에 우리는 두 소년을 구분하기 위해 Smith와 Williams라는 성으로 부릅니다. 그러나 각자의 집 안에서 가족들은 단순히 이름으로 소년에게 말을 걸 것입니다. 예를들어 Mark의 아버지는 Mark를 단순히 Mark라고 부릅니다. 그러나 아버지가 원하신다면 다른 집에 있는 Mark에게 말하기 위해 성을 붙인 이름을 사용할 수도 있습니다. 각 집에는 고유한 규칙이 있으며, 소비할 수 있는 자체 리소스 세트도 있습니다.
이제 Kubernetes로 돌아가보겠습니다. 비유에서 말한 각자의 집은 Kubernetes에서 Namespace에 해당합니다. 지금까지의 과정에서 우리는 파드, Deployment, Service와 같은 오브젝트들을 생성했습니다. 사실 우리가 어떤 것들을 만들던 우리는 하나의 NameSpace안에서 만들었습니다. 그 동안 우리는 NameSpace라는 집 안에 있었던 것입니다. 이 NameSpace는 우리가 따로 설정하지 않았으므로, default namespace라고 합니다.
이 default namespace는 클러스터가 처음 설정될 때 Kubernetes에 의해 자동으로 생성됩니다. Kubernetes는 파드 와 서비스들을 생성합니다.
kubernetes는 파드와 서비스들을 네트워킹 솔루션이나 DNS서비스 등 내부 목적으로 생성합니다. 이를 실수로 삭제하거나 수정하는 것을 방지하기 위해 유저로부터 격리하기위해 Kubernetes는 다른 namespace에 생성합니다. kube-system이라는 클러스터가 시작될 때 생성됩니다. 쿠버네티스가 자동으로 만든 세 번째 NameSpace는 kube-public입니다. 이곳은 모든 사용자가 자원을 사용할 수 있어야 합니다.
작은 환경에서는 NameSpace에 대해 걱정할 필요가 없습니다. default namespace에서 계속 작업할 수 있습니다. 그러나 Kubernetes 클러스터를 확장하고 사용할 때와 마찬가지로 기업 또는 생산 목적으로 Namespace 사용을 고려할 수 있습니다. 예를 들어 개발 및 프로덕션 환경 둘 다에서 동일한 클러스터를 사용하려는 경우에는 그들 사이에 리소스를 격리하려는 목적으로 각각에 대한 고유한 Namespace를 만들 수 있습니다. 이렇게 하면 개발 환경에서 작업하는 동안 프로덕션 리소스를 실수로 수정하는 일이 없습니다.
이러한 각 namespace는 누가 무엇을 할 수 있는지 정의하고, 리소스 할당량을 할당하는 고유한 정책을 가질 수 있습니다. 리소스 사용량을 할당하면 각 네임스페이스가 허용 한도 이상의 리소스를 사용하지 않습니다.
default 네임스페이스로 돌아가서, 우리는 집 안의 가족들 처럼 서로의 이름을 부르며 네임스페이스 내의 리소스를 단순히 이름으로 참조할 수 있습니다. 웹 애플리케이션 파드는 단순히 호스트 이름을 통해 DB서비스에 접근할 수 있습니다. 필요한 경우 웹 애플리케이션 파드도 다른 namespace의 서비스에 접근할 수 있습니다. 이 경우에는 서비스 이름에 네임스페이스 이름을 추가해야겠지요. 예를 들어 default namespace 의 웹 파드의 경우, 개발 환경에서 데이터베이스에 연결하기 위해servicename.namespace.svc.cluster.local 형식을 사용합니다. 즉, dbservice.dev.svc.cluster.local이 됩니다. 서비스가 생성될 때, DNS항목은 이 형식으로 자동으로 추가됩니다. 서비스의 DNS이름을 자세히 살펴보면 마지막 부분인 cluster.local이 있습니다. cluster.local은 Kubernetes클러스터의 default도메인 이름입니다. svc는 namespace뒤에 오며, 서비스의 하위 도메인입니다. 가장 앞에는 서비스 자체의 이름이 옵니다. 이제 Namespace의 몇 가지 운영 측면을 살펴보겠습니다. 아래 커맨드는 모든 파드를 조회하는 데 사용하는 것으로 배웠는데, 사실은 default namespace에 있는 파드만 조회되는 것입니다.
kubectl get pods
다른 namespace에 있는 pod를 조회하려면 커맨드에 namespace 옵션을 함께 사용하면 됩니다.
kubectl get pods --namespace=kube-system
여기에 Pod Definition file이 있습니다.
apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app: myapp type: front-end spec: containers: - name: nginx-container image: nginx
이 파일을 사용하여 파드를 생성하면, 파드는 default namespace에 생성됩니다. 다른 namespcae에 파드를 생성하려면 namespace옵션을 사용해야 합니다.
이 파드가 생성되었는지 확인하려면, 항상 커맨드에 namespace옵션을 붙이지 않아도 커맨드라인의 namespace 정의를 이동할 수 있습니다. 파드 Definition 파일의 metadata섹션 아래에 있습니다. 이는 리소스를 항상 동일한 Namespace 에 생성되도록 보장하는 좋은 방법입니다.
apiVersion: v1 kind: Pod metadata: name: myapp-pod namespace: dev labels: app: myapp type: front-end spec: containers: - name: nginx-container image: nginx
그렇다면 새로운 NameSpace는 어떻게 생성할까요? 다른 오브젝트와 마찬가지로 NameSpace Definition file을 사용합니다.
apiVersion: v1
kind: NameSpace
metadata:
kubectl create -f 커맨드를 사용해서 Namespace를 만들면 됩니다. NameSpace를 만드는 또다른 방법은 단순히 커맨드를 실행하는 것입니다.
kubectl create -f namespace-dev.yaml
혹은 아래 커맨드를 실행하면 됩니다.
kubectl create namespace dev
세 개의 Namespace에서 작업한다고 가정해보겠습니다. 이전에 언급한 것과 같이, 우리는 기본적으로 default namespace에 있기 때문에 kuectl get pods 커맨드를 입력하면 리소스를 확인할 수 있습니다. dev namespace에 있는 리소스를 보려면 namespace 옵션을 사용해야 합니다. 만약 dev namespace를 지정하지 않아도 되도록 namespace를 전환하고 싶다면 kubectl config 커맨드를 사용하면 됩니다. 이 커맨드를 실행하면 현재 컨텍스트의 Namespace를 dev로 설정합니다. 이 작업 후 kubectl get pods를 실행하면 namespace 옵션 없이도 dev환경에 있는 파드를 조회할 수 있습니다. 마찬가지로 pord namespace로 전환할 수 있습니다. 마지막으로 모든 namespace에서 Pod를 확인하고 싶다면, 커맨드에서 all namespace 옵션을 사용하면 됩니다.
kubectl get pods --all-namespaces
커맨드를 자세히 살펴보면, 어떤 커맨드는 먼저 현재 컨텍스트를 식별하고 현재 컨텍스트에 대해 Namespace를 원하는 것으로 설정합니다. 컨텍스트는 여러 클러스터를 관리하는 데 사용됩니다.
namespace에서 리소스를 제한하려면 리소스 할당량을 만들면 됩니다. 리소스 할당량에 대한 definition file로 시작합니다. 할당량을 줄 namespace를 지정하고 사양에 따라 10개의 파드, 10개의 CPU 유닛,10GB 바이트의 메모리 등과 같이할당량을 조정하세요.
apiVersion: v1 kind: ResourceQuota metadata: name: compute-quota namespace: dev spec: hard: pods: "10" requests.cpu: "4" requests.memory: 5Gi limits.cpu: "10" limits.memory: 10Gi
kubectl create -f compute-quota.yaml
테스트 통과 완료