Kubernetes – CI/CD 파이프라인 구성

By | 2022년 11월 28일
Table of Contents

Kubernetes – CI/CD 파이프라인 구성

소스 배포부터 k8s 클러스터 배포까지의 일련의 과정을 설치합니다.

. . . . . . . . . . . . . . . . . .

기본구조

사전 준비

k8s 클러스터 구성

여기, 여기 를 참조하여 클러스터를 구성합니다.

Jenkins 설치

설치

여기 를 참조하여 Jenkins 를 설치합니다.

Jenkins 추가설정

아래 Jenkins Plugin 을 설치해 줍니다.

kubernetes
docker

아래 아이피로의 접근을 방화벽에서 허용해줍니다.(Github webhook)
접속하는 포트는 30088 입니다.

"192.30.252.0/22",
"185.199.108.0/22",
"140.82.112.0/20"

여기 를 참조하여 Personal Access Token 을 생성합니다.

Private Docker Repository 설치

여기 를 참조하여 Repository 를 설치합니다.

ArgoCD 설치

여기 를 참조하여 ArgoCD 를 설치합니다.

개발자가 소스 push

프로젝트 루트에 Dockerfile 을 추가하고 아래 내용을 추가합니다.

FROM openjdk:11.0.6-jre
EXPOSE 8080
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

Github 가 Jenkins 에 노티

Github Webhook 설정

Github private repo 로 이동 후,
Settings > Webhooks 으로 이동한다.

  • Payload URL : http://worker public ip:30088/github-webhook/
  • Content type : application/json

Jenkins 아이템 생성

젠킨스 아이템을 Pipeline 으로 생성하고 아래 script 를 입력합니다.
위에서 생성한 Personal Access Token 으로 접근합니다.

node {
    stage("Get Source") {
        git url: "https://ghp_a16NFKcFmOXXXXXXXXXXXXXX@github.com/skyer9/TestPrivate.git",
            branch: "master"
    }
}

Build now(지금 빌드) 를 클릭해서 소스를 가져오는지 확인합니다.

소스 빌드

node {
    stage("Get Source") {
        git url: "https://ghp_a16NFKcFmOXXXXXXXXXXXXXX@github.com/skyer9/TestPrivate.git",
            branch: "master"
    }

    stage("Build") {
        sh "chmod 700 gradlew"
        sh "./gradlew clean"
        sh "./gradlew bootJar"
    }
}

빌드가 이루어지는지 확인합니다.

webhook 체크

젠킨스 아이템에 GitHub hook trigger for GITScm polling 을 체크해 줍니다.

소스를 Github 에 push 해서 정상적으로 빌드가 이루어지는지 확인합니다.

Jenkins 가 Docker image 생성 후 Private repo 에 배포

Kubernetes 플러그인 설정

여기 를 참조하여 플러그인을 설정해 줍니다.

Jenkins 아이템 수정

pipeline {
    agent {
        kubernetes {
            defaultContainer 'jnlp'
            yaml """
spec:
  dnsPolicy: Default       # 이게 왜 필요할까?
  containers:
    - name: docker
      image: docker:latest
      command:
        - cat
      tty: true
      privileged: true
      volumeMounts:
        - name: dockersock
          mountPath: /var/run/docker.sock
  volumes:
    - name: dockersock
      hostPath:
        path: /var/run/docker.sock
    - name: m2
      hostPath:
        path: /root/.m2
            """
        }
    }

    stages {
        stage("Get Source") {
            steps {
                git url: "https://ghp_a16NFKXXXXXXXXXXXXXXXXX@github.com/skyer9/TestPrivate.git",
                branch: "master"
            }
        }

        stage("Build") {
            steps {
                sh "chmod 700 gradlew"
                sh "./gradlew clean"
                sh "./gradlew bootJar"
            }
        }

        stage('Docker Build') {
            steps {
                container('docker') {
                    sh "docker build -t 10.101.46.90/skyer9/testprivate:0.1.${build_number} ."
                    sh "docker build -t 10.101.46.90/skyer9/testprivate:latest ."
                }
            }
        }
    }
}

docker build 시 아이피는 docker-repository 의 클러스터 아이피입니다.

Private Docker Repository 에 push

push 는 https 만 허용하므로 아래 설정변경을 통해,
http push 를 허용해 준다.

마스터 노드에서 클러스터 아이피를 확인한다.

kubectl get svc -n repository
NAME                TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
docker-repository   NodePort   10.105.115.134   <none>        80:30099/TCP   10m

워커 노드의 도커 서비스를 수정한다.

sudo vi /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd ...... --insecure-registry 10.105.115.134
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo docker info
        stage('Docker Build') {
            steps {
                container('docker') {
                    sh "docker build -t 10.105.115.134/skyer9/testprivate:0.1.${build_number} ."
                    sh "docker build -t 10.105.115.134/skyer9/testprivate:latest ."
                    sh "docker info"
                    sh "docker push 10.105.115.134/skyer9/testprivate:0.1.${build_number}"
                    sh "docker push 10.105.115.134/skyer9/testprivate:latest"
                }
            }
        }

아래 명령으로 업로드된 이미지를 확인할 수 있다.

curl http://localhost:30099/v2/_catalog

Private Docker Repository 에 https 적용

여기 를 참조하여 사설인증서를 생성합니다.

젠킨스 설정파일은 아래처럼 수정해 줍니다.

pipeline {
    agent {
        kubernetes {
            defaultContainer 'jnlp'
            yaml """
spec:
  dnsPolicy: Default       # 이게 왜 필요할까?
  containers:
  - name: docker
    image: docker:latest
    command:
    - cat
    tty: true
    privileged: true
    volumeMounts:
    - name: private-rootca-crt
      mountPath: /etc/docker/certs.d/docker-repository.repository.svc.cluster.local/ca.crt
      subPath: rootCA.crt
      readOnly: true
    - name: dockersock
      mountPath: /var/run/docker.sock
  volumes:
  - name: private-rootca-crt
    configMap:
      name: private-rootca.crt
  - name: dockersock
    hostPath:
      path: /var/run/docker.sock
  - name: m2
    hostPath:
      path: /root/.m2
            """
        }
    }

    stages {
        stage("Get Source") {
            steps {
                git url: "https://ghp_ttA52XKpXXXXXXXXXXXXXXX@github.com/skyer9/TestPrivate.git",
                branch: "master"
            }
        }

        stage("Build") {
            steps {
                sh "chmod 700 gradlew"
                sh "./gradlew clean"
                sh "./gradlew bootJar"
            }
        }

        stage('Docker Build') {
            steps {
                container('docker') {
                    sh "docker build -t docker-repository.repository.svc.cluster.local/testprivate:0.1.${build_number} ."
                    sh "docker build -t docker-repository.repository.svc.cluster.local/testprivate:latest ."
                    sh "docker info"
                    // sh "apk update && apk add ca-certificates"
                    // sh "cp /etc/docker/certs.d/repository.repository.svc.cluster.local/ca.crt /usr/local/share/ca-certificates/my-cert.crt"
                    // sh "update-ca-certificates"
                    // sh "wget https://repository.repository.svc.cluster.local/v2/"
                    sh "docker push docker-repository.repository.svc.cluster.local/testprivate:0.1.${build_number}"
                    sh "docker push docker-repository.repository.svc.cluster.local/testprivate:latest"
                }
            }
        }
    }
}

운영자가 소스를 Github 에 push

여기 를 참조하여 Repo 를 설정합니다.

이미지 주소를 설정해 주면 됩니다.

Worker 노드에서 이미지를 땡겨 오기에,
Worker 노드에 루트인증서가 등록되어 있어야 합니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: testprivate
  namespace: default
  labels:
    app: testprivate
spec:
  replicas: 1
  selector:
    matchLabels:
      app: testprivate
  template:
    metadata:
      labels:
        app: testprivate
    spec:
      containers:
      - name: testprivate
        image: docker-repository.repository.svc.cluster.local/testprivate:0.1.16
        ports:
        - containerPort: 8080

One thought on “Kubernetes – CI/CD 파이프라인 구성

  1. seunghyun ryu

    프로젝트 루트에 Dockerfile 을 추가하고 아래 내용을 추가합니다.
    > 이 부분에 프로젝트 루트가 어딘지 모르겠습니다.
    일단 깃허브에 Dockerfile 추가하고 소스 불러오는 것 까지는 됐는데
    stage(“Build”) {
    sh “chmod 700 gradlew”
    sh “./gradlew clean”
    sh “./gradlew bootJar”
    }
    }
    이걸 추가했을때 gradlew가 없다고 에러가 나와서 진행을 못하고 있습니다…혹시 아시는 부분 있을까요??

답글 남기기