cert-manger로
Let's encrypt 인증서 생성
- 온프레미스 환경
이 문서는 쿠버네티스 설치, 도메인 설정, cert-manager 설치를 다루지 않습니다.
개요
 사용이유
▪ self-signed 인증서의 불편함
▪ 인증기관의 인증서가 아니면 수동설정이 빈번
서비스
① self-signed 인증서로 통신할게!
오픈소스
② 거절
③ 클라이언트 설정 ④ 오픈소스 설정
예상보다 많은 시간을 잡아먹음
 사용이유
▪ Let's encrypt에서 무료 인증서 발급해주고
▪ cert-manager에서 인증서 생성&관리
acme 프로토콜 통신
이게 뭐지?
① ssl인증서 신청
② ssl인증서 생성
 장점
▪ yaml파일로 인증서 생성&관리
▪ 인증서 만료 전 자동 갱신
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-test
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/issuer: "prod"
spec:
tls:
- hosts:
- abcd.choilab.xyz
secretName: stage-test-prod-1
rules:
- host: abcd.choilab.xyz
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-test
port:
number: 80
virtualbox
kubernetes
cert-manager
① ssl인증서 신청
② ssl인증서 생성
도메인 관리
③ 인증서
사용
 인증서 생성과정 요약
▪ 도메인 관리: 가비아
▪ 네임서버 관리: cloudflare
▪ 인증서 생성: let's encrypt
▪ 쿠버네티스 인증서 관리: cert-manager
 사용자 요청처리 요약
virtualbox
kubernetes
cert-manager
Client
① helloworld.com
IP 질의
② 집공유기 IP리턴
③ 서비스 요청
④ 포트포워딩
⑤ 응답
① 사용자가 요청한 도메인(예: helloworld.com)에 대한 IP질의
② 도메인에 해당하는 IP리턴(이 실습에서는 집 공유기 IP사용)
③ IP로 서비스를 요청하면 공유기가 쿠버네티스 ingress로 포트포워딩
④ ingress는 서비스를 처리하고 응답
집공유기
cert-manager 컴퍼넌트
 컴퍼넌트
① Issuer: 인증서 주체
② certificates: 인증서 정의
③ secret: 발급된 인증서와 비밀키 저장
①
②
③
※ 공식문서: https://cert-manager.io/docs/
 컴퍼넌트
※ self-signed issuer: https://cert-manager.io/docs/configuration/selfsigned/
▪ 대표적인 2개 Issuer: self-signed, let's encrypt
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-issuer
namespace: sandbox
spec:
selfSigned: {}
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-staging
spec:
acme:
# The ACME server URL
server: https://acme-staging-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: user@example.com
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-staging
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
class: nginx
<self-signed issuer>
<let's encrypt issuer>
※ let's encrypt issuer: https://cert-manager.io/docs/tutorials/acme/ingress/#step-6-configure-let-s-encrypt-issuer
 컴퍼넌트
▪ issuer는 issuer와 clusterissuer로 분류
▪ issuer: 같은 namespace만 인증서 참조 가능
▪ clusterissuer: 모든 namespace에서 참조 가능
 컴퍼넌트
※ 공식문서: https://cert-manager.io/docs/tutorials/acme/ingress/#step-6-configure-let-s-encrypt-issuer
▪ Issuer은 stage, prod환경으로 분리
▪ stage: 테스트
▪ prod: 운영
 컴퍼넌트
※ 공식문서: https://cert-manager.io/docs/concepts/certificate/
▪ certificates는 인증서 발급에 대한 명세를 정의
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: acme-crt
spec:
secretName: acme-crt-secret
dnsNames:
- foo.example.com
- bar.example.com
issuerRef:
name: letsencrypt-prod
# We can reference ClusterIssuers by changing the kind here.
# The default value is Issuer (i.e. a locally namespaced Issuer)
kind: Issuer
group: cert-manager.io
let's encrypt 인증서 발급
virtualbox
kubernetes
cert-manager
① ssl인증서 신청
② ssl인증서 생성
도메인 발급
③ 인증서
사용
 준비
▪ 외부접속이 가능한 쿠버네티스 클러스터
▪ nginx-ingress
▪ service-type: loadbalancer
▪ 온프레미스는 metaLB사용
▪ 도메인
▪ cloudflare 네임서버 연동
 준비
▪ cloudflare api token을 생성하고 쿠버네티스 secret에 저장
※ toekn생성 공식문서: https://cert-manager.io/docs/configuration/acme/dns01/cloudflare/#api-keys
apiVersion: v1
kind: Secret
metadata:
name: cloudflare-api-key-secret
type: Opaque
stringData:
api-key: <API Key>
 Issuer 발급
※ git wiki: https://github.com/choisungwook/portfolio/wiki/cert-manager-letsencrypt
▪ stage, prod clusterissuer발급
▪ 이메일 수정
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
# The ACME server URL
server: https://acme-staging-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: <your@email>
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-staging
# Enable the challenge provider
solvers:
- dns01:
cloudflare:
email: <your-email>
apiTokenSecretRef:
name: cloudflare-api-token-secret
key: api-token
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: <your@email>
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-prod
# Enable the challenge provider
solvers:
- dns01:
cloudflare:
email: <your-email>
apiTokenSecretRef:
name: cloudflare-api-token-secret
key: api-token
 Issuer 발급
▪ 발급확인: READY상태가 True
 deployment, 서비스 생성
▪ 요청을 처리할 pod, svc생성
▪ pod의 이미지는 nginx:latest사용
kubernetes
cert-manager
② ssl인증서 생성
※ git wiki: https://github.com/choisungwook/portfolio/wiki/cert-manager-letsencrypt#%EC%9D%B8%EC%A6%9D%EC%84%9C-
%EC%A0%81%EC%9A%A9-%EC%98%88%EC%A0%9C
 인증서 발급과 ingress 연동
▪ 인증서를 만들고 -> 저장된 인증서 secret을 ingress에 적용
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: acme-crt
spec:
secretName: acme-crt-secret
...
kubernetes
cert-manager
① ssl인증서 생성
② 인증서
사용 apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-test
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
tls:
- hosts:
- test.choilab.xyz
secretName: acme-crt-secret
...
 인증서 발급과 ingress 연동
▪ 도메인 생성
 인증서 발급과 ingress 연동
▪ certificate 실행
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: stage-test221
spec:
secretName: stage-test221
issuerRef:
name: test-staging
kind: ClusterIssuer
commonName: 'choilab.xyz'
dnsNames:
- choilab.xyz
- test3.choilab.xyz
▪ certificate Ready가 True인지 확인
 인증서 발급과 ingress 연동
▪ ingress 생성
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-test221
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
tls:
- hosts:
- test3.choilab.xyz
secretName: stage-test221
rules:
- host: test3.choilab.xyz
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: nginx-test6
port:
number: 80
 인증서 발급과 ingress 연동
▪ ingress 도메인에 접속하면 경고 페이지 표시
▪ let's encrypt stage환경은 테스트 목적이기 때문에 인증된 인증서 발급 X
▪ 발급자를 보면 (STAGING) ...으로 표시
 stage 설정을 prod로 이동
▪ 기존 ingress는 삭제
▪ prod-clusterissuer을 사용하여 certificate 생성
▪ prod-certificate이 True이면 ingress생성
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: prod-test221
spec:
secretName: prod-test221
issuerRef:
name: test-prod
kind: ClusterIssuer
commonName: 'choilab.xyz'
dnsNames:
- choilab.xyz
- test3.choilab.xyz
<prod-certificate>
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prod-nginx-test221
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
tls:
- hosts:
- test3.choilab.xyz
secretName: prod-test221
rules:
- host: test3.choilab.xyz
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: nginx-test6
port:
number: 80
<prod-ingress>
 stage 설정을 prod로 이동
▪ ingress 접속하여 경고창이 안뜨는지 확인
▪ 인증서 발급자 확인
 인증서 발급과 ingress 연동
▪ 두 단계를 통합하는 방법 존재
kubernetes
cert-manager
인증서 생성과 사용
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-test
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/issuer: "<clusterissuername>"
spec:
tls:
- hosts:
- test.domain
secretName: test-secret # 인증서를 저장할 secret이름
rules:
- host: test.domain
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: nginx-test
port:
number: 80
 인증서 발급과 ingress 연동
▪ clusterissuer는 되었다가 안되었다가 해서... Issuer로 진행
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-test
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/issuer: "issuer-prod-1"
spec:
tls:
- hosts:
- test.domain
secretName: test-secret # 인증서를 저장할 secret이름
rules:
- host: test.domain
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: nginx-test
port:
number: 80
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: issuer-prod-1
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: <cloudflare email>
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: issuer-prod-1
# Enable the challenge provider
solvers:
- dns01:
cloudflare:
email: <cloudflare email>
apiTokenSecretRef:
name: cloudflare-api-token-secret #cloudflare api token
key: api-token
<issuer> <nginx ingress>
참고자료
 참고자료
▪ 가비아 로고: https://www.gabia.com/
▪ cloudflare 로고: https://www.cloudflare.com/logo/
▪ let's encrypt 로고: https://letsencrypt.org/ko/trademarks/
▪ flaticon
▪ 라우터: https://www.flaticon.com/free-icon/wireless-router_2743461

cert-manager로 let's encrypt 인증서 발급

  • 1.
    cert-manger로 Let's encrypt 인증서생성 - 온프레미스 환경 이 문서는 쿠버네티스 설치, 도메인 설정, cert-manager 설치를 다루지 않습니다.
  • 2.
  • 3.
     사용이유 ▪ self-signed인증서의 불편함 ▪ 인증기관의 인증서가 아니면 수동설정이 빈번 서비스 ① self-signed 인증서로 통신할게! 오픈소스 ② 거절 ③ 클라이언트 설정 ④ 오픈소스 설정 예상보다 많은 시간을 잡아먹음
  • 4.
     사용이유 ▪ Let'sencrypt에서 무료 인증서 발급해주고 ▪ cert-manager에서 인증서 생성&관리 acme 프로토콜 통신 이게 뭐지? ① ssl인증서 신청 ② ssl인증서 생성
  • 5.
     장점 ▪ yaml파일로인증서 생성&관리 ▪ 인증서 만료 전 자동 갱신 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-test annotations: kubernetes.io/ingress.class: "nginx" cert-manager.io/issuer: "prod" spec: tls: - hosts: - abcd.choilab.xyz secretName: stage-test-prod-1 rules: - host: abcd.choilab.xyz http: paths: - path: / pathType: Prefix backend: service: name: nginx-test port: number: 80
  • 6.
    virtualbox kubernetes cert-manager ① ssl인증서 신청 ②ssl인증서 생성 도메인 관리 ③ 인증서 사용  인증서 생성과정 요약 ▪ 도메인 관리: 가비아 ▪ 네임서버 관리: cloudflare ▪ 인증서 생성: let's encrypt ▪ 쿠버네티스 인증서 관리: cert-manager
  • 7.
     사용자 요청처리요약 virtualbox kubernetes cert-manager Client ① helloworld.com IP 질의 ② 집공유기 IP리턴 ③ 서비스 요청 ④ 포트포워딩 ⑤ 응답 ① 사용자가 요청한 도메인(예: helloworld.com)에 대한 IP질의 ② 도메인에 해당하는 IP리턴(이 실습에서는 집 공유기 IP사용) ③ IP로 서비스를 요청하면 공유기가 쿠버네티스 ingress로 포트포워딩 ④ ingress는 서비스를 처리하고 응답 집공유기
  • 8.
  • 9.
     컴퍼넌트 ① Issuer:인증서 주체 ② certificates: 인증서 정의 ③ secret: 발급된 인증서와 비밀키 저장 ① ② ③ ※ 공식문서: https://cert-manager.io/docs/
  • 10.
     컴퍼넌트 ※ self-signedissuer: https://cert-manager.io/docs/configuration/selfsigned/ ▪ 대표적인 2개 Issuer: self-signed, let's encrypt apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: selfsigned-issuer namespace: sandbox spec: selfSigned: {} apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: letsencrypt-staging spec: acme: # The ACME server URL server: https://acme-staging-v02.api.letsencrypt.org/directory # Email address used for ACME registration email: user@example.com # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt-staging # Enable the HTTP-01 challenge provider solvers: - http01: ingress: class: nginx <self-signed issuer> <let's encrypt issuer> ※ let's encrypt issuer: https://cert-manager.io/docs/tutorials/acme/ingress/#step-6-configure-let-s-encrypt-issuer
  • 11.
     컴퍼넌트 ▪ issuer는issuer와 clusterissuer로 분류 ▪ issuer: 같은 namespace만 인증서 참조 가능 ▪ clusterissuer: 모든 namespace에서 참조 가능
  • 12.
     컴퍼넌트 ※ 공식문서:https://cert-manager.io/docs/tutorials/acme/ingress/#step-6-configure-let-s-encrypt-issuer ▪ Issuer은 stage, prod환경으로 분리 ▪ stage: 테스트 ▪ prod: 운영
  • 13.
     컴퍼넌트 ※ 공식문서:https://cert-manager.io/docs/concepts/certificate/ ▪ certificates는 인증서 발급에 대한 명세를 정의 apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: acme-crt spec: secretName: acme-crt-secret dnsNames: - foo.example.com - bar.example.com issuerRef: name: letsencrypt-prod # We can reference ClusterIssuers by changing the kind here. # The default value is Issuer (i.e. a locally namespaced Issuer) kind: Issuer group: cert-manager.io
  • 14.
  • 15.
    virtualbox kubernetes cert-manager ① ssl인증서 신청 ②ssl인증서 생성 도메인 발급 ③ 인증서 사용  준비 ▪ 외부접속이 가능한 쿠버네티스 클러스터 ▪ nginx-ingress ▪ service-type: loadbalancer ▪ 온프레미스는 metaLB사용 ▪ 도메인 ▪ cloudflare 네임서버 연동
  • 16.
     준비 ▪ cloudflareapi token을 생성하고 쿠버네티스 secret에 저장 ※ toekn생성 공식문서: https://cert-manager.io/docs/configuration/acme/dns01/cloudflare/#api-keys apiVersion: v1 kind: Secret metadata: name: cloudflare-api-key-secret type: Opaque stringData: api-key: <API Key>
  • 17.
     Issuer 발급 ※git wiki: https://github.com/choisungwook/portfolio/wiki/cert-manager-letsencrypt ▪ stage, prod clusterissuer발급 ▪ 이메일 수정 apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-staging spec: acme: # The ACME server URL server: https://acme-staging-v02.api.letsencrypt.org/directory # Email address used for ACME registration email: <your@email> # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt-staging # Enable the challenge provider solvers: - dns01: cloudflare: email: <your-email> apiTokenSecretRef: name: cloudflare-api-token-secret key: api-token apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: # The ACME server URL server: https://acme-v02.api.letsencrypt.org/directory # Email address used for ACME registration email: <your@email> # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt-prod # Enable the challenge provider solvers: - dns01: cloudflare: email: <your-email> apiTokenSecretRef: name: cloudflare-api-token-secret key: api-token
  • 18.
     Issuer 발급 ▪발급확인: READY상태가 True
  • 19.
     deployment, 서비스생성 ▪ 요청을 처리할 pod, svc생성 ▪ pod의 이미지는 nginx:latest사용 kubernetes cert-manager ② ssl인증서 생성 ※ git wiki: https://github.com/choisungwook/portfolio/wiki/cert-manager-letsencrypt#%EC%9D%B8%EC%A6%9D%EC%84%9C- %EC%A0%81%EC%9A%A9-%EC%98%88%EC%A0%9C
  • 20.
     인증서 발급과ingress 연동 ▪ 인증서를 만들고 -> 저장된 인증서 secret을 ingress에 적용 apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: acme-crt spec: secretName: acme-crt-secret ... kubernetes cert-manager ① ssl인증서 생성 ② 인증서 사용 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-test annotations: kubernetes.io/ingress.class: "nginx" spec: tls: - hosts: - test.choilab.xyz secretName: acme-crt-secret ...
  • 21.
     인증서 발급과ingress 연동 ▪ 도메인 생성
  • 22.
     인증서 발급과ingress 연동 ▪ certificate 실행 apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: stage-test221 spec: secretName: stage-test221 issuerRef: name: test-staging kind: ClusterIssuer commonName: 'choilab.xyz' dnsNames: - choilab.xyz - test3.choilab.xyz ▪ certificate Ready가 True인지 확인
  • 23.
     인증서 발급과ingress 연동 ▪ ingress 생성 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-test221 annotations: kubernetes.io/ingress.class: "nginx" spec: tls: - hosts: - test3.choilab.xyz secretName: stage-test221 rules: - host: test3.choilab.xyz http: paths: - pathType: Prefix path: "/" backend: service: name: nginx-test6 port: number: 80
  • 24.
     인증서 발급과ingress 연동 ▪ ingress 도메인에 접속하면 경고 페이지 표시 ▪ let's encrypt stage환경은 테스트 목적이기 때문에 인증된 인증서 발급 X ▪ 발급자를 보면 (STAGING) ...으로 표시
  • 25.
     stage 설정을prod로 이동 ▪ 기존 ingress는 삭제 ▪ prod-clusterissuer을 사용하여 certificate 생성 ▪ prod-certificate이 True이면 ingress생성 apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: prod-test221 spec: secretName: prod-test221 issuerRef: name: test-prod kind: ClusterIssuer commonName: 'choilab.xyz' dnsNames: - choilab.xyz - test3.choilab.xyz <prod-certificate> apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: prod-nginx-test221 annotations: kubernetes.io/ingress.class: "nginx" spec: tls: - hosts: - test3.choilab.xyz secretName: prod-test221 rules: - host: test3.choilab.xyz http: paths: - pathType: Prefix path: "/" backend: service: name: nginx-test6 port: number: 80 <prod-ingress>
  • 26.
     stage 설정을prod로 이동 ▪ ingress 접속하여 경고창이 안뜨는지 확인 ▪ 인증서 발급자 확인
  • 27.
     인증서 발급과ingress 연동 ▪ 두 단계를 통합하는 방법 존재 kubernetes cert-manager 인증서 생성과 사용 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-test annotations: kubernetes.io/ingress.class: "nginx" cert-manager.io/issuer: "<clusterissuername>" spec: tls: - hosts: - test.domain secretName: test-secret # 인증서를 저장할 secret이름 rules: - host: test.domain http: paths: - pathType: Prefix path: "/" backend: service: name: nginx-test port: number: 80
  • 28.
     인증서 발급과ingress 연동 ▪ clusterissuer는 되었다가 안되었다가 해서... Issuer로 진행 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-test annotations: kubernetes.io/ingress.class: "nginx" cert-manager.io/issuer: "issuer-prod-1" spec: tls: - hosts: - test.domain secretName: test-secret # 인증서를 저장할 secret이름 rules: - host: test.domain http: paths: - pathType: Prefix path: "/" backend: service: name: nginx-test port: number: 80 apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: issuer-prod-1 spec: acme: # The ACME server URL server: https://acme-v02.api.letsencrypt.org/directory # Email address used for ACME registration email: <cloudflare email> # Name of a secret used to store the ACME account private key privateKeySecretRef: name: issuer-prod-1 # Enable the challenge provider solvers: - dns01: cloudflare: email: <cloudflare email> apiTokenSecretRef: name: cloudflare-api-token-secret #cloudflare api token key: api-token <issuer> <nginx ingress>
  • 29.
  • 30.
     참고자료 ▪ 가비아로고: https://www.gabia.com/ ▪ cloudflare 로고: https://www.cloudflare.com/logo/ ▪ let's encrypt 로고: https://letsencrypt.org/ko/trademarks/ ▪ flaticon ▪ 라우터: https://www.flaticon.com/free-icon/wireless-router_2743461