ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [udemy] Ingress - SSL with Let's Encrypt
    kubernetes/udemy 2025. 2. 23. 12:14

    SSL 설정

     

    Let's Encrypt를 통해 인증서를 발급하고, Ingress에 적용해보자.

    * 사전 작업 : Ingress controller 설치, Azure DNS Zone 생성, ExternalDNS 생성

     

    Cert manager 설치

     

    # ingress-basic 네임스페이스에 리소스 검증 비활성화 적용

    # Label the ingress-basic namespace to disable resource validation
    kubectl label namespace ingress-basic cert-manager.io/disable-validation=true

     

    ingress-basic 네임스페이스에 대해 cert-manager의 리소스 검증을 비활성화하는 설정

     

    # helm repository 등록

    # Add the Jetstack Helm repository
    helm repo add jetstack https://charts.jetstack.io
    # Update your local Helm chart repository cache
    helm repo update

     

    # helm chart를 이용하여 cert manager 설치

    # Install the cert-manager Helm chart
    helm install \
      cert-manager jetstack/cert-manager \
      --namespace ingress-basic \
      --version v1.13.3 \
      --set installCRDs=true

     

    # 확인

    kubectl get pods -n ingress-basic
    ---
    NAME                                        READY   STATUS    RESTARTS   AGE
    cert-manager-7dd948954-dwr59                1/1     Running   0          44s
    cert-manager-cainjector-6646674bc8-l4d2c    1/1     Running   0          44s
    cert-manager-webhook-785f6745d8-7kwsd       1/1     Running   0          44s
    ingress-nginx-controller-5486b65c4d-5rk2p   1/1     Running   0          16h
    ingress-nginx-controller-5486b65c4d-5rt5g   1/1     Running   0          16h
    kubectl get svc --namespace ingress-basic
    ---
    NAME                                 TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                      AGE
    cert-manager                         ClusterIP      10.0.149.170

     

     

    Cluster issuer 생성

     

    ClusterIssuer는 cert-manager에서 사용하는 리소스 중 하나로, 클러스터 전체에서 사용할 수 있는 인증서 발급자를 정의합니다. ClusterIssuer는 SSL/TLS 인증서를 자동으로 관리하고 발급하기 위해 ACME 프로토콜(예: Let's Encrypt) 또는 다른 인증서 발급 서비스를 사용할 수 있습니다.

     

    주요 기능

    • 클러스터 범위: ClusterIssuer는 클러스터 내의 모든 네임스페이스에서 사용할 수 있습니다. 
    • ACME 지원: ClusterIssuer는 ACME 프로토콜을 통해 인증서를 발급받을 수 있으며, HTTP-01, DNS-01 등의 챌린지를 통해 도메인 소유권을 검증합니다.
    • 자동화: cert-manager는 ClusterIssuer를 사용하여 인증서의 발급, 갱신 및 관리를 자동화합니다. 이를 통해 사용자는 수동으로 인증서를 관리할 필요가 없어집니다.
    • 비밀 저장: 발급된 인증서는 Kubernetes의 Secret 리소스에 저장되며, 이를 통해 애플리케이션에서 쉽게 사용할 수 있습니다.

    # cluster-issuer.yaml 파일 생성

    apiVersion: cert-manager.io/v1 # cert manager의 api version
    kind: ClusterIssuer # ClusterIssuer는 클러스터 전체에서 사용할 수 있는 인증서 발급자를 정의
    metadata:
      name: letsencrypt # ClusterIssuer의 이름
    spec:
      acme:
        email: 내 이메일 주소@naver.com # 인증서 발급과 관련된 알림을 받을 이메일 주소입니다. 이 주소는 Let's Encrypt에서 인증서 만료 및 계정 문제에 대해 연락하는 데 사용됩니다.
        server: https://acme-v02.api.letsencrypt.org/directory # Let's Encrypt의 ACME 서버 URL입니다. 여기서는 v2 API를 사용하고 있습니다.
        privateKeySecretRef: # 인증서 발급에 필요한 계정의 개인 키를 저장할 Kubernetes Secret 리소스를 지정합니다.
          name: letsencrypt # letsencrypt라는 이름의 Secret 리소스에 개인 키가 저장됩니다.
        # Add a single challenge solver, HTTP01 using nginx
        solvers:
        - http01: # HTTP-01 챌린지를 사용하여 도메인 소유권을 검증
            ingress: # Ingress 리소스를 통해 HTTP-01 챌린지를 처리
              ingressClassName: nginx # nginx는 이 챌린지를 처리할 Ingress 컨트롤러의 클래스 이름입니다. 즉, NGINX Ingress 컨트롤러를 사용하여 HTTP-01 챌린지를 해결합니다.

     

    이 ClusterIssuer 구성은 Let's Encrypt를 통해 SSL/TLS 인증서를 자동으로 발급받기 위해 필요한 설정을 포함하고 있습니다.

    NGINX Ingress 컨트롤러를 사용하여 HTTP-01 챌린지를 처리하며, 발급된 인증서는 지정된 Secret에 저장됩니다.

    이를 통해 Kubernetes 클러스터 내의 애플리케이션에 HTTPS를 쉽게 적용할 수 있습니다.

     

    # 생성

    kubectl apply -f cluster-issuer.yaml

     

    # 확인

    kubectl get clusterissuer
    ---
    NAME          READY   AGE
    letsencrypt   True    26m

     

    kubectl describe clusterissuer letsencrypt
    ---
    Name:         letsencrypt
    Namespace:    
    Labels:       <none>
    Annotations:  <none>
    API Version:  cert-manager.io/v1
    Kind:         ClusterIssuer
    Metadata:
      Creation Timestamp:  2025-02-23T02:38:17Z
      Generation:          1
      Resource Version:    96225
      UID:                 3a265b4d-ff19-4c1f-a5d5-304dfb9e9ea4
    Spec:
      Acme:
        Email: 내 이메일 주소
        Private Key Secret Ref:
          Name:  letsencrypt
        Server:  https://acme-v02.api.letsencrypt.org/directory
        Solvers:
          http01:
            Ingress:
              Ingress Class Name:  nginx
    Status:
      Acme:
        Last Private Key Hash:  gK5ylpDLtf1k5RZOoTcH2UAQf9JZq53XszgVuPZ+dKM=
        Last Registered Email:  내 이메일 주소
        Uri:                    https://acme-v02.api.letsencrypt.org/acme/acct/2244671095
      Conditions:
        Last Transition Time:  2025-02-23T02:38:18Z
        Message:               The ACME account was registered with the ACME server
        Observed Generation:   1
        Reason:                ACMEAccountRegistered
        Status:                True
        Type:                  Ready
    Events:                    <none>

     

     

    애플리케이션 생성 (app1-nginx)

     

    # 01-NginxApp1-Deployment.yaml 파일 작성

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: app1-nginx-deployment
      labels:
        app: app1-nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: app1-nginx
      template:
        metadata:
          labels:
            app: app1-nginx
        spec:
          containers:
            - name: app1-nginx
              image: stacksimplify/kube-nginxapp1:1.0.0
              ports:
                - containerPort: 80

     

    # 01-NginxApp1-Service.yaml 파일 작성

    apiVersion: v1
    kind: Service
    metadata:
      name: app1-nginx-clusterip-service
      labels:
        app: app1-nginx
    spec:
      type: ClusterIP
      selector:
        app: app1-nginx
      ports:
        - port: 80
          targetPort: 80

     

    # 생성

    kubectl apply -f 01-NginxApp1-Deployment.yaml
    kubectl apply -f 01-NginxApp1-Service.yaml

     

    애플리케이션 생성 (app2-nginx)

     

    # 02-NginxApp2-Deployment.yaml 파일 작성

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: app2-nginx-deployment
      labels:
        app: app2-nginx 
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: app2-nginx
      template:
        metadata:
          labels:
            app: app2-nginx
        spec:
          containers:
            - name: app2-nginx
              image: stacksimplify/kube-nginxapp2:1.0.0
              ports:
                - containerPort: 80

     

    # 02-NginxApp2-Service.yaml 파일 작성

    apiVersion: v1
    kind: Service
    metadata:
      name: app2-nginx-clusterip-service
      labels:
        app: app2-nginx
      annotations:
    spec:
      type: ClusterIP
      selector:
        app: app2-nginx
      ports:
        - port: 80
          targetPort: 80

     

    # 생성

    kubectl apply -f 02-NginxApp2-Deployment.yaml
    kubectl apply -f 02-NginxApp2-Service.yaml

     

    Ingress 생성

     

    # 01-Ingress-SSL.yml 파일 작성

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: ingress-ssl
      annotations:
        #kubernetes.io/ingress.class: "nginx"
        cert-manager.io/cluster-issuer: letsencrypt    
    spec:
      ingressClassName: nginx
      rules:
        - host: sapp1.bbiyak.shop
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: app1-nginx-clusterip-service
                    port: 
                      number: 80
        - host: sapp2.bbiyak.shop
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: app2-nginx-clusterip-service
                    port: 
                      number: 80                         
      tls: # tls 설정
      - hosts:
        - sapp1.bbiyak.shop # TLS 설정이 적용될 호스트 이름 나열
        secretName: sapp1-bbiyak-secret # TLS 인증서와 비밀 키가 저장된 Kubernetes 비밀 이름 지정
      - hosts:
        - sapp2.bbiyak.shop
        secretName: sapp2-bbiyak-secret

     

    # 생성

    kubectl apply -f 01-Ingress-SSL.yml

     

     

    확인

     

    # 비밀 및 인증서 생성 확인

    kubectl get secret
    ---
    NAME                        TYPE     DATA   AGE
    azure-config-file           Opaque   1      19h
    sapp1-bbiyak-secret-rwc7c   Opaque   1      2m16s
    sapp2-bbiyak-secret-cf9l2   Opaque   1      2m16s
    kubectl get cert
    ---
    NAME                  READY   SECRET                AGE
    sapp1-bbiyak-secret   True    sapp1-bbiyak-secret   6m25s
    sapp2-bbiyak-secret   True    sapp2-bbiyak-secret   6m25s

     

    certificate 확인 시, ready 상태가 True로 변하면 정상적으로 적용 완료

    5분에서 1시간 정도 걸린다.

     

    # 웹 사이트 접속 후 인증서 확인

     

    https://saap1.bbiyak.shop/app1/index.html 정상 접근 완료

     

     

    https://sapp2.bbiyak.shop/app2/index.html 정상 접근 완료

     

    정리

     

    #  리소스 정리

    kubectl delete -R -F kube-manifests/

     

    kubectl delete ns ingress-basic

    [참고 영상]

    Udemy - Azure Kubernetes Service with Azure DevOps and Terraform

    섹션 15 : Ingress - SSL with Let's Encrypt

     

    [참고 문서]

    https://github.com/stacksimplify/azure-aks-kubernetes-masterclass/tree/master/14-Ingress-SSL-with-LetsEncrypt

    'kubernetes > udemy' 카테고리의 다른 글

    [udemy] Azure Container Registry for AKS  (0) 2025.02.26
    [udemy] Namespace  (0) 2025.02.23
    [udemy] Ingress - ExternalDNS (2)  (0) 2025.02.22
    [udemy] Ingress - ExternalDNS  (0) 2025.02.22
    [udemy] Ingress  (0) 2025.02.18
Designed by Tistory.