-
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 이 조합은 안 되는듯 하다. 이 부분은 좀 더 알아봐야 할듯
반응형'K8S' 카테고리의 다른 글
K8S에서 NFS 서버 없이 동적 프로비저닝 사용하기 (0) 2022.12.02 ArgoCD와 Keycloak OIDC 연동하기 (0) 2022.11.25 Ingress traefik을 이용한 nginx http 배포 (0) 2022.10.25 Keycloak을 이용한 K8S 사용자 분리 (0) 2022.09.04 local 볼륨 동적 프로비저닝을 위한 PV, PVC 예제 (0) 2022.08.26