목차
안녕하세요!. 이 글은 쿠버네티스 cert-manager을 이용하여 let's encrypt 인증서를 발급하는 과정을 소개합니다. 실습환경은 온프레미스에서 진행합니다.
쿠버네티스, 인프라 구성 방법, Let's encrypt에 대한 설명은 생략합니다.
0) 실습문서 링크
- 영상 pdf: https://drive.google.com/file/d/1SbeXUT73uuBpdVkwa03u5hPSP5LHThpC/view?usp=sharing
- git 위키: https://github.com/choisungwook/portfolio/wiki/cert-manager-letsencrypt
1) 준비
■ 외부통신이 되는 쿠버네티스 클러스터
Let's encrypt 인증서를 발급하기 위해서는 Let's encrypt와 통신해야 하므로 폐쇄망은 실습이 불가능합니다.
■ 도메인
ssl인증서가 인증할 도메인이 필요합니다. 저는 가비아에서 xyz도메인을 약 2000원 주고 구매했습니다.
■ 네임서버
도메인을 관리하는 네임서버가 필요하고 cert-manager와 연동이 되야 합니다. 쉽게 사용할 수 있는 cloudflare을 사용했습니다.
■ 네임서버 액세스 토큰
이 실습은 cert-manager dns-01 solver을 사용하므로 액세스 토큰이 필요합니다. 저는 cloudflare 액세스토큰을 사용했습니다. 액세스토큰을 발급할 때 공식문서에 언급된 권한(예: cloudflare-https://cert-manager.io/docs/configuration/acme/dns01/cloudflare/#api-keys)을 설정해야 합니다.
■ cert-manager 설치
cert-manager가 설치되어 있어야 합니다.
2) 실습환경
제가 실습한 인프라는 [그림 1]과 같습니다.
- 쿠버네티스는 virtualbox안에 VM으로 구성했습니다.
- 제가 구매한 도메인은 공유기의 공인IP를 가르킵니다.
- ingress controller은 nginx ingress를 사용했고 공유기 80번포트로 포트포워딩 되어 있습니다.
3) cert-manger 특징
쉬운 인증서 생성과 만료전 자동갱신 특징이 있습니다.
- cert-manager는 yaml로 쉽게 인증서를 생성하고 관리합니다. 실습영상 https://youtu.be/jkAlpv4WAUg?t=255 을 보면 yaml파일을 kubectl로 실행하여 인증서를 쉽게 생성합니다.
- 인증서가 만료되기 전 자동갱신을 수행합니다.
4) cert-manager가 let's encrypt인증서를 생성하는 과정 요약
cert-manager는 사용자와 프로바이더(provider) 중간에서 중계 역할을 수행합니다. 인증서가 생서되면 쿠버네티스 secret리소스에 저장합니다.
- cert-manager는 사용자가 정의한 명세(issuer, certificate 커스텀리소스)를 Let's encrypt에 전송합니다.
- Let's encrypt는 사용자 여러가지 검증을 수행하고 인증서를 발급해줍니다.
- cert-manager는 발급받은 인증서를 secret리소스에 저장합니다.
cert-manager는 인증서 발급과정 커스텀리소스로 관리합니다. kubectl describe을 사용하여 각 단계 로그를 자세히 볼 수 있습니다.
- Certificate는 발급받을 인증서 명세가 있는 커스텀리소스입니다. 사용자가 yaml파일로 certificate를 생성합니다.
- Certficate를 kubectl로 실행하면 Certificaterequest가 생성되고 let's encrypt로 인증서 발급을 요청됩니다.
- let's encrypt는 사용자가 요청한 도메인의 소유자가 사용자 것이 맞는지 검사(acme challenge)를 합니다. 검사 방법(solver)은 http, dns-01방법이 있습니다. Order, Challenge검사 단계를 관리하는 커스텀리소스입니다.
이 문서에서는 dns-01 solver를 사용합니다.
5) cert-manager 컴퍼넌트
컴퍼넌트는 크게 3개로 분류됩니다.
① Issuers
인증서 발급 주체입니다. self-signed, let's encrypt등이 있습니다.
■ let's encrypt issuer
let's encrypt를 사용하면 staging, prod 2개의 Issuer가 있습니다. staging은 테스트용도 prod는 실제 운영단계 적용목적으로 사용됩니다. staging환경에서 발급된 인증서는 self-sisgned인증서처럼 인증되어 있지 않습니다.
■ namespace 적용 범위
Issuer을 모든 namespace에 사용하려면 clussterIssuer, 특정 namespace에서만 사용하려면 Issuer을 사용하면 됩니다.
② certificates
인증서가 인증할 도메인 정보 등 인증서 명세를 정의합니다.
③ kubernetes secrets
Let's encrypt가 발급한 인증서는 쿠버네티스 secret 리소스에 저장됩니다.
6) 인증서 생성 실습
이 문서에서는 네임서버를 사용하여 도메인 소유검증(acme challenge)을 완료합니다. clusterissuer가 생성되면 cert-manager namespace의 secret에 저장됩니다.
① Issuer생성
■ 네임서버 api-token 생성
공식문서를 보고 api-token을 관리한 secret리소스를 생성합니다. 이 문서에서는 cloudflare 액세스 토큰을 사용합니다.
cloudflare 액세스 토큰발급 공식문서: https://cert-manager.io/docs/configuration/acme/dns01/cloudflare/#api-keys
■ yaml파일 작성
소스코드는 git wiki에 있습니다. https://github.com/choisungwook/portfolio/wiki/cert-manager-letsencrypt#clusterissue-%EC%83%9D%EC%84%B1
clusterissue.yml파일을 생성하고 [그림 5]와 같이 설정합니다.
- 전체 namespace에서 issuer을 사용하기 위해 clusterIssuer을 사용합니다.
- let's encrypt staging서버주소를 입력합니다.
- 네임서버에 가입된 이메일주소를 입력합니다.
- clusterissuer를 저장할 secret이름을 입력합니다.
- 네임서버에 가입된 이메일주소를 입력합니다.
- 네임서버 액세스토큰 secret을 설정합니다.
■ yaml파일 실행
kuebctl create명령어로 정의한 clusterissuer을 실행합니다.
kubectl create -f clusterissuer.yml
READY상태가 True인 것을 확인합니다. [그림 6]은 확인 예입니다.
② certificate 생성
certificate는 let's encrypt가 인증할 도메인 등의 정보를 정의합니다.
소스코드는 git wiki에 있습니다. https://github.com/choisungwook/portfolio/wiki/cert-manager-letsencrypt#certificate-%EB%AA%85%EC%84%B8-%EC%A0%95%EC%9D%98
certificate.yml파일을 생성하고 [그림 7]처럼 내용을 작성합니다. [그림 7]은 choilab.xyz, test3.choilab.xyz을 인증하기 위한 예입니다.
- certificate커스텀 리소스를 사용합니다.
- 발급된 인증서를 저장할 secret리소스 이름을 입력합니다.
- 사용할 issuer를 설정합니다.
- 인증할 공통도메인을 입력합니다.
- 인증할 도메인을 입력합니다.
③ 인증서 생성
kuebctl create명령어로 정의한 certificate을 실행합니다.
kubectl create -f certificate.yml
실행한 순간 let's encrypt로 인증서 생성을 요청합니다. 인증서 생성과정은 [그림 3]과 같습니다. 몇 분정도 기다리면 let's encrypt가 인증서를 발급하고 상태가 READY로 바뀝니다. 생성된 인증서는 cetficate리소스와 같은 namespace에 secret리소스로 저장됩니다.
장시간 기다려도 READY상태가 False이면 let's encrypt에서 도메인 소유 검증을 실패한 것입니다.
④ deployment, service, ingress 생성
■ deployment, service 생성
https접속 테스트를 위한 deployment, service를 생성합니다. 컨테이너 이미지는 nginx:latest를 사용했습니다.
소스코드는 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
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-test6 labels: app: nginx-test6 spec: replicas: 1 selector: matchLabels: app: nginx-test6 template: metadata: labels: app: nginx-test6 spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-test6 spec: selector: app: nginx-test6 ports: - port: 80 targetPort: 80 type: NodePort
■ ingress생성
let's encrypt가 생성한 인증서([그림 7])를 ingress에 적용합니다.
소스코드는 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
- certificate.yml에서 설정한 secret을 입력합니다.
- certificate.yml에서 설정한 도메인을 입력합니다.
⑤ 접속확인
staging Issuer가 발급한 인증서는 테스트 목적이기 때문에 [그림 10]와 같이 경고메세지가 출력됩니다. 발급된 인증서는 발급자가 (STAGING)인 것이 특징입니다.
⑥ prod Issuer생성과 다시 certificate, ingress생성
진짜 let's encrypt가 인증한 인증서를 발급하기 위해 prod ClusterIssuer을 생성하고 ② ~ ⑤과정을 반복하시면 됩니다. prod CluseterIssuer는 server주소만 다를 뿐 staging입력내용과 동일합니다. 실습 전 staging 리소스는 삭제합니다.
clusterissuer만 다루고 중복되는 나머지과정은 생략합니다.
■ clusterissuer 생성
- 전체 namespace에서 issuer을 사용하기 위해 clusterIssuer을 사용합니다.
- let's encrypt staging서버주소를 입력합니다.
- 네임서버에 가입된 이메일주소를 입력합니다.
- clusterissuer를 저장할 secret이름을 입력합니다.
- 네임서버에 가입된 이메일주소를 입력합니다.
- 네임서버 액세스토큰 secret을 설정합니다.
■ 접속확인
prod Issuer로 인증서를 성공적으로 발급받으면 [그림 12]와 같이 발급자가 R3으로 표시되고 더이상 경고창이 뜨지 않습니다.
마치며
이 문서에서는 cloudflare를 사용했지만 aws route 53 등 public cloud와 연동해서 사용할 수 있습니다. 이외에도 self-sisgne인증서도 발급할 수 있습니다.
EKS를 실습할 수 있는 돈이 충분하다면 열심히 했을텐데ㅜ.ㅜ
'전공영역 공부 기록' 카테고리의 다른 글
네트워크 part1 - Region과 AZ (0) | 2021.06.28 |
---|---|
nexus private helm 저장소 생성 (0) | 2021.06.13 |
쿠버네티스 클러스터 인증서 갱신 (3) | 2021.05.27 |
kubectl로 cluster admin 생성 (0) | 2021.05.09 |
cert-manager로 self-signed 인증서 생성 (0) | 2021.05.09 |