3aa69e5eda
k8s 1.33 에서 Deployment/ReplicaSet 에 추가된 .status.terminatingReplicas 를
ArgoCD v2.14.5(k8s 라이브러리 0.31/0.32)가 몰라, 클러스터가 1.33 이상이면
ServerSideApply=true 인 Application 이 전부 아래 오류로 죽는다.
ComparisonError: failed to calculate diff: error calculating structured
merge diff: .status.terminatingReplicas: field not declared in schema
v3.5.1 은 k8s 라이브러리 0.36.1 을 써서 해소된다. dev 클러스터(1.35.7+rke2r1)
에서 실제 발생·해소를 확인했다.
- manifests/helm/argo-cd/10.4.0/ 추가 (chart_updater 로 생성)
- custom-values.yaml 을 실제 배포 기준(dipup argo-cd-values.yaml.tpl)에 맞춤:
kong → apisix, server.extraArgs(--insecure), configs.cm/rbac 추가
- configs.params.controller.resource.health.persist=true 지정 —
ArgoCD v3.0 부터 리소스 health 를 CR 에 저장하지 않는 것이 기본값인데,
dip-console-api 가 .status.resources[].health 를 읽는다
- CUSTOM-README.md 는 현재 차트 기준 배포 가이드로 재작성.
승계된 cert-manager 예시가 10.4.0 에 없는 구버전 스키마(hosts/tls 리스트)라
Ingress 가 생성되지 않는 상태였던 것도 함께 수정
- breaking_change_check: breaking=false (제거 26건이 전부 미사용 key)
- scripts/deploy-test/deploy-test-argo-cd.sh 신규
같은 클러스터에 두 번째 argo-cd 를 띄우려면 crds.install=false 가 필수다 —
CRD 3종이 클러스터 전역이고 운영 릴리스가 소유해 Helm 이 ownership 충돌로
거부한다. Ingress 도 항상 끈다(운영과 host 충돌).
검증: 워크로드 롤아웃 / health.persist / api 버전 / admin 로그인
- argo-cd/7.8.11/BUILD-README.md 에 `helm repo add argo ...` 추가
chart_version_detector 가 이 한 줄을 정규식으로 뽑아 업스트림 레포를 정하는데,
argo-cd 에는 없어서 신규 버전 자동 감지가 조용히 실패하고 있었다
(repo: null → latest_version: null). CLAUDE.md 의 "변경 금지" 규정도
실제 파싱 계약에 맞게 정정했다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
152 lines
6.2 KiB
Markdown
152 lines
6.2 KiB
Markdown
# ArgoCD 배포 설정 가이드
|
|
|
|
Chart `argo-cd` 10.4.0 (ArgoCD v3.5.1) 기준이다. 값 이름·구조는 이 버전 `values.yaml` 을
|
|
따른다.
|
|
|
|
## Ingress Enable 시 사전 필요사항
|
|
|
|
- 특정 도메인에 대한 TLS 인증서를 사용한 Ingress 배포 시 해당 Namespace 에 tls secret 이
|
|
생성되어 있어야 합니다.
|
|
|
|
```sh
|
|
$ kubectl create secret tls ${TLS_NAME} --cert=tls.crt --key=tls.key -n ${NAMESPACE}
|
|
```
|
|
|
|
- cert-manager 를 사용하여 tls 를 발급할 경우 custom-values.yaml 설정
|
|
|
|
```yaml
|
|
server:
|
|
ingress:
|
|
enabled: true
|
|
annotations:
|
|
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
|
hostname: argocd.example.com
|
|
ingressClassName: nginx
|
|
extraTls:
|
|
- hosts:
|
|
- argocd.example.com
|
|
secretName: ${TLS_NAME}
|
|
```
|
|
|
|
> 이 차트의 ingress 는 `server.ingress.hostname` + `server.ingress.extraTls` 구조다.
|
|
> `ingress.hosts[].paths` / `ingress.tls[]` 리스트를 쓰는 예전 형식은 10.4.0 에 존재하지
|
|
> 않는다 — 그대로 넣으면 조용히 무시되어 Ingress 가 생성되지 않는다.
|
|
|
|
## custom-values.yaml
|
|
|
|
### Global Configs
|
|
|
|
| Key | Type | Default | Description |
|
|
|-----|------|---------|-------------|
|
|
| global.domain | string | `"argocd.example.com"` | ArgoCD 에서 사용할 호스트네임을 지정합니다. `server.ingress.hostname` 미지정 시 이 값이 쓰입니다. |
|
|
|
|
### ArgoCD Server Ingress
|
|
|
|
| Key | Type | Default | Description |
|
|
|-----|------|---------|-------------|
|
|
| server.ingress.enabled | bool | `false` | Ingress 의 사용 여부를 결정합니다. |
|
|
| server.ingress.controller | string | `"generic"` | Ingress 컨트롤러 구현을 지정합니다. `generic` / `aws` / `gke`. |
|
|
| server.ingress.ingressClassName | string | `""` | Ingress 리소스를 구현할 컨트롤러를 정의합니다. |
|
|
| server.ingress.hostname | string | `""` (defaults to global.domain) | ArgoCD 의 호스트네임을 설정합니다. |
|
|
| server.ingress.annotations | object | `{}` | Ingress 의 annotations 를 설정합니다. |
|
|
| server.ingress.labels | object | `{}` | Ingress 에 추가할 Label 을 정의합니다. |
|
|
| server.ingress.path | string | `"/"` | ArgoCD 서버로 향하는 경로입니다. |
|
|
| server.ingress.pathType | string | `"Prefix"` | `Exact` / `Prefix` / `ImplementationSpecific`. |
|
|
| server.ingress.tls | bool | `false` | `hostname` 에 대한 TLS 를 `argocd-server-tls` secret 으로 활성화합니다. |
|
|
| server.ingress.extraTls | list | `[]` | TLS 설정을 직접 지정합니다. 별도 secret 이름을 쓸 때 사용합니다. |
|
|
| server.ingress.extraHosts | list | `[]` | 추가 호스트네임을 지정합니다. |
|
|
|
|
### 이 카탈로그가 기본 지정하는 값
|
|
|
|
| Key | 값 | 이유 |
|
|
|-----|-----|------|
|
|
| configs.params.controller.resource.health.persist | `"true"` | ArgoCD v3.0 부터 리소스 health 를 Application CR 에 저장하지 않는 것이 기본값이다. dip-console-api 가 `.status.resources[].health` 를 읽어 카탈로그 오류 상세를 만들기 때문에, 끄면 해당 화면이 비어서 나온다. |
|
|
|
|
### admin 계정
|
|
|
|
`configs.cm.admin.enabled` 가 `true`(기본) 인 동안 로컬 `admin` 계정으로 로그인할 수 있다.
|
|
비밀번호를 지정하지 않으면 설치 시 무작위 생성되어 `argocd-initial-admin-secret` 에 담긴다.
|
|
|
|
고정 비밀번호로 배포하려면 bcrypt 해시를 넘긴다.
|
|
|
|
```sh
|
|
# bcrypt 해시 생성
|
|
$ htpasswd -nbBC 10 "" ${ARGO_PWD} | tr -d ':\n' | sed 's/$2y/$2a/'
|
|
```
|
|
|
|
```yaml
|
|
configs:
|
|
secret:
|
|
argocdServerAdminPassword: "<bcrypt hash>"
|
|
# 생략 시 설치 시각. 형식 "2006-01-02T15:04:05Z"
|
|
argocdServerAdminPasswordMtime: "2026-01-01T00:00:00Z"
|
|
```
|
|
|
|
- 해시는 **환경별 비밀값이므로 카탈로그의 `custom-values.yaml` 에 커밋하지 않는다.** 배포
|
|
시점에 별도 values 로 주입한다.
|
|
- 고정 비밀번호로 로그인하는 클라이언트(예: dip-console-api 의 `ARGOCD_PASSWORD`)가 있으면
|
|
이 값을 지정해야 한다. 미지정 시 릴리스를 다시 만들 때마다 비밀번호가 바뀐다.
|
|
|
|
### OIDC 연동
|
|
|
|
`configs.cm.url` 과 `configs.cm.oidc.config` 로 설정한다. 사설 CA 를 쓰는 IdP 는
|
|
`oidc.config` 안에 `rootCA` 를 넣는다.
|
|
|
|
```yaml
|
|
configs:
|
|
cm:
|
|
url: https://argocd.example.com
|
|
oidc.config: |
|
|
name: Keycloak
|
|
issuer: https://keycloak.example.com/realms/<realm>
|
|
clientID: argocd
|
|
clientSecret: $oidc.keycloak.clientSecret
|
|
requestedScopes: ["openid", "profile", "email", "groups"]
|
|
rbac:
|
|
policy.csv: |
|
|
g, <group>, role:admin
|
|
```
|
|
|
|
- IdP 클라이언트에 redirect URI `https://<argocd-host>/auth/callback` 이 등록되어 있어야
|
|
한다. 없으면 로그인 콜백이 실패한다.
|
|
- `requestedScopes` 에 `groups` 가 없으면 `policy.csv` 의 그룹 매핑(`g, ...`)이 동작하지
|
|
않는다.
|
|
- `clientSecret` 의 `$` 접두 표기는 `argocd-secret` 의 동명 key 를 참조하는 ArgoCD 문법이다.
|
|
값을 values 파일에 남기지 않으려면 이 형태를 쓰고, `argocd-secret` 에 해당 key 를 넣는다.
|
|
리터럴을 직접 주입해도 동작한다(dipup 의 `argo-cd-values.yaml.tpl` 이 이 방식이다).
|
|
- 사설 CA 를 쓰는 Keycloak 이면 `oidc.config` 안에 `rootCA` 를 함께 넣는다.
|
|
|
|
### TLS 종료를 Ingress 에서 하는 경우
|
|
|
|
Ingress 컨트롤러가 TLS 를 종료하고 백엔드로 평문을 보내면 ArgoCD 서버를 `--insecure` 로
|
|
띄운다. 그렇지 않으면 리다이렉트 루프가 발생한다.
|
|
|
|
```yaml
|
|
server:
|
|
extraArgs:
|
|
- --insecure
|
|
```
|
|
|
|
### APISIX Ingress Controller 사용 시 (카탈로그 기본값)
|
|
|
|
`custom-values.yaml` 이 채택한 구성이다. https 리다이렉트는 apisix 의 plugin-config 로
|
|
처리하므로 사전에 해당 이름의 plugin-config 가 있어야 한다.
|
|
|
|
```yaml
|
|
server:
|
|
extraArgs:
|
|
- --insecure
|
|
ingress:
|
|
enabled: true
|
|
annotations:
|
|
k8s.apisix.apache.org/plugin-config-name: https-redirect
|
|
cert-manager.io/cluster-issuer: "selfsigned-issuer"
|
|
cert-manager.io/duration: 8760h
|
|
cert-manager.io/renew-before: 720h
|
|
hostname: argocd.example.org
|
|
ingressClassName: "apisix"
|
|
extraTls:
|
|
- hosts:
|
|
- argocd.example.org
|
|
secretName: argocd-tls
|
|
``` |