kubernetesv1.16系列——搞定Traefik2.1的使用

Traefik 介紹

traefik是一個使你把微服務暴露出來變的更容易的http反向代理和負載均衡軟件。traefik支持K8S、docker swarm、mesos、consul、etcd、zookeeper等基礎設施組件,個人認為更適合容器化的微服務,traefik的配置會自動的、動態的配置更新自己。

kubernetesv1.16系列——搞定Traefik2.1的使用

使用 Traefik,不需要維護或者同步一個獨立的配置文件:因為一切都會自動配置,實時操作的(無需重新啟動,不會中斷連接)。使用 Traefik,你可以花更多的時間在系統的開發和新功能上面,而不是在配置和維護工作狀態上面花費大量時間。

核心概念

Traefik 是一個邊緣路由器,是你整個平臺的大門,攔截並路由每個傳入的請求:它知道所有的邏輯和規則,這些規則確定哪些服務處理哪些請求;傳統的反向代理需要一個配置文件,其中包含路由到你服務的所有可能路由,而 Traefik 會實時檢測服務並自動更新路由規則,可以自動服務發現。

kubernetesv1.16系列——搞定Traefik2.1的使用

Traefik是根據定義的 entrypoints(入口點),然後根據連接到這些 entrypoints 的路由來分析傳入的請求,來查看他們是否與一組規則相匹配,如果匹配,則路由可能會將請求通過一系列中間件轉換過後再轉發到你的服務上去。在瞭解 Traefik 之前有幾個核心概念我們必須要了解:

  • Providers 用來自動發現平臺上的服務,可以是編排工具、容器引擎或者 key-value 存儲等,比如 Docker、Kubernetes、File
  • Entrypoints 監聽傳入的流量(端口等…),是網絡入口點,它們定義了接收請求的端口(HTTP 或者 TCP)。
  • Routers 分析請求(host, path, headers, SSL, …),負責將傳入請求連接到可以處理這些請求的服務上去。
  • Services 將請求轉發給你的應用(load balancing, …),負責配置如何獲取最終將處理傳入請求的實際服務。
  • Middlewares 中間件,用來修改請求或者根據請求來做出一些判斷(authentication, rate limiting, headers, …),中間件被附件到路由上,是一種在請求發送到你的服務之前(或者在服務的響應發送到客戶端之前)調整請求的一種方法。

安裝

由於 Traefik 2.X 版本和之前的 1.X 版本不兼容,我們這裡選擇功能更加強大的 2.X 版本來和大家進行講解,我們這裡使用的鏡像是 traefik:2.1.6。

在 Traefik 中的配置可以使用兩種不同的方式:

  • 動態配置:完全動態的路由配置
  • 靜態配置:啟動配置

靜態配置中的元素(這些元素不會經常更改)連接到 providers 並定義 Treafik 將要監聽的 entrypoints。在 Traefik 中有三種方式定義靜態配置:在配置文件中、在命令行參數中、通過環境變量傳遞:

配置文件

在啟動時,Traefik在以下位置搜索名為traefik.toml(traefik.yml或traefik.yaml)的文件:

  • /etc/traefik/
  • $XDG_CONFIG_HOME/
  • $HOME/.config/
  • .(工作目錄)

參數

啟動參數如下,還有很多可以參考官方文檔(https://docs.traefik.io/reference/static-configuration/cli/)

<code>--entryPoints.web.address=:80
--entryPoints.websecure.address=:443
--api=true
--api.dashboard=true
--ping=true
--providers.kubernetesingress
--providers.kubernetescrd/<code>

環境變量參考:https://docs.traefik.io/reference/static-configuration/env/

動態配置包含定義系統如何處理請求的所有配置內容,這些配置是可以改變的,而且是無縫熱更新的,沒有任何請求中斷或連接損耗。

安裝 Traefik 到 Kubernetes 集群中的資源清單文件我這裡提前準備好了,直接執行下面的安裝命令即可:

cat crd.yaml

<code>kind: CustomResourceDefinition
metadata:
name: ingressroutes.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRoute
plural: ingressroutes
singular: ingressroute
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutetcps.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteTCP
plural: ingressroutetcps
singular: ingressroutetcp

scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: middlewares.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: Middleware
plural: middlewares
singular: middleware
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsoptions.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSOption
plural: tlsoptions
singular: tlsoption
scope: Namespaced

---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: traefikservices.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TraefikService
plural: traefikservices
singular: traefikservice
scope: Namespaced/<code>

cat rbac.yaml

<code>kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik
rules:
- apiGroups:

- ""
resources:
- pods
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- traefik.containo.us
resources:
- ingressroutes
- ingressroutetcps
- middlewares
- tlsoptions
- traefikservices
verbs:
- get
- list
- watch

---
kind: ServiceAccount
apiVersion: v1
metadata:
name: traefik
namespace: kube-system

---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik
roleRef:

apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik
subjects:
- kind: ServiceAccount
name: traefik
namespace: kube-system/<code>

cat deployment.yaml

<code>apiVersion: apps/v1
kind: Deployment
metadata:
name: traefik
namespace: kube-system
labels:
app: traefik
spec:
selector:
matchLabels:
app: traefik
strategy:
type: Recreate
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik
tolerations:
- operator: "Exists"
nodeSelector:
kubernetes.io/role: master
containers:
- image: traefik:2.1.6
name: traefik
ports:
- name: web
containerPort: 80
hostPort: 80
- name: websecure
containerPort: 443
hostPort: 443
- name: mongo
hostPort: 27017
containerPort: 27017
- name: postgres
hostPort: 5432
containerPort: 5432
args:

- --entryPoints.web.address=:80
- --entryPoints.websecure.address=:443
- --entryPoints.mongo.address=:27017
- --entryPoints.postgres.address=:5432
- --api=true
- --api.dashboard=true
- --ping=true
- --providers.kubernetesingress
- --providers.kubernetescrd
- --log.level=INFO
- --accesslog
resources:
requests:
cpu: "50m"
memory: "50Mi"
limits:
cpu: "200m"
memory: "100Mi"
securityContext:
allowPrivilegeEscalation: true
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
readinessProbe:
httpGet:
path: /ping
port: 8080
failureThreshold: 1
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
livenessProbe:
httpGet:
path: /ping
port: 8080
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2/<code>

cat dashboard.yaml

<code>kind: IngressRoute
metadata:
name: traefik-dashboard
spec:

routes:
- match: Host(`traefik.domain.com`)
kind: Rule
services:
- name: api@internal
kind: TraefikService

---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard-tls
spec:
entryPoints:
- websecure
routes:
- match: Host(`traefik.domain.com`)
kind: Rule
services:
- name: api@internal
kind: TraefikService
tls:
secretName: who-tls/<code>

其中 deployment.yaml 我這裡是固定到 master 節點上的,如果你需要修改可以下載下來做相應的修改即可。啟動配置其中前兩項配置是來定義 web 和 websecure 這兩個入口點的,--api=true ,就會創建一個名為 api@internal 的特殊 service,在 dashboard 中可以直接使用這個 service 來訪問,然後其他比較重要的就是開啟 kubernetesingress 和 kubernetescrd 這兩個 provider。

dashboard.yaml 中定義的是訪問 dashboard 的資源清單文件,可以根據自己的需求修改。

部署完成後我們可以通過在本地 /etc/hosts 中添加上域名 traefik.domain.com 的映射即可訪問 Traefik 的 Dashboard 頁面了:

kubernetesv1.16系列——搞定Traefik2.1的使用

官方示例whoami 應用:

cat whoami.yaml

<code>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/<code>

然後定義一個 IngressRoute 對象:

cat whoamiroute.yaml

<code>apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: simpleingressroute

spec:
entryPoints:
- web
routes:
- match: Host(`who.domain.com`) && PathPrefix(`/notls`)
kind: Rule
services:
- name: whoami
port: 80/<code>

通過 entryPoints 指定了我們這個應用的入口點是 web,也就是通過 80 端口訪問,然後訪問的規則就是要匹配 who.domain.com 這個域名,並且具有 /notls 的路徑前綴的請求才會被 whoami 這個 Service 所匹配。我們可以直接創建上面的幾個資源對象,然後對域名做對應的解析後,就可以訪問應用了:


kubernetesv1.16系列——搞定Traefik2.1的使用

在 IngressRoute 對象中我們定義了一些匹配規則,這些規則在 Traefik 中有如下定義方式:

kubernetesv1.16系列——搞定Traefik2.1的使用

如果我們需要用 HTTPS 來訪問我們這個應用的話,就需要監聽 websecure 這個入口點,也就是通過 443 端口來訪問,同樣用 HTTPS 訪問應用必然就需要證書,這裡我們用 openssl 來創建一個自簽名的證書:

<code>openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=who.domain.com"/<code>

然後通過 Secret 對象來引用證書文件:

<code>kubectl create secret tls who-tls --cert=tls.crt --key=tls.key
secret/who-tls created/<code>

這個時候我們就可以創建一個 HTTPS 訪問應用的 IngressRoute 對象了:

<code>apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutetls
spec:
entryPoints:
- websecure
routes:
- match: Host(`who.domain.com`) && PathPrefix(`/tls`)
kind: Rule
services:
- name: whoami
port: 80
tls:
secretName: who-tls/<code>

這裡先簡單介紹traefik的基本功能,後面會根據功能單獨介紹。


分享到:


相關文章: