ANSIBLE
open source sw로 provisioning, 구성 관리 등을 자동화시켜주는 tool.
진영씨께서 ANSIBLE을 사용하여 jenkins server 구축한 경험을 바탕으로 study를 진행해주심.
실습 환경 구축
-
노드 구성 CentOS7 머신 2대를 이용하여 하나를 master, 하나를 worker로 잡음.
- Master node에서 Ansible 설치.
yum install epel-release
로 설치 후
yum repolist
로 확인. epel repo 가 잘 들어가있다면,yum install ansible
로 설치 진행. (만약 잘 들어가지 않는다면, 사내에 epel 이 존재하는 머신에 접속하여 가져오는 것도 가능.
scp root@192.168.2.236:/etc/yum.repos.d/epel.repo /etc/yum.repos.d/
) - mkdir && hosts파일 생성
원하는 위치에 directory 를 하나 생성하고, 그 하위에 hosts
라는 파일을 다음과 같이 생성.
[all:vars]
ansible_connection=ssh
ansible_user=root
ansible_ssh_pass=gluesys!!
[master]
192.168.1.82
[worker_group]
192.168.1.104
#...
- ansible ping test
ansible -i hosts all -m ping
로 hosts 파일에 존재하는 host들이 통신이 되는지 확인.
failed 뜬다면 확인이 되지 않은 host이기 때문. ~/.ssh/known_hosts
에 등록이 되어 있어야 함. 등록되지 않은 host들에 대해 ssh 로 접속을 시도하여 finerprints yes 를 입력하면 등록됨.
(이와 관련하여 .ssh 하위의 3가지 directory와 ssh keygen, ssh copy id 에 대해서도 공부하자.)
또는 /etc/ansible/ansible.cfg
파일의 host_key_checking-False 부분을 주석 해제 하면 known_host에 없어도 가능하게 해 준다.
이렇게 설정했을 때, success 가 나와야 정상.
shell_basic
이제 생성한 directory (ex- study_ans) 하위에 들어가서 shell_basic.yaml
파일을 다음과 같이 작성해보자.
---
- hosts: worker_group # 어떤 대상이 아래 task를 수행할건지.
tasks:
- name: task1 # tag
shell: ls /root/ # shell 명령.
register: result # 위에서 수행한 결과값을 이 변수에 받아옴.
- debug: msg= # console.log 정도.
hosts 에 지정된 host들에게 간단한 shell script를 실행시킬 수 있도록 작성하였다.
실행 명령 : ansible-playbook -i hosts shell_basic.yaml
로 실행한다. ansible 을 실행할 때는 playbook을 이용한다.
다음과 같이 실행완료 되었는데 확인할 방법이 없다. (shell script는 간단한 ls 명령이었을 뿐..)
따라서 다음과 같이 -vvv option을 줘서 확인한다.
ansible-playbook -i hosts shell_basic.yaml -vvv
그러면 다음과 같이 상세 정보를 출력한다. (debug 메세지도 볼 수 있음.)
yum_basic
앞서 작성했던 shell_basic과 비슷한 yum_basic.yaml
파일을 작성해 보자.
---
- hosts: # 여기를 * 로 하면 hosts 파일에 있는 모든 host들에게 명령.
- worker_group
tasks:
- name: yum_controller
yum:
name:
- git
- perl-Crypt-DES
state: present
# About state
# present: 설치
# installed : 설치 확인
# latest : 최신 version으로 update
# removed : 제거
yum 을 이용해 worker_group에 존재하는 host들에게 git과 perl-Crypt-DES module을 설치한다.
worker node에서 확인.
확인하는 방법으로 yum history
와 yum history info <ID>
를 이용하는 방법도 있음을 기억하자.
vars(변수) 사용 - loop_basic
다음으로 vars.yaml
과 loop_basic.yaml
파일을 작성해 보자.
ansible에서는 변수를 지정, 할당하여 사용할 수 있다. 이러한 변수를 vars 파일에 선언하고 가져와 사용할 수 도 있고, yaml 파일 내부에서 할당하여 사용할 수도 있다.
먼저 vars.yaml 파일은 진영씨 server에서 scp로 가져온 파일 그대로 사용했다.
---
### vCenter
vcenter_server: "192.168.0.87"
vcenter_user: "administrator@vsphere.local"
datacenter_name: "Jenkins"
cluster_name_vm7: "192.168.0.178"
### datastore
datastore_vm7: "datastore_vm7"
datastore_vm6: "datastore1 (1)"
datastore_vm5: "datastore1"
### VM interface
M_infc: ens192
St_infc: ens161
Sv_infc: ens224
### for Deploy key
token: _uTd_kzPe_hCMxy_zEeX
vm_set1_b1: {ip: 192.168.2.11 ,esxi: Jenkins VM7 ,vm_name: vm7-set1-build ,tmp: VM7.SET1.33 Node ,Host: VM7SET1 ,svc_ip: 10.133.2.11}
vm_set1_c1: {ip: 192.168.2.95 ,esxi: Jenkins VM7 ,vm_name: vm7-set1-c1 ,tmp: VM7.SET1.33 target ,stg_ip: 10.233.2.12 ,svc_ip: 10.133.2.12}
vm_set1_c2: {ip: 192.168.2.96 ,esxi: Jenkins VM7 ,vm_name: vm7-set1-c2 ,tmp: VM7.SET1.33 target ,stg_ip: 10.233.2.13 ,svc_ip: 10.133.2.13}
vm_set1_c3: {ip: 192.168.2.99 ,esxi: Jenkins VM7 ,vm_name: vm7-set1-c3 ,tmp: VM7.SET1.33 target ,stg_ip: 10.233.2.14 ,svc_ip: 10.133.2.14}
vm_set1_c4: {ip: 192.168.2.100 ,esxi: Jenkins VM7 ,vm_name: vm7-set1-c4 ,tmp: VM7.SET1.33 target ,stg_ip: 10.233.2.15 ,svc_ip: 10.133.2.15}
vm_set2_b1: {ip: 192.168.3.1 ,esxi: Jenkins VM7 ,vm_name: vm7-set2-build ,tmp: VM7.SET2.34 Node ,Host: VM7SET2 ,svc_ip: 10.134.3.1 }
vm_set2_c1: {ip: 192.168.3.27 ,esxi: Jenkins VM7 ,vm_name: vm7-set2-c1 ,tmp: VM7.SET2.34 target ,stg_ip: 10.234.3.2 ,svc_ip: 10.134.3.2 }
vm_set2_c2: {ip: 192.168.3.88 ,esxi: Jenkins VM7 ,vm_name: vm7-set2-c2 ,tmp: VM7.SET2.34 target ,stg_ip: 10.234.3.3 ,svc_ip: 10.134.3.3 }
vm_set2_c3: {ip: 192.168.3.99 ,esxi: Jenkins VM7 ,vm_name: vm7-set2-c3 ,tmp: VM7.SET2.34 target ,stg_ip: 10.234.3.4 ,svc_ip: 10.134.3.4 }
vm_set2_c4: {ip: 192.168.3.100 ,esxi: Jenkins VM7 ,vm_name: vm7-set2-c4 ,tmp: VM7.SET2.34 target ,stg_ip: 10.234.3.5 ,svc_ip: 10.134.3.5 }
vm_set3_b1: {ip: 192.168.3.18 ,esxi: Jenkins VM7 ,vm_name: vm7-set3-build ,tmp: VM7.SET3.35 Node ,Host: VM7SET3 ,svc_ip: 10.135.3.18}
vm_set3_c1: {ip: 192.168.2.68 ,esxi: Jenkins VM7 ,vm_name: vm7-set3-c1 ,tmp: VM7.SET3.35 target ,stg_ip: 10.235.3.19 ,svc_ip: 10.135.3.19}
vm_set3_c2: {ip: 192.168.2.69 ,esxi: Jenkins VM7 ,vm_name: vm7-set3-c2 ,tmp: VM7.SET3.35 target ,stg_ip: 10.235.3.20 ,svc_ip: 10.135.3.20}
vm_set3_c3: {ip: 192.168.2.78 ,esxi: Jenkins VM7 ,vm_name: vm7-set3-c3 ,tmp: VM7.SET3.35 target ,stg_ip: 10.235.3.21 ,svc_ip: 10.135.3.21}
vm_set3_c4: {ip: 192.168.2.79 ,esxi: Jenkins VM7 ,vm_name: vm7-set3-c4 ,tmp: VM7.SET3.35 target ,stg_ip: 10.235.3.22 ,svc_ip: 10.135.3.22}
~~~...
(사실상 실습에서 사용해 볼 변수는 vars.yaml의 M_infc 뿐. 이후 deploy_vm.yaml에서 사용된다.)
---
- hosts: master
vars: # 내부 변수 사용.
set1:
- v1
- v2 (version two)
set2:
- v2_1
- v2_2
vars_files: vars.yaml # 외부 변수 사용.
tasks:
- name: make files
shell: | # |(pipe) 는 여러 줄을 실행시킬 수 있도록 해줌.
touch /root/ # .0 => ansible은 기본적으로 배열을 사용. == v1
touch /root/""
touch /root/"" # 쌍따옴표 문자열로 취급. == v2 (version two)
touch /root/ # M_infc 는 vars.yaml에서 ens192로 정의되어 있음.
touch /root/ # external_var 로 민감한 pw등의 부분을 직접 변수로 >전달하며 가져다 쓸 수 있음.
이렇게 작성한 loop_basic.yaml을 실행시켜보자. ansible-playbook -i hosts loop_basic.yaml --extra-vars '{external_var: blahblah}'
로 실행시켜주면 된다. –extra-vars option은 shell script 하위의 external_var를 명시해주기 위해 사용하였다.
확인을 위해 local에서 (hosts: master 로 지정했으므로) ls ../
해주면
이처럼 파일들이 잘 생성되었다.
loop사용 - loop_hard
---
- hosts: master
vars: # 내부 변수 사용.
set1:
- v1
- v2 (version two)
set2:
- v2_1
- v2_2
vars_files: vars.yaml # 외부 변수 사용.
tasks:
- name: simple for loop
shell: touch /root/ #item == iterator
with_items:
- i1
- i2
- i3
# - {ip:192.168.xxx.xxx, name:node1} #이런식으로도 활용 가능
# - {ip:192.168.xxx.xxx, name:node2}
- name: data list
shell: touch /root/ #item == iterator
with_list:
- ""
- ""
# 이렇게 하면 v1, v2_1 이 생성됨
- name: for loop 활용
shell: touch /root/ #item == iterator
with_sequence: start=0 end=10 stride=2 format=KDH%02x
이런식으로 loop를 활용할 수 있다. 실행 명령어는 상동.
Deployment
최종적으로, 진영씨께서 어떻게 수많은 jenkins node들을 빠른 시간안에 만들었는지 방법을 공유해 주셨다.
ansible-galaxy collection install community.vmware
ansible-galaxy collection install community.general
yum install python-pip
pip install pyvmomi
이렇게 의존 package 를 설치해 준 후,
deploy_vm.yaml
파일을 다음과 같이 작성하였다.
---
- hosts: localhost
gather_facts: no
vars_files:
- /root/study_ans/vars.yaml
####################################################################################
tasks:
- name: build VM
vmware_guest:
hostname: ""
username: ""
password: ""
validate_certs: False
name: dohyun #""
template: Jenkins_CI_Base_build
datacenter: ""
folder: //vm
cluster: ""
datastore: "datastore_vm7"
networks:
- name: VM Network
#ip: ""
ip: 192.168.2.238 #""
netmask: 255.255.252.0
gateway: 192.168.0.1
dns_servers: 192.168.0.1
type: static
label: ens161
- name: Cluster Internal
- name: Cluster Internal
#ip: 253.255.212.233
#netmask: 255.255.255.255
- name: Cluster Internal
#ip: 253.255.212.233
#netmask: 255.255.255.255
customization:
hostname: Test #""
state: poweredon
wait_for_ip_address: yes
delegate_to: localhost
with_items:
- ""
여기의 code들을 전부 이해한 것은 아니나, 추후에 다시 살펴봐야겠다.
이제 ansible-playbook -i hosts deploy_vm.yaml --extra-vars '{vcenter_pass: password!@#}'
으로 실행시켜주면 jenkins server 에 node가 배포된다.
** 추후에 공부해볼 topics
- ssh keygen
- ssh copy id
- .ssh 하위 3가지 directory
- epel-release