-
[udemy] Ingress - SSL with Let's Encryptkubernetes/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
[참고 문서]
'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