DevOps

CI/CD 파이프라인 구축하기 - 5.2 (Jenkins, Ansible, Kubernetes(EKS) 병합하기)

우잉~ 2024. 12. 18. 21:12

아래 포스팅에서 이어집니다!

https://wooinge.tistory.com/145

 

CI/CD 파이프라인 구축하기 - 5.1 (파이프라인 구축 전 kubectl, eksctl 설정 및 yaml 파일 작성하기)

아래 포스팅에서 이어집니다!https://wooinge.tistory.com/144 CI/CD 파이프라인 구축하기 - 4.2 (Ansible Playbook을 이용한 Docker 컨테이너 배포)아래 포스팅에서 이어집니다.https://wooinge.tistory.com/143 CI/CD 파이

wooinge.tistory.com

 



 

저번 포스팅에서는 eks 클러스터를 생성하기 위한 사전 설정을 주로 진행했었다.

그리고 쿠버네티스 pod, service, deployment를 생성하는 매니페스트 파일을 작성하는 방법을 알아보았다.

 

이제는 Ansible과 통합함으로써 최종 CI/CD 파이프라인을 완성할 것이다.

최종 CI/CD Pipeline 모습

 

[CI/CD 파이프라인 구축 실습 목표]

  • Docker hub repository 이미지를 쿠버네티스로 가져오기
  • Ansible, Kubernetes 통합하기
  • Jenkins 콘솔에서 쿠버네티스 배포 프로젝트 생성하기
  • 빌드 프로젝트와 배포 프로젝트 통합하기

 

* 이전 포스팅에서 생성된 pod나 service가 있다면 모두 삭제하고 시작하겠다.

 

모든 리소스 삭제

 

1. Kubernetes 서버에 Docker Hub Image 가져오기

우리는 pod, service(load balancer) 파일을 작성하여 생성하였다.

하지만 pod 생성 yaml 파일을 이용하여 애플리케이션을 배포하게 된다면,  장애가 생겼을 때 복구할 수 있는 방법이 없기 때문에 난감하다.

그래서 docker hub repository에 올려둔 image를 이용할 것이다. 문제가 생길 경우, 도커 허브에 있는 이미지를 재생성할 수 있도록 말이다.

 

배포와 서비스를 생성하는 파일을 작성한다.

# regapp-deployment.yml

apiVersion: apps/v1 
kind: Deployment
metadata:
  name: hyun-regapp
  labels: 
     app: regapp

spec:
  replicas: 2 
  selector:
    matchLabels:
      app: regapp

  template:
    metadata:
      labels:
        app: regapp
    spec:
      containers:
      - name: regapp
        image: hyunjung98/regapp
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
# regapp-service.yml

apiVersion: v1
kind: Service

metadata:
  name: hyun-service
  labels:
    app: regapp

spec:
  selector:
    app: regapp

  ports:
    - port: 8080
      targetPort: 8080

  type: LoadBalancer

 

 

두 코드를 살펴보면

service의 selector = deployment의 labels를 뜻한다. 이를 통해 로드 밸런서는 어느 서버에 부하 분산을 해야하는지 파악할 수 있다.

deployment의 containerPort는 service의 targetPort와 동일하게 작성해줌으로써 실제 컨테이너 포트로 요청을 보낼 수 있게 된다.

 

regapp-deployment.yml에서 replicas를 3으로 변경한 뒤 파일을 이용해 배포를 생성할 것이다.

> kubectl apply -f regapp-deployment.yml

yml 파일을 이용한 deployment 생성 완료

 

pod 상세 정보

 

deployment를 생성했으니 service도 똑같이 진행한다.

yml 파일을 이용한 service(load balancer) 생성
로드밸런서 생성 완료

 

실제 AWS 콘솔에서도 로드 밸런서가 생성된 것을 확인할 수 있다.

kubeclt describe 명령을 이용하여 생성한 service의 상세 정보를 확인하면 Endpoints가 총 3개인 것을 확인할 수 있다.

이는 pod의 ip와 동일하다.

로드 밸런서의 엔드포인트 주소 확인

 

로드밸런서 DNS 이름:8080/webapp에 접속하면 성공적으로 통신이 되고 있는 것을 확인할 수 있다.

로드 밸런서의 DNS 이름을 이용한 톰캣 서버 접속

 

+++ 참고로 Replica(복제본)은 최소 개수와 다를 것이 없다! 복제본의 개수를 3개로 지정했었는데, 직접 pod를 지운다해도 다시 생성되는 모습을 확인할 수 있다.

replica 설정으로 인해 다시 생성된 pod

 

 

2. Ansible에 Kubernetes 통합하기

이제 ansible과 kubernetes가 통신할 수 있도록 설정할 것이다.

현재 진행할 부분

 

[각 서버에서 해야할 일]

bootstrap server(kubernetes) ansible node
ansadmin 계정 생성 및 설정 통신 위한 hosts 파일 추가
ansadmin에게 관리 권한 부여하기 위한 visudo 수정 ssh key를 bootstrap server에 복사
패스워드 기반 인증 허용 통신 테스트

 

먼저 Bootstrap server에서 ansadmin 계정을 추가하고 비밀번호를 설정한다.

visudo 명령을 입력하여 패스워드 입력 없이 모든 작업을 수행할 수 있도록 설정한다.

/etc/ssh/sshd_config 파일을 열어 패스워드 기반 인증을 허용하도록 주석을 제거한다.

ansadmin 생성
권한 부여
패스워드 인증 허용

모든 작업을 수행하면 sshd를 업데이트한다.

업데이트

 

다음은 ansible 서버에서 진행해야 한다.

ansadmin 계정으로 전환한다.

ansadmin 계정 로그인

 

파일을 구분하기 위해 mv 명령어를 이용하여 알아보기 쉬운 파일명으로 수정하였다!

배포를 위해 더 명확한 이름으로 수정

 

이제 Ansible의 인벤토리 파일을 생성할 것이다.

/opt/docker 디렉토리에 hosts 파일을 새로 생성한다. → 기본 인벤토리 파일 X 새로 인벤토리 파일을 생성할 것이다.

bootstrap server ip 확인

 

그룹 이름은 각각 kubernetes, ansible로 지정한다.

로컬 서버 자체를 제어하고 싶다면 localhost를 추가할 수도 있다.

 

/opt/docker/hosts 파일 작성

 

다음은 Bootstrap server에 ssh key를 복사하는 작업을 진행해야 한다.

ssh-copy-id [복사할 서버의 IP 주소]를 입력하고 ansadmin 계정의 비밀번호를 입력하면 된다.

키 복사 완료

 

이제 제어가 잘 되는지 확인하기 위해서 명령어를 사용한다.

이런! 에러가 나버렸다.

아무것도 명시해주지 않고 사용하는 명령어는 Ansible이 기본 인벤토리 파일을 사용하여 제어를 하게 된다.

그래서 -i 옵션을 이용하여 사용하려는 인벤토리 파일을 명시해줘야 한다.

일반 인벤토리 파일을 사용하려고 해서 에러가 났다.

 

인벤토리 파일 명시하여 제어 테스트

 

 

3. ansible playbook 생성하여 Kubernetes에 배포하기

이제 Ansible playbook을 이용하여 쿠버네티스에 배포하는 과정을 진행할 것이다.

애플리케이션 배포, 서비스를 생성하는 파일을 작성한다.

# kube_deploy.yml

---
- hosts: kubernetes
  become: true

  tasks:
    - name: deploy regapp on kubernetes
      command: kubectl apply -f /root/regapp-deployment.yml

 

# kube_service.yml

---
- hosts: kubernetes
  become: true
  tasks:
    - name: create service for regapp
      command: kubectl apply -f /root/regapp-service.yml

 

원활한 테스트를 위해 기존에 있던 리소스는 모두 삭제하였다.

 

이런! 무언가 에러가 생겨버렸다. 해당 디렉토리나 파일을 찾을 수 없다고 한다.

에러 발생

 

그래서 관리자 권한을 부여하는 것 대신 user를 root로 등록하여 커맨드를 실행하는 내용으로 변경하였다.

# kube_deploy.yml 수정

---
- hosts: kubernetes
  # become: true
  user: root

  tasks:
    - name: deploy regapp on kubernetes
      command: kubectl apply -f regapp-deployment.yml
# kube_service.yml 수정

---
- hosts: kubernetes
  # become: true
  user: root
  tasks:
    - name: create service for regapp
      command: kubectl apply -f regapp-service.yml

 

그랬더니 또 에러가 발생해버렸는데, root 계정에 ssh 키가 존재하지 않기 때문에 생겨난 에러이다.

root 계정에 키를 복사해주면 정상적으로 실행된다.

root 계정에 key 없음
키 복사를 위해 root 계정 비밀번호 설정

 

키 복사

 

실행이 성공적으로 되었다.

실행 성공

 

배포 확인

 

로드 밸런서도 동일하게 생성해준다.

로드밸런서 생성 완료

 

 

 

4. 젠킨스 프로젝트 생성

이제 젠킨스 콘솔로 돌아가 쿠버네티스 배포 프로젝트를 생성한다.

배포만을 할 것이기 때문에 Freestyle project를 선택해준다.

정말 배포만 할 예정이기 때문에 Send build artifacts over SSH를 선택하고 ansible playbook 명령어 라인을 입력해주기만 하면 끝이다.

배포 생성 명령 입력

정상적으로 빌드되는 것을 확인할 수 있다.

젠킨스 콘솔을 활용한 빌드 및 배포

 

 

이제 모두 정상적으로 돌아가는 것을 확인했으므로 한 yml 파일에 모든 명령을 작성하겠다.

kube_deploy.yml 파일에 배포, 로드밸런서 모두 생성하는 명령이 들어가있기 때문에 service 생성 커맨드를 삭제해준다.

 

 

5. 빌드와 배포 통합하기

젠킨스에서 생성한 배포 프로젝트의 이름을 변경하였다.

이름 변경

 

이제 RegAppCDJob 프로젝트와 연결할 RegAppCIJob 프로젝트를 생성한다.

빌드 후 도커 허브에 이미지를 업로드하는 프로젝트를 복사한다.

RegAppCIJob 프로젝트 생성

이미지를 도커 허브로 넘기는 커맨드만 남겨둔다.

이미지 생성 커맨드 입력

 

코드 수정 후 자동 빌드하는 모습을 확인할 수 있다.

※ ansible 서버에서 꼭 docker를 활성화한 뒤 빌드하길!

빌드 성공

 

 

이제 두 프로젝트를 함께 자동으로 빌드하기 위해서 Build other projects를 이용해 트리거를 걸어준다.

 

 

 

RegAppCIJob이 모두 빌드되면 RegAppCDJob이 빌드되도록 설정했기 때문에 깃허브 레포지토리에서 코드가 변경될 때 두 프로젝트 모두 빌드가 자동으로 진행되는 것을 확인할 수 있다.

변경된 빌드 아티팩트

 

docker hub도 살펴보면 자동으로 이미지가 레포지토리에 업로드된 것을 확인할 수 있다.

 

새 pod로 업데이트하기 위해서는 rollout restart 명령을 사용한다.

태스크 추가
새로 생성된 pod

 

로드밸런서 DNS 이름을 이용하여 /webapp에 접속할 수 있고, 코드 변경도 자동으로 적용되는 것을 확인할 수 있다.

변경 사항 적용 완료

 

 

이렇게 CI/CD 파이프라인 구축 실습은 마무리되었다~!