Automation / Orchestration

주요 특징

  • 에이전트 설치 불필요
  • 간단한 YAML 기반 구성
  • 서버, 네트워크, 클라우드 인프라 자동화

———————————————————————————————————————————

  • Rocky 9.4
    • master / 192.168.0.50
    • node1 / 192.168.0.51
    • node2 / 192.168.0.52

———————————————————————————————————————————

  • master 서버가 ansible 관리 서버
    • ansible 설치
  • node 서버 관리를 위하여 ssh 키 교환

———————————————————————————————————————————

master 서버에서 앤서블 설치

  • ansible 관리 서버에서 ssh 키 설정
    • 관리 서버에서 node1, node2로 비밀번호 없이 SSH 접속이 가능해야 한다.
ssh-keygen -t rsa
# 기본 /root/.ssh/ 에 설정
# 주의 할점은 이미 키가 있는데 재생성 할경우 기존 데이터는 사라지니 확인하고 실행하도록

vim /root/.ssh/id_rsa.pub 
# 해당 파일안의 내용을 복사하여 node1, node2  /root/.ssh/authorized_keys 에 복사

vim /root/.ssh/authorized_keys
# master 서버에 있던 id_rsa.pub 키 값을 node1, node2 서버 authorized_keys에 복사

패스워드 없이 자동 접속이 되는지 확인
  • 시스템 업데이트
dnf -y update
  • EPEL 저장소 추가
dnf -y install epel-release
  • ansible 설치
dnf -y install ansible
  • 버전 확인
ansible --version
  • 인벤토리 설정
    • 관리할 서버의 목록을 인벤토리 파일에 기록하여 사용
    • 기본적으로 /etc/ansible/hosts/ 파일을 사용 하지만, 별도의 인벤토리 파일을 만들어 사용할 수도 있다.
/etc/ansible/hosts  # 인벤토리 설정


[node_servers]
192.168.0.51
192.168.0.52
  • ansible ping 모듈로 서버 확인
    • ansible이 서버에 정상적으로 접속할 수 있는지 확인하려면 ping 모듈을 사용
ansible all -m ping
  • playbook 작성
    • 플레이북은 YAML 파일로 작성되며, 여러 서버에서 실행할 작업을 정의
vim /etc/ansible/nginx_mysql_docker.yml 
  • 플레이북 작성
    • 플레이북 내용: node1, node2 서버에 nginx 설치, port 81 변경, mysql 설치, docker 설치 후에 image apache 설치, port 82 변경, firealld 중지 및 비활성화 설정
[root@master ansible]# cat nginx_mysql_docker.yml
---
- hosts: node_servers
  become: yes
  tasks:

    # 1. Install Nginx
    - name: Install Nginx
      dnf:
        name: nginx
        state: present

    # 2. Configure Nginx to use port 81
    - name: Change Nginx to listen on port 81
      lineinfile:
        path: /etc/nginx/nginx.conf
        regexp: 'listen       80;'
        line: 'listen       81;'
        state: present
      notify:
        - restart nginx

    # 3. Start and enable Nginx
    - name: Ensure Nginx is running and enabled
      systemd:
        name: nginx
        state: started
        enabled: yes

    # 4. Install MySQL
    - name: Install MySQL
      dnf:
        name: mariadb-server
        state: present

    # 5. Start and enable MySQL
    - name: Ensure MySQL is running and enabled
      systemd:
        name: mariadb
        state: started
        enabled: yes

    # 6. Install Docker
    - name: Install Docker
      dnf:
        name: docker
        state: present

    # 7. Start and enable Docker
    - name: Ensure Docker is running and enabled
      systemd:
        name: docker
        state: started
        enabled: yes

    # 8. Pull Apache Docker image
    - name: Pull Apache Docker image
      docker_image:
        name: httpd
        source: pull

    # 9. Run Apache Docker container on port 82
    - name: Run Apache container on port 82
      docker_container:
        name: apache_server
        image: httpd
        ports:
          - "82:80"
        state: started
        restart_policy: always

    # 10. Disable and stop firewalld
    - name: Stop firewalld
      systemd:
        name: firewalld
        state: stopped

    - name: Disable firewalld
      systemd:
        name: firewalld
        enabled: no

  handlers:
    - name: restart nginx
      systemd:
        name: nginx
        state: restarted

  • 플레이북 실행
ansible-playbook nginx_mysql_docker.yml

———————————————————————————————————————————

2번 째 플레이북 작성

  • 플레이북 작성
    • 플레이북 내용: disk 남은 용량, 메모리 버퍼/캐쉬, cpu 사용률 확인
[root@master ansible]# cat 3.test.yml
---
- hosts: all
  become: yes
  gather_facts: no
  tasks:

    # 1. 디스크 남은 용량 확인
    - name: Check available disk space
      command: df -h --output=avail /
      register: disk_available
    - name: Show available disk space
      debug:
        msg: "Available disk space: {{ disk_available.stdout_lines[1] }}"

    # 2. 메모리 전체 정보 확인 (debug로 출력)
    - name: Check memory information
      command: free -m
      register: memory_info
    - name: Show full memory info
      debug:
        var: memory_info.stdout_lines

    # 3. 메모리 버퍼 캐시 확인
    - name: Show buffer/cache memory
      debug:
        msg: "Buffer/Cache memory: {{ memory_info.stdout_lines[1].split()[5] }} MB"

    # 2. CPU 사용률 확인 (iowait, steal 제거)
    - name: Check CPU usage with sar (remove %iowait and %steal using sed)
      shell: sar 1 1 | grep -v Linux | sed 's/\\s*[0-9\\.]\\+\\s*[0-9\\.]\\+\\s*$//'
      register: cpu_usage_sed
      ignore_errors: yes  # 에러가 발생하더라도 플레이북 실행을 중단하지 않음

    - name: Show CPU usage (without %iowait and %steal)
      debug:
        msg: "{{ cpu_usage_sed.stdout }}"
  • 플레이북 실행
ansible-playbook 3.test.yml
  • 실행 결과
    • fail 없이 전부 ok 상태인 것을 확인할 수 있다.
[root@master ansible]# ansible-playbook 3.test.yml

PLAY [all] **********************************************************************************************************************************************************************************************************

TASK [Check available disk space] ***********************************************************************************************************************************************************************************
changed: [192.168.0.51]
changed: [192.168.0.52]

TASK [Show available disk space] ************************************************************************************************************************************************************************************
ok: [192.168.0.51] => {
    "msg": "Available disk space:  9.6G"
}
ok: [192.168.0.52] => {
    "msg": "Available disk space:  9.6G"
}

TASK [Check memory information] *************************************************************************************************************************************************************************************
changed: [192.168.0.52]
changed: [192.168.0.51]

TASK [Show full memory info] ****************************************************************************************************************************************************************************************
ok: [192.168.0.51] => {
    "memory_info.stdout_lines": [
        "               total        used        free      shared  buff/cache   available",
        "Mem:            3659         825        2620          14         444        2834",
        "Swap:           4095           0        4095"
    ]
}
ok: [192.168.0.52] => {
    "memory_info.stdout_lines": [
        "               total        used        free      shared  buff/cache   available",
        "Mem:            3659         840        2531          14         519        2819",
        "Swap:           4095           0        4095"
    ]
}

TASK [Show buffer/cache memory] *************************************************************************************************************************************************************************************
ok: [192.168.0.51] => {
    "msg": "Buffer/Cache memory: 444 MB"
}
ok: [192.168.0.52] => {
    "msg": "Buffer/Cache memory: 519 MB"
}

TASK [Check CPU usage with sar (remove %iowait and %steal using sed)] ***********************************************************************************************************************************************
changed: [192.168.0.51]
changed: [192.168.0.52]

TASK [Show CPU usage (without %iowait and %steal)] ******************************************************************************************************************************************************************
ok: [192.168.0.51] => {
    "msg": "\n14시 08분 07초     CPU     %user     %nice   %system   %iowait    %steal     %idle\n14시 08분 08초     all      0.00      0.00      0.00      0.00\n평균값:      all      0.00      0.00      0.00      0.00"
}
ok: [192.168.0.52] => {
    "msg": "\n14시 08분 07초     CPU     %user     %nice   %system   %iowait    %steal     %idle\n14시 08분 08초     all      1.00      0.00      0.00      0.00\n평균값:      all      1.00      0.00      0.00      0.00"
}

PLAY RECAP **********************************************************************************************************************************************************************************************************
192.168.0.51               : ok=7    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
192.168.0.52               : ok=7    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0


1. 환경 정보

항목
OSUbuntu
서버 IP192.168.1.35
사용자root
설치 경로/home/min/download/n8n/
실행 방식Docker Compose
n8n 포트5678

2. 디렉토리 구조

/home/min/download/n8n/
├── docker-compose.yml
└── n8n_data/
    ├── config
    ├── workflows
    ├── credentials
    └── database.sqlite
  • n8n_data데이터 영구 보존 디렉토리
  • 컨테이너 삭제/재생성해도 데이터 유지됨

3. docker-compose.yml

version:"3.8"

services:
n8n:
image:n8nio/n8n:latest
container_name:n8n
restart:always

ports:
-"5678:5678"

environment:
TZ:Asia/Seoul
N8N_HOST:192.168.1.35
N8N_PORT:5678
N8N_PROTOCOL:http
NODE_ENV:production
N8N_SECURE_COOKIE:"false"

volumes:
-./n8n_data:/home/node/.n8n
  • 도메인 주소 때문에 변경
min@ubuntu-terraform:~/download/n8n$ cat docker-compose.yml
version: "3.8"

services:
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    restart: always

    ports:
      - "5678:5678"

    environment:
      TZ: Asia/Seoul

      N8N_HOST: n8n.ssunmini.com
      N8N_PROTOCOL: http
      N8N_PORT: 5678

      N8N_EDITOR_BASE_URL: <https://n8n.ssunmini.com>
      WEBHOOK_URL: <https://n8n.ssunmini.com>

      N8N_TRUST_PROXY: "true"

      NODE_ENV: production
      N8N_SECURE_COOKIE: "true"

    volumes:
      - ./n8n_data:/home/node/.n8n

4. 실행 방법

4.1 최초 실행

cd /home/min/download/n8n
docker compose up -d

4.2 실행 상태 확인

docker ps

4.3 로그 확인

docker logs -f n8n

정상 로그 예시

Editor is now accessible via
<http://localhost:5678>

5. 웹 접속

브라우저에서 접속

http://192.168.1.35:5678
https://n8n.ssunmini.com

6. 권한 이슈 및 해결 방법

6.1 발생 에러

Error: EACCES: permission denied, open '/home/node/.n8n/config'

6.2 원인

  • n8n 컨테이너는 node 사용자 (UID 1000) 로 실행
  • n8n_data 디렉토리가 root 소유
  • node 사용자가 파일 생성/쓰기 불가

6.3 해결 명령어

docker compose down

chown -R 1000:1000 /home/min/download/n8n/n8n_data
chmod -R 755 /home/min/download/n8n/n8n_data

docker compose up -d

6.4 정상 상태 확인

ls -l /home/min/download/n8n/n8n_data

정상 예시

node node database.sqlite
node node workflows/
node node credentials/

7. 운영 명령어 정리

# 중지
docker compose down

# 재시작
docker compose restart

# 실행
docker compose up -d

# 로그 확인
docker logs -f n8n

# 이미지 업데이트
docker compose pull
docker compose up -d

8. 데이터 백업

8.1 백업 대상

/home/min/download/n8n/n8n_data/

8.2 간단 백업 예시

tar czvf n8n_backup_$(date +%F).tar.gz n8n_data/


9. 자주 발생하는 문제 요약

증상원인해결
EACCES 에러볼륨 권한chown 1000:1000
접속 불가포트 충돌5678 사용 여부 확인
데이터 초기화볼륨 누락./n8n_data 확인
쿠키 오류HTTPS 없음N8N_SECURE_COOKIE=false


  • n8n workflow 등록
  • 필요한 API 등록
  • Gpt, Claude, Gemini 등 통합으로 채팅 사용