LabHub
배우기 러닝패스 코스

Ansible 기초 · 실패를 설계한다 · 실습

37대는 성공이라고 찍혔다 — 실패를 설계하기

LabHub 에서 이어서 보기

목표

한 대만 실패하게 만들어 놓은 호스트 셋짜리 인벤토리에서, 실패를 다루는 손잡이를 하나씩 켜 보고 그때마다 무엇이 멈추고 무엇이 계속 가는지를 표식 파일로 직접 확인합니다.

왜 중요한가

실패는 일어납니다. 설계해야 할 것은 실패를 없애는 일이 아니라 실패했을 때 무엇이 일어날지를 미리 정해 두는 일입니다. Ansible 의 기본값은 '실패한 호스트만 조용히 빠지고 나머지는 계속 간다' 인데, 서버를 한 대씩 독립적으로 고치는 일에는 좋은 기본값이고 40대가 한 서비스를 이루고 있다면 나쁜 기본값입니다. 그래서 이 실습은 세 가지 질문을 순서대로 다룹니다 — 이 실패는 진짜 실패인가(failed_when), 실패한 그 호스트는 어떻게 할 것인가(ignore_errors·block/rescue), 다른 호스트들은 어떻게 할 것인가(any_errors_fatal·max_fail_percentage). 여기에 시작하기 전에 막는 assert 와, 실패와는 다른 칸으로 세는 unreachable 이 더해지면 배포 리포트를 읽을 수 있게 됩니다. 마지막 단계에서 그 리포트를 직접 만듭니다.

단계

1. /root/ans/err/hosts.iniweb 그룹(web1, web2) · db 그룹(db1) · ghosts 그룹(ghost1)을 적으세요. 네 호스트 모두 ansible_host=127.0.0.1, ansible_user=root 이고 포트는 ghost12223, 나머지는 2222 입니다. 그리고 /root/ans/err/p01.ymlweb:db 에 도는 플레이를 만드세요 — 첫 태스크는 web2 에서만 실패하고, 둘째 태스크는 /root/ans/err/a1/reached-<호스트이름> 을 남깁니다. 실행 출력은 /root/ans/err/out/run1.txt 에 저장하세요.
2. /root/ans/err/p02.yml 을 1단계와 같은 구조로 만들되 실패하는 태스크에 ignore_errors 를 붙이고, 표식은 /root/ans/err/a2/reached-<호스트이름> 에 남기세요. 출력은 /root/ans/err/out/run2.txt 에 저장합니다. 이번에는 세 호스트 모두 표식이 남고 PLAY RECAPignored 칸이 올라가야 합니다.
3. /root/ans/err/sample.conflisten_port=8080 · env=prod · workers=4 세 줄로 만드세요. 그리고 /root/ans/err/p03.ymlweb1 에서 그 파일에 nosuchkey 가 몇 번 나오는지 세는 태스크를 만드세요 — 조회일 뿐이므로 변경으로 세지 않게 하고, 못 찾아서 나오는 종료 코드는 실패가 아니게 기준을 정하세요. 이어서 그 종료 코드를 /root/ans/err/a3/grep-rc.txt 에 한 줄로 남기고 출력은 /root/ans/err/out/run3.txt 에 저장하세요.
4. /root/ans/err/p04.ymlweb1 에 도는 플레이를 만드세요. block 안에 실패하는 태스크와 그 뒤에 /root/ans/err/a4/never.txt 를 만드는 태스크를 두고, rescue/root/ans/err/a4/rescued.txt실패한 태스크의 이름을 담고, always/root/ans/err/a4/always.txt 를 남기게 하세요. 출력은 /root/ans/err/out/run4.txt 에 저장합니다. never.txt 는 만들어지면 안 되고 PLAY RECAPrescued 가 1 이어야 합니다.
5. /root/ans/err/p05.ymllocalhost 에 도는 플레이로 만들되 assert 태스크 하나만 두세요. deploy_envdev·stage·prod 중 하나인지 검사하고, fail_msg허용되지 않은 배포 환경입니다 로 시작해 지금 값을 함께 보여 줘야 합니다. -e deploy_env=prod 로 돌린 출력을 /root/ans/err/out/assert-ok.txt 에, -e deploy_env=qa 로 돌린 출력을 /root/ans/err/out/assert-fail.txt 에 저장하세요.
6. /root/ans/err/p06.yml 을 1단계와 같은 구조로 만들되 플레이에 any_errors_fatal 을 켜고 표식은 /root/ans/err/a6/reached-<호스트이름> 에 남기게 하세요. 출력은 /root/ans/err/out/run6.txt 에 저장합니다. 이번에는 아무 호스트도 표식을 남기지 못해야 합니다.
7. /root/ans/err/p07.ymlweb:db 에 도는 플레이를 만드세요. max_fail_percentage50, 변수 run_tag 의 기본값은 continue, 변수 doomed 의 기본값은 web2 하나입니다. 첫 태스크가 /root/ans/err/a7/<run_tag> 디렉터리를 만들고, 다음 태스크가 doomed 에 든 호스트에서만 실패하고, 마지막 태스크가 /root/ans/err/a7/<run_tag>/reached-<호스트이름> 을 남깁니다. 기본값으로 한 번 돌려 /root/ans/err/out/run7-continue.txt 에, run_tagabort 로 두고 doomedweb2db1 을 넣어 한 번 더 돌려 /root/ans/err/out/run7-abort.txt 에 저장하세요.
8. /root/ans/err/p08.ymlall 에 도는 플레이로 만드세요 — 첫 태스크는 ping 이되 닿지 않는 것을 무시하고, 둘째 태스크는 /root/ans/err/a8/reached-<호스트이름> 을 남깁니다. 출력은 /root/ans/err/out/run8.txt 에 저장하세요. 그리고 실행 기록 파일 하나를 인자로 받아 hosts=N ok=N changed=N unreachable=N failed=N skipped=N rescued=N ignored=N 한 줄을 내는 /root/ans/err/recap.sh 를 쓰고, 그것으로 /root/ans/err/out/failure-report.json 을 만드세요. 키는 default_failed(1단계 실행의 failed 합) · ignored(2단계) · rescued(4단계) · unreachable(8단계) · fatal_reached(a6 의 표식 수) · maxfail_reached(a7/continue 의 표식 수) 여섯 개이고 값은 모두 숫자입니다.

참고

단계 8개

  1. 기본 동작 — 실패한 호스트만 빠진다
  2. 결과만 무시하면 무엇이 달라지나
  3. 무엇을 실패로 볼 것인가를 직접 정하기
  4. block·rescue·always 로 롤백을 구조로 만들기
  5. 전제가 어긋나면 아무것도 건드리기 전에 멈춘다
  6. 한 대라도 실패하면 전부 멈추게 하기
  7. 몇 대까지는 견딘다 — 비율로 정하기
  8. 닿지 않는 호스트와 여섯 번의 실행을 한 장으로