티스토리 뷰

공부/Infra

컨테이너 기반 기술

JStack 2025. 8. 7. 10:31

컨테이너

컨테이너란 물리적인 하드웨어 위의 Host OS 상에 논리적인 구획을 만들고,

애플리케이션 작동을 위한 라이브러리나 파일을 모아,

별도의 서버처럼 사용할 수 있게 만든 것이다.

https://www.docker.com/resources/what-container/

 

컨테이너는 리눅스 커널에서 제공해주는 여러 기능들을 활용해서 구현되었고, 이 기능들에 대해서 알아보자.

 

chroot

chroot를 활용하여 bash shell을 사용하게되면 격리된 파일 시스템 환경을 제공한다.

https://www.geeksforgeeks.org/linux-unix/chroot-command-in-linux-with-examples/

 

chroot를 활용해서 별도 디렉토리를 생성하고, 격리하여 bash를 실행할 것이다.

이를 위해 해당 디렉토리 하위에 bash에 필요한 기본 라이브러리를 옮길 것이다.

 

mkdir -p /root/newroot/lib: 별도 디렉토리 생성

cp /bin/bash /root/newroot/bin/bash, cp /bin/ls /root/newroot/bin/ls: 기본 명령어 파일 copy

위 명령어들을 먼저 실행해서 새로운 디렉토리를 만들고, 이 디렉토리에 bash, ls 명령어에 필요한 파일을 옮겨준다.
 

동적 라이브러리 파일

ldd /bin/bash, ldd /bin/ls 명령어를 실행해 bash, ls 명령어의 동적 라이브러리를 찾는다.

 

 
동적 라이브러리 이동
cp [library_path] /root/newroot/[library_path] 명령어를 실행하여 동적 라이브러리도 옮겨준다.
위의 그림과 같이 동적 라이브러리들이 옮겨진 것을 확인할 수 있다.
 
chroot

chroot /root/newroot /bin/bash 명령어를 실행하면 /newroot 디렉토리를 기준으로 bash를 실행할 수 있다.

이 경우 /newroot 디렉토리를 가상의 root 디렉토리처럼 격리된 환경에서 bash를 실행한다.

 

namespace

네임스페이스란 리눅스 기반의 프로세스 가상화 기술이다.

https://8gwifi.org/docs/linux-namespace.jsp

네임스페이스의 종류는 위와 같이 여러가지가 있고, 각 종류별로 프로세스 격리 기능을 제공한다.

예를 들어 UTS namespace의 경우에는 네임스페이스별로 hostname을 다르게 설정할 수 있고, 각 네임스페이스에 포함된 프로세스가 서로 다른 hostname을 가질 수 있다.

 

우선, 리눅스에서 프로세스는 계층형 구조를 가지고 있으며, 1번 PID로부터 모든 프로세스가 생성된다.

pstree

pstree 명령어를 실행해보면 위와 같은 구조를 확인할 수 있다.

그렇다면 이 구조에서 새로운 네임스페이스를 만들고, 아래 명령어를 활용해 네임스페이스에 프로세스를 할당해볼 것이다.

  • clone(): 새로운 프로세스를 생성하고, 새로 지정된 네임스페이스에 연결
  • unshare(): 현재 프로세스를 새로 지정된 네임스페이스에 연결
  • setns(): 이미 존재하는 네임스페이스에 프로세스를 연결

 

unshare --fork --pid --mount-proc=/proc /bin/sh 명령어를 수행하여, 격리된 네임스페이스의 프로세스를 확인할 수 있다.

 

두 개의 터미널을 띄워서 UTS namespace를 별도로 나누어서 서로 다른 hostname을 설정한다.

uts number를 조회하더라도 다른 uts number가 조회된다.

 

https://blog.famzah.net/tag/veth/

Linux에서 네임스페이스를 분리하더라도 Networt Interface는 Default namespace에만 존재한다.

따라서 분리된 네임스페이스에서 가상의 peer를 만들고, 이를 기본 네임스페이스의 가상 이더넷에 마운트하는 과정이 필요하다.

 

  • ip netns add guestnet: guestnet이라는 새로운 네트워크 네임스페이스 생성
  • ip netns exec guestnet ip link: guestnet의 LOOPBACK 활성화 (localhost interface)
  • ip netns exec guestnet ip link set lo up: guestnet의 LOWER_UP 설정
  • ip netns exec guestnet ip link: guestnet의 LOWER_UP 활성화 (physical layer active)

 

  • ip link add host type veth peer name guest: veth인 host와 vpeer인 guest 연결
  • ip link: 연결 활성화 (if3: guest@host, if4: host@guest)
  • ip link set guest netns guestnet: vpeer guest를 guestnet에 할당
  • ip link: 할당 활성화 (if4: host@if3)
  • ip netns exec guestnet ip link: guest@if4 인터페이스의 활성화

 

  • ip link set host up: veth host에 ip 할당
  • ip address add 2.2.2.1/24 dev host: ip 설정
  • ip address show dev host: 할당된 ip 조회

 

  • ip netns exec guestnet ip link set guest up: vpeer guest에 ip 할당
  • ip netns exec guestnet ip address add 2.2.2.2/24 dev guest: ip 설정
  • ip netns exec guestnet ip address show dev guest: 할당된 ip 조회

 

  • ping 2.2.2.2: guest ip에 ping 실행
  • ip netns exec guestnet ping 2.2.2.1: host ip에 ping 실행

 

cgroups

cgroups는 리눅스 기반의 프로세스별 자원 할당 및 제어를 위한 기능이다.

https://zesty.co/finops-glossary/cgroups-in-kubernetes/

 

테스트를 위해 vi를 활용하여 a.c 파일을 생성한다. 내부 로직은 무한루프이다.

 

해당 파일을 컴파일하고 기계어 파일을 두 개로 복사한다.

 

컴파일된 두 개의 파일을 실행한다.

 

top 명령어를 통해 두 개의 프로세스의 자원 할당량을 조회해볼 수 있다.

둘 다 같은 크기의 CPU를 할당받는다.

 

/sys/fs/cgroup/cpu 경로에 limit_50_percent 디렉토리를 생성한다.

해당 디렉토리로 접속해보면 생성하지 않은 파일들이 생성되어있다.

cgroup은 가상 파일 시스템 구조로 부모 속성을 상속받으므로 자동으로 일부 속성이 생성되기 때문이다.

 

cpu.shares 파일을 조회해보면 1024가 조회된다. 이것은 기본값이며 100%를 의미한다.

 

  • echo $(pgrep a.out) > /sys/fs/cgroup/cpu/limit_50_percent/tasks: a.out 프로세스를 limit_50_percent cgroup에 포함
  • echo 512 > /sys/fs/cgroup/cpu/limit_50_percent/cpu.shares: 해당 cgroup의 cpu 상대값을 50%로 설정

 

따라서 위와 같이 a.out 프로세스는 33%, b.out 프로세스는 66%의 CPU를 할당받게 된다.

 

UnionFS

컨테이너 환경에서 수정이 발생하는 경우 image는 수정되지 않고, 컨테이너 내부가 수정된다.

image는 read-only다. 이를 위해 컨테이너를 Layered로 구성하고, 리눅스 커널의 UnionFS 기능을 활용한다.

 

  • mkdir overlayfs ; cd overlayfs: overlayfs 디렉토리 생성
  • mkdir container image1 image2 work merge: 하위 디렉토리 생성
  • touch image1/{a,b} image2/c: image 디렉토리 하위 파일 생성
  • mount -t overlay overlay -o lowerdir=image2:image1,upperdir=container,workdir=work merge: merge 기준 하위 디렉토리 및 상위 디렉토리 설정
  • df: overlayfs 디렉토리에 마운트된 디렉토리 확인

 

tree 명령어로 구성된 디렉토리를 확인해본다.

 

merge 디렉토리에 파일을 삭제하고 생성하더라도 image 디렉토리는 변경이 없다.

이처럼 컨테이너 내부에 Image Layer와 Merge Layer를 구분해서 구성하여 관리할 수 있다.

'공부 > Infra' 카테고리의 다른 글

Docker 기본 동작 원리  (6) 2024.09.19
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함