Kubernetes에 올라가 있는 웹에 https로 통신해야 하는 경우 Let’s Encrypt 인증서를 발급하고 적용할 수 있다. 해당 테스트에서는 Nginx Ingress Controller를 사용해서 테스트 합니다.
와일드카드 인증서를 발급할 경우 DNS01 문서를 참조해주세요
사전 준비
- Nginx Controoler 설치
- 테스트 용도의 Pod 또는 Deployment와 Cluster IP 타입의 Service 생성
Helm으로 Cert-Manager 설치하기
- Cert-Manager는 Kubernetes 클러스터 내에서 SSL/TLS 인증서를 관리하는 도구(컨트롤러)
- 사용자와 Provider(letsencrypt) 중간에서 중계 역할
- Kubernetes에 배포될 때 cert-manager는 자동으로 ingress controller에 필요한 인증서를 발급하고 인증서가 유효하고 최신 상태인지 확인
- 인증서의 만료 날짜를 추적하고 구성된 시간 간격으로 갱신을 시도
- 자세한 내용은 다음 Helm 공식 링크에서 확인 가능합니다.
1. Helm Repository를 추가합니다.
helm repo add jetstack https://charts.jetstack.io
2. 로컬 helm chart repository를 업데이트 합니다.
helm repo update
3. CRD(CustomResourceDefinitions)를 설치합니다.
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.0/cert-manager.crds.yaml
4. cert-manager를 설치합니다.
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.12.0 \
# --set installCRDs=true
ClusterIssuer 생성
- Issuer와 ClusterIssuer는 Cert-Manager에서 사용되는 인증서 발급을 구성하는 리소스
- 인증서 발급을 위한 정보와 설정을 제공하는 역할
- Issuer와 ClusterIssuer는 다양한 인증서 발급 기술(ACME, Vault, Self-Signed 등)을 지원하며, 각각의 리소스는 해당 기술에 필요한 구성을 포함합니다. 예를 들어, ACME Issuer는 Let's Encrypt와 같은 ACME 서버와 통신하여 인증서를 자동으로 발급 및 갱신할 수 있습니다.
- 자세한 내용은 다음 링크에서 확인 가능
1) Issuer
- Kubernetes 네임스페이스에 속하는 리소스로, 네임스페이스 내의 리소스에 대한 인증서를 발급
- 네임스페이스 범위에서 작동하기 때문에, 동일한 네임스페이스 내의 리소스에 대한 인증서 발급을 관리
2) ClusterIssuer
- 전체 클러스터 범위에서 동작하는 리소스
- 클러스터 내의 모든 네임스페이스에 대한 인증서를 발급
- ClusterIssuer는 여러 네임스페이스에서 사용되는 인증서를 관리할 때 유용
- 예: Ingress 리소스
ACME가 무엇인가요?
- Automatic Certificate Management Environment의 약자로, SSL/TLS 인증서를 자동으로 발급하고 관리하기 위한 프로토콜
- 가장 널리 사용되는 ACME 구현체는 Let’s Encrypt
- ACME 프로토콜을 사용하면 Let’s Encrypt와 같은 인증기관과 클라이언트(예: Cert-Manager) 간에 자동으로 인증서 발급 및 갱신을 처리
Let’s Encrypt ClusterIssuer발급 시 Staging 서버와 Prod 서버 2가지가 존재합니다.
1) Staging 서버
- 개발 및 테스트 환경에서는 일반적으로 staging 서버를 사용
- Staging 서버는 실제 운영 환경과 유사한 기능을 제공하지만, 발급된 인증서는 실제로 인증되지 않음
- 이는 인증서를 테스트하고 애플리케이션 통합하는 데 유용
- Staging 서버를 사용하여 인증서를 발급할 때는 발급 제한이나 제약이 적용되지 않기 때문에 테스트 및 개발 목적으로 자주 사용
// 예시 코드
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
# You must replace this email address with your own.
# Let's Encrypt will use this to contact you about expiring
# certificates, and issues related to your account.
email: user@example.com
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Secret resource that will be used to store the account's private key.
name: example-issuer-account-key
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx
2) Prod 서버
- 실제 운영 환경에서는 prod서버를 사용해야 함
- Prod 서버는 실제로 인증되고 신뢰할 수 있는 인증서를 발급
- Prod 서버를 사용할 때 발급 제한이 있으므로, 실제 운영 환경에서 사용하기 전에는 충분한 테스트와 검증을 거쳐야 함
// 예제 코드
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
1. 본인은 다음과 같이 코드를 배포하여 ClusterIssuer와 Secret을 설치했습니다.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-issuer
spec:
acme:
# You must replace this email address with your own.
# Let's Encrypt will use this to contact you about expiring
# certificates, and issues related to your account.
email: <E-mail주소 기입>
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Secret resource that will be used to store the account's private key.
name: letsencrypt-issuer-account-key
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx
2. ClusterIssuer와 Secret 생성을 확인 합니다.
Ingress 생성
- ingress생성 시 기존에 생성해 두었던 ClusterIssuer와 Secret 값을 등록하면 자동적으로 Certificate도 생성됩니다.
- cert-manager와 관련된 annotations은 다음 링크에서 확인 가능합니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-issuer
name: nuri-ingress
namespace: nuri
spec:
ingressClassName: nginx
rules:
- host: "hello.balance.gaonnuri.site"
http:
paths:
- backend:
service:
name: nuri-service
port:
number: 80
path: /
pathType: Prefix
tls:
- hosts:
- "hello.balance.gaonnuri.site"
secretName: letsencrypt-issuer-account-key
Ingress와 Certificate가 제대로 생성되었는지 확인합니다.
kubectl get ing -n <Namespace>
kubectl get certificate -n <Namespace>
Cert-Manager 인증서 발급 메커니즘
- cert-manager는 사용자가 정의한 명세(ClusterIssuer, Certificate)를 Let’s Encrypt에 전송
- Let’s Encrypt는 여러가지 검증을 수행하고 인증서를 발급
- cert-manager는 발급받은 인증서를 secret 리소스에 저장
Cert-Manager ACME 인증 메커니즘
- Ingress 생성 시 자동으로 함께 Certificate가 생성되고 이 때 Certificaterequest도 함께 생성되면서 letsencrypt로 인증서 발급을 요청
- Let’s Encrypt는 사용자가 요청한 도메인의 소유자가 사용자 것이 맞는지 검사(acme challenge)
- 검사 방법은 2가지가 존재합니다.(challengeType : http01, dns01)
1) http01
- ACME 인증을 위해 HTTP 프로토콜을 사용하는 방법
- 가장 일반적으로 사용하는 유형
- 80번 포트가 방화벽에서 차단되어 있는 경우 DNS방식 사용
2) dns01
- ACME 인증을 위해 DNS TXT레코드를 사용하는 방법
- 와일드 카드 인증서를 발행할 수 있도록 해줌
- Let’s Encrypt가 ACME 클라이언트에 토큰을 제공하면 클라이언트는 해당 토큰과 계정 키에서 파생된 TXT 레코드를 생성
참조 링크
'Kubernetes' 카테고리의 다른 글
[Kubernetes] Kubernetes 버전 업그레이드 시 주의사항 (0) | 2025.01.20 |
---|---|
[Kubernetes] Nginx Controller에 Let’s Encrypt 인증서 등록(DNS01) (0) | 2025.01.20 |
[Kubernetes] Pod 또는 Deployment 생성 시 주의 사항 (0) | 2025.01.20 |