8주차 - K8S CI/CD (3)

728x90

Argo CD

 

ArgoCD는 쿠버네티스를 위한 CD(Continuous Delivery)도구로

GitOps방식으로 관리되는 Mainfest(yaml)파일의 변경사항을 감시하여, 현재 배포되어 있는 환경의 상태와 / Git Manifest파일에 정의된 상태를 동일하게 유지 하는 역학을 수행

 

 

ArgoCD 구성요소

  •  API Server: Web UI, API 서버
  • Repository Server: Git 연결 및 배포할 yaml 생성
  • Application Controller: k8s 리소스 모니터링, Git 비교 
  • redis: k8s와 git요청을 줄이기 위한 캐싱
  • Notification: 이벤트 알림, 트리거
  • Dex: 외부 인증 관리
  • ApplicationSet Controller: 멀티 클러스터를 위한 App 패키징 관리

 

Argo CD + K8S(Kind)

 

  • 설치
# 네임스페이스 생성 및 파라미터 파일 작성
cd cicd-labs

kubectl create ns argocd
cat <<EOF > argocd-values.yaml
dex:
  enabled: false

server:
  service:
    type: NodePort
    nodePortHttps: 30002
  extraArgs:
    - --insecure  # HTTPS 대신 HTTP 사용
EOF

# 설치
helm repo add argo https://argoproj.github.io/argo-helm
helm install argocd argo/argo-cd --version 7.8.13 -f argocd-values.yaml --namespace argocd # 7.7.10

# 확인
kubectl get pod,svc,ep,secret,cm -n argocd
kubectl get crd | grep argo
applications.argoproj.io                     2024-04-14T08:12:16Z
applicationsets.argoproj.io                  2024-04-14T08:12:17Z
appprojects.argoproj.io                      2024-04-14T08:12:16Z

kubectl get appproject -n argocd -o yaml

# configmap
kubectl get cm -n argocd argocd-cm -o yaml
kubectl get cm -n argocd argocd-rbac-cm -o yaml
...
data:
  policy.csv: ""
  policy.default: ""
  policy.matchMode: glob
  scopes: '[groups]'


# 최초 접속 암호 확인
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d ;echo
XxJMMJUv8MHZa-kk

# Argo CD 웹 접속 주소 확인 : 초기 암호 입력 (admin 계정)
open "http://127.0.0.1:30002" # macOS
# Windows OS경우 직접 웹 브라우저에서 http://127.0.0.1:30002 접속

#초기 패스워드 변경

#User info → UPDATE PASSWORD 로 admin 계정 암호 변경 (qwe12345)

  • ops-deploy Repo 등록
- connection method : VIA HTTPS
- Type : git
- Project : default
- Repo URL : http://<자신의 집 IP>:3000/devops/ops-deploy  [http://192.168.254.127:3000/devops/ops-deploy](http://192.168.254.124:3000/devops/ops-deploy)
    - Windows (WSL2) 사용자는 자신의 WSL2 Ubuntu eth0 IP
- Username : devops
- Password : <Gogs 토큰>

 ⇒ 입력 후 CONNECT 클릭

  • helm chart 를 통한 배포 실습
#
cd cicd-labs
mkdir nginx-chart
cd nginx-chart

mkdir templates

cat > templates/configmap.yaml <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}
data:
  index.html: |
{{ .Values.indexHtml | indent 4 }}
EOF

cat > templates/deployment.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: {{ .Release.Name }}
  template:
    metadata:
      labels:
        app: {{ .Release.Name }}
    spec:
      containers:
      - name: nginx
        image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
        ports:
        - containerPort: 80
        volumeMounts:
        - name: index-html
          mountPath: /usr/share/nginx/html/index.html
          subPath: index.html
      volumes:
      - name: index-html
        configMap:
          name: {{ .Release.Name }}
EOF

cat > templates/service.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
  name: {{ .Release.Name }}
spec:
  selector:
    app: {{ .Release.Name }}
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30000
  type: NodePort
EOF

cat > values.yaml <<EOF
indexHtml: |
  <!DOCTYPE html>
  <html>
  <head>
    <title>Welcome to Nginx!</title>
  </head>
  <body>
    <h1>Hello, Kubernetes!</h1>
    <p>Nginx version 1.26.1</p>
  </body>
  </html>

image:
  repository: nginx
  tag: 1.26.1

replicaCount: 1
EOF

cat > Chart.yaml <<EOF
apiVersion: v2
name: nginx-chart
description: A Helm chart for deploying Nginx with custom index.html
type: application
version: 1.0.0
appVersion: "1.26.1"
EOF

# 이전 timeserver/service(nodeport) 삭제
kubectl delete deploy,svc --all

# 직접 배포 해보기
helm template dev-nginx . -f values.yaml
helm install dev-nginx . -f values.yaml
helm list
kubectl get deploy,svc,ep,cm dev-nginx -owide

#
curl http://127.0.0.1:30000
curl -s http://127.0.0.1:30000 | grep version
open http://127.0.0.1:30000


# value 값 변경 후 적용 해보기 : version/tag, replicaCount
cat > values.yaml <<EOF
indexHtml: |
  <!DOCTYPE html>
  <html>
  <head>
    <title>Welcome to Nginx!</title>
  </head>
  <body>
    <h1>Hello, Kubernetes!</h1>
    <p>Nginx version 1.26.2</p>
  </body>
  </html>

image:
  repository: nginx
  tag: 1.26.2

replicaCount: 2
EOF

sed -i "s|1.26.1|1.26.2|g" Chart.yaml #WSL Ubuntu 기준

# helm chart 업그레이드 적용
helm template dev-nginx . -f values.yaml # 적용 전 렌더링 확인 Render chart templates locally and display the output.
helm upgrade dev-nginx . -f values.yaml

# 확인
helm list
kubectl get deploy,svc,ep,cm dev-nginx -owide
curl http://127.0.0.1:30000
curl -s http://127.0.0.1:30000 | grep version
open http://127.0.0.1:30000

# 확인 후 삭제
helm uninstall dev-nginx

 

 

  • Repo(ops-deploy) 에 nginx helm chart 를 Argo CD를 통한 배포 1
cd cicd-labs

TOKEN=<>
git clone http://devops:$TOKEN@$MyIP:3000/devops/ops-deploy.git
cd ops-deploy

#
git --no-pager config --local --list
git config --local user.name "devops"
git config --local user.email "a@a.com"
git config --local init.defaultBranch main
git config --local credential.helper store
git --no-pager config --local --list
cat .git/config

#
git --no-pager branch
git remote -v

#
VERSION=1.26.1
mkdir nginx-chart
mkdir nginx-chart/templates

cat > nginx-chart/VERSION <<EOF
$VERSION
EOF

cat > nginx-chart/templates/configmap.yaml <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}
data:
  index.html: |
{{ .Values.indexHtml | indent 4 }}
EOF

cat > nginx-chart/templates/deployment.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: {{ .Release.Name }}
  template:
    metadata:
      labels:
        app: {{ .Release.Name }}
    spec:
      containers:
      - name: nginx
        image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
        ports:
        - containerPort: 80
        volumeMounts:
        - name: index-html
          mountPath: /usr/share/nginx/html/index.html
          subPath: index.html
      volumes:
      - name: index-html
        configMap:
          name: {{ .Release.Name }}
EOF

cat > nginx-chart/templates/service.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
  name: {{ .Release.Name }}
spec:
  selector:
    app: {{ .Release.Name }}
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30000
  type: NodePort
EOF

cat > nginx-chart/values-dev.yaml <<EOF
indexHtml: |
  <!DOCTYPE html>
  <html>
  <head>
    <title>Welcome to Nginx!</title>
  </head>
  <body>
    <h1>Hello, Kubernetes!</h1>
    <p>DEV : Nginx version $VERSION</p>
  </body>
  </html>

image:
  repository: nginx
  tag: $VERSION

replicaCount: 1
EOF

cat > nginx-chart/values-prd.yaml <<EOF
indexHtml: |
  <!DOCTYPE html>
  <html>
  <head>
    <title>Welcome to Nginx!</title>
  </head>
  <body>
    <h1>Hello, Kubernetes!</h1>
    <p>PRD : Nginx version $VERSION</p>
  </body>
  </html>

image:
  repository: nginx
  tag: $VERSION

replicaCount: 2
EOF

cat > nginx-chart/Chart.yaml <<EOF
apiVersion: v2
name: nginx-chart
description: A Helm chart for deploying Nginx with custom index.html
type: application
version: 1.0.0
appVersion: "$VERSION"
EOF


tree nginx-chart
nginx-chart
├── Chart.yaml
├── VERSION
├── templates
│   ├── configmap.yaml
│   ├── deployment.yaml
│   └── service.yaml
├── values-dev.yaml
└── values-prd.yaml

# 
helm template dev-nginx nginx-chart -f nginx-chart/values-dev.yaml
helm template prd-nginx nginx-chart -f nginx-chart/values-prd.yaml
DEVNGINX=$(helm template dev-nginx nginx-chart -f nginx-chart/values-dev.yaml | sed 's/---//g')
PRDNGINX=$(helm template prd-nginx nginx-chart -f nginx-chart/values-prd.yaml | sed 's/---//g')
diff <(echo "$DEVNGINX") <(echo "$PRDNGINX")

#
git add . && git commit -m "Add nginx helm chart" && git push -u origin main

  • Argo CD에 App 등록 : Application → NEW APP
- GENERAL
    - App Name : dev-nginx
    - Project Name : default
    - SYNC POLICY : Manual
        - AUTO-CREATE NAMESPACE : 클러스터에 네임스페이스가 없을 시 argocd에 입력한 이름으로 자동 생성
        - APPLY OUT OF SYNC ONLY : 현재 동기화 상태가 아닌 리소스만 배포
    - SYNC OPTIONS : AUTO-CREATE NAMESPACE(Check)
    - PRUNE PROPAGATION POLICY
        - foreground : 부모(소유자, ex. deployment) 자원을 먼저 삭제함
        - background  : 자식(종속자, ex. pod) 자원을 먼저 삭제함
        - orphan  : 고아(소유자는 삭제됐지만, 종속자가 삭제되지 않은 경우) 자원을 삭제함
- Source
    - Repo URL : 설정되어 있는 것 선택
    - Revision : HEAD
    - PATH : nginx-chart
- DESTINATION
    - Cluster URL : <기본값>
    - NAMESPACE : dev-nginx
- HELM
    - Values files : values-dev.yaml

⇒ 작성 후 상단 CREATE 클릭

- PRUNE : GIt에서 자원 삭제 후 배포시 K8S에서는 삭제되지 않으나, 해당 옵션을 선택하면 삭제시킴
- FORCE : --force 옵션으로 리소스 삭제
- APPLY ONLY : ArgoCD의 Pre/Post Hook은 사용 안함 (리소스만 배포)
- DRY RUN : 테스트 배포 (배포에 에러가 있는지 한번 확인해 볼때 사용)

 

  • 확인
#
kubectl get applications -n argocd
NAME        SYNC STATUS   HEALTH STATUS
dev-nginx   OutOfSync     Missing

kubectl describe applications -n argocd dev-nginx

# 상태 모니터링
kubectl get applications -n argocd -w

# 반복 접속 시도
while true; do curl -s --connect-timeout 1 http://127.0.0.1:30000 ; date ; echo "------------" ; sleep 1 ; done

 

 

  • SYNC 클릭 으로 K8S(Live) 반영 확인 : 생성될 리소스 확인

  • SYNC 확인

 

 

 

#
kubectl get cm -n dev-nginx dev-nginx -o yaml
apiVersion: v1
data:
  index.html: |
    <!DOCTYPE html>
    <html>
    <head>
      <title>Welcome to Nginx!</title>
    </head>
    <body>
      <h1>Hello, Kubernetes!</h1>
      <p>DEV testtest : Nginx version 1.26.1</p>
    </body>
    </html>
...
  labels:
    argocd.argoproj.io/instance: dev-nginx
    myname: tester
...

# (추가) kubectl 로 직접 k8s 추가 시 >> 이후 ArgoCD LIVE 에서 확인!
kubectl get cm -n dev-nginx dev-nginx --show-labels
kubectl label cm dev-nginx -n dev-nginx study=aews
kubectl get cm -n dev-nginx dev-nginx --show-labels

# 변경된 CM 적용을 위해서 롤아웃
kubectl rollout restart deployment -n dev-nginx dev-nginx

#
while true; do curl -s --connect-timeout 1 http://127.0.0.1:30000 ; date ; echo "------------" ; sleep 1 ; done

 

 

※ GitOps를 위해서는, 반드시 단일 진실 공급원(Single Source Of Trush, SSOT)를 통해서 관리를 할 것!

  • code 수정 후 반영 확인
    • 1.26.2로 버전 변경
#
VERSION=1.26.2

cat > nginx-chart/VERSION <<EOF
$VERSION
EOF

cat > nginx-chart/values-dev.yaml <<EOF
indexHtml: |
  <!DOCTYPE html>
  <html>
  <head>
    <title>Welcome to Nginx!</title>
  </head>
  <body>
    <h1>Hello, Kubernetes!</h1>
    <p>DEV : Nginx version $VERSION</p>
  </body>
  </html>

image:
  repository: nginx
  tag: $VERSION

replicaCount: 2
EOF

cat > nginx-chart/values-prd.yaml <<EOF
indexHtml: |
  <!DOCTYPE html>
  <html>
  <head>
    <title>Welcome to Nginx!</title>
  </head>
  <body>
    <h1>Hello, Kubernetes!</h1>
    <p>PRD : Nginx version $VERSION</p>
  </body>
  </html>

image:
  repository: nginx
  tag: $VERSION

replicaCount: 2
EOF

cat > nginx-chart/Chart.yaml <<EOF
apiVersion: v2
name: nginx-chart
description: A Helm chart for deploying Nginx with custom index.html
type: application
version: 1.0.0
appVersion: "$VERSION"
EOF

#
git add . && git commit -m "Update nginx version $(cat nginx-chart/VERSION)" && git push -u origin main

 

  • ArgoCD 수동 Sync 진행

728x90

'2025_AEWS Study' 카테고리의 다른 글

8주차 - K8S CI/CD (4)  (0) 2025.03.30
8주차 - K8S CI/CD (2)  (0) 2025.03.30
8주차 - K8S CI/CD (1)  (0) 2025.03.30
7주차 - EKS Mode/Nodes - Auto mode(2)  (0) 2025.03.22
7주차 - EKS Mode/Nodes - Fargate(1)  (0) 2025.03.22