Kubernetes 1.18.3 部署 Traefik2.0
Centos 3.10.0-693.el7.x86_64
Kubernetes 1.18.3
Traefik 2.2
[root@k8s-master1 traefik]# kubectl get cs
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
scheduler Healthy ok
etcd-0 Healthy {"health":"true"}
etcd-2 Healthy {"health":"true"}
etcd-1 Healthy {"health":"true"}
[root@k8s-master1 traefik]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready <none> 6d1h v1.18.3
k8s-node1 Ready <none> 6d v1.18.3
k8s-node2 Ready <none> 6d v1.18.3
[root@k8s-master1 traefik]# uname -a
Linux k8s-master1 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
Traefik 2.0 官方文檔:https://docs.traefik.io/v2.0/
1.Traefik 介紹
traefik 是一款反向代理、負載均衡服務,使用 golang 實現的。和 nginx 最大的不同是,它支持自動化更新反向代理和負載均衡配置。在微服務架構越來越流行的今天,一個業務恨不得有好幾個數據庫、后台服務和 webapp,開發團隊擁有一款 “智能” 的反向代理服務,為他們簡化服務配置。traefik 就是為了解決這個問題而誕生的。
Traefik 2.2新增的功能如下:
1. 支持了udp
2. traefik2.2 支持使用K/V存儲做為動態配置的源,分別是 consul, etcd, Redis, zookeeper
3. 能夠使用kubernetes CRD自定義資源定義UDP負載平衡 IngressRouteUDP。
4. 能夠使用 rancher, consul catalog, docker和 marathon中的標簽定義UDP的負載平衡
5. 增加了對ingress注解的主持
6. 將TLS存儲功能 TLSStores添加到Kubernetes CRD中,使kubernetes用戶無需使用配置文件和安裝證書即可提供默認證書。
7. 在日志中增加了http的請求方式,是http還是https
8. 因為TLS的配置可能會影響CPU的使用率,因此增加了 TLS version和 TLS cipher使用的指標信息
9. 當前的WRR算法對於權重不平衡端點存在嚴重的偏差問題,將EDF調度算法用於WeightedRoundRobin, Envoy也是使用了 EOF調度算法
10. 支持請求主體用於流量鏡像
11. 增加了 ElasticAPM作為traefik的tracing系統。
12. Traefik的Dashboard增加了UDP的頁面
13. Traefik也增加了黑暗主題
2.部署 Traefik 2.0
在 traefik v2.0 版本后,開始使用 CRD(Custom Resource Definition)來完成路由配置等,所以需要提前創建 CRD 資源。
下面進行安裝過程。
注:我們這里是將traefik部署在ingress-traefik命名空間,如果你需要部署在其他命名空間,需要更改資源清單,如果你是部署在和我同樣的命令空間中,你需要創建該命名空間。
創建命名空間:
kubectl create ns ingress-traefik
創建CRD資源
Traefik 2.0版本后開始使用CRD來對資源進行管理配置,所以我們需要先創建CRD資源。
traefik-crd.yaml
## IngressRoute
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutes.traefik.containo.us
spec:
scope: Namespaced
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRoute
plural: ingressroutes
singular: ingressroute
---
## IngressRouteTCP
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutetcps.traefik.containo.us
spec:
scope: Namespaced
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteTCP
plural: ingressroutetcps
singular: ingressroutetcp
---
## Middleware
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: middlewares.traefik.containo.us
spec:
scope: Namespaced
group: traefik.containo.us
version: v1alpha1
names:
kind: Middleware
plural: middlewares
singular: middleware
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsoptions.traefik.containo.us
spec:
scope: Namespaced
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSOption
plural: tlsoptions
singular: tlsoption
---
## TraefikService
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: traefikservices.traefik.containo.us
spec:
scope: Namespaced
group: traefik.containo.us
version: v1alpha1
names:
kind: TraefikService
plural: traefikservices
singular: traefikservice
---
## TraefikTLSStore
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsstores.traefik.containo.us
spec:
scope: Namespaced
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSStore
plural: tlsstores
singular: tlsstore
---
## IngressRouteUDP
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressrouteudps.traefik.containo.us
spec:
scope: Namespaced
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteUDP
plural: ingressrouteudps
singular: ingressrouteudp
部署 CRD 資源
kubectl apply -f traefik-crd.yaml
創建 RBAC 權限
Kubernetes 在 1.6 以后的版本中引入了基於角色的訪問控制(RBAC)策略,方便對 Kubernetes 資源和 API 進行細粒度控制。Traefik 需要一定的權限,所以這里提前創建好 Traefik ServiceAccount 並分配一定的權限。
traefik-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: ingress-traefik
name: traefik-ingress-controller
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
rules:
- apiGroups: [""]
resources: ["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: ["middlewares"]
verbs: ["get","list","watch"]
- apiGroups: ["traefik.containo.us"]
resources: ["ingressroutes","traefikservices"]
verbs: ["get","list","watch"]
- apiGroups: ["traefik.containo.us"]
resources: ["ingressroutetcps","ingressrouteudps"]
verbs: ["get","list","watch"]
- apiGroups: ["traefik.containo.us"]
resources: ["tlsoptions","tlsstores"]
verbs: ["get","list","watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
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: ingress-traefik
部署 Traefik RBAC 資源
kubectl apply -f traefik-rbac.yaml
創建 Traefik 配置文件
由於 Traefik 配置很多,使用 CLI 定義操作過於繁瑣,盡量使用將其配置選項放到配置文件中,然后存入 ConfigMap,將其掛入 traefik 中。
traefik-config.yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: traefik-config
namespace: ingress-traefik
data:
traefik.yaml: |-
serversTransport:
insecureSkipVerify: true
api:
insecure: true
dashboard: true
debug: true
metrics:
prometheus: ""
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
providers:
kubernetesCRD: ""
kubernetesingress: ""
log:
filePath: ""
level: error
format: json
accessLog:
filePath: ""
format: json
bufferingSize: 0
filters:
retryAttempts: true
minDuration: 20
fields:
defaultMode: keep
names:
ClientUsername: drop
headers:
defaultMode: keep
names:
User-Agent: redact
Authorization: drop
Content-Type: keep
部署 Traefik ConfigMap 資源
kubectl apply -f traefik-config.yaml -n kube-system
設置Label標簽
由於使用的Kubernetes DeamonSet方式部署Traefik,所以需要提前給節點設置Label,當程序部署Pod會自動調度到設置 Label的node節點上。
節點設置 Label 標簽
kubectl label nodes k8s-node-1 IngressProxy=true
驗證是否成功
[root@k8s-master1 traefik]# kubectl get node --show-labels
NAME STATUS ROLES AGE VERSION LABELS
k8s-master Ready <none> 6d1h v1.18.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master,kubernetes.io/os=linux
k8s-node1 Ready <none> 6d1h v1.18.3 IngressProxy=true,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node1,kubernetes.io/os=linux
k8s-node2 Ready <none> 6d v1.18.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,ingress=true,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node2,kubernetes.io/os=linux
節點刪除Label標簽
kubectl label nodes k8s-node-1 IngressProxy-
Kubernetes 部署 Traefik
按照以前Traefik1.7部署方式,使用DaemonSet類型部署,以便於在多服務器間擴展,使用 hostport 方式占用服務器 80、443 端口,方便流量進入。
traefik-deploy.yaml
apiVersion: v1
kind: Service
metadata:
name: traefik
namespace: ingress-traefik
spec:
ports:
- name: web
port: 80
- name: websecure
port: 443
- name: admin
port: 8080
selector:
app: traefik
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: traefik-ingress-controller
namespace: ingress-traefik
labels:
app: traefik
spec:
selector:
matchLabels:
app: traefik
template:
metadata:
name: traefik
labels:
app: traefik
spec:
serviceAccountName: traefik-ingress-controller
terminationGracePeriodSeconds: 1
containers:
- image: traefik:2.2.0
name: traefik-ingress-lb
ports:
- name: web
containerPort: 80
hostPort: 80 #hostPort方式,將端口暴露到集群節點
- name: websecure
containerPort: 443
hostPort: 443 #hostPort方式,將端口暴露到集群節點
- name: admin
containerPort: 8080
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 1000m
memory: 1024Mi
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
args:
- --configfile=/config/traefik.yaml
volumeMounts:
- mountPath: "/config"
name: "config"
volumes:
- name: config
configMap:
name: traefik-config
tolerations: #設置容忍所有污點,防止節點被設置污點
- operator: "Exists"
nodeSelector: #設置node篩選器,在特定label的節點上啟動
IngressProxy: "true"
部署 Traefik
kubectl apply -f traefik-deploy.yaml
3.Traefik 路由規則基礎配置
配置 HTTP 路由規則 (Traefik Dashboard 為例)
Traefik 應用已經部署完成,但是想讓外部訪問 Kubernetes 內部服務,還需要配置路由規則,這里開啟了 Traefik Dashboard 配置,所以首先配置 Traefik Dashboard 看板的路由規則,使外部能夠訪問 Traefik Dashboard。
traefik-dashboard-route.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard-route
namespace: ingress-traefik
spec:
entryPoints:
- web
routes:
- match: Host(`traefik.example.cn`)
kind: Rule
services:
- name: traefik
port: 8080
部署Traefik Dashboard 路由規則對象
kubectl apply -f traefik-dashboard-route.yaml
接下來配置dnsmasq,客戶端想通過域名訪問服務,必須要進行DNS解析,我使用的本地 DNS 服務器進行域名解析,將 Traefik 指定節點的 IP 和自定義 域名 綁定,重啟dnsmasq服務即可。
打開任意瀏覽器輸入地址:http://traefik.example.cn進行訪問,此處沒有配置驗證登錄,如果想配置驗證登錄,使用middleware即可。
4. 配置 HTTPS 路由規則(Kubernetes Dashboard)
這里我們創建 Kubernetes 的 Dashboard,它是 基於 Https 協議方式訪問,由於它是需要使用 Https 請求,所以我們需要配置 Https 的路由規則並指定證書。
測試域名:kuboard.heian.com (內網建立的)
創建證書文件
# 創建自簽名證書
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=kuboard.heian.com"
# 將證書存儲到Kubernetes Secret中,新建的k8dash-sa-tls必須與k8dash-route中的tls: secretName一致。
kubectl create secret tls k8dash-sa-tls --key=tls.key --cert=tls.crt -n kube-system
k8dash-route.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: k8dash-sa-route
namespace: kube-system
spec:
entryPoints:
- websecure
tls:
secretName: k8dash-sa-tls
routes:
- match: Host(`kuboard.heian.com`)
kind: Rule
services:
# 此處的services是Kubernetes中的svc name 與 端口 可以使用kubectl get svc --namespace=kube-system獲取
- name: kuboard
port: 80
打開任意瀏覽器輸入地址:https://kuboard.heian.com進行訪問