현대 오토에버 SW 스쿨 - 클라우드/클라우드

[CD] - Continuous Delivery, Deployment

yongyongMom 2024. 11. 15. 12:22
SMALL

1. 개요

  • 지속적인 배포
  • 배포를 자동화하는 것
  • 코드를 이용해서 인프라를 빠르게 배포하는 형태로 사용 - IaC : Instructure as a Code)

 

2. Ansible

1) 개요

  • 여러 개의 서버를 효율적으로 관리하기 위해 고안된 환경 구성 자동화 도구
  • 현재는 redhat 에서 개발
  • chef, puppet 도 동일한 작업을 수행해주는 도구
  • Bash shell Script :: 리눅스에서 동일한 환경을 구성하기 위해서 사용하는 가장 기초적인 방법 
    • 각종 패키지의 설치 및 설정 파일의 수정등을 위해 일괄 처리 목록 (Batch Processing List) 을 Shell Script 에 나열 후 실해하는 방식으로 작업
    • 클러스터에 존재하는 많은 서버들에 동시에 동일한 환경을 배포해야 하는 상황에서 Bash Shell Script 는 한계점이 명확함
    • bash shell script 는 환경 설정을 위해 만들어진 것이 아니며 규칙이 명확하지 않음
  • 환경의 배포와 구성을 규격화된 코드로 정의해 사용해 나가는 것이 IaC(Infrastructure as a Code)
  • IaC 의 대표적인 도구가 Ansible

 

2) Ansible 사용 환경 준비

  • 서버와 클라이언트 구조로 구성
  • chef, puppet 과 다르게 에이전트가 없는 구조
    • Ansible Command 를 입력할 수 있는 컴퓨터에서 명령을 입력하면 SSH 가 Daemon 을 이용
    • 클라이언트 컴퓨터에 접속해서 명령을 전달
  • Ansible 을 사용하기 위한 컴퓨터는 Python 이 설치되어 있어야하고 SSH 접속이 가능해야 함
  • python 확인 
pyhton3 --version
  • ansible 설치
sudo apt install software-properties-common
sudo apt-add-repository ppa:ansible/ansible
sudo apt update
sudo apt install ansible
ansible --version

 

3) Ansible 의 기본 개념

  • Inventory 
  • Ansible 에서 관리하는 모든 서버의 목록
  • 컴퓨터들은 파이썬 인터프리터가 설치되어 있어야 함
  • SSH 서버가 설치되어 있어야 함
  • /etc/ansible/hosts 에 설정
  • 기본설정
[group_name]
서버주소
서버주소
…

[webservers]
192.168.0.241
192.168.0.242
  • SSH-key 를 복사한 후 별명을 이용해서 원격 사용자를 지정
  • 퍼블릭 클라우드에서는 인벤토리를 동적으로 가져오는 기능을 제공
  • 애드훅 명령 
ansible all -m ping

구성 형식
ansible <타겟> -m 명령 -a 인자

 

4) playhook

  • 개요
    • 서버의 설정 방법을 기술한 구성 파일
    • 각 서버에서 수행해야 할 일련의 작업을 이 파일에 정의 
    • yaml 파일로 작성
  • 샘플 작성 및 실행
    • playbook.yaml 파일을 만들고 작성
      ---
      - hosts: localhost #수행될 컴퓨터로 inventory에 있는 컴퓨터 이름이나 all 또는 localhost
        become: yes
        become_method: sudo #관리자 모드로 수행
        tasks:
        - name: ensure apache is at the latest version
          apt: name=apache2 state=latest
        - name: ensure apache is running
          service: name=apache2 state=started enabled=yes
  • 실행 
ansible-playbook playbook.yaml
  • 확인
systemctl status apache2
  • playbook 을 실행할 때 --f 스레드 개수를 설정하면 테스크를 병렬로 수행할 수 있음
  • playbook 은 멱등성을 가짐
    • 이전 내용과 동일한 부분은 작업을 다시 수행하지 않고 이전의 내용을 이용

 

5) Handler

  • 변경이 발생하면 알려주는 이벤트 방식의 메커니즘 구현을 위한 개념
  • 주요 개념
    • handler: 알림을 받으면 실행할 태스크를 지정
    • notify: 실행할 핸들러를 지정
  • playbook.yaml 파일 수정
    ---
    - hosts: localhost #수행될 컴퓨터로 inventory에 있는 컴퓨터 이름이나 all 또는 localhost
      become: yes
      become_method: sudo #관리자 모드로 수행
      tasks:
      - name: ensure apache is at the latest version
        apt: name=apache2 state=latest
      - name: ensure apache is running
        service: name=apache2 state=started enabled=yes
      - name: copy configuration
        copy:
          src: foo.conf
          dest: /etc/foo.conf
        notify:
        - restart apache
      handlers:
      - name: restart apache
        service:
          name: apache2
          state: restarted
  • foo.conf 파일 생성
touch foo.conf
  • 재실행 - 아무런 변화가 없음
ansible-playbook playbook.yaml
  • foo.conf 수정
echo "something" > foo.conf
  • 재실행
ansible-playbook playbook.yaml

 

6) 변수 사용

  • ansible 은 만들어서 사용할 수 있는 기능을 제공
  • 변수를 만들 때 vars 속성에 이름과 값을 설정
    • jinja 구문을 이용해서 변수를 이용
    • jinja 구문이 Django 에서 python 의 문법을 이용해서 HTML 을 만드는 구문이기도 함
  • playbook.yaml 파일 수정
- hosts: localhost #수행될 컴퓨터로 inventory에 있는 컴퓨터 이름이나 all 또는 localhost
  become: yes
  become_method: sudo #관리자 모드로 수행

  vars:
    http_port: 8080

  tasks:
  - name: print port number
    debug:
      msg: "Port number: {{ http_port }}"

 

7) 롤

  • 재사용의 개념
  • role : 다른 playbook 에 삽입해 재사용할 수 있도록 구조화된 playbook
  • role 은 동일한 디렉터리 구조를 가짐
templates/
tasks/
handlers/
vars/
defaults/
meta
---
- hosts: localhost
  become: yes
  become_method: sudo
  roles:
  - role: geelingguy.mysql

 

8) ansible 갤럭시

  • 공통적으로 사용할 수 있는 role 요소를 저장하고 다른 사람과 공유할 수 있도록 해주는 docker hub 와 유사한 사이트
  • 사용할 수 있는 role 의 목록:https://galaxy.ansible.com 에 존재
  • 캘럭시를 이용한 설치 
ansible-galaxy install geerlingguy.mysql
ansible-playbook playbook.yaml

 

9) docker 및 kubenetest 와 ansible

  • 유사한 점
  • 환경 구성 방법을 제공
    • ansible 은 script 를 사용하는데 docker 는 전체 환경을 컨테이너에 캡슐화
  • 의존성
    • 여러 서비스들을 같은 또는 다른 호스트로 배포하는 방법을 제공
  • 확장성 
    • ansible 은 inventory 와 호스트 그룹을 통해서 서비스를 확장하고 쿠버네티스는 컨테이너 수를 늘리거나 줄이는 방식을 선택
  • 구성 파일을 사용한 자동화
    • docker 는 Dockerfile 에 쿠버네테스는 Deployment.yaml 파일 같은 yaml 파일에 ansible은 playbook.yaml 파일을 이용
  • ansible 의 장점
    • docker/kubenets 를 운영하는 경우 호스트 머신에 대한 설정과 관리가 필요
    • 이미지화 할 수 없는 애플리케이션 이용
      • 이미지화하지 않는 애플리케이션
        성능이나 보안 또는 특정 하드웨어 요구 사항이나 레거시 연동 문제임
    • inventory
      • ansible 은 모든 서버에 대한 정보를 저장하는 inventory 를 사용해서 물리적 인프라를 관리하는 방식을 제공함
    • cloud provisioning 
      • 쿠버네티스 클러스터의 프로비저닝이나 클라우드에 쿠버네티스 설치 가능
  • 도커 이미지를 위한 yaml 파일을 생성
---
- hosts: localhost
  become: yes
  become_method: sudo
  tasks:
  - name: Hazecast Container
    community.docker.docker_container:
      name: hazelcast
      image: busybox
      exposed_ports:
      - 5701
  • kubenetes 사용을 위한 yaml
---
- hosts: localhost
  become: yes
  become_method: sudo
  tasks:
  - name: Create Namespace
    kubernetes.core.k8s:
      name: my-namespace
      api_version: v1
      kind: Namespace
      state: present

 

3.  Kubenetes 환경에서의 CI/CD

1) 개요

  • 리소스를 등록할 때는 kubectl 명령을 사용
    • 실제 운영 환경에서는 수동을 kubectl 명령어를 실행하는 것은 권장하지 않음
    • 휴먼 에러가 발생하거나 관리 가능한 규모가 확장되지 않은 문제점 떄문
  • 일반적으로 자동으로CI/CD 를 수행하는 파이프라인을 구축하는 것을 권장
  • 애플리케이션의 소스 코드나 Ansible, Chef 등의 인프라 구성 코드는 git 저장소에서 관리하는 것이 일반적
  • 쿠버네티스에서 지속적인 배포를 실시하는 경우 git 저장소에 저장된 mainifest 파일을 kubectl 등으로 자동 배포하는 구조를 만들어야 함

 

2) GitOps 

  • git 을 이용한 CI/CD
  • 애플리케이션 업데이트 를 git 저장소를 통해 실시 -> 수동으로 manifest 변경 / 수동으로 kubectl apply 명령 수행 X
    • 애플리케이션 업데이트:: deployment 등의 리소스등을 사용하는 도커 이미지 변경 같은 쿠버네티스 조작
  • 과정
    1. 애플리케이션 소드 코드를 변경
    2. 애플리케이션 테스트를 수행
    3. 애플리케이션 이미지 생성 - 애플리케이션 컴파일이나 빌드 수행
    4. 애플리케이션 이미지를 컨테이너 레지스트리에 푸시
    5. 디플로이먼트 등의 매니페스트를 변경 - 이미지 변경
    6. kubectl apply 같은 명령을 실시해서 클러스터 반영
  • git Ops 에서는 하나의 애플리케이션에 2개의 저장소 필요
    • 하나는 애플리케이션 소스 코드용 저장소
    • 하나는 kubenetes 와 manifest 관련 저장소
  • 소스 코드를 변경하고 저장소에 변경을 커밋 시 자동으로
    • 애플리케이션 테스트와 도커 이미지빌드
    • 도커 레지스트리로 푸시 (jenkins) 하고 menifext를 가진 저장소에 Push Request 를 생성
    • PR 기반으로 쿠버네티스 menifest 변경점 확인
    • 문제가 없다면 병합
    • kubenetes 에서 동작하고 있는 배포 에이전트와 같은 구성 요소의 저장소의 menifest 를 가져와 적용
  • menifest 저장소를 별도로 만드는 이유
    • 인프라 변경이 하나의 저장소에서 끝
    • 해당 저장소 -> 클러스터와 상태가 같음 -> 복원이 쉬움
  • GitOps 는 kubeCon + CloudNativeCon 에서도 자주 발표되어 많은 기업이 주목
  • jenkins X 도 gitOps 사상을 담은 도구 중 하나
  • CI Ops
    • kubenetes 에 배포할 때 배포 operator 가 menifest 저장소에서 데이터를 가져와 자신의 클러스터에 manifest 를 적용
    • kubenetes 에 배포할 때 CI 도구가 kubectl 명령을 사용 
      -> 외부에서 kubenetes 클러스터에 manifest 적용
    • 보안이 Git Ops 보다 약함 
    • 기본의 배포 사상과 유사해 사용하기 편리함

 

3) 매니페스트 체크 도구 - Kubeval

  • 개요
    • menifest 파일의 YAML 구조가 특정 API 버전을 준수하는지 검증할 수 있는 OSS (Open Source Sofrware)
  • 설치
  • menifest 확인 방법
kubeval 파일경로(디렉토리 경로) --kubernetes-version 버전

실습

  • 쿠버네티스 배포를 위한 deployment 생성
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-deployment
  annotations:
    max-replicas: 100
spec:
  replicas: 3
  selector:
    matchLabels:
      role: sample-app
  template:
    metadata:
      labels:
        role: sample-app
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.16
  • 배포
kubectl apply -f sample.yaml
# 에러가 발생: 어노테이션에는 문자열이나 null 만 가능

#문법 검사 수행
kubeval ./sample.yaml --kubernetes-version 1.18.1
# 에러가 발생

# annotations 아래에 있는 값을 “100” 으로 변경하고 실행
  • 도커 허브 컨테이너 이미지도 공개되어 있어 컨테이너 이미지를 사용하는 CI 에도 통합이 가능

 

4) menifest 체크 도구 - Conftest

  • 개요
    • 매니페스트 파일을 유닛 테스트하는 OSS
    • OpenPolicyAgent 에서 사용되는 Rego 라는 언어로 작성
  • 수행할 수 있는 테스트
    • 특수 권한 컨테이너가 있는지
    • 리소스에 부여하는 레이블 룰을 정한 경우 필요한 레이블이 누락되지 않았는지
    • 이미지 태그가 latest 는 아닌지
  • 사용법 : rego 언어로 작성된 규칙을 만들고 검사를 수행
  • 설치 : https://www.conftest.dev/install/
  • 작업
    • policy 디렉터리를 생성 
    • 정책을 담은 rego 파일을 생성
    • #Deployment 는 matchLabels 와 labels 가 app으로 시작해야 한다는 규칙
      package main
      
      deny[msg] {
        input.kind == "Deployment"
        not (input.spec.selector.matchLabels.app == input.spec.template.metadata.labels.app)
        msg = sprintf("Pod Template 과 Selector는 app 으로 시작해야 합니다.: %s", [input.metadata.name])
      }
    • 확인한 yaml 파일을 생성 : success.yaml
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: success-deployment
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: success-app
        template:
          metadata:
            labels:
              app: success-app
          spec:
            containers:
            - name: nginx-container
              image: nginx
    • 검사
      conftest test ./success.yaml
    • 확인할 yaml 파일을 생성 : fail.yaml
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: success-deployment
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: success-app
        template:
          metadata:
            labels:
              app: success-app
          spec:
            containers:
            - name: nginx-container
              image: nginx
      
      # 검사 
      conftest test ./fail.yaml

5) GitOps 의 CD 도구 : ArgoCD

  • 개요
    • GitOps 를 구현하기 위한 CD 도구
    • 지정한 저장소를 모니터링하고 kubenetes 클러스터에 manifest 를 적용
  • 설치
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

실습

  • URL: https://github.com/itstudy001/cicd.git
  • 경로 : argocd/manifest 디렉터리에 yaml 파일이 존재
  • argocd 로 위 경로에 있는 menifest 파일을 현재 클러스터에 적용하기 위한 yaml 파일을 생성
apiVersion: argoproj.io/v1alpha1
kind: application
metadata:
  name: sample-cd
  namespace: argocd
spec:
  project: default
  #적용할 Manifest 의 경로를 설정
  source:
    repoURL: https://github.com/itstudy001/cicd.git
    targetRevision: 1st-edition
    path: argocd/manifests
    directory:
      recurse: true
  #적용 대상으로 기본은 자신의 클러스터
  destination:
    server: https://kubernetes.defalut.svc
    namespace: default
  #동기화 옵션 설정
  syncPolocy:
    automated:
      prune: true  #저장소에서 삭제된 리소스를 자동으로 삭제하는 옵션
      selfHeal: true #자동 복구하는 옵션
  • 명령 수행
kubectl apply -f sample

 

6) Skafford

  • 구글이 개발한 오픈 소스로 docker 및 kubenetes 용 빌드와 배포를 자동화하는 도구
  • 애플리케이션 소스 코드가 변경된 것을 감지하면 도커 이미지 빌드, 도커 레지스트리 푸시, 쿠버네티스 클러스터의 배포를 일원화해서 관리하는 도구
  • 개발이 진행되는 단계에서 소스 코드 변경 횟수가 많아짐 
    • 소스 코드로 만들어진 도커 이미지도 늘어남
    • 레지스트리에 저장하지 않고 쿠버네티스 클러스터에 배포할 수 있음
    • 정해진 타이밍에 도커 이미지를 레지스트리에 푸시 할 수 있음
  • skafford 설치
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 && \

sudo install skaffold /usr/local/bin/
  • skafford 확인
skafford version
  • golang 설치
apt install golang
  • 컴파일 및 실행 : 소스코드 작성 : main.go
package main

import "fmt"

func main(){
        fmt.Print("Hello Go")
}
  • 바이너리 파일을 만들지 않고 바로 실행 
go run main.go
  • 바이너리 파일을 만들고 실행
go build main.go
./main
반응형
LIST