A101 3기(=Ansible 101 Study)는 Ansible 실무 실습 스터디입니다.
CloudNet@ 가시다 님이 진행하시며, 책 "앤서블로 시작하는 인프라 자동화"을 기반으로 진행하고 있습니다.
여러 서버를 통합해서 관리할 수 있는 도구를 찾고 있던 도중 Ansible를 알게 되었습니다. 쿠버네티스 실무자인 저에게 Ansible 는 IaC 도구로 테라폼의 영향으로 더 이상 안쓰는 것으로 알았지만, 클러스터 구축 이후의 k8s 운영 관리, 클러스터 외 서버(ec2) 관리 목적으로 사용되더군요. 운영 측면에서 Ansible을 통해 어떻게 서버를 관리할 수 있는 지 알아보겠습니다.
Ansible ?
Ansible 이란 오픈소스 자동화 도구로 다양한 IT 작업을 자동화하는데 사용되는 도구입니다. Ansible 를 사용하면 코드 기반으로 여러 대의 환경(서버, 애플리케이션 등)을 관리할 수 있게 됩니다. 이를 통해 서버 구성 관리, 보안 자동화, 인프라 오케스트레이션 등 IT 작업을 자동화할 수 있습니다.
Ansible 특징
Agentless 에이전트-리스: : Ansible은 SSH를 통해 서버를 관리합니다. SSH로 관리하기에 별도의 Agent(작업 실행 서버)가 필요 없습니다.
Idempotent 멱등성 : 멱등성이란 동일한 작업을 반복 실행해도 시스템의 최종 상태가 동일하게 유지된다는 원리를 의미합니다. 동일한 운영 작업을 여러 번 실행해도 같은 결과를 나타냅니다.
커뮤니티와 확장성 지원 : 활발한 커뮤니티와 다수의 사용자가 있어 사용 예를 쉽게 찾을 수 있고 다양한 확장성 모듈이 제공됩니다. 모듈을 통해 AWS, Azure 같은 클라우드 서비스, 네트워크 장비 등 다양한 플랫폼과 서비스를 관리할 수 있습니다.
Ansible 구조
커뮤니티 앤서블 : 가장 일반적인 앤시블 버전으로 contraol Node, Managed Node로 분리되어 있습니다.
노드라 칭하였지만, 별도의 에이전트 구성은 없으며 ssh와 Python을 통해 관리됩니다.
레드햇 앤서블 오토메이션 플랫폼 : 커뮤니티 앤서블과 달리 인벤토리, 인증 정보, 실행 환경 등을 관리하는 CMDB가 중간에 있는 구조입니다. 유료 버전으로 본 가이드에서는 다루지 않았습니다.
Ansible 문법 미리보기
앤서블이 어떻게 동작하는 지 간단한 코드를 통해 확인하겠습니다. 앤서블은 크게 인벤토리와 플레이북으로 구성됩니다.
Inventory 인벤토리 : 관리하고자 하는 호스트들의 목록을 정의합니다. 각 호스트 목록들은 [] 표시를 통해 그룹으로 묶을 수도 있으며 [all:children] 을 통해 그룹간 재귀적으로 선언이 가능합니다. 예제에서 사용한 all:children 은 all 의 그룹은 web과 db그룹을 포함한다는 의미입니다.
1
2
3
4
5
6
7
8
9
10
11
# inventory[web]tnode1
tnode2
[db]tnode3
[all:children]web
db
Playbook 플레이북 : 수행하고자 하는 작업들을 정의합니다. 아래 내용은 호스트 그룹 ‘all’ 에서 핑 모듈을 통해 ping을 확인하는 예제입니다.
1
2
3
4
5
6
7
---
- name: Ping Test for All Hosts
hosts: all
gather_facts: no
tasks:
- name: Ping Test
ansible.builtin.ping: # 앤서블에서 제공하는 'ping' 모듈입니다.
위 내용으로 구성해서 실행한다면 앤서블에 인벤토리에 정의한 호스트 서버에 Ping 명령어를 실행합니다. 간단하게 본 예제는 하단 Case1 로컬 서버 예제에서 확인 가능합니다.
Ansible 설치
Ansible 을 설치하기 위해서는 파이썬과 SSH 설치가 사전에 필요합니다. 우분투 22.04 버전인 경우 파이썬이 기본적으로 설치되어 있습니다. 앤서블 설치는 다음과 같습니다.
Step 1 서버 환경 구성
일반 서버(EC2) 4대를 구성하여 앤서블을 설치하겠습니다. EC2 4대 구성은 Cloudnet@ 가시다님이 제공해주신 클라우드포메이션 템플릿으로 진행합니다.
단, 이미 EKS 클러스터 구성된 경우 노드 그룹에 태깅시 노드 재시작이 필요합니다. 태그 설정을 위해 노드를 재시작하는 것은 위험비용이 크기에 이미 있는 태그가 있다면 해당 태그로 호스트를 설정하는 것을 추천드립니다. 저는 앤서블 관리를 위한 태그없이 EKS를 구성했음으로 이미 구성된 태그를 통해 앤서블 기능을 테스트하겠습니다.
Step 3 EC2 동적 인벤토리 만들기
앤시블 공식 문서를 참고하면 AWS 동적 서비스 에 대해 인벤토리 가이드를 안내해주고 있습니다. 여기서 우리는 aws_ec2 플러그인을 사용하여 ec2 동적 인벤토리를 만들겠습니다.
각 코드의 대한 내용은 해당 모듈의 공식 문서를 참고해주세요. 공식 문서에서 keyed_groups 를 참고하면 다음과 같이 활용할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
keyed_groups:
# 'Name' 태그를 기반으로 그룹 생성 - key: tags.Name
prefix: tag
separator: "_"# 'Environment' 태그를 기반으로 그룹 생성 - key: tags.Environment
prefix: env
separator: "_" default_value: unknown
# 'Role' 태그를 기반으로 그룹 생성, 'Role' 태그가 없는 경우 'role_unknown' 그룹에 할당 - key: tags.Role
prefix: role
separator: "_" default_value: unknown
1
2
3
4
5
6
7
8
9
10
11
ansible-inventory -i inventory_aws_ec2.yml --graph
[DEPRECATION WARNING]: Ansible will require Python 3.8 or newer on the controller starting with Ansible 2.12. Current version: 3.7.16
(default, Aug 30 2023, 20:37:53)[GCC 7.3.1 20180712(Red Hat 7.3.1-15)]. This feature will be removed from ansible-core in version
2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
@all:
|--@_kops_ec2:
||--ec2-3-35-170-241.ap-northeast-2.compute.amazonaws.com
|--@aws_ec2:
||--ec2-3-35-170-241.ap-northeast-2.compute.amazonaws.com
|--@ungrouped:
EKS 파드 관리 여부
EKS 노드에 접근하여 관리할 경우 파드(컨테이너 환경)까지 관리가 가능할까요? 노드에서 파드 내용을 확인할 수 있는 지 확인해보겠습니다.
일부 프로세스 네임스페이스(PID, MNT, NET, UTS)만 격리되어 있을 뿐, 호스트의 커널을 공유하여 동작하는 리눅스 프로세스입니다. 결론적으로 호스트에서 컨테이너 프로세스를 볼 수 있습니다. 쿠버네티스 파드를 임시적으로 생성하고 워커 노드에서 해당 프로세스를 확인할 수 있는 지 확인하겠습니다.
1
kubectl run my-temp-pod2 --image=busybox --restart=Never -- sleep 3600
1
2
# 호스트 노드 pstree -a
또한, 해당 파드의 PID를 통해 환경 변수 또한 조회가 가능합니다.
1
2
3
4
5
# PID 확인 ps -ef
# 환경 변수 확인 sudo cat /proc/20984/environ
볼륨 또한 호스트에서 확인이 가능합니다. 호스트 노드에서 볼륨 경로를 찾아가면 해당 파드의 마운트 내용을 확인할 수 있습니다.
1
2
# 노드 PC cd /var/lib/kubelet/pods/
앤시블을 통한 EKS 관리
앞서 확인한 내용을 바탕으로 앤시블을 통해 EKS를 비롯한 전체 EC2 서버에서 명령어를 관리해보겠습니다. 관리 시나리오는 전체 서버에 대한 비트 코인 채굴 여부 확인으로 프로세스를 검사하겠습니다.
검사에 필요한 구성은 다음과 같습니다.
1
2
3
4
5
6
tree .
---
.
├── ansible.cfg
├── check_crnatab.yaml
└── inventory_aws_ec2.yml
베스천 서버에서 워커 노드로 접근하기 위해서는 보안 그룹 설정과 SSH 키 등록이 필요합니다.
보안 그룹 설정은 워커 노드 보안 그룹 ingress 규칙에서 베스천서버IP/32, 22 를 추가해주세요.
SSH 접근을 위해 베스천서버의 공개 키를 복사하여 대상 노드에 복사해주세요.
1
2
3
4
5
6
7
# 베스천서버 vi ~/.ssh/id_rsa.pub
--
ssh-rsa ~ root@kops-ec2
# 대상 노드echo"공개키" >> ~/.ssh/authorized_keys