아래 포스팅에서 이어집니다!
https://wooinge.tistory.com/145
저번 포스팅에서는 eks 클러스터를 생성하기 위한 사전 설정을 주로 진행했었다.
그리고 쿠버네티스 pod, service, deployment를 생성하는 매니페스트 파일을 작성하는 방법을 알아보았다.
이제는 Ansible과 통합함으로써 최종 CI/CD 파이프라인을 완성할 것이다.
[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
deployment를 생성했으니 service도 똑같이 진행한다.
실제 AWS 콘솔에서도 로드 밸런서가 생성된 것을 확인할 수 있다.
kubeclt describe 명령을 이용하여 생성한 service의 상세 정보를 확인하면 Endpoints가 총 3개인 것을 확인할 수 있다.
이는 pod의 ip와 동일하다.
로드밸런서 DNS 이름:8080/webapp에 접속하면 성공적으로 통신이 되고 있는 것을 확인할 수 있다.
+++ 참고로 Replica(복제본)은 최소 개수와 다를 것이 없다! 복제본의 개수를 3개로 지정했었는데, 직접 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 파일을 열어 패스워드 기반 인증을 허용하도록 주석을 제거한다.
모든 작업을 수행하면 sshd를 업데이트한다.
다음은 ansible 서버에서 진행해야 한다.
ansadmin 계정으로 전환한다.
파일을 구분하기 위해 mv 명령어를 이용하여 알아보기 쉬운 파일명으로 수정하였다!
이제 Ansible의 인벤토리 파일을 생성할 것이다.
/opt/docker 디렉토리에 hosts 파일을 새로 생성한다. → 기본 인벤토리 파일 X 새로 인벤토리 파일을 생성할 것이다.
그룹 이름은 각각 kubernetes, ansible로 지정한다.
로컬 서버 자체를 제어하고 싶다면 localhost를 추가할 수도 있다.
다음은 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 계정에 키를 복사해주면 정상적으로 실행된다.
실행이 성공적으로 되었다.
로드 밸런서도 동일하게 생성해준다.
4. 젠킨스 프로젝트 생성
이제 젠킨스 콘솔로 돌아가 쿠버네티스 배포 프로젝트를 생성한다.
배포만을 할 것이기 때문에 Freestyle project를 선택해준다.
정말 배포만 할 예정이기 때문에 Send build artifacts over SSH를 선택하고 ansible playbook 명령어 라인을 입력해주기만 하면 끝이다.
정상적으로 빌드되는 것을 확인할 수 있다.
이제 모두 정상적으로 돌아가는 것을 확인했으므로 한 yml 파일에 모든 명령을 작성하겠다.
kube_deploy.yml 파일에 배포, 로드밸런서 모두 생성하는 명령이 들어가있기 때문에 service 생성 커맨드를 삭제해준다.
5. 빌드와 배포 통합하기
젠킨스에서 생성한 배포 프로젝트의 이름을 변경하였다.
이제 RegAppCDJob 프로젝트와 연결할 RegAppCIJob 프로젝트를 생성한다.
빌드 후 도커 허브에 이미지를 업로드하는 프로젝트를 복사한다.
이미지를 도커 허브로 넘기는 커맨드만 남겨둔다.
코드 수정 후 자동 빌드하는 모습을 확인할 수 있다.
※ ansible 서버에서 꼭 docker를 활성화한 뒤 빌드하길!
이제 두 프로젝트를 함께 자동으로 빌드하기 위해서 Build other projects를 이용해 트리거를 걸어준다.
RegAppCIJob이 모두 빌드되면 RegAppCDJob이 빌드되도록 설정했기 때문에 깃허브 레포지토리에서 코드가 변경될 때 두 프로젝트 모두 빌드가 자동으로 진행되는 것을 확인할 수 있다.
docker hub도 살펴보면 자동으로 이미지가 레포지토리에 업로드된 것을 확인할 수 있다.
새 pod로 업데이트하기 위해서는 rollout restart 명령을 사용한다.
로드밸런서 DNS 이름을 이용하여 /webapp에 접속할 수 있고, 코드 변경도 자동으로 적용되는 것을 확인할 수 있다.
이렇게 CI/CD 파이프라인 구축 실습은 마무리되었다~!
'DevOps' 카테고리의 다른 글
CI/CD 파이프라인 구축하기 - 5.1 (파이프라인 구축 전 kubectl, eksctl 설정 및 yaml 파일 작성하기) (1) | 2024.12.17 |
---|---|
CI/CD 파이프라인 구축하기 - 4.2 (Ansible Playbook을 이용한 Docker 컨테이너 배포) (0) | 2024.12.16 |
CI/CD 파이프라인 구축하기 - 4.1 (Ansible 서버 구축 및, Jenkins, Docker 통합) (0) | 2024.12.16 |
CI/CD 파이프라인 구축하기 - 3.2 (Docker 컨테이너 자동 빌드 및 자동 배포) (0) | 2024.12.13 |
CI/CD 파이프라인 구축하기 - 3.1 (Docker 설정 및 Jenkins SSH server 설정하기) (0) | 2024.12.13 |