5장. 파일 시스템
리눅스 리소스의 대부분은 실제 파일이다.
리눅스에서 파일로 취급되는 것도 존재하는데 바로 디바이스와 의사 디바이스가 그런 종류다.
예를 들어 커널은 PID나 프로세스를 실행하는 데 사용되는 바이너리처럼 프로세스에 대한 특정 런타임 정보를 노출한다.
이 모든 것이 공통적으로 지니는 점은 파일 열기, 파일에 대한 정보 수집, 파일 작성 등과 같이 표준화되고 통일된 인터페이스다.
리눅스에서는 바로 파일시스템이 이런 통일된 인터페이스를 제공한다.
이 인터페이스와 리눅스가 파일을 바이트 스트림으로 최급한다는 사실이 더해져서, 구조에 대한 별다른 염려 없이 다양한 파일 유형을 지원하는 도구를 만들 수 있게 된다.
일반적으로 파일 시스템은 커널에서 제공된다.
파일 시스템은 권한이 내장되어 있다. 소유권은 할당된 권한을 통해 파일과 디렉터리에 대한접근을 제한한다.
용어 정리
- 드라이브
- HDD 또는 SSD와 같은 블록 디바이스
- 가상 머신의 드라이브는 에뮬레이션될 수도 있다.
- 예를 들어 /dev/sda, /dev/sdb, /dev/hda 와 같은 식
- 파티션
- 드라이브를 스토리지 섹터의 집합인 파티션으로 논리적으로 분할할 수 있다.
- 예를 들어 HDD에 두 개의 파티션을 생성한다면 /dev/sdb1와 /dev/sdb2로 표시되는 식이다.
- 볼륨
- 볼륨은 파티션과 비슷하지만 더 유연하며, 특정 파일시스템용으로 포맷되기도 한다.
- 슈퍼 블록
- 시스템이 포맷되면 파일시스템의 시작 부분에 파일 시스템의 메타데이터를 캡쳐하는 특수 섹션이 생긴다.
- 여기에는 파일 시스템의 유형, 블록, 상태, 블록당 아이노드 수 등이 담긴다.
- 아이노드
- 파일 시스템의 아이노드는 크기, 소유자, 위치 날짜, 권한과 같은 파일의 메타데이터를 저장하지만 파일명과 실제 데이터는 저장하지 않는다.
- 이 데이터는 디렉터리에 보관되며, 디렉터리는 아이노드를 파일명에 매핑하는 특별한 종류의 일반 파일이라 할 수 있다.
파일 시스템과 관련해 앞으로 접하게 될 또 다른 용어가 바로 링크다.
리눅스에는 두 가지 유형의 링크가 있다.
- 하드 링크: 아이노드를 참조하며 디렉토리는 참조할 수 없다. 또한 파일 시스템이 서로 다르면 동작하지 않는다.
- 심볼릭 링크: 파일의 내용이 다른 파일의 경로를 나타내는 문자열인 특수 파일
가상 파일 시스템
리눅스는 가상 파일 시스템이라는 추상화를 통해 다양한 종류의 리소스(인메모리, 로컬 연결, 네트워크 스토리지)에 파일과 유사한 접근을 제공할 수 있다.
기본 개념은 클라이언트(시스템 콜)와 개별 파일 시스템 사이에 간접 계층을 도입하는 것이다.
여기서 개별 파일시스템은 구체적인 디바이스 또는 다른 리소스 유형을 위한 연산을 구현한다.
즉 VFS는 일반작업을 실제 구현 세부사항과 분리한다.
VFS는 파일 체계를 기반으로 클라이언트가 동일한 방법으로 리소스에 접근할 수 있게 해주는 커널의 추상화 계층이다.
리눅스의 파일에는 규정된 구조가 없다. 그저 바이트 스트림일 뿐이다. 바이트의 의미를 결정하는 것은 클라이언트에게 달려있다.
VFS는 다양한 종류의 파일 시스템에 대한 접근을 추상화한다.
- ext3, XFS, FAT, NTFS 같은 로컬 파일 시스템
- 이런 파일 시스템은 드라이버를 사용해 HDD, SSD와 같은 로컬 블록 디바이스에 접근한다.
- 장기 저장 디바이스가 지원하지 않지만 RAM에 상주하는 tmpfs와 같은 인메모리 파일 시스템
- procfs와 같은 의사 파일 시스템
- 이런 파일 시스템도 본직적으로는 인메모리다. 커널 인터페이스와 디바이스 추상화에 사용
- NFS, 삼바, 넷웨어 등의 네트워크 파일 시스템
- 이런 파일도 드라이버를 사용. 하지만 실제 데이터가 상주하는 저장 디바이스는 로컬이 아니라 원격에 저장되어 있다.
- 이는 드라이버에 네트워크 작업이 포함됨을 의미한다.
VFS 인터페이스를 구성하는 시스템 콜은 아래와 같다.
카테고리 사용예제
아이노드 | chmod, chown, stat |
파일 | open, close, seek, truncate, read, write |
디렉터리 | chdir, getcwd, link, unlink, rename, synlink |
파일시스템 | mount, flush, chroot |
그 외 | mmap, poll, sync, flock |
리눅스 커널은 관련 VFS 데이터 구조를 다음과 같이 정의한다.
- inode: 핵심 파일 시스템 객체, 캡처 유형, 소유권, 권한, 링크, 파일 데이터를 포함하는 블록에 대한 포인터, 생성과 접근 통계 등
- file: 열려 있는 파일을 나타냄
- dentry: 부모와 자식 저장
- super_block: 마운트 정보를 포함한 파일시스템을 나타냄
- 그 외: vfsmount와 file_system_type 포함
범용 파일 시스템 레이아웃
프로그램이 저장된 위치, 구성 데이터 ,시스템 데이터, 사용자 데이터와 같은 항목을 구조화할 수 있는데,
이런 디렉터리의 구성과 그 내용을 파일시스템 레이아웃 이라고 한다.
공식적으로 이런 레이아웃은 파일 시스템 계층 구조 표준(FHS) 라고 한다.
구체적인 설정을 알아보려면 man hier 명령을 사용하는 것이 좋다.
디렉터리 의미
bin, sbin | 시스템 프로그램과 명령(일반적으로 /usr/bin과 /usr/sbin에 링크되어 있다. |
boot | 커널 이미지와 관련 구성요소 |
dev | 디바이스(터미널, 드라이브 등) |
etc | 시스템 구성 파일 |
home | 사용자 홈 디렉터리 |
lib | 공유 시스템 라이브러리 |
mnt, media | 이동식 미디어용 마운트 지점(ex: USB 스틱) |
opt | 배포판 지정 디렉터리. 패키지 관리자 파일을 호스팅 |
proc, sys | 커널 인터페이스 |
tmp | 임시 파일용 |
usr | 사용자 프로그램(일반적으로 읽기 전용) |
var | 사용자 프로그램(로그, 백업, 네트워크 캐시 등) |
의사파일시스템
의사 파일 시스템은 파일시스템인 것처럼 가장하여 일반적인 방식(ls, cd, cat)으로 상호 작용할 수 있지만, 실제로는 커널 인터페이스를 래핑한 것이다.
여기서 인터페이스란 다음과 같이 다양한 범위에 이른다.
- 프로세스에 대한 정보
- 키보드 같은 디바이스와의 상호 작용
- 데이터 소스나 싱크로 사용할 수 있는 특수 디바이스 같은 유틸리티
이제 리눅스의 세 가지 주요 의사 파일 시스템 procfs, sysfs, devfs가 있다.
범용 파일 시스템
- ext4
- 제일 많이 사용하는 파일 시스템
- ext3과 호환되는 진화 버전
- 저널링 기능 제공. 즉 변경 사항이 로그에 기록되어 최악의 경우가 닥쳤을 때 복구가 빠르다.
- XFS
- 1990년대 초 실리콘 그래픽스가 워크스테이션용으로 설계한 저널링 파일 시스템
- 대용량 파일과 고속 I/O를 지원. 현재는 레드햇 배포판 제품군 같은데서 사용
- ZFS
- 초기 ZFS는 파일시스템과 볼륨 관리자 기능을 결합
- 지금은 OpenZFS 프로젝트가 오픈 소스 영역에서 나아갈 길을 제시하고 있지만, ZFS와 리눅스의 통합에는 우려가 있다.
- FAT
- 실제 리눅스용 FAT 파일 시스템 제품군으로, 그중에서도 vfat가 가장 자주 사용된다.
- 주요 사용 사례는 FAT를 사용하는 이동식 미디어뿐만 아니라 윈도우 시스템과의 상호 운용성을 목적으로 한다.
- 불륨에 대해 네이티브 고려사항이 그다지 적용되지 않았다.
쓰기 시 복사(Cow) 파일 시스템
쓰기 시 복사는 I/O 속도를 높이는 동시에 공간은 적게 사용하는 개념이다.
- 블록 A, B, C로 이루어진 원본 파일인 파일 1을 파일 2에 복사한다. 실제 블록을 복사하는 대신 메타데이터만 복사한다. 메타데이터만 생성되기 때문에 속도가 빠르며 공간도 많이 차지하지 않는다.
- 파일 2가 수정되면 C블록만 복사된다. C라는 새 블록이 생성되지만 파일 2는 여전히 수정되지 않은 블록 A와 B를 가리키고 있으며, 이제 새 블록을 사용해 새 데이터를 캡쳐한다.
구현 내용을 다루기 전에 먼저 이 내용과 관련된 두 번째 개념인 유니온 마운트를 이해해야 한다.
이는 여러 디렉터리를 하나의 위치로 결합해서, 해당 디렉터리에 모든 참여 디렉터리가 결합된 내용이 포함된 것처럼 결과 디렉터리의 사용자에게 보이게 할 수 있다는 개념이다.
6장. 애플리케이션, 패키지 관리, 컨테이너
애플리케이션은 프로그램, 바이너리, 실행 파일 과 동일한 의미로 사용될 때가 많다.
리눅스가 시작되고 우리가 의존하는 모든 서비스를 제공하는 방식은 부팅 프로세스 라고 부른다.
init 시스템, 특히 사실상의 표준인 systemd 생태계에 대해 살펴보자.
개요
프로그램
- 일반적으로 리눅스가 메모리에 로드하고 실행할 수 있는 바이너리 파일 혹은 셸 스크립트를 일컫는다.
- 이 엔티티를 부르는 또 다른 이름은 실행 파일 이다.
- 실행 파일의 유형에 따라 그 실행을 정확히 무엇이 관리하는지가 결정된다.
- 예를 들어 셸 스크립트는 셸이 해석하고 실행한다.
프로세스
- 프로그램 기반의 실행 엔티티이며 슬립 상태가 아닌 한 메인 메모리에 로드되어 CPU나 I/O를 사용한다.
데몬
- 데몬 프로세스 의 줄임말로 서비스 라고도 하며 다른 프로세스에 특정 기능을 제공하는 백그라운드 프로세스다.
- 예를 들어 프린터 데몬을 사용하면 인쇄가 가능해진다.
- 그 밖에도 웹 서비스, 로깅, 시간 등 매일 사용하는 유틸리티를 위한 온갖 데몬이 있다.
애플리케이션
- 종속성을 포함한 프로그램, 사용자 인터페이스를 포함한 실질적인 프로그램이다.
- 일반적으로는 검색 부터 업그레이드를 위한 설치, 제거에 이르기까지, 프로그램의 전체 수명주기, 구성, 데이터와 연관해 애플리케이션이라는 용어를 사용한다.
패키지
- 프로그램과 구성을 포함한 파일을 말한다. 소프트웨어 애플리케이션을 배포하는데 사용된다.
패키지 관리자
- 패키지 입력 값으로 받아 해당 콘텐츠의 사용자 지침에 따라 리눅스 환경에서 패키지를 설치, 업그레이드, 제거하는 프로그램이다.
공급망
- 패키지를 기반으로 사용자가 애플리케이션을 찾고 사용할 수 있는 소프트웨어 생산자와 배포자의 모음을 뜻한다.
부팅
- 리눅스를 사용할 수 있는 상태로 만드는 것을 목표로 하드웨어와 운영체제를 초기화하는 리눅스의 시작 시퀀스를 의미한다.
- 여기에는 커널 로딩과 서비스(또는 데몬) 프로그램 시작도 포함된다.
리눅스 시작 프로세스
리눅스 부트 프로세스는 하드웨어와 커널이 함께 작동하는 여러 단계에 걸친 작업이다.
- 전원 시작
- UEFI나 BIOS (하드웨어)
- 부트로더 (하드웨어)
- 커널 (커널 공간)
- init (사용자 공간)
- 그 밖의 사용자 공간 (사용자 공간)
1번: 모던 환경에서 통일 확장 펌웨어 인터페이스 사양은 부팅 구성과 부팅 로더를 정의한다. 이전 시스템에서는 이 단계에서 시동 자체 시험가 완료되면 기본 I/O 시스템이 하드웨어를 초기하고 부트 로더에 제어 권을 넘겨준다.
2번: 부트 로더의 목표는 커널을 부트스트랩하는 것이다. 부팅 매체에 따라 세부 사항은 약간 다르며 부트 로더의 옵션은 다양하고 현재 버전과 예전 레거시 모두 사용 가능하다.
3번: 커널을 일반적으로 압축된 형태로 /boot 디렉토리에 위치해 있다. 따라서 첫 번째 단계는 커널을 추출해 메인 메모리에 로드하는 것이다. 하위 시스템, 파일 시스템, 드라이버를 초기화하고 나면 커널은 init 시스템에 제어권을 넘기고 이로써 부팅 프로세스는 적절하게 종료한다.
4번: init 시스템은 시스템 전반에 걸쳐 데몬을 실행할 책임이 있다. 이 init 프로세스는 프로세스 계층 구조의 루트이며 프로세스 ID 값은 1을 가진다. 즉 PID 1 프로세스는 시스템 전원을 끌 때까지 실행된다. 다른 데몬 실행을 담당하는 것 외에도 PID 1 프로세스는 전통적으로 고아 프로세스도 처리한다.
5번: 일반적으로 이 이후에 환경에 따라 또 다른 사용자 공간 수준의 초기화가 진행된다.
- 일반적으로는 터미널, 환경, 셸 초기화가 일어난다.
- 사용자 설정과 구성을 고려해 GUI가 있는 데스크톱 환경용 디스플레이 관리자, 그래픽 서버 등이 시작된다.
systemd
systemd는 처음에 initd를 대체하는 init 시스템이었지만 최근에는 로깅, 네트워크 구성, 네트워크 시간 동기화의 같은 기능을 포함하는 강력한 관리자다.
이는 데몬과 해당 종속성을 정의하는 유연하고 이식 가능한 방법은 물론이고 구성을 제어하는 통일된 인터페이스도 제공한다.
systemd는 다음을 통해 이전 init 시스템의 단점을 해결한다.
- 여러 배포판에서 리눅스의 시작을 관리할 수 있는 통일된 방법 제공
- 빠르고 이해하기 쉬운 서비스 구성 구현
- 모니터링, 리소스 사용 제어(cgroup), 내장된 감사(audit) 기능을 포함한 최신 제품군 제공
또한 init는 초기화 때 순서대로(즉 영숫자 순서로) 서비스를 시작하는 반면 systemd는 어느 서비스는 종속성만 충족되면 시작할 수 있으므로 시작 시간을 단축할 수 있는 잠재력이 있다.
무엇을 언제 어떻게 실행할지 systemd에 지시하는 방법은 유닛을 통해 이뤄진다.
유닛
systemd의 유닛은 기능 및 대상 리소스에 따라 의미 체계가 다른 논리 그룹이다. systemd는 대상 리소스에 따라 여러 유닛을 구분한다.
- service 유닛 - 서비스나 애플리케이션을 관리하는 방법 설명
- target 유닛 - 종속성 캡쳐
- mount 유닛 - 마운트 지점 정의
- timer 유닛 - 크론 작업 등에 대한 타이머 정의
이보다 중요도가 조금 낮은 유닛은 아래와 같다.
- socket: 네트워크나 IPC 소켓을 설명
- device: udev나 sysfs 파일 시스템용
- automount: 자동 마운트 지점 구성
- swap: 스왑 공간 설명
- path: 경로 기반 활성화용
- snapshot: 변경사항이 일어난 후 시스템의 현재 상태를 재구성할 수 있음
- slice: cgroup과 연관됨
- scope: 외부에서 생성된 시스템 프로세스 세트를 관리
systemd에게 인식되려면 유닛은 한 파일로 직렬화돼야 한다. systemd는 여러 위치에서 유닛 파일을 찾는다. 가장 중요한 파일 경로 세 가지는 다음과 같다.
- /lib/systemd/system: 패키지가 설치한 유닛
- /etc/systemd/system: 시스템 관리자가 구성한 유닛
- /run/systemd/system: 비지속적 런타임 수정사항
systemd의 기본 작업 유닛이 정의되었으니, 이제는 커맨드 라인으로 어떻게 제어하는지를 살펴보자.
systemctl로 관리하기
systemd의 상호 작용해 서비스를 관리하기 위해 사용하는 도구가 systemctl다. 자주 사용하는 systemctl 명령 목록은 아래와 같다.
항목 유형
systemctl enable xxxx.service | 서비스 활성화. 시작할 준비를 갖춤 |
systemctl daemon-reload | 모든 유닛 파일을 다시 로드하고 전체 종속성 트리를 다시 생성함 |
systemctl start xxxx.service | 서비스 시작 |
systemctl stop xxxx.service | 서비스 정지 |
systemctl restart xxxx.service | 서비스 정지 후 새로 시작 |
systemctl reload xxxx.service | 서비스에 reload 명령을 보냄. restart로 돌아감 |
systemctl kill xxxx.service | 서비스 실행 중지 |
systemctl status xxxx.service | 일부 로그를 포함해서 서비스 상태에 대해 간단 요약 |
systemd가 관리하는 로그를 볼 수 있는 도구가 journalctl이라고 한다.
컨테이너
우리는 컨테이너를 리눅스 네임스페이스, cgroup, 때때로 CoW 파일 시스템을 사용해 애플리케이션 수준의 종속성 관리를 제공하는 리눅스 프로세스 그룹으로 이해할 수 있다.
컨테이너의 접근 방식의 공통점은 네임스페이스, cgroup 같이 리눅스 커널이 제공하는 기본 빌등 블록을 이용해 사용자가 애플리케이션을 실행할 수 있게 한다는 점이다.
리눅스에서 컨테이너 자체는 새로운 것이 아니지만, 도커 덕분에 주류로 편입되었다.
도커는 기존 개념을 혁신하고 2가지 획기적인 요소를 도입했다.
하나는 컨테이너 이미지를 통해 패키징을 정의하는 표준화된 방법, 다른 한가지는 인간 친화적인 사용자 인터페이스이다.
도커에서 컨테이너 이미지가 정의되고 배포되는 방식과 컨테이너가 실행되는 방식은 현재 OCI 핵심 사양의 기반이 됐다.
3가지 핵심 OCI 컨테이너 사양은 다음과 같다.
- 런타임 사양
- 운영과 수명 주기 단계를 포함해 런타임이 지원해야 하는 것을 정의한다.
- 이미지 형식 사양
- 메타데이터와 계층을 기반으로 컨테이너 이미지가 구성되는 방식을 정의한다.
- 배포 사양
- 컨테이너 이미지가 전달하는 방식, 컨테이너와 관련해 저장소가 효과적으로 동작할 수 있는 방식을 정의한다.
컨테이너와 관련된 또 다른 개념은 불변성이다. 한 번 구성되면 사용 중에 변경할 수 없다는 의미다.
즉 변경하려면 새로운 구성과 새 리소스를 생성해야 한다.
리눅스 네임 스페이스
리눅스는 리소스에 대한 전역 뷰를 가지고 있다.
프로세스가 리소스에 대한 로컬 뷰를 가질 수 있도록 리눅스는 네임스페이스를 도입했다.
즉 리눅스 네임스페이스는 모두 리소스 가시성에 관한 것이며 운영체제 리소스의 다양한 측면을 격리하는 데 사용할수 있다.
이 맥락에서 격리란 대부분 프로세스가 무엇을 보는지와 관련이 있으며 보안 관점에서 볼 때 반드시 엄격한 경계는 아니다.
네임 스페이스를 생성하려면 다음과 같은 3가지 관련 시스템 콜을 원하는 대로 상황에 맞게 사용할 수 있다.
- clone
- 실행 컨텍스트의 일부를 부모 프로세스와 공유할 수 있는 자식 프로세스를 만드는 데 사용
- unshare
- 기존 프로세스에서 공유된 실행 컨텍스트를 제거하는 데 사용된다.
- setns
- 기존 프로세스를 기존 네임스페이스에 결합하는데 사용된다.
이 시스템 콜은 다양한 플래그를 매개변수로 사용하므로 새로 생성, 가입, 탈퇴하려는 네임스페이스를 세밀하게 제어할 수 있다.
리눅스 cgroup
네임스페이스가 가시성에 관한거싱라면 cgroup은 프로세스 그룹을 구성하는 메커니즘이다.
cgroup을 계층 구조와 함께 사용하면 시스템 리소스 사용을 제어할 수 있다. 또한 cgroup은 리소스 사용 추적을 할 수 있다.
예를 들어 프로세스가 RAM이나 CPU 시간을 얼마나 사용중인지를 보여줄 수 있다.
cgroup은 선언형 유닛으로, 그리고 컨트롤러는 특정 리소스 제한을 적용하거나 사용량을 보고하는 커널 코드로 생각하자.
현재는 cgroup v1과 v2가 있다. 현재는 v1이 널리 사용되고 있지만 결국 v2가 이를 대체할 것이다.\
쓰기 시 복사(Cow) 파일 시스템
컨테이너의 세 번째 빌딩 블록은 쓰기 시 복사 파일 시스템이다.
이들은 빌드 시 사용되며, 애플리케이션과 모든 종속성을 배포 가능한 독립 파일 하나로 패키징한다.
Cow 파일 시스템은 주로 바인드 마운트와 함께 사용되어 종속성이 서로 다른 콘텐츠를 효율적인 방식으로 계층화한다.
7장. 네트워킹
현대 환경에서는 리눅스가 제공하는 네트워크 스택이 필수 구성요소로, 이게 없다면 할 수 있는 일이 별로 없다.
7장은 일반적인 전공책에서 나오는 네트워크 개념을 정리해 놓았으므로 이와 관련한 명령어를 위주로 정리.
아래 명령을 통해 NIC에 대한 정보를 살펴볼 수 있다.
ifconfig
ip link show
arp 관련 명령어
arp
ip neigh
IP 관련 항목에 대해 시스템을 쿼리하는 방법
ip addr show
8장. 옵저빌리티(관측가능성)
옵저빌리티 전략
옵저빌리티에 대해 널리 확립된 전략 중 하나가 우다 루프다.
이는 관측된 데이터를 기반으로 가설을 테스트하고 이에 따라 조치를 취하는 구조화된 방법, 시그널로부터 실행 가능한 통찰력을 얻는 방법을 제공한다.
예시로 애플리케이션이 느리다고 가정해보자. 그럼 느려진 원인으로 여러 후목을 지목한다.(메모리 부족, CPU 주기 부족, 네트워크 I/O 부족)
우선은 각 리소스가 얼마나 소비되는지부터 측정해야 할 것이다.
그런 다음 각 리소스의 할당을 개별적으로 변경하고 결과를 측정해본다.
앱에 더 많은 RAM을 제공했더니 성능이 향상됐는가? 그렇다면 이유를 찾은 것이다.
그렇지 않으면 다른 리소스를 연이어 사용해보면서, 소비량을 측정하고 이를 그 상황에서 관측된 영향과 연결하려 항상 노력해야 한다.
용어
관측가능성(옵저빌리티)
- 외부 정보를 측정하여 시스템(리눅스)의 내부 상태를 평가하는 것.
- 일반적으로는 후속 조치를 취한다.
- 예를 들어 시스템이 느리게 반응하는 것을 느껴 사용 가능한 주 메모리 양을 측정했다면, 특정 앱이 모든 메모리를 독차지하는 상황을 발견했을 수 있다.
- 이때 우리는 그 상황을 해결하기 위해 해당 앱을 종료하기로 결정할 수 있다.
시그널 유형
- 기호적 수단이나 숫자 값, 또는 이들의 조합을 통해 시스템 상태에 대한 정보를 보여주고 내보내는 다양한 방식을 말한다.
소스
- 시그널을 생성하는 곳. 해당 시그널의 유형은 다양할 수 있다.
- 소스는 리눅스 운영체제일 수도, 애플리케이션일 수도 있다.
목적지
- 시그널을 소비, 저장, 추가적으로 처리하는 곳이다.
- GUI를 노출하는 목적지를 프론트엔드라고 한다.
- 예를 들어 로그 뷰어, 시계열을 표시하는 대시보드는 프론트엔드인 반면 S3 버킷은 아니다.
텔레메트리
- 소스에서 시그널을 추출하고 시그널을 목적지로 전송하는 프로세스로, 시그널을 수집 및 전처리하는 에이전트를 사용하는 경우가 많다.
시그널 유형
시그널은 추가 처리나 해석을 위해 시스템 상태를 전달하는 방법으로서, 크게 텍스트 페이로드와 숫자 페이로드로 구분한다.
살펴볼 시그널은 로그, 지표(메트릭), 추적(트레이스)이다.
로그
- 로그는 거의 모든 시스템이 생성하는 기본 시그널 유형
- 로그란 사람이 사용할 수 있는 텍스트 페이로드가 있는 개별 이벤트로서 일반적으로 이런 이벤트에는 타임스탬프가 지정된다.
- 로그는 메시지의 각 부분마다 명확한 의미가 정의되도록 구성하는 것이 이상적이다.
- 이 의미는 유효성 검사가 자동을 ㅗ수행될 수 있도록 형식 스키마를 통해 표현될때가 많다.
- 모든 로그가 일종의 구조를 지님에도 실무에서는 구조화된 로깅이라는 용어를 자주 듣는다.
- 사실 로그가 JSON을 이용해 구성된다는 의미다.
지표(메트릭)
- 지표는 (대부분 정기적으로)샘플링된 숫자 데이터 포인트로서, 시계열을 형성한다.
- 각각의 데이터 포인트는 차원이나 식별 메타데이터의 형태로 추가 컨텍스트를 가질 수 있다.
- 일반적으로는 원시(raw) 지표를 직접 사용하지 않는다.
- 대신 일종의 집계(aggregation)나 그래픽 표현을 사용하고, 특정 조건이 충족되면 알림을 받기도 한다.
- 지표는 운영 작업에도 유용하며, 앱이 완료한 트랜잭션 수나 특정 작업에 소요된 시간과 같은 질문에 답하기 위한 문제 해결에도 유용하다.
메트릭은 아래와 같이 다양한 유형으로 분류한다.
- 카운터 (올라가기만함)
- 게이지 (올라가고 내려감)
- 히스토그램 (값의 분포를 보여줌)
추적(트레이스)
- 추적은 런타임 정보의 동적 모음으로서, 디버깅뿐만 아니라 성능 평가에도 자주 사용된다.
- 예시: 특정 원인에 대해 프로세스가 사용하는 시스템 콜에 대한 정보나 커널의 이벤트 시퀀스
로깅
로그란 사람이 사용하기에 최적화된 텍스트 페이로드가 있는 개별 이벤트다.
개별 이벤트
- 로그 항목을 사용해 코드에서 진행 중인 작업에 대한 정보를 공유하고 싶다고 가정.
- 예시: 데이터베이스 연결이 성공적으로 설정되었다는 로그행을 출력
- 로그 메시지의 범위를 적고 구체적으로 유지하면 메시지를 사용하는 사람이 코드에서 해당 위치를 더 쉽게 찾을 수 있다.
텍스트 페이로드
- 로그 메시지의 페이로드는 텍스트고 기본 소비자는 사람이다.
- 즉 커맨드라인에서 로그 뷰어를 사용하든 GUI가 있는 멋진 로그 처리 시스템을 사용하든 사람이 로그 메시지의 내용을 읽고 해석하고 그에 따라 조치를 결정하는 것이다.
구조적 관점에서 보면 전체적으로 로그는 다음과 같이 구성된다.
- 로그 항목, 메시지, 행의 모음: 개별 이벤트에 대한 정보를 캡처한다.
- 메타데이터, 컨텍스트: 전역범위 뿐만 아니라 메시지 단위로도 존재할 수도 있다.
- 개별 로그 메시지를 해석하는 방법을 보여주는 형식: 로그의 부분과 의미를 정의. 공백으로 구분된 행 중심 메시지나 JSON 스키마를 예로 들 수 있다.
로그로 인한 오버헤드는 피하는 편이 좋다.
이와 관련한 예로 logrotate를 이용한 로그 순환을 사용하는 경우가 있다.
데이터 온도라는 고급 개념도 유용할 수 있으며, 오래된 로그 파일을 더 저렴하고 느린 스토리지로 옮길 수도 있다.
로그 항목의 중요성이나 의도된 대상 소비자를 알려주기 위해 대부분의 로그는 레벨을 정의해둔다.
Syslog
Syslog는 커너렝서부터 데몬, 사용자 공간까지 이르는 다양한 소스의 로깅 표준이다.
네트워크 환경에 근간을 두고 있으며 최근의 프로토콜은 배포 시나리오 및 보안 고려사항과 함께 RFC 5424에 정의된 텍스트 형식으로 구성된다.
systemd가 모든 주요 리눅스 배포판에서 사용되는 init 시스템의 사실상 표준이 되면서 로깅에 대한 새로운 방법이 나타났는데 그것이 바로 systemd 저널이다.
journalctl
systemd 에코시스템의 일부이며 로그 관리를 담당하는 구성 요소인 journalctl을 간략하게 다룬적이 있다.
Syslog 등 지금까지 사용한 시스템들과 달리 journalctl은 바이너리 형식을 사용해 로그 항목을 저장한다.
이를 통해 더 빠르게 접근할 수 있으며 저장 공간도 더 많이 확보할 수 있다.
모니터링
모티렁이란 다양한 이유로 시스템과 애플리케이션 지표를 캡쳐하는 것이다. 모니터링과 관련해 가장 자주 수행하게 될 두 가지 유형의 활동은 다음과 같다.
- 하나 이상의 지표 추적
- 조건에 의거한 알림
uptime, free -h, vmstat, iostat, ss, lsof, top 등을 사용해 모니터링 실습 진행
참고자료
https://product.kyobobook.co.kr/detail/S000210138053
댓글