다른 네임스페이스의 ApplicationSet
다른 네임스페이스의 ApplicationSet (ApplicationSet in any namespace)
Argo CD 2.8부터 컨트롤 플레인 네임스페이스(보통 argocd)가 아닌 다른 네임스페이스의 ApplicationSet 리소스를 관리할 수 있어요. 이 기능은 명시적으로 활성화하고 적절히 구성해야 해요. 잘못 구성하면 보안 문제가 발생할 수 있으니 이 문서를 주의 깊게 읽고 활성화하세요. ApplicationSet이 생성하는 Application은 ApplicationSet 자신과 같은 네임스페이스에 생성되므로, App in any namespace와 함께 동작해요.
출처: 문서
본문
경고 — 이 기능을 활성화하기 전에 이 문서를 주의 깊게 읽으세요. 잘못된 구성은 잠재적인 보안 문제로 이어질 수 있어요.
소개 (Introduction)
Argo CD 2.8부터 컨트롤 플레인의 네임스페이스(보통 argocd)가 아닌 다른 네임스페이스의 ApplicationSet 리소스 관리를 지원하지만, 이 기능은 명시적으로 활성화하고 적절히 구성해야 해요.
Argo CD 관리자는 ApplicationSet 리소스가 생성·업데이트·재조정될 수 있는 특정 네임스페이스 집합을 정의할 수 있어요.
ApplicationSet이 생성한 Application은 ApplicationSet 자신과 같은 네임스페이스에 생성되므로, 이 기능은 App in any namespace와 함께 동작해요.
전제 조건 (Prerequisites)
App in any namespace 구성
이 기능은 App in any namespace 기능이 활성화되어야 해요. 네임스페이스 목록은 같아야 해요.
클러스터 범위 Argo CD 설치 (Cluster-scoped Argo CD installation)
이 기능은 Argo CD ApplicationSet 컨트롤러가 클러스터 전체(cluster-wide) 인스턴스로 설치되어 커널 스코프에서 리소스를 나열·조작할 권한이 있을 때만 활성화·사용할 수 있어요. 네임스페이스 스코프 모드로 설치된 Argo CD에서는 동작하지 않아요.
SCM Providers 시크릿 고려 (SCM Providers secrets consideration)
어떤 네임스페이스의 ApplicationSet을 허용하면 scmProvider나 pullRequest generator를 사용해 어떤 시크릿이든 유출(exfiltrate)될 수 있다는 점을 알아야 해요. 즉 ApplicationSet 컨트롤러가 네임스페이스 appNs를 허용하고 어떤 사용자가 appNs 네임스페이스에 ApplicationSet을 만들 수 있다면, 그 사용자는 아래 설명처럼 appNs 네임스페이스에 악의적인 Pod를 설치해 시크릿 내용을 간접적으로 읽어낼 수 있고, 따라서 시크릿 값을 유출할 수 있어요.
예시:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: myapps
namespace: appNs
spec:
goTemplate: true
goTemplateOptions: ["missingkey=error"]
generators:
- scmProvider:
gitea:
# The Gitea owner to scan.
owner: myorg
# With this malicious setting, user can send all request to a Pod that will log incoming requests including headers with tokens
api: http://my-service.appNs.svc.cluster.local
# If true, scan every branch of every repository. If false, scan only the default branch. Defaults to false.
allBranches: true
# By changing this token reference, user can exfiltrate any secrets
tokenRef:
secretName: gitea-token
key: token
template:
위 시나리오를 막으려면 관리자는 환경 변수 ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS를 argocd-cmd-params-cm applicationsetcontroller.allowed.scm.providers로 설정해 허용된 SCM Provider의 URL을 제한해야 해요(예: https://git.mydomain.com/,https://gitlab.mydomain.com/). 다른 URL을 사용하면 applicationset 컨트롤러가 거부해요.
예를 들어:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cmd-params-cm
data:
applicationsetcontroller.allowed.scm.providers: https://git.mydomain.com/,https://gitlab.mydomain.com/
참고 — ApplicationSet의 api 필드에서 사용하는 URL은 관리자가 프로토콜을 포함해 선언한 URL과 일치해야 해요.
경고 — allow-list는 사용자가 커스텀 api를 구성할 수 있는 SCM provider에만 적용돼요. SCM 또는 PR generator가 커스텀 API URL을 받지 않는 경우, 그 provider는 묵시적으로 허용돼요.
사용자가 SCM 또는 PR generator를 사용하도록 허용하지 않으려면 환경 변수 ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS를 argocd-cmd-params-cm applicationsetcontroller.enable.scm.providers로 false 설정해 그것들을 완전히 비활성화할 수 있어요.
tokenRef 제한 (Restrictions)
시크릿 유출을 피하려면 SCM Providers 시크릿 제한을 활성화하는 것을 적극 권장해요. 이 권장 사항은 AppSets-in-any-namespace가 비활성화된 경우에도 적용되지만, 비-Argo 관리자가 argocd 네임스페이스의 범위 밖 시크릿을 AppSet tokenRef로 참조하려 할 수 있으므로 특히 활성화되었을 때 중요해요.
이 모드가 활성화되면 참조되는 시크릿은 값이 scm-creds인 argocd.argoproj.io/secret-type 라벨을 가져야 해요.
이 모드를 활성화하려면 argocd-application-controller 배포에서 ARGOCD_APPLICATIONSET_CONTROLLER_TOKENREF_STRICT_MODE 환경 변수를 true로 설정하세요. argocd-cmd-paramscm ConfigMap에 다음을 추가하면 됩니다.
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cmd-params-cm
data:
applicationsetcontroller.enable.tokenref.strict.mode: "true"
개요 (Overview)
ApplicationSet이 Argo CD의 컨트롤 플레인 네임스페이스 밖에서 관리·재조정되려면 두 가지 전제 조건이 일치해야 해요.
argocd-applicationset-controller가ApplicationSets를 가져올 수 있는 네임스페이스 목록이 환경 변수ARGOCD_APPLICATIONSET_CONTROLLER_NAMESPACES또는 파라미터--applicationset-namespaces로 명시적으로 설정되어야 해요.- 활성화된 네임스페이스는 App in any namespace로 완전히 덮여야 해요. 그렇지 않으면 허용된 Application 네임스페이스 밖에서 생성된 Application은 재조정되지 않아요.
이는 환경 변수 ARGOCD_APPLICATIONSET_CONTROLLER_NAMESPACES를 argocd-cmd-params-cm applicationsetcontroller.namespaces로 설정해 달성할 수 있어요.
다른 네임스페이스의 ApplicationSets는 이전에 argocd 네임스페이스의 다른 ApplicationSet처럼 선언적으로 또는 Argo CD API(CLI, 웹 UI, REST API 등)를 통해 생성·관리할 수 있어요.
특정 네임스페이스 허용하도록 Argo CD 재구성 (Reconfigure Argo CD to allow certain namespaces)
워크로드 시작 파라미터 변경 (Change workload startup parameters)
이 기능을 활성화하려면 Argo CD 관리자가 argocd-applicationset-controller 워크로드를 재구성해 컨테이너 시작 명령에 --applicationset-namespaces 파라미터를 추가해야 해요.
--applicationset-namespaces 파라미터는 ApplicationSet을 허용할 네임스페이스의 쉼표 구분 목록을 받아요. 목록의 각 항목은 다음을 지원해요.
- shell 스타일 와일드카드(예:
*). 예를 들어app-team-*항목은app-team-one과app-team-two를 매칭해요. Argo CD가 실행 중인 클러스터의 모든 네임스페이스를 활성화하려면 그냥*, 즉--application-namespaces=*를 지정하면 돼요. - 정규식. 문자열을
/로 감싸야 해요. 예를 들어 특정 네임스페이스를 제외한 모든 네임스페이스를 허용하려면:/^((?!not-allowed).)*$/.
argocd-applicationset-controller의 시작 파라미터는 ApplicationSet의 매니페스트를 바꾸는 대신 argocd-cmd-params-cm ConfigMap에 applicationsetcontroller.namespaces 설정을 지정해 편리하게 설정·동기화할 수 있어요. 예를 들어:
data:
applicationsetcontroller.namespaces: "app-team-one, app-team-two"
이렇게 하면 app-team-one과 app-team-two 네임스페이스에서 ApplicationSet 리소스를 관리할 수 있게 해요. argocd-cmd-params-cm 네임스페이스 변경 후에는 ApplicationSet 워크로드를 재시작해야 해요.
kubectl rollout restart -n argocd deployment argocd-applicationset-controller
project 안전하게 템플릿화 (Safely template project)
App in any namespace가 전제 조건이므로 project를 안전하게 템플릿화할 수 있어요.
두 팀과 infra project가 있는 예시를 들어볼게요.
kind: AppProject
apiVersion: argoproj.io/v1alpha1
metadata:
name: infra-project
namespace: argocd
spec:
destinations:
- namespace: '*'
kind: AppProject
apiVersion: argoproj.io/v1alpha1
metadata:
name: team-one-project
namespace: argocd
spec:
sourceNamespaces:
- team-one-cd
kind: AppProject
apiVersion: argoproj.io/v1alpha1
metadata:
name: team-two-project
namespace: argocd
spec:
sourceNamespaces:
- team-two-cd
다음 ApplicationSet을 만들면 infra-escalation과 team-two-escalation 두 Application이 생성돼요. 둘 다 argocd 네임스페이스 밖에 있으므로 거부되며, 이때 sourceNamespaces가 검사돼요.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: team-one-product-one
namespace: team-one-cd
spec:
goTemplate: true
goTemplateOptions: ["missingkey=error"]
generators:
list:
- name: infra
project: infra-project
- name: team-two
project: team-two-project
template:
metadata:
name: '{{.name}}-escalation'
spec:
project: "{{.project}}"
ApplicationSet 이름 (ApplicationSet names)
CLI에서 applicationSet은 이제 <namespace>/<name> 형식으로 참조·표시돼요.
하위 호환을 위해 ApplicationSet의 네임스페이스가 컨트롤 플레인 네임스페이스(즉 argocd)이면 applicationSet 이름에서 <namespace>를 생략할 수 있어요. 예를 들어 애플리케이션 이름 argocd/someappset과 someappset은 의미상 같으며 CLI와 UI에서 같은 애플리케이션을 가리켜요.
Applicationsets RBAC
Application 객체에 대한 RBAC 문법이 <project>/<applicationset>에서 <project>/<namespace>/<applicationset>로 바뀌었어요. 이는 관리할 Application의 소스 네임스페이스에 기반해 접근을 제한해야 할 필요를 수용하기 위해서예요.
하위 호환을 위해 argocd 네임스페이스의 Application은 RBAC 정책 규칙에서 여전히 <project>/<applicationset>로 참조돼요.
참고 — 하위 호환 때문에 foo/argocd/* 패턴으로 Argo CD 컨트롤 플레인 네임스페이스(일반적으로 argocd)의 애플리케이션에 대한 RBAC 정책을 구체적으로 정의할 수 없어요. 컨트롤 플레인 네임스페이스의 애플리케이션은 RBAC 강제에서 항상 2-세그먼트 형식 <project>/<application>으로 정규화돼요. 보안상 AppProject는 .spec.sourceNamespaces 필드를 통해 컨트롤 플레인 네임스페이스에 접근을 부여해서는 안 돼요. 이렇게 하면 사용자가 승격된 권한으로 애플리케이션을 만들 수 있게 되기 때문이에요.
와일드카드는 아직 project와 applicationset 네임스페이스 사이를 구분하지 않아요. 예를 들어 다음 RBAC 규칙은 생성된 네임스페이스에 관계없이 project foo에 속한 어떤 애플리케이션이든 매칭해요.
p, somerole, applicationsets, get, foo/*, allow
접근을 project foo가 있는 bar 네임스페이스 내의 ApplicationSets에만 부여하고 싶다면 규칙을 다음과 같이 조정해야 해요.
p, somerole, applicationsets, get, foo/bar/*, allow
다른 네임스페이스의 applicationSets 관리 (Managing applicationSets in other namespaces)
CLI 사용 (Using the CLI)
컨트롤 플레인 네임스페이스의 ApplicationSet을 CLI로 관리하는 것과 똑같이, 기존 Argo CD CLI 명령을 모두 사용해 다른 네임스페이스의 ApplicationSet을 관리할 수 있어요.
예를 들어 bar 네임스페이스의 foo라는 ApplicationSet을 가져오려면 다음 CLI 명령을 사용할 수 있어요.
argocd appset get foo/bar
마찬가지로 이 applicationSet을 관리할 때는 계속 foo/bar로 참조하세요.
# Delete the application
argocd appset delete foo/bar
create 명령은 파일을 사용하므로 변경이 없어요. metadata.namespace 필드에 네임스페이스를 추가하기만 하면 돼요.
앞서 말했듯이 Argo CD의 컨트롤 플레인 네임스페이스의 applicationSet은 애플리케이션 이름에서 네임스페이스를 생략할 수 있어요.
REST API 사용 (Using the REST API)
REST API를 사용한다면 ApplicationSet의 네임스페이스를 애플리케이션 이름으로 지정할 수 없고, 리소스를 선택적 appNamespace 쿼리 파라미터로 지정해야 해요. 예를 들어 bar 네임스페이스의 foo라는 ApplicationSet 리소스를 다루려면 요청이 다음과 같아요.
GET /api/v1/applicationsets/foo?appsetNamespace=bar
POST와 PUT 같은 다른 작업의 경우 appNamespace 파라미터가 요청의 페이로드에 포함되어야 해요.
컨트롤 플레인 네임스페이스의 ApplicationSet 리소스에 대해서는 이 파라미터를 생략할 수 있어요.
클러스터 시크릿 고려 (Clusters secrets consideration)
어떤 네임스페이스의 ApplicationSet을 허용하면 클러스터를 발견하고 사용할 수 있다는 점을 알아야 해요.
예시:
다음은 모든 클러스터를 발견해요.
spec:
generators:
- clusters: {} # Automatically use all clusters defined within Argo CD
사용자가 다른 네임스페이스의 ApplicationSet로 모든 클러스터를 발견하지 못하게 하려면 ArgoCD를 네임스페이스 스코프로 배포하거나 OPA 규칙 사용을 고려할 수 있어요.
더 알아보기 (Learn more)
- App in any namespace — 다른 네임스페이스의 Application 관리.
- SCM Provider generator — 시크릿 유출 위험 관련.