




https://chabin37.tistory.com/81
[미니PC] 1. 우분투 서버에 Kubernetes(마스터+워커 단일 서버)+ArgoCD 설치 관련
https://chabin37.tistory.com/75 미니 PC를 활용한 나만의 서버 사용 후기CPU : N100Ram : 16GB DDR4이러한 성능을 가진 저전력 CPU를 활용한 미니 PC를 구비해 테스트용 서버로 거의 1년정도 사용하고 있다.업비
chabin37.tistory.com
이전 글에서 말했다시피, 일단은 GitHub Action과 ArgoCD를 활용하여 CI/CD를 구축하기로 하였다(속도를 보아 하니, 답답해서 곧 JenKins로 넘어갈것 같기도 하다).
하면서 느낀점은...코딩 이외의 어려움이였다(진짜 매우 어려움이였다. 나는 GPT없었으면 절때 개발자 못했을 것 같다.)
CI/CD 흐름 정리
간단히 흐름을 정리해보면 다음과 같다.
[개발자]
└─ 코드 푸시 (GitHub / GitLab 등)
[Jenkins]
├─ 1. 코드 빌드 (Maven, Gradle 등)
├─ 2. 테스트 실행 (JUnit, Selenium 등)
├─ 3. Docker 이미지 생성 (Dockerfile)
├─ 4. Docker Hub, ECR, GCR 등에 Push
├─ 5. deployment.yaml의 이미지 태그 수정 (버전 업데이트)
└─ 6. 수정된 yaml을 Git에 커밋 & 푸시
[Argo CD]
├─ 1. Git 변경 감지 (GitOps)
├─ 2. 자동 배포 (Application Sync)
└─ 3. Kubernetes 클러스터에 배포 적용 (kubectl apply)
[Kubernetes]
├─ 1. Deployment 생성 / 업데이트
├─ 2. Pod 스케줄링 (Scheduler)
├─ 3. Service로 외부 트래픽 라우팅 (LoadBalancer, NodePort)
├─ 4. ConfigMap / Secret 적용
└─ 5. Auto-scaling (HPA, VPA)
Jenkins부분에 GitHub Action을 자리하면 된다.
리포지토리를 2개로 나눠서, ArgoCD가 감시할 리포지토리와 실제 내 애플리케이션이 있는 리포지토리 총 2개를 만들어서 사용한다.
자동화 흐름은 다음과 같다
- 내 애플리케이션 수정 사항을 커밋(혹은 PR)
- .github/workflows에 ci.yaml을 인식해서 파일 내 작업 진행(CI)
- 깃허브 서버(우리 서버 아님)에서 테스트 진행
- 테스트 통과 시 컨테이너 레지스트리(여기선 GHCR) 푸시
- ArgoCD가 감시하는 리포지토리에 내용 수정해 자동으로 커밋
- ArgoCD가 해당 리포지토리의 변화를 발견하고, 이미지를 pull하여 배포(CD)
전 과정 자동화가 가능하다. 직접 컨테이너를 만들어서 수동으로 배포하다가 이를 한번 구축하면, 헤어나오지 못할 매력에 빠질 수 있다.
이걸 하루라도 늦게 안게 아쉽고, 하루라도 일찍 알아서 다행이라는 생각이 든다.
사전 작업
- (Github)두 리포지토리에 토큰 생성(GHCR용.repo, write:packages, delete:packages 권한을 허용하여 토큰을 생성)
- (Github)토큰을 해당 리포지토리의 Setting-Security-Secrets and variables-Actions에 저장(GHCR_TOKEN와 MANIFEST_REPO_PAT)
- (Ubuntu-컨테이너 이미지 pull 할 서버)도커 레지스트리 접근을 위해 다음 명령어 실행(이후 아래 helm차트에 명시해야 함)
kubectl create secret docker-registry my-registry-secret \
--docker-server=ghcr.io \
--docker-username=<유저 이름> \
--docker-password=<GHCR용 토큰> \
--docker-email=<이메일> \
-n <네임스페이스명>
.github/workflows내부 ci.yaml
자세한 내용/바꿀 값들은 GPT와 같이 바꿔야 한다.
name: CI/CD - Build, Push, and Update Manifests
on:
push:
branches:
- master
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
# 1. 소스 코드 체크아웃
- name: Checkout source code
uses: actions/checkout@v3
# 2. Gradle 테스트 실행 (빌드 전에)
- name: Test with Gradle
run: ./gradlew test
# 3. Docker Buildx 설정
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# 4. GitHub Container Registry 로그인
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GHCR_TOKEN }}
# 5. 컨테이너 이미지 빌드 및 푸시
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
ghcr.io/name/my-app:latest
ghcr.io/name/my-app:${{ github.sha }}
# 6. ArgoCD 매니페스트 업데이트 (이미지 태그 변경)
- name: Checkout k8s manifests repository
uses: actions/checkout@v3
with:
repository: name/k8s-manifest-repo-test
token: ${{ secrets.MANIFEST_REPO_PAT }}
path: k8s-manifests
- name: Update image tag in values.yaml
run: |
cd k8s-manifests/my-app-manifests-repo/my-app-chart
sed -i "s|tag: .*|tag: ${{ github.sha }}|" values.yaml
- name: Commit and push changes to manifest repo
run: |
cd k8s-manifests
git config user.name "GitHub Actions Bot"
git config user.email "actions@github.com"
git add my-app-manifests-repo/my-app-chart/values.yaml
git commit -m "Update image tag to ${{ github.sha }}"
git push
ArgoCD(k8s 메니페스트) 용 Repository 내용
helm 차트를 활용하여, 간편하게 배포할 수 있게끔 한다. 파일 구조는 다음과 같다.
my-app-manifests-repo/
├── argocd/
│ └── my-app-argocd-application.yaml # ArgoCD 애플리케이션 설정 파일
└── my-app-chart/
├── Chart.yaml # Helm 차트 메타데이터
├── values.yaml # Helm 기본 변수값 설정
└── templates/
├── deployment.yaml # Kubernetes Deployment 설정
└── service.yaml # Kubernetes Service 설정
이 yaml 내부의 내용을 작성은 하겠지만, 아주 높은 확률로 상황에 맞춰서 수정해야 한다.
argocd-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
spec:
project: default
source:
repoURL: <k8s 메니페스트용 repo>
path: my-app-manifests-repo/my-app-chart
targetRevision: HEAD
destination:
server: https://kubernetes.default.svc
namespace: test123
syncPolicy:
automated:
prune: true
selfHeal: true
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-app
labels:
app: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}
spec:
imagePullSecrets:
- name: my-registry-secret
containers:
- name: {{ .Release.Name }}-app
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
ports:
- containerPort: 8080
service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-service
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: 8080
{{- if eq .Values.service.type "NodePort" }}
nodePort: {{ .Values.service.nodePort }}
{{- end }}
selector:
app: {{ .Release.Name }}
chart.yaml
apiVersion: v2
name: my-app
description: My sample application
version: 0.1.0
appVersion: "1.0"
values.yaml
replicaCount: 1
image:
repository: ghcr.io/name/my-app
tag: <자동으로 바뀌거나 정책을 정할 수 있음>
pullPolicy: IfNotPresent
service:
type: NodePort
port: 80
nodePort: 30000
ingress:
enabled: false
hostname: myapp.example.com
destination:
server: https://kubernetes.default.svc
namespace: test123
ArgoCD app생성
다음 필드값들을 설명에 맞게 채우면 된다.
- source - Repository URL: 메니페스트 리포지토리 url
- Revision: 어느 브렌치를 감시할지 지정
- Cluster URL: https://kubernetes.default.svc
- Namespace: 이미 존재하는 namespace적어야 함 (혹은AUTO-CREATE NAMESPACE 옵션)
- Sync Policy: Automatic (Prune, Self-Heal)
'Infra' 카테고리의 다른 글
| [K8S] 쿠버네티스에서 Ingress를 활용한 HTTPS 적용방법(NGINX Ingress Controller) (0) | 2025.06.27 |
|---|---|
| [미니PC] 3. k8s에 환경 변수 적용하기(namespace기준, CI/CD와 별개로 미리 등록) (2) | 2025.05.16 |
| [미니PC] 1. 우분투 서버에 Kubernetes(마스터+워커 단일 서버)+ArgoCD 설치 관련 (0) | 2025.05.14 |
| [Docker] portainer와 watchtower (0) | 2025.03.26 |
| 미니 PC를 활용한 나만의 서버 사용 후기 (2) | 2025.03.23 |