Ssoon

3주차 - Jenkins CI/ArgoCD + K8S : Jenkins CI/CD + K8S(Kind) 본문

CICD 맛보기

3주차 - Jenkins CI/ArgoCD + K8S : Jenkins CI/CD + K8S(Kind)

구구달스 2024. 12. 16. 21:38
CloudNet@ 가시다님이 진행하는 CI/CD 맛보기 스터디

Jenkins CI/CD + K8S(Kind)

🧿 Jenkins에 툴 설치

  • Jenkins 컨테이너 내에서 Kubernetes 클라이언트인 kubectl을 설치합니다.
[ssoon@localhost dev-app]$ docker compose exec --privileged -u root jenkins bash
root@9afd0ab27f06:/# curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   138  100   138    0     0    313      0 --:--:-- --:--:-- --:--:--   314
100 54.6M  100 54.6M    0     0  30.9M      0  0:00:01  0:00:01 --:--:-- 45.2M
root@9afd0ab27f06:/# install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
root@9afd0ab27f06:/# kubectl version --client=true
Client Version: v1.32.0
Kustomize Version: v5.5.0
  •  Jenkins 컨테이너 내에 Helm을 설치합니다.
root@9afd0ab27f06:/# curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 11903  100 11903    0     0  34539      0 --:--:-- --:--:-- --:--:-- 34601
Downloading https://get.helm.sh/helm-v3.16.3-linux-amd64.tar.gz
Verifying checksum... Done.
Preparing to install helm into /usr/local/bin
helm installed into /usr/local/bin/helm
root@9afd0ab27f06:/# helm version
version.BuildInfo{Version:"v3.16.3", GitCommit:"cfd07493f46efc9debd9cc1b02a0961186df7fdf", GitTreeState:"clean", GoVersion:"go1.22.7"}

🧿 Jenkins Item 생성(Pipeline) : item name(k8s-cmd)

  • pipeline
    • Jenkins의 파이프라인 정의를 시작하는 키워드입니다.
    • 이 파이프라인은 모든 에이전트에서 실행될 수 있도록 정의되어 있습니다 (agent any).
  • environment
    • KUBECONFIG = credentials('k8s-crd'):
      • KUBECONFIG 환경 변수를 설정하여 Kubernetes 클러스터에 연결하는 데 필요한 인증 정보를 제공합니다.
      • credentials('k8s-crd')는 Jenkins에서 저장된 Kubernetes 인증 정보를 가져오는 부분입니다. 이 인증 정보는 Jenkins의 비밀 관리 시스템에서 관리됩니다.
  • stages
    • 파이프라인에서 실행될 각 단계를 정의합니다. 여기서는 List Pods라는 하나의 단계만 정의되어 있습니다.
  • stage('List Pods')
    • sh: 쉘 명령어를 실행하는 단계입니다.
    • kubectl get pods -A --kubeconfig "$KUBECONFIG":
      • kubectl get pods: Kubernetes 클러스터 내에서 실행 중인 Pods 목록을 가져오는 명령입니다.
      • -A: 모든 네임스페이스에서 Pods를 가져옵니다.
      • --kubeconfig "$KUBECONFIG": KUBECONFIG 환경 변수를 사용하여 Kubernetes 클러스터에 접근합니다. 이 변수는 위에서 설정한 인증 정보를 참조합니다.
pipeline {
    agent any
    environment {
        KUBECONFIG = credentials('k8s-crd')
    }
    stages {
        stage('List Pods') {
            steps {
                sh '''
                # Fetch and display Pods
                kubectl get pods -A --kubeconfig "$KUBECONFIG"
                '''
            }
        }
    }
}
  • 콘솔 출력을 확인합니다.
Started by user admin
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /var/jenkins_home/workspace/k8s-cmd
[Pipeline] {
[Pipeline] withCredentials
Masking supported pattern matches of $KUBECONFIG
[Pipeline] {
[Pipeline] stage
[Pipeline] { (List Pods)
[Pipeline] sh
+ kubectl get pods -A --kubeconfig ****
NAMESPACE            NAME                                          READY   STATUS    RESTARTS   AGE
kube-system          coredns-7c65d6cfc9-mfhxm                      1/1     Running   0          4m3s
kube-system          coredns-7c65d6cfc9-zn4kg                      1/1     Running   0          4m3s
kube-system          etcd-myk8s-control-plane                      1/1     Running   0          4m9s
kube-system          kindnet-24rxp                                 1/1     Running   0          3m58s
kube-system          kindnet-s54mq                                 1/1     Running   0          3m58s
kube-system          kindnet-zcr9k                                 1/1     Running   0          4m3s
kube-system          kube-apiserver-myk8s-control-plane            1/1     Running   0          4m9s
kube-system          kube-controller-manager-myk8s-control-plane   1/1     Running   0          4m11s
kube-system          kube-proxy-hv4qg                              1/1     Running   0          4m3s
kube-system          kube-proxy-jc6d8                              1/1     Running   0          3m58s
kube-system          kube-proxy-r9nsp                              1/1     Running   0          3m58s
kube-system          kube-scheduler-myk8s-control-plane            1/1     Running   0          4m9s
local-path-storage   local-path-provisioner-57c5987fd4-gwbjz       1/1     Running   0          4m3s
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withCredentials
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

🧿 Jenkins 를 이용한 blue-green 배포 준비

  • 디플로이먼트 / 서비스 yaml 파일 작성 - http-echo 및 코드 push
├── deploy
│   ├── echo-server-blue.yaml
│   ├── echo-server-green.yaml
│   └── echo-server-service.yaml
  • echo-server-blue.yaml
  • Deployment: echo-server-blue라는 이름의 애플리케이션을 2개의 복제본으로 실행.
  • 컨테이너: hashicorp/http-echo 이미지를 사용하여 "Hello from Blue" 메시지를 반환.
  • 포트: 컨테이너는 5678 포트를 통해 HTTP 요청을 수신.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo-server-blue
spec:
  replicas: 2
  selector:
    matchLabels:
      app: echo-server
      version: blue
  template:
    metadata:
      labels:
        app: echo-server
        version: blue
    spec:
      containers:
      - name: echo-server
        image: hashicorp/http-echo
        args:
        - "-text=Hello from Blue"
        ports:
        - containerPort: 5678
  • echo-server-service.yaml
  • Service echo-server-service라는 이름으로 생성됩니다.
  • Selector app: echo-server와 version: blue라는 레이블을 가진 Pod을 선택합니다.
  • 클러스터 외부에서는 http://<NODE_IP>:30000으로 접근하여 echo-server Pod에 연결할 수 있습니다.
  • 포트 80을 사용하여 외부에서 접근하고, 실제 요청은 5678 포트로 전달됩니다.
apiVersion: v1
kind: Service
metadata:
  name: echo-server-service
spec:
  selector:
    app: echo-server
    version: blue
  ports:
  - protocol: TCP
    port: 80
    targetPort: 5678
    nodePort: 30000
  type: NodePort
  • echo-server-green.yaml
  • Deployment echo-server-green이라는 이름으로 생성됩니다.
  • 2개의 replicas echo-server-green 애플리케이션을 실행합니다.
  • echo-server-green 컨테이너는 "Hello from Green" 메시지를 반환하는 HTTP 서버를 실행합니다.
  • version: green 레이블을 사용하여 트래픽을 특정 Pod에 라우팅할 수 있습니다.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo-server-green
spec:
  replicas: 2
  selector:
    matchLabels:
      app: echo-server
      version: green
  template:
    metadata:
      labels:
        app: echo-server
        version: green
    spec:
      containers:
      - name: echo-server
        image: hashicorp/http-echo
        args:
        - "-text=Hello from Green"
        ports:
        - containerPort: 5678
  • 변경된 파일을 추가하고, 커밋한 뒤, 이를 원격 main 브랜치에 푸시합니다.
[ssoon@localhost dev-app]$ git add . && git commit -m "Add echo server yaml" && git push -u origin main
[main 8931ac8] Add echo server yaml
 3 files changed, 60 insertions(+)
 create mode 100644 deploy/echo-server-blue.yaml
 create mode 100644 deploy/echo-server-green.yaml
 create mode 100644 deploy/echo-server-service.yaml
오브젝트 나열하는 중: 7, 완료.
오브젝트 개수 세는 중: 100% (7/7), 완료.
Delta compression using up to 4 threads
오브젝트 압축하는 중: 100% (6/6), 완료.
오브젝트 쓰는 중: 100% (6/6), 797 bytes | 797.00 KiB/s, 완료.
Total 6 (delta 2), reused 0 (delta 0), pack-reused 0
To http://192.168.56.105:3000/devops/dev-app.git
   78856b0..8931ac8  main -> main
branch 'main' set up to track 'origin/main'.


🧿 Jenkins Item 생성(Pipeline) : item name(k8s-bluegreen) - Jenkins 통한 k8s 기본 배포

 

 

Started by user admin
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /var/jenkins_home/workspace/k8s-bluegreen
[Pipeline] {
[Pipeline] withCredentials
Masking supported pattern matches of $KUBECONFIG
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Checkout)
[Pipeline] git
The recommended git tool is: NONE
using credential gogs-crd
Cloning the remote Git repository
Cloning repository http://192.168.56.105:3000/devops/dev-app.git
 > git init /var/jenkins_home/workspace/k8s-bluegreen # timeout=10
Fetching upstream changes from http://192.168.56.105:3000/devops/dev-app.git
 > git --version # timeout=10
 > git --version # 'git version 2.39.5'
using GIT_ASKPASS to set credentials 
 > git fetch --tags --force --progress -- http://192.168.56.105:3000/devops/dev-app.git +refs/heads/*:refs/remotes/origin/* # timeout=10
 > git config remote.origin.url http://192.168.56.105:3000/devops/dev-app.git # timeout=10
 > git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
Avoid second fetch
 > git rev-parse refs/remotes/origin/main^{commit} # timeout=10
Checking out Revision 8931ac89b01c4b636bd834669a945754692d466d (refs/remotes/origin/main)
 > git config core.sparsecheckout # timeout=10
 > git checkout -f 8931ac89b01c4b636bd834669a945754692d466d # timeout=10
 > git branch -a -v --no-abbrev # timeout=10
 > git checkout -b main 8931ac89b01c4b636bd834669a945754692d466d # timeout=10
Commit message: "Add echo server yaml"
First time build. Skipping changelog.
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (container image build)
[Pipeline] echo
container image build
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (container image upload)
[Pipeline] echo
container image upload
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (k8s deployment blue version)
[Pipeline] sh
Warning: A secret was passed to "sh" using Groovy String interpolation, which is insecure.
		 Affected argument(s) used the following variable(s): [KUBECONFIG]
		 See https://jenkins.io/redirect/groovy-string-interpolation for details.
+ kubectl apply -f ./deploy/echo-server-blue.yaml --kubeconfig ****
deployment.apps/echo-server-blue created
[Pipeline] sh
Warning: A secret was passed to "sh" using Groovy String interpolation, which is insecure.
		 Affected argument(s) used the following variable(s): [KUBECONFIG]
		 See https://jenkins.io/redirect/groovy-string-interpolation for details.
+ kubectl apply -f ./deploy/echo-server-service.yaml --kubeconfig ****
service/echo-server-service created
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (approve green version)
[Pipeline] input
approve green version
Yes or Abort
  • Blue 로 배포되는것을 확인합니다.

  • Yes 를 클릭하고 진행합니다.
Approved by admin
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (k8s deployment green version)
[Pipeline] sh
Warning: A secret was passed to "sh" using Groovy String interpolation, which is insecure.
		 Affected argument(s) used the following variable(s): [KUBECONFIG]
		 See https://jenkins.io/redirect/groovy-string-interpolation for details.
+ kubectl apply -f ./deploy/echo-server-green.yaml --kubeconfig ****
deployment.apps/echo-server-green created
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (approve version switching)
[Pipeline] script
[Pipeline] {
[Pipeline] input
Input requested
  • Input requested 클릭 하면 다음의 화면으로 이동되면 Green 으로 스위칭합니다.

  • Green 으로 스위칭 되는것을 확인합니다.

  • Input requested 클릭 하면 다음의 화면으로 이동합니다.
Approved by admin
[Pipeline] sh
Warning: A secret was passed to "sh" using Groovy String interpolation, which is insecure.
		 Affected argument(s) used the following variable(s): [KUBECONFIG]
		 See https://jenkins.io/redirect/groovy-string-interpolation for details.
+ kubectl patch svc echo-server-service -p {"spec": {"selector": {"version": "green"}}} --kubeconfig ****
service/echo-server-service patched
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Blue Rollback)
[Pipeline] script
[Pipeline] {
[Pipeline] input
Input requested
  • rollback 진행합니다.

  • 다시  Blue 로 롤백된것을 확인합니다.

  • 실습 완료 후 삭제
[ssoon@localhost cicd-labs]$ kubectl delete deploy echo-server-blue echo-server-green
deployment.apps "echo-server-blue" deleted
deployment.apps "echo-server-green" deleted
[ssoon@localhost cicd-labs]$ kubectl delete svc echo-server-service
service "echo-server-service" deleted
 
Comments