CloudNet@ 팀의 가시다님이 진행하는 Kubernetes Advanced Networking Study 1주차 정리입니다.
[ 도커 컨테이너 격리 ] - 요약
- 컨테이너는 독립된 리눅스 환경(pivot-root, namespace, Overlay filesystem, cgroup)을 보장받는 프로세스
- 컨테이너는 애플리케이션(프로세스) 동작에 필요한 파일들만 패키징된 이미지를 실행하여 동작
- 컨테이너는 컨테이너 환경이 조성된 곳 어디에서나(온프레미스/클라우드 환경)에서도 실행 가능
[ 실습 환경 구성 ] - VPC 1개(퍼블릭 서브넷 2개), EC2 인스턴스 1대 (Ubuntu 22.04 LTS, t3.small)
[ 1. 도커 소개 ] - 영상 4개 보기
[ 1. 0 도커란 ? ]
: 도커(Docker)는 가상실행 환경을 제공해주는 오픈소스 플랫폼입니다. 도커에서는 이 가상실행 환경을 '컨테이너(Container)' 라고 부릅니다.
- 좀 더 정확히 표현하는 용어는 '컨테이너화된 프로세스(Containerized Process)'이다
- 도커 플랫폼이 설치된 곳이라면 컨테이너로 묶인 애플리케이션을 어디서든 실행할 수 있는 장점을 가진다.
* 프로세스란?
: 프로그램을 실행하면 메모리(RAM)와 같은 주기억장치로 옮겨오면서 CPU의 자원을 할당받아 실행 중인 프로그램을 "프로세스"라고 하며 프로세스에는 PID가 할당되어 관리
: (정의) 실행중인 프로그램, PCB(Process Control Block)를 지닌 프로그램, 프로그램 카운터를 가진 프로그램
1) fork 방식 - 프로세스 호출 시 새로 메모리를 할당받아 복사본 형태로 실행
2) exec 방식 - 완전히 새로운 프로세스로 대체하면서 호출
* 프로세스가 실행되는 위치
: fork와 exec 방식으로 실행된 프로세스들이 실행되는 위치에는 "포어그라운드(foreground)"와 백그라운드(background)" 두가지가 있다
: 포어그라운드 - 프로세스가 실행하는 도중에는 다른 작업을 할 수 없어 프로세스가 종료될 때까지 기다려야 합니다.
: 백그라운드 : 프로세스느 눈에 보이지 않게 뒤에서 실행되는 프로세스이며, 실행 도중 다른 작업을 진행할 수 있어 멀티태스킹 작업 가능
[ 1.2 도커 아키텍처 ]
[ 2. 도커 기본 사용 ]
[ Sam.0 ] 도커 없이 컨테이너 만들기 Update 버전
- Netfilter and iptables, A Deep Dive into iptables and Netfilter Architecture
- Understanding how uid and gid work in Docker containers
- The Curious Case of Pid Namespaces
[ 2.1 사전 준비 사항 ]
보안을 위해서 root 계정 사용을 최소화
- 프로세스는 실행 중인 프로그램의 인스턴스를 의미. OS에서 프로세스를 관리하며, 각 프로세스는 고유한 ID(PID)를 가짐
- 프로세스는 CPU와 메모리를 사용하는 기본 단위로, OS커널 (Cgroup)에서 각 프로세스의 자원을 관리
- pstree 명령어?
: 프로세스와 프로세스 간에 관계를 파악하기 위한 명령어
: 현재 실행중인 프로세스를 트리구조의 형태로 보여주어 관리자가 프로세스를 직관적으로 쉽게 확인
옵션 | 의미 |
-a | 실행한 프로세스의 인자와 옵션까지 모두 표시 |
-c | 1개의 프로세스의 중복된 개수로 출력 |
-h | 부모 프로세스를 강조해서 출력 |
-n | 출력시 PID 순서대로 정렬해서 출력 |
-p | PID를 출력 |
-p [userid] | 입력한 사용자가 소유자인 프로세스를 출력 |
-u | UID를 출력 |
-V | 버전정보를 출력 |
- 리눅스의 /proc 디렉터리는 커널이 동적으로 생성하는 정보를 실시간 제공 : 시스템 상태, 프로세스 (/proc/[PID]), HW정보
- /proc/cpuinfo : CPU에 대한 정보가 포함. CPU 모델, 코어 수, 클럭 속도 등의 정보 확인
- /proc/meminfo : 메모리 사용 현황. 전체 메몰, 사용 중인 메모리, 가용 메모리, 캐시 메모리 등 다양한 메모리 관련 정보 제공
- /proc/uptime : 시스템이 부팅된 후 경과된 시간을 초 단위로 확인 가능. 첫 번째 숫자는 총 가동 시간, 두 번째 숫자는 시스템의 유휴 시간
- /proc/loadavg : 시스템의 현재 부하 상태. 첫 번째 세 개의 숫자는 1, 5, 15 분간의 시스템 부하 평균을 의미하며, 네 번째 숫자는 현재 실행 중인 프로세스와 총 프로세스 수, 마지막 숫자는 마지막으로 실행된 프로세스의 PID를 나타낸다
- /proc/version : 커널 버전, GCC 버전 및 컴파일된 날짜와 같은 커널의 빌드 정보 포함
- /proc/filesystems : 커널이 인식하고 있는 파일 시스템의 목록
- /proc/partitions : 시스템에서 인식된 파티션 정보를 제공. 디스크 장치와 해당 파티션 크기 등을 확인 - 프로세스(/proc/[PID]) 별 정보
- /proc/[PID]/cmdline : 해당 프로세스를 실행할 때 사용된 명령어와 인자 포함
- /proc/[PID]/cwd : 프로세스의 현재 작업 디렉터리에 대한 심볼릭 링크. ls -l로 확인하면 해당 프로세스가 현재 작업 중인 티렉터리를 알 수 있다
- /proc/[PID]/environ : 프로세스의 환경 변수. 각 변수는 NULL 문자로 구분
- /proc/[PID]/exe : 프로세스가 실행 중인 실행 파일에 대한 심볼릭 링크
- /proc/[PID]/fd : 프로세스가 열어놓은 모든 파일 디스크립터에 대한 심볼릭 링크를 포함하는 디렉터리.
이 파일들은 해당 파일 디스크립터가 가리키는 실제 파일이나 소켓 등을 참조
- /proc/[PID]/maps : 프로세스의 메모리 맵. 메모리 영역의 시작과 끝 주소, 접근 권한, 매핑된 파일 등을 확인할 수 있다.
- /proc/[PID]/stat : 프로세스의 상태 정보를 포함한 파일.
프로세스의 상태, CPU 사용량, 메모리 사용량, 부모 프로세스 ID, 우선순위 등의 다양한 정보 확인 가능
- /proc/[PID]/status : 프로세스의 상태 정보를 사람이 읽기 쉽게 정리한 파일.
PID, PPID(부모 PID), 메모리 사용량, CPU 사용률, 스레드 수 등 확인 가능
커널이 동적으로 생성하는 정보 | 실시간(갱신) 정보 |
cat /proc/cpuinfo cat /proc/meminfo cat /proc/uptime cat /proc/loadavg cat /proc/version cat /proc/filesystems cat /proc/partitions |
cat /proc/uptime |
[ 2.2 도커 설치 및 확인 ]
- 도커 설치
- Manage Docker as a non-root user & Socket
[ Warning ] The docker group grants root-level privileges to the user.
For details on how this impacts security in your system, see Docker Daemon Attack Surface.
- The Docker daemon binds to a Unix socket, not a TCP port. By default it's the root user that owns the Unix socket, and other users can only access it using sudo.
- The Docker daemon always runs as the root user
- 소켓은 OS커널에 구현되어 있는 프로토콜 요소에 대한 추상화된 인터페이스, 장치 파일의 일종
▶ Unix Domain Socket : USD 사용 - mysql 로컬 접속 시, Istio proxy와 Envoy 프로세스 (XDS, SDS)간 로컬 통신 시
- Unix Domain은 동일한 시스템 내에서 실행되는 프로세스들 간의 통신을 의미하며, "Domain"은 로컬 시스템 내의 통신 영역을 나타낸다.
- 이 용어는 1980년대 BSD Unix에서 로컬 IPC 메커니즘을 구현하기 위해 처음 도입되었다.
- "Unix Domain Socket"이라는 이름은 네트워크 소켓과 유사한 API를 사용하면서도, 로컬 시스템 내에서만 동작하는 소켓이라는 의미이다.
- TCP socket과 차이점 : local host의 process 간의 통신이므로 속도가 매우 빠르고 메모리 소모가 적다
또한, sockaddr_un 이라는 구조체를 사용하는 것 외에는 일반적인 소켓을 다루는 것과 동일하므로 UDS로 구성해 놓은 후에 성능이나 보안상의 문제로 서버를 클라이언트와 분리하기가 매우 용이
▶ [심화] 컨테이너가 host의 docker socket file 공유로 도커 실행
- Jenkins 컨테이너 : 도커 빌드 과정에서 활용
▶ 도커 설치 후 기본 정보 확인
[ 3. 컨테이너 격리 ]
리눅스 프로세스 격리 기술 발전
▶ 도커 없이 컨테이너 만들기 1 : Chroot + 탈옥
- chroot root directory : user 디렉터리를 user 프로세스에게 root 디렉터리를 속임
: 경로를 모으고(패키징), 경로에 가둬서 실행(격리)
- chroot에서 ps 실행해보기
- 남이 만든 이미지 chroot 해보기 : 컨테이너 이미지는 실행되는 프로세스의 동작에 필요한 모든 관련 파일을 묶어서 패키징
- 탈옥 코드 : vi escape_chroot.c
▶ 도커 없이 컨테이너 만들기 2 : 마운트 네임스페이스 + Pivot_root
- chroot 차단을 위해서, pivot_root + mount ns (호스트 영향 격리)를 사용 : 루트 파일 시스템을 변경 (부착 mount) + 프로세스 환경 격리
- 마운트 네임스페이스 : 마운트 포인트를 격리(unshare)
- 마운트 네임스페이스
[ 주요 명령어 ]
1. pivot_root
: 컨테이너가 독립된 root 파일 시스템에서 작동할 수 있도록 특정 디렉터리를 새로운 root 디렉터리로 설정하는 명령
: 루트파일시스템의 마운트 포인트를 변경함으로써 특정 디렉터리를 새로운 루트 디렉터리로 만드는 명령
: (chroot 차이점) chroot로 만든 격리공간은 루트파일시스템이 동일했기 때문에 탈옥이 가능했던 한편, pivot_root를 이용하면 루트 파일시스템의 마운트 포인트 자체가 변경되므로 탈옥 불가능
2. mount
3. unshare
- pivot_root
: pivot_root와 마운트 네임스페이스를 사용하여 루트를 완전히 변경
* 왜 컨테이너가 pivot_root를 사용하는가??
: pivot_root는 컨테이너가 호스트 시스템과 완벽하게 격리된 환경에서 동작할 수 있도록 하는 핵심적인 기술
1. 완벽한 파일 시스템 격리
- 독립적인 루트 파일 시스템 : pivot_root를 통해 컨테이너는 호스트 시스템의 루트 파일 시스템과는 별개의 독립적인 루트 파일 시스템을 갖게 됩니다. 이는 컨테이너 내에서 발생하는 모든 파일 시스템 변경 사항이 호스트 시스템에 영향을 미치지 않도록 보장합니다.
- 보안 강화 : 컨테이너가 호스트 시스템의 중요한 파일이나 디렉토리에 무단으로 접근하는 것을 방지하여 시스템의 보안을 강화합니다.
2. 탈옥 방지
- 컨테이너 내부 제한 : pivot_root를 통해 컨테이너는 자신이 할당받은 파일 시스템 내에서만 동작하도록 제한됩니다. 이는 컨테이너가 호스트 시스템으로 탈출하여 임의의 명령을 실행하는 것을 방지합니다.
- 안전한 컨테이너 운영 : 컨테이너 간의 간섭을 최소화하고, 예기치 않은 문제 발생을 방지하여 안전한 컨테이너 환경을 구축합니다.
3. 컨테이너 이미지의 일관성 유지
- 고립된 환경 : pivot_root를 통해 컨테이너는 이미지에 정의된 파일 시스템 환경을 그대로 유지할 수 있습니다. 이는 컨테이너 이미지를 다른 시스템으로 이동하더라도 동일한 동작을 보장합니다.
- 재현 가능한 환경 : 컨테이너 이미지를 기반으로 동일한 환경을 여러 개 생성할 수 있어 개발 및 배포 과정에서 일관성을 유지할 수 있습니다.
4. 컨테이너 가상화의 핵심 기술
- 파일 시스템 가상화 : pivot_root는 파일 시스템을 가상화하는 핵심 기술 중 하나입니다. 컨테이너가 마치 독립적인 시스템처럼 동작할 수 있도록 지원합니다.
- 다양한 컨테이너 기술의 기반 : Docker, Kubernetes 등 다양한 컨테이너 기술에서 pivot_root를 기반으로 컨테이너를 구현하고 있습니다.
▶ 도커 없이 컨테이너 만들기 3 : 격리 Namespace
네임스페이스 | - 프로세스에 격리된 환경 제공 - 리눅스 커널 기능 - 컨테이너 레디 |
네임스페이스 특징 | - 모든 프로세스는 타입별로 네임스페이스에 속함 - 자식 프로세스는 부모의 네임스페이스를 상속함 |
네임스페이스 사용 방법 | (사용법) unshare [옵션] [프로그램 [arguments ...]] (옵션) -m, --mount -u, --uts -i, --ipc -p, --pid -n, --net -U, --user |
- 네임스페이스와 관련된 프로세스의 특징
1. 모든 프로세스들은 네임스페이스 타입별로 특정 네임스페이스에 속합니다.
2. Child는 Parent의 네임스페이스를 상속받습니다
3. 프로세스는 네임스페이스 타입별로 일부는 호스트(root) 네임스페이스를 사용하고 일부는 컨테이너의 네임스페이스를 사용할 수 있습니다.
: mount 네임스페이스는 컨테이너의 것으로 격리하고, network 네임스페이스는 호스트 것을 사용 - Mount(파일시스템), Network(네트워크), PID(프로세스 id), User(계정), ipc(프로세스간 통신), Uts (Unix time sharing, 호스트 네임), cgroup
1. 마운트 네임스페이스 MOUNT (mnt) Namespace : 2002년, 마운트 포인트 격리, 최초의 네임스페이스
2. UTS 네임스페이스 Namespace : 2006년, Unix Time Sharing ( 여러 사용자가 작업 환경 제공하고자 서버 시분할 나눠쓰기), 호스트명, 도메인명 격리
3. IPC 네임스페이스 : 2006년, Inter-Process Communication 격리, 프로세스 간 통신 자원 분리 관리 - Shared Memory, Pipe, Message Queue 등
[ 추가 실습 ] 2개의 컨테이너 간 IPC 네임스페이스 공유
4. PID 네임스페이스 : 2008년, Process ID 격리
- 부모 - 자식 네임스페이스 중첩 구조, 부모 네임스페이스에서는 자식 네임스페이스를 볼 수 있음
- 자식 네임스페이스는 parent tree의 id와 subtree의 id 두개를 가짐
- unshare 할 때 fork 하여, 자식 PID 네임스페이스의 pid 1로 실행
- pid 1(init)이 종료되면 pid namespace도 종료
- 호스트에서 컨테이너 프로세스 종료 해보기
5. USER 네임스페이스 : 2012년, UID/GID 넘버스페이스 격리(Remap), 컨테이너의 루트권한 문제를 해결, 부모-자식 네임스페이스의 중첩 구조
- 네임스페이스 안과 밖의 UID/GID를 다르게 설정할 수 있음
- 컨테이너를 탈취 후, 해당 프로세스를 기반으로 호스트에 Action이 가능할 경우, root 계정 권한 실행이 가능 (보안 취약)
- 도커의 root 사용
: 패키지 인스톨이 쉽다, 시스템 리소스 이용에 제약이 없다 - USER 네임스페이스 격리
$ unshare -U --map-root-user /bin/sh - USER 네임스페이스
: 컨테이너 안에서만 root
: USER 네임스페이스 간 UID/GID Remap - 도커의 USER 네임스페이스 지원
: 도커 v1.10+
: 호스트 UID/GID Remap
: 보안관점에서 큰 진보
: But, 기본 설정은 USER 네임스페이스를 쓰지 않음
'스터디 > Kubernetes' 카테고리의 다른 글
[Kubernetes Advanced Networking Study] Calico CNI & Mode_2 (0) | 2024.09.12 |
---|---|
[Kubernetes Advanced Networking Study] Calico CNI & Mode_1 (0) | 2024.09.10 |
[Kubernetes Advanced Networking Study] K8S Flannel CNI & PAUSE_2 (0) | 2024.09.03 |
[Kubernetes Advanced Networking Study] K8S Flannel CNI & PAUSE (0) | 2024.09.01 |
[Kubernetes Advanced Networking Study] 컨테이너 격리 & 네트워크 및 보안_2 (1) | 2024.08.29 |