【2】minikube部署Traefik
目录
【1】minikube初体验
【2】minikube部署Traefik
【3】minikube离线版安装
接上篇, 安装完成 minikube 后,原生单机版的 k8s集群已经搭建完毕,本次是为 minikube 安装 traefik 。 那问题来了, 什么是 traefik? 为什么要用 traefik?
traefik 简介
Traefik 是一款反向代理、负载均衡服务,使用 golang 实现,能够支持自动化更新反向代理和负载均衡配置。要理解 Traefik ,这里有三个概念
- Ingress
- IngressRoute
- Ingress Controller
Ingress : 用于定义和管理HTTP和HTTPS流量的路由规则。通过Ingress资源,可以在Kubernetes集群内部部署一个负载均衡器,并将外部流量路由到集群内部的服务上。说白了就是申明配置规则的。
IngressRoute:用于定义更高级和灵活的HTTP和HTTPS流量路由规则,动态路由、多条件匹配等,可以增强对流量路由的控制。说白了就是申明配置的规则更加高级了,可以实现动态、多条件等。
Ingress Controller:负责监视 ingress 和 ingressRoute资源的变化,并将其应用到实际的负载均衡中去,实现流量的转发和管理。说白了就是nginx这款软件。
这三者的关系,我自身的理解,通过 nginx 来举例说明:
Traefik 部署分了两种组合:
-
Traefik + Ingress
-
Traefik + IngressRoute
Traefik Ingress主要用于定义基本的路由规则,适用于简单的流量路由需求,类似于Kubernetes原生的Ingress资源。
Traefik IngressRoute则提供了更多高级的功能和选项,如中间件的应用、动态路由配置、服务权重调整等,用于处理更复杂的流量路由场景。
总的来说,Traefik Ingress和Traefik IngressRoute都是Traefik Ingress Controller提供的资源对象,用于定义和管理HTTP和HTTPS流量路由规则,主要区别在于Ingress适用于基本的路由配置,而IngressRoute提供了更高级的功能和强大的路由控制选项。根据具体的需求和场景选择使用Traefik Ingress或Traefik IngressRoute来管理流量路由。
接下来就通过实例配置来分别描述这两种组合的安装。
注意:Traefik+ingress
和 Traefik+ingresRoute
同一个集群只能选择其一,通常会选择功能更加强大的 Traefik+IngressRoute
组合。
Traefik+Ingress部署
通过上一篇:https://www.cnblogs.com/hukey/p/18061513 已经部署了一个 minikube
环境。Traefik的部署在 minikube 和 kubernetes 是一致的。
参考官方文档进行部署:https://doc.traefik.io/traefik/routing/providers/kubernetes-ingress/
在官方文档页面找到 Configuration Example
下的 RBAC
部分,并复制其中的yaml代码。
注意:直接复制官方文档,官方可能会更新。
root@minikube(192.168.199.200)~>mkdir traefik-ingress
root@minikube(192.168.199.200)~>cd traefik-ingress/
root@minikube(192.168.199.200)~/traefik-ingress>vim traefik-ingress.yaml
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: traefik-ingress-controller
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses
- ingressclasses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: traefik-ingress-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
name: traefik-ingress-controller
namespace: default
执行清单文件
root@minikube(192.168.199.200)~/traefik-ingress> kubectl apply -f traefik-ingress.yaml
clusterrole.rbac.authorization.k8s.io/traefik-ingress-controller created
clusterrolebinding.rbac.authorization.k8s.io/traefik-ingress-controller created
同样的位置,点击 Traefik
并复制其中的 yaml 代码
root@minikube(192.168.199.200)~/traefik-ingress>vim traefik-daemon.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-ingress-controller
---
apiVersion: apps/v1
kind: Deployment #[修改]将Deployment 修改为 DaemonSet
metadata:
name: traefik
labels:
app: traefik
spec:
replicas: 1 #[删除]本项在 DaemonSet中没有配置此项
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-ingress-controller
containers:
- name: traefik
image: traefik:v2.11
args:
- --log.level=INFO #[新增] Traefik日志级别
- --api #[新增] 允许访问API接口
- --api.insecure #[新增] 允许以HTTP
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443 #[新增] 定义 HTTPS 的接收端口
- --providers.kubernetesingress
ports:
- name: web
containerPort: 80
hostPort: 80 #[新增] 暴露Traefik容器的80端口至节点[HTTP转发]
- name: websecure #[新增] 增加HTTPS转发的支持[选用]
containerPort: 443 #[新增] Traefik容器上使用的端口[对应上面的配置][选用]
hostPort: 443 #[新增] 暴露Traefik容器的443端口至节点[HTTPS转发]
- name: admin #[新增] Traefik管理页面
containerPort: 8080 #[新增] Traefik dashboard访问端口
hostPort: 8080 #[新增] 暴露Tracfik容器的8080端口至节点[可不用配置,使用kubectl port-forward转发]
[删除] 删除 service 该部分是为公有云负载均衡使用
---
apiVersion: v1
kind: Service
metadata:
name: traefik
spec:
type: LoadBalancer
selector:
app: traefik
ports:
- protocol: TCP
port: 80
name: web
targetPort: 80
---
执行清单文件
root@minikube(192.168.199.200)~/traefik-ingress>kubectl apply -f traefik-daemon.yaml
serviceaccount/traefik-ingress-controller created
deployment.apps/traefik created
service/traefik created
将 Deployment
修改为 DaemonSet
是为了让每个节点都创建一个 Traefik Pod,实现更好的冗余和负载均衡;
通过Pod直接暴露 hostPort
减少了service代理,社区通常的方案是通过 Traefik Pod
以 hostPort
形式发布,然后外部在提供一个四层负载均衡器
root@minikube(192.168.199.200)~/traefik-ingress>kubectl get ds
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
traefik 1 1 1 1 1 <none> 42s
通过浏览器访问 traefik dashboard
到此,已经可以通过 http://node_ip:8080
的方式去访问 Traefik 的后台了。如果是这样做的话,K8S集群中每台主机的 8080
端口都会被占用。目前已经有 Traefik作为边缘代理,而且也已经暴露了80端口,这时候就可以通过 ingress
来设置访问 Traefik dashboard
如果需要使用 ingress
则需要创建 service
资源,如下:
注意:非官方代码
root@minikube(192.168.199.200)~/traefik-ingress>cat dashboard-ingress.yaml
apiVersion: v1
kind: Service
metadata:
name: traefik
spec:
ports:
- protocol: TCP
name: traefik
port: 8080
selector:
app: traefik
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: traefik
spec:
rules:
- host: traefik-dashboard.domain.local #定义域名
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: traefik #Service资源定义的名称
port:
number: 8080 #Service资源的端口
上面代码第一步创建了一个 traefik
服务,然后创建一个 ingress
资源进行转发。
上面的代码中使用了定义域名,所有如果客户端是 windows
电脑则需要在 C:\Windows\System32\drivers\etc\hosts
中申明:
现在就可通过浏览器访问:http://traefik-dashboard.domain.local/ 来访问 Traefik
到此,K8S 的 Traefik+ingress
部署完毕。
Traefik+IngressRoute部署
如果安装了上面的 Traefik+ingress
组合,则需要删除其配置信息:
root@minikube(192.168.199.200)~/traefik-ingress>ls
dashboard-ingress.yaml traefik-daemon.yaml traefik-ingress.yaml
root@minikube(192.168.199.200)~/traefik-ingress>kubectl delete -f traefik-daemon.yaml -f traefik-ingress.yaml -f dashboard-ingress.yaml
serviceaccount "traefik-ingress-controller" deleted
daemonset.apps "traefik" deleted
clusterrole.rbac.authorization.k8s.io "traefik-ingress-controller" deleted
clusterrolebinding.rbac.authorization.k8s.io "traefik-ingress-controller" deleted
service "traefik" deleted
ingress.networking.k8s.io "traefik" deleted
通过上一篇:https://www.cnblogs.com/hukey/p/18061513 已经部署了一个 minikube
环境。Traefik的部署在 minikube 和 kubernetes 是一致的。
参考官方文档进行部署:https://doc.traefik.io/traefik/routing/providers/kubernetes-crd/
在官方文档页面找到如下信息
复制 Resource Definition
中的yaml内容到 traefik-definition.yaml
yaml文件内容太长就不在这里展示,请以官方文档中内容为准。
执行清单文件:
root@minikube(192.168.199.200)~/traefik-ingressroute>kubectl apply -f traefik-definition.yaml
customresourcedefinition.apiextensions.k8s.io/ingressroutes.traefik.io created
customresourcedefinition.apiextensions.k8s.io/ingressroutetcps.traefik.io created
customresourcedefinition.apiextensions.k8s.io/ingressrouteudps.traefik.io created
customresourcedefinition.apiextensions.k8s.io/middlewares.traefik.io created
customresourcedefinition.apiextensions.k8s.io/middlewaretcps.traefik.io created
customresourcedefinition.apiextensions.k8s.io/serverstransports.traefik.io created
customresourcedefinition.apiextensions.k8s.io/tlsoptions.traefik.io created
customresourcedefinition.apiextensions.k8s.io/tlsstores.traefik.io created
customresourcedefinition.apiextensions.k8s.io/traefikservices.traefik.io created
customresourcedefinition.apiextensions.k8s.io/ingressroutes.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/ingressroutetcps.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/ingressrouteudps.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/middlewares.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/middlewaretcps.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/serverstransports.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/tlsoptions.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/tlsstores.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/traefikservices.traefik.containo.us created
完成后,同样的位置找到 RBAC
复制 RBAC
中的yaml内容到 traefik-rbac.yaml
官方文档可能会更新,请以官方文档中内容为准。
root@minikube(192.168.199.200)~/traefik-ingressroute>vim traefik-rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: traefik-ingress-controller
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses
- ingressclasses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- traefik.io
- traefik.containo.us
resources:
- middlewares
- middlewaretcps
- ingressroutes
- traefikservices
- ingressroutetcps
- ingressrouteudps
- tlsoptions
- tlsstores
- serverstransports
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: traefik-ingress-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
name: traefik-ingress-controller
namespace: default
执行清单文件
root@minikube(192.168.199.200)~/traefik-ingressroute>kubectl apply -f traefik-rbac.yaml
clusterrole.rbac.authorization.k8s.io/traefik-ingress-controller configured
clusterrolebinding.rbac.authorization.k8s.io/traefik-ingress-controller unchanged
完成后,在该页面找到 Traefik
复制 Traefik
中的yaml内容到 traefik-daemonset.yaml
root@minikube(192.168.199.200)~/traefik-ingressroute>cat traefik-daemonset.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-ingress-controller
---
kind: Deployment # [修改] 修改为 DaemonSet
apiVersion: apps/v1
metadata:
name: traefik
labels:
app: traefik
spec:
replicas: 1 # [删除] DaemonSet中没有该项,删除
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-ingress-controller
containers:
- name: traefik
image: traefik:v2.11
args:
- --log.level=DEBUG # [修改] 日志修改为 'info' 即可
- --api
- --api.insecure
- --entrypoints.web.address=:80 # [说明] 定义HTTP的接收端口
- --entrypoints.websecure.address=:443 # [新增] 定义HTTPS的接收端口
- --entrypoints.tcpep.address=:8000 # [说明] 定义TCP 8080接收端口
- --entrypoints.udpep.address=:9000/udp # [说明] 定义UDP 9000接收端口
- --providers.kubernetescrd
ports:
- name: web
containerPort: 80
hostPort: 80 # [新增] 暴露Traefik容器的80端口至节点
- name: websecure # [新增] 暴露Traefik容器的443端口至节点
containerPort: 443 # [新增] Traefik容器上使用的端口
hostPort: 443 # [新增] 暴露Traefik容器的443端口至节点
- name: admin
containerPort: 8080
nodePort: 8080 # [新增] 暴露Tracfik容器的8080端口至节点[尽量别使用,可以后期通用转发实现访问]
- name: tcpep
containerPort: 8000
nodePort: 8000 # [新增] 暴露Tracfik容器的8000端口至节点
- name: udpep
containerPort: 9000
nodePort: 9000 # [新增] 暴露Tracfik容器的9000端口至节点
[删除] 以下部分在公有云使用SLB部署使用,这里直接删除。
---
apiVersion: v1
kind: Service
metadata:
name: traefik
spec:
type: LoadBalancer
selector:
app: traefik
ports:
- protocol: TCP
port: 80
name: web
targetPort: 80
- protocol: TCP
port: 8080
name: admin
targetPort: 8080
- protocol: TCP
port: 8000
name: tcpep
targetPort: 8000
---
apiVersion: v1
kind: Service
metadata:
name: traefikudp
spec:
type: LoadBalancer
selector:
app: traefik
ports:
- protocol: UDP
port: 9000
name: udpep
targetPort: 9000
----------------------------
执行清单文件
kubectl apply -f traefik-daemonset.yaml
通过 port-forward
来访问 traefik dashboard
安装使用 kubectl port-forward 之前需要安装 socat
yum install -y socat
启用端口转发
kubectl port-forward -n default traefik-676967d669-kltct --address 0.0.0.0 8080:8080
浏览器访问:
接下来使用 traefik ingressRoute
来代理 traefik dashboard
#dashboard-ingress.yaml
apiVersion: v1
kind: Service
metadata:
name: traefik
spec:
ports:
- protocol: TCP
name: traefik
port: 8080
selector:
app: traefik
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik
spec:
entryPoints:
- web
routes:
- match: Host(`traefik.domain.local`)
kind: Rule
services:
- name: traefik
port: 8080
执行清单文件:
kubectl apply -f dashboard-ingress.yaml
上面的代码中使用了定义域名,所有如果客户端是 windows
电脑则需要在 C:\Windows\System32\drivers\etc\hosts
中申明:
然后使用浏览器访问:
IngressRoute常用实例
有这样一个需求:一个服务通过ip:host 访问直接返回文本"hello world",使用 Traefik
为其添加一个二级目录,返回的依然是 "hello world"
比如:
后端服务: 192.168.199.200:8080 -> "hello world."
通过Traefik加二级目录访问:192.168.199.200/hello -> "hello world."
(1)编写ngx-pod
#ngx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: ngx
name: ngx
spec:
replicas: 1
selector:
matchLabels:
app: ngx
template:
metadata:
labels:
app: ngx
spec:
containers:
- image: nginx:alpine
name: nginx
ports:
- containerPort: 80
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
hostPath:
path: /opt/web #挂载本地路径,路径下存放 echo "hello, world." > /opt/web/index.html
---
apiVersion: v1
kind: Service
metadata:
labels:
app: ngx
name: ngx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: ngx
(2)编写 Middleware
#ngx-middleware.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: ngx-middleware
spec:
stripPrefix:
prefixes:
- /hello
(3)编写ingressRoute
#ngx-route.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ngx
spec:
entryPoints:
- web
routes:
- match: Host(`www.super.com`) && PathPrefix(`/hello`) #这里使用了域名/子目录的形式:www.super.com/hello
kind: Rule
services:
- name: ngx
port: 80
middlewares:
- name: ngx-middleware
执行清单文件:
kubectl apply -f ngx.yaml -f ngx-middleware.yaml -f ngx-route.yaml
在window中申明域名
浏览器直接访问:
Traefik+ingressRoute
使用方式还有很多,具体请自行试用。
参考链接
K8S部署Traefik与Ingress、IngressRoute教程: https://www.lemonsys.cn/tech_563/