공부하기싫어
article thumbnail

 

EKS 클러스터는 terraform 으로 만들어져있는 상태

cloud9 을 통해 EKS 에 연결된 EC2 로 들어가서 작업

terraform 문서는 추후 업데이트

 

사전 작업

  • 보안그룹

문제의 보안그룹

 

node group 인스턴스

eks 가 초기에 보안그룹 2개를 할당하는것 같다

eks-cluster-sg 랑

eks-node, eks-cluster 인데

eks-node 보안그룹이 저렇게 제한된 포트 커넥트를 가지고 있어서 이걸 제거해 줘야 multiple tag 오류가 나지 않았다

 

  • Helm 설치
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 > get_helm.sh
chmod 700 get_helm.sh
./get_helm.sh

helm version --short | cut -d + -f 1

  • aws-load-balancer-controller 설치
helm repo add eks https://aws.github.io/eks-charts
helm repo list
helm repo update
helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=project-myeks --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller --set image.repository=602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/amazon/aws-load-balancer-controller

 

 

CI

젠킨스 서버 생성

EKS 클러스터 내 jenkins pod 만들어서 실습할때

docker in docker 를 구현해야 하는데

권한 문제 때문에 docker 가 설치가 안되서 jenkins 서버를 별도로 만들어줬다

 

t3a.small, ubuntu

[inbound : 22- 0.0.0.0/0 , 8080 - 0.0.0.0/0] [outbound : ALL - 0.0.0.0/0]

 

이 실습에선 안해줬는데

나중에 webhook 구현을 위해 EIP 를 할당해줘야 한다

 

도커 설치

$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh

웹에서 스크립트를 받아 개발환경에 빠르고 간단하게 사용 가능하다

권장하는 방법은 아님

 

Jenkins 설치

sudo docker run -itd --name jenkins -p 8080:8080 -p 50000:50000 -v /docker/jenkins:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock -e TZ=Asia/Seoul -u root jenkins/jenkins:latest

 

Jenkins container에 docker, kustomize 설치

docker exec -it 젠킨스컨테이너이름 bash

curl -fsSL get.docker.com -o get-docker.sh 
sh get-docker.sh

curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"  | bash 
mv kustomize /usr/local/bin 
kustomize version

 

ECR 생성

ecr

 

 

Jenkins 환경구성

server IP:8080 으로 접속

unlock jenkins
권장 플러그인 설치
설치중
jenkins 설치 완료

 

Jenkins 환경 구성

대쉬보드 - jenkins 관리 - 플러그인 관리 에서

docker-build-step , docker plugin, docker pipeline, AWS ECR 다운로드

plugin manager

 

installing

플러그인 설치에 따라 container 를 재시작 해야 할 수도 있다

이후 대쉬보드 - jenkins 관리 - manage Credentials 이동

global - add Credentials

 

음.. 원래 ECR 로 하려고 했는데

계정 access key 는 최대 2개까지 만들 수 있고

그 조원 분들이 아마 각각 하나씩 가지고 계신거 같은데

미리 좀 얻어놓을껄

지금생각났다

 

어쩔수 없이 github, hub.docker 로 자격증명을 만들어줌

 

new credentials

 

Github 자격증명 생성

kind : Username with Password

Username : Github 계정명

Password : github persnal access token

ID : 젠킨스 내에서 자격증명을 가리키기 위해 사용할 변수 이름

 

Docker Hub 자격증명 생성

kind : Username with Password

Username : Docker Hub 계정명

Password : Docker Hub persnal access token ( hub.docker - account settings - security - new access tokens )

ID : 젠킨스 내에서 자격증명을 가리키기 위해 사용할 변수 이름

 

ECR 자격증명 생성

kind : AWS credentails

Accesskey : aws 사용자 access key

SecretAccessKey : aws 사용자 secret access key

ID : 젠킨스 내에서 자격증명을 가리키기 위해 사용할 변수 이름

credentials

Jenkinsfile

git dir

 

pipeline {
  agent any

  // 해당 스크립트 내에서 사용할 로컬 변수들 설정-
  // 레포지토리가 없으면 생성됨
  // Credential들에는 젠킨스 크레덴셜에서 설정한 ID를 사용
  environment {
    //dockerHubRegistry = 'cyaninn/demo-eks-cicd' 
    //dockerHubRegistryCredential = 'credential-dockerhub'
    awsecrRegistry = '605680513436.dkr.ecr.ap-northeast-2.amazonaws.com/groom-pj-app-for-eks'
    awsecrRegistryCredentail = 'credential-AWS-ECR'
    githubCredential = 'credential-github'
    gitEmail = 'sounddevice3@gmail.com'
    gitName = 'cyaninn-entj'
  }

  stages {

    // 깃허브 계정으로 레포지토리를 클론한다.
    stage('Checkout Application Git Branch') {
      steps {
        checkout([$class: 'GitSCM', branches: [[name: '*/main']], extensions: [], userRemoteConfigs: [[credentialsId: githubCredential, url: 'https://github.com/cyaninn-entj/mini-cicd-eks-project.git']]])
      }
      // steps 가 끝날 경우 실행한다.
      // steps 가 실패할 경우에는 failure 를 실행하고 성공할 경우에는 success 를 실행한다.
      post {
        failure {
          echo 'Repository clone failure' 
        }
        success {
          echo 'Repository clone success' 
        }
      }
    }

    stage('Docker Image Build') {
      steps {
        // 도커 이미지 빌드
        sh "docker build . -t ${awsecrRegistry}:${currentBuild.number}"
        sh "docker build . -t ${awsecrRegistry}:latest"
      }
      // 성공, 실패 시 슬랙에 알람오도록 설정
      post {
        failure {
          echo 'Docker image build failure'
          //slackSend (color: '#FF0000', message: "FAILED: Docker Image Build '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
        }
        success {
          echo 'Docker image build success'
          //slackSend (color: '#0AC9FF', message: "SUCCESS: Docker Image Build '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
        }
      }
    }  

    stage('Docker Image Push') {
      steps {
        // 젠킨스에 등록한 계정으로 ECR 에 이미지 푸시
        withDockerRegistry([url: "https://${awsecrRegistry}", credentialsId: "ecr:ap-northeast-2:${awsecrRegistryCredentail}"]) {
          sh "docker push ${awsecrRegistry}:${currentBuild.number}"
          sh "docker push ${awsecrRegistry}:latest"
          // 10초 쉰 후에 다음 작업 이어나가도록 함
          sleep 10
        } 
      }
      post {
        failure {
          echo 'Docker Image Push failure'
          sh "docker rmi ${awsecrRegistry}:${currentBuild.number}"
          sh "docker rmi ${awsecrRegistry}:latest"
          //slackSend (color: '#FF0000', message: "FAILED: Docker Image Push '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
        }
        success {
          echo 'Docker Image Push success'
          sh "docker rmi ${awsecrRegistry}:${currentBuild.number}"
          sh "docker rmi ${awsecrRegistry}:latest"
          //slackSend (color: '#0AC9FF', message: "SUCCESS: Docker Image Push '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
        }
      }
    }

    // updated docker image 태그를 git push 
    stage('Deploy') { 
      steps {
        // git 계정 로그인, 해당 레포지토리의 main 브랜치에서 클론
        git credentialsId: githubCredential,
            url: 'https://github.com/cyaninn-entj/mini-cicd-eks-project.git',
            branch: 'main'  
        /*
        // 이미지 태그 변경 후 메인 브랜치에 푸시
        sh "git config --global user.email ${gitEmail}"
        sh "git config --global user.name ${gitName}"
        sh "cd prod && kustomize edit set image ${awsecrRegistry}:${currentBuild.number}"
        sh "git add kustomization.yaml"
        sh "git status"
        sh "git commit -m 'update the image tag'"
        sh "git branch -M main"
        sh "git push -u origin main"
        */
      }
    }
  }
}

 

Dockerfile

# Use the official image as a parent image.
FROM node:current-slim

# Set the working directory
WORKDIR /home

# Copy the file from your host to your current location.
COPY app/ /home/

# Run the command inside your image filesystem
RUN npm install

# Inform Docker that the container is listening on the specified port at runtime
EXPOSE 3000

# Run the specified command within the container.
CMD ["npm", "start"]

# Copy the rest of your app's source code from your host to your image filesystem.

 

kustomization

kustomization.yaml

namePrefix: prod-
resources:
- deployment.yaml
- service.yaml

 

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-nginx-app
spec:
  replicas: 1
  revisionHistoryLimit: 3
  selector:
    matchLabels:
      app: demo-nginx-app
  template:
    metadata:
      labels:
        app: demo-cicd-nginx-app
    spec:
      containers:
      - image: cyaninn/demo-eks-cicd:latest
        name: demo-nginx-app
        ports:
        - containerPort: 80

 

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: demo-nginx-app
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: demo-nginx-app

 

git repo 생성 + 연동

pipline

아이템 이름과 pipline 선택

definition

definition 에 SCM 을 선택하고

scm 은 git 으로 선택

repo url 넣고 자격증명 선택

 

script path

jenkinsfile 은 깃허브 디렉토리 최상단에 위치해야한다고 함

그래서 그냥 파일이름만 적고

브랜치 수정해줌

 

확인

+ cd prod
+ kustomize edit set image cyaninn/demo-eks-cicd:5
Error: error converting YAML to JSON: yaml: line 8: mapping values are not allowed in this context
Usage:
  kustomize edit set image [flags]

kustomizez 파일이 잘못됬나보다

일단

 

hub.docker

그래도 hub.docker 에 이미지 빌드는 잘 되있는 모습

 

ECR

access 키 발급 때문에 나중에 repository 를 ecr 로 바꿔주었다.

 

 

Webhook

깃허브 리포지토리에서 setting - webhoook 에서 webhook을 추가해준다

일단 이렇게 add 해놨고

( payload URL 은 http:// 붙여줬다 )

ip:포트 뒤에 /github-webhook/ 을 붙여줘야 작동한다

 

그리고 jenkins 에 만들어놨던 pipeline 아이템에 들어가서 구성으로 들어간 후

github intergration 설치

플러그인을 설치해주고

 

triggers

기존 만든 pipeline 아이템의 구성으로 들어가서

hook trigger 로 트리거를 선택해준다.

 

push

이후 간단하게 코드 수정해서 push 작업을 해봤는데

(이때 webhook 주소에 그냥 ip:port 만 넣었었는데 webhook 을 캐치하지 못했음)

 

changes found

github hook log 에 가서 확인해보니 push 변화를 잡아냈고

 

build

이후 빌드까지 알아서 잘 하는 모습

 

이렇게 CI 끝