Docker을 Ansible로 구축하기

TAEWOO HA·2023년 7월 17일
0

Docker

목록 보기
1/7

Ansible

  • 구성관리 도구
  • 서비스들은 준비된 상태를 원하는데 그 상탤르 유지해주는 도구

예시)
¡ Ansible이 설치된 VM 만들기
¡ 빈 작업 디렉토리 생성 후 실습
¡ 윈도우 예시
¡ C:\Grepp\Docker-Lab
¡ 리눅스 예시
¡ ~/grepp/docker-lab

Vagrantfile

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "ubuntu/focal64"
config.vm.hostname = "ansible.local"
config.vm.provider "virtualbox" do |vb|
vb.memory = 2048

end

if Vagrant.has_plugin?("vagrant-vbguest")
  config.vbguest.auto_update = false
end

config.vm.network "private_network", ip: "192.168.0.20"
config.vm.synced_folder ".", "/vagrant", type: "rsync", rsync__exclude: [".git/"]

config.vm.provision "shell", inline: <<-SHELL
  export DEBIAN_FRONTEND=noninteractive
  sudo apt -y update
  sudo apt install -y ca-certificates apt-transport-https
  sudo apt install -y software-properties-common curl
  sudo apt install -y python3-pip python-is-python3
  sudo add-apt-repository --yes --update ppa:ansible/ansible
  sudo apt install -y ansible
  sudo pip3 install docker
SHELL
end

Ansible.LOCAL 머신 부팅 및 접속

vagrant up

==> ip를 변경해야함

vagrant ssh

ansible --version

Ansible에 호스트 등록하기

NGINX 서비스 시작하기

vm$ ansible localhost -b -c local -m service -a "name=nginx state=started"
-b
¡ 원격 실행되는 대상 서버에서 어떤 사용자에 의해 실행되는 지 여부
¡ -b 는 root 사용자를 의미함

-c local
¡ 대상 서버가 자기 자신인 경우
¡ ssh 가 필요 없음 è local 연결로 부여
¡ 일반적으로는 ssh 사용

-m service
¡ service 모듈을 이용함 선언

-a “name=nginx state=started”
¡ -m 에 기술한 모듈에 전달하는 인수
¡ name=nginx è 이름이 nginx 인 서비스에 대해
¡ state=started è 상태가 시작된 상태여야 함

Localhost
¡ 인벤토리에 기재된 서버 중에서 명령을 수행하는 대상
¡ /etc/ansible/hosts 에 기재함

GIT으로 PLAYBOOK 샘플 가져오기

sudo apt install -y git

¡ 앞의 샘플을 CLONE 하기
git clone https://github.com/devops-book/ansible-playbook-sample.git

playbook 실행

Clone 한 ansible-playbook-sample 디렉토리로 이동

vm$ ansible-playbook –i development site.yml

  • 인벤토리 , 개발용으로 플레이북 실행

상태

¡ OK:결과가 이미 예상했던 대로 되었다.
è 아무것도 할 필요가 없었음
¡ SKIP: 명시적인 조건에 의해 TASK 자체가 SKIP됨 (실행 안함)
¡ CHANGED: Task 실행에 의해 예상대로 변경됨
¡ UNREACHABLE: 원래의 실행 대상 호스트에 도달 불가 (Error)
¡ FAILED: 실행 대상 호스트에 도달했지만, 조작에 실패함 (Error)

적용사항 확인

vm$ curl localhost

PRODUCTION 으로 변경하기

vm$ ansible-playbook –i production site.yml

SITE.YML

¡ hosts: webservers
¡ 실행대상 결정
¡ 인벤토리 파일에 정의된 그룹

¡ become: yes
¡ Root 계정을 사용할 것인지
정함

¡ connection: local
¡ 연결 방법을 정함

¡ roles:

  • common
  • nginx
    ¡ roles 경로에 정의된
    수행 TASK를 포함

인벤토리 파일 : 실행 대상 정의

¡ hosts: webservers 에서 webservers 는 어디에 정의되어 있는가?
¡ -i 옵션 è 인벤토리 지정
¡ -i development è development 파일이 인벤토리 파일
¡ -i production è production 파일이 인벤토리 파일

¡ [섹션 이름] : 그룹 설정
¡ [그룹이름:옵션]
¡ webservers:children 섹션
¡ development-webservers 그룹을 포함함
¡ development-webservers 섹션
¡ localhost 를 포함함 è 즉, webservers는 localhost 1개

ROLE 파일 : 실행 내용 정의

¡ 앞에서 수정했던 roles/OOOO/tasks/main.yml
¡ OOOO 은 role의 이름 è site.yml 에서 언급하여 포함시킴
¡ YAML 형식으로 정의
¡ 모듈에 의해 동작이 처리됨
¡ yum : … è ansible의 yum 모듈로 처리
¡ apt : … è ansible의 apt 모듈로 처리

환경에 의한 설정 변경

¡ vars
¡ 인벤토리의 환경 변수는 group_vars 에 정의
¡ group_vars/인벤토리섹션.yml // env: "development" // hello, {{ env }} ansible
¡ template
¡ roles/nginx/templates/index.html.j2 파일 참고하기 (JINJA 형식)

인프라 구성 관리 도구

¡ 인프라 구성 관리 도구의 특징
¡ 선언적
¡ 추상화
¡ 수렴화 ( convergence )
¡ 멱등성 ( idempotence )
¡ 간소화

선언적?

¡ 구성 정보에 의해 설정 대상의 “상태"가 명확하게 기재
¡ è 상태를 파악할 수 있는 것
¡ è 선언적

¡ “미챌 드한”은 구성 관리 도구 è 선언적 언어
¡ (O)
“서버가 어떤 상태로 존재했으면 좋겠다”고 생각하는 상태를 설명하는 것
¡ (X)
어떻게 하고 싶은 것인가 하는 작업을 기술하는 것이 아님

추상화?

¡ 구성 정보를 대상 환경의 미세한 차이에 따라 별도로 구분하여 기
술하지 않음
¡ è 코드 실행의 전문성을 배제
¡ 예) Ubuntu / Debian 등 운영체제의 미세한 차이에 따라 구성 관리 기술(표
현)이 바뀌지 않음

¡ 구성 정보를 추상적으로 작성
¡ Web 서버, DB 서버와 같이 서버의 상태 자체를 추상화 가능
¡ 개발자
¡ 전제가 되는 환경을 명확하게 인식해야 할 필요 없음
¡ 예) OS의 차이, 패키지 관리자(yum, apt-get, snap)의 차이

수렴화?

¡ Convergence
¡ 대상의 상태가 어떠한 상태라고 하더라도, 기대했던 상태로 변경되는 것

¡ 시간의 흐름과 상태의 정보 분리
¡ 이전 파일의 내용에서 특정 부분의 변경되어야 할 때..
¡ 스크립트로 작성하는 경우, awk, sed 사용
è 이전 파일이 기대했던 내용과 다르다면? è 아마도 실패할 가능성 높음
¡ 수렴화 è 이전 상태와 관계 없이 원하는 결과로 귀결

멱등성?

¡ Idempotence
¡ 몇 번을 실행해도 같은 결과를 얻을 수 있는 성질

¡ 선언적 + 수렴화의 결합 개념
¡ 인프라 구성 관리에서 멱등성의 의미
¡ 멱등성이 담보되지 않은 Shell Script
¡ 이전 상태 취득, 조건 분기(if ) 에 의해 조작 수행을 분명하게 정의
¡ 멱등성이 있는 도구가 있다면?
¡ 도구에 의한 처리 è 기술(표현)의 간결화
¡ 잘못된 상태에서 반복 실행 è 결과가 달라지지 않음 è 안심할 수 있음

간소화

기술한 설정 è 실행의 자동화

¡ 구성 관리 도구를 통해 구성 정보 기반으로
¡ 대상에 대한 설정을 신속하게 수행
¡ 여러 대를 동시에 기계적으로 수행 가능 è 실행 속도가 빠름

¡ 간소화 관점에서 다른 장점
¡ Portability : 텍스트 형식으로 팀 내 공유가 쉬움
¡ Review : 텍스트 파일 è 변경 사항의 파악이 용이함 (diff ) , 추상화된 내용의 기술 è 짧은 리뷰 시간
¡ Version 관리 : 문제가 있는 경우, 이전 버전으로 되돌릴 수 있음, 환경을 고정시킬 수 있음 (서비스 Update 문제)
¡ Open Source

인프라 구성 관리도구가 가져다 주는 것

¡ 구축 절차를 이해하기 어렵다
¡ “선언적” 기술 방법 è 상태가 수렴화
¡ 절차가 아닌 결과만 바라봄

¡ 설정을 추가할 수 없다.
¡ 모든 설정은 “멱등성”과 “수렴화”에 의해 의존 관계 해방
¡ 기존 파일에서 일부만 고치겠다 è 할 수 없음

¡ 구축 절차를 다른 환경에서 유용하기 어렵다.
¡ “추상화” 기술에 의해 OS 등의 환경 조건을 걱정 안함
¡ 약간의 다른 환경에 활용하는 것(적용X)은 다루지 않음

실습 ) Docker을 설치하는 Playbook 만들기

main.yml

- name: Add Docker GPG apt Key
  apt_key:
    url: https://download.docker.com/linux/ubuntu/gpg
    state: present

- name: Add Docker Repository
    apt_repository:
        repo: deb https://download.docker.com/linux/ubuntu focal stable
        state: present

- name: Update apt and install docker-ce
    apt:
        name: docker-ce
        state: latest
        update_cache: true
  • docker-instlal

main.yml(2)

- name: Pull Docker Registry image
  community.docker.docker_image:
          name: registry
          source: pull

- name: Create directory for registry config.yml
  file:
          path: /etc/docker/registry
          state: directory

- name: Configure registry config.yml
  copy:
          dest: /etc/docker/registry/config.yml
          content: |
            proxy:
              remoteurl: https://registry-1.docker.io

- name: Create docker registry container
  community.docker.docker_container:
          name: registry
          image: registry
          detach: true
          recreate: true
          restart_policy: unless-stopped
          mounts:
                - type: bind
                  source: /etc/docker/registry/
                  target: /etc/registry/
          ports:
                - 5000:5000
          state: started

- name: Update daemon.json
  copy:
          dest: /etc/docker/daemon.json
          content: |
                  {
                          "registry-mirrors": ["http://localhost:5000"]
                  }

- name: Restart docker daemon
  systemd:
          name: docker
          state: restarted
  • docker-registry

site.yml

---
- hosts: localhost
  become: yes
  roles:
    - docker-install
    - docker-registry

결과

vagrant@ansible:~/ansible-playbook-sample$ ansible-playbook site.yml

PLAY [localhost] ****************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************
ok: [localhost]

PLAY RECAP **********************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

나는 이미 설치를 해놓은 상태라 변화가 없다.

1개의 댓글

comment-user-thumbnail
2023년 7월 18일

뛰어난 글이네요, 감사합니다.

답글 달기