EKS 환경에서 CI/CD 구축하기 (5)

수정일 금, 5월 6, 2022 시간: 10:29 PM

EKS 란?

EKS란 Elastic Kubernetes Service의 약자로 AWS의 쿠버네티스 서비스입니다. Master Node가 따로 필요한 기존의 쿠버네티스와는 다르게 

EKS의 마스터 노드 (컨트롤 플레인) 는 AWS에서 관리해 주어 따로 구성 및 관리할 필요가 없다는 장점이 있습니다.

 

자세한 내용은 아래의 문서[1]를 참고 해 주세요.

[1] https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/what-is-eks.html

 

이번 장은 저희 최종 목표인 EKS 클러스터 내에 Pod를 배포하기 위해 앞장에서 다뤘던 Jenkins Pipeline에 추가 구성을 해보도록 하겠습니다.

 

kubectl 설치 및 설정

 

CI/CD로 Pod 배포를 하려면 jenkins 서버에서 해당 EKS 클러스터에 접근 할 수 있도록 kubectl이 설정되어 있어야합니다.

 

일단, jenkins 서버의 jenkins 유저로 접속 해 봅시다.

 

kubectl 설치

 

$ curl -o kubectl https://amazon-eks.s3-us-west-2.amazonaws.com/1.14.6/2019-08-22/bin/linux/amd64/kubectl

  % Total     % Received % Xferd  Average Speed   Time    Time      Time  Current

                                 Dload  Upload    Total   Spent    Left   Speed

100 41.0M  100 41.0M    0      0  8835k      0   0:00:04  0:00:04 --:--:-- 9304k

 

$ chmod +x ./kubectl

 

$ mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$HOME/bin:$PATH

 

$ echo 'export PATH=$HOME/bin:$PATH' >> ~/.bashrc

 

$ kubectl version --short --client

Client Version: v1.14.7-eks-1861c5

 

IAM AccessKey/ SecretAccessKey 설정

 

IAM 엔티티가 EKS 클러스터의 RBAC에 제어받기 때문에, Jenkins 서버에 클러스터를 생성한 IAM 계정의

Access Key를 설정 해 줍니다.

 

물론, Jenkins 서버에서만 사용하는 계정을 생성하여 최소한의 권한만 부여하는 것이 Best Practice입니다.

다른 IAM 사용자에 클러스터 액세스 권한을 주기 위해서는 아래 문서[2]를 참고 하시면 됩니다.

 

[2] https://aws.amazon.com/ko/premiumsupport/knowledge-center/amazon-eks-cluster-access/

 

aws configure 커맨드로 설정 가능하며, 파일 저장 위치는 .aws/credentials 입니다.

 

$ aws configure

AWS Access Key ID [****************IWTW]:

AWS Secret Access Key [****************5CIJ]:

Default region name [ap-northeast-2]:

Default output format [None]:

 

$ aws sts get-caller-identity

{

    "UserId": "*******************",

    "Account": "************",

    "Arn": "arn:aws:iam::************:user/sanghyeon.park"

}   

 

aws eks 커맨드로 kubeconfig 파일을 자동으로 생성합니다.

 

$ aws eks update-kubeconfig --region ap-northeast-2 --name srebgk_cluster

Added new context arn:aws:eks:ap-northeast-2:************:cluster/srebgk_cluster to /home/jenkins/.kube/config

 

$ kubectl get pods

NAME                                            READY   STATUS    RESTARTS    AGE

 

여기 까지 잘 따라 오셨다면, kubectl 설정은 끝이납니다.

 


Jenkins Pipeline 추가 구성

 

다시 Jenkins 대시보드로 돌아갑니다.

구성에 해당 Job에 들어가 Pipeline에 아래와 같이 Deployment를 배포하는 Step을 추가 해 줍니다.

 

[Stage: Deploy pod]

 

        stage('Deploy pods'){

            when {

                expression {

                    return env.dockerBuildResult ==~ /(?i)(Y|YES|T|TRUE|ON|RUN)/

                }

            }

            steps{

                script{

                    try{

                        sh """

                        sudo rm -rf deployfiles

                        mkdir deployfiles && cd deployfiles

                        #!/bin/bash

                         cat>monthly_deploy.yaml<

apiVersion: apps/v1

kind: Deployment

metadata:

  name: monthly-deployment

  labels:

    app: monthly

spec:

  replicas: 3

  selector:

    matchLabels:

      app: monthly

  template:

    metadata:

      labels:

        app: monthly

    spec:

      containers:

      - name: monthly-cont

        image: ${ECR_TASK_URI}:ver${env.BUILD_NUMBER}

        ports:

        - containerPort: 5000

EOF"""

                        sh "pwd"

                        sh "/home/jenkins/bin/kubectl apply -f /var/lib/jenkins/workspace/Deploy_SREBGK_MonthlyReport/deployfiles/monthly_deploy.yaml"

                         env.deployPodsResult=true

                    }catch(error){

                        print(error)

                         env.deployPodsResult=false

                         currnetBuild.result='FAILURE'

                    }

                    

                }

            }

            

        }

 

Script 
pipeline { 
2 
agent any 
3 
stages { 
stage('Git Clone') Z} 
20 
stage( ' Docker Build ' 
stage( ' Deploy pods 
55. 
56 
when { 
expression { 
57. 
58 
return env. dockerBui IdResuIt 
59 
60 
61. 
steps{ 
62. 
script{ 
63 
try{ 
64 
65 
sudo rm -rf deployfiles 
66 
mkdir deployfi les && cd deployfiles 
67 
/ bin/bash 
68 
cat>month ly_deploy. yaml EOF 
69 
apiVersion: apps/vl 
kind: Deployment 
70 
71 
metadata : 
72 
name: monthly-deployment 
73 
labels: 
74 
app: monthly 
75 
spec : 
76 
replicas: 3 
77 
selector: 
78 
match Labels : 
app: monthly 
79 
80 
templ ate : 
81 
metadata : 
82 
I abets: 
83 
app: monthly 
84 
spec: 
contai ners : 
85 
86 
- name: monthly-cont 
87 
image: BUILD_NUMBER} 
88 
ports : 
89 
- containerPort: 5ØØØ 
90 
EOF

 

 

 

 

전체 Script

 

pipeline {

    agent any

 

    stages {

        stage('Git Clone') {

            steps {

                script {

                    try{

                        git url: "https://$GIT_URL", branch: "master", credentialsId: "$GIT_CREDENTIALS_ID"

                        env.cloneResult=true

                    }catch(error){

                        print(error)

                        env.cloneResult=false

                         currentBuild.result='FAILURE'

                    }

                }

                

            }

        }

        stage('Docker Build'){

            when{

                expression {

                    return env.cloneResult ==~ /(?i)(Y|YES|T|TRUE|ON|RUN)/

                }

            }

            steps {

                script{

                    try{

                        sh"""

                        #!/bin/bash

                         cat>Dockerfile<

# build stage

FROM ${ECR_BASE_URI}:init as build-stage

COPY . /app

WORKDIR /app

RUN pip install -r requirements.txt

EXPOSE 8000

CMD ["gunicorn",   "--bind", "0.0.0.0:8000",  "flasktest:app", "-w", "2", "--timeout=300", "-k", "gevent"]

EOF"""

                        sh"""

                        aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin ${ECR_URI}

                        docker build -t ${env.JOB_NAME.toLowerCase()} .

                        docker tag ${env.JOB_NAME.toLowerCase()}:latest ${ECR_TASK_URI}:ver${env.BUILD_NUMBER}

                        docker push ${ECR_TASK_URI}:ver${env.BUILD_NUMBER}

                        """

                         env.dockerBuildResult=true

                    }catch(error){

                        print(error)

                         env.dockerBuildResult=false

                         currentBuild.result='FAILURE'

                    }

                }

            }

        }

        stage('Deploy pods'){

            when {

                expression {

                    return env.dockerBuildResult ==~ /(?i)(Y|YES|T|TRUE|ON|RUN)/

                }

            }

            steps{

                script{

                    try{

                        sh """

                        sudo rm -rf deployfiles

                        mkdir deployfiles && cd deployfiles

                        #!/bin/bash

                         cat>monthly_deploy.yaml<

apiVersion: apps/v1

kind: Deployment

metadata:

  name: monthly-deployment

  labels:

    app: monthly

spec:

  replicas: 3

  selector:

    matchLabels:

      app: monthly

  template:

    metadata:

      labels:

        app: monthly

    spec:

      containers:

      - name: monthly-cont

        image: ${ECR_TASK_URI}:ver${env.BUILD_NUMBER}

        ports:

        - containerPort: 5000

EOF"""

                        sh "pwd"

                        sh "/home/jenkins/bin/kubectl apply -f /var/lib/jenkins/workspace/Deploy_SREBGK_MonthlyReport/deployfiles/monthly_deploy.yaml"

                         env.deployPodsResult=true

                    }catch(error){

                        print(error)

                         env.deployPodsResult=false

                         currnetBuild.result='FAILURE'

                    }

                    

                }

            }

            

        }

    }

}

 

최종 결과

 

코드에서 master 브랜치로의 git push를 진행하고 pod가 잘 배포되는 지 확인 해 보자.

 

% git push

Total 0 (delta 0), reused 0 (delta 0), pack-reused 0

To https://git-codecommit.ap-northeast-2.amazonaws.com/v1/repos/Monthly_Report

   8bc8c23..9d1c9c3  master -> master

 

마지막으로 추가한 Deploy pods stg View에 추가된 것을 확인 할 수 있습니다

Stage View 
Average stage times: 
(Average full run time: —1 min 44s) 
Jun 28 
commit 
14:16 
Jun 28 
commit 
00:12 
Git Clone 
2s 
Docker Build 
1 min 39s 
Imin 29s 
Imin 30s 
Deploy pods 
Is 
Is

 

클러스터에 Deployment 까지 확인 할 수있습니다.

 

monthly—deployment 
srebgk—deployment 
READY 
3/3 
3/3 
—l $ kubectl get 
UP-TO-DATE 
1 
3 
3 
deploy 
AVAILABLE 
1 
3 
3 
AGE 
89d 
2m4s 
119d

 

 

이렇게 해서, EKS 환경에서 CI/CD 구축이 완료되었습니다.

개발자 분들은 코드 배포 과정에서 더이상 고통 받지 마시고 개발에만 집중하시는게 어떨까요!

 

감사합니다.

아티클이 유용했나요?

훌륭합니다!

피드백을 제공해 주셔서 감사합니다.

도움이 되지 못해 죄송합니다!

피드백을 제공해 주셔서 감사합니다.

아티클을 개선할 수 있는 방법을 알려주세요!

최소 하나의 이유를 선택하세요
CAPTCHA 확인이 필요합니다.

피드백 전송

소중한 의견을 수렴하여 아티클을 개선하도록 노력하겠습니다.