개발놀이터

AWS EKS 스프링 + Nginx + SSL 본문

배포/kubernetes

AWS EKS 스프링 + Nginx + SSL

마늘냄새폴폴 2024. 10. 5. 01:23

저번 포스팅에서 이어지는 내용입니다! 

 

https://coding-review.tistory.com/557

 

AWS EKS 스프링 프로젝트에 NGINX 붙이기

이번 포스팅은 이전 포스팅과 어느정도 이어집니다. 이전에 스프링 프로젝트를 간단하게 배포했는데 저는 추후 HTTPS를 붙여서 실제 도메인을 붙여볼 예정이기 때문에 Nginx에 스프링 프로젝트를

coding-review.tistory.com

 

저번 포스팅에선 Nginx를 설치하고 스프링 프로젝트를 붙여서 로드밸런서를 이용해서 외부에서 접속해봤습니다. 

 

이번엔 Nginx에 SSL을 붙여서 HTTPS를 적용시켜봤습니다. 거의 4일내내 이거만 한거같네요. 본격적으로 시작해보겠습니다!

 

Nginx와 SSL 근데 이제 Kubernetes를 곁들인

저도 Nginx에 SSL을 붙인게 한두번이 아닌지라 제가 익숙한 방식대로 했습니다. 처음엔 이렇게요. 

 

apiVersion: v1
data:
  default.conf: |-
    server {dd
        listen 443 ssl;
        server_name studyk8swithaws.shop;
        server_tokens off;

        ssl_certificate /etc/nginx/ssl/fullchain.pem;
        ssl_certificate_key /etc/nginx/ssl/privkey.pem;

        location / {
          proxy_pass http://spring-svc.was.svc.cluster.local:8080;
          proxy_set_header Host $http_host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
kind: ConfigMap
metadata:
  creationTimestamp: "2024-09-30T13:15:21Z"
  name: nginx-conf
  namespace: ingress-nginx
  resourceVersion: "1565754"
  uid: ffe6bda7-017c-4a85-a7c4-1b2f8e1bbb14

 

conf파일을 configmap으로 만들어서 이걸 volumeMount하는 작전이었는데...

 

사실 이렇게 하면 될 줄 알았는데 실패했습니다. 조금 더 깊이있게 파봤으면 성공했을지도 모르지만 nginx ingress controller에서 SSL을 리다이렉트 시켜주는 것을 지원해준다고 하길래 곧장 선회했습니다. 

 

1. 도메인 사기

도메인을 구입했는데 저는 .shop이 붙은 도메인으로 550원주고 샀습니다. 저렴한 도메인이 많으니 한번 찾아보시는 것을 추천드려요!

 

2. Route53과 도메인 연결하기

이 부분은 빠르게 넘어가겠습니다. Cafe24던 가비아던 네임서버를 Route53의 네임서버로 변경해주는 것입니다. 그리고 만들어진 로드밸런서를 A레코드를 이용해서 붙여줘야합니다. 

 

그리고 letsencrypt에서 발급한 TXT레코드도 등록해야하니 이부분은 정확히 짚고 넘어가겠습니다. 

 

certbot certonly --manual --preferred-challenges=dns \
  --email {내 이메일} \
  --server https://acme-v02.api.letsencrypt.org/directory \
  --agree-tos \
  --domain {내 도메인 www 빼고} \
  --domain "*.{내 도메인}" \
  --work-dir ./certbot \
  --config-dir ./certbot \
  --logs-dir ./certbot

 

이렇게 진행하면 다음과 같은 문구가 뜹니다. 엔터를 누르라고 하는데 우선 엔터를 누르지 말아야합니다!

 

 

이걸 Route53에서 TXT를 생성하고 붙여넣기 해야합니다. 

 

Route53에서 새 레코드 생성을 누르시고 TXT타입으로 만들어줍니다. 

 

 

레코드 이름에 정확히 _acme-challenge라고 넣어주시고 값에는 위에서 빨간 밑줄 친 부분을 넣어줍니다. 

 

그리고 상태 확인을 통해 DNS에 전파되는 것을 확인하고 엔터를 눌러줍니다. 

 

 

여기로 들어가면 fullchain과 privkey가 생깁니다. 해당 디렉토리로 이동한 다음 다음과 같은 명령어를 작성해줍니다. 

 

kubectl create secret tls nginx-ssl-secret \
  --namespace ingress-nginx \
  --cert=fullchain.pem \
  --key=privkey.pem \
  --dry-run=client -o yaml | kubectl apply -f -

 

이렇게 secret을 만들어줍니다. 그럼 일단 letsencrypt는 준비 끝!

 

3. cert-manager 설치

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.3/cert-manager.yaml

 

이걸 설치해주시면 Certificate 오브젝트를 관리할 수 있습니다. 

 

그리고 cert-manager는 ClusterIssuer를 이용해서 인증서를 지속적으로 발급해줍니다. 이어서 ClusterIssuer까지 만들겠습니다. 

 

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-nginx
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: kyoungsuk3254@naver.com
    privateKeySecretRef:
      name: letsencrypt-nginx
    solvers:
    - http01:
        ingress:
          class: nginx

 

그리고 이제 ingress를 업데이트해줘야합니다.

4. ingress 수정

저번 포스팅에서 조금 많이 수정되는 ingress입니다. 

 

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
  namespace: ingress-nginx
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-nginx
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  tls:
    - hosts:
        - studyk8swithaws.shop
      secretName: nginx-ssl-secret
  rules:
    - host: studyk8swithaws.shop
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: spring-svc
                port:
                  number: 80

 

issuer로 letsentrypt-nginx (<< 이건 ClusterIssuer에서 작성한 이름이어야합니다.) 를 작성하고 tls 부분을 추가해줍니다. 그리고 서비스를 원래는 nginx의 서비스를 붙였었는데 이걸 스프링 서비스로 바꿔줍니다. 

 

이전 포스팅들과 달라지는 점이라면 네임스페이스가 다르면 인식할 수 없을 수도 있어서 스프링 replicaset이랑 service를 모두 ingress-nginx와 같은 네임스페이스를 사용하도록 했습니다. 

 

서비스의 포트는 80포트입니다. 아래에서 바로 서비스 yaml 파일을 보시죠. 

 

apiVersion: v1
kind: Service
metadata:
  name: spring-svc
  namespace: ingress-nginx
spec:
  selector:
    type: was
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

 

서비스 포트는 80, 타겟 포트는 8080을 설정해주고 replicaset에서도 containerPort를 8080으로 변경해줍니다. 

 

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: spring-rs
  namespace: ingress-nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      type: was
  template:
    metadata:
      labels:
        type: was
    spec:
      volumes:
      - name: was-storage
        persistentVolumeClaim:
          claimName: nginx
      containers:
      - name: was-container
        image: 192021811870.dkr.ecr.ap-northeast-2.amazonaws.com/k8s/ecr:latest
        ports:
        - containerPort: 8080
        volumeMounts:
        - name: was-storage
          mountPath: /was/storage
        resources:
          requests:
            cpu: 500m
            memory: 1Gi
          limits:
            cpu: 500m
            memory: 1Gi
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: deploy
                operator: In
                values:
                - was

 

이렇게 준비를 모두 끝마치고 ingress controller를 재시작해줍니다. 

 

kubectl rollout restart deployment -n ingress-nginx ingress-nginx-controller

 

혹시 이때 안된다면 로그를 확인해서 어떤 부분이 문제인지 확인하셔야합니다! 저는 보안 그룹에서 8080포트를 열어주지 않아서 502 에러가 떴었습니다. 

 

그리고 도메인으로 입력해보면?

 

성공적으로 띄웠습니다! 옆에 빨간경고도 안뜨고 정말 보기 좋네요. 

 

 

마치며

4일이 넘게 걸려서 해결한 것을 블로그로 정리하려니 30분도 안걸렸네요. 그래도 성공하니까 기분은 좋습니다!

 

다음 포스팅은 실제로 파드에 부하를 줘서 파드가 늘어나는지 확인해볼겁니다. Kubernetes Auto Scaler, 그중에서도 HPA를 이용해서 파드를 늘려보고 실제로 파드가 늘어나는지 그리고 노드의 자원이 부족하면 노드도 늘어나는지 테스트 해보려고합니다. 

 

그럼 이번 포스팅도 여기까지 마치도록 하겠습니다. 긴 글 읽어주셔서 감사합니다. 오늘도 즐거운 하루 되세요~