Ansible (실습 - Ansible) - 9.21

양승현·2022년 9월 21일
0

Ansible

목록 보기
2/4
post-thumbnail

https://velog.io/@yange/Vagrant-Ansible-9.20

  • 이어서 실습 진행하겠습니다.

2. 클라우드 이미지 준비하기

2.1 CentOS01.qcow2 파일 다운로드

  • cd /ansible # ansible 디렉토리에서 작업
wget https://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-1905.qcow2.xz

2.2 압축 해제

  • 압축해제
xz -d CentOS-7-x86_64-GenericCloud-1905.qcow2.xz

2.3 libguestfs-tools 다운로드

yum -y install libguestfs-tools libguestfs-xfs

2.4. 이미지에 패스워드 입력하기

  • 이미지 커스텀마이즈
virt-customize -a centos01.qcow2 --root-password password:test123 --selinux-relabel

2.5 이미지 복사

  • 이미지 4개 생성
 cp CentOS-7-x86_64-GenericCloud-1905.qcow2 centos01.qcow2
cp centos01.qcow2 centos02.qcow2
cp centos01.qcow2 centos03.qcow2
cp centos01.qcow2 centos00.qcow2

2.6 인스턴스 생성하기

  • 인스턴스 4개 생성
virt-install --name ansible-server --vcpus 1 --ram 1024 --disk=/ansible/centos00.qcow2 --import --graphics none
virt-install --name ansible-node2 --vcpus 1 --ram 1024 --disk=/root/ansible/centos02.qcow2 --import --graphics none --serial pty --console pty &
virt-install --name ansible-node3 --vcpus 1 --ram 1024 --disk=/root/ansible/centos03.qcow2 --import --graphics none --serial pty --console pty &
virt-install --name ansible-node1 --vcpus 1 --ram 1024 --disk=/root/ansible/centos01.qcow2 --import --graphics none --serial pty --console pty &
  • 설치되면서 자동으로 콘솔 접속이 진행된다 콘솔에서 나가기 Ctrl + ]
  • 생성 완료

2.6.2 만약 접속이 안된다면 아래와 같이 해본다

  • 볼륨은 남겨두고 인스턴스만 삭제
virsh undifine ansible-server
  • 인스턴스 생성
virt-install --name ansible-server --vcpus 1 --ram 1024 --disk=/root/ansible/centos00.qcow2 --import --graphics none --serial pty --console pty

2.7 VM 에서 나온 상태에서 다시 VM 으로 진입하기

virsh console ansible-node1
  • 최종적으로 ansible-server 로 들어가기
  • 인스턴스 생성확인
virsh list --all
211.183.3.148 server
211.183.3.151 node1
211.183.3.149 node2
211.183.3.150 node3

2.8 ansible-server setting

  • 호스트 네임 번경
hostnamectl set-hostname ansible-server
  • 각종 패키지의 최신 버전을 제공하는 community 기반의 저장소 설치
yum -y install epel-release
  • 앤서블 설치
yum -y install ansible
  • 키 생성
ssh-keygen -q -f ~/.ssh/id_rsa -N ""
  • node 1,2,3에게 ~/.ssh/authorized_keys에게 id_rsa.pub 값 전달하기
  • 접속해보기
ssh -i ~/.ssh/id_rsa -l root 211.183.3.151
ssh -i ~/.ssh/id_rsa -l root 211.183.3.149
ssh -i ~/.ssh/id_rsa -l root 211.183.3.150
  • 211.183.3.X 에 대한 SSH 접속시 root로 접속하고, Key file로 ~/.ssh/id_rsa를 사용하여 접속
cat /etc/ssh/ssh_config

# 맨 아래에 다음과 같이 입력한다.
Host 211.183.3.*
        User root
        IdentityFile ~/.ssh/id_rsa
# 혹은 파일 접속없이 다음과 같이 입력한다.
cat<<EOF >>/etc/ssh/ssh_config
Host 211.183.3.*
        User root
        IdentityFile ~/.ssh/id_rsa
EOF

ansible 사용해보기

  • 다양한 모듈 사용
    1. ping - 지정된 노드에 로그인이 가능한지 여부와 파이썬 철치 여부를 확인할 수 있는 모듈
    1. shell - 타겟(노드)에서 쉘 명령을 실행할 수 있는 모듈
    1. user - 사용자 생성, 삭제, 수정할 수 있는 모듈
    1. yum - yum을 이용해 특정 패키지의 설치와 삭제
    1. copy - 로컬에서 작성한 파일을 노드에 복사할 수 있는 모듈

1. ping

관리할 Node 주소 설정

  • 별도로 인벤토리 파일 만들어 사용하기
    예) ansible -i seoul.lst
vi /etc/ansible/hosts
# 맨 아래에 node ip 적기
211.183.3.151
211.183.3.149
211.183.3.150
  • Ansible 실행
[root@ansible-server ~]# ansible all -m ping
211.183.3.149 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
211.183.3.150 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
211.183.3.151 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
  • ip옆에 SUCCESS 인 것을 확인할 수 있다. 변경 사항이 없으므로 changed 는 false 이다. pong 은 ping 에 대한 응답이다

Inventory 파일 사용해보기

  • 데이터 센터 리전 별로 구분하기
[root@ansible-server ~]# touch seoul.lst
[root@ansible-server ~]# touch busan.lst
[root@ansible-server ~]# echo "211.183.3.151" >> seoul.lst
[root@ansible-server ~]# echo "211.183.3.149" >> seoul.lst
[root@ansible-server ~]# echo "211.183.3.150" >> busan.lst
  • 서울.lst에 있는 ip에 핑을 보내겠다.
ansible all -i seoul.lst -m ping

ansible all -i busan.lst -m ping

  • 다음과 같이 web과 db로 나누어 핑 보내보기
[root@ansible-server ~]# vi seoul.lst

[web]
211.183.3.151
[db]
211.183.3.149
[root@ansible-server ~]# ansible web -i seoul.lst -m ping
  • ip만 보기
[root@ansible-server ~]# ansible all -m ping --list-host
  hosts (3):
    211.183.3.151
    211.183.3.149
    211.183.3.150

[quiz] zone 에 상관없이 모든 DC 에서 웹 서버들로부터만 응답을 받아보세요

[root@ansible-server ~]# ansible all -m ping --list-host
  hosts (3):
    211.183.3.151
    211.183.3.149
    211.183.3.150
[root@ansible-server ~]# ansible web -i seoul.lst -m ping
211.183.3.151 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
[root@ansible-server ~]# ansible web -i seoul.lst -i busan.lst -m ping
211.183.3.151 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"

[quiz] Zone 상관 없이 web 서버들만 업데이트

ansible web -i seoul.lst -i busan.lst -m shell -a 'yum -y update'
# -i 는 인벤토리를 지정
# 위와 같이 shell 모듈을 이용하여 shell 명령을 내린다
  • 만약 모듈 쉘을 이용하여 특정 패키지를 설치했고 다시 한번 동일 명령을 실행한다면? 설치를 진행한다 물론 설치가 되어 있으므로 결과에서는 "이미 설치되어있다"가 출력된다
    • 좋지않다.
    • 이런경우 yum 모듈을 이용하면 이미설치가 된 상태에서는 다시 한번 설치를 진행하면 skip 한다.
    • 결국 shell은 ansible에서 사용하기에 적절한 모듈은 아니다.

3. user

사용자 생성 및 삭제

  • user2 생성
[root@ansible-server ~]# ansible all -m user -a "name=user2"
  • ansible은 멱등성을 사용한다.
    • 동일한 명령을 실행하더라도 결과가 달라지지 않는다.
    • 예를 들어 앤서블을 이용하여 httpd를 설치하고 이후 다시 설치를 진행하면 이 경우 해당 명령을 bash를 이용하였다면 추가 설치를 진행시킨다.
    • 처음 설치 : changed -> true
    • 두번째 설치 : changed -> false
    • 이를 이용하게 되면 불필요한 작업을 skip하게 되므로 리소스를 줄일 수 있게 된다.
      • user add user2(추가 또는 생성) -> userdel user2(삭제)
      • 생성되어 있는 상태를 보장해줘 -> present
      • 삭제되어 있는 상태를 보장해 달라 -> absent
        -> start -> started
        -> stop -> stopped
  • user2 삭제
[root@ansible-server ~]# ansible all -m user -a "name=user2 state=absent"
  • user2 삭제 확인 해보기
[root@ansible-server ~]# ansible all -m shell -a "cat /etc/passwd | grep user2"

4. yum

yum을 이용한 특정 패키지의 설치와 삭제

  • curl 설치
[root@ansible-server ~]# ansible all -m yum -a "name=curl state=present"
  • curl 삭제
[root@ansible-server ~]# ansible all -m yum -a "name=curl state=absent"
  • git 설치
[root@ansible-server ~]# ansible all -m yum -a "name=git state=present"
# 명령에 state=present가 없어도 동일하게 설치된다.
  • git clone하기
ansible all -m git -a "repo=https://github.com/beomtaek/k8s-quiz.git dest=/root/gittest"
  • 파일 목록확인
[root@ansible-server ~]# ansible all -m shell -a "ls /root/gittest"

[quiz]

  • 웹 서버 설치 및 홈 디렉토리에 index.html 을 복사 붙여넣기
ansible all -m yum -a "name=httpd state=present" -k
  • 웹 서버 설치
echo "<h2>yang</h2>" > index.html
  • index.html 생성
ansible all -m copy -a "src=index.html dest=/var/www/html/index.html"
  • server 의 index.html 을 node 의 디렉토리에 복사
[root@ansible-server ~]# ansible all -m shell -a "ls /var/www/html"
211.183.3.149 | CHANGED | rc=0 >>
index.html
211.183.3.150 | CHANGED | rc=0 >>
index.html
211.183.3.151 | CHANGED | rc=0 >>
index.html
  • 실행하기
ansible all -m service -a "name=httpd state=started" # = ansible all -m shell -a "systemctl start httpd"
  • service 모듈을 통해 state 를 started 로 지정하여 해당 서비스가 시작된 상태를 보장해준다.
  • 해당 주소로 접속하면 index.html이 나타난다.
http://211.183.3.149/

[quiz2]

  • git hub 의 아무 저장소에 간단한 index.html 파일을 올려두세요!!! (내용은 shop)
  • git 모듈을 이용하여 기존 동작중인 웹서버의 /var/www/html/shop 아래에 github 에 있는 index.html 파일을 클론 시키세요!
  • http://211.183.3.x/shop으로 파일을 확인할 수 있어야 한다.

[해설]

  • index.html 업로드
ansible all -m git -a "repo=https://github.com/Yangyang0429/tutorial.git dest=/var/www/html/shop"
  • 접속해보기
http://211.183.3.149/shop

서비스 중지하기

ansible all -m service -a "name=httpd state=stopped"

httpd 삭제하기

ansible all -m yum -a "name=httpd state=absent"

Vagrant

  • IaC
    • 코드를 이용하여 인프라를 구추가고 사용가능하 준비 상태를 만들어 줄 수 있다. -> 프로비저닝
    • 추가적으로 아주 정밀하지는 않지만 자동화도 지원한다.
  • 현재 Vagrant와 Kvm간의 연결을 위한 모듈(terraform과 kvm)은 결합도가 낮다.
  • vagrant + virtualbox는 결합도가 높다
  • 실제 클라우드 환경에 IaC를 적용할 때에는

1. Vagrant 실습 환경 구성

  • 기존 실습했던 가상 머신은 중지시키자

1.1 가상머신 리스트 확인 및 중지

[root@localhost ansible]# virsh list --all
 Id    Name                           State
----------------------------------------------------
 4     ansible-server                 running
 5     ansible-node2                  running
 6     ansible-node3                  running
 7     ansible-node1                  running
  • 중지
[root@localhost ansible]# virsh destroy ansible-node1
  • 삭제
[root@localhost ansible]# virsh undefine ansible-node1

1.2 vagrant의 설치와 libvirt(kvm)용 vagrant 플러그인 설치하기

yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
yum -y install libvirt-daemon-kvm libvirt-client vagrant gcc-c++ make libstdc++-devel libvirt-devel
systemctl restart libvirtd
vagrant plugin install vagrant-libvirt
vagrant -v Vagrant 2.2.16
  • vagrant 실습을 위한 파일 생성
mkdir project1; cd project1
  • 현재 디렉토리에서 프로젝트를 시작한다고 명시
vagrant init
  • Vagrantfile 보기
    • Vagrantfile은 프로비저닝을 위한 도구이다(네트워크, vm 생성 등)
vi Vagrantfile
8 Vagrant.configure("2") do |config|
# "2" 해당 버전에서 제공되는 것
# do - do 부터 end 사이에 하나의 작업을 수행
# |config| - 작업 내용 중에 config 작업을 수행한다. 
           - 여러개의 작업을 둘 수 있다. 
           - | | 는 일종의 작업 구분자
15   config.vm.box = "base"
# base 이미지 말들기
# 만약 다른 이미지를 사용하고 싶다면 "" 안에 사용하고 싶은 이미지의 이름 즉, centos7을 사용하고 싶다면 "centos/7"로 변경하면 된다.
  • Vagrantfile 파일 수정
8 Vagrant.configure("2") do |config|
15   config.vm.box = "centos/7"
16   config.vm.host_name = "server"
26   config.vm.network "forwarded_port", guest: 22, host: 20021, id: 'ssh    ' #id는 ssh를 위한것(id는 특별히 지정해줄 필요없다.)
35   config.vm.network "private_network", ip: "192.168.33.10" # eth1 IP
  • Vagrantfile 파일 실행
vagrant up
  • 가상머신 생성 확인
[root@localhost project1]# virsh list --all
 Id    Name                           State
----------------------------------------------------
 1     project1_default               running
 -     ansible-node1                  shut off
 -     ansible-node2                  shut off
 -     ansible-node3                  shut off
 -     ansible-server                 shut off
  • vagrant에 접속
[root@localhost project1]# vagrant ssh default
  • ip 확인
[vagrant@server ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:42:e7:01 brd ff:ff:ff:ff:ff:ff
    inet 192.168.121.155/24 brd 192.168.121.255 scope global noprefixroute dynamic eth0
       valid_lft 2748sec preferred_lft 2748sec
    inet6 fe80::5054:ff:fe42:e701/64 scope link
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:13:a8:5f brd ff:ff:ff:ff:ff:ff
    inet 192.168.33.10/24 brd 192.168.33.255 scope global noprefixroute eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe13:a85f/64 scope link
       valid_lft forever preferred_lft forever

실습

  • 초기 환경
virsh undefine server
virsh undefine node1
virsh undefine node2
virsh undefine node3
virsh destroy

1. /ansible/project2 생성

mkdir /ansible/project2; cd /ansible/project2

2. vagrant init

vagrant init

6.1 키 생성

  • 키 생성
ssh-keygen -q -f ~/.ssh/id_rsa -N ""

3. vi Vagrantfile을 열어서 아래의 내용을 만족하도록 프로비저닝한다.

인스턴스   box      public network    private network
server  centos/7   지정하지 말것              10.10.10.10
node1                                        10.10.10.11
node2                                        10.10.10.12
node3                                        10.10.10.13
  • vi Vagrantfile 파일 수정
vi Vagrantfile
Vagrant.configure("2") do |config|
######### Ansible server #########
  config.vm.define "server" do |cfg|
    cfg.vm.box = "centos/7"
    cfg.vm.host_name = "server"
    cfg.vm.network "private_network", ip: "10.10.10.10"
    cfg.vm.network "forwarded_port", guest: 22, host:60011, auto_correct: true, id: "ssh"
    cfg.vm.provision "shell", inline: "yum install -y epel-release"
    cfg.vm.provision "shell", inline: "yum install -y ansible"
    cfg.vm.provision "file", source: "~/.ssh/id_rsa",
      destination: "~/.ssh/id_rsa"
  end

######### Ansible node1 #########
  config.vm.define "node1" do |cfg|
    cfg.vm.box = "centos/7"
    cfg.vm.host_name = "node1"
    cfg.vm.network "private_network", ip: "10.10.10.11"
    cfg.vm.network "forwarded_port", guest: 22, host:60012, auto_correct:
true, id: "ssh"
  end

######### Ansible node2 #########
  config.vm.define "node2" do |cfg|
    cfg.vm.box = "centos/7"
    cfg.vm.host_name = "node2"
    cfg.vm.network "private_network", ip: "10.10.10.12"
    cfg.vm.network "forwarded_port", guest: 22, host:60013, auto_correct:
true, id: "ssh"
  end

######### Ansible node3 #########
  config.vm.define "node3" do |cfg|
    cfg.vm.box = "centos/7"
    cfg.vm.host_name = "node3"
    cfg.vm.network "private_network", ip: "10.10.10.13"
    cfg.vm.network "forwarded_port", guest: 22, host:60014, auto_correct:
true, id: "ssh"
  end
end

4. vagrant up -> 이후 virsh list --all, vagrant ssh server/vagrant ssh node1 등으로 접속하여 상태확인

[root@localhost project2]# virsh list --all
 Id    Name                           State
----------------------------------------------------
 2     project2_node3                 running
 3     project2_node2                 running
 4     project2_node1                 running
 5     project2_server                running
vagrant ssh server
vagrant ssh node1
vagrant ssh node2
vagrant ssh node3

5. Vagrantfile 중 server 항목에 ansible 설치를 추가하여 provision 한다.

  • vi Vagrantfile server 항목에 추가
    cfg.vm.provision "shell", inline: "yum install -y epel-release"
    cfg.vm.provision "shell", inline: "yum install -y ansible"
vagrant provision

6. 로컬에서(211.183.3.99 호스트) 새로운 키페어를 만든다.

private key는 server로 전달
public key는 node들에게 전달

7. vagrant ssh server로 진입하여 /etc/ansible/hosts 파일에 node들의 ip를 등록하고 ansible all -m ping이 성공해야 한다.

/etc/ansible/hosts
# 맨 아래에 추가
10.10.10.11
10.10.10.12
10.10.10.13
  • 종료
vagrant halt
  • 성공

또 다른 방법

[root@localhost project2]# cat Vagrantfile ; echo ------------------- ; cat ssh_config_mykey
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.define "server" do |cfg0|
    cfg0.vm.box = "centos/7"
    cfg0.vm.host_name = "server"
    cfg0.vm.network "private_network", ip: "10.10.10.10"
    cfg0.vm.network "forwarded_port", guest: 22, host: 20010, id: "ssh"
    cfg0.vm.provision "shell", inline: "yum -y install epel-release && yum -y install ansible"
    cfg0.vm.provision "file", source: "mykey.pem", destination: "/home/vagrant/.ssh/mykey.pem"
    cfg0.vm.provision "shell", inline: "chmod 600 /home/vagrant/.ssh/mykey.pem"
    cfg0.vm.provision "file", source: "ssh_config_mykey", destination: "/home/vagrant/ssh_config_mykey"
    cfg0.vm.provision "shell", inline: "cat /home/vagrant/ssh_config_mykey >> /etc/ssh/ssh_config"
    cfg0.vm.provision "shell", inline: "echo '10.10.10.11' >> /etc/ansible/hosts"
    cfg0.vm.provision "shell", inline: "echo '10.10.10.12' >> /etc/ansible/hosts"
    cfg0.vm.provision "shell", inline: "echo '10.10.10.13' >> /etc/ansible/hosts"
    cfg0.vm.provision "shell", inline: "ssh-keyscan 10.10.10.11 >> /home/vagrant/.ssh/known_hosts"
    cfg0.vm.provision "shell", inline: "ssh-keyscan 10.10.10.12 >> /home/vagrant/.ssh/known_hosts"
    cfg0.vm.provision "shell", inline: "ssh-keyscan 10.10.10.13 >> /home/vagrant/.ssh/known_hosts"
    cfg0.vm.provision "shell", inline: "chown vagrant.vagrant /home/vagrant/.ssh/known_hosts"
  end

  config.vm.define "node1" do |cfg1|
    cfg1.vm.box = "centos/7"
    cfg1.vm.host_name = "node1"
    cfg1.vm.network "private_network", ip: "10.10.10.11"
    cfg1.vm.network "forwarded_port", guest: 22, host: 20011, id: "ssh"
    cfg1.vm.provision "file", source: "mykey.pem.pub", destination: "/home/vagrant/.ssh/mykey.pem.pub"
    cfg1.vm.provision "shell", inline: "cat /home/vagrant/.ssh/mykey.pem.pub >> /home/vagrant/.ssh/authorized_keys"
  end

  config.vm.define "node2" do |cfg2|
    cfg2.vm.box = "centos/7"
    cfg2.vm.host_name = "node2"
    cfg2.vm.network "private_network", ip: "10.10.10.12"
    cfg2.vm.network "forwarded_port", guest: 22, host: 20012, id: "ssh"
    cfg2.vm.provision "file", source: "mykey.pem.pub", destination: "/home/vagrant/.ssh/mykey.pem.pub"
    cfg2.vm.provision "shell", inline: "cat /home/vagrant/.ssh/mykey.pem.pub >> /home/vagrant/.ssh/authorized_keys"
  end

  config.vm.define "node3" do |cfg3|
    cfg3.vm.box = "centos/7"
    cfg3.vm.host_name = "node3"
    cfg3.vm.network "private_network", ip: "10.10.10.13"
    cfg3.vm.network "forwarded_port", guest: 22, host: 20013, id: "ssh"
    cfg3.vm.provision "file", source: "mykey.pem.pub", destination: "/home/vagrant/.ssh/mykey.pem.pub"
    cfg3.vm.provision "shell", inline: "cat /home/vagrant/.ssh/mykey.pem.pub >> /home/vagrant/.ssh/authorized_keys"
  end
end
-------------------
Host 10.10.10.*
        User vagrant
        IdentityFile /home/vagrant/.ssh/mykey.pem

0개의 댓글