4 minute read

일지

특이 사항 없음

오늘의 할일

  • 220610 TIL 작성 및 복습

주요 키워드

CI/CD

  • Ansible을 활용한 이미지 빌드 및 배포
  • k8s와 Jenkins 통합

공부 정리

Ansible을 활용한 이미지 빌드 및 배포

Ansible을 배포작업에 포함하기

  1. 새로운 EC2 인스턴스 생성
    • 이름: Ansible
    • IP: 192.168.56.104
  2. ansible 인스턴스에 ansible 설치
    • sudo apt update
    • sudo apt -y install ansible
  3. ansible 인스턴스에 docker 설치
    • 이전 설치과정 참고
  4. ansible을 사용하여 작업을 제어할 수 있는 환경 구성
    • ~/.ansible.cfg
       [defaults]
       inventory = ./inventory.ini
      
    • ~/inventory.ini
       [ansible_host]
       192.168.56.104  ansible_connection=local
      
    • ansible 인스턴스에서 자신에게 ssh 키 기반 인증이 가능하도록 설정
    • ssh 데몬 설정에서 PasswordAuthentication 허용
      • sudo vi /etc/ssh/sshd_config
        • PasswordAuthentication yes
    • ssh 서비스 재시작
      • sudo systemctl restart ssh
    • ubuntu 사용자 패스워드 생성
      • sudo passwd ubuntu
    • ubuntu 사용자 키 생성 및 복사(ssh-keygen/ssh-copy-id)
      • ssh-keygen
      • ssh-copy-id ubuntu@192.168.56.104
    • ssh 패스워드 인증 해제
      • sudo vi /etc/ssh/sshd_config
        • PasswordAuthentication no
    • ssh 서비스 재시작
      • sudo systemctl restart ssh

Ansible 을 사용한 이미지 빌드 및 배포 작업 구성

  1. 간단한 테스트용 플레이북 작성 ``` —
    • name: Jenkins CI/CD test playbook hosts: ansible_host tasks:
    • name: image build command: docker build -t my-hello-world ~/hello-world
    • name: container create command: docker run -d –name my-hello-world-container -p 8080:8080 my-hello-world … ```
  2. 파일을 전달하기 위한 jenkins 작업 생성
    • jenkins 메뉴에서 새로운 item - Maven 프로젝트
    • deploy-to-docker-with-ansible - 소스코드 관리
    • github
      • repository: 자신의 github 레포지토리 주소
      • (선택)credential: 앞에서 생성한 credential 사용 - 빌드
    • Root POM: pom.xml
    • Goals and options: clean install - 빌드 후 조치
    • Send build artifacts over SSH
      • SSH Server: ansible-instance (이전에 생성한)
      • Transfer 1
        • Source files: webapp/target/webapp.war
        • remove prefix: webapp/target
        • remote directory: hello-world
      • Transfer 2
        • Source files: dockerfile/Dockerfile
        • remove prefix: dockerfile
        • remote directory: hello-world
  3. 생성한 플레이북 실행 및 재실행
    • ansible-playbook cicd.yaml
  4. 플레이북 수정
  ---
  - name: Jenkins CI/CD test playbook
    hosts: ansible_host
    tasks:
    - name: image build
      command: docker build -t my-hello-world ~/hello-world
    - name: container rm
      command: docker rm -f my-hello-world-container
    - name: container create
      command: docker run -d --name my-hello-world-container -p 8080:8080 my-hello-world
  1. 모듈을 사용한 방식으로 플레이북 수정
  ---
  - name: cicd with docker module
    hosts: ansible_host
    tasks:
    - name: Build an image
      docker_image:
        build:
          path: ~/hello-world
        name: my-hello-world
        tag: latest
        push: no
        source: build
    - name: Container started
      docker_container:
        name: my-hello-world-container
        state: started
        image: my-hello-world:latest
  1. docker 모듈 실행을 위한 패키지 설치
    • pip3 install docker-py
  2. docker 모듈을 사용한 플레이북 실행
    • ansible-playbook cicd-module.yaml
  3. 테스트 완료 후 테스트에 사용한 리소스 삭제
    • docker rm -f docker ps -aq
    • docker rmi my-hello-world
    • rm ~/*.yaml
  4. 작성한 플레이북을 git에 포함 (git 로컬저장소에서)
    • mkdir playbook
    • vi playbook/cicd-module.yaml
    • 위 플레이북 내용 입력 - git add . - git commit -m “ansible” - git push origin master
  5. jenkins 기존 작업 아래에 transfer 항목 추가
    • Transfer 3
    • Source files: playbook/cicd-module.yaml
    • remove prefix: playbook
    • remote directory: hello-world
    • exec command
      • ansible-playbook ~/hello-world/cicd-module.yaml

쿠버네티스와 jenkins 통합

  • jenkins: git로컬저장소 및 관리, 어플리케이션 빌드, CI/CD 구성 담당
  • ansible : 이미지 빌드, 이미지 push
  • k8s : 어플리케이션 파드 구동

이미지 빌드 후 컨테이너 생성 대신 이미지 업로드를 수행하는 플레이북

---
- name: cicd with docker module
  hosts: ansible_host
  tasks:
  - name: Build an image
    docker_image:
      build:
        path: ~/hello-world
      name: encore0511/my-hello-world
      tag: latest
      push: yes
      source: build
      #  - name: Container started
      #    docker_container:
      #     name: my-hello-world-container
      #     state: started
      #     image: my-hello-world:latest

이미지 삭제 후 다시 빌드하는 플레이북

---
- name: cicd with docker module
  hosts: ansible_host
  tasks:
  - name: Remove image
    docker_image:
      state: absent
      name: <dockerhub_ID>/my-hello-world
      tag: latest
  #  - name: Log into DockerHub
  #    docker_login:
  #      username: docker
  #      password: rekcod
  - name: Build an image
    docker_image:
      build:
        path: ~/hello-world
      name: <dockerhub_ID>/my-hello-world
      tag: latest
      push: yes
      source: build

쿠버네티스 리소스를 배포하기 위한 오브젝트 파일 작성 (git 로컬저장소에서)

  • mkdir manifest
  • vi manifest/deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-hello-world-deployment
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: my-hello-world
      template:
        metadata:
          labels:
            app: my-hello-world
        spec:
          containers:
          - name: my-hello-world-container
            image: <dockerhub_ID>/my-hello-world
            ports:
            - containerPort: 8080
              protocol: TCP
    
  • vi manifest/nodeport.yaml ``` apiVersion: v1 kind: Service metadata: name: my-hello-world-svc spec: selector: app: my-hello-world type: NodePort ports:
    • targetPort: 8080 port: 8080 nodePort: 30080 ```

이미지 빌드 작업 및 이미지 빌드 작업에 의해 트리거된 쿠버네티스 배포 작업 생성

  1. jenkins 작업 생성 (이미지 빌드)
    • jenkins 메뉴에서 새로운 item - Maven 프로젝트
    • docker-image-build - 소스코드 관리
    • github
      • repository: 자신의 github 레포지토리 주소
      • (선택)credential: 앞에서 생성한 credential 사용 - 빌드
    • Root POM: pom.xml
    • Goals and options: clean install - 빌드 후 조치
    • Send build artifacts over SSH
      • SSH Server: ansible-instance
      • Transfer 1
        • Source files: webapp/target/webapp.war
        • remove prefix: webapp/target
        • remote directory: hello-world
      • Transfer 2
        • Source files: dockerfile/Dockerfile
        • remove prefix: dockerfile
        • remote directory: hello-world
      • Transfer 3
        • Source files: playbook/build.yaml
        • remove prefix: playbook
        • remote directory: hello-world
        • exec command
          • ansible-playbook ~/hello-world/build.yaml
  2. jenkins 작업 생성 (쿠버네티스 배포)
    • jenkins 메뉴에서 새로운 item - Maven 프로젝트
    • deploy-to-k8s - 빌드 유발
    • Build after other projects are built
      • project to watch: docker-image-build
      • 실행옵션: Trigger only if build is stable - 빌드 후 조치
    • Send build artifacts over SSH
      • SSH Server: k8s-instance
      • Transfer 1
        • Source files: manifest/*.yaml
        • remove prefix: 없음
        • remote directory: 없음
        • exec command
          • kubectl apply -f ~/manifest
  3. 현재까지 작업된 내용을 git에 반영하고 docker-image-build 작업 실행 및 트리거된 배포 작업 확인

Github 업데이트에 따른 빌드 유발 설정 (Github Webhook)

  1. jenkins VM에서 인증에 사용할 키 설정
    • ssh-keygen -t rsa -f ~/.ssh/jenkins-github
  2. 생성된 키 중 public key 내용을 github에 저장
    • cat ~/.ssh/jenkins-github.pub
    • github 레포지토리 - setting - Deploy key에서 항목 생성하여 키 추가
  3. jenkins에서 생성한 키 등록
    • jenkins 관리 - manage credential
    • global 우측 화살표 클릭 - add credential
      • SSH username and private key 선택
        • ID: 키 이름 (임의로 입력)
        • username: 키 생성시 사용한 사용자
        • private key:
          • Enter directly
            • add 버튼 클릭 후 개인키 값 입력
            • cat ~/.ssh/jenkins-github
  4. jenkins 플러그인 설치: github integration

  5. 빌드 작업 구성에서 빌드 유발 항목 추가
    • 항목 체크: GitHub hook trigger for GITScm polling
  6. github webhook 생성
    • 레포지토리 설정 - webhook
    • URL: http://:8080/github-webhook/
  7. git 로컬저장소의 파일을 수정 후 push하여 webhook에 의한 docker-image-build 작업이 트리거되는지 확인

Categories:

Updated:

Leave a comment