需求来源
博主需要为自己的部署在Kubenetes上的服务通过Traefik配置IngressRoute,实现通过域名建立HTTPS访问。
需求分析
博主的需求本质上是签发证书的问题,所以需要一个能自动签发泛域名证书的工具。这类工具有很多,例如Certimate、acme.sh等。在Kubenetes上比较流行且经过验证的方案是cert-manager。
工具介绍
cert-manage是一款可以给Kubenetes的工作负载签发并自动需求证书的工具。支持ACME的两种Challenge方式,即HTTP Challenge和DNS Challenge。
cert-manager部署
本文使用Helm部署cert-manager,博主默认读者已掌握Helm命令的基本使用方法,并能阅读values文件。
添加chart仓库
首先需要添加chart仓库,仓库地址: https://charts.jetstack.io
修改values文件
以下是博主使用的values文件,读者可参考。
acmesolver:
image:
pullPolicy: IfNotPresent
repository: quay.io/jetstack/cert-manager-acmesolver
affinity: {}
approveSignerNames:
- issuers.cert-manager.io/*
- clusterissuers.cert-manager.io/*
cainjector:
affinity: {}
config: {}
containerSecurityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
enableServiceLinks: false
enabled: true
extraArgs: []
extraEnv: []
featureGates: ''
image:
pullPolicy: IfNotPresent
repository: quay.io/jetstack/cert-manager-cainjector
nodeSelector:
kubernetes.io/os: linux
podDisruptionBudget:
enabled: false
podLabels: {}
replicaCount: 1
resources: {}
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
serviceAccount:
automountServiceAccountToken: true
create: true
serviceLabels: {}
strategy: {}
tolerations: []
topologySpreadConstraints: []
volumeMounts: []
volumes: []
clusterResourceNamespace: ''
config: {}
containerSecurityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
crds:
enabled: false
keep: true
creator: helm
disableAutoApproval: false
dns01RecursiveNameservers: ''
dns01RecursiveNameserversOnly: false
enableCertificateOwnerRef: false
enableServiceLinks: false
enabled: true
extraArgs: []
extraEnv: []
extraObjects: []
featureGates: ''
global:
commonLabels: {}
imagePullSecrets: []
leaderElection:
namespace: kube-system
logLevel: 2
podSecurityPolicy:
enabled: false
useAppArmor: true
priorityClassName: ''
rbac:
aggregateClusterRoles: true
create: true
cattle:
systemProjectId: p-mz6m6
hostAliases: []
image:
pullPolicy: IfNotPresent
repository: quay.io/jetstack/cert-manager-controller
ingressShim: {}
installCRDs: false
livenessProbe:
enabled: true
failureThreshold: 8
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 15
maxConcurrentChallenges: 60
namespace: ''
nodeSelector:
kubernetes.io/os: linux
podDisruptionBudget:
enabled: false
podLabels: {}
prometheus:
enabled: true
podmonitor:
annotations: {}
enabled: false
endpointAdditionalProperties: {}
honorLabels: false
interval: 60s
labels: {}
path: /metrics
prometheusInstance: default
scrapeTimeout: 30s
servicemonitor:
annotations: {}
enabled: false
endpointAdditionalProperties: {}
honorLabels: false
interval: 60s
labels: {}
path: /metrics
prometheusInstance: default
scrapeTimeout: 30s
targetPort: 9402
replicaCount: 1
resources: {}
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
serviceAccount:
automountServiceAccountToken: true
create: true
startupapicheck:
affinity: {}
backoffLimit: 4
containerSecurityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
enableServiceLinks: false
enabled: true
extraArgs:
- '-v'
extraEnv: []
image:
pullPolicy: IfNotPresent
repository: quay.io/jetstack/cert-manager-startupapicheck
jobAnnotations:
helm.sh/hook: post-install
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
helm.sh/hook-weight: '1'
nodeSelector:
kubernetes.io/os: linux
podLabels: {}
rbac:
annotations:
helm.sh/hook: post-install
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
helm.sh/hook-weight: '-5'
resources: {}
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
serviceAccount:
annotations:
helm.sh/hook: post-install
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
helm.sh/hook-weight: '-5'
automountServiceAccountToken: true
create: true
timeout: 1m
tolerations: []
volumeMounts: []
volumes: []
strategy: {}
tolerations: []
topologySpreadConstraints: []
volumeMounts: []
volumes: []
webhook:
affinity: {}
config: {}
containerSecurityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
enableServiceLinks: false
extraArgs: []
extraEnv: []
featureGates: ''
hostNetwork: false
image:
pullPolicy: IfNotPresent
repository: quay.io/jetstack/cert-manager-webhook
livenessProbe:
failureThreshold: 3
initialDelaySeconds: 60
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
mutatingWebhookConfiguration:
namespaceSelector: {}
networkPolicy:
egress:
- ports:
- port: 80
protocol: TCP
- port: 443
protocol: TCP
- port: 53
protocol: TCP
- port: 53
protocol: UDP
- port: 6443
protocol: TCP
to:
- ipBlock:
cidr: 0.0.0.0/0
enabled: false
ingress:
- from:
- ipBlock:
cidr: 0.0.0.0/0
nodeSelector:
kubernetes.io/os: linux
podDisruptionBudget:
enabled: false
podLabels: {}
readinessProbe:
failureThreshold: 3
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
replicaCount: 1
resources: {}
securePort: 10250
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
serviceAccount:
automountServiceAccountToken: true
create: true
serviceIPFamilies: []
serviceIPFamilyPolicy: ''
serviceLabels: {}
serviceType: ClusterIP
strategy: {}
timeoutSeconds: 30
tolerations: []
topologySpreadConstraints: []
url: {}
validatingWebhookConfiguration:
namespaceSelector:
matchExpressions:
- key: cert-manager.io/disable-validation
operator: NotIn
values:
- 'true'
volumeMounts: []
volumes: []
此文件博主未进行任何修改,直接使用官方默认配置部署。
部署
读者请自行使用helm命令行或其他工具进行部署,此处不赘述。
配置
使用cert-manager签发证书,仅需要配置三个资源即可使用。分别是包含了cloudflare的Secret、cert-manager的ClusterIssuer和cerr-manager的Certificate。
完整的yaml文件如下。
apiVersion: v1
kind: Secret
metadata:
name: cloudflare-api-token-secret
namespace: cert-manager
type: Opaque
stringData:
api-token: your-token
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt
namespace: cert-manager
spec:
acme:
# Change to your letsencrypt email
email: your-email@example.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-account-key
solvers:
- dns01:
cloudflare:
apiTokenSecretRef:
name: cloudflare-api-token-secret
key: api-token
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-com
namespace: traefik
spec:
# Secret names are always required.
secretName: example-com
duration: 2160h # 90d
renewBefore: 360h # 15d
dnsNames:
- "*.example.com"
- "example.com"
# Issuer references are always required.
issuerRef:
name: letsencrypt
kind: ClusterIssuer
读者仅须注意以下几点。
将
your-token
替换为自己在Cloudflare申请的token。将
your-email@example.com
替换为自己的电子邮箱地址。cloudflare-api-token-secret
和声明的存储token的Secret的name
保持一致。*.example.com
和example.com
修改为自己需要签发证书的域名。
验证
至此为止,已经完成了cert-manager的部署和配置,在配置好Ingress或者IngressRoute等入口后,即可通过域名建立HTTPS连接。