2025. 11. 15. 10:00ㆍCICD
실습 환경 배포
kind 배포
kind create cluster --name myk8s --image kindest/node:v1.32.8 --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
labels:
ingress-ready: true
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
- containerPort: 30000
hostPort: 30000
- containerPort: 30001
hostPort: 30001
- containerPort: 30002
hostPort: 30002
- containerPort: 30003
hostPort: 30003
EOF
kube-ops-view 배포
# helm 레포지토리 추가
helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
# kube-ops-view 배포
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set service.main.type=NodePort,service.main.ports.http.nodePort=30001 --set env.TZ="Asia/Seoul" --namespace kube-system
# kube-ops-view 접속 URL 접속 확인
open "http://127.0.0.1:30001/#scale=2"

ingress-nginx 배포
노드 라벨 확인
# 마스터 노드 라벨 확인
kubectl get nodes myk8s-control-plane -o jsonpath={.metadata.labels} | jq
배포
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
# 배포 확인
kubectl get deploy,svc,ep ingress-nginx-controller -n ingress-nginx
kubectl describe -n ingress-nginx deployments/ingress-nginx-controller



myk8s-control-plane의 iptables 규칙 확인
DNAT 설정 - myk8s-control-plane으로 80,443 포트로 트래픽이 들어올 경우 10.244.0.8 IP가 할당된 Pod의 80,443포트로 포워딩
(ingress-nginx)- SSL Passthrough flag 활성화
해당 설정을 활성화 하는 목적은 호화된 트래픽(TLS/SSL)을 인그레스 컨트롤러에서 복호화(해독)하지 않고, 원본 그대로 백엔드 파드(Pod)까지 전달하기 위해서다.(활성화 하지 않을 경우 Too Many Redirect 발생)
# ingress-nginx-controller 수정
KUBE_EDITOR="nano" kubectl edit -n ingress-nginx deployments/ingress-nginx-controller

ArgoCD 설치
TLS 통신 과정(Client > ingress > Argo CD Server > Secret)

TLS 인증서 발급
# 공통 이름 argocd.example.com
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout argocd.example.com.key \
-out argocd.example.com.crt \
-subj "/CN=argocd.example.com/O=argocd"
# 인증서 확인
openssl x509 -noout -text -in argocd.example.com.crt


생성된 TLS 적용을 위해 secret 생성
# 네임스페이스 생성
kubectl create ns argocd
# TLS 시크릿 생성
kubectl -n argocd create secret tls argocd-server-tls \
--cert=argocd.example.com.crt \
--key=argocd.example.com.key

(ArgoCD) - SSL-PassThrough 적용 및 배포
cat <<EOF > argocd-values.yaml
global:
domain: argocd.example.com
# TLS certificate configuration via cert-manager
certificate:
enabled: true
server:
ingress:
enabled: true
ingressClassName: nginx
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "true" # 강제 리다이렉트
nginx.ingress.kubernetes.io/ssl-passthrough: "true" # SSL-Passthrough
tls: true
EOF
helm repo add argo https://argoproj.github.io/argo-helm
helm install argocd argo/argo-cd --version 9.0.5 -f argocd-values.yaml --namespace argocd
(Argo CD) - 서비스 확인
kubectl get pod,ingress,svc,ep,secret,cm -n argocd


도메인 설정

접속 확인
# 도메인 curl
curl -vk https://argocd.example.com/
kubectl -n ingress-nginx logs deploy/ingress-nginx-controller
kubectl -n argocd logs deploy/argocd-server
# 최초 비밀번호 확인
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d ;echo
# UI 접속(강제 리다이렉트 확인 필요)
open "http://argocd.example.com"

TLS 인증서 확인(발급 기관 : argocd.example.com)

(Argo CD) - CLI 접속 확인
argocd login argocd.example.com --insecure
ID/PW 입력

(Argo CD) - CLI 명령어 실행 확인

선언적 사용자
- Argo CD에서 선언적 사용자란 핵심 설정 파일인 argocd-cm(configmap) 내에 코드로 직접 정의하고 관리하는 로컬 사용자 계정을 의미한다.
- 선언적 사용자에게 실제 권한은 RBAC(Role-Based Access Control)으로 설정
선언적 방식 사용 목적
- Argo CD를 다른 시스템으로 전환할 경우 argocd-cm YAML파일만 적용하면 기존에 정의된 모든 자동화 계정들 사용 가능
- GitOps 파이프라인을 통해 사용자 계쩡의 생성 및 변경을 자동화 가능
관리자(admin) 계정
- Argo CD 생성 시 기본적으로 관리자 계정 생성 ( 전체 액세스 권한 부여 )
- admin 비밀번호는 Secret에 저장
kubectl get secret -n argocd argocd-initial-admin-secret --context kind-myk8s -o jsonpath='{.data.password}' | base64 -d

관리자(admin) 패스워드 변경
# 현재 접속 중인 계정 패스워드 변경
argocd account update-password
# 현재 패스워드 입력
# 변경 패스워드 입력
# 변경 패스워드 재입력
# 다른 계정 패스워드 변경
argocd account update-password --acount {user명}

(중요!) 관리자 계정은 초기 구축 이후 로컬 사용자 계정이나 SSO 통합을 구성하는 것이 보안성 면에서는 좋음.
아래 argocd-cm configmap에서 정의된 admin.enabled를 true > false로 변경하면 admin 계정 비활성화

일반(user) 계정
argocd-cm 수정
kubectl get cm -n argocd argocd-cm -o yaml
KUBE_EDITOR="nano" kubectl edit cm -n argocd argocd-cm
# 내용 추가
accounts.alice: apikey, login
# 계정 확인
argocd account list
apikey - API key를 통한 호출 허용
login - UI 접속 허용



계정 패스워드 변경
argocd account update-password --account alice --curent-password qwe12345 --new-password alice12345
# 변경 확인
kubectl get secret -n argocd argocd-secret -o jsonpath='{.data}' | jq


accounts.alice.password는 base64로 디코딩해도 실제 비밀번호가 나오지 않는다.

위와 같이 $2a$~로 표시되는데 Argo CD가 보안을 위해 실제 비밀번호를 bcrypt 해시로 변환하여 저장한 값으로 실제 비밀번호를 Secret을 통해서 확인하는 것은 불가능하다.
애플리케이션 배포 테스트
Admin 계정 - 애플리케이션 배포
cat <<EOF | kubectl apply -f -
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
helm:
valueFiles:
- values.yaml
path: helm-guestbook
repoURL: https://github.com/argoproj/argocd-example-apps
targetRevision: HEAD
syncPolicy:
automated:
enabled: true
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
destination:
namespace: guestbook
server: https://kubernetes.default.svc
EOF
배포 확인
kubectl get applications -n argocd guestbook
kubectl get applications -n argocd guestbook -o yaml | kubectl neat | yq
kubectl get pod,svc,ep -n guestbook

Argo CD UI 확인 - admin 계정

Argo CD UI 확인 - alice 계정

alice 계정은 생성 이후 별도에 권한을 부여하지 않았으며, 권한이 부여되지 않은 경우 기본 정책(policy.default)에 따라 argoCD에 대한 권한이 결졍된다.
권한 부여(RBAC)
- RBAC 기능은 Argo CD 리소스에 대한 액세스를 제한
- admin 사용자는 SuperUser이며, 모든 액세스 권한 부여
- RBAC을 사용하려면 SSO 구성 or 하나 이상의 로컬 사용자 필요
- SSO 또는 로컬 사용자를 구성한 후에는 추가 RBAC 역할을 정의하고 SSO 그룹 또는 로컬 사용자를 역할에 매핑

기본 내장 역할 : Argo CD에는 두 가지 사전 정의된 역할이 있지만 RBAC 구성을 사용하면 역할과 그룹을 정의할 수 있습니다.
- role:readonly : 모든 리소스에 대한 읽기 전용 액세스
- role:admin : 모든 리소스에 대한 무제한 액세스
RBAC 설정
kubectl get cm -n argocd argocd-rbac-cm -o jsonpath='{.data}' | jq
KUBE_EDITOR="nano" kubectl edit cm -n argocd argocd-rbac-cm
# 기존 - policy.default: ""
# 변경 - policy.default: "role:readonly"
Argo CD UI 확인 - alice 계정


Argo CD CLI - alice 계정 로그인
argocd login argocd.example.com --insecure --username alice
# User - alice, Password - alice12345


admin 계정 비활성화
KUBE_EDITOR="nano" kubectl edit cm -n argocd argocd-cm
argocd account list


admin 계정 접속 확인

서비스 어카운트
- CI/CD 파이프라인과 같은 자동화를 시스템에 인증하는 데 사용하는 계정
- 사용자를 비활성화하거나 권한을 제어하면 파이프라인이 실패할 수 있기 때문에 사용자와 연결
- 엄격하게 권한을 제한해야 하고 파이프라인에서 수행하는 것 이상의 권한이 있으면 안 된다.
- ArgoCD에서 서비스 어카운트 생성 방법(API 키만을 사용하는 로컬 사용자[로그인 기능 제거], 프로젝트 역할을 사용하고 그 역할에 토큰을 할당)
서비스 어카운트 생성 및 RBAC 설정(api키만 생성)
KUBE_EDITOR="nano" kubectl edit cm -n argocd argocd-cm
# accounts.gitops-ci : apiKey 내용 추가
# 생성 확인
acrocd account list

계정 토큰 생성
argocd account generate-token -a gitops-ci
PermissionDenied 에러 발생

현재 로그인 되어 있는 alice 계정에는 별도에 권한을 설정하지 않았기에 토큰이 생성되지 않는다.
권한 설정은 아래와 같이 진행한다.
# p : 권한 정책 설정, g : 사용자 또는 그룹에 역할을 연결 할 때 사용
KUBE_EDITOR="nano" kubectl edit cm -n argocd argocd-rbac-cm
policy.csv: |
p, role:user-update, accounts, update, *, allow # 정책 설정(user-update 역할을 통해 부여된 계정이 업데이트 권한 허용)
p, role:user-update, accounts, get, *, allow # 정책 설정(user-update 역할을 통해 부여된 계정이 조회 권한 허용)
g, alice, role:user-update # 그룹 정의(alice 계정에 user-update 정책 부여)
# 토큰 재생성 시도
argocd account generate-token -a gitops-ci
# 토큰 작동 확인
argocd account get-user-info --auth-token {토큰 값}


Project Role과 Token
- 프로젝트 역할은 서비스 어카운트에서 사용할 수 있는 두 번째 옵션
- 애플리케이션 프로젝트는 역할을 통해 애플리케이션 정의에 일부 제약 조건을 적용하는 방식
- 리포지터리, 대상 클러스터나 배포할 수 있는 네임스페이스를 지정할 수 있고, 설치할 수 있는 리소스 유형을 필터링
기본 프로젝트 권한 확인
kubectl get appprojects.argoproj.io -n argocd default -o yaml | k neat | yq

Argo CD 생성 이후 기본으로 제공되는 프로젝트는 별도의 제약 사항 없다.
- clusterResourceWhitelist : 클러스터 범위 내 리소스에 대한 모든 그룹 및 종류에 대한 관리 가능
- destinations : 모든 네임스페이스 및 워커 노드들에 대해서 애플리케이션 배포 가능
- sourceRepos : 모든 Git 저장소를 소스 저장소로 사용 가능
애플리케이션 프로젝트 생성(프로젝트 역할 설정)
#
cat <<EOF | kubectl apply -f -
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: sample-apps
namespace: argocd
spec:
roles:
- name: read-sync
description: read and sync privileges
policies:
- p, proj:sample-apps:read-sync, applications, get, sample-apps/*, allow
- p, proj:sample-apps:read-sync, applications, sync, sample-apps/*, allow
clusterResourceWhitelist:
- group: '*'
kind: '*'
description: Project to configure argocd self-manage application
destinations:
- namespace: test
server: https://kubernetes.default.svc
sourceRepos:
- https://github.com/argoproj/argocd-example-apps.git
EOF
#
kubectl get appproject -n argocd

프로젝트 권한 설명
- 사용자 역할(spec.roles)

>> read-sync 역할을 가진 사용자는 sample-apps 프로젝트에 속한 모든 애플리케이션에 get,sync 작업을 허용
- 프로젝트 역할(제한)

>> 모든 클러스터 리소스에 대한 그룹과 종류에 대한 배포가 가능하며, test 네임스페이스에서만 리소스 배포가 가능하며, argocd-example-apps.git만 소스 저장소로 사용 가능
Argo CD - UI 확인



sample-apps 프로젝트에 애플리케이션 배포
cat <<EOF | kubectl apply -f -
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: pre-post-sync
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: sample-apps
source:
path: pre-post-sync
repoURL: https://github.com/argoproj/argocd-example-apps
targetRevision: master
destination:
namespace: test
server: https://kubernetes.default.svc
syncPolicy:
automated:
enabled: false
syncOptions:
- CreateNamespace=true
EOF
# 애플리케이션 조회
argocd app list

수동 동기화 실행(실패 - 권한 에러 발생)
argocd app sync argocd/pre-post-sync

rbac-cm 정책 수정(read,sync 권한 추가)
KUBE_EDITOR="nano" kubectl edit cm -n argocd argocd-rbac-cm
# 현재 권한
# apiVersion: v1
# data:
# policy.csv: |
# p, role:user-update, accounts, update, *, allow
# p, role:user-update, accounts, get, *, allow
# g, alice, role:user-update
# 변경 권한
# apiVersion: v1
# data:
# policy.csv: |
# p, role:user-update, accounts, update, *, allow
# p, role:user-update, accounts, get, *, allow
#(추가)p, role:user-update, projects, update, sample-apps, allow
# g, alice, role:user-update
역할 토큰 생성
argocd proj role create-token sample-apps read-sync


Argo CD - SSO

ArgoCD - admin 계정 활성화
# argocd-cm 수정
KUBE_EDITOR="nano" kubectl edit cm -n argocd argocd-cm

ArgoCD CLI - admin 로그인
argocd login argocd.example.com --username admin --password qwe12345 --insecure

설치 - Kubernetes
# 관리자 ID : admin, 관리자 PW : admin
docker run -d \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
-p 8080:8080 \
--name dev-keycloak \
quay.io/keycloak/keycloak:22.0.0 start-dev
# 확인
docker ps
# 로그 확인
docker logs dev-keycloak
# 자바 버전 확인
docker exec -it dev-keycloak java --version
docker images
docker history quay.io/keycloak/keycloak:22.0.0 --no-trunc --format json | jq
# /opt/keycloak/bin 경로 확인 및 실행
docker exec -it dev-keycloak ls -l /opt/keycloak/bin
docker exec -it dev-keycloak cat /opt/keycloak/bin/kc.sh
# 기본 정보 및 접속 확인
docker exec -it dev-keycloak id
open http://localhost:8080/admin
#접속 모니터링
```bash
# 도커에서 컨테이너로 Keycloak 실행
# 기본 관리자 계정이 제공되지 않아, 환경 변수로 초기 관리자 계정 생성
docker run -d -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin **--net host** --name dev-keycloak quay.io/keycloak/keycloak:22.0.0 **start-dev**
# 확인
**docker ps**
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
db56c9925eff quay.io/keycloak/keycloak:22.0.0 "/opt/keycloak/bin/k…" 7 seconds ago Up 6 seconds 0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp, 8443/tcp dev-keycloak
**docker logs dev-keycloak**
...
2025-10-13 13:52:35,966 INFO [org.keycloak.services] (main) KC-SERVICES0050: **Initializing master realm**
2025-10-13 13:52:36,845 INFO [io.quarkus] (main) Keycloak 22.0.0 on JVM (powered by Quarkus 3.2.0.Final) started in 4.856s. Listening on: http://0.0.0.0:8080
2025-10-13 13:52:36,845 INFO [io.quarkus] (main) **Profile dev activated**.
2025-10-13 13:52:36,845 INFO [io.quarkus] (main) Installed features: [agroal, cdi, hibernate-orm, jdbc-h2, jdbc-mariadb, jdbc-mssql, jdbc-mysql, jdbc-oracle, jdbc-postgresql, keycloak, logging-gelf, micrometer, narayana-jta, reactive-routes, resteasy, resteasy-jackson, smallrye-context-propagation, smallrye-health, vertx]
2025-10-13 13:52:36,941 INFO [org.keycloak.services] (main) KC-SERVICES0009: Added **user** 'admin' to **realm** 'master'
2025-10-13 13:52:36,943 WARN [org.keycloak.quarkus.runtime.KeycloakMain] (main) Running the server in **development mode**. DO NOT use this configuration in production.
docker exec -it dev-keycloak **java --version**
openjdk 17.0.8 2023-07-18 LTS
docker images
**docker history quay.io/keycloak/keycloak:22.0.0 --no-trunc --format json | jq**
{
"Comment": "buildkit.dockerfile.v0",
"CreatedAt": "2023-08-10T00:27:54+09:00",
"CreatedBy": "**ENTRYPOINT** [\"**/opt/keycloak/bin/kc.sh**\"]",
"CreatedSince": "2 years ago",
"ID": "sha256:456b66461f4b63c7a42de1981b8f72052087c84df460b57db013c7d6fc7aed3e",
"Size": "0B"
...
docker exec -it dev-keycloak **ls -l /opt/keycloak/bin**
docker exec -it dev-keycloak **cat /opt/keycloak/bin/kc.sh**
docker exec -it dev-keycloak **id**
uid=1000(keycloak) gid=0(root) groups=0(root)
# admin 웹 콘솔 접속 : admin / admin
**open http://localhost:8080/admin**
# 로그 모니터링 걸어두기
docker logs dev-keycloak -f




KeyCloak - 접속 확인


KeyCloak - 일반 유저 생성



KeyCloak - ArgoCD 연동 Client 생성




Key Cloak - Client Credential 복사 및 저장

ArgoCD - OIDC 설정
# oidc key의 값으로 아까 생성된 key-cloak client credential 입력
kubectl -n argocd patch secret argocd-secret --patch='{"stringData": { "oidc.keycloak.clientSecret": "LO7dCzcBsXDgcVXdjvPFkHrSCC3C08WP" }}'


Argocd - argocd-cm 수정
# argocd-cm 내용 추가
KUBE_EDITOR="nano" kubectl edit cm -n argocd argocd-cm
# 해당 내용 추가
data:
url: https://argocd.example.com # 맨 아래 있음
oidc.config: |
name: Keycloak
issuer: http://192.168.254.110:8080/realms/master
clientID: argocd
clientSecret: mV3IZO3nmHoZr3BBC37UpdrMSMkF9Umt
requestedScopes: ["openid", "profile", "email"]

ArgoCD - 재기동
kubectl rollout restart deploy argocd-server -n argocd
ArgoCD - Keycloak 로그인



KeyClock - 세션 현황 확인



'CICD' 카테고리의 다른 글
| CI/CD 6주차(Argo CD)[3] - App of Apps, ApplicationSet (0) | 2025.11.22 |
|---|---|
| CI/CD 5주차(Argo CD)[2] - Argo Rollout (0) | 2025.11.15 |
| CI/CD 4주차(Argo CD) (0) | 2025.11.09 |
| CI/CD 3주차(Jenkins + ArgoCD + gogs[Repo]) (0) | 2025.11.01 |
| CI/CD 2주차 (0) | 2025.10.26 |