Ansible를 활용한 MySQL 및 Apache 자동 배포와 HTTP 응답 코드 분석

Ansible Playbook을 통한 MySQL 이진 방식 설치

다음은 Ansible을 사용하여 리눅스 환경에 MySQL 5.7.33을 이진 파일로 배포하는 실습 예제이다. 이 작업은 제어 노드에서 실행되며, 대상 호스트에 대해 일관된 방식으로 데이터베이스 서버를 설치하고 초기화한다.

[root@control ansible]# tree
.
├── ansible.cfg
├── files
│   ├── my.cnf
│   └── mysql-5.7.33-linux-glibc2.12-x86_64.tar.gz

my.cnf 설정 파일은 기본적인 MySQL 구성 요소를 포함하며, 데이터 디렉터리, 소켓 파일, 로그 경로 등을 지정한다:

[mysqld]
server-id=1
log-bin
datadir=/data/mysql
socket=/data/mysql/mysql.sock
log-error=/data/mysql/mysql.log
pid-file=/data/mysql/mysql.pid

[client]
socket=/data/mysql/mysql.sock

Playbook install_mysql.yml은 다음과 같은 단계를 수행한다:

  • 필요한 시스템 패키지 설치 (libaio, numactl-libs 등)
  • mysql 그룹과 사용자 생성
  • MySQL 이진 아카이브를 대상 서버에 복사 및 압축 해제
  • 심볼릭 링크 /usr/local/mysql 생성
  • 데이터 디렉터리 준비 및 권한 설정
  • 초기 데이터베이스 초기화 (mysqld --initialize)
  • 설정 파일 배포 및 서비스 스크립트 등록
  • 환경 변수 PATH 추가
  • 서비스 등록 및 시작
  • 임시 비밀번호 추출 후 루트 비밀번호 재설정
- name: Deploy MySQL 5.7.33 via binary
  hosts: test
  gather_facts: no
  vars:
    mysql_version: "5.7.33"
    archive_name: "mysql-{{mysql_version}}-linux-glibc2.12-x86_64.tar.gz"
    root_password: "securePass123"

  tasks:
    - name: Install required dependencies
      yum:
        name:
          - libaio
          - numactl-libs
          - MySQL-python
        state: present

    - name: Create mysql group
      group:
        name: mysql
        gid: 306

    - name: Create mysql user
      user:
        name: mysql
        uid: 306
        group: mysql
        shell: /sbin/nologin
        system: yes
        create_home: no
        home: /data/mysql

    - name: Extract MySQL binary package
      unarchive:
        src: "/data/ansible/files/{{archive_name}}"
        dest: /usr/local/
        remote_src: yes

    - name: Create symbolic link for mysql home
      file:
        src: "/usr/local/mysql-{{mysql_version}}-linux-glibc2.12-x86_64"
        dest: /usr/local/mysql
        state: link

    - name: Ensure data directory exists
      file:
        path: /data/mysql
        state: directory
        mode: '0755'
        owner: mysql
        group: mysql
        recurse: yes

    - name: Initialize MySQL data directory
      shell: |
        /usr/local/mysql/bin/mysqld --initialize --user=mysql --datadir=/data/mysql
      args:
        creates: /data/mysql/mysql.pid

    - name: Copy configuration file
      copy:
        src: files/my.cnf
        dest: /etc/my.cnf
        owner: root
        group: root
        mode: '0644'

    - name: Install service script
      shell: cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
      args:
        creates: /etc/init.d/mysqld

    - name: Add MySQL to system PATH
      copy:
        content: "export PATH=/usr/local/mysql/bin:\$PATH"
        dest: /etc/profile.d/mysql.sh
        mode: '0755'

    - name: Register and start mysqld service
      shell: chkconfig --add mysqld && service mysqld start
      args:
        creates: /var/lock/subsys/mysqld

    - name: Retrieve temporary root password
      shell: grep 'temporary password' /data/mysql/mysql.log | awk '{print $NF}'
      register: temp_pass
      changed_when: false

    - name: Change MySQL root password
      shell: |
        /usr/local/mysql/bin/mysqladmin -uroot -p"{{ temp_pass.stdout }}" password "{{ root_password }}"
      when: temp_pass.stdout != ""

Ansible Roles를 이용한 Apache 배포 및 동적 콘텐츠 제공

Apache 웹 서버를 여러 호스트에 자동으로 설치하고, 각 서버의 고유 IP 주소를 표시하는 인덱스 페이지를 제공하도록 구성할 수 있다. 이를 위해 Ansible Role 기반 구조를 사용한다.

ansible-galaxy init apache

Role의 주요 작업 정의:

# roles/apache/tasks/main.yml
- name: Install httpd package
  yum:
    name: httpd
    state: latest

- name: Start and enable Apache service
  service:
    name: httpd
    state: started
    enabled: yes

- name: Deploy index.html using template
  template:
    src: index.html.j2
    dest: /var/www/html/index.html
    mode: '0644'

Jinja2 템플릿을 통해 각 호스트의 네트워크 정보를 삽입:

{% raw %}{{ ansible_default_ipv4.address }}{% endraw %}

Playbook 실행:

# site.yml
- name: Configure web servers
  hosts: all
  roles:
    - apache

배포 후 검증:

ansible all -m shell -a "curl -s http://localhost"

결과적으로 각 서버는 자신의 IP 주소를 반환하며, 성공적으로 배포되었음을 확인할 수 있다.

HTTP 메시지 구조와 상태 코드 설명

HTTP 프로토콜은 클라이언트와 서버 간 통신을 위한 요청과 응답 메시지를 사용한다.

메시지 구성 요소

  • 요청 라인: 메서드(GET, POST 등), URI, HTTP 버전
  • 응답 라인: HTTP 버전, 상태 코드, 이유 구문
  • 헤더 필드: 메타데이터 (Content-Type, Location 등)
  • 엔터티 바디: 실제 전송되는 데이터 (HTML, JSON 등)

주요 HTTP 상태 코드

코드 의미
200 OK 요청 성공
301 Moved Permanently 리소스가 영구적으로 다른 위치로 이동함
302 Found 일시적인 리다이렉션
304 Not Modified 조건부 요청 시 변경 없음
401 Unauthorized 인증 필요
403 Forbidden 접근 거부
404 Not Found 요청한 리소스 없음
500 Internal Server Error 서버 내부 오류
502 Bad Gateway 게이트웨이가 백엔드에서 잘못된 응답 수신
503 Service Unavailable 서버 과부하 또는 유지보수 중
504 Gateway Timeout 게이트웨이 타임아웃 발생

태그: Ansible MySQL Apache HTTP Playbook

8월 1일 07:19에 게시됨