본문 바로가기
서버구축 (WEB,DB)

Kubernetes(K8s) Ingress 컨트롤러 SSL/TLS 무료 인증서 자동화 구성

by 날으는물고기 2024. 5. 21.

Kubernetes(K8s) Ingress 컨트롤러 SSL/TLS 무료 인증서 자동화 구성

Kubernetes (8) - Automatic TLS Certificates signed by Let's Encrypt

Kubernetes(K8s)에서 Ingress를 사용하여 애플리케이션을 외부에 노출시키려면 일반적으로 Ingress 컨트롤러가 필요하고, 이 컨트롤러는 클러스터 내의 NodePort 또는 LoadBalancer를 통해 동작합니다. Ingress 자체는 외부 요청을 적절한 서비스로 라우팅하는 규칙을 정의하지만, 실제 트래픽을 받기 위해서는 클러스터 밖으로의 연결 경로가 설정되어 있어야 합니다.

 

NodePort는 각 노드에 특정 포트를 할당하고, 이 포트를 통해 서비스에 접근할 수 있게 해주는 방법입니다. 이 포트를 통해 Ingress 컨트롤러에 도달하고, Ingress 컨트롤러는 정의된 규칙에 따라 트래픽을 적절한 서비스로 라우팅합니다. 따라서 NodePort 없이는 외부에서 Ingress 컨트롤러로의 접근이 불가능할 수 있습니다.

 

다만, 클라우드 환경에서는 LoadBalancer를 사용하여 이를 보다 효율적으로 관리할 수 있습니다. LoadBalancer를 사용하면 각 노드에 포트를 개별적으로 열지 않고도 외부 IP를 통해 클러스터로의 진입점을 제공할 수 있습니다. 이 경우, LoadBalancer가 Ingress 컨트롤러로 트래픽을 직접 전달하게 됩니다.

 

ingress-nginx 컨트롤러는 Kubernetes에서 가장 일반적으로 사용되는 Ingress 컨트롤러 중 하나이며, 기본적으로 HTTP 트래픽을 처리하기 위한 80 포트와 HTTPS 트래픽을 처리하기 위한 443 포트를 오픈합니다. 이 포트들은 외부 트래픽을 받아서 클러스터 내의 적절한 서비스로 라우팅하는 역할을 합니다.

 

ingress-nginx 설치 시, 일반적으로 LoadBalancer 서비스 유형을 사용하여 자동으로 이 포트들이 클러스터 외부에 노출되도록 구성됩니다. 이를 통해 외부에서 들어오는 트래픽이 ingress-nginx 컨트롤러를 통해 적절한 서비스로 라우팅되어 처리될 수 있습니다.

 

다음은 ingress-nginx의 LoadBalancer 서비스 예시입니다.

apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  type: LoadBalancer
  ports:
    - name: http
      port: 80
      targetPort: http
    - name: https
      port: 443
      targetPort: https
  selector:
    app.kubernetes.io/name: ingress-nginx

이 설정에서는 클러스터 외부로 80과 443 포트를 노출하고, 이 포트들은 내부적으로 ingress-nginx 컨트롤러로 트래픽을 전달합니다. 이를 통해 외부 트래픽이 클러스터 내부의 적절한 서비스로 정확하게 라우팅될 수 있습니다.

 

ingress-nginx-controller를 사용할 때, 일반적으로 LoadBalancer 서비스 타입을 선택하여 외부 IP를 할당받고, 이 IP를 통해 외부 트래픽을 직접 받을 수 있습니다. 이 방법은 특히 클라우드 환경에서 더욱 편리하고 효율적입니다.

 

NodePort 서비스 타입은 각 노드의 특정 포트를 사용하여 외부 트래픽을 수신하고, 이 포트를 통해 서비스에 접근하게 합니다. 그러나 LoadBalancer 서비스를 사용할 수 있는 환경에서는 LoadBalancerNodePort의 모든 기능을 포함하고 추가적으로 트래픽 관리와 배분을 더 효율적으로 수행하므로, NodePort 설정을 별도로 할 필요가 없습니다.

 

LoadBalancer 타입을 사용하면, 클라우드 제공업체가 제공하는 로드 밸런서가 자동으로 생성되고, 이 로드 밸런서가 외부 트래픽을 ingress-nginx 컨트롤러로 라우팅합니다. 따라서 추가적인 포트 설정 없이도 효율적으로 트래픽을 처리할 수 있습니다.

 

ingress-nginx 컨트롤러와 일반적인 Kubernetes 서비스의 NodePort 설정 사이에는 몇 가지 차이가 있습니다. 일반 서비스와 ingress-nginx 컨트롤러 모두 NodePort를 사용할 수 있지만, 그들이 작동하는 방식에는 차이가 있습니다.

  1. 일반 서비스의 NodePort
    • Kubernetes에서 일반적인 서비스를 NodePort로 설정할 때, 자동으로 높은 범위의 포트 (기본적으로 30000-32767) 중 하나가 할당됩니다. 이 포트를 통해 각 노드에서 해당 서비스에 접근할 수 있게 됩니다.
    • 사용자는 필요에 따라 이 포트 번호를 직접 지정할 수도 있습니다.
  2. ingress-nginx의 NodePort
    • ingress-nginx 컨트롤러를 설치할 때, 기본적으로 HTTP (80) 및 HTTPS (443) 트래픽을 처리하기 위해 이 포트들이 자동으로 설정됩니다.
    • 또한 NodePort 설정을 사용할 경우, ingress-nginx 컨트롤러는 자동으로 80과 443 포트 외에도 높은 범위의 포트를 하나 더 할당받아 사용합니다. 예를 들어, 80 포트는 30080으로, 443 포트는 30443으로 매핑될 수 있습니다. 이는 클러스터 내 모든 노드에서 해당 높은 포트를 통해 ingress-nginx에 접근할 수 있음을 의미합니다.

ingress-nginx가 특별한 이유는, 이 컨트롤러가 기본적으로 특정 포트(80, 443)를 노출하는데 최적화되어 설계되었기 때문입니다. 그러므로 이러한 특수 포트를 이용하는 트래픽을 관리하는 것은 ingress-nginx의 일반적인 운영 방식의 일부입니다. 이는 ingress-nginx 컨트롤러가 트래픽을 효율적으로 라우팅하고 관리하는 데 중요한 역할을 합니다.

 

ingress-nginxClusterIP 서비스 타입으로 설정하는 경우, 80과 443 포트는 클러스터 내부에서만 접근 가능하게 됩니다. ClusterIP는 클러스터 내부 통신을 위한 IP 주소를 제공하며, 외부에서 직접 접근할 수 없기 때문에 외부 노출을 직접적으로 지원하지 않습니다.

 

외부에서 ingress-nginx를 통해 서비스에 접근하려면, 다음과 같은 방법 중 하나를 사용해야 합니다.

  1. NodePort: NodePort 서비스 타입을 사용하면, 클러스터의 모든 노드에서 특정 고정 포트를 통해 서비스에 접근할 수 있습니다. 이 포트는 외부에 노출되므로, 외부 사용자가 해당 포트를 통해 클러스터에 접근할 수 있습니다.
  2. LoadBalancer: 클라우드 환경에서는 LoadBalancer 서비스 타입이 외부 트래픽을 ingress-nginx 컨트롤러로 라우팅하는 가장 간편하고 효율적인 방법입니다. 이는 외부 IP 주소를 제공하며, 이 IP를 통해 외부 트래픽이 컨트롤러로 직접 라우팅됩니다.

ClusterIP로 설정한 경우에는 다음과 같은 접근 방법이 필요합니다.

  • Ingress: ClusterIP로 설정된 ingress-nginx 컨트롤러를 사용하는 경우, 클러스터 내부에서만 접근할 수 있습니다. 그러나, ingress-nginx를 통한 라우팅은 클러스터 외부의 요청을 처리할 수 있도록 별도의 NodePort 또는 LoadBalancer 설정이 필요합니다. 즉, ClusterIP만으로는 외부 노출이 되지 않습니다.

따라서, ingress-nginxClusterIP 타입으로 설정했다면, 그 자체로는 외부 노출되지 않으며, 외부에서 접근하기 위해서는 추가적인 외부 접근 설정이 필요합니다.

 

Kubernetes 클러스터에서 ingress-nginx를 사용하여 HTTPS 서비스를 제공하고, Let's Encrypt를 통해 SSL/TLS 인증서를 적용하는 과정을 쉽게 관리하기 위해, cert-manager라는 도구를 사용하는 것이 일반적입니다. cert-manager는 Kubernetes 리소스로서 SSL/TLS 인증서를 자동으로 발급하고, 관리하며, 갱신합니다.

 

다음은 Let's Encrypt를 사용하여 ingress-nginx에 SSL/TLS 인증서를 적용하는 방법입니다.

1. cert-manager 설치

첫 번째 단계는 cert-manager를 클러스터에 설치하는 것입니다. 이는 다음과 같은 kubectl 명령어를 사용하여 진행할 수 있습니다.

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

이 명령은 cert-manager의 최신 안정 버전을 설치합니다. 설치 후에는 모든 컴포넌트가 올바르게 배포되었는지 확인하기 위해 상태를 검사할 수 있습니다.

kubectl get pods --namespace cert-manager

Helm을 사용하여 cert-manager 설치할 수 있습니다.

helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager --namespace cert-manager --version v1.5.3 --set installCRDs=true

2. Let's Encrypt 발급자(Issuer) 설정

Let's Encrypt를 사용하려면 발급자(Issuer) 또는 클러스터 발급자(ClusterIssuer) 리소스를 설정해야 합니다. ClusterIssuer는 클러스터 전체에 걸쳐 사용될 수 있는 반면, Issuer는 특정 네임스페이스에 국한됩니다.

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: your-email@example.com  # 여기에 사용자의 이메일 주소 입력
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          class: nginx

이 리소스를 적용하려면, 저장한 yaml 파일을 kubectl apply -f <filename>.yaml로 적용합니다.

3. 인증서 리소스 생성

이제 원하는 도메인에 대한 인증서를 요청할 수 있습니다. 인증서 리소스를 생성하여 cert-manager가 Let's Encrypt를 통해 인증서를 자동으로 발급받도록 설정합니다.

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: mysite-tls
  namespace: default
spec:
  secretName: mysite-tls-secret  # 인증서가 저장될 Secret
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
  - example.com  # 여기에 도메인 입력
  - www.example.com

이 파일을 적용한 후, cert-manager는 자동으로 ACME 프로토콜을 사용하여 Let's Encrypt에 인증서 발급을 요청하고, 도메인의 소유권을 검증하며, 발급된 인증서를 Kubernetes Secret에 저장합니다.

4. Ingress 리소스 업데이트

마지막으로, ingress-nginx 리소스를 업데이트하여 HTTPS 트래픽을 위한 인증서를 사용하도록 설정합니다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: mysite-ingress
  namespace: default
spec:
  tls:
  - hosts:
    - example.com
    - www.example.com
    secretName: mysite-tls-secret  # 위에서 생성한 Secret 사용
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-service
            port:
              number: 80

이렇게 설정함으로써, ingress-nginx는 Let's Encrypt에서 발급받은 인증서를 사용하여 HTTPS 트래픽을 안전하게 처리할 수 있습니다.

728x90

댓글