오늘은 어제하던 로컬 환경에 쿠버네티스를 마저 구축하겠다.
어제 cnpg까지 구성했다.
일단 1교시 수업을 날려먹어서
2교시 수업부터 이어가겠다
harbor 구성까지는 일단 완료했고
gitea부터 가겠다.
폴더를 만들어 주고

07_gitea/main.tf
# main.tf 파일
terraform {
required_providers {
# terraform 으로 k8s 자원들을 provision 할수 있도록 provider 추가
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.30"
}
# terraform 으로 helm chart 를 직접 배포 가능하도록 하는 provider 추가
helm = {
source = "hashicorp/helm"
version = "~> 2.14"
}
}
}
# 클러스터 접속정보 (local k8s 를 바라 보도록 context 가 변경되어 있어야 한다)
provider "kubernetes" {
config_path = "~/.kube/config"
}
# helm provider 가 동작하려면 config 파일 정보를 전달해야 한다.
provider "helm" {
kubernetes {
config_path = "~/.kube/config"
}
}
resource "helm_release" "my_gitea" {
# helm install my-gitea
name = "my-gitea"
# helm repo add gitea-charts https://dl.gitea.com/charts/
repository = "https://dl.gitea.com/charts/"
chart = "gitea"
version = "12.6.0"
# -n gitea
namespace = "gitea"
# kubectl create namespace gitea 역할
create_namespace = true
# -f gitea-values.yaml
values = [
file("${path.module}/gitea-values.yaml")
]
}
기존의 깃티 네임스페이스가 있다면 지우고 다시 실행하면 된다
kube delete ns gitea

젠킨스를 위한 yaml 파일 jenkins-values.yaml도 작성해준다
# [네트워크 설정] MetalLB 로드밸런서를 통한 외부 서비스 노출
service:
http:
type: LoadBalancer
port: 80
loadBalancerIP: "172.16.8.42"
annotations:
# HTTP와 SSH 서비스가 동일한 고정 IP(172.16.8.42)를 나눠 쓰도록 허용하는 설정입니다.
# 이 주석(Annotation) 값이 서로 같아야만 두 서비스가 충돌 없이 1개의 IP로 묶입니다.
metallb.universe.tf/allow-shared-ip: "gitea-shared"
ssh:
type: LoadBalancer
port: 22
loadBalancerIP: "172.16.8.42"
annotations:
# 동일한 공유 ID를 지정하여 HTTP(80)와 SSH(22)가 공존할 수 있게 만듭니다.
metallb.universe.tf/allow-shared-ip: "gitea-shared"
# 깃랩/깃허브 역할을 하는 소스코드 저장소(Gitea) 앱 설정
gitea:
admin:
username: "admin"
password: "abcd1234"
config:
server:
# 웹 브라우저 화면에 표시될 기본 도메인과 깃 클론용 SSH 주소를 우리 로드밸런서 IP로 강제 지정!
DOMAIN: "172.16.8.42"
SSH_DOMAIN: "172.16.8.42"
webhook:
ALLOWED_HOST_LIST: "*"
# 실습 환경을 위해 무겁고 복잡한 고가용성(HA/Cluster) 모드는 모두 차단합니다.
postgresql-ha:
enabled: false
redis-cluster:
enabled: false
valkey-cluster:
enabled: false
# [실습 최적화] 가볍고 날씬한 단일(Standalone) DB & 캐시만 활성화합니다.
postgresql:
enabled: true
persistence:
enabled: true
size: "5Gi" # 우리가 만든 nfs-client 스토리지 클래스에서 5기가를 자동으로 떼옵니다.
volumePermissions:
# 온프레미스 NFS 실습 시 발생하는 Permission Denied 에러를 원천 차단합니다.
enabled: true
valkey:
enabled: true
volumePermissions:
# 캐시 서버(Valkey) 역시 데이터 저장소 권한 문제를 자동으로 해결하도록 켭니다.
enabled: true
테라폼을 실행해보면 깃티 파드가 정상적으로 뜬 것을 확인할 수 있다.

다음은 젠킨스를 바꿔보겠다.

여기에도 main.tf를 만들어주고
# main.tf 파일
terraform {
required_providers {
# terraform 으로 k8s 자원들을 provision 할수 있도록 provider 추가
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.30"
}
# terraform 으로 helm chart 를 직접 배포 가능하도록 하는 provider 추가
helm = {
source = "hashicorp/helm"
version = "~> 2.14"
}
}
}
# 클러스터 접속정보 (local k8s 를 바라 보도록 context 가 변경되어 있어야 한다)
provider "kubernetes" {
config_path = "~/.kube/config"
}
# helm provider 가 동작하려면 config 파일 정보를 전달해야 한다.
provider "helm" {
kubernetes {
config_path = "~/.kube/config"
}
}
# main.tf
resource "helm_release" "my_jenkins" {
# helm install my-jenkins
name = "my-jenkins"
# helm repo add jenkins https://charts.jenkins.io
repository = "https://charts.jenkins.io"
chart = "jenkins"
version = "5.9.34"
# -n jenkins
namespace = "jenkins"
# kubectl create namespace jenkins 역할
create_namespace = true
# -f jenkins-values.yaml
values = [
file("${path.module}/jenkins-values.yaml")
]
}
jenkins-values.yaml
controller:
# 젠킨스 웹 UI 접속 방식 (MetalLB를 활용한 LoadBalancer)
serviceType: LoadBalancer
# 고정 IP MetalLB 대역
loadBalancerIP: "172.16.8.41"
# 젠킨스가 내부적으로 인식할 공식 주소를 아예 Helm 배포 단계에서 주입
jenkinsUrl: "http://172.16.8.41:8080/"
# 관리자 초기 비밀번호
admin:
password: "@admin1234"
# K8s 플러그인을 위한 권한 부여 (필수)
rbac:
create: true
overwritePlugins: false
persistence:
enabled: true
size: "3Gi"
storageClass: "nfs-client"
41번 ip를 쓰고
Nfs 볼륨을 쓴다.
비밀번호도 지정을 해줄 수 있다
젠킨스에 들어가서 새 레포지토리를 만들어주겠다.
젠킨스가 초기 환경이니 설정에 들어가서 크레덴셜을 등록해주겠다.

젠킨스에서는 깃티와 하버에 접속해야하니 크레덴셜을 등록해주겠다.
이것또한 테라폼을 통해 자동화시킬 수 있다.
유저네임과 비밀번호를 입력해준다

이런식으로 깃티와 하버 둘다 등록해준다

그 다음 플러그인이 필요하다

플러그인가서 gitea와 generic webhook Trigger를 설치해주자
이것또한 테라폼으로 자동화할 수 있다
install을 누르면 설치가 된다

이제 파이프라인을 만들어주겠다
어제 배운대로 한번만 만들고 xml로 다운받아서 자동화 시키겠음

파이프라인의 이름을 정해주겠다 hello-app-pipeline으로 했다
설명 대충 적어주고
트리거를 generic webhook trigger를 이용하겠다

variable, expression도 설정해주고, token도 설정해주자
나중에 사진을 첨부하겠다.
optional fileter도 정규표현식과 텍스트를 설정해주고
파이프라인은 SCM으로부터 가져오겠다
깃티에서 http 주소 가져오고
젠킨스파일의 위치도 명시해주고

세이브를 누르면 파이프라인이 만들어졌다.
파이프라인이 동작을 하는지 테스트를 하려면 지금 빌드를 눌러보면 된다

정상동작하고 있다
젠킨스 파드가 만들어지고 여기서 실행이 된다 실행이 완료되면 이 파드는 자동으로 삭제된다

그 닫음 실습을 위해 새로운 폴더를 만들어보자
코드 공유 사이트에서 파일을 다운받고 안에 넣어주자

msa로 구성된 앱이다
소스코드를 봐보자

이런 요청이 들어오면

json 값을 리턴하는데 토큰을 리턴하게 된다.
구조는 다음과 같다
클라이언트는 인덱스와 유저에는 접속이 가능하지만
마켓과 포스트에는 유효한 토큰이 없으면 접속이 불가능하게 되어있다.

인덱스 페이지로 이동 -> 로그인 (액세스 토큰 발급) -> 토큰을 가지고 마켓과 포스트에 접근 가능

큰 구조는 이렇다

안에 들어있는 도커파일을 이용해서 이미지를 빌드하고 msa를 구성할 예정이다
docker Hub에 로그인을 먼저한다
# 도커허브 로그인
docker login
# 환경 변수 설정, 매번 입력해주기 귀찮으니
export DOCKER_ID="docker hub id"
# 파일 위치로 이동해서
cd /home/user1/ktcloud-kubernetes/example/step11_jwt/micro-app-istio
# 이미지 빌드
docker build -t $DOCKER_ID/micro-index:1.0 ./index
docker build -t $DOCKER_ID/micro-user:1.0 ./user
docker build -t $DOCKER_ID/micro-market:1.0 ./market
docker build -t $DOCKER_ID/micro-posts:1.0 ./posts
# 이미지 푸시
docker push $DOCKER_ID/micro-index:1.0
docker push $DOCKER_ID/micro-user:1.0
docker push $DOCKER_ID/micro-market:1.0
docker push $DOCKER_ID/micro-posts:1.0
이렇게하면 이미지들이 내 도커허브에 푸시가 되었다.
이제 이 이미지들을 내 로컬 쿠버네티스 환경에 배포하고 싶다면,
깃티 레포 만들기 -> 젠킨스 연결 -> 파이프라인 작성 -> 아르고 CD 연결을 해주면 될 것이다.
주말에 시간이 된다면 이것을 구현해보겠다.
다음주에 있을 프로젝트 발표부터 준비하고..