cert-manager와 HashiCorp Vault를 사용하여 인증서를 관리하는 방법
Jintao Zhang
March 2, 2023
cert-manager가 해결하는 문제
2017년 JETSTACK에 의해 오픈소스로 공개된 cert-manager는 CNCF (Cloud Native Computing Foundation)에 기증되어 샌드박스 레벨 프로젝트가 되었습니다. 그리고 2022년 10월에 CNCF 인큐베이팅 프로젝트로 승격되었습니다.
cert-manager
는 Kubernetes와 OpenShift에서 x.509 인증서를 자동으로 관리할 수 있습니다. 이를 통해 인증서와 인증서 서명 요청이 Kubernetes에서 지원되는 첫 번째 종류의 리소스가 되었으며, 이 과정은 CRD를 통해 구현되었습니다. 또한, cert-manager는 개발자가 애플리케이션 접근 보안을 강화하기 위해 빠르게 인증서를 요청할 수 있도록 합니다.
그럼 cert-manager가 등장하기 전에 Kubernetes에서 인증서를 어떻게 관리했는지 살펴보겠습니다.
Kubernetes에서 인증서 관리 방법
Kubernetes에서 데이터를 저장하는 기본적인 방법은 주로 두 가지가 있습니다:
- ConfigMap
- Secret
그러나 ConfigMap의 모든 정보는 평문으로 저장됩니다. 따라서 일반적인 설정 정보를 저장하는 데는 적합하지만, 인증서와 같은 민감한 정보를 저장하는 데는 적합하지 않습니다.
Kubernetes 설계 당시, 인증서와 같은 관련 정보를 저장하기 위해 Secret
을 사용하는 것이 권장되었으며, 이를 지원하기도 합니다. kubectl create secret tls
를 통해 인증서 정보를 쉽게 저장할 수 있습니다. 예를 들어:
➜ ~ kubectl create secret tls moelove-tls --cert=./cert.pem --key=./cert-key.pem
secret/moelove-tls created
➜ ~ kubectl get secret moelove-tls -oyaml
apiVersion: v1
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNFekNDQWJtZ0F3SUJBZ0lVVHhCTC9aQkdpOEJCOUFVN2JRWi9jK3c2L1Rzd0NnWUlLb1pJemowRUF3SXcKVFRFTE1Ba0dBMVVFQmhNQ1EwNHhFREFPQmdOVkJBY1RCMEpsYVdwcGJtY3hGVEFUQmdOVkJBb1RERTF2WlV4dgpkbVVnU1U1R1R6RVZNQk1HQTFVRUF4TU1iVzlsYkc5MlpTNXBibVp2TUI0WERUSXlNVEF4T1RBM01UY3dNRm9YCkRUSXpNVEF4T1RBM01UY3dNRm93VFRFTE1Ba0dBMVVFQmhNQ1EwNHhFREFPQmdOVkJBY1RCMEpsYVdwcGJtY3gKRlRBVEJnTlZCQW9UREUxdlpVeHZkbVVnU1U1R1R6RVZNQk1HQTFVRUF4TU1iVzlsYkc5MlpTNXBibVp2TUZrdwpFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRVVTcEFjNGE1UXQwQ0NVa2hGSGY3WnZvR1FReVVPUUxSClJhZG0rSUUrV1ZkOThyWkc5NFpob08ybDZSWkY2MnVPN3FpZ2VsaUJwY0FGQ3FzWU9HNnVLcU4zTUhVd0RnWUQKVlIwUEFRSC9CQVFEQWdXZ01CMEdBMVVkSlFRV01CUUdDQ3NHQVFVRkJ3TUJCZ2dyQmdFRkJRY0RBakFNQmdOVgpIUk1CQWY4RUFqQUFNQjBHQTFVZERnUVdCQlFnS01icnBUb3k4NVcvRy9hMGZtYzlDMUJRbURBWEJnTlZIUkVFCkVEQU9nZ3h0YjJWc2IzWmxMbWx1Wm04d0NnWUlLb1pJemowRUF3SURTQUF3UlFJZ1EzTzhJZ0N2MlRkNUhhV00KcE1LWmRCLzNXdEMreERlSVdPbER6L2hCdzE0Q0lRRExQNG0weFpmSkJvRGc5cERocThGdHN5VDdVZVhVdlZGQQpsS0tReFZNOXFBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
tls.key: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUsyZjZHQlNZQ0R4eVoycnB2bVZ1YW5MNDhxeW9SK1NiWmxiQzNqSUZybzhvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFVVNwQWM0YTVRdDBDQ1VraEZIZjdadm9HUVF5VU9RTFJSYWRtK0lFK1dWZDk4clpHOTRaaApvTzJsNlJaRjYydU83cWlnZWxpQnBjQUZDcXNZT0c2dUtnPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=
kind: Secret
metadata:
creationTimestamp: "2022-10-19T07:24:26Z"
name: moelove-tls
namespace: default
resourceVersion: "2103326"
uid: 14f86514-a1d1-4d99-b000-9ed8b5189d56
type: kubernetes.io/tls
위 명령을 통해 Kubernetes에 moelove-tls
라는 이름의 kubernetes.io/tls
타입의 secret 리소스가 생성됩니다.
이 리소스는 애플리케이션이 필요로 할 때 직접 참조하여 해당 인증서 정보를 얻을 수 있습니다. 대부분의 경우, Ingress Controller에서 이를 사용합니다. 예를 들어:
➜ ~ kubectl create ingress moelove-ing --rule="moelove.info/=moelove:8080,tls=moelove-tls"
ingress.networking.k8s.io/moelove-ing created
➜ ~ kubectl get ing moelove-ing -oyaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
creationTimestamp: "2022-10-19T07:32:43Z"
generation: 1
name: moelove-ing
namespace: default
resourceVersion: "2104268"
uid: b90f09f7-8036-4b9f-9744-a247141ea8da
spec:
rules:
- host: moelove.info
http:
paths:
- backend:
service:
name: moelove
port:
number: 8080
path: /
pathType: Exact
tls:
- hosts:
- moelove.info
secretName: moelove-tls
status:
loadBalancer: {}
위 명령을 통해 moelove-ing
라는 이름의 ingress 리소스가 생성됩니다. 이 리소스는 도메인 이름을 moelove.info
로 선언하고, moelove-tls
를 사용하여 이 도메인 이름에 대한 인증서 보호를 추가합니다. 해당 Ingress 컨트롤러 컴포넌트가 Ingress 리소스를 얻은 후, 컴포넌트는 이 도메인 이름에 대한 인증서를 자동으로 구성하여 웹사이트의 보안을 강화합니다.
우리가 직면한 문제들
번거로운 인증서 발급
위 내용에서 인증서를 발급하는 방법을 보여주지 않았습니다. 관심이 있다면 OpenSSL 문서를 확인할 수 있습니다. 인증서 발급 과정에서 이해해야 할 많은 개념들이 있으며, 서명 과정은 Kubernetes 클러스터 외부에서 발생합니다. 따라서 "선언적" 구성 방법을 통해 구체적으로 어떤 일이 발생했는지 이해할 수 없습니다. 특히, 인증서는 다양한 암호화 알고리즘과 설정 등을 가질 수 있습니다.
따라서 기본 방법을 사용하면 생성된 인증서와 키를 Kubernetes Secrets에 저장할 수밖에 없습니다.
번거로운 인증서 갱신/재서명
우리는 모두 인증서가 만료 기간을 가지고 있다는 것을 알고 있습니다. 인증서가 만료되거나 취소되기 전에 새로운 인증서를 준비해야 하며, 새로운 인증서의 만료 기간은 이전 것보다 나중이어야 합니다.
Kubernetes Secrets의 인증서 관리에는 다음과 같은 문제가 있습니다:
-
자동 만료 기간 확인이 없음: Kubernetes에 인증서가 만료되었는지 여부와 상관없이 임의의 인증서를 저장할 수 있습니다.
-
유효하지 않은 데이터에 대한 확인이 없음: Kubernetes Secrets에 저장된 데이터가 손상되었거나 유효하지 않은 경우, Kubernetes에서 특별한 처리를 하지 않습니다.
보안 부족
Kubernetes Secrets에 저장된 인증서와 키 정보는 base64로 인코딩되어 있습니다. 따라서 이 데이터를 얻은 사람은 base64 디코딩을 통해 실제 데이터를 얻을 수 있습니다. 예를 들어:
➜ ~ kubectl get secrets moelove-tls -o jsonpath='{ .data.tls\.crt }' |base64 -d
-----BEGIN CERTIFICATE-----
MIICEzCCAbmgAwIBAgIUTxBL/ZBGi8BB9AU7bQZ/c+w6/TswCgYIKoZIzj0EAwIw
TTELMAkGA1UEBhMCQ04xEDAOBgNVBAcTB0JlaWppbmcxFTATBgNVBAoTDE1vZUxv
dmUgSU5GTzEVMBMGA1UEAxMMbW9lbG92ZS5pbmZvMB4XDTIyMTAxOTA3MTcwMFoX
DTIzMTAxOTA3MTcwMFowTTELMAkGA1UEBhMCQ04xEDAOBgNVBAcTB0JlaWppbmcx
FTATBgNVBAoTDE1vZUxvdmUgSU5GTzEVMBMGA1UEAxMMbW9lbG92ZS5pbmZvMFkw
EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUSpAc4a5Qt0CCUkhFHf7ZvoGQQyUOQLR
Radm+IE+WVd98rZG94ZhoO2l6RZF62uO7qigeliBpcAFCqsYOG6uKqN3MHUwDgYD
VR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNV
HRMBAf8EAjAAMB0GA1UdDgQWBBQgKMbrpToy85W/G/a0fmc9C1BQmDAXBgNVHREE
EDAOggxtb2Vsb3ZlLmluZm8wCgYIKoZIzj0EAwIDSAAwRQIgQ3O8IgCv2Td5HaWM
pMKZdB/3WtC+xDeIWOlDz/hBw14CIQDLP4m0xZfJBoDg9pDhq8FtsyT7UeXUvVFA
lKKQxVM9qA==
-----END CERTIFICATE-----
위 명령을 통해 인증서와 관련된 원본 데이터를 얻을 수 있습니다.
반면, 인증서와 키 데이터를 업데이트하려면 추가 확인 과정 없이 직접 업데이트할 수 있습니다.
이는 대부분의 시나리오에서 보안 정책과 일치하지 않습니다.
다음으로, cert-manager가 이러한 문제를 어떻게 해결하는지 살펴보겠습니다.
cert-manager가 이러한 문제를 해결하는 방법
자동 발급
Cert-manager는 CRD를 통해 개발 및 확장되었으며, Issuers
와 ClusterIssuers
리소스를 추가하고 구현하여 인증서의 CA(인증 기관)를 나타냅니다.
또한 다양한 내장 타입을 지원하며, 외부 컴포넌트와 쉽게 통합할 수 있습니다. 예를 들어:
-
SelfSigned: 자체 서명된 인증서
-
CA: 발급을 위한 CA 제공
-
Vault: HashiCorp Vault를 사용한 발급
-
Venafi: Venafi를 사용한 발급
-
External: 일부 외부 컴포넌트를 사용한 서명, 예를 들어:
-
ACME (Automated Certificate Management Environment)
이러한 컴포넌트를 사용하여 편리하게 인증서를 발급할 수 있습니다. 이후 내용에서는 Vault를 예로 들어 구체적으로 설명하겠습니다.
자동 갱신/재서명
cert-manager에서는 cmctl
을 통해 수동으로 인증서를 갱신할 수 있으며, 동시에 cert-manager는 인증서의 유효 기간과 무결성을 자동으로 확인합니다.
인증서가 만료되거나 인증서 데이터가 불완전한 경우, 자동으로 인증서 재발급을 트리거할 수 있어 인력과 유지 보수 비용을 절약할 수 있습니다.
보안 보장
cert-manager에서는 CRD(CustomResourceDefinitions)를 통해 signers
리소스를 추가하여 인증서 요청을 확인하고, Approved
또는 Denied
로 처리할 수 있습니다. Approve된 후에만 인증서가 발급되며, 이는 더 안전한 방식입니다.
APISIX Ingress Controller가 cert-manager와 통합하는 방법
설치
Apache APISIX Ingress Controller는 Kubernetes Ingress Controller로, Ingress, 사용자 정의 리소스 및 Gateway API를 통해 프록시 규칙을 구성할 수 있습니다.
다음으로, APISIX Ingress Controller와 cert-manager를 통합하여 프록시 도메인 이름에 TLS 인증서를 추가하여 보안을 강화하는 방법을 시연하겠습니다.
동시에, Vault를 사용하여 인증서를 발급합니다.
APISIX Ingress Controller 배포
APISIX Ingress Controller를 배포하는 것은 매우 간단합니다. 다음 단계를 수행하면 됩니다:
tao@moelove:~$ helm repo add apisix https://charts.apiseven.com
tao@moelove:~$ helm repo add bitnami https://charts.bitnami.com/bitnami
tao@moelove:~$ helm repo update
tao@moelove:~$ helm install apisix apisix/apisix --set gateway.tls.enabled=true --set gateway.type=NodePort --set ingress-controller.enabled=true --set ingress-controller.config.apisix.serviceNamespace=apisix --namespace apisix --create-namespace --set ingress-controller.config.apisix.serviceName=apisix-admin --set ingress-controller.config.ingressPublishService="apisix/apisix-gateway"
NAME: apisix
LAST DEPLOYED: Wed Oct 19 21:33:37 2022
NAMESPACE: apisix
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1. Get the application URL by running these commands:
export NODE_PORT=$(kubectl get --namespace apisix -o jsonpath="{.spec.ports[0].nodePort}" services apisix-gateway)
export NODE_IP=$(kubectl get nodes --namespace apisix -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
모든 Pod가 실행 상태가 되면 배포가 성공한 것입니다.
tao@moelove:~$ kubectl -n apisix get pods
NAME READY STATUS RESTARTS AGE
apisix-777c9fdd67-rf8zs 1/1 Running 0 6m48s
apisix-etcd-0 1/1 Running 0 6m48s
apisix-etcd-1 1/1 Running 0 6m48s
apisix-etcd-2 1/1 Running 0 6m48s
apisix-ingress-controller-568544b554-k7nd4 1/1 Running 0 6m48s
Vault 배포
Vault를 배포할 때도 Helm을 사용할 수 있습니다. 여기서는 --set "server.dev.enabled=true"
구성 항목을 추가하여 배포 후 추가 작업 없이 바로 사용할 수 있도록 했습니다. (이 구성은 프로덕션 환경에서 사용하지 않아야 합니다.)
tao@moelove:~$ helm repo add hashicorp https://helm.releases.hashicorp.com
tao@moelove:~$ helm install vault hashicorp/vault --set "injector.enabled=false" --set "server.dev.enabled=true"
NAME: vault
LAST DEPLOYED: Wed Oct 19 21:53:50 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
Thank you for installing HashiCorp Vault!
Now that you have deployed Vault, you should look over the docs on using
Vault with Kubernetes available here:
https://www.vaultproject.io/docs/
Your release is named "vault". To learn more about the release, try the following:
$ helm status vault
$ helm get manifest vault
배포가 완료된 후, Pod가 Running 상태가 되면 배포가 완료된 것입니다.
tao@moelove:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
vault-0 1/1 Running 0 29s
tao@moelove:~$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 84m
vault ClusterIP 10.96.190.88 <none> 8200/TCP,8201/TCP 4m14s
vault-internal ClusterIP None <none> 8200/TCP,8201/TCP 4m14s
다음으로, Vault에 접속하여 pki 기능을 활성화하고 해당 정책을 구성합니다.
tao@moelove:~$ kubectl exec -it vault-0 -- sh
/ $ vault secrets enable pki
Success! Enabled the pki secrets engine at: pki/
/ $ vault write pki/root/generate/internal common_name=moelove.info ttl=8760h
Key Value
--- -----
certificate -----BEGIN CERTIFICATE-----
MIIDODCCAiCgAwIBAgIUds5uMJV9rOkwFEt6Xof5T2SVFccwDQYJKoZIhvcNAQEL
...
VM4DRVgDkqY9JdHU
-----END CERTIFICATE-----
expiration 1668983612
issuer_id 8df13015-7c70-df9a-7bb7-9b3b4afe7f82
issuer_name n/a
issuing_ca -----BEGIN CERTIFICATE-----
MIIDODCCAiCgAwIBAgIUds5uMJV9rOkwFEt6Xof5T2SVFccwDQYJKoZIhvcNAQEL
...
VM4DRVgDkqY9JdHU
-----END CERTIFICATE-----
key_id c9fcfcb0-3548-a9a7-e706-30510592c797
key_name n/a
serial_number 76:ce:6e:30:95:7d:ac:e9:30:14:4b:7a:5e:87:f9:4f:64:95:15:c7
/ $
/ $ vault write pki/config/urls issuing_certificates="http://vault.default:8200/v1/pki/ca" crl_distribution_points="http://vault.default:8200/v1/pki/crl"
Success! Data written to: pki/config/urls
/ $ vault write pki/roles/moelove-dot-info allowed_domains=moelove.info allow_subdomains=true max_ttl=72h
Success! Data written to: pki/roles/moelove-dot-info
/ $
/ $ vault policy write pki - <<EOF
> path "pki*" { capabilities = ["read", "list"] }
> path "pki/sign/moelove-dot-info" { capabilities = ["create", "update"] }
> path "pki/issue/moelove-dot-info" { capabilities = ["create"] }
> EOF
Success! Uploaded policy: pki
다음으로, Kubernetes 인증을 구성합니다:
/ $ vault auth enable kubernetes
Success! Enabled kubernetes auth method at: kubernetes/
/ $ vault write auth/kubernetes/config kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443"
Success! Data written to: auth/kubernetes/config
/ $ vault write auth/kubernetes/role/issuer bound_service_account_names=issuer bound_service_account_namespaces=default policies=pki ttl=20m
Success! Data written to: auth/kubernetes/role/issuer
위 작업을 완료한 후, 다음 단계는 cert-manager를 배포하는 것입니다.
cert-manager 배포
이제 Helm을 통해 cert-manager를 설치할 수 있으며, 설치 과정은 비교적 간단합니다.
tao@moelove:~$ helm repo add jetstack https://charts.jetstack.io
tao@moelove:~$ helm repo update jetstack
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "jetstack" chart repository
Update Complete. ⎈Happy Helming!⎈
tao@moelove:~$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.10.0/cert-manager.crds.yaml
customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/issuers.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io created
tao@moelove:~$ helm install \
> cert-manager jetstack/cert-manager \
> --namespace cert-manager \
> --create-namespace \
> --version v1.10.0
xNAME: cert-manager
LAST DEPLOYED: Wed Oct 19 22:51:06 2022
NAMESPACE: cert-manager
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
cert-manager v1.10.0 has been deployed successfully!
In order to begin issuing certificates, you will need to set up a ClusterIssuer
or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer).
More information on the different types of issuers and how to configure them
can be found in our documentation:
https://cert-manager.io/docs/configuration/
For information on how to configure cert-manager to automatically provision
Certificates for Ingress resources, take a look at the `ingress-shim`
documentation:
https://cert-manager.io/docs/usage/ingress/
Pod 상태 확인:
tao@moelove:~$ kubectl -n cert-manager get pods
NAME READY STATUS RESTARTS AGE
cert-manager-69b456d85c-znpq4 1/1 Running 0 117s
cert-manager-cainjector-5f44d58c4b-wcd27 1/1 Running 0 117s
cert-manager-webhook-566bd88f7b-7rptf 1/1 Running 0 117s
이제 구성과 검증을 시작할 수 있습니다.
구성 및 검증 방법?
구성 및 인증서 발급
tao@moelove:~$ kubectl create serviceaccount issuer
serviceaccount/issuer created
tao@moelove:~$ kubectl get secret
NAME TYPE DATA AGE
sh.helm.release.v1.vault.v1 helm.sh/release.v1 1 36m
tao@moelove:~$ vim issuer-secret.yaml
tao@moelove:~$ cat issuer-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: issuer-token-moelove
annotations:
kubernetes.io/service-account.name: issuer
type: kubernetes.io/service-account-token
tao@moelove:~$ kubectl apply -f issuer-secret.yaml
secret/issuer-token-moelove created
tao@moelove:~$ kubectl get sa,secret
NAME SECRETS AGE
serviceaccount/default 0 118m
serviceaccount/issuer 0 2m11s
serviceaccount/vault 0 38m
NAME TYPE DATA AGE
secret/issuer-token-moelove kubernetes.io/service-account-token 3 35s
secret/sh.helm.release.v1.vault.v1 helm.sh/release.v1 1 38m
Issuer 생성
이 구성을 통해 Vault가 인증 기관으로 사용되며, Vault에 구성된 역할과 secret을 참조하여 자동 발급이 수행됩니다.
tao@moelove:~$ cat vault-issuer.yaml
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: vault-issuer
namespace: default
spec:
vault:
server: http://vault.default
path: pki/sign/moelove-dot-info
auth:
kubernetes:
mountPath: /v1/auth/kubernetes
role: moelove-dot-info
secretRef:
name: issuer-token-moelove
key: token
tao@moelove:~$ kubectl apply -f vault-issuer.yaml
issuer.cert-manager.io/vault-issuer created
인증서 생성
이 구성을 통해 인증서가 자동으로 발급되며, 이후 사용 시 moelove-info-tls
를 통해 참조할 수 있습니다.
tao@moelove:~$ cat moelove-dot-info-cert.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: moelove-info
namespace: default
spec:
secretName: moelove-info-tls
issuerRef:
name: vault-issuer
commonName: www.moelove.info
dnsNames:
- www.moelove.info
tao@moelove:~$ kubectl apply -f moelove-dot-info-cert.yaml
certificate.cert-manager.io/moelove-info created
검증
다음으로, HTTPBIN 서비스를 프록시하여 검증합니다.
먼저, HTTPBIN 애플리케이션을 생성하고 해당 Service를 생성합니다.
kubectl run httpbin --image kennethreitz/httpbin
kubectl expose pod httpbin --port=80
그런 다음, 다음 리소스를 정의하여 프록시 및 인증서를 참조합니다:
# ApisixTls 객체 정의
apiVersion: apisix.apache.org/v2
kind: ApisixTls
metadata:
name: moelove
spec:
hosts:
- moelove.info
secret:
name: moelove-info-tls
---
# 백엔드에 접근하기 위한 경로 정의
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: moelove
spec:
http:
- name: httpbin
match:
paths:
- /*
hosts:
- moelove.info
backends:
- serviceName: httpbin
servicePort: 80
이 리소스를 클러스터에 적용합니다. 그런 다음 kubectl port-forward
를 사용하여 APISIX의 443 포트를 로컬로 포워딩하고 테스트 접근을 수행합니다:
$ ~ kubectl port-forward -n ingress-apisix svc/apisix-gateway 8443:443 &
$ ~ curl -sk https://moelove.info:8443/ip --resolve 'moelove.info:8443:127.0.0.1'
{
"origin": "172.17.18.1"
}
moelove.info
도메인 이름에 대해 HTTPS 인증서가 올바르게 구성되었으며, APISIX Ingress Controller를 통해 이를 프록시한 것을 확인할 수 있습니다.
결론
Kubernetes에서 인증서를 저장하는 기본적인 방법은 ConfigMap과 Secret 두 가지가 있습니다. 그러나 인증서 발급 및 갱신/재서명은 번거롭고, 보안이 개선될 필요가 있습니다.
cert-manager는 이러한 문제를 해결했으며, Kubernetes 생태계에서 인증서 발급/관리 분야의 사실상의 표준이 되었습니다. 또한, Vault와 같은 도구와 통합할 수 있어 더 안전합니다.
Apache APISIX Ingress Controller는 사용자 친화적인 Ingress Controller를 만들기 위해 노력하고 있으며, 이에 따라 초기부터 완전한 cert-manager 통합 기능을 추가했습니다. 사용자는 Apache APISIX Ingress Controller에서 Vault를 통해 cert-manager를 사용하여 인증서를 발급하고 애플리케이션에 HTTPS 프록시를 제공할 수 있습니다.