目錄
minikube初體驗【1】
minikube部署Traefik【2】
接上篇, 安裝完成 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/