[Kubernetes] 컨테이너 격리 이해하기

Jade·2022년 1월 15일
0

Kubernetes Advanced Networking Study(KANS)의 1주차 내용을 학습하며 정리한 내용입니다.

컨테이너 격리

도커

  • 도커란, 가상실행 환경을 제공해주는 오픈소스 플랫폼이며, 도커에서는 이 가상실행 환경을 컨테이너라고 부른다. 좀 더 정확히 표현하자면 도커 이미지를 기반으로 실행되는 컨테이너화 된 프로세스라고 할 수 있다.

💡 운영체제에서 프로세스는 하나의 작업 단위이다. 그렇다면 프로그램과 프로세스의 차이는 뭘까? 프로그램은 하드디스크 같은 저장장치에 저장되어 있는 정적인 상태고, 프로세스는 실행을 위해 메모리에 올라온 동적인 상태다. 폰노이만 구조에서 프로그램이 실행된다는 것은 해당 코드가 메모리에 올라와서 작업이 진행된다는 의미다. 따라서 누군가가 작성한 프로그램이 실행되면 프로세스가 된다.

  • 도커 이미지만 있다면 환경의 영향을 받지 않고 다양한 환경에서 컨테이너를 기동시킬 수 있기 때문에 이식성이 높다.

도커 아키텍처

컨테이너

  • 컨테이너란, 호스트 OS상에 논리적인 구획을 만들어 애플리케이션을 작동시키기 위해 필요한 라이브러리나 애플리케이션 등을 하나로 모아 마치 별도의 서버인 것처럼 사용할 수 있게 만든 것이다.
  • 컨테이너는 호스트 OS의 리소스를 논리적으로 분리시켜 여러 개의 컨테이너가 공유하여 사용한다. 오버헤드가 적기 때문에 가볍고 고속으로 작동한다는 것이 특징이다.

호스트 OS vs 도커 컨테이너 vs 가상머신

  • 일반적으로 물리 서버에 설치한 호스트 OS의 경우 하나의 OS 상에서 움직이는 여러 애플리케이션과 같은 시스템 리소스를 사용한다. 이때 작동하는 여러 애플리케이션은 데이터를 저장하는 디렉토리를 공유하고, 서버에 설정된 동일한 IP 주소로 통신한다. 그렇기 때문에 여러 애플리케이션에서 사용하고 있는 미들웨어나 라이브러리 버전이 다른 경우, 각 애플리케이션이 서로 영향을 받지 않도록 주의해야 한다.
  • 가상 머신은 기존 호스트 OS에 하이퍼바이저를 설치하고, 그 위에 게스트 OS와 패키징한 VM을 만들어 실행하는 방식인 하드웨어 레벨의 가상화를 지원한다. 그렇기 때문에 보안은 더 좋지만, 오버헤드가 크고 무겁고 느리다는 단점이 있다.
  • 반면, 컨테이너 사용시, 하드웨어 에뮬레이션 없이 리눅스 커널을 공유해서 바로 프로세스를 실행한다. 즉 운영체제를 제외한 나머지 애플리케이션 실행에 필요한 모든 파일을 패키징한다는 점에서 OS레벨 가상화를 지원한다. 호스트 OS의 커널을 공유하지만, 개별적인 user space를 가지고, 가상화된 공간을 생성하기 위해 리눅스 기능인 pivot-root, namespace, cgroup을 사용함으로써 OS나 디렉토리, IP 주소 등과 같은 시스템 자원들을 마치 각 애플리케이션이 점유하고 있는 것처럼 보이게 할 수 있다.

💡 Docker는 Linux 커널 기술을 베이스로 작동한다.

  • namespace: Docker는 컨테이너라는 독립된 환경을 만들고, 그 컨테이너를 구획화하여 애플리케이션 실행 환경을 만드는데, 그때 사용하는 기능이 Linux 커널의 namaspace다. 이것은 한 덩어리의 데이터에 이름을 붙여 분할함으로써 충돌 가능성을 낮추고, 쉽게 참조할 수 있게 할 수 있게 하는 개념이다.
  • cgroups: Docker에서는 물리 머신 상의 자원을 여러 컨테이너가 공유하여 작동한다. 이 때 사용하는 기능이 Linux 커널 기능인 ‘control groups(cgroups)’이다. 리눅스에서는 프로그램을 프로세스로서 실행하는데, 프로세스는 하나 이상의 스레드 모음으로 움직이게 된다. cgroups는 프로세스와 스레드를 그룹화하여, 그 그룹 안에 존재하는 프로세스와 스레드에 대한 관리를 수행하기 위한 기능이다. 또한 계층 구조를 사용하여 프로세스를 그룹화하여 관리할 수도 있다.
  • 결론적으로 컨테이너 기술과 서버 가상화 기술은 매우 비슷하지만 목적이 다르다고 볼 수 있다. 컨테이너 기술은 애플리케이션의 실행 환경을 모음으로써 이식성을 높이고 확장성이 좋은 환경에서 작동하는 것을 지향하는 반면, 가상화 기술은 서로 다른 환경을 어떻게 효율적으로 에뮬레이트할 것인지를 지향한다. (격리 수준은 컨테이너보다 가상머신이 더 높다고 볼 수 있다.)

컨테이너 격리 실습

  • 사전 준비 사항: vagrant로 ubuntu 설치 → Ubuntu 배포 관련 Vagrantfile 파일 다운로드시 Powershell에서 Invoke-WebRequest 대신 curl 사용하기Powershell에서 curl 명령어는 Invoke-WebRequest로 alias 되어 있는데, 나의 경우 그냥 del alias:curl로 alias를 해제하고 curl 명령어를 그대로 실행하였다.

실습 1. 터미널 2개를 띄워 Host와 Container의 Namespace 정보가 다른 것을 확인하기

▪️ PID namespace: PID란, 리눅스에서 각 프로세스에 할당된 고유 ID이다. 여기서 PID namespace는 PID와 프로세스를 격리시킨다. namespace가 다른 프로세스끼리는 서로 액세스할 수 없다.
▪️ Network namespace: 네트워크 디바이스, IP 주소, 포트 번호, 라우팅 테이블, 필터링 테이블 등과 같은 네트워크 리소스를 격리된 namespace마다 독립적으로 가질 수 있다. 이 기능을 사용하면 호스트 OS 상에서 사용 중인 포트가 있더라도 컨테이너 안에서 동일한 번호의 포트를 사용할 수 있다.
▪️ UID namespace: UID(사용자 ID), GID(그룹 ID)를 namespace별로 독립적으로 가질 수 있다. namespace 안과 호스트 OS상의 UID/GID가 서로 연결되어 namespace 안과 밖에서 서로 다른 UID/GID를 가질 수 있다. 예를 들어 namespace 안에서는 UID/GID가 0인 root 사용자를, 호스트 OS 상에서는 일반 사용자로 취급할 수 있다.
▪️ Mount namespace: Linux에서 파일 시스템을 사용하기 위해서는 마운트가 필요하다. 마운트란 컴퓨터에 연결된 기기나 기억장치를 OS에 인식시켜 이용 가능한 상태로 만드는 것이다. Mount namespace는 마운트 조작을 하면 namespace 안에 격리된 파일 시스템 트리를 만든다. 다른 namespace 기능과 마찬가지로 namespace 안에서 수행한 마운트는 호스트 OS나 다른 namespace에서는 액세스할 수 없게 되어 있다.
▪️ UTS namespace: namespace 별로 호스트명이나 도메인명을 독자적으로 가질수 있다.
▪️ IPC namespace: 프로세스 간의 통신(IPC) 오브젝트를 namespace별로 독립적으로 가질 수 있다.

  1. ipc, mnt, net, pid, uts가 다르다.
    • 터미널1 (Ubuntu Container)
    • 터미널2 (Host Shell)
  2. hostname이 다르다.
    • 터미널1 (Ubuntu Container)
    • 터미널2 (Host Shell)
  3. NET(네트워크 환경)이 다르다.
    • 터미널1 (Ubuntu Container)
    • 터미널2 (Host Shell)

실습 2. 컨테이너가 독립된 리눅스 환경을 보장받는 프로세스라면, 호스트에서 컨테이너(프로세스)를 종료할 수 있는지 확인하기

- 터미널1 (Ubuntu Host)![](https://velog.velcdn.com/images%2F200ok%2Fpost%2Fe8aa3a27-6aac-49f6-af43-8e24160c9335%2Fimage.png)docker run —rm -it ubuntu bash 명령어 실행 후, 컨테이너 내부에서 아래 내용 실행![](https://velog.velcdn.com/images%2F200ok%2Fpost%2F2430e0ec-0eb4-4773-9470-a14ac7724b28%2Fimage.png)

- 터미널2 (Host Shell)
![](https://velog.velcdn.com/images%2F200ok%2Fpost%2F7d94fa91-1057-46d0-8b2a-860080c68ff4%2Fimage.png)![](https://velog.velcdn.com/images%2F200ok%2Fpost%2F82f82e9f-2fc9-4731-bbc3-22e78ac761b2%2Fimage.png)![](https://velog.velcdn.com/images%2F200ok%2Fpost%2Ff7d4a0c5-225e-49c5-a871-9abf36bd272b%2Fimage.png)호스트에서 컨테이너에서 동작하는 sleep 종료
- 터미널1 (Ubuntu Container)

sleep 프로세스가 사라진 것을 알 수 있다. 즉, 호스트에서 컨테이너 프로세스를 컨트롤 할 수 있다.

참고

profile
우당탕탕 좌충우돌 인프라 여행기

0개의 댓글