Skip to content

skarltjr/GKE_K8s_CI_CD

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

33 Commits
 
 

Repository files navigation

GKE_K8s_CI_CD

GKE를 활용한 쿠버네티스 클러스터 구축 및 젠킨스CI / argo CD 구성해보기

  • 스크린샷 2022-03-10 오후 10 16 41
목표 및 진행 방향 정리
1. 소스코드 레포지토리에서 변동 사항이 발생
2. 웹훅 트리거 -> 젠킨스에서 소스코드 변동 사항을 반영
    -> 빌드 -> 새로운 이미지 생성 및 태깅 -> 도커허브 푸쉬 -> 별도의 manifest repo안 deployment.yaml을 새로운 이미지 태그로 업데이트
3. argo cd는 manifest repo 변동사항을 바탕으로 재배포    
  
- https://github.com/skarltjr/ci_cd_test 는 코드 레포지토리
- 별도의 k8s manifest repository 

1. GKE 클러스터 구축

  • 스크린샷 2022-03-09 오후 1 14 58
  • 돌발상황을 고려하여 정적 버전을 선택
  • default-pool에서 노드의 성능을 선택할 수 있지만 여기서는 기본 세팅을 따르기로한다.
  • 만들기 선택!

2. cloud shell setting

  • 스크린샷 2022-03-09 오후 1 25 42
  • 1번을 클릭하여 cloud shell을 열고
  • 2번 - 클러스터 연결을 눌렀을 때 나오는 명령어를 복사하여
  • 3번 - 쉘에 붙여넣으면 kubectl이 자동으로 활성화!!
  • 이용준비는 완료!

3. jenkins 설치

4. jenkins ci 파이프라인 구성

도커허브에 이미지 푸쉬하기위해 젠킨스에서 도커허브에 접근할 수 있도록 credential발급
manage credentials -> jenkins -> Global credentials -> add 
유저네임 패스워드는 도커허브 계정
id는 pipeline구성시 활요할거니까 기억하기

추가로 deployment.yaml service.yaml은 gitops repo에 존재하고 나중에 이미지가 새로 빌드되었을 때 해당 레포에 변경이 반영되야한다
그래서 깃허브 credential도 동일하게 만들어준다. 이때 비밀번호는 토큰으로

도커허브 credential & github credential을 젠킨스에 생성해둔다.
이미지 생성을 위한 도커파일을 작성하자

FROM openjdk:11-jdk AS builder
COPY gradlew .
COPY gradle gradle
COPY build.gradle .
COPY settings.gradle .
COPY src src
RUN chmod +x ./gradlew
RUN ./gradlew bootJar

FROM openjdk:11-slim
# 위에서 빌드한 jar 파일을 실행해 주기 위해 다시 JDK 11 버전을 베이스로 설정합니다.

COPY --from=builder build/libs/*.jar springboot-sample-app.jar
VOLUME /tmp
EXPOSE 8080
# builder를 통해 생성된 jar 파일을 이미지로 가져옵니다.
# 8080 포트를 공개한다고 명시합니다.

ENTRYPOINT ["java", "-jar", "/springboot-sample-app.jar"]
# 가져온 jar 파일을 실행시킵니다.
배포 스크립트. 
파이프라인을 구성해보자
pipeline{
    agent any

    environment {
        dockerHubRegistry = 'skarltjr/k8s'
        dockerHubRegistryCredential = 'docker-hub'
        githubCredential = 'github'
    }

    stages {
        stage('check out application git branch'){
            steps {
                checkout scm
            }
            post {
                failure {
                    echo 'repository checkout failure'
                }
                success {
                    echo 'repository checkout success'
                }
            }
        }
        stage('build gradle') {
            steps {
                sh  './gradlew build'
                sh 'ls -al ./build'
            }
            post {
                success {
                    echo 'gradle build success'
                }
                failure {
                    echo 'gradle build failed'
                }
            }
        }
        stage('docker image build'){
            steps{
                sh "docker build . -t ${dockerHubRegistry}:${currentBuild.number}"
                sh "docker build . -t ${dockerHubRegistry}:latest"
            }
            post {
                    failure {
                      echo 'Docker image build failure !'
                    }
                    success {
                      echo 'Docker image build success !'
                    }
            }
        }
        stage('Docker Image Push') {
            steps {
                withDockerRegistry([ credentialsId: dockerHubRegistryCredential, url: "" ]) {
                    sh "docker push ${dockerHubRegistry}:${currentBuild.number}"
                    sh "docker push ${dockerHubRegistry}:latest"

                    sleep 10 /* Wait uploading */
                }
            }
            post {
                    failure {
                      echo 'Docker Image Push failure !'
                      sh "docker rmi ${dockerHubRegistry}:${currentBuild.number}"
                      sh "docker rmi ${dockerHubRegistry}:latest"
                    }
                    success {
                      echo 'Docker image push success !'
                      sh "docker rmi ${dockerHubRegistry}:${currentBuild.number}"
                      sh "docker rmi ${dockerHubRegistry}:latest"
                    }
            }
        }
        stage('K8S Manifest Update') {
            steps {
                sh "ls"
                sh 'mkdir -p gitOpsRepo'
                dir("gitOpsRepo")
                {
                    git branch: "main",
                    credentialsId: githubCredential,
                    url: 'https://github.com/skarltjr/kube-manifests.git'
                    sh "sed -i 's/k8s:.*\$/k8s:${currentBuild.number}/' deployment.yaml"
                    sh "git add deployment.yaml"
                    sh "git commit -m '[UPDATE] k8s ${currentBuild.number} image versioning'"
//                     sshagent(credentials: ['19bdc43b-f3be-4cb9-aa1d-9896f503e3e8']) {
//                         sh "git remote set-url origin git@github.com:skarltjr/kube-manifests.git"
//                         sh "git push -u origin main"
//                     }
                    withCredentials([gitUsernamePassword(credentialsId: githubCredential,
                                     gitToolName: 'git-tool')]) {
                        sh "git remote set-url origin https://github.com/skarltjr/kube-manifests"
                        sh "git push -u origin main"
                    }
                }
            }
            post {
                    failure {
                      echo 'K8S Manifest Update failure !'
                    }
                    success {
                      echo 'K8S Manifest Update success !'
                    }
            }
        }

    }
}


참고로 여기서 헤맸다.
깜빡하고 도커 파이프라인 플러그인설치를 안함 젠킨스에.

sh "sed -i 's/k8s:.*\$/k8s:${currentBuild.number}/g' deployment.yaml" 를 통해 
deployment.yaml에 있는 image: skarltjr/k8s:{jenkins build number}중 k8s부터 뒤 모든 부분을  k8s:${currentBuild.number} 
새로 푸쉬된 이미지 태그로 갈아끼운다-> yaml수정이 된다.

sed 커맨드는 참고: https://m.blog.naver.com/hanajava/220595096628
배포 manifest를 작성하자
참고로 해당 manifest는 별도의 레포지토리 https://github.com/skarltjr/kube-manifests / 소스코드 레포랑 별개다

apiVersion: v1
kind: Service
metadata:
  labels:
    app: k8s
  name: k8s
spec:
  type: LoadBalancer
  selector:
    app: k8s
  ports:
    - port: 8080
      targetPort: 8080

---      
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: k8s
  name: k8s
spec:
  replicas: 3
  selector:
    matchLabels:
      app: k8s
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: k8s
    spec:
      containers:
      - name: k8s
        image: {dockerhub}/k8s:{jenkins build number}
        ports:
          - containerPort: 8080
  • 드디어 완성!
  • 이제 소스코드 레포지토리 변경사항 -> 웹훅 -> 젠킨스를 통해 빌드&이미지 새로 구성&이미지 푸쉬 -> k8s manifest repository update가 완료!
  • 스크린샷 2022-03-09 오후 11 40 58
  • 스크린샷 2022-03-10 오후 7 27 07
  • 스크린샷 2022-03-10 오후 7 25 40

5. argo CD 구성 준비

지금까지 CD를 위한 CI를 구성했다.
이제는 새로운 이미지 태그로 변경되어 manifest레포에 푸쉬되면 이를 바탕으로 argo가 재배포하도록 할 것이다.

앞에서 젠킨스는 쿠버네티스 클러스터와 직접적인 연관이 없기에 이를 별도로 관리하는것이 더 좋다고 생각했다.
argo cd의 경우 직접적으로 클러스터내에 배포를 수행해야하기에 클러스터에 띄우고자한다.

6. argo 설치

  • 스크린샷 2022-03-10 오후 10 26 13
  • kubectl create namespace argocd // 네임스페이스 생성
  • kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
  • 스크린샷 2022-03-10 오후 10 29 42
argo가 잘 띄워진걸 확인할 수 있다.
여기서 살펴볼부분은 argo server service가 현재 clusterIp로 동작
직접 접근을 위해 해당 부분을 LoadBalancer로 변경해준다.
  • kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
  • 스크린샷 2022-03-10 오후 10 31 40
  • service의 external-ip로 접근해보자 / 나는 https://35.222.118.22
  • 패스워드 확인 kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
  • 초기 username = admin / password = 바로위에서 확인
  • 스크린샷 2022-03-10 오후 10 43 04

6. argo app 생성

  • 우리가 관리할 프로젝트를 구성하자
  • 먼저 private repo접근을 위해 설정
  • 스크린샷 2022-03-10 오후 10 57 11
  • 참고로 비밀번호는 마찬가지로 토큰으로
  • new app
  • 스크린샷 2022-03-10 오후 11 05 04
  • manifest repository는 private으로 루트에 바로 manifest파일들이 있다
  • 스크린샷 2022-03-10 오후 10 48 35
  • 스크린샷 2022-03-10 오후 10 51 07
  • 바로 위에서 네임스페이스를 지정했기때문에 쿠버네티스에 네임스페이스 생성 springboot-ns
  • 스크린샷 2022-03-10 오후 11 03 00

7. 확인해보자

지금 현재 클러스터에 어떤 배포도 일어나지 않았다.
이제 소스코드를 변경하면 새로운 이미지가 생겨나고 이를 적용한 deployment.yaml을 바탕으로 배포가 자동 진행되는지 확인해보자

todo

github actions 공부하고 젠킨스 대체하기

About

GKE를 활용한 쿠버네티스 클러스터 구축 및 젠킨스CI / argo CD 구성해보기

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published