본문 바로가기

카테고리 없음

쿠버네티스_GitOps

1. Probe 

1) Probe의 개요

- 컨테이너에서 kubelet에 의해 주기적으로 수행되는 진단 ( Pod Healthcheck )

 

(1) Pod LifeCycle

- Pending - Running-Succeed/Fail ( unknown : 통신 불가 )

  ① pending : pod 생성이 시작되었지만 아직 컨테이너 설정이 진행중 

  ② running: 1개 이상의 pod container가 생성, 실행중 or 시작/재시작 상태

      ( 시작 실패 시, Running이지만 접속되지 않는 상황을 Health Check )

  ③ succeeded : 모든 container가 성공적으로 종료 

 

(2) 체크 메커니즘 

exec : 지정된 명령 실행 (상태 코드 0으로 종료시 진단 성공)

② rhttpGet : get요청으로 상태가 200~400미만이면 성공 (Java SpringBoot의 Actuator호출 등)

③ grpc : gRPC를 사용하여 원격 프로시져 호출, 응답 status가 SERVING이면 진단 성공

④ tcpSocket : 컨테이너 IP주소에 대해 TCP검사 수행, 포트 활성화시 진단 성공으로 간주 

 

2) Probe 종류

(1) livenessProbe ( 활성 Probe )

① 컨테이너가 동작중인지 체크

- 동작 체크 실패시 kubelet이 해당 컨테이너를 terminate하고 새 container가동 

- 서비스의 엔드포인트에 연결된 개별 pod의 IP를 제거 ( 준비된 Pod에 traffic )

- 미지정 시 기본 상태 Success

 

② 구동 실습

- InitialDelaySeconds : 컨테이너가 시작되는 시간 ( 3초간 활성화하지 않고 대기 )

- 실패시 Pod를 다시 시작 

cat <<EOF>> liveness-test.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: registry.k8s.io/e2e-test-images/agnhost:2.40
    args:
    - liveness
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 3
EOF

kubectl apply -f liveness-test.yaml

# Pod 확인
watch kubectl get pod -o wide

# Pod 상세 정보
kubectl describe pod liveness-http

 

liveness probe구동 현황과 관련 정보 (계속 restart 진행중)

 

(2) readiness Probe ( 준비성 Probe )

 컨테이너가 요청을 처리할 준비가 되었는지 여부 체크

- 실패시, 엔드포인트 컨트롤러가 pod에 연관된 모든 서비스 엔드포인트에서 pod의 IP주소제거

   ( 서비스를 다른 Pod로 요청, 트래픽 차단 )

- 초기 지연 이전의 기본상태 Failure ( 미지정 시 기본 상태 Success ) 

- 운영환경에서는 liveness probe와 readiness probe를 함께 사용

 

② 구동 실습

- 8080포트로 3초마다 시도, 준비되지 않으면 ready로 변경되지 않고 대기 

cat <<EOF>> readiness-test.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: readiness
  name: readiness-http
spec:
  containers:
  - name: readiness
    image: registry.k8s.io/e2e-test-images/agnhost:2.40
    args:
    - liveness
    readinessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 3
EOF

kubectl apply -f readiness-test.yaml

# Pod 확인
watch kubectl get pod -o wide


# Pod 상세 정보
kubectl describe pod readiness-http

 

 

(3) startupProbe 

- 컨테이너 내의 어플리케이션의 시작여부 ( 시작이 느린 SpringBoot, Actuator로 체크 )

- startup probe가 주어진 경우, 성공할 때까지 다른 나머지 프로브는 활성화되지 않음 (성공후 다른 프루브로 전환)

- 실패시 kubelet이 container를 terminate한 후 재시작 정책 적용 

 

2. Manifest

https://www.inflearn.com/blogs/5626

 

 

 

1) Manifest의 개요

-  Kubernetes리소스를 정의하는 설정 파일 ( 선언형 파일, yaml )

 

(1) 환경별 구성 분리 및 Overlay

① 개발, 검증, 운영 환경별로 구성과 설정이 다른 경우에도 일관성 확보 ( 누락, 오타, 오류의 가능성 높아 기본 구성에 overlay하는 방식 적용 ) 

Template화, 변수화하여 일관된 구조를 유지하고 유지/보수 및 재사용성 향상 

③ 관리도구를 사용하여 버전관리와 롤백, 자동화 & GitOps통합 

 

(2) 관리 도구 

Kustomize (kubectl 내장)

- Kubernetes구성을 사용자 정의화하는 도구

- Overlay, 공통설정 재사용 

 

Helm

- 보편적으로 사용되는 Manifest도구 ( Kubernetes의 package manager)

- Template기반 manifest생성, 버전관리/업그레이드/롤백, 재사용 가능(차트)

 

③ 기타 : Kpt, Jsonnet

 

2) Kustomize (Kubernetes Customize)

https://kubectl.docs.kubernetes.io/

 

 

(1) 기본 기능

① Kubernetes 리소스를 레이어별로 구성 

② 리소스를 변경하지 않고 필드를 재정의하여 새로운 쿠버네티스 리소스를 생성 (override하여 생성)

 

(2) 구성

- 디렉터리 형태로 구성 ( base & overlay )  

 

Base

- Kustomize를 통해 변경할 yaml이 저장된 디렉터리

- Kustomization을 통해 재사용 가능 ( deployment, service등의 재사용 가능한 기본 yaml )

 

 Overlay

- Base에 적용할 kustomization.yaml이 저장된 디렉터리

- 환경별 차이점을 정의 ( overlays/prd, overlays/dev, overlays/stg 등으로 구성 )

 

(3) kustomization.yaml

 kustomize가 수행될때 재정의 될 필드를 설정하는 파일 (resource, patches, ... )

 resource, patches, namePrefix, ConfigMapGenerator 등 다양한 설정구성

- resources : kustomize 를 적용할 yaml 파일

- generators : 새로운 필드 생성

- transformers : 필드 변경

- validators : 검증 - 실패 시 배포 금지

- 그 외에도 configMapGenerator , namePrefix , patches 등의 플러그인 

③ kustomize 실행 순서

- resources → generators → transformers → validators

 

(4) 기본 활용 

① 설치 및 버전확인 

- 기본적으로  kubectl에 통합되어 있으나 여러 기능을 사용하기 위해서는 설치 필요

# Kubectl Version 확인
kubectl version --client

# Kubectl Version 확인 (kcustomize build외 다른 기능을 사용하기 위해 설치필요한 경우가 있음)
kubectl version --client

# Binary 설치
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash && mv kustomize /usr/local/bin

# MacOS
brew install kustomize

# Chocolatey (Window)
choco install kustomize

kustomize version

내장된 kustomize 버전확인 부가기능 활용을 위한 설치

 

② Kustomize 실행

- resourcce에 pod.yaml ( image에도 변경이 있으며, 변경된 이미지로 시행 )에 이미지 변경 적용

# 실습 디렉토리 생성
mkdir kustomize && cd kustomize

cat << EOF >> kustomization.yaml
resources:
  - pod.yaml

images:
  - name: nginx
    newName: new-nginx
    newTag: 1.23.1
EOF

kubectl kustomize .

# kustomize 결과를 파일로 추출
kubectl kustomize . > pod-kustomize.yaml

# 기존 Pod 파일과 차이 확인
diff pod.yaml pod-kustomize.yaml

새로운 리소스에 적용될 변경사항 (이미지 overlay, 기존의 Pod의 설정은 유지)

 

③ Kustomize로 배포 (기존 yaml파일 변경없이 새로운 설정을 적용)

# kustomize 배포
kubectl kustomize . | kubectl apply -f -

# kustomize 파일로 추출 후 배포
kubectl kustomize . > pod-kustomize.yaml | kubectl apply -f pod-kustomize.yaml

# 배포 확인
kubectl describe pod nginx | grep -i containers: -A4

#리소스 삭제
kubectl kustomize . | kubectl delete -f -

nginx pod에 변경된 설정 적용확인

 

(5) 심화 실습  

① reource 필드 확인 

-  명시된 파일이 지정된 조건으로 overlay (경로가 같아도 kustomization에 선언되지 않으면 적용안됨)

- 서비스, pod2개 배포, kustomization 

- 리소스에는 kustomization에 선언되어 있는 pod만 적용 

mkdir kustomize-1 && cd kustomize-1

cat << EOT > service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
EOT

cat << EOF > pod-1.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    name: nginx-1
  name: nginx-1
spec:
  containers:
  - image: nginx:latest
    name: nginx-1
    resources:
      limits:
        cpu: 100m
        memory: 64Mi
EOF

cat << EOF > pod-2.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    name: nginx-2
  name: nginx-2
spec:
  containers:
  - image: nginx:latest
    name: nginx-2
    resources:
      limits:
        cpu: 100m
        memory: 64Mi
EOF

cat << EOF > kustomization.yaml
resources:
  - pod-1.yaml
  - service.yaml
EOF

 

 1개의 서비스와 2개의 pod생성했으나 kustomize는 resource에 선언된 내용만 포함

1개의 서비스와 2개의 pod생성, kustomization.yaml에는 일부 pod만 포함

 

② 트랜스포머 필드확인

트랜스포머 필드 : namespace, image등의 다양한 필드값을 변경하는 기능 

- namespace를 변경, 이미지의 태그를 변경하는 내용 수행

#test의 namespace생성 
kubectl create ns test

#ns를 변경하도록 kustomization설정 
cat << EOT > kustomization.yaml
namespace: test
resources:
  - pod-1.yaml
  - service.yaml
EOT

# kustomize 실행, 변경 내용 확인 
kubectl kustomize .

#이미지의 태그를 변경하도록 kustomization설정 
cat << EOT > kustomization.yaml
namespace: test
images:
  - name: nginx
    newTag: 1.23.1
resources:
  - pod-1.yaml
  - service.yaml
EOT

# kustomize 실행, 변경 내용 확인 
kubectl kustomize .

kustomize로 namespace를 default에서 test로 변경적용 및 내용확인
kustomize로 image의 Tag를 변경적용 및 내용확인

 

③ Base / Overlays

- base와 overlay, dev와 prd

- base의 kustomize : resource에 pod 설정 

- overlay의 kustomize : resource에 base 디렉토리 설정, prefix(pod 이름앞에 추가) 

 

cd .. && mkdir kustomize-2 && cd kustomize-2

# 실습 디렉토리 구성
mkdir -p base overlays/dev overlays/prd

#트리 구성확인 
tree .

# Base kustomization.yaml 생성
cat << EOT > ./base/kustomization.yaml
resources:
- pod.yaml
EOT

# Base pod.yaml 생성 (공통으로 사용할 YAML 파일)
cat << EOT > ./base/pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: nginx
    image: nginx:latest
EOT

#dev, namePrefix를 네임앞에 적용 
cat << EOT > ./overlays/dev/kustomization.yaml
resources:
- ../../base
namePrefix: dev-
EOT

#prd, namePrefix를 네임앞에 적용 
cat << EOT > ./overlays/prd/kustomization.yaml
resources:
- ../../base
namePrefix: prd-
EOT

#변경된구조 확인 
tree .

# dev kustomize 실행 
kubectl kustomize overlays/dev

# prd kustomize 실행 
kubectl kustomize overlays/prd

overlays구성 ( base 실행시에 name에 prefix추가 )
개발과 운영의 pod에 주어진 prefix가 반영된 name설정

 

 

3) Helm ( 현업에서 일반적으로 쓰이는 방식 )

- Template형식, 하나의 yaml파일 (values.yaml) 모두 배포가능 

- 인증된 차트 공급자의 파일활용 : 자사 환경에 맞게 values.yaml설정을 overlay (주로 OpenSource인 ArgoCD, Metric Server, Nginx Ingress Controller등)   

- Helm Chart생성 : 자사의 서비스 배포환경에 맞게 구성 ( 주로 Application배포용으로 NextJS, SpringBoot )

 

 

https://circleci.com/blog/what-is-helm/

 

 

(1) 주요 구성 

① Chart 

- Helm의 패키지 ( yum, apt, brew와 유사 )

- 애플리케이션, 도구, 서비스를 구동하는 데 필요한 모든 리소스 정의 포함, Kubernetes 리소스들(Deployment, Service 등)

② Repository 

- Helm Chart의 저장/공유하는 장소 ( Kustomize의 경우는 공유하는 장이 없음 )

- 공유 저장소(Artifact Hub), 공유하기 어려운 내부 조건이 반영 시 설치형(Harbor)

** Harbor는 container설정 저장소였으나 최근 Helm chart저장소로도 확장 

③ Release 

- Helm Chart로 Kubernetes의 cluster에 배포한 인스턴스

- Chart별로 복수의 Release가능 ( overlay개념, version )

④ Values

- 사용자 정의값 (values.yaml이나 커맨드라인에서 전달하는 값 )커스터마이즈 

- 템플릿 파일 내의 변수들을 바인딩, 동적인 리소스 생성 가능

 

(2)기본 실습 

① Helm 설치 및 내용 확인 

- Helm repo ls : 로컬의 내부 repository확인 (local에 등록된 repo, 원격 url등)

- Helm create : Helm의 template의 기본 구조를 생성

- values.yaml의 내용을 각 template의 내용으로 대입하여 실행 

# Mac Homebrew 설치
brew install helm

# Windows Chocolatey
choco install kubernetes-helm

# Helm Version 확인
helm version
helm version --short

# Helm 디렉토리 이동
mkdir helm-practice

# Helm Repo 확인
helm repo ls

# Helm 생성
helm create mychart

# Helm 구조 확인
cd mychart
tree .

 

② Helm의 배포  

- install 명령어로 배포 ( release_name과 경로표시가 필요, 배포와 함께 version/namespace(Helm은 namespace에 종속)/notes(Helm>templates>notes에도 있음) 포함

- helm의 배포로 pod, deployment, service, service account까지 모두 완료

# Helm 배포
# helm install <RELEASE_NAME> <패키지 경로> [flags]
helm install myapp .   

# Helm Release 확인
helm list

# Helm 으로 배포된 리소스 확인
kubectl get po,deploy,svc,sa

# Helm 삭제
helm delete myapp

helm install로 배포하여 관련 리소스 일시에 생성

 

helm delete로 관련된 리소스 모두 terminate

 

(3) Values.yaml 

- 템플릿 파일 내의 변수들을 바인딩하여 동적인 리소스 생성 가능 

- 환경별로 yaml파일로 적용가능 ( dev, stg, prd )

artifacthub의 repo검색 후 install선택 시 관련 명령어(사용법) 출력, DEFAULT VALUES선택시 기본설정값 확인

 

① artifactHub의 repo를 활용한 배포  ( 커뮤니티의 공신력있는 Repository추가)

- repository추가 : helm repo add 차트명 <URL> 

- install 명령어로 배포 ( release_name과 chart경로표시 )

# Community Repository 추가
helm repo add bitnami https://charts.bitnami.com/bitnami

# Helm Repo 조회
helm repo ls

# Bitnami 의 Helm Chart 조회
helm search repo bitnami

# Helm Nginx 설치
# 최신 차트 정보를 가져오도록 하는 명령어
helm repo update

# Helm
# helm install <RELEASE_NAME> <CHART 경로> [flags]
helm install mynginx bitnami/nginx

kubectl describe deploy mynginx
kubectl describe deployments.apps mynginx | grep 'Containers:' -A5

repo추가 및 확인
artifact hub의 bitnami의 nginx repo로 배포
container부분의 구성

 

② values.yaml을 이용한 설정 변경(배포)  

- 이미지 태그를 변경하기 위한 values.yaml파일을 구성해서 helm에 적용 ( release에서 태그가 적용되며 version변경도 수행) 

# values.yaml 작성 (태그변경)
cat <<EOF > values.yaml
image:
  tag: 1.24
EOF

# 기존 Helm 설정을 values.yaml 파일에 기반하여 변경
helm upgrade mynginx bitnami/nginx -f values.yaml

kubectl describe deploy mynginx
kubectl describe deployments.apps mynginx | grep 'Containers:' -A5

# Helm Realese 조회
helm ls

새로운 values.yaml을 적용
이미지 태그 변경적용됨을 확인

 

 

3. GitOps 

 

https://docs.kakaocloud.com/blog/240524-gitops

 

1)Git Ops의 개요

(1) Git Ops의 내용 

① Flux를 개발한 Weaveworks에서 사용 (2017~)

② 환경을 선언적으로 정의하기 위해 Git Repository사용

③ 버전 관리와 병합요청을 통해 변경하여 전체 시스템 감시

 

(2) Git중심의 운영/배포 자동화 방식

① Infra와 Application설정을 Git저장소에 선언적 정의 ( 클러스터 상태 동기화 수행의 기반 )

CI(소스코드)와 CD(배포용 코드) 저장소 구분관리 ( yaml 파일 변경으로 리소스나 런타임 설정 변경시 빌드없이 배포/롤백 가능)

③ 핵심 개념

- 모든 설정을 Git에 저장, SSOT(Single Source of Truth, 단일 진실의 원천)로 사용

- 선언형 인프라 ( yaml 형태의 선언형 파일로 원하는 상태를 정의 )

- 자동 동기화 (Git의 선언형 파일과 클러스터 상태 동기화)

- 자동 롤백 및 감시 (Git으로 History추적, 승인절차 적용) 

 

2) ArgoCD 

- 현업에서는 실제로 GitOps와 ArgoCD활용

Architecture ( https://argo-cd.readthedocs.io/en/stable/ )

 

(1) Argo CD의 내용

① Git을 배포의 원천으로 사용하는 GitOps CD도구

- Git의 manifest를 기반으로 쿠버네티스 배포 및 상태 동기화 

② ArgoCD의 Application Controller 

- Kubernetes Controller(원하는 상태를 동기화)로 구성 

- Git의 선언된 상태와 동기화 수행  

③ 동작 방식이나 확장 플러그인의 활용이 다양함

- 배포전략, 알림설정등 확장성 보유 (Argo Rollout, Argo CD Notification)

 

(2) 실습

ArgoCD설치 

- helm으로 설치

- 서비스는 NodePort ( 31000, 31001번 포트연결, local 접속가능 )  

# ArgoCD Namespace 생성
kubectl create ns argocd

# Terminal 2번
watch kubectl get pod,pvc,svc -n argocd

# Helm Repo 등록
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update

helm install argocd argo/argo-cd --set server.service.type=NodePort --namespace argocd

# ArgoCD 서비스 접근을 위한 노드포트 변경
kubectl patch svc argocd-server -n argocd \
  -p '{"spec": {"ports": [{"port": 443, "targetPort": 8080, "nodePort": 31001}]}}'
  
# 리소스 확인
kubectl get all -n argocd

namespace argoCD등록 후 해당 ns에 repository추가
배포 후 pod, pvc, svc, argocd
443포트를 31001으로 변경

 

② ArgoCD 로그인 

- 비밀번호를 확인 후 Nodeport로 연결한 localhost의 포트주소로 연결하여 admin으로 로그인

# 초기 비밀번호 확인
kubectl -n argocd get secrets argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

# ArgoCD UI 접근
open http://localhost:31001

ID : admin,   PW : 위에서 나온 Hash 값

 

③ Git저장소를 생성하여 Chart생성  

- Git의 저장소 open하여 (ArgoCD가 접근할수 있는 Repository) clone

- Helm Chart생성 ( repository에 helm이 들어가 있으니깐 커밋 후 push하여 배포 ) 

 

# 본인 Repository 클론
git clone https://github.com/ellanelee/argocd-practice.git

# Helm Chart 생성
helm create argo-test-chart

# Git Push
git add . && git commit -m "Initial Commit" && git push origin main

Git Repository Clone
argo-test-chart를 만들고 원격 저장소에 push

 

Git의 원격 저장소에 반영

 

④ ArgoCD에 Git저장소를 연결하여 배포

- 어플리케이션 기본정보, Git저장소 연결 및 values.yaml 정보 설정 후 배포(CREATE)  

Application이름등의 기본정보 입력

 

git repository입력시 관련 정보가 연동되며 설정을 선택하여 Cluster정보와 yaml설정 후 CREATE

 

 

argoCD로 Git의 설정을 통한 배포 실행

 

ArgoCD에서 Container의 세부정보조회 (해당 Container Click)
CLI에서도 ArgoCD로 배포한 custom-nginx pod가 추가됨을 확인

 

⑤ values.yaml의 설정을 변경

- replicaCount를 2로, tag를 1.24로 변경하여 ArgoCD

# values 파일 변경
vim values.yaml

...
replicaCount: 2

image:
  repository: nginx
  tag: "1.24"
...

# Git push
git add . && git commit -m "Values Modified" && git push

values.yaml변경

 

ArgoCD에서 Pod구성 반영
세부 정보에서 이미지 태그 변경확인

 

CLI에서도 GitOps(ArgoCD)를 통해 배포한 pod 2개가 관찰됨

 

 

 

현업에서는 GitOps와 ArgoCD활용이 대세 ( ArgoCD 적용시 Default동기화 주기 3분으로 즉시 반영되지 않으며, 동기화 주기는 조정가능 )

  Custom Helm Chart생성을 위한 Helm Template문법 ( https://helm.sh/ko/docs/chart_template_guide/getting_started/ )

 

 

 

________________________________________________________

도커, 쿠버네티스 동아리의 마지막 강좌가 끝났다. 말로만 듣던 GitOps로 대단원의 막을 내렸다. 감개무량 ~ 

도커는 그래도 기본 개념은 알아서 수월했는데, 쿠버네티스는 생초보인데다가 CLI화면에 익숙하지 않은 리눅스 초짜여서 다채로운 국면이 있었다. 폴더를 잘못 들어가서 엉뚱한 짓(??)을 해놓고는 왜 안되지 어리둥절한 적도 있었다. 

아무리 자료가 상세해도 강의를 들을때만 이해가 되고 다시 보면 이거 뭐였더라~ 하고 파악이 안되는 경우도 많은데, 강의를 녹화본으로 제공해주셔서 차례차례 눈으로 확인할수 있고 잘 모르겠으면 여러번 돌려보면서 틀린 부분을 찾을수 있어서 좋았다.