在Kubernetes中部署和使用Traefik 2.0的快速指南

2,462 阅读4分钟

在Kubernetes中部署和使用Traefik 2.0的快速指南

阅读原文,体验更佳。

shouneng.website/2020/04/08/…

前言

上一次我安装Traefik时还在使用Traefik 1.7版本,前天我这里有个项目搞容器化,部署边缘节点时,选型Ingress Controller的时候又去看了下Traefik,发现2.0版本功能强大地让人惊讶,果断选择了Traefik。

关于边缘节点的概念,可以参考我之前总结的一篇博客

本文旨在为同行提供Traefik 2.0踩坑经验的分享。

本文内容

  1. 在Kubernetes中使用Helm安装Traefik的选项说明
  2. 关于配置边缘节点的说明
  3. 使用Traefik 2.0的CRD -- IngressRoute为一个HTTP和WebSocket后端服务配置路由的说明
  4. Traefik 2.0功能以及使用场景简单总结

阅读本文需要有以下前提:

  • Kubernetes的基本概念要清晰
  • Helm的组件逻辑结构(Repo、Chart、release、template等),基本使用等经验

在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-95ip-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-95ip-10-20-1-96这2个节点上了。

PodhostPort方式运行,所以集群外可以通过NODE_IP:PORT访问到Traefik。

在外部秩序配置一个4层的load balancing,后端指向ip-10-20-1-95ip-10-20-1-96这2个节点的Traefik的端口就可以了。

使用Traefik 2.0的CRD – IngressRoute为一个HTTP和WebSocket后端服务配置路由的说明

  1. 创建用于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
    
  2. 创建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了。