gitOps

kimchigood·2023년 3월 23일
0

PKOS Study

목록 보기
6/8
post-thumbnail

이번 포스팅은 k8s를 활용한 gitOps에 대한 내용이다. 본 포스팅은 PKOS 스터디에서 '24단계 실습으로 정복하는 쿠버네티스' 책과 함께 진행되는 내용임을 밝힌다.
(이전 포스팅들과 마찬가지로, aws configure를 통해 cli에서 administer 권한이 있는 access key가 등록되어 있음을 가정한다.)

자, 그럼 Harbor, Gitlab, ArgoCD를 설치하여 GitOps를 구성해보자.

1. Preparation

kops 설치 (parameter는 각자의 환경에 맞는 값을 세팅한다.)

# YAML 파일 다운로드
curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/kops-oneclick-f1.yaml

# CloudFormation 스택 배포 : 노드 인스턴스 타입 변경 - MasterNodeInstanceType=t3.medium WorkerNodeInstanceType=c5d.large
aws cloudformation deploy --template-file kops-oneclick-f1.yaml --stack-name mykops --parameter-overrides KeyName=kp-gasida SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32  MyIamUserAccessKeyID=AKIA5... MyIamUserSecretAccessKey='CVNa2...' ClusterBaseName='gasida.link' S3StateStore='gasida-k8s-s3' MasterNodeInstanceType=c5a.2xlarge WorkerNodeInstanceType=c5a.2xlarge --region ap-northeast-2

# CloudFormation 스택 배포 완료 후 kOps EC2 IP 출력
aws cloudformation describe-stacks --stack-name mykops --query 'Stacks[*].Outputs[0].OutputValue' --output text

# 13분 후 작업 SSH 접속
ssh -i ~/.ssh/kp-gasida.pem ec2-user@$(aws cloudformation describe-stacks --stack-name mykops --query 'Stacks[*].Outputs[0].OutputValue' --output text)

# EC2 instance profiles 에 IAM Policy 추가(attach) : 처음 입력 시 적용이 잘 안될 경우 다시 한번 더 입력 하자! - IAM Role에서 새로고침 먼저 확인!
aws iam attach-role-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy --role-name masters.$KOPS_CLUSTER_NAME
aws iam attach-role-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy --role-name nodes.$KOPS_CLUSTER_NAME

# 메트릭 서버 확인 : 메트릭은 15초 간격으로 cAdvisor를 통하여 가져옴
kubectl top node

위 yaml파일로 설치를 하면, docker가 기본적으로 탑재되어 있는 bastion이 설치가 된다.

2. Harbor

Harbor는 도커레지스트리 처럼 컨테이너 이미지를 관리해주는 이미지 저장소라고 할 수 있다. Harbor가 오픈소스이기도 하고, 이렇게 로컬에서 설치와 사용이 간편해서 자주 쓰이는 것 같다. 보통 퍼블릭 클라우드 사용 시에는 CSP에서 제공하는 레지스트리를 사용하긴 한다.

그럼, helm chart를 통해 Harbor를 설치해보자.

Helm chart 설치

# 사용 리전의 인증서 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.gasida.link
expose.ingress.hosts.notary=notary.gasida.link
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.gasida.link             
----------------------

# 모니터링
kubectl create ns harbor
watch kubectl get pod,pvc,ingress -n harbor

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

# 확인
# registry : 컨테이너 이미지를 저장
# chartmuseum : 하버를 컨테이너 이미지뿐 아니라, 헬름 차트 리포지토리로도 사용
# notary : 서명이 완료된 컨테이너 이미지만 운영 환경에 사용하도록 설정. 서명이 완료된 이미지는 별도로 구분
# trivy : 컨테이너 이미지의 보안 취약점을 스캔, 스캔 기능은 별도 솔루션에서 제공하여 관리자는 보안 스캔용 도구를 선택 가능
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

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

미리 AWS에서 만든 ceritificate를 각자의 domain과 연동하면, 위에서 만들어진 url로 Harbor 접근이 가능하다.


Harbor 접속 및 이미지 push

  • 로그인: admin/Harbor12345
  • 신규 프로젝트 생성 : pkos (퍼블릭으로 생성해준다)


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

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

# 로그인 - 방안2
echo 'Harbor12345' > harborpw.txt
cat harborpw.txt | docker login harbor.$KOPS_CLUSTER_NAME -u admin --password-stdin
cat /root/.docker/config.json | jq

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


각자 url에 접속하여 로그인을 해보자. helm chart의 value.yaml에 보면 비밀번호가 있다.(Harbor12345)
위 실습에서 docker login 시 아래와 같은 에러가 날 경우

Get "https://harbor.kimchigood.link/v2/": dial tcp: lookup harbor.kimchigood.link on 10.0.0.2:53: no such host

/etc/resolv.conf의 nameserver를 8.8.8.8로 바꿔주면 해결된다.



[Harbor에 push된 이미지]

3. Gitlab

Gitlab도 자주 쓰는 소스코드관리 툴이다. 보통 Github이나 Gitlab을 사용하는 것 같은데, Gitlab은 쉽게 호스팅이 가능해서 많이들 사용하는 것 같다.

바로 설치를 진행해보자.

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

# 설치
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: <각자자신의도메인>             # 52줄
    https: true

  ingress:                             # 66줄~
    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}   # 각자 자신의 값으로 수정입력
      alb.ingress.kubernetes.io/success-codes: 200-399
      alb.ingress.kubernetes.io/group.name: "gitlab"
    tls:                               # 79줄
      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

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

# 4개의 Ingress 가 1개의 ALB를 공유해서 사용 : ALB의 Rule 확인해볼것!
# alb.ingress.kubernetes.io/group.name: "gitlab"
kubectl get ingress -n gitlab
NAME                        CLASS   HOSTS                  ADDRESS                                                             PORTS   AGE
gitlab-kas                  alb     kas.gasida.link        k8s-gitlab-3fbf5c8cab-1066962252.ap-northeast-2.elb.amazonaws.com   80      93s
gitlab-minio                alb     minio.gasida.link      k8s-gitlab-3fbf5c8cab-1066962252.ap-northeast-2.elb.amazonaws.com   80      93s
gitlab-registry             alb     registry.gasida.link   k8s-gitlab-3fbf5c8cab-1066962252.ap-northeast-2.elb.amazonaws.com   80      93s
gitlab-webservice-default   alb     gitlab.gasida.link     k8s-gitlab-3fbf5c8cab-1066962252.ap-northeast-2.elb.amazonaws.com   80      93s

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

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

# 웹 접속 https://gitlab.<각자 자신의 도메인> (root / 웹 root 계정 암호)

global.host.domain은 gitlab.kimchigood.link 형식이 아니라 kimchigood.link 만 입력해주는 것에 주의하자!

root유저로 새로운 user를 생성해준다. Administrator권한과 전체 scope를 체크한 impersonation token를 만들고, Internal Project까지 생성해보자. 프로젝트명은 test-stg로 하자.

그럼, 생성한 프로젝트와 k8s를 연동해보자

#
mkdir ~/gitlab-test && cd ~/gitlab-test

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

# git 계정 정보 확인 및 global 계정 정보 입력
git config --list
git config --global user.name "<각자 자신의 Gitlab 계정>"
git config --global user.email "<각자 자신의 Gitlab 계정의 이메일>"
git config --global user.name "gasida"
git config --global user.email "gasida@cloudneta.net"

# git clone
git clone https://gitlab.$KOPS_CLUSTER_NAME/<각자 자신의 Gitlab 계정>/test-stg.git
git clone https://gitlab.$KOPS_CLUSTER_NAME/kimchigood/test-stg.git
Cloning into 'test-stg'...
Username for 'https://gitlab.kimchigood.link': gasida
Password for 'https://gasida@gitlab.gasida.link': <토큰 입력>

# 이동
ls -al test-stg && cd test-stg && pwd

# 파일 생성 및 깃 업로드(push) : 웹에서 확인
echo "gitlab test memo" >> test.txt
git add . && git commit -m "initial commit - add test.txt"
git push
Username for 'https://gitlab.gasida.link': gasida
Password for 'https://gasida@gitlab.gasida.link': <토큰 입력>

여기까지 잘 되었으면, 아래와 같은 화면이 나온다. Gitlab까지 잘 세팅되었다. 이제 이번 포스팅에서 가장 중요한 ArgoCD로 넘어가보자.

4. ArgoCD

Harbor와 Gitlab은 보통 많이 쓰니까 잘 알고 있는 개념인데, ArgoCD는 무엇일까? 이게 바로 k8s에서 GitOps를 구현하기 위한 툴이다!

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

# 설치
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

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

kubectl get crd | grep argoproj
applications.argoproj.io              2023-03-19T11:39:26Z
applicationsets.argoproj.io           2023-03-19T11:39:26Z
appprojects.argoproj.io               2023-03-19T11:39:26Z

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

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

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

처음 Preparation에서 IAM Role세팅이 잘 되었다면 CLB에 도메인 연결이 잘된다. 접속을 해보면, ArgoCD 로그인 화면이 나온다.

이제 ArgoCD CLI도구를 설치해보자. 기본적으로 ArgoCD를 설치한 k8s가 클러스터로 등록되는데, 외부 클러스터로 등록하려면 UI에서는 불가능하고, CLI로만 가능하다.

# 최신버전 설치
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

# 버전 확인
argocd version --short

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

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

# 기 설치한 깃랩의 프로젝트 URL 을 argocd 깃 리포지토리(argocd repo)로 등록. 깃랩은 프로젝트 단위로 소스 코드를 보관.
argocd repo add https://gitlab.$KOPS_CLUSTER_NAME/<깃랩 계정명>/test-stg.git --username <깃랩 계정명> --password <깃랩 계정 암호>
argocd repo add https://gitlab.$KOPS_CLUSTER_NAME/gasida/test-stg.git --username gasida --password P@ssw0rd
 
# 등록 확인 : 기본적으로 아르고시디가 설치된 쿠버네티스 클러스터는 타깃 클러스터로 등록됨
argocd repo list
TYPE  NAME  REPO                                            INSECURE  OCI    LFS    CREDS  STATUS      MESSAGE  PROJECT
git         https://gitlab.gasida.link/gasida/test-stg.git  false     false  false  true   Successful

# 기본적으로 아르고시디가 설치된 쿠버네티스 클러스터는 타깃 클러스터로 등록됨
argocd cluster list
SERVER                          NAME        VERSION  STATUS   MESSAGE                                                  PROJECT
https://kubernetes.default.svc  in-cluster           Unknown  Cluster has no applications and is not being monitored.

아래는 세팅이 완료된 화면이다.

그럼 이제, rabbitMQ helm chart를 argoCD를 활용해서 배포해보자.

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

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

# RabbitMQ 헬름 차트 설치
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

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

# argocd CRD 확인
kubectl get crd | grep argo
applications.argoproj.io                              2022-01-25T15:46:16Z   # 배포 앱 현재 실행 상태와 깃 저장소의 의도한 상태를 계속 비교
appprojects.argoproj.io                               2022-01-25T15:46:16Z   # 프로젝트 단위 구분
argocdextensions.argoproj.io                          2022-01-25T15:46:16Z

# 수정
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.kimchigood.link/kimchigood/test-stg.git
    path: rabbitmq
    targetRevision: HEAD
    helm:
      valueFiles:
      - my-values.yaml
  syncPolicy:
    syncOptions:
    - CreateNamespace=true
--------------------------------------

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

# 배포
kubectl apply -f rabbitmq-helm-argo-application.yml

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

자, ArgoCD UI에서 보면 뭔가가 생겼다!

rabbitmq-helm-argo-application.yml 에서 repoURL을 rabbiMQ helm chart를 push한 곳을 바꿔주고, 배포를 하니 ArgoCD에서 helm chart를 설치하는 것이다.

Sync를 클릭하면 helm chart가 배포가 된다.

이제, GitOps를 찍먹해보자.
먼저 my-values.yaml 파일의 626라인 replicaCount 값을 2로 수정한다.

git push 하기

git add . & git commit -m "replica to 2"
git push

ArgoCD refresh & sync

결과는? 따로 kubectl 커맨드를 날리지 않아도 git을 통해 k8s의 리소스가 변했다. 이렇게 관리 하는게 바로 gitOps이다^^

wrap up

이번 시간에는 ArgoCD를 활용한 GitOps를 찍먹해봤다. 사실 현업에서도 아주 살짝 쓰고 있는 기능이라 그리 어렵지는 않았지만, 멤버들의 경험발표를 통해 많은 걸 배울 수 있었다.

예전에 ArgoCD의 데이터는 도대체 어디에 저장되는지 찾질 못해서 좀 의문인게 있었는데, ETCD에 저장된다는 말을 듣고 정말 깜짝 놀랬다!!!!!!!

배우고 공부하고 기억할건 넘친다~~~

profile
Shout out to Kubernetes⎈

0개의 댓글