ArgoCD
Kubernetes 모의해킹 자료 정리하다가 알게된 ArgoCD.
DevOps 환경에서 반드시 사용될 것으로 생각되어 사용해보기로 함. 너무 편해보여서 나도 써야겠음.
설치
버전이 자주 오르는 것 같다. 버전이 오를 때마다 아래 설치 작업을 해주면 업그레이드가 진행됨. 단, 업데이트 후 이전 버전 서버가 함께 유지될 수 있으니 Pod 확인 필수.
1.1. ArgoCD 설치 (Control Plane)
1
2
ubuntu@cplane:~$ kubectl create namespace argocd
ubuntu@cplane:~$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
1.2. ArgoCD CLI 설치 (Control Plane)
1
2
3
ubuntu@cplane:~$ curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
ubuntu@cplane:~$ sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
ubuntu@cplane:~$ rm ./argocd-linux-amd64
1.3. 초기 비밀번호 확인
이후에 관리자가 비밀번호를 변경하더라도 이 값은 바뀌지 않음.
1
2
ubuntu@cplane:~$ kubectl get secret -n argocd argocd-initial-admin-secret -o jsonpath={.data.password} | base64 -d
# <Password 표시됨>
1.4. 접속 테스트
브라우저로 접속 후 위에서 확인한 비밀번호로 로그인.
1
ubuntu@cplane:~$ kubectl port-forward --address=0.0.0.0 svc/argocd-server -n argocd 8080:443
ArgoCD 서비스 확인
argocd-server 서비스를 외부 인터넷에서 접속할 수 있도록 할 예정
1
2
3
4
5
6
7
8
9
10
ubuntu@cplane:~$ kubectl get svc -n argocd
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
argocd-applicationset-controller ClusterIP 10.99.168.87 <none> 7000/TCP,8080/TCP 23h
argocd-dex-server ClusterIP 10.103.239.103 <none> 5556/TCP,5557/TCP,5558/TCP 23h
argocd-metrics ClusterIP 10.108.60.54 <none> 8082/TCP 23h
argocd-notifications-controller-metrics ClusterIP 10.102.164.141 <none> 9001/TCP 23h
argocd-redis ClusterIP 10.97.50.179 <none> 6379/TCP 23h
argocd-repo-server ClusterIP 10.110.146.193 <none> 8081/TCP,8084/TCP 23h
argocd-server ClusterIP 10.110.181.12 <none> 80/TCP,443/TCP 23h
argocd-server-metrics ClusterIP 10.106.46.163 <none> 8083/TCP 23h
Ingress 설정
이거때문에 너무 고생을 했다. EKS를 사용하지 않고, EC2에 직접 Kubernetes를 설치하였기 때문에, 사용한 Ingress에 따라 라우팅 설정을 해보겠다. 사용한 Ingress는 Ingress-Nginx 와 Istio 임.
2.1. ALB 생성 (ingress-nginx, istio 공통)
- 이름
- DOMAIN-ALB
- 네트워크 매핑
- ap-northeast-2a (Public AZ 선택)
- ap-northeast-2c (Public AZ 선택)
- 보안그룹
- Inbound 80, 443, 6443
- 리스너 및 라우팅
- HTTP:80 / redirect
- HTTPS:443 / DOMAIN-INGRESS(ingress-nginx) 또는 DOMAIN-GATEWAY(istio)
- HTTSP:6443 / K8S-API
- 보안 리스너 설정
- 인증서 설정
2.2. Ingress-Nginx 설정
Route53(domain.com) > ALB > Ingress > Argo Service 로 라우팅을 잡을 것이다.
2.2.1. 대상그룹 생성
기본구성
- 인스턴스
- 대상그룹이름
- DOMAIN-INGRESS
- 프로토콜 : 포트
- HTTPS : 30851
1 2 3 4
ubuntu@cplane:~$ kubectl get svc -n ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller NodePort 10.105.213.161 <none> 80:31983/TCP,443:30851/TCP 6h23m ingress-nginx-controller-admission ClusterIP 10.99.246.21 <none> 443/TCP 6h23m
- HTTPS : 30851
- 상태 검사 프로토콜
- HTTPS , /healthz
- 사용 가능한 인스턴스
- worker node 선택
2.2.2. YAML 설정
여러 annotations를 조합하여 설정해보았는데, 공식문서에서 가이드 하는대로 하는게 제일 좋더라..
리다이렉트 문제로 좀 고생을 했는데, 바로 이어서 설명.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ubuntu@cplane:~$ cat ./argocd-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-ingress
namespace: argocd
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
ingressClassName: nginx
rules:
- host: argocd.domain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
name: https
그리고 반영.
1
2
3
4
5
6
ubuntu@cplane:~$ kubectl apply -f ./argocd-ingress.yaml
ingress.networking.k8s.io/argocd-server-ingress created
ubuntu@cplane:~$ kubectl get ingress -n argocd
NAME CLASS HOSTS ADDRESS PORTS AGE
argocd-server-ingress nginx argocd.hack8s.com 172.31.82.157 80 5h15m
# ADDRESS 는 즉시 반영되지 않고, 조금 기다리면 할당됨
이대로 argocd-server-ingress를 타고 잘 들어오면 너무 좋았겠지만, https 리다이렉트가 기본 설정이라는 이유로, 계속 리다이렉트가 발생하는 현상이 나타났다.
1
2
ubuntu@cplane:~$ curl -k -L https://argocd.domain.com
curl: (47) Maximum (50) redirects followed
노력끝에, 해결방법을 찾았고, 다음과 같이 ArgoCD의 configmap 설정을 변경하면 리다이렉트가 발생하지 않았음.
HTTP로 요청이 들어와도, HTTPS로 리다이렉트 하지 않는 설정. 의아한건, ssl-passthrough로 HTTPS로 들어오고 있다는 생각.. 뭐가 맞는진 잘 모르겠음.
1
2
3
4
5
6
7
8
ubuntu@cplane:~$ kubectl edit configmap argocd-cmd-params-cm -n argocd
apiVersion: v1
data: # 추가
server.insecure: "true" # 추가
kind: ConfigMap
ubuntu@cplane:~$ kubectl rollout restart deploy argocd-server -n argocd # ArgoCD 서버 재시작
ubuntu@cplane:~$ curl -k -L https://argocd.domain.com/healthz
ok
2.3. Istio 설정
ALB(HTTPS) > Gateway(HTTP) > VirtualService > Service > Deployment 로 라우팅.
2.3.1. 대상그룹 생성
기본구성
- 인스턴스
- 대상그룹이름
- DOMAIN-ISTIO
- 프로토콜 : 포트
- HTTP : 32357
1 2 3 4 5
ubuntu@cplane:~$ kubectl get svc -n istio-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-egressgateway ClusterIP 10.109.72.139 <none> 80/TCP,443/TCP 31h istio-ingressgateway NodePort 10.106.133.107 <none> 15021:32316/TCP,80:32357/TCP,443:30179/TCP,31400:30804/TCP,15443:31683/TCP 31h istiod ClusterIP 10.105.251.55 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 31h
- HTTP : 32357
- 상태 검사 프로토콜
- HTTP ,/healthz/ready, port : 32316 (15021 포트가 status 확인하는 포트임)
- 사용 가능한 인스턴스
- worker node 선택
2.3.2. Gateway 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ubuntu@cplane:~$ cat argocd-gateway.yaml
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
annotations:
name: argocd-gateway
namespace: argocd
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- argocd.domain.com
port:
name: http
number: 80
protocol: HTTP
ubuntu@cplane:~$ k apply -f ./argocd-gateway.yaml
2.3.3. VirtualService 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ubuntu@cplane:~$ cat argocd-virtualservice.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
name: argocd-virtualservice
namespace: argocd
spec:
gateways:
- argocd/argocd-gateway
hosts:
- argocd.domain.com
http:
- route:
- destination:
host: argocd-server.argocd.svc.cluster.local
port:
number: 80
ubuntu@cplane:~$ k apply -f ./argocd-virtualservice.yaml
ArgoCD 테스트
3.1. 로그인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ubuntu@cplane:~$ export ARGOCD_SERVER=argocd.domain.com
ubuntu@cplane:~$ argocd version --grpc-web
argocd: v2.9.6+ba62a0a
BuildDate: 2024-02-02T19:36:48Z
GitCommit: ba62a0a86d19f71a65ec2b510a39ea55497e1580
GitTreeState: clean
GoVersion: go1.21.6
Compiler: gc
Platform: linux/amd64
argocd-server: v2.9.3+6eba5be
ubuntu@cplane:~$ argocd login argocd.domain.com --grpc-web
Username: admin
Password:
'admin:login' logged in successfully
Context 'argocd.domain.com' updated # 앞서 로그인 한 적 있음.
ArgoCD 사용자 추가
4.1. 사용자 추가
사용자 목록 확인
1
2
3
ubuntu@cplane:~$ argocd account list
NAME ENABLED CAPABILITIES
admin true login
사용자 추가
1
2
3
4
5
6
ubuntu@cplane:~$ kubectl edit configmap argocd-cm -n argocd
apiVersion: v1
data:
accounts.<new user account name>: apiKey,login
kind: ConfigMap
...
다시 사용자 목록 확인
1
2
3
4
ubuntu@cplane:~$ argocd account list
NAME ENABLED CAPABILITIES
admin true login
newuser1 true apiKey, login
사용자 비밀번호 설정
1
ubuntu@cplane:~$ argocd account update-password --account <new user account name> --current-password <admin password> --new-password <new user password>
사용자 권한 설정, 읽기 전용으로 설정. ArgoCD가 설치될 때 기본적으로 readonly, admin 권한이 빌트인 되어 있음
1
2
3
4
5
6
7
8
ubuntu@cplane:~$ kubectl edit configmap argocd-rbac-cm -n argocd
apiVersion: v1
data:
policy.csv: |
g, <new user account name>, role:readonly
policy.default: role:''
kind: ConfigMap
...
Trouble Shooting
5.1. ArgoCD 통신 문제
모두 설치하고, ArgoCD에 Repo 및 Application 생성을 시도했는데, 자꾸 DNS 쿼리에 실패하는 듯한 에러가 발생
1
2
ubuntu@cplane:~$ argocd repo add https://github.com/abc/abc.git
FATA[0020] rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing: dial tcp: lookup argocd-repo-server: i/o timeout"
문제는 CoreDNS가 고장나 있었다. CordDNS를 재시작하는 것으로 해결
1
2
ubuntu@cplane:~$ kubectl -n kube-system rollout restart deployment coredns
deployment.apps/coredns restarted