LabHub
배우기 러닝패스 코스

Ansible実戦

バッチに分けロードバランサへ委譲して無停止で上げる

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

호스트 집합을 배치로 쪼개고, 배포 중인 서버를 로드밸런서에서 빼고 넣고, 배치마다 상태를 판정해 사고가 다음 배치로 번지지 않게 하는 플레이북을 쓸 수 있게 됩니다.

왜 중요한가

기본 동작에서 Ansible 은 태스크 하나를 전 호스트에서 끝내고 다음 태스크로 갑니다. 서비스를 재시작하는 태스크가 있으면 그 순간 전 호스트가 함께 내려갑니다. 그래서 무중단 배포는 도구가 아니라 플레이북의 구조로 만듭니다. 쪼개고(serial), 빼고 넣고(delegate_to), 배치마다 판정합니다(max_fail_percentage). 이 중 하나만 빠져도 무중단이 아닙니다 - 빼지 않으면 요청이 배포 중인 서버로 들어가고, 판정하지 않으면 망가진 판이 남은 서버로 번집니다. 그리고 serial 을 걸면 run_once 와 핸들러의 의미까지 조용히 바뀝니다. 그 사실을 모르고 쓰면 '한 번만 돌 줄 알았던 태스크' 가 배치 수만큼 돕니다.

단계

  1. /root/ans/roll/inventory/hosts.ini 에 web 그룹(web1·web2·web3, ansible_host=127.0.0.1, ansible_port=2222)과 lb 그룹(lb1, ansible_connection=local)을 적으세요. /root/ans/roll/p01.ymlserial: 2 를 걸고, 호스트마다 자기 배치의 구성원을 쉼표로 이어 /root/ans/roll/out/01-<호스트>.txt 에 적게 하세요.
  2. /root/ans/roll/p02.ymlserial 을 목록 [1, 100%] 로 주어 카나리 배치를 만들고, 1단계와 같은 방식으로 /root/ans/roll/out/02-<호스트>.txt 에 배치 구성원을 적으세요.
  3. /root/ans/roll/p03.ymlserial: 2 를 걸고, run_once: truedelegate_to: lb1 을 붙인 태스크 하나로 /root/ans/roll/out/03-runonce.txtbatch <배치구성원> ran on <실행한호스트> 형식의 줄을 남기세요.
  4. /root/ans/roll/p04.ymlserial: 1 로 만들고, 모든 태스크를 lb1 로 위임/root/ans/roll/out/lb/ 디렉터리를 만든 뒤 호스트마다 drained-<호스트>.txtenabled-<호스트>.txt 를 각각 host=<호스트> 내용으로 남기세요.
  5. /root/ans/roll/p05.yml 에서 delegate_to: lb1delegate_facts: true 를 함께 준 set_factlb_pool_size 를 플레이 대상 수로 세우고, 그 값을 hostvars 로 읽어 /root/ans/roll/out/05-lbfact.txtlb_pool_size=<값> on_web=<웹 호스트에서 본 값> 형식으로 남기세요. 웹 호스트 쪽에는 값이 없어야 합니다.
  6. /root/ans/roll/p06.ymlserial: 2 로 만들고, 호스트마다 /root/ans/roll/out/06-<호스트>.conf 를 놓는 태스크가 핸들러를 부르게 하세요. 핸들러는 run_once: truedelegate_to: lb1/root/ans/roll/out/06-handlers.txtrestarted: <배치구성원> 줄을 남깁니다.
  7. /root/ans/roll/p07.ymlserial: 1 · max_fail_percentage: 0 으로 만들고, 플레이 varshealthy_hosts[web1, web3] 으로 두세요. 태스크는 /root/ans/roll/out/07-deployed-<호스트>.txt 를 남기는 배포 표식과 healthy_hosts 에 들어 있는지를 보는 assert 확인 둘입니다. 실행 출력을 /root/ans/roll/out/07-run.txt 로 저장하세요.
  8. /root/ans/roll/p08.yml 에 플레이 둘을 두세요. 첫 플레이는 web 을 serial: [1, 100%] · max_fail_percentage: 0 으로 돌며 배치 기록을 /root/ans/roll/out/08-batches.txt 에 남기고, 호스트마다 /root/ans/roll/out/08/ 아래에 drained-·release-(내용 release=2.4.0enabled- 표식을 남기고 그 사이에 assert 로 상태를 확인합니다(세 대 모두 정상). 둘째 플레이는 lb1 에서 그 기록을 모아 /root/ans/roll/out/rolling.jsonbatches·drained·enabled 를 적습니다. 마지막으로 같은 플레이북을 한 번 더 돌려 출력을 /root/ans/roll/out/08-run2.txt 에 저장하되 changed=0 이어야 합니다.

참고

두 대씩 끊어 올리기

/root/ans/roll/inventory/hosts.ini 에 web 그룹(web1·web2·web3, ansible_host=127.0.0.1, ansible_port=2222)과 lb 그룹(lb1, ansible_connection=local)을 적으세요. /root/ans/roll/p01.ymlserial: 2 를 걸고, 호스트마다 자기 배치의 구성원을 쉼표로 이어 /root/ans/roll/out/01-<호스트>.txt 에 적게 하세요.

지금 배치에 누가 들어와 있는지는 실행 중에 변수로 알 수 있습니다. ansible_play_batch 를 쉼표로 이어 적으면 배치가 어떻게 나뉘었는지가 파일에 남습니다.

카나리 한 대 먼저, 나머지 한 번에

/root/ans/roll/p02.ymlserial 을 목록 [1, 100%] 로 주어 카나리 배치를 만들고, 1단계와 같은 방식으로 /root/ans/roll/out/02-<호스트>.txt 에 배치 구성원을 적으세요.

목록의 원소는 숫자와 비율을 섞어 쓸 수 있습니다. 마지막 원소를 100% 로 두면 '남은 전부' 라는 뜻이 됩니다.

run_once 는 배치마다 한 번이다

/root/ans/roll/p03.ymlserial: 2 를 걸고, run_once: truedelegate_to: lb1 을 붙인 태스크 하나로 /root/ans/roll/out/03-runonce.txtbatch <배치구성원> ran on <실행한호스트> 형식의 줄을 남기세요.

같은 줄을 여러 번 돌려도 파일이 늘어나지 않아야 합니다. 줄 단위로 '없으면 넣는' 모듈을 쓰세요. 몇 줄이 나오는지 세어 보면 run_once 의 범위가 드러납니다.

로드밸런서에서 빼고 다시 넣기

/root/ans/roll/p04.ymlserial: 1 로 만들고, 모든 태스크를 lb1 로 위임/root/ans/roll/out/lb/ 디렉터리를 만든 뒤 호스트마다 drained-<호스트>.txtenabled-<호스트>.txt 를 각각 host=<호스트> 내용으로 남기세요.

위임된 태스크 안에서도 대상은 원래 호스트입니다. 파일 이름과 내용에 그 이름을 그대로 쓰면 '누구를 뺐는지' 가 로드밸런서 쪽 기록에 남습니다. 이 단계에서는 배치마다가 아니라 호스트마다 일어나야 합니다.

사실을 누구 앞으로 적을 것인가

/root/ans/roll/p05.yml 에서 delegate_to: lb1delegate_facts: true 를 함께 준 set_factlb_pool_size 를 플레이 대상 수로 세우고, 그 값을 hostvars 로 읽어 /root/ans/roll/out/05-lbfact.txtlb_pool_size=<값> on_web=<웹 호스트에서 본 값> 형식으로 남기세요. 웹 호스트 쪽에는 값이 없어야 합니다.

플레이 대상 수는 실행 중에 변수로 알 수 있습니다. 웹 호스트 쪽에서 같은 이름을 읽을 때는 없을 수도 있으니 기본값을 주어 없음 이 찍히게 하세요.

핸들러는 플레이 끝이 아니라 배치 끝에 돈다

/root/ans/roll/p06.ymlserial: 2 로 만들고, 호스트마다 /root/ans/roll/out/06-<호스트>.conf 를 놓는 태스크가 핸들러를 부르게 하세요. 핸들러는 run_once: truedelegate_to: lb1/root/ans/roll/out/06-handlers.txtrestarted: <배치구성원> 줄을 남깁니다.

핸들러는 이름으로 이어집니다. 몇 줄이 남는지 세어 보면 핸들러가 언제 도는지 알 수 있습니다 - 플레이 끝에 한 번이라면 한 줄이어야 합니다.

한 대가 무너지면 거기서 멈춘다

/root/ans/roll/p07.ymlserial: 1 · max_fail_percentage: 0 으로 만들고, 플레이 varshealthy_hosts[web1, web3] 으로 두세요. 태스크는 /root/ans/roll/out/07-deployed-<호스트>.txt 를 남기는 배포 표식과 healthy_hosts 에 들어 있는지를 보는 assert 확인 둘입니다. 실행 출력을 /root/ans/roll/out/07-run.txt 로 저장하세요.

이 플레이북은 일부러 실패합니다. 출력을 파일로 받을 때 실패로 스크립트가 멈추지 않게 하세요. 세 번째 호스트의 배포 표식이 생기는지 아닌지가 이 단계의 답입니다.

한 바퀴를 돌고 요약을 남긴다

/root/ans/roll/p08.yml 에 플레이 둘을 두세요. 첫 플레이는 web 을 serial: [1, 100%] · max_fail_percentage: 0 으로 돌며 배치 기록을 /root/ans/roll/out/08-batches.txt 에 남기고, 호스트마다 /root/ans/roll/out/08/ 아래에 drained-·release-(내용 release=2.4.0enabled- 표식을 남기고 그 사이에 assert 로 상태를 확인합니다(세 대 모두 정상). 둘째 플레이는 lb1 에서 그 기록을 모아 /root/ans/roll/out/rolling.jsonbatches·drained·enabled 를 적습니다. 마지막으로 같은 플레이북을 한 번 더 돌려 출력을 /root/ans/roll/out/08-run2.txt 에 저장하되 changed=0 이어야 합니다.

빼기와 넣기는 로드밸런서에 위임하고 배포는 대상에서 합니다. 표식을 세는 것은 파일을 찾는 모듈로, 배치 기록을 읽는 것은 파일을 읽어 오는 모듈로 하면 두 번째 플레이가 짧아집니다. 두 번째 실행이 조용하려면 모든 태스크가 멱등해야 합니다.