gitops
Mont Kim / February 2023 (1433 Words, 8 Minutes)
4주차 GitOps
이번 Gitops에서 다루는 내용은 위와 같다.
이번 스터디내용에서는 Gitlab Runner는 사용하지 않고 Gitlab 에서 GIt version이 변경되면 argo에서 변경된것을 Deploy 할 수 있는 구조이다.
하지만 이번 게시글에선 추가적으로 Gitlab Runner를 설치해서 CI/CD 파이프라인을 구축하는 과정까지 따로 담아본다.
Harbor 설치하기
harbor를 설치하는데도 몇가지 옵션이 존재한다.
stand alone 서버에 docker로 서비스를 올리는것도 가능하고,
쿠버네티스 내부에 helm chart를 이용한 harbor 설치도 지원한다.
helm 등을 이용해 서비스를 설치할때
ingress를 생성하면서 로드밸런서에 설정할 값들을 미리 입력해준다.
# 사용 리전의 인증서 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 차트를 이용해 harbor 차트를 다운로드받는다.
helm repo add harbor https://helm.goharbor.io
helm fetch harbor/harbor --untar
helm차트를 직접 설치하는것이 아닌 fetch를 하면 로컬에 helm 파일들이 생기는데
일반적으로 values.yaml 파일에 내가 필요했던 옵션들을 명세해두면
그 값들에 해당되는 설정되로 helm설치가 진행된다.
vi harobr/values.yaml
expose.tls.certSource=none
expose.ingress.hosts.core=harbor.mont-kim.com
expose.ingress.hosts.notary=notary.mont-kim.com
expose.ingress.controller=alb
expose.ingress.className=alb
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}
externalURL=https://harbor.mont-kim.com
파일 작성을 완료했으면 설치를 진행한다.
kubectl create ns harbor
helm install harbor harbor/harbor -f ~/harbor/values.yaml --namespace harbor --version 1.11.0
위와같이 fetch 해서 다운로드받은 후 수정했던 values.yaml 파일을 -f 옵션으로 지정해 설치를 진행한다.
helm 설치에 문제가 발생한다면
helm install harbor harbor/harbor -f ~/harbor/values.yaml --namespace harbor --version 1.11.0
kubectl delete pvc --all -n harbor
과정을 통해 원상복구 할 수 있다.
설치가 진행되면서 loadbalancer가 생성되는데, 약 3-5분정도 대기후 해당 도메인으로 접속하면 접속이 가능하다.
harbor의 기본 접속정보는
ID | PW |
---|---|
admin | Harbor12345 |
로 접속 할 수 있다.
과제 1 Harbor에 이미지 푸시하기
harbor는 docker 레지스트리로 https 통신을 하기때문에 꼭 인증서가 필요하다.
오늘 하는 실습의 경우엔 클라우드상 진행되고, ACM을 이용한 인증서를 ACM으로 발급받았다.
만약 온프렘에서 구현을하고자한다면 let’s encrypt (certbot)을 이용해 인증서를 발급받아 harbor를 실행할때 별도로 넣어주는 작업이 필요하다.
인증서 이야기가 왜 나왔냐면
harbor를 설치할 때, https 인증서가 없으면 별도의 설정을 변경하지 않는다면
docker login 자체가 불가능하다.
정상적인 설정이 끝났다면 로그인에 문제가 없어야한다.
docker login harbor.mont-kim.com -u admin -p Harbor12345
사실 로그인 명령어창에 비밀번호까지 치는건 절대 보안에 좋지않다…
이제 도커 이미지를 만들시간이다.
아무 예제나 해도 상관없지만, 실생활에 조금 더 밀접한 이미지면 친근하지않을까 싶어
“마인크래프트 서버 이미지 굽기”로 실행을 해본다
Dockerfile
FROM openjdk:18-jdk-bullseye
RUN curl -OJ https://meta.fabricmc.net/v2/versions/loader/1.19.2/0.14.12/0.11.1/server/jar
ENTRYPOINT java -Xmx4G -jar fabric-server-mc.1.19.2-loader.0.14.12-launcher.0.11.1.jar nogui
docker build --tag minecraft .
로컬 이미지 명이아닌, 레지스트리 명으로 도커이미지를 태그해준다.
빌드가 완료되면 빌드 된 이미지를 따로 확인 할 수 있다.
docker images
이미지가 정상적으로 생긴것을 확인했으니 도커 이미지 태그를 변경해 레지스트리에 적합한 이름으로 변경한다.
docker image tag minecraft harbor.mont-kim.com/pkos/minecraft
푸쉬를 진행한다.
푸쉬 성공!
하버에서 확인을 마저 진행해본다.
이미지가 정상적으로 들어온걸 확인했다.
Gitlab 설치하기
gitlab또한 helm 차트를 이용해 설치를 진행한다.
kubectl create ns gitlab
helm repo add gitlab https://charts.gitlab.io/
helm repo update
helm fetch gitlab/gitlab --untar
vi gitlab/values.yaml
global:
hosts:
domain: mont-kim.com # 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
certmanager: # 833줄
installCRDs: false
install: false
rbac:
create: false
nginx-ingress: # 847줄
enabled: false
prometheus: # 904줄
install: false
gitlab-runner: # 1130줄
install: false
certmanager에서 인증서를 발급받을 필요 없이, acm으로 발급받은 인증서를 arn으로 받아와 인증하기떄문에 옵션을 활성화 할 필요가 없다.
nginx-ingress는 온프렘에서 ingress를 로드밸런서 대신 쓰기위해 사용하는 옵션이다.
별도로 프로메테우스 모니터링을 할게 아니기때문에 활성화 할 필요가 없고
gitlab-runner또한 기본 과제에서는 쓸 일이없기때문에 false로 해둔다.
gitlab runner는 별도의 helm chart로 실행해도 되기때문에, 설치를 하지않고 진행해본다.
helm install gitlab gitlab/gitlab -f ~/gitlab/values.yaml --namespace gitlab --version 6.8.1
LoadBalancer가 생성되어 Gitlab에 접속되기까지 5분이상 기다려아하는것 같다.
kubectl get secrets -n gitlab gitlab-gitlab-initial-root-password --template= | base64 -d ;echo
기본 비밀번호는 secret에 base 64로 인코딩 되어있어 디코딩을 진행한후 로그인한다.
gitlab의 기본 접속정보는 https://gitlab.mont-kim.com
ID | PW |
---|---|
root | 디코딩한 PW |
Gitlab에 접속해 프로젝트를 생성한다.
Project : test-stg
URL : mont-kim/test-stg
Type : Internal
프로젝트 내부의 Access Token을 발급해 자격증명에 사용한다.
mkdir ~/gitlab-test && cd ~/gitlab-test
git config --global user.name mont
git config --global user.email mont@pkos.com
git 사용을 위한 기본적인 값을 입력해준다.
global 설정이기때문에 해당 머신을 다른사람과 같이쓰고있으면…
정보가 겹칠 수 있으니 조심하도록 한다.
과제2 gitlab에 파일 푸쉬하기
git clone https://gitlab.$KOPS_CLUSTER_NAME/mont/test-stg.git
개인이 만든 계정의 하위 git 폴더를 git clone한다.
ls -al test-stg && cd test-stg
# 파일 생성 및 깃 업로드(push) : 웹에서 확인
echo "gitlab test memo" >> test.txt
git add .
git commit -m "initial commit - add test.txt"
git push
clone 했던 폴더로 들어가 임의의 파일을 생성한다
git clone 명령어에 계정이름 - api token으로 인증이 가능하다
push되어 생성된 test.txt 파일을 확인한다.
Gitlab Runner 설치하기
Gitlab에서는 쿠버네티스의 자원을 이용해 코드가 push 되었을때 동작하는 시스템을 갖고있다.
github의 action과 비슷한 개념이라고 볼 수 있다.
gitlab runner를 등록하기위해선 runner의 token을 받아야한다.
project 내부의 settings → CI/CD → Runner에 들어가면 해당 창과같이 정보가 표시된다.
해당 주소, token을 다음 runner 파일에 입력하면 된다.
gitlab-values.yaml
gitlabUrl: http://gitlab.mont-kim.com
runnerRegistrationToken: "@@@@@@@@@"
## For RBAC support:
rbac:
create: true
clusterWideAccess: true
runners:
config: |
[[runners]]
[runners.kubernetes]
image = "gitlab/gitlab-runner:15.7.1"
helper_cpu_limit = "200m"
[[runners.kubernetes.volumes.empty_dir]]
name = "docker-certs"
mount_path = "/certs/client"
medium = "Memory"
[[runners.kubernetes.volumes.empty_dir]]
name = "dind-storage"
mount_path = "/var/lib/docker"
[[runners.kubernetes.volumes.host_path]]
name = "hostpath-modules"
mount_path = "/lib/modules"
read_only = true
host_path = "/lib/modules"
[[runners.kubernetes.volumes.host_path]]
name = "docker"
mount_path = "/var/run/docker.sock"
host_path = "/var/run/docker.sock"
tags: "dind"
privileged: true
등록할 gitlab runner에서 jenkins와같이 특정 job을 할당하기위해 tags를 부여하는것이 명확하게 구분하기 좋다.
태그명으로 알 수 있듯이, Docker In Docker 기능을 사용하기위해 tag로 dind로 구분을 했으며
Docker(쿠버네티스상 컨테이너) 안에서 또 새로운 도커 명령어를 수행해야하기때문에
pribileged 권한을 부여해야 gitlab에서 docker 명령어를 사용 할 수 있다.
작성한 gitlab-values.yaml파일을 이용해 helm 설치를 진행한다.
helm repo add gitlab https://charts.gitlab.io
helm repo update
kubectl create namespace gitlab-managed-apps
helm install --namespace gitlab-managed-apps gitlab-runner -f gitlab-values.yaml gitlab/gitlab-runner
문제가 생기거나, 재설치가 필요하면 helm 재설치를 진행해준다.
helm uninstall --namespace gitlab-manged-apps gitlab-runner
helm install --namespace gitlab-managed-apps gitlab-runner -f gitlab-values.yaml
해당 helm을 설치하게되면
gitlab runner라는 deployment가 생성되고
ci 요청이 들어올때마다 새로운 pod들을 생성한다.
sample ci 파일을 작성해본다.
.gitlab-ci.yml
stages:
- test
- build
- deploy
variables:
IMAGE_NAME: nodejs-server-test
cache:
paths:
- node_modules/
test:
stage: test
tags:
- dind
image: node:latest
script:
- env
- npm install
build:
stage: package
image: docker:latest
services:
- docker:dind
stage: build
tags:
- dind
script:
- ls -al
- docker container ls -a
- docker build -t $IMAGE_NAME .
- docker images | grep 'nodejs-server-server'
deploy:
stage: deploy
image: docker:latest
services:
- docker:dind
script:
- docker container ls -a
- docker container rm -f nodejs-server
- docker run -d -p 8090:8090 --name nodejs-server --restart always $IMAGE_NAME
- docker container ls -a
정상적으로 pipeline이 동작해 도커 이미지를 만든것을 확인했다.
ARGO CD
CI / CD 파이프라인의 완성은 CI로 끝나는것이 아닌 CD까지 있어야 완성이다.
이 CD를 완성시켜주는 솔루션중 하나가 ARGO CD이다.
ARGO CD 또한 helm으로 설치를 진행한다.
argo cd 는 별도로 설정이 필요없이 설치를 진행해도 된다.
kubectl create ns argocd
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
ALB로 프로비저닝을 진행했기때문에 생성까지 5-10분정도 기다리면 접속이 된다.
이후엔 argo 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
classic 로드밸런서로 argocd를 서비스를 노출했기때문에, loadbalancer의 주소를 획득해 서비스에 접속을 진행한다.
CLB=<각자 자신의 argocd 서비스의 CLB 도메인 주소>
ARGOPW=$(kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d)
echo $ARGOPW
argocd login $CLB --username admin --password $ARGOPW
argocd 로그인이 완료되었다.
argocd repo add https://gitlab.$KOPS_CLUSTER_NAME/mont-kim/test-stg.git --username mont--password P@ssw0rd
arogcd repo list
gitlab 프로젝트를 internal로 생성했기때문에, 자격증명을 완료해야 argo에 gitlab 소스를 등록 할 수 있다.
과제 3 ARGOCD 적용하기
예제파일인 rabbit-mq를 실행하는 예제를 실행해본다.
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm fetch bitnami/rabbitmq --untar
cd rabbitmq/
cp values.yaml my-values.yaml
git add .
git commit -m "add rabbitmq helm"
git push
rabbit mq에 필요한 파일들을 git 저장소에 push해둔다.
curl -s -O https://raw.githubusercontent.com/wikibook/kubepractice/main/ch15/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.mont-kim/mont/test-stg.git
path: rabbitmq
targetRevision: HEAD
helm:
valueFiles:
- my-values.yaml
syncPolicy:
syncOptions:
- CreateNamespace=true
argocd에 필요한 파일 작성후 적용한다
kubectl apply -f rabbitmq-helm-argo-application.yml
argocd 웹에서 상태창을 확인 할 수 있다.
이번주는 전체적인 GitOps에 대해 배워보았다.
Git의 경우 Gitlab이 마이너한 느낌이 없지않아있지만
Self Hosted으로 설치할수있다는 장점부터 직접 관리하기에도 꽤 유용한듯해
CI/CD 파이프라인을 관리하기 수월할수도 있다는 생각이 든다.
레지스트리또한 Harbor외에 아티팩토리 기능까지 지원하는 다른 솔루션들도 많지만
제일간편하게 쓰기 좋은방법이라고 생각이 된다.
사실 자사에서 미니PC(Wyse Thin PC)를 이용해 클러스터를 구축중이다
온프렘에서 클러스터를 구축하는데 애로사항이 진짜 많다.
내부망에서만 사용할것이라면 상관없겠지만, 그렇지않다면 해결해야될 네트워크 문제들이 정말많은데
클라우드에서는 프로비저닝부터 서비스 노출하기까지 정말 편하다는 생각이 다시끔 든다.
아직 자세히 아는것은 아니지만, 클라우드를 사용하면 가격이 많이 올라간다 라는 이야기들이있다.
하지만 클라우드도 잘 알고 비용절감을 한다면 꽤 합리적인 가격에 이용할수있다는 이야기가 있던데, 클라우들 쓰면 정말 많은 기능들을 손쉽게 쓸수있다는걸 다시끔 느끼는 실습과정이였다.