一、ingress-nginx

官方文档:​​https://kubernetes.github.io/ingress-nginx/deploy/​

1.1 部署

使用官方提供的 manifest 模板(版本 1.6.4)修改:

  1. 强制 http 跳转到 https
# 在模板的这个 configmap 中的 data 下增加“force-ssl-redirect: "true"”
# 还有很多参数可以在官方文档查看
---
apiVersion: v1
data:
allow-snippet-annotations: "true"
force-ssl-redirect: "true"
kind: ConfigMap
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.6.4
name: ingress-nginx-controller
namespace: ingress-nginx
---
  1. 设置全局默认 TLS 证书
# 在 Deployment 中的启动参数(spec.template.spec.containers.args)
# 增加 “--default-ssl-certificate=ingress-nginx/default-tls”
# ingress-nginx 是命名空间,default-tls 是 secret
# 这里是因为我们有泛域名证书,设置一个全局默认证书后,下面的二级域名就不用每个都创建一个 secret
...
spec:
containers:
- args:
- /nginx-ingress-controller
- --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
- --election-id=ingress-nginx-leader
- --controller-class=k8s.io/ingress-nginx
- --ingress-class=nginx
- --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
- --validating-webhook=:8443
- --validating-webhook-certificate=/usr/local/certificates/cert
- --validating-webhook-key=/usr/local/certificates/key
- --default-ssl-certificate=ingress-nginx/default-tls
...

服务启动后还需要创建证书:

# 部署
kubectl apply -f deploy.yaml

# 创建默认证书
kubectl create secret tls default-tls \
--key xxx.key --cert xxx.crt -n ingress-nginx

1.2 测试模板

# 访问 http://xx.xx.net 时,会直接跳转到 https,同时由于这里没有配置 TLS 证书,会使用配置的默认证书。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
spec:
ingressClassName: nginx
rules:
- host: xx.xx.net
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: nginx
port:
number: 80
# 不使用默认证书,需要创建对应的 secret,还要在 ingress.spec 中配置 tls。
# 其中 tls 中的 hosts 的取值需要与 rules 字段中的 host 完全匹配。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-example-ingress
spec:
tls:
- hosts:
- https-example.foo.com
secretName: testsecret-tls
rules:
- host: https-example.foo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service1
port:
number: 80

二、traefik

Traefik 是一个云原生的新型的 HTTP 反向代理、负载均衡软件。它负责接收系统的请求,然后使用合适的组件来对这些请求进行处理。

2.1 部署

2.1.1 创建 CRD、RBAC

可在官方文档找到:​​https://doc.traefik.io/traefik/master/providers/kubernetes-crd/​

2.1.2 创建配置文件

kind: ConfigMap
apiVersion: v1
metadata:
name: traefik-config
namespace: kube-system
data:
traefik.yaml: |-
serversTransport:
insecureSkipVerify: true
api:
insecure: true
dashboard: true
metrics:
prometheus: metrics
entryPoints:
# dashboard 端口
traefik:
address: ":8888"
web:
address: ":80"
# 强制 http 跳转 https
http:
redirections:
entryPoint:
to: websecure
scheme: https
forwardedHeaders:
insecure: true
transport:
lifeCycle:
requestAcceptGraceTimeout: 10s
graceTimeOut: 10s
respondingTimeouts:
readTimeout: 10s
writeTimeout: 300s
idleTimeout: 300s
websecure:
address: ":443"
forwardedHeaders:
insecure: true
transport:
lifeCycle:
requestAcceptGraceTimeout: 10s
graceTimeOut: 10s
respondingTimeouts:
readTimeout: 10s
writeTimeout: 300s
idleTimeout: 300s
# tls 的默认配置,主要配置 tls 版本和加密套件
tls:
options:
default:
minVersion: VersionTLS12
maxVersion: VersionTLS13
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
providers:
kubernetesCRD: ""
kubernetesingress: ""
log:
level: info
format: json
accessLog:
filePath: "/var/log/access.log"
format: json
bufferingSize: 100

2.1.3 创建默认的 TLS 参数

# 提供给服务使用的 tls 选项
apiVersion: traefik.containo.us/v1alpha1
kind: TLSOption
metadata:
name: traefik-tls-options
namespace: kube-system
spec:
minVersion: VersionTLS12
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 # TLS 1.2
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 # TLS 1.2
- TLS_AES_256_GCM_SHA384 # TLS 1.3
- TLS_CHACHA20_POLY1305_SHA256 # TLS 1.3
curvePreferences:
- CurveP521
- CurveP384

---
# 存储分组,需提前创建 secret
# kubectl create secret tls traefik-tls --cert=tls.crt --key=tls.key -n kube-system
apiVersion: traefik.containo.us/v1alpha1
kind: TLSStore
metadata:
name: default
namespace: kube-system
spec:
# 指定默认证书,k8s中traefik默认通过这个指定证书
defaultCertificate:
secretName: traefik-tls

2.1.4 部署服务

# 使用 daemonset,部署到所有 master 节点上。
# traefik 版本为 2.9.9
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: traefik-ingress
namespace: kube-system
labels:
app: traefik-ingress
kubernetes.io/cluster-service: "true"
spec:
selector:
matchLabels:
app: traefik-ingress
template:
metadata:
labels:
app: traefik-ingress
name: traefik-ingress
namespace: kube-system
spec:
dnsPolicy: ClusterFirstWithHostNet
terminationGracePeriodSeconds: 10
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- traefik-ingress
namespaces:
- kube-system
topologyKey: kubernetes.io/hostname
tolerations:
- effect: NoSchedule
operator: Exists
- key: CriticalAddonsOnly
operator: Exists
- effect: NoExecute
operator: Exists
nodeSelector:
kubernetes.io/role: master
serviceAccountName: traefik-ingress-controller
containers:
- image: traefik:v2.9.9
name: traefik-ingress
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 500m
memory: 500Mi
ports:
- name: web
containerPort: 80
- name: websecure
containerPort: 443
- name: traefik
containerPort: 8888
args:
- --configfile=/traefik/traefik.yaml
volumeMounts:
- mountPath: "/traefik"
name: config
volumes:
- name: config
configMap:
name: traefik-config
items:
- key: traefik.yaml
path: traefik.yaml

2.1.5 创建 SVC

apiVersion: v1
kind: Service
metadata:
name: traefik
namespace: kube-system
spec:
selector:
app: traefik-ingress
ports:
- port: 80
targetPort: 80
nodePort: 30080
name: web
- port: 443
targetPort: 443
nodePort: 30443
name: websecure
type: NodePort

---
apiVersion: v1
kind: Service
metadata:
name: traefik-dashboard
namespace: kube-system
spec:
selector:
app: traefik-ingress
ports:
- port: 8888
targetPort: 8888
name: dashboard
type: ClusterIP

2.2 测试

2.2.1 traefik dashboard

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
labels:
app: traefik
name: traefik-dashboard-ingress
namespace: kube-system
spec:
entryPoints:
- web
- websecure
routes:
- kind: Rule
match: Host(`traefik.belkuy.top`) && PathPrefix(`/`)
services:
- name: traefik-dashboard
port: 8888
# tls相关配置
tls:
# 使用全局默认的证书
options:
name: traefik-tls-options
namespace: kube-system

2.2.2 nginx example

# 创建自定义的 TLS 配置
apiVersion: traefik.containo.us/v1alpha1
kind: TLSOption
metadata:
name: test-tls-options
namespace: default
spec:
# 最低支持 TLS1.1 版本
minVersion: VersionTLS11
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 # TLS 1.2
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 # TLS 1.2
- TLS_AES_256_GCM_SHA384 # TLS 1.3
- TLS_CHACHA20_POLY1305_SHA256 # TLS 1.3
curvePreferences:
- CurveP521
- CurveP384

---
# 不使用全局默认证书,需提前在同个 namespace 下创建其他 TLS 证书
# kubectl create secret tls default-tls --cert=tls2.crt --key=tls2.key -n default
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: test-ingress
namespace: default
spec:
entryPoints:
- websecure
routes:
- kind: Rule
match: Host(`nginx.belkuy.top`) && PathPrefix(`/`)
services:
- name: nginx
port: 80
tls:
# 使用单独的 TLS 证书、参数
secretName: default-tls
options:
name: test-tls-options
namespace: default