Don't think! Just do it!

종합 IT 기술 정체성 카오스 블로그! 이... 이곳은 어디지?

Server services/kubernetes

[kubernetes] Cert manager + Let's encrypt

방피터 2023. 12. 1. 22:40

네이버 클라우드에서

kubernetes로 시스템을 구축했단말이지..

그런데 왠일인지...

로드 발란서에 SSL을 사서 붙여야 하더라구

스타트업이 인증서 살 돈이 어딨어?

그래서 let's encrypt랑 cert-manager로 구축했어.

이 이야기를 하려고 했는데..

지금 살펴보니 😅😅

👇👇👇

Certificate manger

 

Certificate manager 뭔데!

왜 로드 발란서에 붙이기 쉬운건데?

Certificate manager에서 발급받고

로드 발란서에 붙이면 끝이네;;;

공짜고 갱신도 필요없고..

좋긴한데 나는 뻘찟했네 ㅠㅠ

 

아니 분명 없었던거 같은데......🤔


암튼

난 kubernetes에 cert-manager를 설치하고

Let's encrypt에서 발급받아 했어.

그런데 그 과정이 꽤~~

너저분(?)했다고나 할까?

 

전체적으로 간단하게 설명하면 이래.

 

1. cert-manager가 let's encrypt에 인증서를 요청햇!

2. let's encrypt는 도메인의 소유주를 확인하기 위한 키를 발급햇!

3. 그 키를 cert-manager가 dns 서버에 등록햇!

4.  let's encrypt에 도메인이 확인되면 인증서를 발급햇!

5. cert-manager가 인증서를 잘 저장햇!

6. cert-manager가 동일한 방법으로 3개월마다 자동 갱신햇!

쿠버네티스에서 let's encrypt와 cert-manager로 뻘짓하는 과정

 

이 때 DNS에 접근할 수 있는 권한을 Cert-manager에 줘야 해.

이런 방식을 DNS01이라고 하는데

아래가 Cert-manager에서 DNS01이 가능한 아이들 목록이야.

여기서 현실적으로 가능한 게 Google DNS 뿐이 없더라구..

dns01

(참고로 HTTP01 방식이 훨씬 쉽게 동작하지만 와일드 카드가 안됨)

그래서 후이즈에 있는 도메인의 dns를 gcp dns로 설정하고

gcp iam에서 Cert-manager가 사용할 dns01-solver라는 이름의 롤도 하나 만들어 줬어.

iam dns administrator

 

이 다음에는 아래의 명령으로 key 파일을 생성하고

gcloud iam service-accounts keys create key.json \
   --iam-account dns01-solver@$PROJECT_ID.iam.gserviceaccount.com

 

그걸로 다시 kubernetes에 secret을 만들지.

kubectl create secret generic clouddns-dns01-solver-svc-acct \
   --from-file=key.json

 

그 다음에는 인증서가 저장될 secret을 하나 더 만들고~

# secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: istio-tls
  namespace: istio-system
type: kubernetes.io/tls
stringData:
  tls.key: ""
  tls.crt: ""

 

이젠 issuer를 만들고

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod-dns01
  namespace: istio-system
spec:
  acme:
    # The ACME server URL
    server: https://acme-v02.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: "너의 이메일!"
    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
      name: letsencrypt-prod-dns01
    # Enable the HTTP-01 challenge provider
    solvers:
    - dns01:
        cloudDNS:
          # The ID of the GCP project
          project: "너의 프로젝트"
          # This is the secret used to access the service account
          serviceAccountSecretRef:
            name: clouddns-dns01-solver-svc-acct
            key: key.json

 

Issuer가 정상적으로 생성되고 나면 Certificate를 만들어 마무으리!

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: test-domain-certificate
  namespace: istio-system
spec:
  dnsNames:
    - "*.test.domain"
    - "test.domain"
  secretName: istio-tls
  issuerRef:
    name: letsencrypt-prod-dns01
    kind: ClusterIssuer

 

보통 1-2분? 정도 안에 인증서 발급이 마무리 되는 것 같아.

 

이렇게 보면 심플해보이는데..

여러가지 문제들 때문에 꽤 애를 먹었어.

👇👇👇

 

1. kubernetes DNS 문제

cert-manager가 acme 셀프 체크를 하다가 실패하는 경우가 있는데

cert-manager에 기본적으로 등록된 네임서버가 도메인을 못찾아서 그렇데.

그래서 아래처럼 설치할 때 도메인 서버를 지정하면 해결돼.

helm install cert-manager jetstack/cert-manager  --namespace cert-manager --create-namespace --version v1.12.0  --set installCRDs=true --set 'extraArgs={--dns01-recursive-nameservers-only,--dns01-recursive-nameservers=8.8.8.8:53\,1.1.1.1:53}'

 

2. CRDs

음.. 잘 기억이 안나는데..

resource type 에러? 비슷한게 나오면

아래와 같이 Cert-manager의 CRDs를 설치해주면 해결돼.

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

 

이 외에는 딱히 큰 오류가 없었는데

그럼에도 불구하고

인증서가 잘 발급되어지지 않는다면

아래와 같은 명령들로 어디서 오류가 났는지 확인할 수 있어.

k get certificate -n istio-system #인증서 보기

k get clusterissuer -n istio-system #이슈어 보기

k describe clusterissuer letsencrypt-prod-dns01 #이슈어 자세히 보기

k get certificaterequest -n istio-system #인증서 요청 보기

k describe certificaterequest -n istio-system #인증서 요청 자세히 보기

k get order -n istio-system #order

k describe order testx-main-certificate-jn6hn-115670144 -n istio-system #order 자세히

k describe challenge #challenge 자세히 보기

 

그리고 뭐가 진짜 잘 안된다 그러면!

아래 링크를 참고해.

생각보다 트러블 슈팅이 자세하게 잘 나와 있어.

https://cert-manager.io/docs/troubleshooting/acme/

 

Troubleshooting Problems with ACME / Let's Encrypt Certificates

Learn how to diagnose problems if cert-manager fails to renew ACME / Let's Encrypt Certificates.

cert-manager.io

 

또 한가지 주의할 점은!

lets encrypt에 요청할 수 있는 인증서, 오더, 챌린지 수에 제한이 있어.

그러니까 너무 많이 인증서를 요청하면 같은 도메인으로 인증서 발급이 제한될 수 있는거지.

그래서 보통 staging 환경에서 인증서를 테스트해보고

그 다음에 production 인증서를 발급받는게 정석임.

뭐 별다른 건 없고 issuer 만들 때 staging 서버에 요청하면 돼.

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging-dns01
  namespace: istio-system
spec:
  acme:
    # The ACME server URL 여기여기여기여기여기여기여기여기가 Staging 서버 주소~!!!!!!!
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: "제발 너의 이메일~~~~~"
    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
      name: letsencrypt-staging-dns01
    # Enable the HTTP-01 challenge provider

    solvers:
    - dns01:
        cloudDNS:
          # The ID of the GCP project
          project: "프로젝트 id"
          # This is the secret used to access the service account
          serviceAccountSecretRef:
            name: clouddns-dns01-solver-svc-acct
            key: key.json

 

아래 링크를 참고해!

https://letsencrypt.org/docs/staging-environment/

 

Staging Environment - Let's Encrypt

 

letsencrypt.org

 

아이고 길다~~~
걍 네이버 인증서 쓰자!

 

안녕

반응형