Go, Vantage point
가까운 곳을 걷지 않고 서는 먼 곳을 갈 수 없다.
Github | https://github.com/overnew/
Blog | https://everenew.tistory.com/
티스토리 뷰
쿠버네티스 네임스페이스
네임스페이스는 쿠버네티스에서 용도에 따라서 리소스를 논리적으로 구분하기 위해 사용하는 오브젝트이다.
리눅스의 네임스페이스와 같은 이름이기 때문에 동일한 것으로 생각할 수 있지만, 완전히 다른 것이다.
단순히 파드를 그룹화하여 관리하기 위해 사용하는 것으로 이해하면 쉽다.
리눅스의 네임스페이스는 컨테이너의 격리 공간을 만들기 위해 리눅스 커널의 자체 기능을 활용한다. 일반적으로는 네트워크와 마운트, 프로세스 네임스페이스 등을 의미한다.
리눅스 네임스페이스
프로세스를 실행할 때 시스템의 리소스를 분리해서 실행할 수 있도록 도와주는 기능.
리눅스는 기본적으로 하나의 시스템의 프로세스들은 리소스를 공유하여 실행한다. 예를 들어 자식 프로세스는 부모 프로세스의 네임스페이스에 속하므로 자원을 고유하게 된다.
일반적으로 리눅스의 프로세스들은 모두 init (1번 프로세스)의 자식 프로세스이므로, 모두 자원을 공유한다. 하지만 시스템콜이나 unshare 명령어를 사용해 리소스 별로 네임스페이스를 분리하는 것이 가능하다. 컨테이너에서 사용하는 프로세스 격리 기능도 네임스페이스를 활용한다.
네임스페이스에도 여러 가지 종류가 있다. 주요한 4가지 네임스페이스만 살펴보자.
PID 네임스페이스(pid)
PID로 격리하면 컨테이너가 마치 init 프로세스(최상위) 인 것처럼 실행할 수 있게 된다.
Cgroup 네임스페이스(cgorup)
Control group은 프로세스에서 사용 가능한 컴퓨팅 자원(CPU, Memory, network..)을 group 단위로 제어할 수 있게 해주는 리눅스 커널 기능이다. 이는 컨테이너뿐만 아니라 일반적으로 리눅스 시스템에서도 활용된다.
네트워크 네임스페이스(network)
프로세스별로 네트워크 환경을 구축할 수 있는 격리 기능이다. 이를 통해 프로세스에게 IP를 부여하거나 네트워크 인터페이스를 추가할 수 있다.
IPC(Inter-process communication) 네임스페이스
Inter-process communication는 프로세스 간에 서로 데이터를 주고 받는 경로를 의미한다. 리눅스의 IPC로는 signal, Socket과 pipe 등이 있다. IPC 네임스페이스는 이러한 IPC 리소스의 격리를 제공한다.
pause 컨테이너란?
쿠버네티스에서 Pod 생성시 반드시 자동으로 생성되는 기본 컨테이너로, 일종의 부모 프로세스의 역할을 하는 컨테이너다.
Pod 생성시 네트워크 인터페이스인 eht0이 pause 컨테이너에게 생성되어 연결된다. Pod의 IP를 할당받는 것이 바로, 이 eth0이다.
Pod를 가지는 Node에는 veth0라는 가사의 인터페이스가 생성되어 pause 컨테이너와 1대1로 연결된다.
동일한 Pod 내의 컨테이너들은 Pasue 컨테이너의 Network namespace와 IPC namespace를 공유하게 된다.
따라서 같은 Pod 내의 두 컨테이너에서 확인해보면 동일한 네트워크 구성을 가지고 있다.
그런데 동일한 네트워크 구성을 가지게 때문에 Nginx가 열어둔 포드로 인해 두 컨테이너 모두 80번 port로 listen 중이다.
그렇다면 Pause 컨테이너는 어떻게 특정 컨테이너(Nginx 컨테이너)에게만 http 요청을 전달할 수 있을까?
이를 이해하려면 컨테이너 별로 분리를 하지 않고, pod를 하나의 컨테이너라고 생각한 다음 각 컨테이너를 프로세스라고 생각하면 쉽다. (같은 네임스페이스면 하나로 추상화 하면 이해가 편하다.)
80번 포트를 listening 중인 것은 Nignx이기 때문에, 80번 port로의 트래픽은 Nginx 컨테이너에게 전달된다.
만약 netshoot 컨테이너도 80번 포트를 linstening 하게 되면 동일한 네트워크 네임스페이스에서 같은 포트를 사용하려는 것이 되기 때문에 충돌이 발생해 문제가 발생한다.
따라서 하나의 파드에 웹서비스 두 개 이상 올릴려면, webserver의 port를 바꾸어 줘야 한다.
Docker에서는 각각의 container별로 ip(식별자)를 할당받을 수 있었기 때문에 container가 배포 단위가 되었다. 하지만 k8s에서는 컨테이너가 아니라 Pod가 IP(식별자)를 할당받게 된다.
즉, 실습을 통해 다시 한번 확인할 수 있는 것은 K8s에서의 배포의 최소 단위는 Pod라는 것이다.
아쉽게도 containerd에서는 이러한 pause 컨테이너를 직접 확인할 수 없다. (dockerd에서는 가능하다고 한다.)
이후 다른 Pod와의 통신을 한다면, 네트워크 네임스페이스가 다르기 때문에 서로 다른 IP를 사용하므로 네트워크 연결을 진행하면 된다. 이때 사용하는 것이 CNI 플러그인이고, 대표적인 것이 우리가 설치한 calico이다.
참고
'개발 > Kubernetes' 카테고리의 다른 글
Kubernetes Pod 활용하기 (Pause container, label, volume) (0) | 2024.03.03 |
---|---|
Kubernetes Kubectl 기본 명령어 정리 (0) | 2024.03.03 |
KubeSpary로 Kubernetes 설치하기 (0) | 2024.03.03 |
[Vagrant] Kubeadm로 쿠버네티스 직접 설치하기 (0) | 2024.03.02 |
쿠버네티스 란? (0) | 2024.03.02 |