Linux htop/top 화면에 보이는 값들 해설 (2019)

4 hours ago 3
  • Ubuntu Server 16.04 x64의 htop 화면을 출발점으로 uptime, load average, Tasks, PID, 프로세스 트리, 상태, CPU 시간, 우선순위, 메모리 지표가 실제로 무엇을 뜻하는지 /proc와 명령어 출력으로 추적함
  • 화면의 많은 값은 procfs와 /etc/passwd, /etc/group, /etc/shadow, /etc/nsswitch.conf 같은 시스템 파일에서 오며, strace로 프로그램이 어떤 파일을 읽는지 확인할 수 있음
  • Load average는 CPU 사용률과 같은 값이 아니며, 실행 중·실행 대기 중인 프로세스와 uninterruptible 상태 프로세스를 포함한 지수 감쇠 이동평균임
  • R, S, D, Z, T, t 같은 상태 코드는 signal, kill, fork/exec/wait 동작과 연결되어 있어 프로세스가 왜 멈추거나 남아 있는지 판단하는 단서가 됨
  • VIRT, RES, SHR, MEM%는 가상 메모리, 물리 메모리, 공유 가능 메모리를 서로 다른 관점에서 보여주므로 한 숫자만 보고 실제 메모리 사용량을 단정하기 어려움

htop 값은 어디서 오는가

  • uptime은 시스템이 얼마나 오래 실행됐는지 보여주며, 같은 정보는 uptime 명령으로도 확인할 수 있음
  • uptime 프로그램은 /proc/uptime을 읽음
    • 첫 번째 숫자는 시스템이 켜져 있던 전체 초 단위 시간
    • 두 번째 숫자는 시스템이 idle 상태였던 초 단위 시간
    • 멀티코어 시스템에서는 idle 시간이 코어별로 합산되어 전체 uptime보다 클 수 있음
  • strace uptime 2>&1 | grep open 또는 strace -e open uptime으로 uptime이 여는 파일을 볼 수 있음
    • 예시 출력에는 /proc/uptime, /var/run/utmp, /proc/loadavg가 포함됨
  • /proc/uptime의 숫자는 프로그램이나 스크립트에서 쓰기 좋고, uptime 출력은 사람이 읽기 좋게 포맷됨

Load average와 CPU 사용률

  • /proc/loadavg의 첫 세 값은 최근 1분, 5분, 15분의 시스템 load average를 나타냄
  • 네 번째 값은 현재 실행 중인 프로세스 수와 전체 프로세스 수를 1/120처럼 보여주고, 마지막 값은 마지막으로 사용된 PID임
  • 새 프로세스를 실행하면 PID가 할당되며, PID는 보통 증가하다가 고갈되면 재사용됨
    • PID 1은 부팅 시 시작되는 /sbin/init에 속함
  • htop에서 실행 중인 프로세스가 하나만 보이면 그 하나가 htop 자체일 수 있음
  • sleep 30은 실행 중이 아니라 sleep 상태라 running process 수를 늘리지 않음
  • cat /dev/urandom > /dev/null처럼 계속 CPU를 쓰는 작업은 running process 수와 load average를 올림
  • Load number는 실행 중이거나 실행 대기 중인 프로세스와 uninterruptible 상태 프로세스를 세는 값임
  • load average는 단순 평균이 아니라 지수 감쇠 이동평균
    • 1분 load average도 마지막 60초만 반영하지 않고, 최근 1분에 더 큰 비중을 두면서 이전 활동도 일부 포함함
  • 단일 CPU 시스템에서 CPU-bound 프로세스 하나가 있으면 load average 1.00은 CPU 100% 사용으로 단순화해 볼 수 있음
    • 2코어 시스템에서 같은 상황은 CPU 사용률 50%로 볼 수 있음
    • 2코어 시스템의 CPU 100% 사용에 해당하는 load average는 2.00으로 단순화할 수 있음
  • 이 단순화는 uninterruptible 상태 프로세스가 load에 포함되기 때문에 항상 맞지는 않음
    • 높은 load average인데 CPU 사용률은 높지 않은 상황도 가능함
  • 순간적인 CPU 사용률은 mpstat로 확인할 수 있음
    • sudo apt install sysstat -y
    • mpstat 1

Tasks, PID, 프로세스 트리

  • htop 오른쪽 위의 Tasks는 전체 프로세스 수와 실행 중인 프로세스 수를 보여줌
  • Linux 커널은 내부적으로 프로세스를 task라고 부르며, htop은 화면 공간을 줄이기 위해 Processes 대신 Tasks를 사용함
  • Shift+H로 thread 표시를 토글할 수 있음
    • Tasks: 23, 10 thr처럼 보이면 thread가 표시 중임
  • Shift+K로 kernel thread 표시를 토글할 수 있음
    • Tasks: 23, 40 kthr처럼 보이면 kernel thread가 표시 중임
  • 새 프로세스가 시작될 때마다 PID가 할당됨
    • sleep 1000 &처럼 백그라운드 실행하면 job 번호와 PID가 표시됨
    • bash의 $!는 마지막 백그라운드 프로세스 ID로 확장됨
  • 프로세스 관련 정보는 /proc/<pid>/ 아래에 있음
    • /proc/<pid>/cmdline은 실행 명령을 담고 있으며 인자는 \0 바이트로 구분됨
    • tr '\0' '\n' < /proc/<pid>/cmdline 또는 strings /proc/<pid>/cmdline로 읽기 쉽게 볼 수 있음
    • /proc/<pid>/cwd는 현재 작업 디렉터리 링크이고, /proc/<pid>/exe는 실행된 바이너리 링크임
  • htop, top, ps 같은 진단 도구는 프로세스 세부 정보를 /proc/<pid>/<file>에서 읽음
  • 새 프로세스를 만든 쪽은 parent process, 새로 만들어진 쪽은 child process이며 이 관계가 프로세스 트리를 이룸
  • htop에서 F5를 누르면 프로세스 계층을 볼 수 있음
    • ps f와 pstree -a도 같은 관계를 보여줌
  • bash에서 date를 실행하면 bash가 fork로 자기 복사본을 만들고, exec로 /bin/date를 메모리에 올린 뒤, parent인 bash가 child 종료를 기다림
  • /sbin/init은 부팅 때 시작되고 sshd를 띄우며, SSH 접속 시 sshd가 세션 프로세스를 만들고 그 세션이 bash shell을 실행함

프로세스 사용자와 권한

  • 각 프로세스는 사용자에게 소유되며, 사용자는 숫자 ID로 표현됨
  • /proc/<pid>/status의 Uid 항목으로 프로세스의 사용자 ID를 확인할 수 있음
  • id 1000 같은 명령은 숫자 ID에 해당하는 사용자 이름과 그룹을 보여줌
  • id는 /etc/nsswitch.conf 설정에 따라 이름 해석 소스를 선택함
    • 예시 시스템에서는 /etc/passwd와 /etc/group을 읽음
    • compat은 Compatibility mode이며, files와 같지만 특수 항목을 허용함
    • 사용자 정보는 LDAP 같은 다른 데이터베이스나 서비스에도 저장될 수 있음
  • /etc/passwd와 /etc/group은 숫자 ID를 사람이 읽을 수 있는 이름으로 매핑하는 평문 파일임
  • 실제 비밀번호 정보는 /etc/shadow에 있음
    • $6$은 sha512 해싱 알고리듬을 뜻함
    • 그 뒤에는 rainbow table 공격을 막기 위한 랜덤 salt와 password+salt의 hash가 이어짐
  • 프로그램은 기본적으로 실행한 사용자 권한으로 실행됨
    • 실행 파일 소유자가 다른 사용자여도 동일함
  • 다른 사용자나 root로 실행하려면 sudo를 사용함
    • sudo id는 root의 UID 0으로 실행됨
    • sudo -u daemon id처럼 특정 사용자로 실행할 수 있음
  • /etc/sudoers에 직접 redirect로 쓰려 하면 echo만 root로 실행되고 append는 현재 사용자로 수행되어 실패할 수 있음
    • echo "$USER ALL=(ALL) NOPASSWD: ALL" | sudo tee -a /etc/sudoers
    • sudo bash -c "echo '$USER ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers"
  • /etc/sudoers는 sudo visudo로 편집해야 함
    • 저장 전 내용을 검증해 sudo를 사용할 수 없는 상태가 되는 실수를 막음
  • /usr/bin/passwd는 일반 사용자가 실행해도 /etc/shadow에 쓸 수 있음
    • 파일 권한에 s가 있어 setuid 실행 파일로 동작함
    • 실행 파일 소유자인 root 권한으로 실행됨
    • root 소유 setuid 실행 파일은 find /bin -user root -perm -u+s로 찾을 수 있음

프로세스 상태 코드

  • htop의 상태 열은 S라는 이름으로 표시되며, 주요 값은 다음과 같음
    • R: running 또는 runnable, 실행 중이거나 run queue에서 대기 중
    • S: interruptible sleep, 이벤트 완료를 기다림
    • D: uninterruptible sleep, 보통 I/O 대기
    • Z: defunct zombie, 종료됐지만 parent가 reap하지 않음
    • T: job control signal로 정지
    • t: tracing 중 debugger에 의해 정지
    • X: dead, 보여서는 안 되는 상태
  • ps는 Ss, R+, Ss+ 같은 substate도 보여줌
  • R: 실행 중 또는 실행 가능

    • R 상태는 프로세스가 현재 실행 중이거나 실행 대기열에서 기다리는 상태임
    • 프로그램 소스 코드는 컴파일 후 CPU 명령어가 되고, 실행 시 메모리에 로드되어 CPU가 해당 명령을 실행함
    • 실행 중이라는 것은 CPU가 물리적으로 명령어를 실행한다는 뜻임
  • S: 인터럽트 가능한 sleep

    • S 상태에서는 프로세스의 명령어가 CPU에서 실행되지 않고, 이벤트나 조건을 기다림
    • 이벤트가 발생하면 커널이 상태를 running으로 바꿈
    • sleep 1000은 지정한 시간 동안 대기하는 예시임
    • 이 상태는 signal로 interrupt할 수 있음
    • htop에서는 F9를 눌러 signal을 보낼 수 있음
    • kill은 signal을 보내는 시스템 호출이며, /bin/kill은 userland에서 이를 호출하는 프로그램임
    • 기본 signal은 TERM이며 프로세스 종료를 요청함
    • signal은 숫자이며 이름은 보통 대문자로 쓰고 SIG prefix가 붙을 수 있음
    • 예: INT, KILL, STOP, CONT, HUP
    • kill -INT 10089, kill -2 10089, /bin/kill -2 10089는 같은 동작을 함
    • CTRL+C를 누르면 bash가 foreground process에 SIGINT를 보냄
    • SIGINT나 SIGTERM을 보낸다고 프로세스가 반드시 종료되지는 않음
    • 프로그램은 signal handler를 설정해 정리 작업 후 종료하는 식으로 처리할 수 있음
    • SIGKILL 또는 9는 커널이 프로세스에 응답 기회를 주지 않고 강제 종료하게 함
  • D: 인터럽트 불가능한 sleep

    • D 상태는 signal로 깨울 수 없으며, SIGKILL도 signal이기 때문에 이런 프로세스를 kill할 수 없음
    • 이 상태는 프로세스가 중단 없이 기다려야 하거나 이벤트가 빠르게 발생할 것으로 예상될 때 사용됨
    • 예: disk read/write
    • uninterruptible process는 보통 page fault 이후 I/O를 기다리는 상태일 수 있음
    • NFS 읽기·쓰기 지연에서 이런 상태가 생길 수 있음
    • 사용 가능한 메모리가 너무 적어 프로세스가 swap을 많이 하는 상황에서도 나타날 수 있음
    • 예시로 sudo mount 8.8.8.8:/tmp /tmp &를 실행하면 /sbin/mount.nfs가 D 상태가 됨
    • strace로 보면 mount 시스템 호출이 프로세스를 block함
    • mount에 intr 옵션을 주면 interruptible하게 실행할 수 있음
    • sudo mount 8.8.8.8:/tmp /tmp -o intr
  • Z: 좀비 프로세스

    • Z 상태는 프로세스가 종료됐지만 parent가 아직 reap하지 않은 상태임
    • 좀비 프로세스는 짧게 존재하면 정상적일 수 있음
    • 오래 남아 있는 좀비 프로세스는 프로그램 버그를 나타낼 수 있음
    • 좀비 프로세스는 메모리를 소비하지 않고 PID만 차지함
    • 좀비 프로세스 자체는 kill할 수 없음
    • parent process에 SIGCHLD를 보내 좀비를 reap하라고 요청할 수 있음
    • parent process를 kill하면 parent와 그 좀비를 제거할 수 있음
    • fork 후 child가 exit(0)하고 parent가 sleep(20)하는 C 프로그램으로 좀비 상태를 재현할 수 있음
    • parent가 끝나면 좀비는 사라짐
    • 좀비가 유지되는 이유는 parent가 wait 시스템 호출로 child의 exit code를 확인할 수 있어야 하기 때문임
  • T와 t: 정지된 프로세스

    • T 상태는 job control signal로 정지된 상태임
    • cat /dev/urandom > /dev/null 실행 중 CTRL+Z를 누르면 T 상태가 됨
    • fg로 다시 실행할 수 있음
    • STOP signal로 멈추고 CONT signal로 재개할 수도 있음
    • t 상태는 debugger가 tracing하는 동안 정지된 상태임
    • nc -l 1234 &로 실행한 프로세스에 sudo gdb -p <pid>로 attach하면 t 상태가 됨

CPU 시간, niceness, priority

  • Linux는 multitasking 운영체제라 단일 CPU에서도 여러 프로세스가 동시에 실행되는 것처럼 보임
  • 실제로 단일 CPU는 한 번에 하나의 명령만 실행할 수 있으므로 time sharing을 사용함
    • 한 프로세스가 잠깐 실행되고 중단됨
    • 실행 대기 중인 다른 프로세스가 차례로 실행됨
    • 한 프로세스가 실행되는 짧은 구간을 time slice라고 함
  • time slice는 보통 몇 밀리초라 시스템 load가 높지 않으면 잘 느껴지지 않음
  • 단일 코어에서 load average가 1.0이면 CPU가 100% 사용됐다고 볼 수 있음
    • 1.0보다 높으면 실행하려는 프로세스 수가 CPU가 처리할 수 있는 수보다 많아 slowdown이나 delay가 생길 수 있음
    • 1.0보다 낮으면 CPU가 때때로 idle 상태임
  • 프로세스 running time이 실제 경과 시간과 정확히 같지 않을 수 있는 이유도 time sharing으로 설명됨
  • 사용 가능한 CPU core 수보다 실행할 task가 많으면 어떤 task를 먼저 실행할지 정해야 함
  • Linux 커널의 scheduler는 run queue에서 다음 프로세스를 고르며, 커널의 scheduler 알고리듬에 의존함
  • 일반적으로 scheduler를 직접 제어할 수는 없지만, 어떤 프로세스가 더 중요한지 알려줄 수 있음
  • NI로 표시되는 niceness는 user-space priority임
    • 범위는 -20부터 19까지
    • -20이 가장 높은 우선순위이고 19가 가장 낮은 우선순위임
    • 더 nice한 프로세스는 덜 nice한 프로세스에 더 양보한다고 볼 수 있음
  • PRI는 Linux 커널이 사용하는 kernel-space priority임
    • 범위는 0부터 139
    • 0~99는 real time, 100~139는 user용 범위임
  • nice 값과 priority의 관계는 PR = 20 + NI로 설명됨
    • NI의 -20~+19가 PR의 0~39가 되고, 이는 100~139에 매핑됨
  • 실행 전 niceness는 nice -n niceness program으로 설정함
  • 실행 중인 프로세스 niceness는 renice -n niceness -p PID로 바꿈
  • CPU 사용률 색상은 다음과 같음
    • Blue: 낮은 우선순위 thread, nice > 0
    • Green: 일반 우선순위 thread
    • Red: kernel thread

메모리 지표: VIRT, RES, SHR, MEM%

  • 프로세스는 자신이 메모리에 단독으로 존재하는 것처럼 보이며, 이는 가상 메모리로 구현됨
  • 프로세스는 물리 메모리에 직접 접근하지 않고 자체 virtual address space를 가짐
  • 커널은 virtual memory address를 physical memory로 변환하거나 일부를 disk에 매핑할 수 있음
  • 이 때문에 프로세스가 컴퓨터에 설치된 메모리보다 더 많은 메모리를 쓰는 것처럼 보일 수 있음
  • 프로세스 메모리 사용량은 다음 항목을 포함하는지에 따라 달라짐
    • shared library
    • disk-mapped memory
    • swapped out memory
  • 메모리 사용량 색상은 다음과 같음
    • Green: used memory
    • Blue: buffers
    • Orange: cache
  • VIRT/VSZ

    • VIRT는 task가 사용하는 전체 virtual memory 양임
    • code, data, shared library, swapped out page, mapped됐지만 사용되지 않은 page를 포함함
    • 애플리케이션이 1GB를 요청하고 1MB만 사용해도 VIRT는 1GB로 나올 수 있음
    • 1GB 파일을 mmap하고 실제 사용하지 않아도 VIRT는 1GB로 표시될 수 있음
    • 대부분의 경우 VIRT는 유용한 숫자가 아님
  • RES/RSS

    • RES는 swapped out되지 않은 physical memory, 즉 현재 물리 메모리에 있는 resident memory 사용량임
    • RES는 VIRT보다 실제 메모리 사용량을 더 잘 나타낼 수 있지만 한계가 있음
    • swapped out memory를 포함하지 않음
    • 일부 메모리는 다른 프로세스와 공유될 수 있음
    • 프로세스가 1GB 메모리를 사용한 뒤 fork()하면 두 프로세스의 RES가 각각 1GB로 보일 수 있지만, Linux의 copy-on-write 때문에 실제로는 1GB만 사용될 수 있음
  • SHR

    • SHR은 task가 사용하는 shared memory 양임
    • 다른 프로세스와 잠재적으로 공유될 수 있는 메모리를 반영함
    • 예시 C 프로그램은 malloc, 일부 메모리 사용, fork, 추가 메모리 쓰기를 거치며 VIRT, RES, SHR 값이 어떻게 달라지는지 보여줌
    • 해당 메모리 예제 섹션은 TODO로 남아 있음
  • MEM%

    • MEM%는 task가 현재 사용하는 available physical memory의 비율임
    • RES를 전체 RAM으로 나눈 값임
    • 예: RES가 400M이고 RAM이 8GB이면 400/8192*100 = 4.88%

Ubuntu Server 16.04 기본 프로세스들

  • fresh Digital Ocean droplet의 Ubuntu Server 16.04.1 LTS x64에서 시작되는 프로세스들을 조사함
  • /sbin/init

    • /sbin/init은 boot process의 나머지를 조정하고 사용자 환경을 구성함
    • 자동으로 시작되는 프로세스들의 parent 또는 grandparent가 됨
    • dpkg -S /sbin/init 결과 systemd-sysv: /sbin/init으로, 해당 시스템에서는 systemd임
    • kill해도 아무 일도 일어나지 않음
  • /lib/systemd/systemd-journald

    • systemd-journald는 logging data를 수집하고 저장하는 system service임
    • 여러 source에서 받은 로그 정보를 기반으로 structured, indexed journal을 만들고 유지함
    • 단순한 평문 로그 파일 대신 로그 메시지에 최적화된 특수 파일 형식을 사용함
    • journalctl로 조회함
    • journalctl _COMM=sshd
    • journalctl _COMM=sshd -o json-pretty
    • journalctl --since yesterday
    • journalctl -b
    • journalctl -f
    • journalctl --disk-usage
    • journalctl --vacuum-size=1G
    • 제거하거나 비활성화할 수는 없어 보이며, logging을 끌 수만 있음
  • /sbin/lvmetad -f

    • lvmetad는 LVM metadata를 cache해서 LVM 명령이 disk scan 없이 metadata를 읽게 함
    • disk scan은 시간이 걸리고 시스템과 disk의 일반 작업을 방해할 수 있음
    • LVM은 Linux가 실행 중일 때 logical volume을 만들고, resize하고, 삭제할 수 있는 “dynamic partitions”로 볼 수 있음
    • LVM을 사용 중이라면 유지해야 할 것으로 정리됨
  • /lib/systemd/udevd

    • systemd-udevd는 kernel uevent를 듣고, 각 event에 대해 udev rules의 matching instruction을 실행함
    • udev는 Linux kernel의 device manager이며 /dev directory의 device node를 주로 관리함
    • virtual server에서 필요한지는 확신하지 못함
  • /lib/systemd/timesyncd

    • systemd-timesyncd는 remote NTP server와 local system clock을 동기화하는 system service임
    • ntpd를 대체함
    • 예시 시스템에서는 timedatectl status가 network time과 NTP synchronized를 yes로 보여줌
    • netstat 출력에서는 SSH port만 listening 상태로 보이며, Ubuntu 14.04의 ntpd처럼 여러 UDP 123 port를 열지 않음
  • /usr/sbin/atd -f

    • atd는 나중에 실행하도록 queue에 넣은 job을 실행함
    • at과 batch는 stdin 또는 파일에서 명령을 읽어 나중에 실행함
    • 반복 실행을 예약하는 cron과 달리 at은 특정 시간에 한 번 실행함
    • 예시에서는 echo "touch /tmp/yolo.txt" | at now + 1 minute로 1분 뒤 파일을 생성함
    • 사용하지 않으면 sudo apt remove at -y --purge로 제거함
  • /usr/lib/snapd/snapd

    • Snappy Ubuntu Core는 transactional update를 사용하는 Ubuntu rendition으로 소개됨
    • snap은 하나의 binary package가 Linux desktop, server, cloud, device에서 동작하도록 하는 universal Linux package format으로 설명됨
    • dependency를 single snap에 묶어 배포하는 simplified deb package처럼 이해됨
    • 서버에서 snappy로 애플리케이션을 deploy하거나 distribute해 본 적이 없어 sudo apt remove snapd -y --purge로 제거함
  • /usr/bin/dbus-daemon

    • D-Bus는 같은 machine에서 동시에 실행되는 여러 process 사이의 IPC와 RPC mechanism임
    • desktop environment에는 필요하지만 web app을 실행하는 server에서는 필요한지 의문을 가짐
    • dbus를 제거하자 timedatectl status가 Failed to create bus connection: No such file or directory로 실패함
    • 그래서 keep하는 편이 좋다고 정리됨
  • /lib/systemd/systemd-logind

    • systemd-logind는 user login을 관리하는 system service임
  • /usr/sbin/cron -f

    • cron은 scheduled command를 실행하는 daemon임
    • -f는 foreground mode로 daemonize하지 않음을 뜻함
    • 주기적으로 실행할 작업은 cron으로 예약할 수 있음
    • crontab -e
    • Ubuntu에서는 /etc/cron.hourly, /etc/cron.daily 등을 사용하는 편이라고 정리됨
    • 로그는 다음 방식으로 볼 수 있음
    • grep cron /var/log/syslog
    • journalctl _COMM=cron
    • journalctl _COMM=cron --since="date" --until="date"
    • cron은 유지할 가능성이 높음
    • 제거하지 않을 경우 sudo systemctl stop cron, sudo systemctl disable cron으로 중지·비활성화할 수 있음
    • apt remove cron은 postfix 등을 설치하려고 할 수 있음
    • cron이 mail transport agent를 suggest하기 때문임
  • /usr/sbin/rsyslogd -n

    • rsyslogd는 message logging을 지원하는 system utility임
    • /var/log/auth.log 같은 /var/log/의 로그 파일을 채우는 역할을 함
    • 설정 파일은 /etc/rsyslog.d에 있음
    • 원격 서버로 로그를 보내 centralized logging을 구성할 수 있음
    • logger 명령으로 background script에서 /var/log/syslog에 메시지를 남길 수 있음
    • systemd-journald가 이미 있어도 rsyslog와 journal은 서로 다른 특징이 있어 함께 쓰는 상황이 유용할 수 있음
    • 그래서 일단 유지함
  • /usr/sbin/acpid

    • acpid는 ACPI event daemon임
    • user-space program에 ACPI event를 알려주도록 설계됨
    • ACPI는 hardware component discovery/configuration, power management, status monitoring 등에 쓰임
    • virtual server에서 suspend/resume을 의도하지 않아 제거해 봄
    • reboot은 성공했지만 halt 후 Digital Ocean이 여전히 켜진 것으로 인식해 web interface에서 Power Off해야 했음
    • 따라서 유지하는 편이 좋다고 정리됨
  • /usr/bin/lxcfs /var/lib/lxcfs/

    • lxcfs는 LXC container를 위해 설계된 FUSE filesystem임
    • /proc 일부 파일의 virtualized view와 host cgroup filesystem에 대한 filtered access를 제공함
    • container 안에서 uptime, top 등이 더 “correct”한 결과를 갖게 함
    • LXC container를 쓰지 않으면 sudo apt remove lxcfs -y --purge로 제거할 수 있음
  • /usr/lib/accountservice/accounts-daemon

    • AccountsService는 user account 정보를 query하고 조작하기 위한 D-Bus interface와 구현을 제공함
    • 구현은 usermod(8), useradd(8), userdel(8) 명령을 기반으로 함
    • 제거 후 무엇이 깨질지는 “Time will tell”로 남겨짐
  • /sbin/mdadm

    • mdadm은 software RAID device를 관리하고 모니터링하는 Linux utility임
    • RAID는 여러 hard drive를 하나처럼 사용하는 방식임
    • RAID 0은 drive capacity를 확장함
    • RAID 1, RAID 5, RAID 6, RAID 10은 drive failure 시 data loss를 막는 목적이 있음
    • sudo apt remove mdadm -y --purge로 제거할 수 있음
  • /usr/lib/policykit-1/polkitd --no-debug

    • polkitd는 PolicyKit daemon이며, polkit은 Authorization Framework임
    • fine-grained sudo처럼 이해됨
    • non-privileged user에게 root로 특정 action을 할 권한을 줄 수 있음
    • 예: desktop Linux에서 reboot 허용
    • server에서는 sudo apt remove policykit-1 -y --purge로 제거할 수 있다고 정리됨
    • 무엇이 깨지는지는 여전히 의문으로 남음
  • /usr/sbin/sshd -D

    • sshd는 OpenSSH Daemon임
    • -D 옵션은 detach하지 않고 daemon이 되지 않게 하며, monitoring을 쉽게 함
  • /sbin/iscsid

    • iscsid는 iSCSI configuration에 따라 동작하고 connection을 관리하는 background daemon임
    • iSCSI는 IP 기반 storage networking standard로, SCSI command를 IP network로 전달해 remote storage를 local disk처럼 사용할 수 있게 함
    • sudo apt remove open-iscsi -y --purge로 제거할 수 있음
  • /sbin/agetty --noclear tty1 linux

    • agetty는 alternative Linux getty임
    • getty는 physical 또는 virtual terminal을 관리하고, 연결이 감지되면 username prompt를 띄운 뒤 login 프로그램을 실행함
    • Digital Ocean에서는 droplet details의 Console을 통해 이 terminal과 browser에서 상호작용할 수 있음
    • getty@tty1.service 관련 파일을 제거하고 reboot하면 SSH 접속은 가능했지만 Digital Ocean web console에서는 login할 수 없었음
  • SSH 세션, bash, htop

    • sshd: root@pts/0은 root 사용자의 SSH session이 pseudoterminal pts/0에 설정됐다는 뜻임
    • pseudoterminal은 실제 text terminal을 emulate함
    • bash는 사용 중인 shell임
    • -bash처럼 앞에 dash가 붙으면 login shell로 시작된 것임
    • argument zero의 첫 문자가 -이거나 --login option으로 시작된 shell은 login shell임
    • 이 경우 다른 configuration file set을 읽음
    • htop은 screenshot에서 실행 중인 interactive process viewer임

서비스 제거 실험

  • 일반 제거 목록은 다음과 같음
    • sudo apt remove lvm2 -y --purge
    • sudo apt remove at -y --purge
    • sudo apt remove snapd -y --purge
    • sudo apt remove lxcfs -y --purge
    • sudo apt remove mdadm -y --purge
    • sudo apt remove open-iscsi -y --purge
    • sudo apt remove accountsservice -y --purge
    • sudo apt remove policykit-1 -y --purge
  • Extreme edition은 다음 작업을 포함함
    • sudo apt remove dbus -y --purge
    • sudo apt remove rsyslog -y --purge
    • sudo apt remove acpid -y --purge
    • sudo systemctl stop cron && sudo systemctl disable cron
    • sudo rm /etc/systemd/system/getty.target.wants/getty@tty1.service
    • sudo rm /lib/systemd/system/getty@.service
  • unattended installation of WordPress on Ubuntu Server 지침을 따른 nginx, PHP7, MySQL 구성은 동작함

부록: 조사 도구와 shell 동작

  • 소스 코드 찾기

    • strace만으로 충분하지 않을 때는 source code를 볼 수 있음
    • which uptime으로 binary 위치를 찾고, dpkg -S /usr/bin/uptime으로 Ubuntu package를 찾음
    • 예시에서는 uptime이 procps package에 속함
    • packages.ubuntu.com에서 package를 검색하고 source repository link를 찾을 수 있음
  • file descriptor와 redirection

    • stderr를 stdout으로 redirect할 때는 2>&1을 사용함
    • echo something > file은 stdout을 file에 쓰는 것이며 echo something 1> file과 같음
    • echo something 2> file은 stderr를 file에 씀
    • echo something 2>1은 stderr를 1이라는 filename에 redirect하는 뜻임
    • &를 붙인 2>&1에서 1은 filename이 아니라 stream ID임
  • PuTTY 색상 문제

    • PuTTY에서 htop 요소가 빠져 보이면 Window → Colours 설정에서 해결할 수 있음
    • title bar 우클릭
    • Change settings...
    • Window → Colours
    • Both radio button 선택
    • Apply
  • C로 만든 간단한 shell

    • C로 작성한 간단한 shell은 fork, exec, wait 시스템 호출 사용을 보여줌
    • 입력이 exit이면 shell built-in으로 종료함
    • 그 외 명령은 fork 후 child에서 execlp로 실행하고, parent는 waitpid로 종료 상태를 기다림
    • date, true, false 실행 예시는 child exit code가 각각 출력됨
    • sleep 1 & 같은 background process의 종료 메시지가 Enter를 누른 뒤에야 보이는 이유는 shell이 input을 기다리다가 명령 입력 시 background process 상태를 확인하기 때문임

남은 조사 항목과 수정 이력

  • 더 알아보고 싶은 항목은 process state substatus, kernel thread, /dev/pts, CODE·DATA·SWAP 메모리, time slice 길이, Linux scheduler 알고리듬, core pinning, manual page, CPU/memory bar 색상, process ID limit와 fork bomb, lsof, ionice, schedtool 등임
  • 주요 수정·업데이트에는 다음이 포함됨
    • /proc/uptime idle time은 모든 core의 합산임
    • zombie C 예제의 parent/child printf가 수정됨
    • apt remove cron이 MTA dependency 때문에 postfix를 설치하려는 점이 추가됨
    • id는 /etc/nsswitch.conf를 통해 /etc/passwd 외 다른 source에서도 정보를 로드할 수 있음
    • /etc/shadow password hash format 설명이 추가됨
    • /etc/sudoers는 안전하게 visudo로 편집해야 함
    • MEM% 설명이 추가됨
    • load average 섹션이 다시 작성됨
    • kill 1234의 기본 signal은 INT가 아니라 TERM으로 수정됨
    • CPU와 memory color bar 설명이 추가됨
Read Entire Article