앤서블(ansible)의 내부 변수 활용 방법
![]()
앤서블의 플레이북은 제작에 시간과 충분한 테스트가 필요하지만 가상서버를 사용 시 OS 재설치도 빠르게 가능하여 틈틈히 연습 할 수록 진입 장벽이 조금씩 줄어드는 것을 느꼈습니다.
바쁜 프로젝트로 인해 시간이 많지는 않지만 잠시 ceph 신규버전의 설치 테스트를 진행할 때 여러 서버의 hostname와 hosts를 설정해야 할 때가 있었는데요. 플레이북이 공식적으로 제공되기는 하나 앤서블과 ceph를 같이 이해하기위해 별도로 플레이북을 만들어 봤습니다.
※ 주의사항 - 이 글은 플레이북에 들어간 기능만을 참고하시는 것을 권장하며 문제 발생시 책임을 지지 않습니다. - ssh-key에 관련된 내용이 있습니다. 보안적으로 권장하지 않으며 테스트를 위한 용도로만 사용한 점 참고 해주시기 바랍니다. - ceph의 경우 테스트 용도로 설치가 진행된 것으로 실제로 사용하지 않는 것을 권장합니다.
준비물
서버 모니터링 : 3대 스토리지 : 3대 (블록스토리지 각 3개씩 장착된 상태)
host 설정
ceph_ansible라는 디렉토리와 host 파일을 생성 했습니다. 여러 플레이북을 한곳에 집약하는 것 보다는 개별적으로 나누고 설명을 적어놓는게 좋을 것으로 판단 됐기 때문입니다.
vi /root/ceph_ansible/ceph_host
[ceph] mon0 ansible_host=1.1.1.1 # mon0 부분을 기억해주세요. mon1 ansible_host=2.2.2.2 mon2 ansible_host=3.3.3.3 osd0 ansible_host=4.4.4.4 osd1 ansible_host=5.5.5.5 osd2 ansible_host=6.6.6.6
hosts 파일 준비
ceph 구성 때 사용할 hosts 파일을 별도로 생성했습니다.
vi /root/ceph_ansible/hosts
1.1.1.1 mon0 2.2.2.2 mon1 3.3.3.3 mon2 4.4.4.4 osd0 5.5.5.5 osd1 6.6.6.6 osd2
ssh config 파일 준비
ssh를 접속할 때 key를 물어보지 않도록 하기 위한 파일 입니다. 다시 설명드리지만 테스트 목적으로 사용된 것으로 보안 상 권장하지 않으며 플레이북을 통해 해당 파일은 마지막에 클라이언트 서버에서 삭제 처리가 진행됩니다.
vi /root/ceph_ansible/host_config
Host * StrictHostKeyChecking no UserKnownHostsFile=/dev/null
setup 참고
플레이북에서는 유저가 직접 변수를 사용할 수 있으나 setup에 나오는 내용도 플레이북에서 변수로서 활용이 가능합니다.
ansible all -i /root/ceph_ansible/ceph_host -m setup -k > setup_list
setup_list를 vi로 열어서 봐보면 아래에서 나오는 ansible_default_ipv4[‘address’]는 이것을 사용하면 address에 저장되어있는 1.1.1.11이 플레이북에서 지정되어 사용됩니다. 하지만 이것만 사용하면 모든 호스트에서 동일하게 작동하겠죠.
"ansible_default_ipv4": {
"address": "1.1.1.11",
"alias": "eth0",
"broadcast": "1.1.255.255",
"gateway": "1.1.1.1",
"interface": "eth0",
"macaddress": "xx:xx:xx:xx:xx:xx",
"mtu": 1500,
"netmask": "255.255.0.0",
"network": "11.1.0.0",
"prefix": "16",
"type": "ether"
},
아래의 옵션은 플레이북이 작동중인 호스트가 mon0일 경우에만 기능이 작동하게 되며 1.1.1.11만이 사용되게 됩니다. 그런데 inventory_hostname는 뭘 뜻할까요?
when: "'mon0' in inventory_hostname"
ceph_hosts에 있는 ip 앞에 있는 값인 mon0을 뜻하는 것으로 이해하시면 됩니다.
[ceph] mon0 ansible_host=1.1.1.1
플레이북
- name: 모든 ceph 기본 셋팅
#gather_facts: yes
hosts: ceph
become: yes
tasks:
- name: hosts 파일 전송
copy:
src: /root/ceph_ansible/hosts
dest: /etc/hosts
- name: ssh config 파일 전송 # mon0 서버에만 등록
copy:
src: /root/ceph_ansible/host_config
dest: /root/.ssh/config
when: "'mon0' in inventory_hostname"
- name: hostname 파일 변경
copy:
content: "{{inventory_hostname}}"
dest: /etc/hostname
- name: hostname 명령어 적용
shell: hostname "{{inventory_hostname}}"
- name: ceph reef 파일 설치
dnf:
name: centos-release-ceph-reef
state: present
- name: cephadm docker 설치
dnf:
name: cephadm, docker
state: present
- name: mon0만 ssh key 생성 진행
shell: ssh-keygen -t rsa -N "" -f /root/.ssh/id_rsa
when: "'mon0' in inventory_hostname"
- name: ssh key 다운로드
fetch:
src: /root/.ssh/id_rsa.pub # 원격 서버의 경로
dest: /root/ceph_ansible/sshkey/id_rsa.pub # 앤서블이 작동 중인 서버로 다운로드 진행
flat: yes
become: yes
when: "'mon0' in inventory_hostname"
- name: 원본 키 값 삭제
command: rm /root/.ssh/authorized_keys
when: "'mon0' not in inventory_hostname" # mon0을 제외한 모든 서버에서 작동
- name: ssh key 파일 업로드 진행
copy:
src: /root/ceph_ansible/sshkey/id_rsa.pub
dest: /root/.ssh/authorized_keys
mode: '0600'
when: "'mon0' not in inventory_hostname"
- name: cephadm 셋팅
command: cephadm bootstrap --mon-ip {{ansible_default_ipv4['address']}}
when: "'mon0' in inventory_hostname"
- name: 레포지토리 지정
command: cephadm add-repo --release reef
when: "'mon0' in inventory_hostname"
- name: mon0 ceph-common 설치
command: cephadm install ceph-common
when: "'mon0' in inventory_hostname"
- name: ceph 키 배포
shell: for i in mon1 mon2 osd0 osd1 osd2; do ssh-copy-id -f -i /etc/ceph/ceph.pub ${i}; done
when: "'mon0' in inventory_hostname"
- name: cephadm 셋팅
command: ceph config set mon public_network {{ansible_default_ipv4['network']}}/24
when: "'mon0' in inventory_hostname"
- name: ceph 호스트 지정
shell: for i in mon1 mon2 osd0 osd1 osd2; do ceph orch host add ${i} $(cat /etc/hosts |grep ${i} |awk '{print $1}'); done
when: "'mon0' in inventory_hostname"
- name: mon 추가
command: ceph orch apply mon "mon0,mon1,mon2"
when: "'mon0' in inventory_hostname"
- name: mon 라벨 추가
shell: for i in mon0 mon1 mon2; do ceph orch host label add ${i} mon; done
when: "'mon0' in inventory_hostname"
- name: 블록 스토리지 상태 재정리
shell: for i in vdb vdc vdd; do parted -s /dev/${i} mktable msdos; done
when: inventory_hostname not in ['mon0', 'mon1', 'mon2'] # 디스크가 lvm 또는 pvs에 포함되어 있을 경우 osd 설정이 불가능하며 블록스토리지가 없는 mon 서버들은 조건에서 제외
- name: osd 추가
shell: for i in vdb vdc vdd; do ceph orch daemon add osd osd0:/dev/${i}; done
when: "'mon0' in inventory_hostname"
- name: osd 추가
shell: for i in vdb vdc vdd; do ceph orch daemon add osd osd1:/dev/${i}; done
when: "'mon0' in inventory_hostname"
- name: osd 추가
shell: for i in vdb vdc vdd; do ceph orch daemon add osd osd2:/dev/${i}; done
when: "'mon0' in inventory_hostname"
- name: ssh config 값 삭제
command: rm /root/.ssh/config
when: "'mon0' in inventory_hostname"
명령어 사용
export ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i /root/ceph_ansible/ceph_host /root/ceph_ansible/ceph.yml -k
설치 확인
[root@mon0 ~]# ceph -s
cluster:
id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
health: HEALTH_OK
services:
mon: 3 daemons, quorum mon0,mon2,mon1 (age 9d)
mgr: mon0.phftmt(active, since 2w), standbys: osd0.kdonrr
osd: 9 osds: 9 up (since 2w), 9 in (since 2w)
data:
pools: 1 pools, 1 pgs
objects: 2 objects, 449 KiB
usage: 503 MiB used, 89 GiB / 90 GiB avail
pgs: 1 active+clean



