[TOC]
国内可能会无法连接一些网站,需要准备好代理,然后运行
export http_proxy=192.168.11.61:11714
export https_proxy=192.168.11.61:11714
export no_proxy=.cn,.aliyun.com,.aliyuncs.com,.163.com,.baiduce.com,.qiniu.com,.daocloud.io,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,100.64.0.0/10,169.254.0.0/16
请将192.168.11.61:11714
修改成你的代理服务器地址和端口。
云厂商方案:使用 LoadBalancer 曝露 80 和 443 端口,并通过 DNS 配置将流量指向负载均衡器。
在裸机环境中,有几种方式可以暴露 Nginx Ingress Controller 的 80 和 443 端口:
可以根据具体需求选择一种方式。可以重点关注一下 MetalLB 组件。
请将下文的 yourdomain.com 替换成真实的域名。
添加 Helm 仓库并安装 cert-manager:
helm repo add jetstack https://charts.jetstack.io
helm repo update
# 安装最新版本:
helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set installCRDs=true
# 指定安装版本:
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.16.2 \
--set crds.enabled=true
验证 cert-manager 是否成功部署:
kubectl get pods --namespace cert-manager
本地环境通常无法通过公网访问,无法通过http的方式让CA验证域名所有权。需要通过DNS的方式让CA验证域名所有权。下面以阿里云DNS为例。其他的DNS resolver。
添加 cert-manager-webhook-alidns Helm 仓库:
helm repo add cert-manager-alidns-webhook https://devmachine-fr.github.io/cert-manager-alidns-webhook
helm repo update
安装 cert-manager-alidns-webhook:
helm install alidns-webhook cert-manager-alidns-webhook/alidns-webhook \
--namespace cert-manager \
--set groupName=acme.yourdomain.com
配置说明:
groupName
应该是唯一的,建议使用你的域名或类似标识。
在阿里云控制台创建一个RAM用户,并赋予DNSFullAccess 策略。在这个用户下创建access key。然后在k8s 创建secret:
kubectl -n cert-manager create secret generic alidns-secrets --from-literal="access-token=yourtoken" --from-literal="secret-key=yoursecretkey"
确保将 yourtoken
和yoursecretkey
修改成从阿里云控制台获得的 AK/SK。
请将下文的 yourdomain.com 替换成真实的域名。
创建 ClusterIssuer 文件:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: your-email@example.com
privateKeySecretRef:
name: letsencrypt-staging
solvers:
- dns01:
webhook:
groupName: acme.yourdomain.com
solverName: alidns-solver
config:
regionId: cn-beijing
accessTokenSecretRef:
name: alidns-secrets
key: access-token
secretKeySecretRef:
name: alidns-secrets
key: secret-key
selector:
dnsZones:
- yourdomain.com
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: your-email@example.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- dns01:
webhook:
groupName: acme.yourdomain.com
solverName: alidns-solver
config:
regionId: cn-beijing
accessTokenSecretRef:
name: alidns-secrets
key: access-token
secretKeySecretRef:
name: alidns-secrets
key: secret-key
selector:
dnsZones:
- yourdomain.com
应用配置:
kubectl apply -f letsencrypt-staging.yaml
kubectl apply -f letsencrypt-prod.yaml
配置说明:
groupName
需要和之前helm指定的一致。email
需要修改为你的邮箱。创建 Issuer 文件:
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-staging-issuer
namespace: your-namespace
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: your-email@example.com
privateKeySecretRef:
name: letsencrypt-staging
solvers:
- dns01:
webhook:
groupName: acme.yourdomain.com
solverName: alidns-solver
config:
regionId: cn-beijing
accessTokenSecretRef:
name: alidns-secrets
key: access-token
secretKeySecretRef:
name: alidns-secrets
key: secret-key
selector:
dnsZones:
- yourdomain.com
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-prod-issuer
namespace: your-namespace
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: your-email@example.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- dns01:
webhook:
groupName: acme.yourdomain.com
solverName: alidns-solver
config:
regionId: cn-beijing
accessTokenSecretRef:
name: alidns-secrets
key: access-token
secretKeySecretRef:
name: alidns-secrets
key: secret-key
selector:
dnsZones:
- yourdomain.com
应用配置:
kubectl apply -f letsencrypt-staging-issuer.yaml
kubectl apply -f letsencrypt-prod-issuer.yaml
配置说明:
groupName
需要和之前helm指定的一致。email
需要修改为你的邮箱。namespace
需要和你的应用的 namespace 一致,否则无法找到 Issuer, 无法颁发证书。而之前的ClusterIssuer是Cluster级别的,不需要指定namespace。创建测试应用的 Deployment 和 Service:
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-app
namespace: your-namespace
spec:
replicas: 1
selector:
matchLabels:
app: test-app
template:
metadata:
labels:
app: test-app
spec:
containers:
- name: test-app
image: nginx:alpine
ports:
- containerPort: 80
apiVersion: v1
kind: Service
metadata:
name: test-app
namespace: your-namespace
spec:
selector:
app: test-app
ports:
- port: 80
targetPort: 80
应用配置:
kubectl apply -f test-app-deployment.yaml
kubectl apply -f test-app-service.yaml
使用 Let's Encrypt Staging 请求证书:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-app-ingress
namespace: your-namespace
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-staging"
spec:
rules:
- host: ingress-test.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-app
port:
number: 80
tls:
- hosts:
- ingress-test.yourdomain.com
secretName: test-app-tls
应用配置:
kubectl apply -f test-app-ingress.yaml
验证证书颁发情况:
查看 Ingress 的证书是否成功颁发:
kubectl describe certificate test-app-tls -n your-namespace
测试从浏览器访问:
先在阿里云DNS控制台创建DNS记录。
EXTERNAL-IP
。 然后在本地浏览器访问 https://ingress-test.yourdomain.com
将 cert-manager.io/cluster-issuer
注解从 letsencrypt-staging
更改为 letsencrypt-prod
:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-app-ingress
namespace: your-namespace
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
rules:
- host: ingress-test.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-app
port:
number: 80
tls:
- hosts:
- ingress-test.yourdomain.com
secretName: test-app-tls
应用更新:
kubectl apply -f test-app-ingress.yaml
步骤 1:指定颁发 ECC 证书
添加以下注解来指定 ECC 证书并设置密钥大小和轮换策略:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-app-ingress
namespace: your-namespace
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
cert-manager.io/private-key-algorithm: "ECDSA"
cert-manager.io/private-key-size: "256"
cert-manager.io/private-key-rotation-policy: "Always"
spec:
rules:
- host: ingress-test.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-app
port:
number: 80
tls:
- hosts:
- ingress-test.yourdomain.com
secretName: test-app-tls
配置说明:
private-key-size: "256"
:指定 ECC 密钥的大小为 256 位。常用的 ECC 密钥大小有 256、384 和 521 位,256 位通常足够提供高强度的安全性。private-key-rotation-policy: "Always"
:启用私钥轮换策略,即每次证书更新时都生成新的私钥。这种策略有助于提高安全性,因为它减少了私钥泄露或被攻击的风险。应用更新:
kubectl apply -f test-app-ingress.yaml
部署并曝露 Nginx Ingress 的 80 和 443 端口
云厂商方案:使用 LoadBalancer 曝露 80 和 443 端口,并通过 DNS 配置将流量指向负载均衡器。
裸机环境方案:
负载均衡软件:使用 Nginx 或 HAProxy 将流量转发到 Ingress Controller。
MetalLB:使用 MetalLB 组件在裸机环境中实现 LoadBalancer。
HostNetwork:将 Nginx Ingress Controller 作为 DaemonSet 部署,并直接监听 80 和 443 端口。
修改 Kubelet NodePort 范围:扩展 NodePort 范围以允许 80 和 443 端口。
Cert manager 和 Ingress 配置 SSL 证书:使用 cert-manager 自动管理和应用 SSL
删除测试应用的 Deployment 和 Service:
kubectl delete deployment test-app -n your-namespace
kubectl delete service test-app -n your-namespace
删除 Ingress 资源和证书:
kubectl delete ingress test-app-ingress -n your-namespace
kubectl delete certificate test-app-tls -n your-namespace
删除 Issuer 和 ClusterIssuer:
kubectl delete issuer letsencrypt-staging-issuer -n your-namespace
kubectl delete issuer letsencrypt-prod-issuer -n your-namespace
kubectl delete clusterissuer letsencrypt-staging
kubectl delete clusterissuer letsencrypt-prod
删除 Cert-Manager 和 Alidns Webhook:
helm uninstall cert-manager -n cert-manager
helm uninstall cert-manager-webhook-alidns -n cert-manager
kubectl delete namespace cert-manager
删除 Nginx Ingress Controller:
helm uninstall ingress-nginx -n ingress-nginx
kubectl delete namespace ingress-nginx
清理负载均衡软件(如 NGINX 或 HAProxy 配置文件):
如果你使用了集群外的负载均衡软件如 NGINX 或 HAProxy,请移除你为暴露 80 和 443 端口而添加的配置。具体步骤请参考之前的文档。
删除 MetalLB 资源(如果使用了 MetalLB 方式):
kubectl delete -f metallb-addresspool.yaml
kubectl delete -f metallb-l2advertisement.yaml
kubectl delete -f metallb-native.yaml
helm uninstall metallb -n metallb-system
kubectl delete namespace metallb-system
对于 HostNetwork
之前删除 Nginx Ingress Controller就已经完成清理。
恢复kube-apiserver 启动参数(如果修改过 NodePort 范围):
如果你修改过 kube-apiserver 的 --service-node-port-range
范围,请恢复默认设置 --service-node-port-range=30000-32767
。
在 kubeadm
部署中,编辑 /etc/kubernetes/manifests/kube-apiserver.yaml
在手动以服务部署 kube-apiserver 时,编辑 /etc/systemd/system/kube-apiserver.service
具体步骤请参考之前的文档。