PKOS Study #3 – GitOps System

PKOS Study #3은 GitOps System을 다룰 예정이다. 기존 실습에서는 kOps Instance에서 yaml을 통해 배포를 진행했었는데 GitOps을 사용하여 파이프라인을 통한 배포를 진행하는 것이 이번 실습의 목표이다.

0. 환경 구성

이번 실습도 Study #2와 마찬가지로 One-Click kOps yaml을 통해 진행했다. (maxpods 설정은 제거하고 진행했다.)

1. Harbor을 통해 Image 저장소 구축

Harbor : Docker 이미지를 저장하고 관리할 수 있는 중앙 집중식 이미지 저장소이다. Harbor을 통해 로컬 개발 환경에서 Docker 이미지를 빌드한 뒤 업로드할 수 있고 Docker CLI 및 API와 호환이 가능하다. 또한 이미지의 보안적 취약점 및 인증 문제를 확인할 수 있는 특징이 있다.

Harbor을 HelmChart을 통해 설치한다.

# 사용 리전의 인증서 ARN 확인
aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text
CERT_ARN=`aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text`
echo "alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN"

# 하버 설치<
helm repo add harbor https://helm.goharbor.io
helm fetch harbor/harbor --untar --version 1.11.0
vim ~/harbor/values.yaml
----------------------
expose.tls.certSource=none                        # 19줄
expose.ingress.hosts.core=harbor.<각자자신의도메인>    # 36줄
expose.ingress.hosts.notary=notary.<각자자신의도메인>  # 37줄<
expose.ingress.hosts.core=harbor.bs-yang.com
expose.ingress.hosts.notary=notary.bs-yang.com
expose.ingress.controller=alb                      # 44줄
expose.ingress.className=alb                       # 47줄~
expose.ingress.annotations=alb.ingress.kubernetes.io/scheme: internet-facing
expose.ingress.annotations=alb.ingress.kubernetes.io/target-type: ip
expose.ingress.annotations=alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
expose.ingress.annotations=alb.ingress.kubernetes.io/certificate-arn: ${CERT_ARN}   # 각자 자신의 값으로 수정입력
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
alb.ingress.kubernetes.io/certificate-arn: ${CERT_ARN}   # 각자 자신의 값으로 수정입력
externalURL=https://harbor.<각자자신의도메인>          # 131줄
externalURL=https://harbor.bs-yang.com             
----------------------
kubectl create ns harbor

helm install harbor harbor/harbor -f ~/harbor/values.yaml --namespace harbor --version 1.11.0

Harbor을 설치하고 모니터링 명령어 등을 통해 확인한다.

watch kubectl get pod,pvc,ingress -n harbor

helm list -n harbor
kubectl get-all -n harbor
kubectl get pod,pvc,ingress,deploy,sts -n harbor
kubectl get ingress -n harbor harbor-ingress -o json | jq
kubectl krew install df-pv && kubectl df-pv

<em># 웹 접속 주소 확인 및 접속</em>
echo -e "harbor URL = https://harbor.$KOPS_CLUSTER_NAME"

Harbor URL을 접속해서 제대로 사이트가 호출되는지 확인한다.

위와 같이 Harbor가 잘 설치 된 것을 확인할 수 있다.

로그인 후 New Project로 Project을 생성한다.

프로젝트 생성 후 컨테이너 이미지에 Tag 설정을 한 뒤 Harbor Project에 업로드를 한다.

<em># 컨테이너 이미지 가져오기</em>
docker pull nginx && docker pull busybox && docker images

<em># 태그 설정</em>
docker tag busybox harbor.$KOPS_CLUSTER_NAME/pkos/busybox:0.1
docker image ls

<em># 로그인 - 비밀번호는 미리 Harbor Portal에서 변경을 한다. 아래는 기본값을 바탕으로 한다.</em>
echo 'Harbor12345' > harborpw.txt
cat harborpw.txt | docker login harbor.$KOPS_CLUSTER_NAME -u admin --password-stdin
cat /root/.docker/config.json | jq

<em># 이미지 업로드</em>
docker push harbor.$KOPS_CLUSTER_NAME/pkos/busybox:0.1

이미지가 잘 업로드 된 것을 확인할 수 있다.

업로드 된 이미지로 Deployment을 생성하는 과정을 테스트해본다.

<em># 파드 배포</em>
curl -s -O https://raw.githubusercontent.com/junghoon2/kube-books/main/ch13/busybox-deploy.yml
sed -i "s|harbor.myweb.io/erp|harbor.$KOPS_CLUSTER_NAME/pkos|g" busybox-deploy.yml
kubectl apply -f busybox-deploy.yml

샘플 yaml을 받은 뒤 이미지 위치를 내 Harbor Project 저장소로 선택한다. 이렇게 하면 Pods을 배포할 때 위에서 설정한 이미지 저장소를 사용하게 된다. Pulling/Pulled을 참고하면 내 주소를 사용함을 알 수 있다.

업로드 된 이미지를 스캔하고 앞으로 업로드 될 이미지를 자동으로 스캔하게 하는 설정을 진행한다.

이미지를 선택 후 SCAN을 클릭한다. SCAN이 아직 진행되지 않았을 때는 Vulnerabilities에 Not Scanned로 표시 된다.

Scan이 완료 된 뒤에 문제가 없을 경우 No vulnerability로 표기됨을 알 수 있다.

아래는 앞으로 업로드(Push) 될 이미지들을 자동으로 Scan하는 방법이다.

Project을 선택한 뒤 Configuration을 선택하고 Automatically scan images on push을 체크하고 화면 하단의 SAVE을 클릭한다.

2. GitLab을 통해 Local Git 소스 저장소 구축

GitLab : Git Repo을 내부에서 관리할 수 있는 서비스이다. Private Github이라고 생각하면 편리하다.

이번 실습은 생성한 파일을 GitLab Repo에 업로드하는 것을 목표로 한다.

<em># 모니터링</em>
kubectl create ns gitlab
watch kubectl get pod,pvc,ingress -n gitlab

<em># 설치</em>
echo $CERT_ARN
helm repo add gitlab https://charts.gitlab.io/
helm repo update
helm fetch gitlab/gitlab --untar --version 6.8.1
vim ~/gitlab/values.yaml
----------------------
global:
  hosts:
    domain: <각자자신의도메인>             <em># 52줄</em>
    https: true

  ingress:                             <em># 66줄~</em>
    configureCertmanager: false
    provider: aws
    class: alb
    annotations:
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
      alb.ingress.kubernetes.io/certificate-arn: ${CERT_ARN}   <em># 각자 자신의 값으로 수정입력</em>
      alb.ingress.kubernetes.io/success-codes: 200-399
      alb.ingress.kubernetes.io/group.name: "gitlab" <em># 이렇게 할 경우 4개의 Ingress을 하나의 ALB로 생성 가능</em>
    tls:                               <em># 79줄</em>
      enabled: false
----------------------
helm install gitlab gitlab/gitlab -f ~/gitlab/values.yaml --set certmanager.install=false --set nginx-ingress.enabled=false --set prometheus.install=false --set gitlab-runner.install=false --namespace gitlab --version 6.8.4

위 내용을 사용하여 설치를 진행하고 아래와 같이 확인을 진행한다.

<em># 확인 - SubCharts</em>
<em># gitlab-gitaly : 웹서비스 혹은 ssh 방식으로 진행되는 깃 제목, 브랜치, 태그 등의 깃 요청 등에 대한 작업을 담당</em>
<em># gitlab-gitlab-shell : https 가 아닌 ssh 방식으로 깃 명령어 실행 시 해당 요청을 처리</em>
<em># gitlab-kas : gitlab agent server</em>
<em># gitlab-postgresql : 유저, 권한, 이슈 등 깃랩의 메타 데이터 정보가 저장</em>
<em># gitlab-redis-master : 깃랩 작업 정보는 레디스 캐시 서버를 이용하여 처리</em>
<em># gitlab-sidekiq-all-in-1-v2 : 레디스와 연동하여 작업 큐 처리 용도로 사용</em>
<em># gitlab-webservice-default : 깃랩 웹 서비스를 처리</em>
helm list -n gitlab
kubectl get pod,pvc,ingress,deploy,sts -n gitlab
kubectl df-pv -n gitlab
kubectl get-all -n gitlab

pod, pvc. ingress들이 정상적으로 생성 된 것을 확인 할 수 있다. 실습에 사용한 yaml 파일의 내용은 4개의 ingress을 하나의 ALB로 묶는 내용이었기 때문에 gitlab 관련 ALB는 하나만 생성 된 것을 볼 수 있다.

<em># 웹 root 계정 암호 확인</em>
kubectl get secrets -n gitlab gitlab-gitlab-initial-root-password --template={{.data.password}} | base64 -d ;echo

위 명령어로 root passwd을 확인한 뒤 alb와 연결 된 도메인 주소를 통해 gitlab에 접속을 할 수 있었다.

root로 로그인 후 간편하게 로그인 하기 위해 별도의 계정을 생성한 후 Admin권한을 부여한 뒤 해당 계정으로 로그인하였다. 앞으로 Gitlab 관련 된 작업은 해당 계정으로 진행할 예정이다. 해당 계정은 패스워드도 있지만 토큰 값도 생성되어 있는 상태로 터미널에서 계정에 로그인 할 때는 토큰값을 사용한다.

Gitlab에 코드를 업로드/다운로드 테스트하기 위해 프로젝트를 생성하였다.

<em>#</em>
mkdir ~/gitlab-test && cd ~/gitlab-test

<em># git 계정 초기화 : 토큰 및 로그인 실패 시 매번 실행해주자</em>
git config --system --unset credential.helper
git config --global --unset credential.helper

<em># git 계정 정보 확인 및 global 계정 정보 입력</em>
git config --list
git config --global user.name "userid"
git config --global user.email "user email"

<em># git clone/로그인 시 토큰 값을 사용</em>
git clone https://gitlab.$KOPS_CLUSTER_NAME/<각자 자신의 Gitlab 계정>/test-stg.git

터미널에서 gitlab 계정 정보를 입력해주고 git clone까지 시도했을 때 문제없이 정상적으로 성공했다.

이때 로그인에는 일반 패스워드가 아닌 계정 생성 때 같이 만든 Token값을 활용하였다.

로그인까지 정상적으로 됐으니 이제는 Local (kOps EC2)에 파일을 만들고 해당 파일을 push해보는 과정을 진행한다.

<em># 파일 생성 및 깃 업로드(push) : 웹에서 확인</em>
echo "gitlab test memo" >> test.txt
git add . && git commit -m "initial commit - add test.txt"
git push

위와 같이 test.txt가 정상적으로 push가 된 것을 확인 할 수 있다. 아래는 gitlab에 직접 접속해서 push 된 파일을 확인한 화면이다.

터미널에서 push한 파일이 정상적으로 gitlab site에서도 보이는 것을 확인 할 수 있다.

3. ArgoCD를 활용한 깃옵스(GitOps) 시스템 구축

Harbor을 통해 컨테이너 이미지 저장소를 구성했고 Gitlab으로 코드 저장소를 구성했다면 이제 ArgoCD을 통해 GitOps 시스템을 구축할 계획이다.

<em># 모니터링</em>
kubectl create ns argocd
watch kubectl get pod,pvc,svc -n argocd

<em># 설치</em>
cd
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
helm install argocd argo/argo-cd --set server.service.type=LoadBalancer --namespace argocd --version 5.19.14

<em># 확인</em>
<em># argocd-application-controller : 실행 중인 k8s 애플리케이션의 설정과 깃 저장소의 소스 파일에 선언된 상태를 서로 비교하는 컨트롤러. 상태와 다르면 ‘OutOfSync’ 에러를 출력.</em>
<em># argocd-dex-server : 외부 사용자의 LDAP 인증에 Dex 서버를 사용할 수 있음</em>
<em># argocd-repo-server : 원격 깃 저장소의 소스 코드를 아르고시디 내부 캐시 서버에 저장합니다. 디렉토리 경로, 소스, 헬름 차트 등이 저장.</em>
helm list -n argocd
kubectl get pod,pvc,svc,deploy,sts -n argocd
kubectl get-all -n argocd

kubectl get crd | grep argoproj

<em># CLB에 ExternanDNS 로 도메인 연결</em>
kubectl annotate service -n argocd argocd-server "external-dns.alpha.kubernetes.io/hostname=argocd.$KOPS_CLUSTER_NAME"

<em># admin 계정의 암호 확인</em>
ARGOPW=$(kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d)
echo $ARGOPW

<em># 웹 접속 로그인 (admin) CLB의 DNS 주소로 접속</em>
echo -e "Argocd Web URL = https://argocd.$KOPS_CLUSTER_NAME"

helm chart를 통해 설치하고 생성 된 CLB을 내 도메인에 연결하는 과정을 거친다.

위에서 확인한 admin 계정의 암호를 통해 로그인까지 성공할 수 있었다. 이상하게 argocd를 등록한 레코드만 실습 환경인 맥북에서 접속되지 않아 dns flush를 강제로 진행하고서야 접속할 수 있었다.

로그인을 진행했으니 앞서 생성한 Gitlab과 k8s cluster 등록을 위해 ArgocdCLI 도구를 설치한다.

<em># 최신버전 설치</em>
curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
chmod +x /usr/local/bin/argocd

<em># 버전 확인</em>
argocd version --short

<em># Help</em>
<em># argocd app : 쿠버네티스 애플리케이션 동기화 상태 확인</em>
<em># argocd context : 복수의 쿠버네티스 클러스터 등록 및 선택</em>
<em># argocd login : 아르고시디 서버에 로그인 </em>
<em># argocd repo : 원격 깃 저장소를 등록하고 현황 파악</em>
argocd

<em># argocd 서버 로그인</em>
argocd login argocd.$KOPS_CLUSTER_NAME --username admin --password $ARGOPW

<em># 기 설치한 깃랩의 프로젝트 URL 을 argocd 깃 리포지토리(argocd repo)로 등록. 깃랩은 프로젝트 단위로 소스 코드를 보관.</em>
argocd repo add https://gitlab.$KOPS_CLUSTER_NAME/<깃랩 계정명>/test-stg.git --username <깃랩 계정명> --password <깃랩 계정 암호>

Git repo와 kubernetes cluster 정보가 정상적으로 출력되는 것을 확인할 수 있다.

* 현재 출력되는 Cluster는 Argocd가 설치 된 k8s cluster로 이는 자동으로 등록된다. 나는 별도의 cluster를 나눠서 진행하고 있지 않기 때문에 상관 없으나 Cluster을 나눠서 진행할 경우 별도로 등록을 해줘야 한다.

Git repo가 등록됐으니 해당 repo을 사용해서 RabbitMQ Application을 배포해본다.

<em># test-stg 깃 디렉터리에서 아래 실행</em>
cd ~/gitlab-test/test-stg

<em># 깃 원격 오리진 주소 확인</em>
git config -l | grep remote.origin.url

<em># RabbitMQ 헬름 차트 설치</em>
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm fetch bitnami/rabbitmq --untar --version 11.10.3
cd rabbitmq/
cp values.yaml my-values.yaml

<em># 헬름 차트를 깃랩 저장소에 업로드</em>
git add . && git commit -m "add rabbitmq helm"
git push

<em># 수정</em>
cd ~/
curl -s -O https://raw.githubusercontent.com/wikibook/kubepractice/main/ch15/rabbitmq-helm-argo-application.yml
vim rabbitmq-helm-argo-application.yml
--------------------------------------
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: rabbitmq-helm
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    namespace: rabbitmq
    server: https://kubernetes.default.svc
  project: default
  source:
    repoURL: https://gitlab.myurl.com/path/xxx.git
    path: rabbitmq
    targetRevision: HEAD
    helm:
      valueFiles:
      - my-values.yaml
  syncPolicy:
    syncOptions:
    - CreateNamespace=true
--------------------------------------

<em># 모니터링 : argocd 웹 화면 보고 있기!</em>
echo -e "Argocd Web URL = https://argocd.$KOPS_CLUSTER_NAME"

<em># 배포</em>
kubectl apply -f rabbitmq-helm-argo-application.yml

<em># YAML 파일을 적용(apply)하여 아르고시디 ‘Application’ CRD를 생성</em>
kubectl get applications.argoproj.io -n argocd
NAME            SYNC STATUS   HEALTH STATUS
rabbitmq-helm   OutOfSync     Missing

배포 명령어를 입력하자마자 아래와 같이 ArgoCD 화면이 변경되는 것을 확인할 수 있었다.

 현재는 Missing/OutOfSync 상태이기 때문에 RabbitMQ Application을 들어가서 Sync을 클릭하여 동기화를 진행해준다. 이렇게 할 경우 별도의 helm install 명령어는 진행하지 않아도 된다.

동기화가 완료되면 아래 화면과 같이 Missing은 Healthy로 OutOfSync는 Synced로 변경된 것을 확인할 수 있다.

추가로 svc, ep 등이 확장되었음도 확인할 수 있다.

위 화면의 pod는 현재 1개인데 이를 2개로 확장하는 명령어를 입력해본 뒤 화면이 어떻게 변화하는지 확인해봤다.

명령어를 입력하자마자 ArgoCD 화면에 pod가 1개 추가 늘어나는 것을 볼 수 있었다.

물론 이 내용은 변경 된 부분이기 대문에 Sync는 다시 OutOfSync가 되니 다시 동기화를 진행해주어야 Synced 상태로 바꿀 수 있다.

여기까지 간단한게 ArgoCD을 활용한 GitOps 실습을 진행해보았다.

4. 마무리

이번 실습은 설치해야 하는 것들이 많아 시간이 오래 걸렸다. 지난 시간은 이론적으로 이해해야 하는 부분이 많았지만 실습 자체는 난이도가 높지 않았는데 이번에는 ingress 배포에서 조금 좌절을 하는 시간도 있었다. 제공 된 yaml을 수정하는 중에 놓치고 넘어간 부분이 있거나 잘못 수정한 부분이 있어 ingress가 배포되지 않아 로그를 확인해보는 등 시간을 소모해야 했다. 덕분에 실습을 조금 더 깊이 있게 들여다볼 수 있었고 harbor, gitops, ArgoCD을 사용한 GitOps 환경 구축 실습이 더 흥미로웠던 것 같다.

앞으로 프로젝트를 진행할 때 GitOps을 빼놓을 수 없을 것 같은데 이번에 미리 학습한 덕분에 실무에서도 잘 적용할 수 있을 것 같다는 생각을 하게 됐다.

다음 목표는 이번에 구성한 환경을 바탕으로 Application을 제작/수정/배포하는 내용을 진행해보고 싶다. 언젠가는 간단하지만 나만의 Application을 만들고 싶었는데 그 과정에 오늘 실습한 GitOps을 포함하면 더 수월하고 의미있는 프로젝트가 될 것 같다.

“PKOS Study #3 – GitOps System”에 한개의 의견

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다