[DevOps] ansible nginx config 배포 구성

안녕하세요? 정리하는 개발자 워니즈입니다. 이번시간에는 ansible을 이용한 nginx config 파일의 배포에 대해서 정리해보도록 하겠습니다. 필자가 속한 프로젝트에서는 nginx를 Front-end의 export된 html 소스를 서빙하기 위한 용도로 사용하고 있습니다. nginx config의 설정 변경을 수행하고 배포시에는 별도의 사내 시스템을 사용하고 있었지만, 이는 scp를 통해서 직접 파일을 카피하고 전송하는 부분이였습니다.

이러한 부분을 좀더 수월하게 개선하기 위해서 필자는 ansible을 통하여 파일을 배포하고 배포된 파일이 정상인지 검증(validation)을 수행하고, 이후에 기동한 뒤 프로세스체크까지 하는 파이프라인구조로 변경을 하기로 했습니다.

Nginx에 관한 시리즈 포스팅은 아래에서 확인이 가능합니다.

1. nginx deploy with ansible

ansible_deploy_1

nginx의 config 파일 관리는 github에서 우선적으로 합니다. ansible은 별도 ansible server에서 설치하여 사용하며 ansible을 위한 별도의 git repository도 존재합니다. 흐름은 다음 플로우를 통해서 진행이 되며, ansible을 통해서 nginx config 파일을 배포하고 nginx를 기동합니다.

  • ansible에서 target되는 nginx config파일을 다운로드 받습니다.
  • nginx.conf 파일을 nginx의 binary를 통해서 검증(-t)를 수행합니다.
  • Nginx.conf 파일을 기반으로 restart를 수행합니다. (nginx config 파일을 갖고 기동합니다.)
  • Nginx의 프로세스(systemctl status)를 통해서 정상 기동되었는지 체크를 합니다.
  • 위의 과정을 serial하게 1대씩 진행을 합니다.

위와 같은 과정을 거쳐서 타겟팅 되는 nginx를 1대씩 배포를 수행하고(Rolling Update) 배포 완료시 알람을 발송합니다.

2. ansible folder 구조

Ansible의 git repository 구성에 대해서 정리를 해보도록 하겠습니다.

├── group_vars
│    └── test-web-nginx-prod.yml
├── nginx_deploy.yml
├── test-web-nginx-prod
└── roles
    ├── common
    │   ├── meta
    │   │   └── main.yml
    │   └── tasks
    │       └── main.yml
    └── nginx
        ├── meta
        │    └── main.yml
        ├── tasks
        │     └── main.yml
        └── templates
            └── index.html.j2
  • ansible inventory 작성은 배포그룹(ex. test-web-nginx-prod) 에 작성

inventory / test-web-nginx-prod

[test-web-nginx-prod]
test1501
test1502
test1503

[webservers:children]
test-web-nginx-prod

inventory / group_vars / test-web-nginx-prod.yml

phase: "prod"
application: "test-web-nginx"
index: true
maintenence: true
members: false
vosdomain: "test-objects.com"
vosbucket: "test-nft"

inventory에는 서버에 대한 정보 설정을 기입합니다. 그리고 관련하여 참조할 변수들을 group_vars 하위에 기입을 합니다.

3. ssh 접속을 위한 사전설정

ansible 서버에서 target 서버로 접속을 하기 위해서는 ssh 설정이 필요합니다. 별도의 비밀번호 없이 public key와 private key를 통해서 접근을 하기 위한 설정입니다.

키생성

$ ssh-keygen -t rsa
  1. 키를 저장할 경로( 기본값 : $HOME/.ssh/id_rsa)
  2. passphrase (추가로 사용할 암호, 기본값 없음)
  3. passphrase 확인

ssh key 등록하기

.pub이 공개키 인데 해당 공개키를 서버에 등록하면 다음부턴 비밀번호를 입력할 필요가 없어집니다.

$ mkdir ~/.ssh
$ touch ~/.ssh/authorized_keys
$ chmod 755 ~/.ssh/authorized_keys

Host의 ~/.ssh/id_rsa.pub 에 있는 모든 내용을 복사해서, 접속한 서버의 .ssh 폴더 내에 있는 authorized_keys 파일을 수정해 해당 내용을 모두 붙여 넣고 저장합니다.

이렇게 되면, ansible서버에서 target 서버로 접속이 비밀번호 없이 바로 할 수 있습니다.

4. jenkins 연계

Jenkins를 통해서 ansible playbook 명령어를 호출하여 target 서버에 nginx config를 배포하고 restart를 해주는 내용을 연계하려고 합니다.

jenkins의 파라미터로는 2가지로 선정을 했습니다. nginx가 FE의 서빙 역할을 하기 때문에 application 별로 있습니다.

따라서 application이라는 파라미터를 설정했고, 각 phase(alpha, beta, real) 순서로 파라미터를 설정했습니다.

  • applicatoin
  • phase

설정한 값에 맞춰서 ansible playbook 실행시, nginx-config 와 target 서버 목록을 셋팅합니다.

ansible 명령어

$ ansible-playbook -i ${WORKSPACE}/devops-nginx-deploy/inventory/${APPLICATION}-${PHASE} ${WORKSPACE}/devops-nginx-deploy/playbook/nginx_deploy.yml -u irteamsu

ansible roles

# roles/nginx/tasks/main.yml

---
# tasks file for nginx
#- name: install nginx
#  yum: name=nginx state=installed

- name: git clone
  git:
    repo: https://test:xxxxx@github.com/dongwonlee/test-web-nginx.git
    dest: /home1/test/apps/test-web-nginx/
    update: yes
    version: master

- name: copy nginx.config
  copy:
    src: /home1/test/apps/test-web-nginx/config/{{ application }}/nginx-{{ phase }}.conf
    dest: /etc/nginx/nginx.conf
    remote_src: yes

- name: Verify Nginx config
  command: nginx -t
  changed_when: false

- name: Download Index html
  get_url:
    url: https://{{ vosdomain }}/{{ vosbucket }}-{{ phase }}/index.html
    dest: /etc/nginx/index.html
    force: true
  when: index | bool

- name: Reload nginx config
  service: name=nginx state=reloaded enabled=yes

- name: check nginx status
  command: systemctl status nginx
  register: process
  failed_when: "'running' not in process.stdout"

ansible yaml 파일을 보면, 기존의 수동으로 하던 작업들을 일련의 작업으로 순서화를 시킨내용입니다.

  • git clone
  • verify nginx
  • download resource ( index.html )
  • reload nginx cofig
  • check nginx status

5. 테스트

기본적으로 ansible은 병렬 수행을 하는데, serial 수행으로 옵션을 줄 수 있습니다.

Playbook / nginx_deploy.yml

---
- hosts: webservers
  become: yes
  serial: 1
  roles:
    - nginx

위와 같이 serial: 1을 주게 되면, 1대씩 실행을 합니다. 아래 결과에서 보듯이 2대의 서버를 1대씩 진행하고 결과를 출력해주고 있습니다.

PLAY [webservers] **************************************************************

TASK [Gathering Facts] *********************************************************
ok: [test-web-nginx001-dev]

TASK [nginx : git clone] *******************************************************
ok: [test-web-nginx001-jp2v-dev]

TASK [copy nginx.config] *******************************************************
ok: [test-web-nginx001-dev]

TASK [nginx : Verify Nginx config] *********************************************
ok: [test-web-nginx001-dev]

TASK [nginx : Download Index html] *********************************************
changed: [test-web-nginx001-dev]

TASK [Reload nginx config] *****************************************************
changed: [test-web-nginx001-dev]

TASK [check nginx status] ******************************************************
changed: [test-web-nginx001-dev]

PLAY [webservers] **************************************************************

TASK [Gathering Facts] *********************************************************
ok: [test-web-nginx002-dev]

TASK [nginx : git clone] *******************************************************
ok: [test-web-nginx002-dev]

TASK [copy nginx.config] *******************************************************
ok: [test-web-nginx002-dev]

TASK [nginx : Verify Nginx config] *********************************************
ok: [test-web-nginx002-dev]

TASK [nginx : Download Index html] *********************************************
changed: [test-web-nginx002-dev]

TASK [Reload nginx config] *****************************************************
changed: [test-web-nginx002-dev]

TASK [check nginx status] ******************************************************
changed: [test-web-nginx002-dev]

PLAY RECAP *********************************************************************
test-web-nginx001-dev : ok=8    changed=3    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
test-web-nginx002-dev : ok=8    changed=3    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

6. 마치며

ansible은 여러대의 config 설정과 같이 다양한 환경에서 반복적이고 여러대의 작업에서 수행되는 작업을 할 때 굉장히 유용한것 같습니다. 본 포스팅은 사내의 시스템이 있었는데 설정도 배포도 상당히 어려움이 있어서 ansible을 통해서 간단하게 jenkins 연계를 통하여 nginx 설정 배포를 할 수 있도록 구성했습니다.

다음 시간에는 ansible을 실행하고 job들을 관리할 수 있는 ansible tower(AWX)에 대해서 정리해보고 적용해보는 시간을 갖도록 하겠습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다