일상 운영 시나리오
Ansible로 관리되는 서버에서 자 주 수행하는 작업들의 명령 모음입니다.
이 문서의 모든 명령은 <account>를 실제 계정명(예: self, customer-a)으로 바꿔서 실행합니다.
scripts/ansible-account.sh가 inventory, vault, roles_path를 계정별로 자동 주입하여 타 계정 사고를 방지합니다.
직접 ansible-playbook 호출은 디버깅 목적으로만 사용하고, 일상 운영은 wrapper를 통해 실행하세요.
시나리오 1: 신규 서버 추가
# 1. IaaS 대시보드/API에서 서버 생성 (Ubuntu 24.04, SSH 키 등록) — Vultr/DigitalOcean/Linode 등
# 2. Inventory에 추가 (해당 계정 폴더의 hosts.ini)
cat >> workspace/_infra/ansible-accounts/<account>/inventory/hosts.ini << 'EOF'
[app_servers]
msk-app-new ansible_host=64.176.xx.xx
EOF
# 3. Bootstrap (최초 1회, root로 접속)
cd workspace/_infra
scripts/ansible-account.sh <account> bootstrap --limit msk-app-new -u root
# 4. 표준 셋업 (deploy로)
scripts/ansible-account.sh <account> site --limit msk-app-new
# 5. 역할별 배포
scripts/ansible-account.sh <account> app --limit msk-app-new
소요 시간: 약 10~15분
시나리오 2: 전체 서버 보안 패치
# apt 보안 업데이트 (unattended-upgrades가 자동 실행하지만 수동 트리거)
ansible all -m apt -a "upgrade=safe update_cache=yes" --become
# 재부팅이 필요한 서버만 재부팅 (rolling)
ansible all -m reboot --become --serial 1 \
--extra-vars "reboot_timeout=300"
주의: 운영 중 서버는 --serial 1로 한 대씩 재부팅하여 다운타임 최소화.
시나리오 3: 특정 역할만 재설정
# NPM 서버들만 재구성
ansible-playbook playbooks/npm.yml --limit npm_servers
# 모든 서버의 Tailscale role만 재실행
ansible-playbook playbooks/site.yml --tags tailscale
# 특정 서버 + 특정 role
ansible-playbook playbooks/site.yml --limit msk-app-quant --tags docker
시 나리오 4: 서버 장애 후 재구축
# 1. IaaS에서 동일 스펙 새 서버 생성 (동일 or 다른 IaaS)
# 2. Inventory의 해당 호스트 IP만 업데이트
vim workspace/_infra/ansible/inventory/hosts.ini
# 3. Bootstrap + site.yml 재실행
ansible-playbook -u root playbooks/bootstrap.yml --limit msk-app-quant --ask-vault-pass
ansible-playbook -u deploy playbooks/site.yml --limit msk-app-quant
# 4. 데이터 복원 (DB 덤프, 볼륨 백업 등 — 별도 백업 절차)
ansible-playbook playbooks/restore-from-backup.yml --limit msk-app-quant \
--extra-vars "backup_date=2026-04-17"
서버 자체는 10분 이내 재구축 → 데이터 복원 시간이 전체 RTO 결정 요인.
시나리오 5: 환경변수 변경
# group_vars 또는 vault 수정
ansible-vault edit vault/secrets.yml
# 영향 받는 서비스만 재배포 (NPM 예시)
ansible-playbook playbooks/npm.yml --limit npm_servers --tags config
많은 role이 notify: restart service 패턴을 써서 config 변경 시 자동 재시작.
시나리오 6: Ad-hoc 명령
모든 서버의 디스크 사용량 확인
ansible all -m shell -a "df -h /"
특정 프로세스 상태
ansible app_servers -m shell -a "docker ps --format '{{.Names}}: {{.Status}}'"
긴급 파일 배포
ansible all -m copy -a "src=./hotfix.sh dest=/tmp/hotfix.sh mode=0755"
ansible all -m shell -a "/tmp/hotfix.sh"
시나리오 7: Tailscale ACL 재적용
# Tailscale Admin Console에서 ACL 변경 후
# 각 서버에서 tag 재등록 필요할 때
ansible all -m command -a "tailscale up --authkey={{ tailscale_authkey }} --advertise-tags=tag:app" --become
시나리오 8: Docker 컨테이너 재시작 (롤링)
# 한 대씩 순차 재시작 (무중단 배포)
ansible-playbook playbooks/app.yml \
--limit app_servers \
--tags deploy \
--serial 1
운영 베스트 프랙티스
1. --check 드라이런 습관화
# 실제 변경 전 항상 드라이런
ansible-playbook playbooks/site.yml --check --diff
2. --limit으로 범위 좁히기
# 전체 대신 특정 서버만
ansible-playbook playbooks/site.yml --limit msk-app-quant
전체 서버 대상 실수를 방지.
3. 태그 기반 실행
# 전체 role 중 특정 태그만
ansible-playbook playbooks/site.yml --tags docker,tailscale
4. 멱등성 검증
동일 Playbook을 2번 실행해서 changed=0이 나오는지 확인.
ansible-playbook playbooks/site.yml # 1회차: changed=X
ansible-playbook playbooks/site.yml # 2회차: changed=0 이어야 정상
5. Git 커밋 주기
| 변경 | 커밋 시점 |
|---|---|
| Inventory 변경 | 즉시 |
| Role 수정 | 테스트 후 |
| Vault 수정 | 신중히 (비밀 평문 커밋 금지 — 암호화 상태로만) |
| Playbook 추가 | 리뷰 후 |
6. CI/CD 통합 (Phase 4 이후)
GitHub Actions에서 PR 머지 시 자동 실행:
# .github/workflows/ansible-deploy.yml (향후)
on:
push:
branches: [main]
paths: ['workspace/_infra/ansible/**']
jobs:
deploy:
runs-on: ubuntu-latest
defaults:
run:
working-directory: workspace/_infra/ansible
steps:
- uses: actions/checkout@v4
- run: ansible-playbook playbooks/site.yml
env:
ANSIBLE_VAULT_PASSWORD_FILE: /tmp/vault-pass
트러블슈팅
NPM/Docker 컨테이너가 재부팅 후 안 뜸 (부팅 순서 race)
증상: 서버 재부팅(예: unattended kernel update 후 자동재부팅) 뒤 NPM 등 프록시가 안 뜨고, 프록시 대상 사이트 전체가 ERR_CONNECTION_TIMED_OUT. 컨테이너가 Exited (128), 또는 healthy인데도 외부 도달 불가.
원인: Docker 게시 포트를 동적 인터페이스 IP(Tailscale/VPN/VIP) 에 바인딩한 경우, 재부팅 시 dockerd가 tailscaled보다 먼저 기동 → 그 IP가 아직 없어 바인딩 실패(cannot assign requested address) → 컨테이너 전체 미기동(기동 단계 실패라 restart 정책이 재시도하지 않음, RestartCount=0).
즉시 복구:
# docker start 만으론 포트 publishing이 복원 안 될 수 있음 → recreate
cd /path/to/compose && docker compose up -d --force-recreate
재발 방지 (common role):
# 해당 호스트 host_vars
ip_nonlocal_bind_enabled: true # net.ipv4.ip_nonlocal_bind=1
인터페이스 IP가 늦게 올라와도 바인딩이 성공하고, IP가 할당되면 자동으로 연결됩니다.
연관 정책: 자동재부팅은 IaC로 관리하고 기본 notify+manual(또는 새벽)로 둡니다(hardening role). 핵심 서비스 헬스 알림은 분 단위(*/5)로 설정하고 컨테이너 health뿐 아니라 외부 도달성도 확인합니다(service_health_notify).
Playbook 실행 중 SSH 타임아웃
# ansible.cfg에 timeout 추가
[defaults]
timeout = 30
ERROR! Unable to parse inventory
# 문법 확인
ansible-inventory -i inventory/hosts.ini --list
ansible-vault 비밀번호 잃어버림
복구 불가. 새 vault 생성 + 모든 secret 재등록.
→ 예방: 1Password/Bitwarden에 비밀번호 별도 보관
특정 task만 재실행
# --start-at-task로 특정 task부터 시작
ansible-playbook playbooks/site.yml --start-at-task="Install Docker"
자주 쓰는 명령 치트시트
# 인벤토리 확인
ansible-inventory --list
# 호스트 ping
ansible all -m ping
# facts 수집
ansible msk-app-01 -m setup
# 특정 변수만 출력
ansible msk-app-01 -m debug -a "var=ansible_memtotal_mb"
# 파일 내용 확인
ansible app_servers -m shell -a "cat /etc/os-release"
# 서비스 상태
ansible all -m systemd -a "name=docker state=started" --become
시나리오 N: 저사양 호스트 swap 압력 완화 (호스트 튜닝)
저사양 머신(예: P330 mini PC, 8~16GB RAM)에서 multi-saas-kit + 모니터링 + 다수의 컨테이너를 동시에 운영하면 메모리 압박 시 swap thrashing이 발생해 sshd/tmux가 멎거나 서버 응답이 사라지는 일이 생깁니다. 커널 sysctl 4개 값 조정만으로 큰 효과를 얻을 수 있습니다.
증상
free -h에서 swap 사용량이 RAM 대비 비정상적으로 높음 (예: RAM 23GB 중 5GB가 swap)uptimeload average가 CPU 코어 수에 근접하거나 초과- tmux/ssh 입력이 수 초씩 지연되거나 freeze
- 디스크 LED가 거의 항상 켜져 있음 (I/O 대기)
권장 sysctl 값
# /etc/sysctl.d/99-ai-tuning.conf (또는 99-host-tuning.conf)
vm.swappiness = 10 # 기본 60. 메모리 여유 있을 때 swap 회피
vm.vfs_cache_pressure = 50 # 기본 100. dentry/inode 캐시 회수 약화
vm.dirty_background_ratio = 5 # 대량 쓰기 시 stall 완화
vm.dirty_ratio = 15
⚠️
vm.swappiness=0은 OOM 직전까지 swap을 회피하므로 권장하지 않습니다. 10이 안전한 권장값.
적용
# 1) 파일 작성 (sudo 필요)
sudo install -m 0644 sysctl-host-tuning.conf /etc/sysctl.d/99-host-tuning.conf
# 2) 즉시 적용
sudo sysctl --system
# 3) 확인
sysctl vm.swappiness vm.vfs_cache_pressure vm.dirty_background_ratio vm.dirty_ratio
multi-saas-kit 리포에는 이 값을 포함한 sysctl-ai-tuning.conf 원본과 자동 적용 make 타겟이 포함되어 있습니다. 자세한 사용법은 Makefile / tune-system 절을 참조하세요.
관찰 포인트
적용 후 24~48시간 동안 다음 항목 추이 비교:
free -hSwap used (감소해야 정상)uptimeload average (감소 또는 평탄화)- tmux freeze/sshd 응답 지연 재발 여부
보안 점검 체크리스트
주기적으로 (매월) 확인:
- SSH root 로그인 차단 유지 (
grep PermitRootLogin /etc/ssh/sshd_config) - fail2ban 활성 (
systemctl is-active fail2ban) - UFW 정책 예상과 일치 (
ufw status numbered) - unattended-upgrades 정상 동작 (
/var/log/unattended-upgrades/) - 불필요 패키지/포트 없음
- Tailscale 세션 정상 (
tailscale status) - Ansible vault 백업 존재
# 한 번에 확인하는 audit playbook
ansible-playbook playbooks/audit.yml