7.3. 인증서 관리
어떨 때 보는가
- HTTPS 접속에서 인증서 오류가 날 때
- 인증서 만료가 가까워졌을 때
- 새 도메인에 인증서를 발급할 때
인증서가 필요한 이유
HTTPS 로 접속하면 브라우저와 서버가 주고받는 내용이 암호화됩니다. 이때 서버는 "내가 그 도메인의 진짜 주인이다" 를 증명해야 하는데, 그 증명서가 인증서입니다.
인증서에는 유효 기간 이 있습니다. 만료되면 브라우저가 경고를 띄우고 접속을 막습니다. 도메인이 여럿이면 만료 시각도 제각각이라 손으로 관리하기 어렵습니다.
cert-manager 가 하는 일
cert-manager 는 클러스터 안에서 인증서를 자동으로 발급하고 갱신 합니다.
동작 방식은 Kubernetes 의 다른 자원과 같습니다. "이 도메인의 인증서가 필요하다" 는 요청 (Certificate)을 만들어 두면, cert-manager 가 그 상태를 맞추려고 발급을 진행하고, 만료가 가까워지면 스스로 갱신합니다.
발급 결과는 Secret 으로 저장되고, Ingress 가 그 Secret 을 가리켜 씁니다(3.4 장, 5.1 장).
인증서 목록
인증서 관리 > 인증서 로 들어갑니다.

| 열 | 설명 |
|---|---|
| 이름 | 인증서 자원 이름 |
| 네임스페이스 | 속한 네임스페이스 |
| 준비 | 발급이 끝났는지 |
| 발급 기관 | 어떤 Issuer 로 발급했는지 |
| 만료 | 인증서 만료 시각 |
준비 가 True 면 정상입니다.
인증서는 네임스페이스 단위 자원입니다. Ingress 와 같은 네임스페이스 에 있어야 쓸 수 있습니다. 다른 네임스페이스의 Secret 은 참조되지 않습니다.
인증서 상세
이름을 누르면 발급 상태와 만료 시각을 자세히 봅니다.

| 항목 | 무엇을 확인하는가 |
|---|---|
| 조건(Conditions) | Ready 가 True 인지, False 면 사유 |
| 만료 시각 | 언제까지 유효한지 |
| 갱신 예정 시각 | cert-manager 가 언제 갱신을 시도할지 |
| 대상 도메인 | 이 인증서가 보증하는 주소 |
| 저장 Secret | 발급 결과가 담긴 Secret 이름 |
대상 도메인이 실제 접속 주소와 다르면 브라우저가 인증서 오류를 냅니다. Ingress 의 호스트와 같은지 확인하십시오(5.1 장).
*.example.com 처럼 와일드카드로 발급하면 하위 도메인 전체에 쓸 수 있습니다. 다만 소유 확인
방식이 달라져(DNS 확인만 가능) 설정이 까다롭습니다.
발급 기관
인증서를 어디서 받을지 정하는 설정입니다.
| 종류 | 적용 범위 |
|---|---|
| Issuer | 한 네임스페이스 안에서만 |
| ClusterIssuer | 클러스터 전체 |
인증서 관리 > 클러스터 발급자 와 발급자 에서 각각 봅니다.
발급 방식은 크게 세 가지입니다.
| 방식 | 설명 | 폐쇄망 |
|---|---|---|
| 자체 서명 | cert-manager 가 스스로 만든 인증서로 서명 | 가능 |
| 내부 인증 기관(CA) | 조직이 가진 CA 인증서로 서명 | 가능. 대개 이 방식을 씁니다 |
| ACME | 공인 기관에서 자동으로 발급받음 | 외부 통신이 필요해 불가 |
ACME(Automatic Certificate Management Environment) 는 인증서를 사람 손을 거치지 않고 발급받기 위한 통신 규약 입니다. 예전에는 인증 기관 홈페이지에서 신청서를 넣고 심사를 기다려 파일을 내려받았는데, ACME 는 이 과정을 프로그램끼리 주고받아 끝냅니다.
순서는 이렇습니다.
| 순서 | 하는 일 |
|---|---|
| 1 | 인증서가 필요한 쪽이 인증 기관에 "이 도메인 인증서를 달라" 고 요청합니다 |
| 2 | 인증 기관이 "그 도메인이 정말 당신 것인지 증명하라" 며 과제를 냅니다 |
| 3 | 요청한 쪽이 과제를 수행합니다 (정해진 경로에 파일을 두거나 DNS 에 값을 넣습니다) |
| 4 | 인증 기관이 밖에서 확인하고, 맞으면 인증서를 발급합니다 |
2~3 단계 때문에 폐쇄망에서는 쓸 수 없습니다. 인증 기관이 인터넷에서 우리 서버나 DNS 에
접근해야 하는데 폐쇄망은 그 경로가 없습니다. Order 와 Challenge 라는 자원이 이 규약에서
나온 것입니다(아래 "발급 과정 자원").
ACME 를 쓰는 대표적인 인증 기관이 Let's Encrypt 이고, 무료로 발급합니다. 자세한 절차는 아래 "Let's Encrypt 로 공인 인증서 받기" 에 있습니다.
폐쇄망에서는 내부 CA 를 ClusterIssuer 로 등록해 씁니다. 이 인증서는 공인 기관이 서명한 것이 아니므로, 접속하는 PC 에 조직 CA 인증서를 미리 신뢰 목록에 넣어야 브라우저 경고가 사라집니다.
발급 과정 자원
인증서를 요청하면 다음 자원이 순서대로 만들어집니다.
| 자원 | 하는 일 |
|---|---|
| Certificate | 원하는 인증서를 선언합니다 |
| CertificateRequest | 실제 서명 요청입니다 |
| Order | ACME 방식에서 만들어지는 주문 |
| Challenge | 도메인 소유를 증명하는 절차 |
내부 CA 방식에서는 Order·Challenge 가 만들어지지 않습니다. CertificateRequest 에서 바로 서명되기 때문입니다.
발급이 멈추면 이 순서로 따라가며 어느 단계에서 멈췄는지 확인합니다. 각각 인증서 관리 메뉴 아래에 화면이 있습니다.
자체 서명 인증서 만들기 — 단계별
폐쇄망에서 가장 많이 쓰는 방식입니다. 내부 CA 를 한 번 만들어 두고, 그 CA 로 서비스마다 인증서를 찍어 냅니다.
CA 를 거치지 않고 서비스마다 자체 서명 인증서를 따로 만들 수도 있지만 권하지 않습니다. 인증서마다 서명 주체가 달라 접속하는 PC 에 인증서 개수만큼 신뢰 등록을 해야 합니다. 내부 CA 를 하 나 두면 그 CA 하나만 등록하면 됩니다.
만드는 순서는 네 단계입니다. 앞 단계가 뒤 단계의 재료가 되므로 순서를 지켜야 합니다.
각 단계의 YAML 은 Console 의 자원 만들기 또는 YAML 편집기로 적용합니다 (1.2 장).
1단계 — 자체 서명 발급 기관
CA 인증서 자체를 서명해 줄 것이 필요합니다. 맨 처음 인증서는 서명해 줄 상위가 없으므로 스스로 서명 합니다. 이 발급 기관은 다음 단계에서 한 번 쓰고 끝입니다.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: selfsigned-cluster-issuer
spec:
selfSigned: {}
spec.selfSigned 가 빈 객체인 것이 맞습니다. 설정할 값이 없습니다.
2단계 — 내부 CA 인증서
조직의 뿌리 인증서를 만듭니다. isCA: true 가 이 인증서를 "다른 인증서를 서명할 수 있는
인증서" 로 만듭니다.
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: cluster-root-ca
namespace: cert-manager
spec:
isCA: true # 다른 인증서를 서명할 수 있는 인증서
commonName: cluster-root-ca
secretName: cluster-root-ca-secret # CA 인증서와 개인키가 여기 저장됩니다
duration: 87600h # 10년
renewBefore: 8760h # 만료 1년 전에 갱신
privateKey:
algorithm: RSA
size: 4096 # CA 는 오래 쓰므로 넉넉히
issuerRef:
name: selfsigned-cluster-issuer
kind: ClusterIssuer
| 항목 | 설명 |
|---|---|
isCA | true 면 서명용 인증서가 됩니다. 서비스 인증서에는 넣지 않습니다 |
secretName | 만들어진 인증서와 개인키가 저장될 Secret 이름 |
duration | 유효 기간. 시간 단위(h)로 씁니다. 87600h = 10년 |
renewBefore | 만료 몇 시간 전에 갱신할지 |
privateKey.size | 키 길이. CA 는 4096, 서비스 인증서는 2048 이 일반적입니다 |
CA 는 길게 잡습니다. CA 가 바뀌면 그것으로 서명한 인증서를 모두 다시 발급해야 하고, 접속하는 PC 의 신뢰 목록도 전부 갈아야 합니다.
namespace: cert-manager 로 두는 이유 는 다음 단계의 ClusterIssuer 가 이 Secret 을
그 네임스페이스에서 찾기 때문입니다. 다른 곳에 만들면 찾지 못합니다.
3단계 — CA 발급 기관
앞에서 만든 CA 로 서명하는 발급 기관입니다. 이제부터 인증서는 모두 이것을 가리킵니다.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: cluster-ca-issuer
spec:
ca:
secretName: cluster-root-ca-secret # 2단계에서 만든 Secret
여기까지가 한 번만 하는 준비입니다.
4단계 — 서비스 인증서
실제로 서비스에 붙일 인증서입니다. 서비스마다 하나씩 만듭니다.
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: app-tls
namespace: my-app
spec:
secretName: app-tls-secret # Ingress 가 이 이름을 가리킵니다
duration: 8760h # 1년
renewBefore: 720h # 만료 30일 전 갱신
commonName: app.example.com
dnsNames: # 이 인증서가 보장하는 주소 목록
- app.example.com
- app.my-app.svc.cluster.local
privateKey:
algorithm: RSA
size: 2048
issuerRef:
name: cluster-ca-issuer # 3단계에서 만든 발급 기관
kind: ClusterIssuer
dnsNames 에 실제로 접속할 주소를 빠짐없이 적으십시오. 여기 없는 주소로 접속하면
브라우저가 "인증서 이름이 맞지 않는다" 고 경고합니다. 클러스터 안에서만 쓰는 서비스라면
내부 주소(<서비스>.<네임스페이스>.svc.cluster.local)도 함께 적습니다.
commonName 은 옛 방식이고 지금은 dnsNames 를 봅니다. 둘 다 적되 commonName 값은
dnsNames 에도 반드시 포함시키십시오.
발급 확인
Console 의 인증서 관리 > 인증서 목록에서 준비 열이 True 가 되면 끝입니다.
상세 화면에서 유효 기간과 갱신 예정 시각을 확인할 수 있습니다.
접속하는 PC 에 CA 등록
내부 CA 로 만든 인증서는 브라우저가 모르는 CA 라 경고를 냅니다. 2단계에서 만든 CA 인증서를 접속하는 PC 의 신뢰 목록에 넣어야 경고가 사라집니다. 이 배포는 운영 담당자가 합니다 — 회사 PC 에 일괄로 넣는 방식이 일반적입니다.
Let's Encrypt 로 공인 인증 서 받기
인터넷에 공개하는 서비스라면 공인 인증서를 받을 수 있습니다. cert-manager 가 앞에서 설명한 ACME 규약으로 Let's Encrypt 에서 자동으로 발급받고 갱신합니다.
폐쇄망에서는 쓸 수 없습니다. 발급 과정에서 Let's Encrypt 서버와 통신해야 하고, 도메인 소유 확인을 위해 외부에서 우리 서비스로 접속할 수 있어야 합니다. COP 는 폐쇄망 설치가 기본이므로 이 방식은 인터넷에 노출된 서비스에만 해당합니다.
도메인 소유를 어떻게 증명하는가
Let's Encrypt 는 "이 도메인이 정말 당신 것인가" 를 확인한 뒤 발급합니다. 확인 방식이 두 가지입니다.
| 방식 | 확인 방법 | 필요한 것 |
|---|---|---|
| HTTP-01 | 우리 웹 서버의 특정 경로에 임시 파일을 두고 Let's Encrypt 가 밖에서 읽습니다 | 80 포트가 인터넷에서 열려 있어야 합니다 |
| DNS-01 | DNS 에 임시 레코드를 넣고 Let's Encrypt 가 조회합니다 | DNS 제공자 API 접근 권한 |
HTTP-01 이 간단합니다. 다만 *.example.com 같은 와일드카드 인증서는 DNS-01 로만
받을 수 있습니다.
1단계 — ACME 발급 기관 (연습용)
처음에는 반드시 연습용(staging) 서버로 시험하십시오. Let's Encrypt 운영 서버에는 발급 한도가 있습니다. 특히 같은 도메인 조합으로는 일주일에 5장 까지만 받을 수 있어, 설정을 잘못한 채 여러 번 시도하면 그 주 내내 발급이 막힙니다. 연습용 서버는 한도가 넉넉합니다.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: admin@example.com # 만료 알림을 받을 주소
privateKeySecretRef:
name: letsencrypt-staging-key # 계정 키가 저장될 Secret (자동 생성)
solvers:
- http01:
ingress:
ingressClassName: default # 임시 경로를 만들 Ingress 컨트롤러