Ansible playbook
Ansible은 IT 자동화 도구로, 주로 서버 구성 관리, 애플리케이션 배포, 그리고 네트워크 장비 관리 등을 자동화하는 데 사용됩니다. Ansible은 에이전트리스 방식으로, 원격 서버에 별도의 소프트웨어를 설치할 필요 없이 SSH를 통해 명령을 전달하고 실행합니다. YAML 형식의 간단한 파일(플레이북)을 사용하여 작업을 정의하고, 여러 서버에서 동시에 실행할 수 있어 대규모 인프라 관리에 유용합니다.
주요 특징
- 에이전트 설치 불필요
- 간단한 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

n8n 설치·운영 매뉴얼
1. 환경 정보
| 항목 | 값 |
|---|---|
| OS | Ubuntu |
| 서버 IP | 192.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 등 통합으로 채팅 사용
