Traefik ForwardAuth
ForwardAuth 可以用来外挂一些 验证、鉴权 服务,之所以使用它主要是我需要一个 Gateway
这个Gateway需要调用一些外部接口,然后执行一些业务逻辑,构成一个AOP切面
大约分成几个部分
- 能够接收请求的Golang rest服务,作为auth restapi ,通过header来获得token
- 将上面的Golang应用容器化,制作docker镜像
- 构建服务使用 ForwardAuth中间件调用上面的服务
ForwardAuth 可以用来外挂一些 验证、鉴权 服务,之所以使用它主要是我需要一个 Gateway
这个Gateway需要调用一些外部接口,然后执行一些业务逻辑,构成一个AOP切面
大约分成几个部分
安装一个测试用的nginx
给这个 deploy 安装一个 svc
创建对应的 Traefik service 和 Ingress route
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ngingressroute
namespace: lizhe
spec:
entryPoints:
- web
routes:
- match: Host(`ngts.lizhe.com`)
kind: Rule
services:
- name: ngts
kind: TraefikService
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
name: ngts
namespace: lizhe
spec:
weighted:
services:
- name: nginxsvc
port: 80
kind: Service
创建一个 middleware
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-ipwhitelist
namespace: lizhe
spec:
ipWhiteList:
sourceRange:
- 127.1.1.1/32
- 192.1.1.1/32
然后需要修改一下 route ,让route使用这个新创建的 middleware
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ngingressroute
namespace: lizhe
spec:
entryPoints:
- web
routes:
routes:
- middlewares:
- name: test-ipwhitelist
match: Host(`ngts.lizhe.com`)
kind: Rule
services:
- name: ngts
kind: TraefikService
更新一下这个白名单,打开 本机 ip
这里不需要重启,就可以看见已经生效了
需要添加 endpoint 和 hostport
spec:
containers:
- args:
- --global.checknewversion
- --global.sendanonymoususage
- --entryPoints.traefik.address=:9000/tcp
- --entryPoints.web.address=:8000/tcp
- --entryPoints.websecure.address=:8443/tcp
- --entryPoints.mysql.address=:3306/tcp
- --api.dashboard=true
- --ping=true
- --providers.kubernetescrd
- --providers.kubernetesingress
image: traefik:2.4.8
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
httpGet:
path: /ping
port: 9000
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
name: traefik
ports:
- containerPort: 9000
name: traefik
protocol: TCP
- containerPort: 8000
name: web
protocol: TCP
- containerPort: 8443
name: websecure
protocol: TCP
- containerPort: 8000
hostPort: 8000
name: http
protocol: TCP
- containerPort: 9000
hostPort: 9000
name: db
protocol: TCP
- containerPort: 3306
hostPort: 3306
name: mysql
protocol: TCP
apiVersion: v1
kind: Service
metadata:
name: mysql-traefik
namespace: database
spec:
selector:
app: mysql
ports:
- port: 3306
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
name: traefik-tcp
namespace: database
spec:
entryPoints:
- mysql
routes:
- match: HostSNI(`*`)
services:
- name: mysql-traefik
port: 3306
流量复制可以将 request 发给主 endpoint 的同时,将同样的request发给另一个endpoint,并且忽略第二个endpoint的response
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
name: app-mirror
namespace: version
spec:
mirroring:
name: ver1 # 发送 100% 的请求到 K8S 的 Service "v1"
port: 80
mirrors:
- name: ver2 # 然后复制 50% 的请求到 v2
percent: 50
port: 80
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: mirror-ingress-route
namespace: version
spec:
entryPoints:
- web
routes:
- match: Host(`mi.lizhe.com`)
kind: Rule
services:
- name: app-mirror
kind: TraefikService # 使用声明的 TraefikService 服务,而不是 K8S 的 Service
for i in `seq 20`; do curl http://mi.lizhe.com:8000/helloworld.html;echo "" ;done
不同于 Istio,Traefik需要每个dep对应各自的 service
这里我们分别创建3个不同的 service 使用clusterip
创建 traefik service
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
name: lizhets
namespace: version
spec:
weighted:
services:
- name: ver1
weight: 3 # 定义权重
port: 80
kind: Service # 可选,默认就是 Service
- name: ver2
weight: 1
port: 80
创建 IngressRoute
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: lizheingressroute
namespace: version
spec:
entryPoints:
- web
routes:
- match: Host(`ts.lizhe.com`)
kind: Rule
services:
- name: lizhets
kind: TraefikService
for i in `seq 20`; do curl http://ts.lizhe.com:8000/helloworld.html;echo "" ;done
首先确定我们的 Traefik dep 部署在
出于我懒得原因,我直接在dep上开一个 hostport,用来暴露 8000端口,当然nodeport也可以用
加4条本机hosts dns ,2个用来测试 Traefik,另外2个用来测试nginx ingress
因为 Traefik 在 173上,nginx 在 171 上
192.168.194.173 traefik1.lizhe.com
192.168.194.173 traefik2.lizhe.com
192.168.194.171 nginx1.lizhe.com
192.168.194.171 nginx2.lizhe.com
创建4个 ingress
这里 ingress 没有什么特殊的内容
第一次用Traefik是在2019年,
它的结构图差不多是这样
直接上helm
helm repo add traefik https://helm.traefik.io/traefik
helm repo update
helm install traefik traefik/traefik
kubectl port-forward $(kubectl get pods --selector "app.kubernetes.io/name=traefik" --output=name) 9000:9000
可以用 hostport
nodeport
先做一个清理
kubectl delete secret istio-ingressgateway-certs -n istio-system
准备 两套 证书
这里我用的两个域名是
kubectl create secret generic istio-ingressgateway-certs -n istio-system --from-file=diy-cert.pem --from-file=diy-key.pem --from-file=go-cert.pem --from-file=go-key.pem
修改 gateway
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: nginx-gateway
namespace: lizhe
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 443
name: https-diy
protocol: HTTPS
hosts:
- "diynocap.com"
tls:
mode: SIMPLE
serverCertificate: /etc/istio/ingressgateway-certs/diy-cert.pem
privateKey: /etc/istio/ingressgateway-certs/diy-key.pem
- port:
number: 443
name: https-go
protocol: HTTPS
hosts:
- "golang.press"
tls:
mode: SIMPLE
serverCertificate: /etc/istio/ingressgateway-certs/go-cert.pem
privateKey: /etc/istio/ingressgateway-certs/go-key.pem
这里我用的域名是 diynocap.com 准备好证书
kubectl create -n istio-system secret tls istio-ingressgateway-certs --key private.key --cert cert.pem
然后修改 gateway
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: nginx-gateway
namespace: lizhe
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "diynocap.com"
- "diynocap2.com"
tls:
mode: SIMPLE
serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
privateKey: /etc/istio/ingressgateway-certs/tls.key
需要设置对应的 hostport端口或者使用nodeport
Ingressgateway 人如其名,毕竟还是 ingress,那ingress是按照 URL 地址来匹配资源的,而且受 namespace 影响
如果把 Gateway 的 hosts 从 * 改成 地址,那么就只能用地址来访问了
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: nginx-gateway
namespace: lizhe
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "diynocap.com"
当然要把 diynocap.com 指向对应的 IP地址
但是因为 服务是通过 nodeport 暴露的,所以提供的是 高位端口
如何使ingressgateway使用 80 端口呢?
当然可以使用 hostport
设置dns