repo-server용 상호 TLS
repo-server용 상호 TLS (Mutual TLS, mTLS)
argocd-server(API 서버), argocd-application-controller, argocd-applicationset-controller와 argocd-repo-server 사이에 상호 TLS(mTLS)를 지원해요. 이렇게 하면 유효한 클라이언트 인증서를 제시하는 인가된 클라이언트만 repo-server가 받아들이게 돼요.
출처: 문서
본문
[!TIP] Argo CD 전 구성 요소에 걸친 일반적인 TLS 설정을 찾고 있다면 TLS 구성을 참고하세요.
[!NOTE] repo-server는 기본적으로 TLS로 gRPC 엔드포인트를 실행해요. mTLS를 활성화하면 서버 측 TLS 위에 클라이언트 인증서 검증이 추가돼요.
퀵스타트 — 기본 공유 인증서(shared-cert) 설정
이 방식이 mTLS를 활성화하는 가장 간단하고 권장되는 방법이에요. 모든 클라이언트 컴포넌트(argocd-server, argocd-application-controller, argocd-applicationset-controller, argocd-notifications-controller)가 단일 클라이언트 인증서와 키를 공유해요. Argo CD는 관련 배포마다 Secret을 자동으로 마운트하므로 수동으로 volume이나 volumeMount를 구성할 필요가 없어요.
1단계 — argocd 네임스페이스에 다음 키를 가진 argocd-repo-server-mtls Secret을 생성하세요:
apiVersion: v1
kind: Secret
metadata:
name: argocd-repo-server-mtls
namespace: argocd
type: Opaque
data:
# CA used by argocd-repo-server to verify incoming client certificates (enables mTLS)
client-ca.crt: <BASE64_CA_PEM>
# Shared client certificate and key presented by all client components
client.crt: <BASE64_CLIENT_CERT_PEM>
client.key: <BASE64_CLIENT_KEY_PEM>
# Optional: CA used by clients to verify the repo-server's own TLS certificate
# server-ca.crt: <BASE64_SERVER_CA_PEM>
이 Secret은 모든 관련 Pod의 /app/config/reposerver/mtls에 자동으로 마운트돼요. 모든 컴포넌트는 기본적으로 해당 마운트 경로에서 자체 cert/key/CA 파일을 읽으므로, Secret만 존재하면 mTLS가 자동으로 활성화돼요 — ConfigMap 변경이나 플래그 오버라이드가 필요 없어요.
Secret을 만든 뒤 영향을 받는 배포를 재시작하거나(또는 rollout을 기다리고) 하세요. 기본 공유 인증서 mTLS 설정에 필요한 것은 이것뿐이에요.
[!NOTE] mTLS가 활성화되면 repo-server는 자체 내부 헬스 체크(활성 검사) 셀프 연결을 위한 임시 클라이언트 인증서를 자동으로 생성해요. readiness/liveness 프로브를 바꿀 필요는 없어요. 시작 시 다음 같은 로그 줄이 보일 거예요:
Generated ephemeral health-check client certificate (CN=<value>)
참조 (Reference)
아래 섹션은 사용 가능한 모든 ConfigMap 키, 환경 변수, 고급 구성 옵션을 문서화해요.
repo-server에서 mTLS 활성화
argocd-repo-server에서 mTLS를 활성화하려면 클라이언트 CA 인증서를 제공하세요. 구성되면 repo-server는 모든 클라이언트가 이 CA가 서명한 인증서를 제시하도록 요구해요.
환경 변수 (Environment variables)
ARGOCD_REPO_SERVER_CLIENT_CA_PATH:--client-ca-path와 동일. 기본값은/app/config/reposerver/mtls/client-ca.crt.ARGOCD_REPO_SERVER_DISABLE_TLS:--disable-tls와 동일.
서버 인증서 위치 (repo-server)
repo-server의 서버 인증서와 키는 다음에서 읽어요:
/app/config/reposerver/tls/tls.crt/app/config/reposerver/tls/tls.key
클라이언트 구성 (Configuring clients)
argocd-server, argocd-application-controller, argocd-applicationset-controller는 mTLS가 활성화된 repo-server에 연결하려면 클라이언트 인증서와 키로 구성되어야 해요. 인증서는 repo-server에 구성된 것과 같은 CA가 서명해야 해요.
[!NOTE] TLS 인증서 검증의 기존 방식(legacy path) vs 권장 방식
--repo-server-strict-tls(알림 컨트롤러는--argocd-repo-server-strict-tls)는 기존 방식(legacy path) 이에요. 설정하면 컴포넌트가argocd-repo-server-tlsKubernetes secret에서 repo-server 인증서를 자동으로 발견해요. 이 플래그는 deprecated이며 향후 릴리스에서 제거될 수 있어요.
--repo-server-ca-cert-path(알림 컨트롤러는--argocd-repo-server-ca-cert-path)가 권장되는 명시적 방식이에요. CA 인증서 파일 경로를 직접 제공해요. mTLS 구성에 필요하며 신뢰할 CA를 완전히 제어할 수 있어요. 모든 새 배포에는--repo-server-ca-cert-path를 사용하세요.
argocd-cmd-params-cm ConfigMap 키
이 환경 변수들은 argocd-cmd-params-cm ConfigMap으로도 설정할 수 있는데, 이게 Kubernetes 배포에서 권장되는 방식이에요:
argocd-repo-server
reposerver.client.ca.path— 클라이언트 CA 인증서 파일 경로. 기본값/app/config/reposerver/mtls/client-ca.crt. 파일이 존재하면 repo-server는 모든 gRPC 클라이언트가 이 CA가 서명한 인증서를 제시하도록 요구해요. 파일이 없으면 mTLS는 조용히 건너뛰어져요.
argocd-server
server.repo.server.ca.cert.path— repo 서버의 TLS 인증서를 검증하기 위한 CA 인증서 경로server.repo.server.client.cert.path— mTLS용 클라이언트 인증서 경로. 기본값/app/config/reposerver/mtls/client.crtserver.repo.server.client.cert.key.path— mTLS용 클라이언트 인증서 키 경로. 기본값/app/config/reposerver/mtls/client.key
argocd-application-controller
controller.repo.server.ca.cert.path— repo 서버의 TLS 인증서를 검증하기 위한 CA 인증서 경로controller.repo.server.client.cert.path— mTLS용 클라이언트 인증서 경로. 기본값/app/config/reposerver/mtls/client.crtcontroller.repo.server.client.cert.key.path— mTLS용 클라이언트 인증서 키 경로. 기본값/app/config/reposerver/mtls/client.key
argocd-applicationset-controller
applicationsetcontroller.repo.server.ca.cert.path— repo 서버의 TLS 인증서를 검증하기 위한 CA 인증서 경로applicationsetcontroller.repo.server.client.cert.path— mTLS용 클라이언트 인증서 경로. 기본값/app/config/reposerver/mtls/client.crtapplicationsetcontroller.repo.server.client.cert.key.path— mTLS용 클라이언트 인증서 키 경로. 기본값/app/config/reposerver/mtls/client.key
argocd-notifications-controller
notificationscontroller.repo.server.ca.cert.path— repo 서버의 TLS 인증서를 검증하기 위한 CA 인증서 경로notificationscontroller.repo.server.client.cert.path— mTLS용 클라이언트 인증서 경로. 기본값/app/config/reposerver/mtls/client.crtnotificationscontroller.repo.server.client.cert.key.path— mTLS용 클라이언트 인증서 키 경로. 기본값/app/config/reposerver/mtls/client.key
공유 vs 컴포넌트별 클라이언트 인증서 (Shared vs. per-component client certificates)
기본적으로 argocd-repo-server-mtls Secret은 모든 클라이언트 컴포넌트(argocd-server, argocd-application-controller, argocd-applicationset-controller, argocd-notifications-controller)에 마운트되는 하나의 공유 키/인증서 쌍(client.crt / client.key)을 사용해요. 따라서 모든 컴포넌트는 repo-server에 동일한 클라이언트 인증서를 제시해요.
이 정도면 대부분의 배포에 충분해요. repo-server가 어떤 컴포넌트가 연결하는지 구분해야 한다면(예: 컴포넌트별 인가 정책 적용), 컴포넌트마다 별도 인증서를 발급하고 각 배포가 자체 인증서를 쓰도록 구성해야 해요.
[!NOTE] repo-server는 클라이언트 인증서가 구성된 클라이언트 CA에 의해 서명되었는지만 검증해요. 기본적으로 컴포넌트별 신원은 강제하지 않아요. 컴포넌트별 인증서는 mTLS 위에 자체 인가 로직을 추가할 때만 의미가 있어요.
옵션 A — 한 Secret에 여러 키 (Option A — Multiple keys in one Secret)
모든 컴포넌트 인증서를 단일 argocd-repo-server-mtls Secret의 서로 다른 키 이름 아래 두고, 각 배포에서 volume items 투영을 커스터마이즈해 관련 인증서만 노출하세요.
1. 컴포넌트별 키로 Secret을 생성하세요:
apiVersion: v1
kind: Secret
metadata:
name: argocd-repo-server-mtls
namespace: argocd
type: Opaque
data:
client-ca.crt: <BASE64_CA_PEM>
# argocd-server client cert
server-client.crt: <BASE64_SERVER_CLIENT_CERT_PEM>
server-client.key: <BASE64_SERVER_CLIENT_KEY_PEM>
# argocd-application-controller client cert
controller-client.crt: <BASE64_CONTROLLER_CLIENT_CERT_PEM>
controller-client.key: <BASE64_CONTROLLER_CLIENT_KEY_PEM>
# argocd-applicationset-controller client cert
appsetcontroller-client.crt: <BASE64_APPSET_CLIENT_CERT_PEM>
appsetcontroller-client.key: <BASE64_APPSET_CLIENT_KEY_PEM>
# argocd-notifications-controller client cert
notifications-client.crt: <BASE64_NOTIFICATIONS_CLIENT_CERT_PEM>
notifications-client.key: <BASE64_NOTIFICATIONS_CLIENT_KEY_PEM>
2. 각 배포의 volume을 패치해 관련 키만 client.crt / client.key로 투영하세요:
# Example patch for argocd-server deployment
volumes:
- name: argocd-repo-server-mtls
secret:
secretName: argocd-repo-server-mtls
items:
- key: server-client.crt
path: client.crt
- key: server-client.key
path: client.key
- key: client-ca.crt
path: client-ca.crt
각 컴포넌트 배포에 적절한 키 이름으로 반복하세요. 마운트 경로와 ConfigMap 키는 그대로 두고, Secret items 투영만 배포마다 달라져요.
옵션 B — 컴포넌트당 Secret 하나 (Option B — One Secret per component)
각 컴포넌트에 별도 Secret을 생성하세요. 각 Secret은 argocd-repo-server-mtls와 같은 형식이지만 해당 컴포넌트의 인증서만 담아요.
1. 컴포넌트별 Secret을 생성하세요:
# argocd-server
apiVersion: v1
kind: Secret
metadata:
name: argocd-repo-server-mtls-server
namespace: argocd
type: Opaque
data:
client.crt: <BASE64_SERVER_CLIENT_CERT_PEM>
client.key: <BASE64_SERVER_CLIENT_KEY_PEM>
---
# argocd-application-controller
apiVersion: v1
kind: Secret
metadata:
name: argocd-repo-server-mtls-controller
namespace: argocd
type: Opaque
data:
client.crt: <BASE64_CONTROLLER_CLIENT_CERT_PEM>
client.key: <BASE64_CONTROLLER_CLIENT_KEY_PEM>
# ... repeat for argocd-applicationset-controller and argocd-notifications-controller
2. 각 배포에 자체 Secret을 가리키는 별도 volume과 volumeMount를 추가하세요:
# Example patch for argocd-server deployment
volumes:
- name: argocd-repo-server-mtls-server
secret:
secretName: argocd-repo-server-mtls-server
volumeMounts:
- name: argocd-repo-server-mtls-server
mountPath: /app/config/reposerver/mtls
readOnly: true
각 컴포넌트 배포에 적절한 Secret 이름으로 반복하세요. 마운트 경로와 ConfigMap 키는 그대로예요.
[!IMPORTANT] 옵션 B에서는 패치된 각 배포에서 Argo CD가 자동 마운트하는 기본
argocd-repo-server-mtlsvolume을 제거하거나 오버라이드해야 해요. 그렇지 않으면 두 volume이 같은 마운트 경로를 두고 경쟁하게 돼요.
서버 측 컴포넌트별 강제 없음 (No per-component enforcement on the server side)
위의 옵션 A나 B로 컴포넌트별 클라이언트 인증서를 구성해도, repo-server는 인증서를 구분하지 않아요. 이것은 서버 측 TLS 검증이 작동하는 방식의 근본적 특성이며, 운영자는 컴포넌트별 인증서 발급에 투자하기 전에 알아야 해요.
repo-server는 단일 CA 인증서 파일을 가리키는 단일 --client-ca-path 플래그로 구성돼요. 내부적으로 repository 서버는 그 파일을 단일 x509.CertPool로 로드해요. 클라이언트가 연결하면 TLS 레이어가 한 가지 질문만 해요: "이 인증서가 구성된 CA에 의해 서명됐나?" 맞으면 연결이 수락되고, 아니면 거부돼요.
특정 컴포넌트 신원과 특정 인증서 사이의 바인딩은 없어요. 서버는 인증서의 Subject, SAN 또는 다른 필드를 검사해 어떤 컴포넌트가 연결하는지 판단하지 않아요. 신뢰할 CA가 서명한 인증서를 가진 클라이언트는 argocd-server, argocd-application-controller이든, 유효한 인증서에 접근할 수 있는 다른 프로세스든 — 무엇이든 통과해요.
모든 클라이언트 인증서는 repo-server가 신뢰하는 CA가 서명해야 해요. --client-ca-path 플래그는 하나 이상의 CA 인증서를 포함한 PEM 파일을 받아요. 서로 다른 CA에서 컴포넌트별 인증서를 발급한다면, 그 CA들을 단일 번들 파일로 연결(concatenate)해 그 번들을 --client-ca-path에 넘겨주세요. 서버는 번들의 어떤 CA가 서명한 인증서든 신뢰하지만, 여전히 어떤 컴포넌트가 연결하는지는 구분하지 못해요.
[!NOTE] 컴포넌트별 인증서는 mTLS 위에 자체 인가 로직을 구현할 때만 의미가 있어요 — 예를 들어 피어 인증서의 Subject/SAN을 검사해 컴포넌트 수준 접근 정책을 시행하는 Envoy sidecar나 커스텀 gRPC 인터셉터. 기본 제공 상태의 Argo CD mTLS는 인증(인증서를 가진 클라이언트만 연결 가능)을 제공하지만 인가(인증된 클라이언트 아무나 어떤 RPC든 호출 가능)는 제공하지 않아요.
mTLS 활성 확인 (Verifying mTLS is active)
배포 후:
--client-ca-path가 설정되면 repo-server 로그에서 헬스 체크 인증서 메시지를 확인하세요:Generated ephemeral health-check client certificate (CN=...)- 클라이언트 인증서가 없는 pod에서 연결을 시도해 보세요 — 클라이언트 인증 부재로 TLS 오류가 나며 실패해야 해요.
argocd-server/argocd-application-controller/argocd-applicationset-controller에서의 연결은 일치하는 클라이언트 cert/key로 구성되면 성공해야 해요.
문제 해결 (Troubleshooting)
- 오류:
--client-ca-path cannot be used when --disable-tls is enabled- mTLS를 활성화할 때
--disable-tls를 제거하세요(또는ARGOCD_REPO_SERVER_DISABLE_TLSunset).
- mTLS를 활성화할 때
--repo-server-client-cert-path/--repo-server-client-cert-key-path중 하나 누락- 두 플래그(또는 해당 환경 변수)를 함께 제공하세요.
- repo-server 서버 인증서용 커스텀 CA
- 클라이언트에
--repo-server-ca-cert-path를 제공해 repo-server의 서버 인증서를 검증하게 하세요.
- 클라이언트에
더 알아보기 (Learn more)
- TLS 구성 — Argo CD 전반의 일반 TLS 설정.
- 문서: Mutual TLS (mTLS) for repo-server