07-[AEWS]-CI/CD

CI/CD는 Continuous Integration (CI) 및 Continuous Deployment (CD)의 약어입니다. 이는 소프트웨어 개발 및 배포 프로세스를 자동화하고 개선하기 위한 접근 방법입니다.

  1. Continuous Integration (CI):
    • CI는 소스 코드의 변경 사항을 지속적으로 통합하여 품질을 유지하는 프로세스입니다.
    • 여러 명의 개발자가 동시에 작업할 때 코드의 충돌이나 문제를 미리 발견할 수 있게 도와줍니다.
    • 개발자는 코드를 버전 관리 시스템(예: Git)에 커밋하면, CI 서버가 자동으로 해당 코드를 가져와 빌드하고 테스트를 실행합니다.
    • 이를 통해 코드 변경이 주기적으로 검증되고, 통합 문제를 최소화하여 소프트웨어 품질을 향상시킵니다.
  2. Continuous Deployment (CD):
    • CD는 변경 사항이 통합되고 검증된 후 자동으로 프로덕션 환경에 배포되도록 하는 프로세스입니다.
    • 이를 통해 개발된 기능이 사용자에게 빠르게 제공되며, 소프트웨어 배포의 오류 가능성을 줄일 수 있습니다.
    • CD 파이프라인은 CI와 연계되어 있어, CI에서 검증된 코드가 자동으로 배포되도록 구성됩니다.
    • 배포 단계에서는 여러 작업을 수행할 수 있으며, 예를 들어 컨테이너화, 서버 구성 변경, 자동화된 테스트, 배포 환경의 업데이트 등이 포함될 수 있습니다.


Jenkins는 자동화된 소프트웨어 개발 프로세스를 지원하기 위한 오픈 소스 자동화 도구입니다. 주로 CI/CD 파이프라인을 구축하고 관리하는 데 사용됩니다. 다음은 Jenkins의 주요 특징과 기능입니다:

  1. CI/CD 파이프라인 구축: Jenkins를 사용하면 소프트웨어의 변경 사항을 지속적으로 통합하고 테스트하여 자동으로 배포할 수 있는 CI/CD 파이프라인을 구축할 수 있습니다.
  2. 자동화된 빌드 및 테스트: Jenkins는 코드 변경이 발생할 때 자동으로 소스 코드를 가져와서 빌드하고 테스트하는 작업을 수행할 수 있습니다. 이를 통해 소프트웨어의 품질을 유지하고 개발자들이 빠르게 피드백을 받을 수 있습니다.
  3. 다양한 플러그인 지원: Jenkins는 다양한 플러그인을 지원하여 사용자의 요구에 맞게 확장할 수 있습니다. 이러한 플러그인을 사용하여 소프트웨어 빌드, 테스트, 배포 및 모니터링 등의 작업을 자동화할 수 있습니다.
  4. 분산 빌드: Jenkins는 여러 대의 에이전트를 사용하여 작업을 병렬로 실행할 수 있습니다. 이를 통해 대규모 프로젝트의 빌드 시간을 단축하고 성능을 최적화할 수 있습니다.
  5. 편리한 사용자 인터페이스: Jenkins는 직관적이고 사용하기 쉬운 웹 기반 사용자 인터페이스를 제공하여 사용자가 작업을 관리하고 모니터링할 수 있도록 도와줍니다.
  6. 강력한 커뮤니티 및 지원: Jenkins는 널리 사용되고 활발한 커뮤니티를 가지고 있으며, 다양한 문제에 대한 지원 및 자료가 풍부합니다.

Jenkins with Kubernetes

# jenkins 사용자에서 아래 작업 진행
whoami
mkdir ~/.kube

# root 계정에서 아래 복사 실행
cp ~/.kube/config /var/lib/jenkins/.kube/config
chown jenkins:jenkins /var/lib/jenkins/.kube/config

# jenkins 사용자에서 aws eks 사용(sts 호출 등)을 위한 자격증명 설정
aws configure
AWS Access Key ID [None]: AKIA5ILF2###
AWS Secret Access Key [None]: ###
Default region name [None]: ap-northeast-2

# jenkins 사용자에서 kubectl 명령어 사용 확인
kubectl get pods -A
  • Github repo에 yaml 추가
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myweb
spec:
  replicas: 2
  selector:
    matchLabels:
      app: mywebs
  template:
    metadata:
      name: myweb
      labels:
        app: mywebs
    spec:
      containers:
      - name: myweb
        image: gasida/myweb:v1.0.0
      terminationGracePeriodSeconds: 0
---
apiVersion: v1
kind: Service
metadata:
  name: myweb
spec:
  ports:
    - name: webport
      port: 8080
      targetPort: 80
  selector:
    app: mywebs
  type: ClusterIP
---
  • jenkins에 pipeline 추가
pipeline {
    agent any

    tools {
        jdk 'jdk-17'
    }

    environment {
        DOCKERHUB_USERNAME = 'gasida'
        GITHUB_URL = 'https://github.com/gasida/aews-cicd.git'
        // deployment-svc.yaml -> image: gasida/myweb:v1.0.0        
        DIR_NUM = '3'
    }

    stages {
        stage('Container Build') {
            steps {	
                // 릴리즈파일 체크아웃
                checkout scmGit(branches: [[name: '*/main']], 
                    extensions: [[$class: 'SparseCheckoutPaths', 
                    sparseCheckoutPaths: [[path: "/${DIR_NUM}"]]]], 
                    userRemoteConfigs: [[URL: "${GITHUB_URL}"]])

                // 컨테이너 빌드 및 업로드
                sh "docker build -t ${DOCKERHUB_USERNAME}/myweb:v1.0.0 ./${DIR_NUM}"
                sh "docker push ${DOCKERHUB_USERNAME}/myweb:v1.0.0"
            }
        }

        stage('K8S Deploy') {
            steps {
                sh "kubectl apply -f ./${DIR_NUM}/deploy/deployment-svc.yaml"
            }
        }
    }
}

Argo


Argo는 Kubernetes를 기반으로 하는 오픈 소스 자동화 도구로, 대규모 마이크로서비스 및 복잡한 워크플로우를 관리하기 위해 설계되었습니다. Argo는 크게 세 가지 하위 프로젝트로 구성되어 있습니다:

  1. Argo Workflows:
    • Argo Workflows는 Kubernetes에서 워크플로우를 실행하고 관리하는 도구입니다.
    • 사용자는 YAML로 정의된 워크플로우를 작성하고 Argo에게 제출하여 실행할 수 있습니다.
    • 워크플로우는 여러 단계로 구성되며, 각 단계는 컨테이너, 파라미터, 종속성 등을 포함할 수 있습니다.
    • 병렬 처리, 조건부 실행, 루프 등과 같은 다양한 제어 흐름 패턴을 지원하여 유연한 워크플로우를 구성할 수 있습니다.
  2. Argo CD:
    • Argo CD는 Kubernetes 클러스터에 대한 지속적인 배포 (Continuous Deployment)를 관리하는 도구입니다.
    • GitOps 원칙을 따라 작동하여 Git 리포지토리에 정의된 애플리케이션 상태와 실제 클러스터의 상태를 동기화합니다.
    • 변경 사항이 Git 리포지토리에 푸시되면 Argo CD가 자동으로 해당 변경 사항을 감지하고 배포를 시작합니다.
  3. Argo Events:
    • Argo Events는 이벤트 기반 아키텍처 (Event-Driven Architecture)를 지원하기 위한 도구입니다.
    • 다양한 이벤트 소스에서 이벤트를 수집하고 워크플로우를 트리거하는 데 사용됩니다.
    • Kubernetes 이벤트, 메시지 브로커, 웹훅 등 다양한 이벤트 소스를 지원합니다.

Argo CD Install

# helm 설치
cat <<EOT > argocd-values.yaml
global:
  domain: argocd.$MyDomain

configs:
  params:
    server.insecure: true

controller:
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true

server:
  ingress:
    enabled: true
    controller: aws
    ingressClassName: alb
    hostname: "argocd.$MyDomain"
    annotations:
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/backend-protocol: HTTP
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":80}, {"HTTPS":443}]'
      alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
      alb.ingress.kubernetes.io/ssl-redirect: '443'
    aws:
      serviceType: ClusterIP
      backendProtocolVersion: GRPC
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true

repoServer:
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true

applicationSet:
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true

notifications:
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true
EOT

kubectl create ns argocd
helm repo add argo https://argoproj.github.io/argo-helm
helm install argocd argo/argo-cd --version 6.7.11 -f argocd-values.yaml --namespace argocd

# 확인
kubectl get ingress,pod,svc -n argocd
kubectl get crd | grep argo

# 최초 접속 암호 확인
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d ;echo
  • SYNCHRONIZE 옵션
    • PRUNE
      • GIt에서 자원 삭제 후 배포시 K8S에서는 삭제되지 않으나, 해당 옵션을 선택하면 삭제시킴
    • DRY RUN
      • 테스트 배포 (배포에 에러가 있는지 한번 확인해 볼때 사용)
    • APPLY ONLY
      • ArgoCD의 Pre/Post Hook은 사용 안함 (리소스만 배포)
    • FORCE
      • –force 옵션으로 리소스 삭제
    • SKIP SCHEMA VALIDATION (스키마 유효성 검사 생략):
      • 이 옵션은 Argo CD가 Kubernetes 매니페스트를 OpenAPI 스키마에 대한 유효성 검사를 생략하도록 지시합니다.
      • Kubernetes 스키마에 준하지 않지만 여전히 유효하고 기능적인 매니페스트를 배포하는 경우 유용합니다.
    • AUTO-CREATE NAMESPACE (자동 네임스페이스 생성):
      • 활성화된 경우, 이 옵션은 Argo CD가 매니페스트에서 지정된 네임스페이스를 자동으로 생성합니다.
      • 수동으로 네임스페이스를 사전에 만들 필요 없이 배포 프로세스를 간소화합니다.
    • PRUNE LAST (최신 Prune):
      • 이 옵션을 활성화하면 Argo CD가 최신 동기화 버전에 존재했지만 현재 버전에서 누락된 리소스를 제거합니다.
      • 더 이상 필요하지 않은 리소스가 동기화 중에 클러스터에서 제거되도록 보장합니다.
    • APPLY OUT OF SYNC ONLY (동기화 상태가 아닌 경우에만 적용):
      • 이 옵션이 선택되면 Argo CD가 원하는 상태와 동기화되지 않은 리소스에만 변경 사항을 적용합니다.
      • 이미 원하는 상태에 있는 리소스에 불필요한 업데이트를 피하고 배포 프로세스를 최적화하는 데 도움이 됩니다.
    • RESPECT IGNORE DIFFERENCES (차이점 무시 존중):
      • 활성화된 경우, Argo CD는 Application 리소스의 spec에 지정된 ignoreDifferences 필드를 존중합니다.
      • 이 필드를 사용하여 원하는 상태와 라이브 상태 간에 무시해야 할 특정 차이점을 정의할 수 있습니다.
    • SERVER-SIDE APPLY (서버 측 적용):
      • 이 옵션이 활성화되면 Argo CD가 리소스 조정을 위해 서버 측 적용 방법을 사용합니다.
      • 대규모 배포에 특히 유용한 성능을 제공하며 클라이언트 측 적용보다 효율적입니다.

Argo CD CLI

FATA[0000] Failed to establish connection to argocd.gyuroot.com:443: dial tcp: lookup argocd.gyuroot.com on 192.168.0.2:53: no such host
위의 에러인 경우 /etc/resolv.conf 에 dns주소를 수정해야함
curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
rm -f argocd-linux-amd64
argocd version
argocd: v2.10.7+b060053
  BuildDate: 2024-04-15T09:05:25Z
  GitCommit: b060053b099b4c81c1e635839a309c9c8c1863e9
  GitTreeState: clean
  GoVersion: go1.21.9
  Compiler: gc
  Platform: linux/amd64
argocd login argocd.$MyDomain
kubectl config get-contexts -o name
admin@myeks.ap-northeast-2.eksctl.io
argocd cluster add admin@myeks.ap-northeast-2.eksctl.io
#INFO[0002] ServiceAccount "argocd-manager" already exists in namespace "kube-system" 
#INFO[0002] ClusterRole "argocd-manager-role" updated    
#INFO[0002] ClusterRoleBinding "argocd-manager-role-binding" updated 
#Cluster 'https://DE434AE57592207B6B594662FD5DC486.sk1.ap-northeast-2.eks.amazonaws.com' added
argocd app list
#NAME  CLUSTER  NAMESPACE  PROJECT  STATUS  HEALTH  SYNCPOLICY  CONDITIONS  REPO  PATH  TARGET

#Application 생성
kubectl config set-context --current --namespace=argocd
#Context "pak8266@myeks.ap-northeast-2.eksctl.io" modified.
argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default
#application 'guestbook' created
argocd app list
#NAME              CLUSTER                         NAMESPACE  PROJECT  STATUS     HEALTH   SYNCPOLICY  CONDITIONS  REPO                                                 PATH       TARGET
#argocd/guestbook  https://kubernetes.default.svc  default    default  OutOfSync  Missing  <none>      <none>      https://github.com/argoproj/argocd-example-apps.git  guestbook

#Sync (Deploy) The Application
argocd app get guestbook
#Name:               argocd/guestbook
#Project:            default
#Server:             https://kubernetes.default.svc
#Namespace:          default
#URL:                https://argocd.gyuroot.com/applications/guestbook
#Repo:               https://github.com/argoproj/argocd-example-apps.git
#Target:             
#Path:               guestbook
#SyncWindow:         Sync Allowed
#Sync Policy:        <none>
#Sync Status:        OutOfSync from  (d7927a2)
#Health Status:      Missing
#
#GROUP  KIND        NAMESPACE  NAME          STATUS     HEALTH   HOOK  MESSAGE
#       Service     default    guestbook-ui  OutOfSync  Missing        
#apps   Deployment  default    guestbook-ui  OutOfSync  Missing

argocd app sync guestbook
#TIMESTAMP                  GROUP        KIND   NAMESPACE                  NAME    STATUS    HEALTH        HOOK  MESSAGE
#2024-04-20T16:07:41+09:00   apps  Deployment     default          guestbook-ui  OutOfSync  Missing              
#2024-04-20T16:07:41+09:00            Service     default          guestbook-ui  OutOfSync  Missing              
#2024-04-20T16:07:42+09:00            Service     default          guestbook-ui    Synced  Healthy              
#2024-04-20T16:07:42+09:00            Service     default          guestbook-ui    Synced   Healthy              service/guestbook-ui created
#2024-04-20T16:07:42+09:00   apps  Deployment     default          guestbook-ui  OutOfSync  Missing              deployment.apps/guestbook-ui created
#2024-04-20T16:07:42+09:00   apps  Deployment     default          guestbook-ui    Synced  Progressing              deployment.apps/guestbook-ui created

#Name:               argocd/guestbook
#Project:            default
#Server:             https://kubernetes.default.svc
#Namespace:          default
#URL:                https://argocd.gyuroot.com/applications/guestbook
#Repo:               https://github.com/argoproj/argocd-example-apps.git
#Target:             
#Path:               guestbook
#SyncWindow:         Sync Allowed
#Sync Policy:        <none>
#Sync Status:        Synced to  (d7927a2)
#Health Status:      Progressing

#Operation:          Sync
#Sync Revision:      d7927a27b4533926b7d86b5f249cd9ebe7625e90
#Phase:              Succeeded
#Start:              2024-04-20 16:07:41 +0900 KST
#Finished:           2024-04-20 16:07:42 +0900 KST
#Duration:           1s
#Message:            successfully synced (all tasks run)

#GROUP  KIND        NAMESPACE  NAME          STATUS  HEALTH       HOOK  MESSAGE
#       Service     default    guestbook-ui  Synced  Healthy            service/guestbook-ui created
#apps   Deployment  default    guestbook-ui  Synced  Progressing        deployment.apps/guestbook-ui created

Argo Rollouts

  • Argo Rollouts : Argo Rollouts는 블루-그린, 카나리, 카나리 분석, 실험 및 프로그레시브 배포 기능과 같은 고급 배포 기능을 제공하는 Kubernetes 컨트롤러CRD 세트입니다.
    • Argo Rollouts는 선택적으로 인그레스 컨트롤러서비스 메시와 통합되며, 업데이트 중에 새 버전으로 트래픽을 점진적으로 이동하는 데 사용되는 트래픽 형성 능력을 활용합니다. 또한, Rollouts는 다양한 공급 업체에서 메트릭을 쿼리하고 해석하여 주요 KPI를 확인하고 업데이트 중에 자동 프로모션 또는 롤백을 제어할 수 있습니다.
  • Argo Rollouts를 사용해야 하는 이유:
    • 기본 Kubernetes 배포 개체는 업데이트 중에 기본적인 안전 보증(준비 프로브)을 제공하는 롤링 업데이트 전략을 지원합니다. 그러나 롤링 업데이트 전략은 다음과 같은 많은 제한 사항을 가지고 있습니다:
    • 롤아웃 속도에 대한 제어 부족
    • 새 버전으로의 트래픽 흐름을 제어할 수 없음
    • 준비 프로브는 깊은, 스트레스, 또는 일회성 체크에 적합하지 않음
    • 업데이트를 확인하기 위해 외부 메트릭을 쿼리할 수 없음
    • 진행을 중단할 수 있지만 업데이트를 자동으로 중단하고 롤백할 수 없음
  • 컨트롤러 기능:
    • 블루-그린 업데이트 전략
    • 카나리 업데이트 전략
    • 세밀하게 조정된 가중치 트래픽 이동
    • 자동 롤백 및 프로모션
    • 수동 판단
    • 비즈니스 KPI의 메트릭 쿼리 및 분석을 사용자 정의
    • 인그레스 컨트롤러 통합: NGINX, ALB, Apache APISIX
    • 서비스 메시 통합: Istio, Linkerd, SMI
    • 여러 공급 업체의 동시 사용: SMI + NGINX, Istio + ALB 등
    • 메트릭 공급 업체 통합: Prometheus, Wavefront, Kayenta, Web, Kubernetes Jobs, Datadog, New Relic, Graphite, InfluxDB
(pak8266@myeks:argocd) [root@myeks-bastion ~]# cat <<EOT > argorollouts-values.yaml
> dashboard:
>   enabled: true
>   ingress:
>     enabled: true
>     ingressClassName: alb
>     hosts:
>       - argorollouts.$MyDomain
>     annotations:
>       alb.ingress.kubernetes.io/scheme: internet-facing
>       alb.ingress.kubernetes.io/target-type: ip
>       alb.ingress.kubernetes.io/backend-protocol: HTTP
>       alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":80}, {"HTTPS":443}]'
>       alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
>       alb.ingress.kubernetes.io/ssl-redirect: '443'
>
EOT
(pak8266@myeks:argocd) [root@myeks-bastion ~]# kubectl create ns argo-rollouts
namespace/argo-rollouts created
(pak8266@myeks:argocd) [root@myeks-bastion ~]# helm install argo-rollouts argo/argo-rollouts --version 2.35.1 -f argorollouts-values.yaml --namespace argo-rollouts
NAME: argo-rollouts
LAST DEPLOYED: Sun Apr 20 16:11:47 2024
NAMESPACE: argo-rollouts
STATUS: deployed
REVISION: 1
TEST SUITE: None
(pak8266@myeks:argocd) [root@myeks-bastion ~]# kubectl get all -n argo-rollouts

NAME                                           READY   STATUS    RESTARTS   AGE
pod/argo-rollouts-7647d689d6-hrcsm             1/1     Running   0          56s
pod/argo-rollouts-7647d689d6-s4lqj             1/1     Running   0          56s
pod/argo-rollouts-dashboard-79d489cfc7-4h8h2   1/1     Running   0          56s

NAME                              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/argo-rollouts-dashboard   ClusterIP   10.100.117.204   <none>        3100/TCP   56s

NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/argo-rollouts             2/2     2            2           56s
deployment.apps/argo-rollouts-dashboard   1/1     1            1           56s

NAME                                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/argo-rollouts-7647d689d6             2         2         2       56s
replicaset.apps/argo-rollouts-dashboard-79d489cfc7   1         1         1       56s
(pak8266@myeks:argocd) [root@myeks-bastion ~]# kubectl get crd | grep argo
analysisruns.argoproj.io                     2024-04-20T07:11:49Z
analysistemplates.argoproj.io                2024-04-20T07:11:49Z
applications.argoproj.io                     2024-04-20T05:51:46Z
applicationsets.argoproj.io                  2024-04-20T05:51:46Z
appprojects.argoproj.io                      2024-04-20T05:51:46Z
clusteranalysistemplates.argoproj.io         2024-04-20T07:11:49Z
experiments.argoproj.io                      2024-04-20T07:11:49Z
rollouts.argoproj.io                         2024-04-20T07:11:49Z

Argo rollouts cli

(pak8266@myeks:argocd) [root@myeks-bastion ~]# curl -LO https://github.com/argoproj/argo-rollouts/releases/download/v1.6.4/kubectl-argo-rollouts-linux-amd64
(pak8266@myeks:argocd) [root@myeks-bastion ~]# chmod +x ./kubectl-argo-rollouts-linux-amd64
(pak8266@myeks:argocd) [root@myeks-bastion ~]# mv ./kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts
(pak8266@myeks:argocd) [root@myeks-bastion ~]# kubectl argo rollouts version
kubectl-argo-rollouts: v1.6.4+a312af9
  BuildDate: 2023-12-11T18:31:15Z
  GitCommit: a312af9f632b985ec13f64918b918c5dcd02a15e
  GitTreeState: clean
  GoVersion: go1.20.12
  Compiler: gc
  Platform: linux/amd64
kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/basic/rollout.yaml
kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/basic/service.yaml

Updating a Rollout

Aborting a Rollout

Leave a Comment