본문 바로가기
Kubernetes/CI-CD

AWS EKS에 ArgoCD를 ALB로 연결하여 배포하기

by isn`t 2022. 3. 26.

ALB-ArgoCD on EKS

EKS에 ArgoCD를 배포하고 CI/CD를 구현하는 과정에서 ArgoCD를 AWS ELB에 붙여서 HTTPS로 외부 접근 가능하도록 배포하고 싶었다. 그러나 제공되고 있는 yaml 템플릿은 CLB를 기준으로 되어있었으며, 인증서 설정도 되어있지 않아 HTTPS 로 연결할 수 없었다.
결국 사용자가 자기 환경에 맞게 커스텀해서 사용해야 하는데, 구글링해서 얻을 수 있는 use case들은 모두 제각기 다른 환경에 맞추어 커스텀하고 있기에 즉각 적용하기가 어려웠다.

잘못된 정보들..

많은 블로그에서 Service Type을 LoadBalancer로 지정하고 적절한 annotation을 주면 alb로 올릴 수 있다고 설명하고 있다. 또는 NodePort 타입을 지정한다던가..(NodePort를 사용해서 올릴 필요가 전혀 없는 환경이기에 내게 필요한 정보가 아니었다.)

Service의 yaml을 정의할 때 type을 LoadBalancer로 지정하면 CLB가 기본으로 생성되며, annotation을 추가하면 NLB로도 생성이 가능하다. EKS가 버전업 되면서 뭔가 문제가 생긴 것인지는 모르겠지만, 유독 ALB만 type 변경과 annotation만으로 생성이 불가능했다.

Summary

  • EKS에서 Service의 type을 LoadBalancer로 지정하면 기본적으로 CLB가 생성된다.
  • ArgoCD의 기본 yaml 템플릿은 NLB/ALB 가 아닌 CLB로 작성되어 있다.
  • AWS는 CLB의 사용을 권장하지 않는다.
  • service type을 LoadBalancer로 하고 적절한 annotation을 추가하면 NLB 생성 가능하다.
  • ALB를 생성할 때는 Service type을 LoadBalancer로 해봤자 annotation 아무리 넣어도 안된다.
  • ALB 만들려면 service type은 ClusterIP로 만들어야 하고, AWS ALB 자체는 Ingress 에 의해 생성된다.
  • 즉, service type을 LoadBalancer로 하고 Ingress를 정의하면 CLB와 ALB가 둘 다 생성된다.

Solutions

1. ArgoCD on EKS - HTTP

ArgoCD를 AWS의 ALB로 연결하고 Linster를 80포트로 지정하는 경우 yaml파일의 service, ingress를 아래와 같이 수정한다.

이렇게 하면 ALB DNS 주소의 80포트로 접근했을 때 내부적으로 argocd-server 파드가 돌고 있는 8080포트로 매핑하여 ArgoCD 대시보드를 확인할 수 있게 된다.

---

apiVersion: v1
kind: Service
metadata:
 labels:
 app.kubernetes.io/component: server
 app.kubernetes.io/name: argocd-server
 app.kubernetes.io/part-of: argocd
 name: argocd-server
 namespace: argocd
 annotations:
 ## Health Check
 alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
 alb.ingress.kubernetes.io/healthcheck-port: traffic-port
 alb.ingress.kubernetes.io/healthcheck-path: /
 alb.ingress.kubernetes.io/healthcheck-interval-seconds: '10'
 alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '5'
 alb.ingress.kubernetes.io/success-codes: '200-399'
 # Target group
 alb.ingress.kubernetes.io/target-group-attributes: "deregistration_delay.timeout_seconds=10, load_balancing.algorithm.type=least_outstanding_requests"
spec:
 ports:
 - name: http
 port: 80
 protocol: TCP
 targetPort: 8080
 selector:
 app.kubernetes.io/name: argocd-server
 type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: argocd-server-8080
 annotations:
 ## ALB
 kubernetes.io/ingress.class: alb
 alb.ingress.kubernetes.io/scheme: internet-facing # internet-facing
 alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]'
 alb.ingress.kubernetes.io/target-type: ip
spec:
 rules:
 - http:
 paths:
 - path: /
 pathType: Prefix
 backend:
 service:
 name: argocd-server
 port:
 number: 80
---

2. ArgoCD on EKS - HTTPS

위에서 추가로 HTTPS 리스너를 생성하고 HTTP에 대한 요청을 리다이렉트 하고 싶다면?


먼저 특정 도메인에 대해서 ACM 인증서를 발급받고, arn을 확보한다.

---

apiVersion: v1
kind: Service
metadata:
 labels:
 app.kubernetes.io/component: server
 app.kubernetes.io/name: argocd-server
 app.kubernetes.io/part-of: argocd
 name: argocd-server
 namespace: argocd
 annotations:
 ## Health Check
 alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
 alb.ingress.kubernetes.io/healthcheck-port: traffic-port
 alb.ingress.kubernetes.io/healthcheck-path: /
 alb.ingress.kubernetes.io/healthcheck-interval-seconds: '10'
 alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '5'
 alb.ingress.kubernetes.io/success-codes: '200-399'
 # Target group
 alb.ingress.kubernetes.io/target-group-attributes: "deregistration_delay.timeout_seconds=10, load_balancing.algorithm.type=least_outstanding_requests"
spec:
 ports:
 - name: http
 port: 80
 protocol: TCP
 targetPort: 8080
 selector:
 app.kubernetes.io/name: argocd-server
 type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: argocd-server-8080
 annotations:
 ## ALB
 kubernetes.io/ingress.class: alb
 alb.ingress.kubernetes.io/scheme: internet-facing # internet-facing
 alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]'
 alb.ingress.kubernetes.io/target-type: ip
 alb.ingress.kubernetes.io/ssl-redirect: '443'
spec:
 rules:
 - http:
 paths:
 - path: /
 pathType: Prefix
 backend:
 service:
 name: argocd-server
 port:
 number: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: argocd-server-443
 namespace: argocd
 annotations:
 ## Ingress Core Settings
 kubernetes.io/ingress.class: "alb"
 alb.ingress.kubernetes.io/scheme: internal # internet-facing
 alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS": 443}]'
 alb.ingress.kubernetes.io/target-type: ip
 ## SSL Option
 alb.ingress.kubernetes.io/ssl-policy: "ELBSecurityPolicy-2016-08"
 alb.ingress.kubernetes.io/certificate-arn: "<인증서의 arn>"
spec:
 rules:
 - http:
 paths:
 - path: /
 pathType: Prefix
 backend:
 service:
 name: argocd-server
 port:
 number: 80

1번 HTTP일 경우와 달라진 점을 보자면, 443 포트에 대한 ingress가 추가되었고 80 포트에 대한 ingress는 443 포트에 대한 ingress로 redirect 하는 annotation이 추가되었다.
이외에도 annotation에는 ALB에 대한 보안그룹과 접속 대상의 CIDR등을 정의할 필요가 있다.