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

概述

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

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

元件版本

配置過程

安裝Traefik

  • 配置Helm Repo

    helm repo add traefik https://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

參考資料