[CI/CD Study 5주차] ArgoCD 접근 제어
CoudNet@ 팀의 가시다님께서 리딩하시는 CI/CD Study 5주차 스터디 내용 정리
이번 주차도 마찬가지로 '예제로 배우는 ArgoCD 책' 기반으로 학습했습니다.
이번 글에서는 ArgoCD 접근 제어에 대해서 학습한 내용을 서술하겠습니다.
1. ArgoCD 접근 제어 실습 환경 구성
이번 실습 환경도 전과 마찬가지로 kind 를 통해서 구성했으며, Control Plane 1대로 구성했습니다.
그 후 ArgoCD 와의 통신을 위해 Ingress Nginx Controller 를 배포하여 HTTPS 통신을 구현했습니다.
1.1. 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
1.2. Ingress Nginx Controller 배포
이번은 ArgoCD 가 메인이므로 Ingress Nginx Controller 에 대해서는 자세히 다루지 않았습니다.
다만 기본 설정으로 배포할 경우 ArgoCD 의 HTTPS 접속 시,
307 Too Much Redirect 에러가 발생하므로 SSL Passthrough 설정을 추가로 활성화 합니다.
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
# 307 Too Much Redirect 에러 방지를 위한 SSL Passthrough 활성화
kubectl edit -n ingress-nginx deployments/ingress-nginx-controller
# Ingress Nginx Controller Argument 에 아래 옵션 주입
- --enable-ssl-passthrough

주입이 성공적으로 완료되면, Pod 가 자동으로 재기동 됩니다.
1.3. ArgoCD 배포
ArgoCD TLS 인증서 생성
ArgoCD TLS 동작을 구현하기 위해서 cert-manager 없이 OpenSSL 로 self-signed 인증서를 생성하고 Secrets 을 생성하겠습니다.
Argo CD 서버는 TLS 인증서를 argocd-server-tls Secret 에서 직접 로드합니다.
# 인증서 생성
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"
# CRT 생성
openssl x509 -noout -text -in argocd.example.com.crt
# ArgoCD 네임스페이스 생성
kubectl create ns argocd
# TLS 시크릿 생성
kubectl -n argocd create secret tls argocd-server-tls \
--cert=argocd.example.com.crt \
--key=argocd.example.com.key
# Secret 확인
kubectl get secret -n argocd
ArgoCD 배포
# ArgoCD Values 작성
cat <<EOF > argocd-values.yaml
global:
domain: argocd.example.com
server:
ingress:
enabled: true
ingressClassName: nginx
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
tls: true
EOF
# ArgoCD 배포
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
# Mac 에서 ArgoCD 도메인에 대해 host 파일 등록
echo "127.0.0.1 argocd.example.com" | sudo tee -a /etc/hosts
# 접속 확인
curl -vk https://argocd.example.com/
# 최초 암호 확인 후 로그인
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d ;echo
open "http://argocd.example.com"
TLS 를 설정하고 Cert 를 주입했기 떄문에, 인증서 목록에 자체 인증서 항목이 나옵니다.

2. ArgoCD 계정 설정
Argo CD 를 설치하면 admin 시스템에 대한 전체 액세스 권한을 가진 기본 사용자 한 명이 생성됩니다.
Admin 계정은 초기 구성 시에만 사용하고, 이후에는 로컬 사용자 계정으로 전환하거나 SSO 통합을 구성하는 것이 좋습니다.
2.1. Admin 계정 암호 변경
이전 글에는 계정 암호를 UI 에서 변경했지만, ArgoCD CLI 로도 가능합니다.
argocd account update-password

2.2. ArgoCD 일반 계정 생성
Admin 계정을 대신할 일반 사용자 계정을 생성해보겠습니다.
사용자 계정은 ArgoCD 의 argocd-cm 컨피그맵을 통해 관리할 수 있습니다.
kubectl edit cm -n argocd argocd-cm
# data 구문에 아래 값 추가
accounts.alice: apiKey, login

이후 ArgoCD UI 에서 확인하면 Alice 사용자가 생성된 것을 알 수 있습니다.

2.3. ArgoCD 일반 계정 암호 설정
ArgoCD 에서 사용자 계정 관리에 대한 설정은 모두 YAML 파일로 관리하거나 ArgoCD CLI 로 진행해야합니다.
UI 에서는 아직 해당 기능을 제공하지 않고 있습니다.
생성한 Alice 계정에 대해 암호를 설정해보겠습니다.
# 사용자 확인
argocd account list
# Alice 계정 암호 변경
argocd account update-password \
--account alice \
--current-password qwe12345 \
--new-password alice12345

샘플 애플리케이션 배포
Alice 계정으로 접속이 가능하도록 암호를 설정해주었으나, 아직 Alice 계정에 대한 권한을 부여하지 않았습니다.
권한을 부여하지 않으면 ArgoCD UI 에서 어떻게 보이는 지 확인해보기 위해 샘플 앱을 하나 배포합니다.
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
이후 Admin 사용자와 Alice 사용자로 각각 UI 에 접속해보겠습니다.


보시는 것과 같이, Alice 사용자는 Application 에 대한 조회권한이 없어 배포된 앱이 보이지 않습니다.
2.4. ArgoCD 일반 계정 RBAC 설정
RBAC
- Argo CD 리소스에 대한 액세스 제한
- Argo CD 에는 자체 사용자 관리 시스템이 없으며 기본 사용자(admin) 하나만 존재
- admin 사용자는 슈퍼유저, 시스템에 대한 무제한 액세스 권한 보유
- SSO 또는 로컬 사용자를 구성한 후에는 추가 RBAC 역할을 정의하고 SSO 그룹 또는 로컬 사용자를 역할에 매핑 가능
RBAC 구성을 정의할 수 있는 두 가지 주요 구성 요소
- 글로벌 RBAC 구성 맵 (argo-rbac-cm.yaml)
- AppProject 의 역할
ArgoCD 기본 내장 역할
- role:readonly : 모든 리소스에 대한 읽기 전용 액세스
- role:admin : 모든 리소스에 대한 무제한 액세스
RBAC 설정
argocd-rbac-cm 컨피그맵을 수정하겠습니다.
모든 사용자에 대해 role:readonly 권한을 부여합니다.
kubectl edit cm -n argocd argocd-rbac-cm
# data 구문에 아래 내용 추가
policy.default: role:readonly

컨피그맵이 적용되자마자 ArgoCD UI 에서 Alice 사용자는 샘플 앱 조회가 가능하게 됩니다.

2.5. Admin 계정 비활성화
ArgoCD 의 일반 사용자가 설정이 되었으므로, 기존에 사용하던 Admin 사용자는 비활성화 하는 것이 좋습니다.
kubectl edit cm -n argocd argocd-cm
# Data 구문 값 변경
admin.enabled: "false"
3. 서비스 어카운트
3.1. ArgoCD 서비스 어카운트 개념
서비스 어카운트
- CI/CD 파이프라인과 같은 자동화를 위해 시스템 인증에 사용하는 계정
- 사용자를 비활성화하거나 권한을 제어하면 파이프라인이 실패할 수 있기 때문에 사용자와 연결 금지
- 엄격하게 권한 제한, 파이프라인에서 수행하는 것 이상의 권한이 있으면 안 됨
서비스 어카운트를 생성 방법 두 가지
1. login 기능은 제거하고 api 키만을 사용하는 로컬 사용자
2. 프로젝트 역할을 사용하고 그 역할에 토큰을 할당
3.2. 서비스 어카운트 계정 생성
서비스 어카운트 실습을 위해 API 키만 활성화된 계정을 생성합니다.
kubectl edit cm -n argocd argocd-cm
# 아래 계정 추가
accounts.gitops-ci: apiKey
gitops-ci 계정의 토큰 발급을 위해 Alice 계정에 토큰 발급 권한 부여
kubectl edit cm -n argocd argocd-rbac-cm
# policy.csv 에 아래 정책 추가
policy.csv: |
p, role:user-update, accounts, update, *, allow
p, role:user-update, accounts, get, *, allow
g, alice, role:user-update

서비스 어카운트 계정 토큰 발급
argocd account generate-token -a gitops-ci
현재는 조회 권한만 있는 토큰이기 때문에, 파이프라인에서 많은 기능을 수행하진 못합니다.
실제로는 적절한 정책을 부여하는 것이 필요합니다.
3.3. 프로젝트 역할
- 애플리케이션 프로젝트는 역할을 통해 애플리케이션 정의에 일부 제약 조건을 적용하는 방식
- 상태를 가져오는 리포지터리, 대상 클러스터나 배포할 수 있는 네임스페이스를 지정할 수 있고, 설치할 수 있는 리소스 유형 필터링 가능
ArgoCD 설치 시 Default 프로젝트가 생성되어 있는데, 이것은 모든 부분에서 허용되어 있습니다.
kubectl get appprojects.argoproj.io -n argocd default -o yaml | k neat | yq

신규 프로젝트 생성
프로젝트 역할 테스트를 위해 신규 프로젝트를 생성합니다.
특정 레포지토리로부터만 상태 파일을 가져오며, test 네임스페이스에만 배포를 할 수 있도록 제한되어 있는 프로젝트 입니다.
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
테스트 애플리케이션 배포
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 sync argocd/pre-post-sync
현재 Alice 사용자에게는 동기화 권한이 없기 때문에, 추가해줍니다.

kubectl edit cm -n argocd argocd-rbac-cm
# 아래 정책 추가
p, role:user-update, projects, update, sample-apps, allow

역할에 대한 토큰 생성
프로젝트에 대해서 토큰이 발급 가능하고, 그것을 통해서 애플리케이션 싱크가 가능합니다.
argocd proj role create-token sample-apps read-sync
# 애플리케이션 무효화
TOKEN=<토큰값 입력>
argocd app sync argocd/pre-post-sync --auth-token $TOKEN

이번 글에서는 ArgoCD 의 접근 제어에 대해서 알아보았습니다.
다음글에서는 ArgoCD SSO 방법에 대해서 작성하겠습니다.