ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Cert-manager와 Traefik IngressRoute을 이용한 nginx https 배포
    K8S 2022. 10. 25. 22:49

     

     

    틀린 내용이 있을 수도 있습니다! 

    틀린 내용이 있다면 댓글로 달아주시면 감사하겠습니다!

     

    개요  

    • IngressRoute를 이용해서 nginx를 배포한다. 
    • cert-manager를 통해 인증서를 발급하고 https를 사용한다.

     

    구성

    1. loadbalancer를 사용할 수 없는 환경인 경우, traefik service를 nodeport로 배포해서 ingressroute를 사용한다. 

    2. lb를 사용할 수 있다면, traefik service를 loadbalancer로 만들어  ingressroute를 사용한다. 

     

    1. NodePort를 사용하는 경우

    1) helm을 이용해서 traefik chart를 설치한다. 

    helm repo add traefik https://helm.traefik.io/traefik
    helm repo update
    helm pull traefik/traefik --untar

     

    2) traefik helm chart의 values.yaml을 변경한다.

    # values.yaml
    ingressClass.enabled: true # 이부분은 없어도 될 듯 하다. 하지만 혹시 몰라서 추가  
    ingressClass.isDefaultClass: true # 이부분은 없어도 될 듯 하다. 하지만 혹시 몰라서 추가  
    service.type: NodePort 
    ports.web.nodePort: 32080
    ports.websecure.nodePort: 32443

     

    3) traefik을 설치한다. 

    kubectl create ns traefik
    helm install traefik ./traefik -n traefik

     

    4) cert-manager를 설치한다.

    helm repo add jetstack https://charts.jetstack.io
    helm repo update
    helm pull jetstack/cert-manager --untar

     

    5) cert-manager chart의 values를 변경한다.

    # values.yaml
    installCRDs: true # 이 부분을 변경해 주어야, certificate나 clusterissuer crd가 설치된다.

     

    6) cert-manger 설치 

    kubectl create ns cert-manager
    helm install cert-manager . -n cert-manager

     

    7) nginx deployment와 service 생성한다. 

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
      name: nginx
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nginx
      strategy: {}
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: nginx
        spec:
          containers:
          - image: nginx
            name: nginx
            ports:
            - containerPort: 80
            resources: {}
    status: {}
    
    ---
    apiVersion: v1
    kind: Service
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
      name: nginx
      namespace: default
    spec:
      ports:
      - name: http
        port: 8080
        protocol: TCP
        targetPort: 80
      selector:
        app: nginx
    status:
      loadBalancer: {}

     

    8) issuer와 인증서를 생성하자. 

     

    나의 경우에는 공인 인증서가 아닌 간편한 self-signed 인증서를 선택했다.  

    또한 도메인을 따로 발급하지 않았기 때문에 nip.io를 사용하였는데,

    nginx라는 서브 도메인 사용을 원했기 때문에 nginx.[node의 ip].nip.io를 도메인으로 사용했다. 

    그리고 어차피 nodeport 타입으로 traefik service를 생성했기 때문에 cluster의 어떤 노드의 ip를 사용해도 무관하다. 

    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: selfsigned-issuer
    spec:
      selfSigned: {}
    
    ---
    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: nginx-ingress-certificate
      namespace: default
    spec:
      secretName: nginx-ingress-tls
      issuerRef:
        name: selfsigned-issuer
        kind: ClusterIssuer
        group: cert-manager.io
      commonName: nginx.192.168.9.37.nip.io
      dnsNames:
      - nginx.192.168.9.37.nip.io # subdomain.[node의 ip].nip.io를 사용하였다.

     

    9) IngressRoute를 생성하자.

     

    IngressRoute는 ingress와 유사하지만, 더 많은 기능을 제공하기 때문에 traefik을 api-gateway로 사용하는 경우라면  ingress 대신 ingressroute를 사용하는 것이 더 적합한 방법일 것이다.

    예를 들면, middleware 라는 리소스를 이용해 들어온 요청의 URI를 변경할 수도 있고, tlsStore라는 리소스를 통해 하나의 인증서로 여러 ingressroute에 https를 적용할 수도 있다. 

    apiVersion: traefik.containo.us/v1alpha1
    kind: IngressRoute
    metadata:
      name: nginx-ingressroute
      namespace: default
    spec:
      routes:
      - match: Host(`nginx.192.168.9.37.nip.io`) && PathPrefix(`/`)
        kind: Rule
        services:
        - name: nginx
          namespace: default
          port: 8080
      tls:                          
        secretName: nginx-ingress-tls

     

    배포가 잘 끝났다면, 다음 경로의 nodePort로 접속해본다.  

    https://nginx.192.168.9.37.nip.io:32080

     

     

    2. Loadbalancer를 사용하는 경우

    위에서 배포한 traefik helm chart에 이어서 작업한다. 

    참고로 내가 사용하고 있는 환경은 metallb를 이용해서 loadbalancer를 생성할 수 있는 환경이다. 

     

    1) 위에서 이어 traefik helm chart values를 수정한다. 

    # values.yaml
    service.type: LoadBalancer
    providers.kubernetesIngress.publishedService.enabled: true # 이 부분 사실 설정 안해도 상관없을듯하다.

     

    2) 기존 chart를 upgrade한다. 

    helm upgrade traefik [chart 경로] -n traefik

     

    3) loadbalancer ip를 확인한다.

    kubectl get svc traefik -n traefik -o jsonpath={.status.loadBalancer.ingress[0].ip}

     

    4) certificate를 생성한다.

     

    cluster issuer를 미리 생성해놓았기 때문에, loadbalancer용 certificate만 새로 생성하자.  

    이 또한 마찬가지로 nip.io를 이용해서 도메인으로 만들었다. 

    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: nginx-ingress-certificate-lb
      namespace: default
    spec:
      secretName: nginx-ingress-tls-lb
      issuerRef:
        name: selfsigned-issuer
        kind: ClusterIssuer
        group: cert-manager.io
      commonName: nginx.192.168.109.20.nip.io
      dnsNames:
      - nginx.192.168.109.20.nip.io

     

    5) IngressRoute를 생성한다.

     

    변경된 부분이 있다면 이전의 ingress에는 node의 ip를 적었다면, 현재 배포할 ingress에는 loadbalancer의 ip를 적었다. 

    이외의 다른 부분은 동일하다.  

    apiVersion: traefik.containo.us/v1alpha1
    kind: IngressRoute
    metadata:
      name: nginx-ingressroute-lb
      namespace: default
    spec:
      routes:
      - match: Host(`nginx.192.168.109.20.nip.io`) && PathPrefix(`/`)
        kind: Rule
        services:
        - name: nginx
          namespace: default
          port: 8080
      tls:                          
        secretName: nginx-ingress-tls-lb

     

    https://nginx.192.168.109.20.nip.io 로 접속해서 배포된 nginx를 확인해보자. 

     

    그리고

    원래는 ingressroute가 아닌 ingress를 이용해서 nginx를 https로 배포하려고 했다.

    하지만 계속 연결 실패해서 ingressroute로 변경했는데, 이 과정에서 알게 된 것들을 잠시 풀어보면 다음과 같다.

    1. ingress와 cert-manager를 함께 사용하고 싶을 때는 ingress에 cert-manager가 읽을 수 있는 label 또는 annotation을 달아주어야 한다. 

    2. ingress + cert-manager + traefik 이 조합은 안 되는듯 하다. 이 부분은 좀 더 알아봐야 할듯

    반응형

    댓글

Designed by Tistory.