在Kubernetes中部署和使用Traefik 2.0的快速指南
阅读原文,体验更佳。
前言
上一次我安装Traefik时还在使用Traefik 1.7版本,前天我这里有个项目搞容器化,部署边缘节点时,选型Ingress Controller的时候又去看了下Traefik,发现2.0版本功能强大地让人惊讶,果断选择了Traefik。
关于边缘节点的概念,可以参考我之前总结的一篇博客。
本文旨在为同行提供Traefik 2.0踩坑经验的分享。
本文内容
- 在Kubernetes中使用Helm安装Traefik的选项说明
- 关于配置边缘节点的说明
- 使用Traefik 2.0的CRD -- IngressRoute为一个HTTP和WebSocket后端服务配置路由的说明
- Traefik 2.0功能以及使用场景简单总结
阅读本文需要有以下前提:
在Kubernetes中使用Helm安装Traefik的选项说明
在k8s中安装Traefik,一般使用官方的Helm chart,就可以了。 官方的例子中没有对选项有什么解释,所以我先把chart下载下来看看有啥内容。
helm pull traefik/traefik --version 7.0.0
看过一遍之后,我也没啥想改的,除了为了把Traefik的Pod固定在指定的节点上,我打算使用Node Affinity属性之外,就没有改values.yaml
中的其他部分了。
以下为Traefik-7.0.0的chart中我修改了部分。
affinity:
# # This example pod anti-affinity forces the scheduler to put traefik pods
# # on nodes where no other traefik pods are scheduled.
# # It should be used when hostNetwork: true to prevent port conflicts
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-role
operator: In
values:
- ingress-controller
- key: ingress-controller
operator: In
values:
- traefik
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- software-traefik
topologyKey: failure-domain.beta.kubernetes.io/zone
# This example node affinity "forces" the scheduler to put traefik pods
# on nodes with specified lables.
然后使用以下的一段命令来部署了Traefik。
-
我打算将
ip-10-20-1-95
和ip-10-20-1-96
作为边缘节点,所以打上label# Specify traefik node label, to be used with node affinity kubectl label node ip-10-20-1-95 ip-10-20-1-96 node-role=ingress-controller ingress-controller=traefik
-
用
helm template
命令渲染一下模板,看看最终生成的manifest长啥样?cd ~/helm/charts/traefik mkdir -pv dry-run # Render Helm chart into dry-run to check final manifests # In dev environment, we can use Traefik dashboard. # Can use a fixed IP for Traefik service helm template -n traefik-v2 --dry-run --dependency-update --output-dir dry-run traefik-v2-r2 ./traefik-7.0.0-customized/traefik \ --set nameOverride=software-traefik \ --set image.name='harbor.YOUR-DOMAIN.com.cn/library/traefik' \ --set image.tag='2.2.0' \ --set deployment.replicas=2 \ --set ports.traefik.hostPort=9000 \ --set ports.web.hostPort=8000 \ --set ports.websecure.hostPort=8443 \ --set additionalArguments="{--accesslog=true}" \ --set service.type=ClusterIP \ --set service.spec.clusterIP='10.20.211.200'
-
正式安装Traefik
# Install Traefik helm upgrade --history-max 10 --atomic --install --namespace traefik-v2 traefik-v2 ./traefik-7.0.0-customized/traefik/ \ --set nameOverride=software-traefik \ --set image.name='harbor.YOUR-DOMAIN.com.cn/library/traefik' \ --set image.tag='2.2.0' \ --set deployment.replicas=2 \ --set ports.traefik.hostPort=9000 \ --set ports.web.hostPort=8000 \ --set ports.websecure.hostPort=8443 \ --set additionalArguments="{--accesslog=true}" \ --set service.type=ClusterIP \ --set service.spec.clusterIP='10.20.211.200'
关于配置边缘节点的说明
首先解释下什么叫边缘节点(Edge Node),所谓的边缘节点即集群内部用来向集群外暴露服务能力的节点,集群外部的服务通过该节点来调用集群内部的服务,边缘节点是集群内外交流的一个Endpoint。
以上面部分部署时的配置来说,就是把Traefik部署的node通过Node Affinity固定在ip-10-20-1-95
和ip-10-20-1-96
这2个节点上了。
Pod
以hostPort
方式运行,所以集群外可以通过NODE_IP:PORT
访问到Traefik。
在外部秩序配置一个4层的load balancing,后端指向ip-10-20-1-95
和ip-10-20-1-96
这2个节点的Traefik的端口就可以了。
使用Traefik 2.0的CRD – IngressRoute为一个HTTP和WebSocket后端服务配置路由的说明
-
创建用于TLS证书的secret,注意secret中的文件名必须为固定值
注意Traefik的IngressRoute必须和TLS的secret在同一namespace下才能获取到到secret。
# Create secret for Traffic ingressRoute to use # Secret must be in the same namespace with ingressRoute # The filename inside the secret must be 'tls.crt' and 'tls.key' cat<<-'EOF' | kubectl apply -f - apiVersion: v1 kind: Secret metadata: name: secret-name namespace: namespace-name # `type` is not needed to be specified # type: kubernetes.io/tls data: tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0... tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVk... EOF
可选项,TLSStore可以定义一个默认的secret。
# This is optional, if you only use one cert, e.g. "*.example.com", you can use TLSStore to define a default TLS secret to be used in ingressRoute cat<<-'EOF' | kubectl apply -f - apiVersion: traefik.containo.us/v1alpha1 kind: TLSStore metadata: name: tlsstore-name namespace: namespace-name spec: defaultCertificate: secretName: secret-name EOF
-
创建IngressRoute,用来配置Traefik中实际的路由规则。顺带吐槽以下,Traefik官网上关于配置的说明还是不够详细。
cat<<-'EOF' | kubectl apply -f -
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: svc-your-app-http
namespace: namespace-name
spec:
entryPoints:
- web
routes:
- match: Host(`YOUR-APP.YOUR-DOMAIN.com.cn`)
middlewares:
- name: svc-YOUR-APP-redirectscheme-to-https
kind: Rule
services:
- name: YOUR-APP
port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: svc-your-app-https
namespace: namespace-name
spec:
entryPoints:
- websecure
routes:
- match: Host(`YOUR-APP.YOUR-DOMAIN.com.cn`)
middlewares:
- name: svc-YOUR-APP-headers
kind: Rule
services:
- name: YOUR-APP
port: 80
tls:
secretName: secret-name
domains:
- main: YOUR-DOMAIN.com.cn
sans:
- YOUR-APP.YOUR-DOMAIN.com.cn
# certResolver: default
# options: {}
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: svc-YOUR-APP-redirectscheme-to-https
namespace: namespace-name
spec:
redirectScheme:
scheme: https
permanent: true
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: svc-YOUR-APP-headers
spec:
headers:
customRequestHeaders:
X-Forwarded-Proto: "https"
Traefik 2.0功能以及使用场景简单总结
Traefik 2.0 新增了万众期待的TCP、UDP代理,而且还可以配置相当灵活的转发规则,比如同一个Host(app.example.com)
下,/dashboard/
这个path
转发到web-ui
这个Service
,而/api/
转发到api
这个Service。
还有各种内置Middleware
可以使用,比如对请求头的操作、重定向、截取path、basicauth等。
总之就是一个功能强大的Application Load Balancing和Network Load Balancing了。