Intro


최적의 리소스를 찾는 과정은 중요하다.

어쩌다보니 프로젝트의 기획 규모가 필자 기준에서는 방대해졌다. 문제풀이 기능과 1:1 멘토링 기능, 알림 기능 등과 더불어 사용자 관련 기능까지 개발하다보니 도입해야할 기술스택이나 도구들이 그만큼 많이 필요했다.

이 때, 뭐가 필요한지, 어떤 리소스가 가장 적합한지를 찾을 때 많은 시간을 투자하게 된다. 이전에도 느꼈지만 특정 기술의 필요성을 느꼈다면, 해당 기술에 대해서 조사해보고, 탐색해보고 학습하여 도입하게 되는데 도입하기 까지의 과정에서 느끼거나 깨닫는 부분이 생각 이상으로 많았다.

물론 필요한 자원을 찾아 도입하여 현재 업무를 마무리하는 것도 중요하지만, 필요한 자원을 도입하기 위해 개발자 본인이 주체적으로 검색하고, 공부하고, 고민해보는 시간이 보다 귀하다고 느껴졌다.

그런데 시간의 압박으로 인해 자원을 도입하기까지 고민할 수 있는 시간이 많지 않아 나중에라도 기억하고 공부하기 위해 노션에 키워드를 정리해두었다.

앞으로 개발을 하면서도 특정 기술을 도입하기까지 내가 어떻게 공부했고, 고민했고, 노력했는지를 보여줄 수 있는 개발자가 될 것이다!




Week 25

카카오 클라우드 스쿨 25주차 116~120일까지의 공부하고 고민했던 흔적들을 기록하였습니다.

HTTPS 접속을 위해 AWS Managed Service인 Route53과 ACM, 그리고 ALB(Ingress) 이용하기

진행하고 있는 프로젝트는 AWS 환경에서 운영하다보니 IP 단위로 접속할 수 있다. 이 IP를 원하는 도메인의 DNS로 설정하는 것과 함께 SSL 인증서를 통해 HTTPS 통신을 할 수 있도록 설정하는 과정을 기록해보려 한다.

도메인 등록을 위해 가비아에서 diveloper.site라는 도메인을 2천원에 구입했다. developers로 시작하는 도메인은 금액이 너무 비쌌다 ㅠ


가비아에서 구입한 도메인을 AWS Route53에서 호스팅하기

만약 AWS에서 이용하는 EC2 인스턴스가 1~2개 정도라면, 단순히 가비아에 DNS 레코드에 EC2 인스턴스의 IP를 등록하는 것이 가장 간단하게 도메인 설정을 마칠 수 있는 방법이다.

다만 필자의 프로젝트는 AWS EKS Cluster에서 운영환경을 구축하다보니 워커노드로 이용할 인스턴스가 추가적으로 2개가 요구되었고, 앞으로의 확장성이나 보안적인 측면을 생각해서라도 Route53을 이용하는 것이 바람직하다고 판단하여 가비아에서 구입한 도메인의 호스팅 설정을 Route53에서 진행했다.

Route53은 추가적으로 여러가지 고급 기능을 제공하는데 Traffic Flow 기능을 사용하여 사용자가 가장 가까운 서버로 연결되도록 조정하거나, Health Check 기능을 사용하여 호스팅하는 서버가 다운되면 이를 자동으로 감지하고 다른 서버로 전환할 수 있도록 설정할 수 있다. 따라서 AWS Route53은 DNS 관리를 자동화하고, 유연성과 안정성을 제공하여 웹 사이트 또는 애플리케이션을 더욱 안정적으로 운영할 수 있게 해준다.

위 사진은 Route53에서 diveloper.site라는 이름으로 호스팅 영역을 생성한 후 관리하는 레코드의 내역을 볼 수 있는 콘솔 화면이다.

Route53에 호스팅 영역을 생성하면 기본으로 NS, SOA 레코드가 만들어진다. (A 레코드와 CNAME 레코드는 ALB 및 SSL 설정을 위해 추가한 레코드라서 지금 중요하게 볼 필요는 없다.)

가비아에 EC2 인스턴스의 IP를 등록하여 도메인을 호스팅할 것이라면 상관없지만 Route53에서 도메인을 호스팅하려면 Route53에서 만들어진 네임서버(NS) 정보를 가비아의 도메인 네임서버로 등록해주어야 한다.

AWS Route53의 NS 레코드 종류는 다음 4가지가 자동으로 생성된다.

  • xxx.com
  • xxx.org
  • xxx.co.uk
  • xxx.net

도메인 네임서버는 도메인 이름의 IP 주소를 찾아서 웹사이트 또는 이메일 등의 서비스에 연결해주는 역할을 한다. 도메인 네임서버는 도메인 이름의 일부분인 최상위 도메인(TLD, Top-level Domain)을 포함하여 여러 레벨로 구성되는데 이 중에서도 일반적으로 사용되는 최상위 도메인은 .com, .org, .net 등이 있다.

가비아에서 기본으로 설정된 네임서버는 다음과 같다.

이 네임서버 설정을 AWS Route53의 해당 도메인으로 만든 호스팅 영역의 NS 레코드 값으로 변경해주면 된다.


HTTPS 접속을 위해 ACM(AWS Certificate Manager)에서 무료 인증서 발급받기

가비아에서 구입한 도메인을 AWS Route53에 정상적으로 매핑은 성공했다. 이제 HTTP 접속이 아닌 HTTPS 접속을 하기 위해 SSL 인증서를 발급받아 해당 도메인에 적용하는 과정이 필요했다.

SSL 인증서를 무료로 발급받기 위해 2가지 방법이 있었다.

  • Let's Encrypt
  • ACM(AWS Certificate Manager)

사실 크게 고민할 것도 없이 ACM을 선택했다. 무료 오픈소스 SSL 인증서 발급 기관인 Let's Encrypt를 통해 인증서를 직접 관리하는 것보다 ACM을 이용하는 것이 더 쉽다고 느꼈기 때문이다.

또한, 운영환경도 이미 AWS에서 구축했을 뿐더러 ACM을 이용하면 인증서를 직접 관리하지 않아도 되고, 자동 갱신 또한 지원해주기에 이용안할 이유가 없었다.

그렇게 ACM에서 diveloper.site 도메인 이름으로 인증서를 발급받았다.

여기서 주의할 점!

ACM에서 인증서를 발급받는다고 끝나는 것이 아니다. 반드시 해당 인증서를 Route53에 레코드로 등록해야한다.

필자의 Route53 호스팅 영역을 보면 기본으로 제공되는 NS, SOA 레코드 말고도 A 레코드와 CNAME 레코드가 등록되어 있다.

ACM 인증서를 발급받고 바로 Route53에서 레코드 생성을 하게 된다면 CNAME 레코드가 생성된다.


HTTPS 통신으로 로드밸런싱을 수행하기위해 ALB(로드밸런서) 설정하기

앞서 ACM에서 무료 인증서를 발급받고 Route53에 CNAME 레코드까지 등록했다.

이제 Route53에 A 레코드를 등록하면 개발한 프로젝트를 외부에서 접속하기 위한 준비는 마무리된다.

Route53에서 A 레코드는 도메인 이름을 IP 주소로 매핑하는 역할을 한다. A 레코드를 등록해 도메인 이름과 IP 주소를 매핑하면, AWS에서의 안정적인 서비스 제공과 사용자의 편의성을 높일 수 있다.

사실 HTTPS 통신이 아닌 HTTP 접속만 수행한다면 EC2 인스턴스의 IP를 A 레코드로 등록하면 끝나지만, HTTPS 접속을 위해서는 로드밸런서의 설정 변경이 필요하다.

필자의 프로젝트는 EKS Cluster 위에서 Pod를 Deployment로 Deployment를 Service로 배포하여 애플리케이션을 서비스하고 있었다.

그리고 Service들을 Ingress를 통해 로드밸런싱하기 위해서 AWS의 ALB 형식의 Manifest를 개발하여 배포해둔 상태였다.

이 ALB에 앞서 ACM에서 발급받은 SSL 인증서 정보를 가지고 TLS(Transport Layer Security) 설정만 추가해준다면 HTTPS 통신 설정이 마무리되고 정상적으로 클라이언트에서 웹 서비스를 HTTPS로 통신할 수 있을 것이라 생각했다.

AWS EKS Ingress Manifest 파일에 annotations 설정에 ACM의 SSL 인증서 정보를 추가하였고, 해당 파일의 정보는 다음과 같다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: developers-ingress
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: instance
    alb.ingress.kubernetes.io/subnets: subnet-1,subnet-2
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-northeast-2:xxxxxxxxxxxx:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    alb.ingress.kubernetes.io/ssl-redirect: '443'
spec:
  rules:
    - host: diveloper.site

annotations 옵션에 listen-ports, certificate-arn, ssl-redirect 설정을 추가하였다.

여기서 중요한 부분은 바로 certificate-arn 옵션이다. 해당 옵션에는 자격 증명 공급자를 정보를 기입해야 한다.

AWS EKS에서 Ingress로 ALB를 사용하기 위해서는 자격 증명 공급자를 별도로 생성해야만 한다.

AWS EKS에서 ALB를 위한 Ingress Manifest를 작성할 때는 일반적으로 k8s를 통해 로컬 클러스터를 구축할 때의 Ingress Manifest를 작성하는 것과 달리 AWS에서 제공하는 가이드라인을 따라야 한다. 이와 관련된 링크는 AWS Load Balancer Controller 문서를 참고바란다.

필자도 이것을 잘 모르는 상태로 Ingress Manifest를 EKS에 반영하려고 할 때, Ingress Controller와 Ingress를 AWS에서 정해준 가이드라인을 따라야 함을 나중에 알게되어 삽질했던 경험이 있다.


$ kubectl describe ingress
Name:             developers-ingress
Labels:           <none>
Namespace:        default
Address:          k8s-default-develope-xxxxxxxxxx-xxxxxxxxx.ap-northeast-2.elb.amazonaws.com
Ingress Class:    <none>
Default backend:  <default>
Rules:
  Host            Path  Backends
  ----            ----  --------
  diveloper.site  
                  /                     developers-client-svc:80 (xx.xx.x.xxx:3000)
                  /api/                 developers-member-svc:80 (xx.xx.x.xxx:9000)
                  ... 생략
                  
Annotations:      alb.ingress.kubernetes.io/actions.ssl-redirect:
                    {"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}
                  alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-northeast-2:780477479548:certificate/bdcb81c1-6256-464c-a15d-54e0bd7f1a13
                  alb.ingress.kubernetes.io/listen-ports: [{"HTTP": 80}, {"HTTPS":443}]
                  alb.ingress.kubernetes.io/scheme: internet-facing
                  alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-2016-08
                  alb.ingress.kubernetes.io/ssl-redirect: 443
                  alb.ingress.kubernetes.io/subnets: subnet-1,subnet-2
                  alb.ingress.kubernetes.io/target-type: instance
                  kubernetes.io/ingress.class: alb
Events:
  Type    Reason                  Age   From     Message
  ----    ------                  ----  ----     -------
  Normal  SuccessfullyReconciled  7s    ingress  Successfully reconciled

아무튼, 그렇게 위와 같이 Ingress Manifest 파일에 SSL 인증서 정보와 자격 증명 공급자 정보를 기입해주고 Ingress를 업데이트하니 위와 같이 정상적으로 반영되었다.


추가적으로 AWS Managed Console의 로드밸런서 리스너 정보를 확인해보니, 80포트와 443포트가 추가되어있다.

먼저 80포트로 접속할 경우 위에서 작성한 Ingress의 ssl-redirect 설정으로 인해 443포트로 리다이렉트하도록 설정된 것을 확인할 수 있었다.

그리고 443포트로 접속할 경우 ACM에서 발급받은 SSL 인증서가 정상적으로 반영되어 있음을 확인할 수 있었다.

이렇게 Route53, ACM, ALB 설정을 마치고 diveloper.site로 접속하니 정상적으로 HTTPS로 접속이 되었다.




Final..

최종 프로젝트의 골격이 어느정도 나왔다.

발표를 위해서라면 준비할 것은 아직 많지만 대략적인 개발이 마무리되었다는 사실이 뿌듯했고, 한편으로는 나태하게 했다.

그래도 팀 리드로써 발표를 위한 문서화도 중요하지만, 앞으로 수료 이후에 프로젝트를 열람할 여러 선배 개발자들에게 보여주기 위한 문서 정리도 반드시 필요하기에 쉼 없이 프로젝트 문서화를 진행하고 있다.


혹여 잘못된 내용이 있다면 지적해주시면 정정하도록 하겠습니다.

참고자료 출처

profile
찍어 먹기보단 부어 먹기를 좋아하는 개발자

0개의 댓글