13년차의 서버실

서버, 인프라, 홈랩 기술 블로그

[태그:] Linux

  • [Linux] Linux 사용자 관리: sudo 권한부터 계정 관리까지 1년 실전 가이드

    [Linux] Linux 사용자 관리: sudo 권한부터 계정 관리까지 1년 실전 가이드

    [Linux] Linux 사용자 관리: sudo 권한부터 계정 관리까지 1년 실전 가이드

    홈랩을 오래 굴리다 보면 결국 제일 자주 만지는 영역이 Linux 사용자 관리더라고요. 처음에는 계정 하나 만들고 <code>sudo만 붙여주면 끝인 줄 알았는데, 실제로 1년 정도 운영해보니 그게 시작이었습니다. 누가 어떤 권한을 가져야 하는지, 비밀번호 정책은 어디까지 강하게 가져갈지, SSH(Secure Shell, 원격 접속) 접근은 어떻게 나눌지 같은 문제가 계속 나오거든요. 특히 여러 대의 서버를 동시에 관리하면 작은 실수가 바로 보안 이슈로 이어질 수 있어서, 이 부분은 초반에 습관을 잘 잡는 게 정말 중요합니다.

    저도 처음엔 루트(root, 최고 관리자 계정)로 바로 접속해서 작업하던 시기가 있었는데요. 편하긴 한데, 실수 한 번이면 복구가 꽤 피곤했습니다. 그래서 지난 1년 동안은 일반 사용자 계정 기반으로 운영하고, 필요한 작업만 sudo로 올리는 방식으로 정리해봤습니다. 실제로 써보니까 관리 포인트가 명확해지고, 문제 추적도 쉬워지더라고요. 이번 글에서는 제가 직접 해보며 정리한 사용자 관리 기준, sudo 권한 설정 방법, 그리고 계정 운영할 때 자주 터지는 문제까지 한 번에 묶어서 공유해보겠습니다.

    여러 대의 Linux 서버에서 사용자, 그룹, sudo 권한, SSH 접근 흐름이 어떻게 연결되는지 보여주는 개요 이미지입니다.

    1. 왜 Linux 사용자 관리가 생각보다 중요한가

    쉽게 말해 Linux 사용자 관리는 “누가, 어디까지, 어떤 방식으로 시스템을 만질 수 있느냐”를 정하는 일입니다. 서버가 한 대일 때는 체감이 덜할 수 있는데, 두 대 세 대 넘어가고 NAS(Network Attached Storage, 네트워크 저장소)나 컨테이너 호스트까지 붙기 시작하면 이야기가 달라집니다. 계정을 아무 생각 없이 늘리면, 나중에 누가 어떤 변경을 했는지 찾기 어려워집니다.

    • 책임 추적(Accountability, 작업 책임 추적)이 쉬워집니다.
    • 최소 권한 원칙(Principle of Least Privilege, 필요한 만큼만 권한 부여)을 적용할 수 있습니다.
    • 루트 계정 직접 사용을 줄여서 사고 범위를 제한할 수 있습니다.
    • 퇴사자 계정, 테스트 계정, 임시 계정을 정리하기 쉬워집니다.

    여기서 중요한 포인트! Linux는 기본적으로 강력한 멀티유저(multi-user, 다중 사용자) 시스템입니다. 그런데 운영자가 그 특성을 제대로 활용하지 않으면, 그냥 “다들 sudo 되는 단일 사용자 환경”처럼 굴러가 버리더라고요. 저도 한동안 그렇게 썼었는데, 나중에 계정 관리가 꼬이니까 정리가 꽤 힘들었습니다.

    2. Linux 사용자 관리의 핵심 개념 정리

    저도 처음엔 헷갈렸는데, 아래 네 가지만 명확히 잡으면 절반은 끝입니다.

    2-1. 사용자(User)와 그룹(Group)

    사용자(User, 개별 계정)는 실제 로그인 주체이고, 그룹(Group, 권한 묶음)은 여러 사용자에게 공통 권한을 부여할 때 씁니다. 보통 운영은 사용자에게 직접 권한을 덕지덕지 붙이는 것보다, 그룹 설계를 먼저 하고 사용자를 그룹에 넣는 쪽이 관리가 훨씬 편하더라고요.

    2-2. sudo 권한

    sudo는 superuser do의 약자로, 일반 계정이 관리자 권한으로 특정 명령을 실행할 수 있게 해줍니다. 즉, 항상 루트로 로그인하지 않아도 필요한 순간에만 권한을 올릴 수 있는 거죠. 실제로 써보니까 이 방식이 사고 범위를 줄이는 데 확실히 도움이 됐습니다.

    2-3. 인증(Authentication)과 인가(Authorization)

    인증은 “누구냐”를 확인하는 것이고, 인가는 “무엇을 할 수 있느냐”를 정하는 겁니다. SSH 키 로그인, 비밀번호, MFA(Multi-Factor Authentication, 다중 인증) 같은 건 인증 쪽이고, sudoers 설정은 인가 쪽에 가깝습니다.

    2-4. 관련 파일

    파일 역할 실무 포인트
    /etc/passwd 사용자 기본 정보 로그인 셸, 홈 디렉터리 확인
    /etc/shadow 비밀번호 해시 저장 권한 제한 필수
    /etc/group 그룹 정보 권한 설계 시 자주 확인
    /etc/sudoers sudo 정책 직접 수정 시 반드시 visudo 사용
    /etc/sudoers.d/ sudo 분리 설정 서버 역할별 관리에 유리

    사실 Linux 계정 관리에서 제일 중요한 건 명령어를 많이 아는 것보다, 정책을 일관되게 가져가는 것입니다. 같은 팀인데 서버마다 sudo 정책이 다르면, 그게 더 큰 장애 포인트가 되더라고요.

    3. 실전 구현: 계정 생성부터 그룹 설계까지

    제가 홈랩에서 가장 많이 쓰는 방식은 “개인 사용자 계정 + 역할 그룹 + 필요한 sudo만 부여” 구조입니다. 아래 예시는 Debian/Ubuntu 계열에서도 이해하기 쉽고, 다른 배포판에서도 거의 같은 개념으로 적용됩니다.

    1. 관리용 그룹을 먼저 만듭니다.
    2. 사용자 계정을 생성하고 홈 디렉터리를 함께 준비합니다.
    3. 필요한 그룹에 사용자를 추가합니다.
    4. SSH 키 인증을 붙입니다.
    5. 마지막으로 sudo 정책을 분리 파일로 관리합니다.

    3-1. 사용자 생성

    sudo adduser minsu
    sudo passwd minsu
    id minsu
    getent passwd minsu

    adduser는 대화형으로 홈 디렉터리와 기본 설정을 함께 잡아줘서 초반엔 편합니다. 반대로 자동화가 필요할 때는 useradd를 더 자주 쓰게 되더라고요.

    3-2. 그룹 기반으로 권한 묶기

    sudo groupadd ops
    sudo usermod -aG ops minsu
    id minsu
    getent group ops

    여기서 -aG 옵션을 빼먹으면 기존 보조 그룹이 날아갈 수 있습니다. 저 이거 한 번 놓쳐서 기존 접근 권한이 꼬인 적이 있었는데요. 드디어 됐다 싶었는데, 다른 작업 권한이 사라져 있더라고요. 그 뒤로는 id 사용자명으로 바로 검증하는 습관을 붙였습니다.

    Linux 사용자 관리와 sudo 권한 설정 흐름을 보여주는 이미지

    사용자 생성, 그룹 추가, sudoers.d 정책 분리까지 이어지는 실전 구성 흐름을 보여주는 이미지입니다.

    3-3. SSH 디렉터리와 권한 정리

    sudo mkdir -p /home/minsu/.ssh
    sudo chmod 700 /home/minsu/.ssh
    sudo touch /home/minsu/.ssh/authorized_keys
    sudo chmod 600 /home/minsu/.ssh/authorized_keys
    sudo chown -R minsu:minsu /home/minsu/.ssh

    SSH 키 로그인은 보안 측면에서 거의 기본값처럼 가져가는 게 좋습니다. 특히 외부에서 접속하는 서버라면 비밀번호 로그인만 믿고 가는 건 꽤 불안하거든요. 혹시 이런 경험 있으신가요? 키는 넣었는데 접속이 안 돼서 한참 헤매는 경우요. 대부분은 파일 권한이나 소유권 문제였습니다.

    4. sudo 권한 설정: 편하게 쓰되 넓게 주지는 않기

    sudo 권한은 편리하지만, 잘못 주면 사실상 루트와 다를 게 없어집니다. 그래서 저는 요즘 /etc/sudoers를 직접 건드리기보다 /etc/sudoers.d/ 아래에 역할별 파일을 나눠서 관리합니다. 이게 나중에 보기 훨씬 좋고, 변경 이력 추적도 편하더라고요.

    4-1. visudo로 안전하게 편집

    sudo visudo -f /etc/sudoers.d/ops

    예시 파일은 이렇게 구성할 수 있습니다.

    %ops ALL=(ALL:ALL) ALL

    이 설정은 ops 그룹 사용자에게 모든 명령에 대한 sudo 실행 권한을 주는 거거든요. 홈랩이나 소규모 환경에선 현실적인 출발점이긴 한데, 실제 운영에서는 더 좁히는 게 좋습니다.

    4-2. 특정 명령만 허용하는 방식

    Cmnd_Alias SERVICE_MGMT = /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx
    %ops ALL=(root) SERVICE_MGMT

    처음엔 이런 세분화가 좀 귀찮았습니다. 근데 실제로 써보니까 “누구나 뭐든지 sudo 가능” 상태보다 훨씬 안정적이더라고요. 특히 여러 사람이 함께 관리하는 환경에서는 이 차이가 큽니다. 쉽게 말해, sudo는 켜고 끄는 스위치가 아니라 정교하게 나눠야 하는 운영 정책에 가깝습니다.

    4-3. 비밀번호 요구 정책도 점검

    Defaults logfile=/var/log/sudo.log
    Defaults lecture=once

    서버마다 필요는 다르겠지만, 누가 어떤 sudo 명령을 썼는지 남기고 싶다면 로그 정책도 함께 보는 게 좋습니다. 나중에 문제 생겼을 때 이 로그가 꽤 유용합니다. 이거 진짜 편하더라고요.

    5. 계정 관리 운영 팁: 1년 써보니 결국 정리 습관이 남습니다

    계정 관리는 만들 때보다 치울 때 실력이 드러납니다. 테스트 계정, 임시 외주 계정, 스크립트용 서비스 계정(service account, 서비스 전용 계정)이 뒤섞이기 시작하면 금방 지저분해집니다. 제가 1년 동안 정리하면서 체감한 운영 팁은 아래와 같습니다.

    • 개인 계정과 서비스 계정을 섞지 않습니다.
    • 공용 계정을 최소화합니다. 가능하면 개인 계정 기반으로 갑니다.
    • sudo 권한은 그룹 단위로 관리합니다.
    • 서버 접속 방식은 SSH 키 중심으로 통일합니다.
    • 퇴역 계정은 잠금(lock) 후 일정 기간 뒤 삭제하는 식으로 단계적으로 정리합니다.

    5-1. 계정 잠금과 만료 처리

    sudo passwd -l minsu
    sudo usermod -L minsu
    sudo chage -l minsu

    즉시 삭제보다 잠금부터 거는 이유는, 혹시 남아 있는 프로세스나 파일 소유권 이슈를 확인할 시간이 필요해서입니다. 처음엔 저도 바로 삭제했었는데, 나중에 cron(Cron, 예약 작업)이나 백업 스크립트에서 참조 중인 경우가 있더라고요.

    5-2. 정말 삭제할 때

    sudo userdel -r minsu

    단, -r 옵션은 홈 디렉터리까지 지우기 때문에 신중해야 합니다. 여기서 중요한 포인트! 삭제 전에 파일 소유권 검색은 꼭 한 번 해보세요.

    sudo find / -user minsu 2>/dev/null | head

    6. ⚠️ 실제로 많이 겪는 문제와 해결법

    이 섹션은 정말 경험담 위주입니다. 제가 직접 해보니, Linux 사용자 관리에서 막히는 포인트는 대체로 비슷했습니다.

    6-1. sudo가 안 되는 경우

    원인은 보통 세 가지였습니다.

    1. 사용자가 올바른 그룹에 들어가 있지 않음
    2. /etc/sudoers.d/ 파일 권한이나 문법 오류
    3. 새 그룹 적용 전에 세션 재로그인 안 함
    id minsu
    sudo visudo -c
    ls -l /etc/sudoers.d/
    newgrp ops

    visudo -c로 문법 검사를 먼저 해보면 생각보다 빨리 원인을 찾습니다. 저도 sudoers 문법 한 글자 잘못 넣고 한참 헤맨 적이 있었는데, 그때 깨달았습니다. sudo 설정은 “될 것 같은데 안 되는” 상태가 제일 사람 지치게 하더라고요.

    6-2. SSH 키는 맞는데 로그인 실패

    대부분은 권한 문제였습니다.

    • ~/.ssh 권한이 너무 넓음
    • authorized_keys 소유자가 다름
    • 홈 디렉터리 권한이 과하게 열려 있음

    이럴 때는 계정만 보지 말고 상위 디렉터리까지 같이 확인해야 합니다.

    6-3. 사용자 삭제 후 파일 찌꺼기 남음

    이건 생각보다 흔합니다. 파일 서버나 백업 경로에 예전 UID(User ID, 사용자 식별자) 소유 파일이 남아 있으면 나중에 권한 꼬임으로 이어질 수 있습니다. 삭제 전에 파일 검색, 삭제 후 UID 재사용 주의, 이 두 개는 꼭 기억해두면 좋습니다.

    Linux 사용자 관리 트러블슈팅과 sudo 권한 점검 장면 이미지

    sudo 문법 검사, 그룹 확인, SSH 권한 점검 같은 트러블슈팅 과정을 터미널 시점으로 보여주는 이미지입니다.

    7. 검증과 결과 확인: 설정은 했고, 이제 믿어도 되나?

    설정이 끝났다고 바로 안심하면 안 됩니다. 저는 마지막 검증 단계를 따로 두는 편입니다. 왜냐하면 계정과 권한은 “지금 된다”보다 “다음 로그인에서도 일관되게 된다”가 더 중요하거든요.

    7-1. 기본 검증 명령

    id minsu
    getent passwd minsu
    getent group ops
    sudo -l -U minsu
    su - minsu
    whoami
    sudo whoami

    여기서 기대 결과는 명확합니다. 일반 로그인 시에는 사용자 본인, sudo 실행 시에는 root가 나와야 합니다. 그리고 sudo -l -U 사용자명으로 허용된 명령 범위를 눈으로 확인하는 습관이 좋습니다.

    7-2. 운영 기준 체크리스트

    • 루트 직접 SSH 로그인 비활성화 여부 확인
    • 불필요한 계정 잠금 또는 삭제 완료
    • sudo 정책이 그룹 단위로 분리되어 있는지 확인
    • SSH 키 권한과 소유권 점검
    • 계정 생성/변경/삭제 절차를 문서화했는지 확인

    이렇게 정리하고 나니, 서버를 새로 추가해도 기준이 흔들리지 않았습니다. 예전에는 서버마다 계정 상태가 제각각이었는데, 지금은 최소한 “어디를 보면 되는지”가 정해져 있으니 정신이 훨씬 덜 없더라고요.

    Linux 사용자 관리 검증 결과와 체크리스트를 보여주는 이미지

    계정 상태, 그룹 소속, sudo 허용 범위, SSH 점검 항목을 한눈에 확인하는 검증 결과 이미지입니다.

    8. 정리와 다음 단계: Linux 사용자 관리, 결국 기본기가 다 합니다

    이번 글을 한 줄로 정리하면 이겁니다. Linux 사용자 관리는 명령어 몇 개 외우는 일이 아니라, 운영 기준을 만들고 지키는 습관입니다. 제가 1년 동안 계속 다듬어보니 가장 효과가 컸던 건 세 가지였습니다. 일반 사용자 계정으로 작업하기, sudo 권한을 그룹과 정책 파일로 분리하기, 그리고 계정 생애주기(lifecycle, 생성부터 삭제까지)를 끝까지 챙기기. 사실 화려한 기술은 아니지만, 이런 기본기가 서버 안정성을 꽤 오래 받쳐줍니다.

    다음 단계로는 PAM(Pluggable Authentication Modules, 인증 모듈) 정책, SSH 하드닝(hardening, 보안 강화), 그리고 중앙 인증까지 확장해보면 좋습니다. 이전 글에서 다뤘던 SSH 키 운영 방법이 있다면 같이 묶어보셔도 좋고, 다음 글에서는 sudo 로그와 감사(audit, 추적 기록) 중심으로 더 깊게 다뤄볼 예정입니다.

    자주 묻는 질문

    1. 루트 계정을 완전히 안 써도 되나요?
      완전히 안 쓴다기보다, 평소 작업은 일반 계정 + sudo로 돌리고 루트 직접 로그인 빈도를 최소화하는 쪽이 안전했습니다.
    2. sudo 권한은 사용자별로 주는 게 좋나요?
      짧게는 가능하지만, 운영이 길어질수록 그룹 기반 관리가 훨씬 덜 헷갈렸습니다.
    3. 계정 삭제 전에 꼭 확인할 건 뭔가요?
      파일 소유권, 예약 작업, SSH 키, 서비스 참조 여부입니다. 삭제보다 잠금부터 거는 방식이 실무에서 덜 위험했습니다.

    사용자, 그룹, sudo 권한, SSH 보안, 계정 정리 원칙을 한 장으로 요약한 마무리 인포그래픽입니다.

    결국 Linux 운영에서 사고를 줄이는 가장 현실적인 방법은, 계정과 권한부터 차분히 정리하는 겁니다. 화려하진 않지만 효과는 확실합니다. 저도 처음엔 이게 뭔가 싶었는데, 계속 손에 익히고 나니 서버 운영의 체력이 여기서 나온다는 걸 알겠더라고요.

  • [Linux] cgroup vs namespace: 컨테이너 격리의 핵심 비교 분석

    [Linux] cgroup vs namespace: 컨테이너 격리의 핵심 비교 분석

    [리눅스 커널] cgroup vs namespace: 컨테이너 격리 핵심 비교

    컨테이너 기술을 조금만 깊게 파보면 결국 cgroup vs namespace 이야기로 귀결되더라고요. 저도 처음 Docker를 쓸 때는 그냥 “컨테이너는 가볍고 빠르다” 정도로만 이해했었는데, 실제로 장애를 따라가다 보니 왜 어떤 프로세스는 CPU를 독식하고, 왜 어떤 프로세스는 다른 프로세스 목록을 못 보는지 여기서 갈리더라고요. 쉽게 말해 namespace(네임스페이스, 리소스를 보이는 범위로 분리)는 “무엇을 볼 수 있느냐”를 나누고, cgroup(컨트롤 그룹, 자원 사용량을 제어하는 기능)은 “얼마나 쓸 수 있느냐”를 관리합니다. 이 차이를 이해하면 컨테이너 기술, 격리, 리눅스 커널의 구조가 한 번에 정리됩니다.

    실제로 홈랩에서 테스트 환경을 만들다가, 프로세스는 잘 분리됐는데 메모리 제한이 안 먹어서 삽질 좀 했습니다 ㅎㅎ 그때 확실히 느꼈어요. 컨테이너 격리는 한 가지 기능으로 되는 게 아니라, 여러 커널 기능을 조합해서 만들어지는 거였거든요.

    cgroup vs namespace 기반 컨테이너 격리 구조를 보여주는 리눅스 커널 아키텍처 이미지

    namespace와 cgroup이 각각 어떤 역할로 컨테이너 격리를 만드는지 보여주는 개요 이미지입니다.

    1. 왜 cgroup과 namespace를 같이 봐야 할까요?

    여기서 중요한 게 있어요. 많은 분들이 컨테이너를 “가벼운 VM”처럼 이해하시는데, 엄밀히 보면 다릅니다. VM은 하이퍼바이저 위에 게스트 OS가 따로 올라가고, 컨테이너는 호스트의 리눅스 커널을 공유합니다. 그러니 격리도 커널 기능에 의존할 수밖에 없죠.

    • namespace: 프로세스가 보는 세계를 분리합니다.
    • cgroup: 프로세스가 쓰는 자원을 제어합니다.
    • capabilities(리눅스 권한 비트 분리), seccomp(시스템 콜 필터링), LSM 계열 기능은 추가 보안 계층으로 붙습니다.

    즉, 컨테이너 기술에서 격리는 한 방에 끝나는 개념이 아니라 층층이 쌓이는 구조예요. 저도 처음엔 namespace만 알면 다 되는 줄 알았는데, 운영 환경에서는 cgroup 쪽을 훨씬 자주 보게 되더라고요. 특히 CPU 폭주나 메모리 OOM(Out Of Memory) 이슈는 거의 cgroup 쪽에서 원인을 찾게 됩니다.

    2. namespace(네임스페이스) 쉽게 이해하기

    쉽게 말해 namespace는 “같은 커널 위에 있지만 서로 다른 방에 들어가 있는 상태”를 만드는 기능입니다. 같은 호스트인데도 프로세스마다 보이는 PID, 네트워크 인터페이스, 마운트 포인트가 달라질 수 있어요.

    대표적인 namespace 종류

    • PID namespace: 프로세스 번호 공간을 분리합니다.
    • NET namespace: 네트워크 인터페이스, 라우팅 테이블, 포트를 분리합니다.
    • MNT namespace: 마운트 지점을 분리합니다.
    • UTS namespace: 호스트명, 도메인명 같은 시스템 식별 정보를 분리합니다.
    • IPC namespace: 프로세스 간 통신 자원을 분리합니다.
    • USER namespace: 사용자와 그룹 ID 매핑을 분리합니다.

    예를 들어 PID namespace 안에서는 프로세스가 자기 자신을 PID 1로 볼 수도 있어요. 컨테이너 안에서 <code>ps를 쳤을 때 호스트 전체 프로세스가 안 보이는 이유가 바로 이겁니다. 실제로 써보니까 이 개념 하나만 이해해도 “왜 컨테이너 안에서는 세상이 작아 보이는지”가 확 들어오더라고요.

    3. cgroup(컨트롤 그룹)은 뭐가 다를까요?

    namespace가 시야를 나눈다면, cgroup은 행동 한도를 정합니다. CPU를 얼마나 쓸지, 메모리를 얼마나 먹을지, I/O를 어느 정도까지 허용할지를 관리하는 쪽이죠. 그래서 cgroup은 격리라기보다 제어와 회계(accounting) 관점이 훨씬 강합니다.

    운영에서 흔히 보는 상황이 이거예요. 애플리케이션 하나가 메모리를 계속 먹습니다. namespace만 있으면 자기 공간 안에서만 보일 뿐이지, 호스트 메모리는 그대로 압박할 수 있거든요. 반대로 cgroup으로 제한을 걸어두면 그 프로세스 그룹은 정해진 범위를 넘기기 어려워집니다. 장애 대응할 때 이 차이가 꽤 크더라고요.

    항목 namespace cgroup
    주요 목적 리소스 가시성 분리 자원 사용량 제어 및 계측
    핵심 질문 무엇을 볼 수 있나? 얼마나 쓸 수 있나?
    예시 다른 PID/네트워크를 못 봄 CPU, 메모리 사용량 제한
    영향 범위 프로세스 관점의 논리적 격리 호스트 자원 배분 정책
    컨테이너에서의 역할 독립된 환경처럼 보이게 함 과도한 자원 사용을 막음

    한 줄 정리: namespace만 있으면 “따로 있는 것처럼 보이는 상태”이고, cgroup까지 있어야 “민폐를 덜 끼치는 상태”가 돼요. 이거 진짜 중요합니다.

    4. 실전 구현: namespace부터 직접 확인해보겠습니다

    제가 직접 해보니 추상 개념으로만 볼 때보다 unshare로 눈으로 확인하는 게 훨씬 빠르더라고요. 아래 예시는 리눅스에서 새로운 UTS, PID, mount namespace를 만들어보는 흐름입니다.

    1. 현재 호스트 이름과 프로세스 상태를 확인합니다.
    2. unshare로 새 namespace를 만듭니다.
    3. 새 환경 안에서 hostname과 프로세스 목록이 어떻게 달라지는지 봅니다.
    hostname
    ps -ef | head
    
    sudo unshare --uts --pid --mount --fork bash
    
    hostname container-lab
    mount -t proc proc /proc
    ps -ef
    hostname

    여기서 --fork를 주는 이유는 새 PID namespace 안에서 새 프로세스를 시작하기 위해서예요. 그리고 mount -t proc proc /proc를 안 하면 ps 출력이 기대와 다를 수 있거든요. 저도 처음엔 이걸 빼먹어서 “왜 분리 안 됐지?” 하고 한참 봤었습니다.

    cgroup vs namespace 실습 중 namespace 분리 셸 구성을 표현한 이미지

    namespace 실습 흐름과 분리된 셸 진입 과정을 보여주는 이미지입니다.

    현재 시스템의 namespace 확인

    lsns

    lsns를 보면 현재 시스템에 어떤 namespace가 잡혀 있는지 확인할 수 있어요. 컨테이너 런타임이 떠 있는 서버에서는 생각보다 다양한 namespace가 보이더라고요.

    5. 실전 구현: cgroup으로 자원 제한 걸어보기

    이제 cgroup입니다. 최근 리눅스 배포판은 보통 cgroup v2 기준으로 보는 게 편해요. 시스템마다 마운트 구조가 조금 다를 수는 있지만, 기본 개념은 비슷합니다. CPU와 메모리 제한을 설정할 수 있고, 프로세스를 특정 cgroup 디렉터리 아래로 넣어 관리하죠.

    mount | grep cgroup
    cat /sys/fs/cgroup/cgroup.controllers
    
    sudo mkdir /sys/fs/cgroup/demo-limit
    echo $$ | sudo tee /sys/fs/cgroup/demo-limit/cgroup.procs

    위처럼 현재 셸을 특정 cgroup에 넣을 수 있어요. 다만 실제 제한을 적용하려면 컨트롤러 활성화와 권한 구조를 이해해야 해서, 운영 서버에서는 systemd 기반 도구를 쓰는 편이 안전합니다.

    systemd-run으로 메모리 제한 테스트

    systemd-run --user --scope -p MemoryMax=200M -p CPUQuota=50% bash
    
    cat /sys/fs/cgroup/$(systemctl --user show --property=ControlGroup --value)/memory.max

    환경에 따라 사용자 세션에서 안 될 수도 있어요. 그런 경우는 시스템 범위에서 실행하거나 테스트 VM에서 보는 쪽이 낫습니다. 핵심은 cgroup이 프로세스를 안 보이게 만드는 기능이 아니라, 자원 사용 정책을 강제하는 기능이라는 점이에요.

    Docker로 보면 훨씬 익숙해요.

    docker run --rm -it --memory=256m --cpus=1 alpine sh
    
    cat /sys/fs/cgroup/memory.max 2>/dev/null || true
    cat /sys/fs/cgroup/cpu.max 2>/dev/null || true

    컨테이너 런타임은 이런 옵션을 받아 내부적으로 cgroup 설정과 namespace 구성을 함께 처리해요. 우리가 편하게 docker run 한 줄로 쓰는 뒤에서 리눅스 커널이 꽤 많은 일을 하는 셈이죠.

    6. cgroup vs namespace 비교를 실무 관점에서 정리해보면

    혹시 이런 경험 있으신가요? 컨테이너는 분명 분리돼 있는데, 한 컨테이너가 CPU를 잡아먹어서 같은 노드의 다른 워크로드까지 느려지는 상황 말이에요. 이럴 때 namespace를 아무리 잘 나눠도 해결이 안 됩니다. 반대로 cgroup만 있고 namespace가 약하면 프로세스 시야가 너무 넓어서 격리 체감이 떨어져요.

    • namespace가 강한 상황: 프로세스, 네트워크, 파일시스템 관점에서 독립된 환경처럼 보입니다.
    • cgroup이 강한 상황: noisy neighbor(시끄러운 이웃, 자원 독식 워크로드) 문제를 줄이기 좋습니다.
    • 둘 다 필요: 컨테이너 기술에서 실용적인 격리는 대부분 둘의 조합이에요.

    제가 홈랩 쿠버네티스 환경을 만질 때도 결국 보는 건 두 가지였어요. “이 파드는 무엇을 볼 수 있지?” 그리고 “이 파드는 얼마나 먹지?” 질문이 딱 namespace와 cgroup으로 나뉘더라고요.

    7. ⚠️ 주의사항과 트러블슈팅

    여기서부터는 제가 실제로 많이 헷갈렸던 부분입니다. 처음엔 개념보다 환경 차이 때문에 더 막히더라고요.

    1) ps 결과가 기대와 다를 때

    PID namespace를 만들었는데도 프로세스가 그대로 보이는 경우가 있어요. 보통 /proc를 새로 마운트하지 않아서 그렇습니다.

    mount -t proc proc /proc

    2) cgroup 디렉터리는 있는데 제한이 안 걸릴 때

    cgroup v1과 v2 차이, systemd 관리 방식, 권한 문제 때문일 수 있어요. 특히 배포판마다 기본 구성이 다르니 무작정 예전 블로그 예제를 복붙하면 안 맞는 경우가 있습니다. 저도 예전 자료 따라 했다가 파일 이름이 달라서 한참 헤맸습니다.

    3) 컨테이너 보안과 자원 제어를 같은 문제로 보면 꼬여요

    이건 실무에서 꽤 중요한 부분이에요.

    • namespace는 보이는 범위를 줄이는 쪽입니다.
    • cgroup은 성능 안정성과 자원 관리 쪽입니다.
    • seccomp, AppArmor, SELinux 같은 보안 계층은 또 별개입니다.

    즉, 보안 사고를 막는 이야기와 리소스 폭주를 막는 이야기를 한 덩어리로 보면 판단이 흐려집니다.

    4) USER namespace는 특히 신중하게 봐야 해요

    USER namespace는 루트 권한 매핑 문제와 연결되기 때문에 환경에 따라 정책 차이가 커요. 실습은 가능하지만, 운영 서버에서는 배포판 기본 정책과 런타임 설정을 반드시 같이 봐야 합니다.

    cgroup vs namespace 비교 중 cgroup v2 자원 제어 구조를 설명하는 이미지

    cgroup v2 구조와 자원 제한이 적용되는 핵심 지점을 시각화한 이미지입니다.

    8. 검증과 결과 확인

    설정은 했는데 실제로 격리가 됐는지 확인을 안 하면 의미가 없죠. 저는 보통 아래처럼 확인합니다.

    1. namespace 분리 여부 확인
    2. cgroup 제한 값 확인
    3. 실제 워크로드를 넣어 동작 확인
    lsns
    
    cat /proc/self/cgroup
    
    cat /sys/fs/cgroup/cpu.max 2>/dev/null || true
    cat /sys/fs/cgroup/memory.max 2>/dev/null || true

    Docker 환경이라면 다음도 자주 봐요.

    docker inspect <container_id>
    docker stats

    검증 포인트는 단순합니다.

    • 프로세스 목록이 호스트와 다르게 보이는가?
    • 호스트명이나 네트워크 인터페이스가 분리되어 보이는가?
    • 메모리/CPU 제한이 파일 시스템이나 런타임 정보에 반영되는가?
    • 부하를 줬을 때 제한 정책이 실제로 동작하는가?

    실제로 써보니까, 격리는 “설정했다”보다 “증명했다”가 더 중요하더라고요. 특히 장애 분석 문서 남길 때 이 확인 단계가 있어야 나중에 팀원과 같은 그림을 볼 수 있어요.

    cgroup vs namespace 검증 결과를 운영 화면처럼 보여주는 이미지

    격리 검증 결과를 확인하는 장면을 담은 이미지입니다.

    9. 정리: 컨테이너 기술에서 둘 중 뭐가 더 중요할까요?

    제 답은 늘 같습니다. 둘 중 하나가 아니라 둘 다예요. namespace는 컨테이너를 컨테이너답게 보이게 만들고, cgroup은 컨테이너를 운영 가능한 상태로 만들어줍니다. 하나는 시야를 분리하고, 다른 하나는 자원을 통제하죠.

    질문 봐야 할 기능 실무 해석
    왜 다른 프로세스가 안 보일까? namespace 격리된 실행 환경
    왜 메모리가 256MB 이상 못 올라갈까? cgroup 자원 제한 정책
    왜 한 컨테이너가 노드 전체를 먹지 못할까? cgroup 멀티테넌시 안정성
    왜 컨테이너 안 hostname이 다를까? namespace 독립된 시스템처럼 보이기

    저도 처음엔 cgroup vs namespace를 경쟁 관계처럼 외웠었는데, 실제로는 역할 분담에 더 가깝거든요. 그래서 컨테이너 기술을 공부할 때는 둘을 따로 암기하기보다, 하나의 워크로드가 커널 위에서 어떻게 분리되고 제한되는지 흐름으로 보는 게 훨씬 이해가 잘 됩니다.

    다음 글에서는 seccomp(시스템 콜 필터링)와 capabilities(권한 비트 세분화)까지 이어서, 왜 “컨테이너는 격리되지만 완전한 보안 경계로 보면 안 된다”는 말이 나오는지 다뤄볼 예정입니다. 이전 글에서 다룬 Docker 기본 구조와 함께 보시면 더 잘 연결되실 겁니다.

    cgroup vs namespace 차이를 한눈에 정리한 비교 인포그래픽 이미지

    cgroup과 namespace의 핵심 차이를 요약한 비교 인포그래픽 이미지입니다.

    자주 묻는 질문(FAQ)

    Q1. namespace만 있으면 컨테이너가 완성되나요?

    아니에요. namespace만으로는 자원 제한이 부족합니다. 실무에서는 cgroup, capabilities, seccomp 같은 요소가 함께 들어갑니다.

    Q2. cgroup은 보안 기능인가요?

    주된 목적은 자원 제어와 계측이에요. 보안에 간접적으로 도움이 될 수는 있지만, 보안 격리 그 자체로 보기엔 부족합니다.

    Q3. 리눅스 커널을 공유하면 위험하지 않나요?

    맞아요. 그래서 컨테이너는 VM과 다른 보안 모델을 가져요. 격리 수준과 운영 목적을 구분해서 설계해야 합니다.

    Q4. 쿠버네티스에서도 결국 같은 원리인가요?

    네, 상위 오케스트레이션이 붙어도 아래에서는 리눅스 커널의 namespace와 cgroup 같은 기능을 활용합니다.

  • [NAS 파일 시스템] Btrfs, 데이터 무결성을 위한 현명한 선택일까?

    [NAS 파일 시스템] Btrfs, 데이터 무결성을 위한 현명한 선택일까?

    [NAS 파일 시스템] Btrfs, 데이터 무결성을 위한 현명한 선택일까?

    안녕하세요, 13년차 서버실 지킴이입니다. 오늘은 NAS를 운영하시는 분들이라면 한 번쯤 고민해봐야 할 주제, 바로 Btrfs 파일 시스템에 대해 얘기해보려고 합니다. 저도 처음엔 ZFS(Zettabyte File System)만 최고인 줄 알았거든요. 근데 홈랩에서 다양한 파일 시스템을 직접 써보고 삽질도 좀 해보면서, Btrfs가 NAS 환경에서 얼마나 매력적인 선택지가 될 수 있는지 깨달았습니다. 특히 데이터 무결성(Data Integrity)을 중요하게 생각하신다면, 오늘 제 경험담이 도움이 될 거예요.

    소중한 데이터, 한순간의 실수나 하드웨어 오류로 날아가면 정말 끔찍하잖아요? 저도 예전에 백업 없이 중요한 자료를 날려본 경험이 있어서, 그때부터는 파일 시스템 선택에 정말 신중해졌습니다. Btrfs는 이런 걱정을 덜어줄 수 있는 강력한 기능들을 제공하더라고요. 과연 Btrfs가 여러분의 NAS 데이터를 안전하게 지켜줄 수 있을지, 함께 파헤쳐 봅시다!

    Btrfs 파일 시스템의 Copy-on-Write(CoW) 및 스냅샷 작동 방식 개념도

    Btrfs 파일 시스템의 Copy-on-Write(CoW) 및 스냅샷 작동 방식 개념도

    Btrfs, 너는 누구냐? 핵심 기능 파헤치기

    Btrfs는 ‘B-tree file system’의 약자로, 오라클에서 개발을 시작한 차세대 파일 시스템입니다. 리눅스 환경에서 널리 사용되고 있죠. 사실 처음엔 이게 뭔가 싶었는데, 몇 가지 핵심 기능들을 알고 나니 “이거 진짜 물건이더라고요!” 하는 생각이 들었습니다. 특히 NAS에 적용했을 때 빛을 발하는 기능들이 많더라고요.

    1. Copy-on-Write (CoW, 카피 온 라이트)

    이름 그대로 ‘쓸 때 복사한다’는 의미입니다. 기존 데이터를 변경할 때, 해당 데이터를 덮어쓰지 않고 새로운 위치에 변경된 데이터를 쓴 다음, 메타데이터(Metadata)만 업데이트하는 방식이죠. 이게 왜 중요하냐면요?

    • 데이터 손상 방지: 전원이 갑자기 나가거나 시스템에 문제가 생겨도, 작업 중이던 데이터는 손상될지언정 기존 데이터는 온전히 보존됩니다.
    • 스냅샷의 기반: 이 CoW 덕분에 스냅샷(Snapshot) 기능이 아주 효율적으로 작동합니다.

    사실 CoW 방식은 ZFS에서도 볼 수 있는 강력한 기능인데, Btrfs도 이걸 아주 잘 활용하고 있더라고요.

    2. 스냅샷 (Snapshot)

    스냅샷은 특정 시점의 파일 시스템 상태를 저장하는 기능입니다. 마치 게임에서 세이브 포인트를 만드는 것과 같아요. Btrfs의 스냅샷은 CoW 덕분에 용량을 거의 차지하지 않는다는 게 정말 큰 장점입니다. 변경된 블록만 저장하면 되니까요.

    • 실수로 파일 삭제/수정: 걱정 마세요! 스냅샷으로 쉽게 특정 시점으로 되돌릴 수 있어요.
    • 랜섬웨어 공격: 이것 때문에 저도 Btrfs를 더 신뢰하게 됐는데요, 만약 랜섬웨어에 감염되더라도 감염되기 전 스냅샷으로 복원하면 피해를 최소화할 수 있습니다. 정말 든든하죠!

    3. 데이터 무결성 (Data Integrity)을 위한 체크섬 (Checksum)

    Btrfs는 데이터 블록과 메타데이터 블록에 각각 체크섬을 적용합니다. 데이터를 읽을 때마다 체크섬을 확인해서, 혹시라도 데이터가 손상(Bit Rot, 비트 로트)되었는지 검사하죠. 만약 손상된 부분을 발견하면, RAID 1이나 RAID 10처럼 미러링된 구성에서는 자동으로 손상되지 않은 사본으로 복구해버립니다. 이게 바로 자가 복구(Self-Healing) 능력입니다.

    제가 실제로 써보니까, 이런 기능들이 작은 홈랩 NAS부터 기업용 스토리지까지 데이터의 신뢰성을 크게 높여주더라고요. 처음엔 “굳이 이렇게까지 해야 하나?” 싶었는데, 한 번 데이터를 잃고 나면 생각이 확 달라집니다.

    NAS에서 Btrfs 실전 활용: 어떻게 적용할까?

    많은 NAS 제조사들이 Btrfs를 채택하고 있습니다. 특히 Synology(시놀로지) 같은 경우 Btrfs를 적극적으로 활용해서 스냅샷, 데이터 무결성 기능을 사용자에게 제공하고 있죠. 하지만 직접 리눅스 서버에 NAS를 구축한다면, Btrfs를 직접 설정해야 합니다.

    1. Btrfs 파일 시스템 생성

    먼저 Btrfs로 포맷할 디스크를 준비해야 합니다. 저는 주로 여러 디스크를 묶어서 사용하는데요, Btrfs는 자체적으로 소프트웨어 RAID 기능을 제공합니다. (물론 안정성 측면에서는 하드웨어 RAID나 mdadm 위에 Btrfs를 쓰는 것도 고려할 수 있습니다.)

    # /dev/sdb, /dev/sdc 두 개의 디스크로 RAID1 Btrfs 파일 시스템 생성
    sudo mkfs.btrfs -d raid1 -m raid1 /dev/sdb /dev/sdc
    
    # 기존 디스크를 Btrfs 풀에 추가할 경우
    sudo btrfs device add /dev/sdd /mnt/btrfs_pool
    sudo btrfs balance start -dusage=50 /mnt/btrfs_pool # 데이터 분배

    이렇게 생성된 Btrfs 볼륨을 원하는 마운트 포인트에 마운트하면 됩니다.

    2. 서브볼륨 (Subvolume) 생성 및 관리

    Btrfs의 서브볼륨은 일반적인 디렉토리와 비슷하지만, 독립적인 스냅샷을 찍거나 할당량(Quota)을 설정할 수 있는 등 더 강력한 기능을 제공합니다. 저는 보통 용도별로 서브볼륨을 나눠서 사용해요. 예를 들어, ‘Documents’, ‘Media’, ‘Backup‘ 이런 식으로요.

    sudo mount /dev/sdb /mnt/btrfs_pool
    
    # 'data'라는 서브볼륨 생성
    sudo btrfs subvolume create /mnt/btrfs_pool/data
    
    # 'data' 서브볼륨을 /srv/nas에 마운트 (fstab에도 등록하여 부팅 시 자동 마운트)
    sudo mount -o subvol=data /dev/sdb /srv/nas

    3. 스냅샷 생성 및 관리

    이제 서브볼륨에 데이터를 저장하고, 주기적으로 스냅샷을 찍어줍니다. 스냅샷은 읽기 전용(Read-Only)으로 생성하는 것이 일반적입니다.

    # 'data' 서브볼륨의 스냅샷 생성
    sudo btrfs subvolume snapshot -r /srv/nas /srv/nas/.snapshots/data_$(date +%Y%m%d_%H%M%S)
    
    # 생성된 스냅샷 목록 확인
    sudo btrfs subvolume list -t -o /mnt/btrfs_pool

    스냅샷을 자동으로 찍어주는 스크립트나 서비스(예: <code>btrfs-autosnap, snapper)를 활용하면 훨씬 편리하게 관리할 수 있어요. 저도 처음엔 수동으로 찍다가, 나중엔 스크립트 걸어놓고 마음 편하게 쓰고 있습니다.

    Btrfs 파일 시스템을 활용한 NAS 구성 개념도

    Btrfs 파일 시스템을 활용한 NAS 구성 개념도

    ⚠️ 주의사항 및 트러블슈팅: 제가 겪었던 삽질들

    Btrfs가 만능은 아닙니다. 제가 직접 써보면서 몇 가지 주의할 점과 삽질 경험을 공유해 드릴게요.

    1. 성능 오버헤드 (Performance Overhead)

    Copy-on-Write 방식은 데이터 무결성을 높여주지만, 쓰기(Write) 작업 시 약간의 성능 저하가 발생할 수 있습니다. 특히 랜덤 쓰기(Random Write)가 많은 환경에서는 체감될 수 있어요. 처음엔 “왜 이렇게 느리지?” 싶었는데, 알고 보니 CoW 때문이더라고요. 그래서 고성능이 최우선인 환경보다는 데이터 안정성이 중요한 환경에 더 적합하다고 생각합니다.

    2. 디스크 공간 관리 (Disk Space Management)

    스냅샷은 공간을 효율적으로 사용하지만, 너무 많은 스냅샷을 오랫동안 보관하면 결국 디스크 공간을 많이 차지하게 됩니다. 특히 삭제된 파일이 스냅샷에 남아있다면 실제 공간은 회수되지 않거든요. 주기적으로 오래된 스냅샷을 삭제해주는 정책이 필요해요.

    # 오래된 스냅샷 삭제 예시 (가장 최신 스냅샷 10개만 남기고 삭제)
    # 실제 사용 시에는 신중하게 접근해야 합니다.
    LATEST_SNAPSHOTS=$(sudo btrfs subvolume list -t -o /mnt/btrfs_pool | grep 'snapshots' | sort -r | head -n 10 | awk '{print $9}')
    ALL_SNAPSHOTS=$(sudo btrfs subvolume list -t -o /mnt/btrfs_pool | grep 'snapshots' | awk '{print $9}')
    
    for SNAPSHOT in $ALL_SNAPSHOTS; do
        IS_LATEST=false
        for LATEST in $LATEST_SNAPSHOTS; do
            if [ "$SNAPSHOT" == "$LATEST" ]; then
                IS_LATEST=true
                break
            fi
        done
        if ! $IS_LATEST; then
            echo "Deleting old snapshot: $SNAPSHOT"
            sudo btrfs subvolume delete "$SNAPSHOT"
        fi
    done

    ⚠️ 경고: 스냅샷 삭제는 신중하게! 복구 불가능합니다.

    3. RAID 기능의 성숙도

    Btrfs는 자체 RAID0, RAID1, RAID5, RAID6 기능을 제공해요. 하지만 RAID5/6의 경우 초기에는 안정성 문제가 보고되기도 했습니다. 지금은 많이 개선되었지만, 아직까지는 mdadm RAID1 위에 Btrfs를 사용하거나, RAID10을 선호하는 경우가 많습니다. 저도 안정성을 위해 RAID10을 주로 사용하거나, 디스크 두 개만 쓰는 NAS에는 Btrfs RAID1을 쓰는 편입니다.

    ✅ 검증 및 결과: 내 데이터는 안전한가?

    Btrfs를 설정하고 나면, 데이터가 정말 안전하게 관리되고 있는지 확인해야겠죠? 저는 주기적으로 btrfs scrub 명령어를 실행해서 파일 시스템의 데이터 무결성을 검사합니다. 이 명령은 모든 데이터와 메타데이터 블록의 체크섬을 확인하고, 손상된 부분이 있으면 자동으로 복구해줍니다.

    # Btrfs 파일 시스템 스크럽 시작
    sudo btrfs scrub start /mnt/btrfs_pool
    
    # 스크럽 진행 상황 확인
    sudo btrfs scrub status /mnt/btrfs_pool

    스크럽이 완료되면 “드디어 됐다!” 하는 안도감이 들어요. 이 기능을 통해서 디스크 자체의 물리적인 오류나 비트 로트 현상으로부터 데이터를 보호할 수 있습니다. NAS를 며칠씩 켜놓는 저에게는 정말 필수적인 기능이라고 생각해요.

    Btrfs scrub 및 스냅샷 목록 확인 터미널 출력 화면

    Btrfs scrub 및 스냅샷 목록 확인 터미널 출력 화면

    마무리: Btrfs, NAS 데이터 무결성을 위한 현명한 선택일까?

    결론부터 말씀드리자면, Btrfs는 NAS 환경에서 데이터 무결성과 관리 유연성을 크게 향상시켜 줄 수 있는 현명한 선택지가 될 수 있습니다. 특히 스냅샷 기능은 랜섬웨어 방어나 실수로 인한 데이터 손실 복구에 엄청난 강점을 보여주거든요. CoW 기반의 효율적인 공간 활용도 정말 매력적입니다.

    하지만 성능 오버헤드나 RAID 기능의 성숙도 등 고려해야 할 부분도 분명히 있습니다. 완벽한 파일 시스템은 없으니까요. 여러분의 NAS 사용 목적과 중요도에 따라 Btrfs가 최적의 선택이 될 수도, 아닐 수도 있겠죠. 저처럼 홈랩에서 다양한 시도를 해보면서 자신에게 맞는 최적의 조합을 찾아가는 과정 자체가 인프라 엔지니어의 숙명 아닐까요? ㅎㅎ

    다음 글에서는 Btrfs와 ZFS를 좀 더 심층적으로 비교해보는 시간을 가져볼까 합니다. 혹시 Btrfs를 사용하면서 겪었던 재미있는 삽질 경험이 있으시다면 댓글로 공유해주세요! 저도 배우는 재미가 쏠쏠하거든요. 긴 글 읽어주셔서 감사합니다!

    Btrfs 파일 시스템의 NAS 적용 장단점 인포그래픽 요약

    Btrfs 파일 시스템의 NAS 적용 장단점 인포그래픽 요약