Kubernetes環境Traefik部署與應用

本作品Galen Suen採用知識共享署名-非商業性使用-禁止演繹 4.0 國際許可協議進行許可。由原作者轉載自個人站點

Traefik Dashboard

概述

本文用於整理基於Kubernetes環境的Traefik部署與應用,實現Ingress Controller、七層/四層反向代理等功能。

本次演練環境為Kubernetes集群環境,環境配置可參考筆者另一篇筆記《Kubernetes集群部署筆記》。

組件版本

配置過程

安裝Traefik

  • 配置Helm Repo

    helm repo add traefik //helm.traefik.io/traefik
    helm repo update
    
  • 安裝Traefik

    本次演練中將traefik安裝至kube-system命名空間,可根據需要替換。

    # deployment.replicas=3 設置Traefik部署副本數
    # pilot.dashboard=false 禁用Dashboard中Pilot鏈接。
    helm upgrade --install --namespace kube-system \
      --set deployment.replicas=3 \
      --set pilot.dashboard=false \
      traefik traefik/traefik
    
  • 其他準備工作

    獲取traefik服務的負載均衡器地址。執行該命令,記錄返回的EXTERNAL-IP地址備用。本次演練環境中,已將local.choral.io*.local.choral.io指向該地址。

    kubectl get svc traefik -n kube-system
    

    創建一個用於部署演練用對象的命名空間。本次演練中使用apps-choral命名空間,可根據需要替換。

    kubectl create namespace apps-choral
    

部署Dashboard

  • 創建IngressRoute

    創建一個IngressRoute,用於配置apidashboard的入口規則。

    本次演練中,使用traefik.local.choral.io域名訪問Dashboard,可根據需要替換。

    cat <<EOF | kubectl apply -f -
    apiVersion: traefik.containo.us/v1alpha1
    kind: IngressRoute
    metadata:
      name: traefik-dashboard
      namespace: apps-choral
    spec:
      entryPoints:
        - web
      routes:
        - match: Host(`traefik.local.choral.io`) && (PathPrefix(`/dashboard`) || PathPrefix(`/api`))
          kind: Rule
          services:
            - name: api@internal
              kind: TraefikService
    EOF
    
  • 啟用BasicAuth認證

    首先,創建一個用於保存用戶名和密碼的Secret,其中的users欄位內容可使用htpassword工具生成。本次演練中,認證usernamepassword都是admin

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Secret
    metadata:
      name: traefik-basicauth-secret
      namespace: apps-choral
    data:
      users: |2 # htpasswd -nb admin admin | openssl base64
        YWRtaW46e1NIQX0wRFBpS3VOSXJyVm1EOElVQ3V3MWhReE5xWmM9Cg==
    EOF
    

    創建一個Traefik中間件,用於對請求啟用BasicAuth認證。

    cat <<EOF | kubectl apply -f -
    apiVersion: traefik.containo.us/v1alpha1
    kind: Middleware
    metadata:
      name: traefik-basicauth
      namespace: apps-choral
    spec:
      basicAuth:
        realm: traefik.local.choral.io
        secret: traefik-basicauth-secret
    EOF
    

    更新DashboardIngressRoute,啟用BasicAuth中間件。

    cat <<EOF | kubectl apply -f -
    apiVersion: traefik.containo.us/v1alpha1
    kind: IngressRoute
    metadata:
      name: traefik-dashboard
      namespace: apps-choral
    spec:
      entryPoints:
        - web
      routes:
        - match: Host(`traefik.local.choral.io`) && (PathPrefix(`/dashboard`) || PathPrefix(`/api`))
          kind: Rule
          services:
            - name: api@internal
              kind: TraefikService
          middlewares:
            - name: traefik-basicauth
    EOF
    

七層反向代理

HTTP應用示例

  • 部署whoami應用

    創建Deployment,部署whoami應用。

    cat <<EOF | kubectl apply -f -
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: whoami
      namespace: apps-choral
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: whoami
      template:
        metadata:
          labels:
            app: whoami
        spec:
          containers:
            - name: whoami
              image: traefik/whoami:latest
              imagePullPolicy: IfNotPresent
              ports:
                - containerPort: 80
    EOF
    

    創建一個用於訪問whoami應用的服務。

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: whoami
      namespace: apps-choral
    spec:
      type: ClusterIP
      ports:
        - protocol: TCP
          port: 80
      selector:
        app: whoami
    EOF
    

    創建一個Ingress,用於配置whoami應用的入口規則。

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: whoami
      namespace: apps-choral
      annotations:
        traefik.ingress.kubernetes.io/router.entrypoints: web
    spec:
      rules:
        - host: local.choral.io
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: whoami
                    port:
                      number: 80
    EOF
    

啟用TLS(HTTPS)

本次演練使用靜態證書配置TLS,該證書被手動創建,應用於local.choral.io*.local.choral.io域名。

有關自動證書管理,可參考Cert Manager項目文檔。

  • 更新Traefik運行參數

    # ports.web.redirectTo=websecure                          啟用Web跳轉至WebSecure
    # additionalArguments[0]=--entrypoints.websecure.http.tls Ingress默認啟用TLS
    helm upgrade --install --namespace kube-system \
      --set deployment.replicas=3 \
      --set pilot.dashboard=false \
      --set ports.web.redirectTo=websecure \
      --set additionalArguments[0]=--entrypoints.websecure.http.tls \
      traefik traefik/traefik
    
  • 創建TLS證書Secret

    從已準備好的證書key文件和crt文件創建Secret

    kubectl create secret tls local-choral-io-tls -n kube-system --key=local.choral.io.key --cert=local.choral.io.crt
    
  • 更新DashboardIngressRoute

    更新DashboardIngressRoute,啟用TLS配置。

    cat <<EOF | kubectl apply -f -
    apiVersion: traefik.containo.us/v1alpha1
    kind: IngressRoute
    metadata:
      name: traefik-dashboard
      namespace: apps-choral
    spec:
      entryPoints:
        - websecure
      routes:
        - match: Host(`traefik.local.choral.io`) && (PathPrefix(`/dashboard`) || PathPrefix(`/api`))
          kind: Rule
          services:
            - name: api@internal
              kind: TraefikService
          middlewares:
            - name: traefik-basicauth
      tls:
        secretName: local-choral-io-tls
    EOF
    
  • 更新whoamiIngress

    更新whoamiIngress,啟用TLS配置。

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: whoami
      namespace: apps-choral
      annotations:
        traefik.ingress.kubernetes.io/router.entrypoints: websecure
    spec:
      tls:
        - secretName: local-choral-io-tls
      rules:
        - host: local.choral.io
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: whoami
                    port:
                      number: 80
    EOF
    

四層反向代理

TCP應用示例

  • 更新Traefik運行參數

    更新Traefik運行參數,創建新的EntryPoint

    # ports.whoamitcp.protocol=TCP     網路協議
    # ports.whoamitcp.port=8081        監聽埠
    # ports.whoamitcp.exposedPort=8081 服務公開埠
    # ports.whoamitcp.expose=true      是否暴露埠
    helm upgrade --install --namespace kube-system \
      --set deployment.replicas=3 \
      --set pilot.dashboard=false \
      --set ports.web.redirectTo=websecure \
      --set additionalArguments[0]=--entrypoints.websecure.http.tls \
      --set ports.whoamitcp.protocol=TCP \
      --set ports.whoamitcp.port=8081 \
      --set ports.whoamitcp.exposedPort=8081 \
      --set ports.whoamitcp.expose=true \
      traefik traefik/traefik
    
  • 部署whoamitcp應用

    創建Deployment,部署whoamitcp應用。

    cat <<EOF | kubectl apply -f -
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: whoamitcp
      namespace: apps-choral
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: whoamitcp
      template:
        metadata:
          labels:
            app: whoamitcp
        spec:
          containers:
            - name: whoamitcp
              image: traefik/whoamitcp:latest
              imagePullPolicy: IfNotPresent
              ports:
                - protocol: TCP
                  containerPort: 8080
    EOF
    

    創建一個用於訪問whoamitcp應用的服務。

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: whoamitcp
      namespace: apps-choral
    spec:
      type: ClusterIP
      ports:
        - protocol: TCP
          port: 8080
      selector:
        app: whoamitcp
    EOF
    

    創建一個IngressRouteTCP,用於配置whoamitcp應用的入口規則。

    cat <<EOF | kubectl apply -f -
    apiVersion: traefik.containo.us/v1alpha1
    kind: IngressRouteTCP
    metadata:
      name: whoamitcp
      namespace: apps-choral
    spec:
      entryPoints:
        - whoamitcp
      routes:
        - match: HostSNI(\`*\`)
          services:
            - name: whoamitcp
              port: 8080
    EOF
    

    驗證反向代理和服務運行狀態。

    # `10.0.0.201`是`traefik`服務的負載均衡器地址(kubectl get svc traefik -n kube-system)
    echo "Hello" | socat - tcp4:10.0.0.201:8081
    # 終端回顯如下內容
    Received: Hello
    

UDP應用示例

  • 更新Traefik運行參數

    更新Traefik運行參數,創建新的EntryPoint

    # ports.whoamiudp.protocol=UDP     網路協議
    # ports.whoamiudp.port=8082        監聽埠
    # ports.whoamiudp.exposedPort=8082 服務公開埠
    # ports.whoamiudp.expose=true      是否暴露埠
    helm upgrade --install --namespace kube-system \
      --set deployment.replicas=3 \
      --set pilot.dashboard=false \
      --set ports.web.redirectTo=websecure \
      --set additionalArguments[0]=--entrypoints.websecure.http.tls \
      --set ports.whoamitcp.protocol=TCP \
      --set ports.whoamitcp.port=8081 \
      --set ports.whoamitcp.exposedPort=8081 \
      --set ports.whoamitcp.expose=true \
      --set ports.whoamiudp.protocol=UDP \
      --set ports.whoamiudp.port=8082 \
      --set ports.whoamiudp.exposedPort=8082 \
      --set ports.whoamiudp.expose=true \
      traefik traefik/traefik
    
  • 部署whoamiudp應用

    創建Deployment,部署whoamiudp應用。

    cat <<EOF | kubectl apply -f -
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: whoamiudp
      namespace: apps-choral
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: whoamiudp
      template:
        metadata:
          labels:
            app: whoamiudp
        spec:
          containers:
            - name: whoamiudp
              image: traefik/whoamiudp:latest
              imagePullPolicy: IfNotPresent
              ports:
                - protocol: UDP
                  containerPort: 8080
    EOF
    

    創建一個用於訪問whoamiudp應用的服務。

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: whoamiudp
      namespace: apps-choral
    spec:
      type: ClusterIP
      ports:
        - protocol: UDP
          port: 8080
      selector:
        app: whoamiudp
    EOF
    

    創建一個IngressRouteUDP,用於配置whoamiudp應用的入口規則。

    cat <<EOF | kubectl apply -f -
    apiVersion: traefik.containo.us/v1alpha1
    kind: IngressRouteUDP
    metadata:
      name: whoamiudp
      namespace: apps-choral
    spec:
      entryPoints:
        - whoamiudp
      routes:
        - services:
            - name: whoamiudp
              port: 8080
    EOF
    

    驗證反向代理和服務運行狀態。

    # `10.0.0.202`是`traefik-udp`服務的負載均衡器地址(kubectl get svc traefik-udp -n kube-system)
    echo "Hello" | socat - udp4:10.0.0.202:8082
    # 終端回顯如下內容
    Received: Hello
    

參考資料