devocean 오픈랩 Deep Dive Kubernetes 1주차 기록입니다.
오프라인 미팅
5/7(화) 오후 7시 을지로 삼화타워에서 Deep Dive Kubernetes 팀의 오프라인 미팅을 진행했습니다. 스터디 운영자님이신 안승규님 께서 컨테이너와 쿠버네티스에 대한 설명을 진행 해 주셨는데요, 초반 컨테이너에 대한 이론 설명과 간단한 실습 자료를 보여주셨는데 시간관계상 실습을 진행하지 못했어서, 직접 실습 해보며 내용을 정리해보고자 합니다.
Container
Container의 구조
Host O/S 기반에 Container Engine이 컨테이너의 구동을 관리합니다. 컨테이너 엔진은 CPU, RAM, Disk자원을 컨테이너에 할당 시켜주고, 각 컨테이너를 격리하여 프로세스를 구동시킵니다. 컨테이너 엔진은 Host OS 위에서 동작하기 때문에, 컨테이너의 커널 사양에 따라 구동시키지 못하는 경우가 발생할 수 있습니다.
자원의 분배와 격리는 각 각 cgroup, namespace를 사용하여 구현합니다. 프로세스 단위로 격리시켜 컨테이너를 구동하기 때문에 컨테이너는 자신에 할당된 자원만큼만 사용할 수 있습니다. namespace에서 격리되는 자원의 정보는 다음과 같습니다.
- 호스트 네임 : `uts`
- 프로세스 ID : `pid`
- 유저 : `user`
- 네트워크 : `net`
- 스토리지 : `mnt`
- 프로세스간 통신 : `ipc`
실습 1. Container에 대한 기본개념 확인
아래는 init process인 pid 1번에 대한 네임스페이스 정보를 확인하는 명령어 입니다. init process도 네임스페이스를 가지고 있음을 확인해볼 수 있습니다. `echo $$`라는 명령을 실행시켜 `echo` 프로세스의 pid를 조회하고, 해당 pid의 네임스페이스를 확인해보면 init process와 동일한 네임스페이스를 사용중인 것을 확인해볼 수 있습니다.
# pid 1번에 대한 네임스페이스 조회
root@ip-172-31-37-95:~# lsns -p 1
NS TYPE NPROCS PID USER COMMAND
4026531834 time 105 1 root /sbin/init
4026531835 cgroup 105 1 root /sbin/init
4026531836 pid 105 1 root /sbin/init
4026531837 user 105 1 root /sbin/init
4026531838 uts 99 1 root /sbin/init
4026531839 ipc 105 1 root /sbin/init
4026531840 net 105 1 root /sbin/init
4026531841 mnt 96 1 root /sbin/init
# echo 명령어의 현재 pid 조회
root@ip-172-31-37-95:/proc# echo $$
1220
# echo 명령어 1220의 네임스페이스 조회
root@ip-172-31-37-95:/proc# lsns -p 1220
NS TYPE NPROCS PID USER COMMAND
4026531834 time 108 1 root /sbin/init
4026531835 cgroup 108 1 root /sbin/init
4026531836 pid 108 1 root /sbin/init
4026531837 user 108 1 root /sbin/init
4026531838 uts 102 1 root /sbin/init
4026531839 ipc 108 1 root /sbin/init
4026531840 net 108 1 root /sbin/init
4026531841 mnt 97 1 root /sbin/init
이번 실습으로 각 프로세스는 pid, user, uts 등 네임스페이스 단위로 자원을 할당받는 다는 점과, init process는 `/` 프로세스가 되어 OS단에서 실행되는 프로세스는 모두 init process와 동일한 네임스페이스를 사용한다는 점을 알 수 있었습니다.
실습 2. namespace 생성 - uts
아래는`unshare -u`라는 명령어로 namespace 중 uts를 격리하여 새로운 Child Process를 생성하는 실습입니다.
# pid 1220번 ps를 실행합니다.
root@ip-172-31-37-95:/proc# echo $$
1220
# unshare -u 명령으로 Child Bash Process를 생성합니다.
root@ip-172-31-37-95:/proc# unshare -u
# Child Bash에서 echo $$ 명령으로 ps를 생성합니다.
# 기존 1220 ps가 아닌 1304 ps가 생성됩니다.
root@ip-172-31-37-95:/proc# echo $$
1304
# lsns로 process의 네임스페이스를 비교합니다.
# Child Process인 1304번의 uts 네임스페이스만 달라진 걸 확인해볼 수 있습니다.
root@ip-172-31-37-95:/proc# lsns -p 1304
NS TYPE NPROCS PID USER COMMAND
4026531834 time 107 1 root /sbin/init
4026531835 cgroup 107 1 root /sbin/init
4026531836 pid 107 1 root /sbin/init
4026531837 user 107 1 root /sbin/init
4026531839 ipc 107 1 root /sbin/init
4026531840 net 107 1 root /sbin/init
4026531841 mnt 98 1 root /sbin/init
4026532247 uts 2 1304 root -bash
root@ip-172-31-37-95:/proc# lsns -p 1220
NS TYPE NPROCS PID USER COMMAND
4026531834 time 107 1 root /sbin/init
4026531835 cgroup 107 1 root /sbin/init
4026531836 pid 107 1 root /sbin/init
4026531837 user 107 1 root /sbin/init
4026531838 uts 99 1 root /sbin/init
4026531839 ipc 107 1 root /sbin/init
4026531840 net 107 1 root /sbin/init
4026531841 mnt 98 1 root /sbin/init
위 실습으로 unshare는 네임스페이스 중 특정 자원을 격리시켜 Child Process를 생성할 수 있음을 확인 해 봤습니다.
실습 3. namespace 생성 - pid, mnt
아래는 pid, filesystem, mount 네임스페이스를 분리 생성하는 예시입니다. /root/sample_rootfs 라는 폴더를 생성하고, 해당 폴더에 `/bin`, `/lib`등 프로세스가 구동되기 위한 최소한의 파일시스템을 준비 합니다. 그리고 `unshare` 명령으로 mount를 격리시키고, 동시에 `chroot` 명령으로 격리된 프로세스의 파일시스템, 마운트 위치를 /root/sample_rootfs로 설정합니다. 그 후 proc을 /proc에 마운트 시켜 프로세스의 정보를 확인 해 봅니다.
먼저 /root/sample_rootfs를 생성하고 주요 directory를 복사합니다.
# root 로그인 상태에서 Home 디렉토리 이동 후 sample_rootfs 디렉토리를 생성합니다.
root@ip-172-31-37-95:~# cd
root@ip-172-31-37-95:~# mkdir sample_rootfs
# /bin, /lib, /var 등 주요 파일을 sample_rootfs에 복사합니다.
root@ip-172-31-37-95:~# cp -R /bin /root/sample_rootfs/
root@ip-172-31-37-95:~# cp -R /sbin /root/sample_rootfs/
root@ip-172-31-37-95:~# cp -R /lib /root/sample_rootfs/
root@ip-172-31-37-95:~# cp -R /lib64 /root/sample_rootfs/
root@ip-172-31-37-95:~# cp -R /etc /root/sample_rootfs/
root@ip-172-31-37-95:~# cp -R /usr /root/sample_rootfs/
root@ip-172-31-37-95:~# cp -R /var /root/sample_rootfs/
아래 명령으로 Process, Filesystem, Mount를 격리한 Child Process를 생성하고, Chroot로 격리된 파일시스템에 진입합니다. 그 후 프로세스 정보를 확인 합니다.
root@ip-172-31-37-95:~# unshare -p -f -m chroot /root/sample_rootfs
# pwd, ls 명령을 통해 chroot로 파일시스템, 마운트 격리가 잘 됐는지 확인합니다.
root@ip-172-31-37-95:/# pwd
/
root@ip-172-31-37-95:/# ls
bin etc lib lib64 sbin usr var
# process 정보를 마운트 하기 위해 proc 폴더를 생성하고, proc 정보를 마운트 시킵니다.
root@ip-172-31-37-95:/# mkdir proc
root@ip-172-31-37-95:/# mount -t proc proc /proc
# lsns -1로 각 자원의 네임스페이스를 확인합니다.
root@ip-172-31-37-95:/# lsns -p 1
NS TYPE NPROCS PID USER COMMAND
4026531834 time 2 1 root /bin/bash -i
4026531835 cgroup 2 1 root /bin/bash -i
4026531837 user 2 1 root /bin/bash -i
4026531839 ipc 2 1 root /bin/bash -i
4026531840 net 2 1 root /bin/bash -i
4026532247 uts 2 1 root /bin/bash -i
4026532249 mnt 2 1 root /bin/bash -i
4026532250 pid 2 1 root /bin/bash -i
# ps -ef로 현재 구동중인 process 정보를 확인합니다.
root@ip-172-31-37-95:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 11:33 ? 00:00:00 /bin/bash -i
root 66 1 0 11:39 ? 00:00:00 ps -ef
# exit로 chroot를 빠져나온 뒤, Host OS의 process 정보를 확인 해봅니다.
root@ip-172-31-37-95:/proc# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 09:38 ? 00:00:04 /sbin/init
root 2 0 0 09:38 ? 00:00:00 [kthreadd]
root 3 2 0 09:38 ? 00:00:00 [pool_workqueue_release]
root 4 2 0 09:38 ? 00:00:00 [kworker/R-rcu_g]
...
이번 실습으로 unshare를 통한 프로세스의 네임스페이스 분리 방법과 process, filesystem 격리 시 구동중인 Host OS의 Process Namespace가 달라지게 되어 `ps -ef`명령을 했을 때 보여지는 정보가 상이했던 것을 확인할 수 있었고, 이를 통해 각 자원별 네임스페이스 분리는 결국 각 각의 프로세스의 격리를 의미한다는 것을 확인해 볼 수 있었습니다.
정리
'운영체제' 카테고리의 다른 글
[Nginx] 사설 인증서로 Proxy 구성하기 (0) | 2024.04.17 |
---|---|
[RHEL 8] Apache + JBoss 조합으로 WAS 구성하기 -2 (0) | 2023.07.12 |
[RHEL 8] Apache + JBoss 조합으로 WAS 구성하기 -1 (0) | 2023.07.12 |
[RHEL 8]LVM 설정 (0) | 2023.07.12 |
[LDAP]LDAP과 GitLab 연동해서 로그인 해보기 (0) | 2023.03.08 |