系统环境:
- Traefik 版本:v2.2.8
- Kubernetes 版本:v1.18.3
一、Traefik 简介
Traefik 是一款开源的边缘路由器,它可以让发布服务变得轻松有趣。它代表您的系统接收请求,并找出负责处理这些
Traefik 与每个主要的集群技术都是原生兼容的,比如 Kubernetes、Docker、Docker Swarm、AWS、Mesos、Marathon 等等;并且可以同时处理多个。(它甚至适用于运行在裸机上的遗留软件。) 使用 Traefik,不需要维护和同步单独的配置文件:所有事情都是实时自动发生的(没有重启,没有连接中断)。使用 Traefik,只需要花费时间开发和
二、Kubernetes 部署 Traefik
Traefik 最新推出了 v2.2 版本,这里将 Traefik 升级到最新版本,简单的介绍了下如何在 Kubernetes 环境下安装 Traefik v2.2.8,下面将介绍如何在 Kubernetes 环境下部署并配置 Traefik v2.2.8。
当部署完 Traefik 后还需要创建外部访问 Kubernetes 内部应用的路由规则,Traefik 支持两种方式创建路由规则,一种是创建 Traefik 自定义 Kubernetes CRD
资源方式,还有一种是创建 Kubernetes Ingress
资源方式。
注意:这里 Traefik 是部署在 Kube-system Namespace 下,如果不是需要修改下面部署文件中的 Namespace 属性。
1、创建 CRD 资源
在 traefik v2.0 版本后,开始使用 CRD(Custom Resource Definition)来完成路由配置等,所以需要提前创建 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
---
## TLSOption
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
---
## TLSStore
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsstores.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSStore
plural: tlsstores
singular: tlsstore
scope: Namespaced
---
## IngressRouteUDP
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressrouteudps.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteUDP
plural: ingressrouteudps
singular: ingressrouteudp
scope: Namespaced
创建 Traefik CRD 资源
$ kubectl apply -f traefik-crd.yaml
2、创建 RBAC 权限
Kubernetes 在 1.6 版本中引入了基于角色的访问控制(RBAC)策略,方便对 Kubernetes 资源和 API 进行细粒度控制。Traefik 需要一定的权限,所以这里提前创建好 Traefik ServiceAccount 并分配一定的权限。
创建 traefik-rbac.yaml 文件
## ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: kube-system
name: traefik-ingress-controller
---
## ClusterRole
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","ingressroutes","ingressroutetcps","tlsoptions","ingressrouteudps","traefikservices","tlsstores"]
verbs: ["get","list","watch"]
---
## ClusterRoleBinding
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: kube-system
创建 Traefik RBAC 资源
- -n:指定部署的 Namespace
$ kubectl apply -f traefik-rbac.yaml -n kube-system
3、创建 Traefik 配置文件
由于 Traefik 配置很多,通过 CLI 定义不是很方便,一般时候选择将其配置选项放到配置文件中,然后存入 ConfigMap,将其挂入 traefik 中。
下面配置中可以通过配置 kubernetesCRD 与 kubernetesIngress 两项参数,让 Traefik 支持 CRD 与 Ingress 两种路由方式。
创建 traefik-config.yaml 文件
kind: ConfigMap
apiVersion: v1
metadata:
name: traefik-config
data:
traefik.yaml: |-
ping: "" ## 启用 Ping
serversTransport:
insecureSkipVerify: true ## Traefik 忽略验证代理服务的 TLS 证书
api:
insecure: true ## 允许 HTTP 方式访问 API
dashboard: true ## 启用 Dashboard
debug: false ## 启用 Debug 调试模式
metrics:
prometheus: "" ## 配置 Prometheus 监控指标数据,并使用默认配置
entryPoints:
web:
address: ":80" ## 配置 80 端口,并设置入口名称为 web
websecure:
address: ":443" ## 配置 443 端口,并设置入口名称为 websecure
providers:
kubernetesCRD: "" ## 启用 Kubernetes CRD 方式来配置路由规则
kubernetesIngress: "" ## 启动 Kubernetes Ingress 方式来配置路由规则
log:
filePath: "" ## 设置调试日志文件存储路径,如果为空则输出到控制台
level: error ## 设置调试日志级别
format: json ## 设置调试日志格式
accessLog:
filePath: "" ## 设置访问日志文件存储路径,如果为空则输出到控制台
format: json ## 设置访问调试日志格式
bufferingSize: 0 ## 设置访问日志缓存行数
filters:
#statusCodes: ["200"] ## 设置只保留指定状态码范围内的访问日志
retryAttempts: true ## 设置代理访问重试失败时,保留访问日志
minDuration: 20 ## 设置保留请求时间超过指定持续时间的访问日志
fields: ## 设置访问日志中的字段是否保留(keep 保留、drop 不保留)
defaultMode: keep ## 设置默认保留访问日志字段
names: ## 针对访问日志特别字段特别配置保留模式
ClientUsername: drop
headers: ## 设置 Header 中字段是否保留
defaultMode: keep ## 设置默认保留 Header 中字段
names: ## 针对 Header 中特别字段特别配置保留模式
User-Agent: redact
Authorization: drop
Content-Type: keep
#tracing: ## 链路追踪配置,支持 zipkin、datadog、jaeger、instana、haystack 等
# serviceName: ## 设置服务名称(在链路追踪端收集后显示的服务名)
# zipkin: ## zipkin配置
# sameSpan: true ## 是否启用 Zipkin SameSpan RPC 类型追踪方式
# id128Bit: true ## 是否启用 Zipkin 128bit 的跟踪 ID
# sampleRate: 0.1 ## 设置链路日志采样率(可以配置0.0到1.0之间的值)
# httpEndpoint: http://localhost:9411/api/v2/spans ## 配置 Zipkin Server 端点
创建 Traefik ConfigMap 资源
- -n: 指定程序启的 Namespace
$ kubectl apply -f traefik-config.yaml -n kube-system
4、节点设置 Label 标签
由于是 Kubernetes DeamonSet 这种方式部署 Traefik,所以需要提前给节点设置 Label,这样当程序部署时 Pod 会自动调度到设置 Label 的点上。
节点设置 Label 标签
- 格式:kubectl label nodes [节点名] [key=value]
$ kubectl label nodes 192.168.99.1 IngressProxy=true
查看节点是否设置 Label 成功
$ kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
192.168.99.1 Ready,SchedulingDisabled master 6d7h v1.18.3 IngressProxy=true,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=192.168.99.1,kubernetes.io/os=linux,kubernetes.io/role=master
192.168.99.2 Ready,SchedulingDisabled master 6d7h v1.18.3 IngressProxy=true,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=192.168.99.2,kubernetes.io/os=linux,kubernetes.io/role=master
192.168.99.3 Ready node 6d7h v1.18.3 IngressProxy=true,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=192.168.99.3,kubernetes.io/os=linux,kubernetes.io/role=node,test=test
192.168.99.4 Ready node 6d7h v1.18.3 IngressProxy=true,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=192.168.99.4,kubernetes.io/os=linux,kubernetes.io/role=node
如果想删除标签,可以使用
kubectl label nodes 192.168.99.1 IngressProxy-
命令
5、Kubernetes 部署 Traefik
这里用 DaemonSet 方式部署,便于在多服务器间扩展,用 hostport 方式占用服务器 80、443 端口,方便流量通过物理机进入 Kubernetes
内部。
创建 traefik 部署文件 traefik-deploy.yaml
apiVersion: v1
kind: Service
metadata:
name: 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
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:v2.2.8
name: traefik-ingress-lb
ports:
- name: web
containerPort: 80
hostPort: 80 ## 将容器端口绑定所在服务器的 80 端口
- name: websecure
containerPort: 443
hostPort: 443 ## 将容器端口绑定所在服务器的 443 端口
- name: admin
containerPort: 8080 ## Traefik Dashboard 端口
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"
readinessProbe:
httpGet:
path: /ping
port: 8080
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
livenessProbe:
httpGet:
path: /ping
port: 8080
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
volumes:
- name: config
configMap:
name: traefik-config
tolerations: ## 设置容忍所有污点,防止节点被设置污点
- operator: "Exists"
nodeSelector: ## 设置node筛选器,在特定label的节点上启动
IngressProxy: "true"
Kubernetes 部署 Traefik
$ kubectl apply -f traefik-deploy.yaml -n kube-system
到此 Traefik v2.2.8 应用已经部署完成。
三、Traefik 路由规则配置
Traefik 应用已经部署完成,但是想让外部访问 Kubernetes
内部服务,还需要配置路由规则,上面部署 Traefik
时开启了 Traefik Dashboard
,这是 Traefik
提供的视图看板,所以,首先配置基于 HTTP
的 Traefik Dashboard
路由规则,使外部能够访问 Traefik Dashboard
。然后,再配置基于 HTTPS
的 Kubernetes Dashboard
的路由规则,这里分别使用 CRD
和 Ingress
两种方式进行演示。
1、方式一:使用 CRD 方式配置 Traefik 路由规则
(1)、配置 HTTP 路由规则 (Traefik Dashboard 为例)
# 创建 Traefik Dashboard 路由规则 traefik-dashboard-route.yaml 文件
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard-route
spec:
entryPoints:
- web
routes:
- match: Host(`traefik.infvie.org`)
kind: Rule
services:
- name: traefik
port: 8080
# 创建 Traefik Dashboard 路由规则对象
$ kubectl apply -f traefik-dashboard-route.yaml -n kube-system
(2)、配置 HTTPS 路由规则(Kubernetes Dashboard 为例)
这里我们创建 Kubernetes
的 Dashboard
看板创建路Https
协议方式,由于它是需要使用 Https 请
# 创建私有证书 tls.key、tls.crt 文件
# 创建自签名证书
$ openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=cloud.infvie.org"
# 将证书存储到 Kubernetes Secret 中
$ kubectl create secret generic cloud-tls --from-file=tls.crt --from-file=tls.key -n kube-system
# 创建 Traefik Dashboard CRD 路由规则 kubernetes-dashboard-route.yaml 文件
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: kubernetes-dashboard-route
spec:
entryPoints:
- websecure
tls:
secretName: cloud-tls
routes:
- match: Host(`cloud.infvie.org`)
kind: Rule
services:
- name: kubernetes-dashboard
port: 443
# 创建 Kubernetes Dashboard 路由规则对象
$ kubectl apply -f kubernetes-dashboard-route.yaml -n kube-system
2、方式二:使用 Ingress 方式配置 Traefik 路由规则
使用 Ingress 方式创建路由规则可言参考 Traefik 文档 Kubernetes Ingress
(1)、配置 HTTP 路由规则 (Traefik Dashboard 为例)
# 创建 Traefik Ingress 路由规则 traefik-dashboard-ingress.yaml 文件
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: traefik-dashboard-ingress
namespace: kube-system
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
rules:
- host: traefik.infvie.org
http:
paths:
- path: /
backend:
serviceName: traefik
servicePort: 8080
# 创建 Traefik Dashboard Ingress 路由规则对象
$ kubectl apply -f traefik-dashboard-ingress.yaml -n kube-system
(2)、配置 HTTPS 路由规则(Kubernetes Dashboard 为例)
跟上面以CRD
方式创建路由规则一样,也需要创建使用证书,然后再以Ingress
方式创建路由规则。
# 创建私有证书 tls.key、tls.crt 文件
# 创建自签名证书
$ openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=cloud.infvie.org"
# 将证书存储到 Kubernetes Secret 中
$ kubectl create secret generic cloud-tls --from-file=tls.crt --from-file=tls.key -n kube-system
# 创建 Traefik Dashboard Ingress 路由规则 kubernetes-dashboard-ingress.yaml 文件
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: kubernetes-dashboard-ingress
namespace: kube-system
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.tls: "true"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
spec:
tls:
- secretName: cloud-tls
rules:
- host: cloud.infvie.org
http:
paths:
- path: /
backend:
serviceName: kubernetes-dashboard
servicePort: 443
# 创建 Traefik Dashboard 路由规则对象
$ kubectl apply -f kubernetes-dashboard-ingress.yaml -n kube-system
四、方式创建路由规则后的应用
配置完成后,打开浏览器输入地址:http://traefik.infvie.org 打开 Traefik Dashboar
配置完成后,打开浏览器输入地址:https://cloud.infvie.org打开 Kubernetes Dashboard。
请问下,traefik默认就能映射80和443端口吗?
我使用rancher安装的k8s,但是端口使用别的绑定的,不如8090:80,8443:443,这样绑定的