traefik架构图
Traefik 的网络入口点。定义接收数据包的端口,以及是侦听 TCP 还是 UDP。
路由器通过分析规则(主机、路径、标头、SSL 等)将请求连接到对应的服务。
中间件是一种在请求发送到服务之前(或在客户端收到服务的响应之前)调整请求的方法,可以组合成链以适应各种场景。
实际的服务,最终请求(根据负载均衡策略)会转发到该服务。
Traefik 会查询提供者 API 以找到有关路由的相关信息,当 Traefik 检测到更改时,会动态更新路由配置。
修改 k8s 的 nodeport 类型端口范围:
vi /etc/kubernetes/manifests/kube-apiserver.yaml
在 - --service-cluster-ip-range
下一行增加:
- --service-node-port-range=1-65535
重启 kubelet :
systemctl daemon-reload
systemctl restart kubelet
添加 helm traefik 仓库:
helm repo add traefik https://helm.traefik.io/traefik
更新 helm 仓库:
helm repo update
新建 traefik 配置,保存为 traefik-config.yaml
:
ports:
traefik:
expose: true
web:
nodePort: 80
websecure:
nodePort: 443
使用 helm 安装 traefik :
kubectl create ns traefik
helm install traefik traefik/traefik -n traefik -f traefik-config.yaml
查看 svc 端口:
kubectl get svc -n traefik
浏览器访问 http://master:31372/dashboard/#/ :
准备一个 ClusterIP 类型的 Service ,并提供 IngressRoute 给 traefik 配置发现,保存为 whoami.yaml
:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoamiingressroute # 入口路由名称
spec:
entryPoints: # 网络入口点
- web
routes:
- match: Host(`master`) && PathPrefix(`/whoami/`) # 路由匹配器,匹配 http://master/whoami/
kind: Rule
services: # 代理服务
- name: whoami
port: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
spec:
ports:
- protocol: TCP
name: web
port: 80
selector:
app: whoami
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: whoami
labels:
app: whoami
spec:
replicas: 2
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: containous/whoami
ports:
- name: web
containerPort: 80
使用 kubectl 创建:
kubectl apply -f whoami.yaml
traefik 已自动发现配置:
访问 http://master/whoami/ :
更改 whoami.yaml
:
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: whoami-auth
spec:
basicAuth:
secret: authsecret
---
# 用户名密码生成方法:
# yum -y install httpd
# htpasswd -nb admin 123456 | openssl base64
apiVersion: v1
kind: Secret
metadata:
name: authsecret
data:
users: |
YWRtaW46JGFwcjEka1FzN0dwcS4kZlFQQlllNlJQOFZCUFkyOGpZRW5jMQoK
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoamiingressroute # 入口路由名称
spec:
entryPoints: # 网络入口点
- web
routes:
- match: Host(`master`) && PathPrefix(`/whoami/`) # 路由匹配器,匹配 http://master/whoami/
middlewares: # 使用中间件
- name: whoami-auth
kind: Rule
services: # 代理服务
- name: whoami
port: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
spec:
ports:
- protocol: TCP
name: web
port: 80
selector:
app: whoami
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: whoami
labels:
app: whoami
spec:
replicas: 2
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: containous/whoami
ports:
- name: web
containerPort: 80
更新 whoami 服务配置:
kubectl apply -f whoami.yaml
traefik 面板可以观察到已经生成了一个中间件:
再次访问 http://master/whoami/ 需要键入用户名密码(admin/123456):
以 consul 为例,更改 traefik 配置 traefik-config.yaml
:
additionalArguments:
- "--providers.consulcatalog=true"
- "--providers.consulcatalog.endpoint.address=10.97.117.24"
ports:
traefik:
expose: true
web:
nodePort: 80
websecure:
nodePort: 443
使用 helm 更新 traefik :
helm upgrade --install traefik traefik/traefik -n traefik -f traefik-config.yaml
查看 traefik 面板,Providers 已新增 ConsulCatalog:
go run main.go
注册一个服务到 consul :
package main
import (
"fmt"
"log"
"net/http"
_ "net/http/pprof"
consulapi "github.com/hashicorp/consul/api"
)
func consulCheck(w http.ResponseWriter, r *http.Request) {
s := "[consulCheck]" + "remote:" + r.RemoteAddr + " " + r.URL.String()
fmt.Println(s)
fmt.Fprintln(w, s)
}
func registerServer() {
config := consulapi.DefaultConfig()
config.Address = "master:708"
client, err := consulapi.NewClient(config)
if err != nil {
log.Fatal("consul client error : ", err)
}
registration := new(consulapi.AgentServiceRegistration)
registration.ID = "hello-server-v1"
registration.Name = "helloServer"
registration.Port = 8080
registration.Tags = []string{
"traefik.http.routers.helloServer.rule=Host(`consul.master`)",
"traefik.http.middlewares.hello-auth.basicauth.users=admin:$apr1$acnT.3Rd$gGL7hvoyrNOU27L4XcEnO/",
"traefik.http.routers.helloServer.middlewares=hello-auth",
} // tag,配置 traefik
registration.Address = "192.168.0.52"
registration.Check = &consulapi.AgentServiceCheck{ // 健康检查
HTTP: fmt.Sprintf("http://%s:%d%s", registration.Address, registration.Port, "/check"),
Timeout: "3s",
Interval: "5s",
DeregisterCriticalServiceAfter: "30s",
}
err = client.Agent().ServiceRegister(registration)
if err != nil {
log.Fatal("register server error : ", err)
}
http.HandleFunc("/check", consulCheck)
http.ListenAndServe(fmt.Sprintf(":%d", registration.Port), nil)
}
func main() {
registerServer()
}
服务已经注册到 consul:
traefik 也自动发现配置了:
访问 http://consul.master/debug/pprof/ :