Traefik2.2安装
Traefik 2.2 新增的功能如下
支持了 udp
traefik2.2 支持使用 K/V 存储做为动态配置的源,分别是
consul
,etcd
,Redis
,zookeeper
能够使用 kubernetes CRD 自定义资源定义 UDP 负载平衡
IngressRouteUDP
。能够使用
rancher
,consul catalog
,docker
和marathon
中的标签定义 UDP 的负载平衡增加了对 ingress 注解的主持
将 TLS 存储功能
TLSStores
添加到 Kubernetes CRD 中,使 kubernetes 用户无需使用配置文件和安装证书即可提供默认证书。在日志中增加了 http 的请求方式,是 http 还是 https
因为 TLS 的配置可能会影响 CPU 的使用率,因此增加了
TLS version
和TLS cipher
使用的指标信息当前的 WRR 算法对于权重不平衡端点存在严重的偏差问题,将 EDF 调度算法用于 WeightedRoundRobin,
Envoy
也是使用了EOF调度算法
支持请求主体用于流量镜像
增加了
ElasticAPM
作为 traefik 的 tracing 系统。Traefik 的 Dashboard 增加了 UDP 的页面
Traefik 也增加了黑暗主题
下面进行安装过程。
注:我们这里是将 traefik 部署在 ingress-traefik 命名空间,如果你需要部署在其他命名空间,需要更改资源清单,如果你是部署在和我同样的命令空间中,你需要创建该命名空间。
创建命名空间:
# kubectl create ns ingress-traefik
1、创建 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
创建资源清单:
# kubectl apply -f traefik-crd.yaml
# kubectl get crd
NAME CREATED AT
ingressroutes.traefik.containo.us 2019-12-13T05:40:30Z
ingressroutetcps.traefik.containo.us 2019-12-13T05:40:30Z
middlewares.traefik.containo.us 2019-12-13T05:40:30Z
2、创建 RBAC 权限
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
创建 RBAC 资源清单:
# kubectl apply -f traefik-rbac.yaml
3、创建 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: ""
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
创建 ConfigMap:
# kubectl apply -f traefik-config.yaml
4、给节点打标签
由于是 Kubernetes DeamonSet 这种方式部署 Traefik,所以需要提前给节点设置 Label,这样当程序部署时 Pod 会自动调度到设置 Label 的点上。
节点设置 Label 标签
- 格式:kubectl label nodes [节点名] [key=value]
kubectl label nodes 172.16.0.33 IngressProxy=true
查看节点标签:
# kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
172.16.0.33 Ready,SchedulingDisabled master 20d v1.15.0 IngressProxy=true,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/fluentd-ds-ready=true,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.0.33,kubernetes.io/os=linux,kubernetes.io/role=master
172.16.0.52 Ready node 20d v1.15.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/fluentd-ds-ready=true,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.0.52,kubernetes.io/os=linux,kubernetes.io/role=node
5、部署 traefik
很多时候我们会采用 DS 方式部署,并且设置网络为 hostNetwork=True,这样方便流量进入。但是在这里我采用的是 service 的 nodeport 进行暴露。
(1)、Service 的配置清单
traefik-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: traefik
namespace: ingress-traefik
spec:
type: NodePort
ports:
- name: web
port: 80
- name: websecure
port: 443
- name: admin
port: 8080
selector:
app: traefik
(2)、DS 的配置清单
traefik-ds.yaml
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: registry.cn-hangzhou.aliyuncs.com/rookieops/traefik:v2.2.0
name: traefik-ingress-lb
ports:
- name: web
containerPort: 80
- name: websecure
containerPort: 443
- 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"
3) 配置 traefik 路由规则
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard-route
namespace: ingress-traefik
spec:
entryPoints:
- web
routes:
- match: Host(`traefik.coolops.cn`)
kind: Rule
services:
- name: traefik
port: 8080
然后创建资源:
# kubectl apply -f traefik-svc.yaml
# kubectl apply -f traefik-ds.yaml
# kubectl get svc -n ingress-traefik
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
traefik NodePort 10.102.225.66 <none> 80:30161/TCP,443:30629/TCP,8080:32359/TCP 31m
# kubectl get pod -n ingress-traefik
NAME READY STATUS RESTARTS AGE
traefik-ingress-controller-whbjm 1/1 Running 0 22m
然后本地配置 hosts
10.1.10.128 traefik.coolops.cn
由于我们 ingress 是通过 svc 的 nodeport 暴露的,所以输入以下访问
并且可以看到我配置的 HTTP
6、配置 SSL
这里使用 Let's Encrypt 来进行自动化 HTTPS。
修改配置文件,新增如下内容:
certificatesresolvers:
default:
acme:
tlsChallenge: {}
email: "coolops@163.com"
storage: "acme.json"
更新配置文件。
新增一个 https 的 ingressRoute,如下:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-webui-tls
namespace: ingress-traefik
spec:
entryPoints:
- websecure # 注意这里是websecure这个entryPoint,监控443端口
routes:
- match: Host(`traefik.coolops.cn`)
kind: Rule
services:
- name: traefik
port: 8080
tls:
certResolver: default
查看 pod 的日志信息,报错如下:
{"level":"error","msg":"Unable to obtain ACME certificate for domains \"traefik.coolops.cn\": cannot get ACME client get directory at 'https://acme-v02.api.letsencrypt.org/directory': Get \"https://acme-v02.api.letsencrypt.org/directory\": dial tcp 172.65.32.248:443: connect: connection refused","providerName":"default.acme","routerName":"ingress-traefik-traefik-webui-tls-fcde00a088d29eefb3a6@kubernetescrd","rule":"Host(`traefik.coolops.cn`)","time":"2020-05-26T02:49:49Z"}
这是因为 pod 里的网络和https://acme-v02.api.letsencrypt.org/directory 不通造成的。
部署成功后可以使用 HTTPS 访问了。
上面是自动生成证书,如果有自己的域名证书,那么一切都简单了,你只需要配置一个 secret,然后在 ingressRoute 中引用即可,比如下面来自官方的例子:
apiVersion: v1
kind: Secret
metadata:
name: supersecret
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutetls
spec:
entryPoints:
- web
routes:
- match: Host(`foo.com`) && PathPrefix(`/bar`)
kind: Rule
services:
- name: whoami
port: 443
tls:
secretName: supersecret
用 Let's Encrypt 的话,虽然免费,用起来还是有坑,这就需要自己去踩了~~!