앤서블(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