:::info 此文已归档,为几年前初次使用时记录的Traefik v1的安装部署,过程繁琐,现Traefik已升级为v2,使用Helm部署也更加方便了,本文不建议阅读。 :::

traefik 是一个前端负载均衡器,对于微服务架构尤其是 kubernetes 等编排工具具有良好的支持;

相对于 nginx ingress,traefix 能够实时跟 Kubernetes API 交互,感知后端 Service、Pod 变化,自动更新配置并热重载。Traefik 更快速更方便,同时支持更多的特性,使反向代理、负载均衡更直接更高效。

一、使用 k8s-ha-install 部署

创建 k8s-master-lb 的证书

  1. kubectl -n kube-system create secret generic traefik-cert --from-file=tls.key --from-file=tls.crt

把证书写入到 k8s 的 secret

  1. kubectl -n kube-system create secret generic traefik-cert --from-file=tls.key --from-file=tls.crt

进入到 k8s-ha-install 目录执行

  1. [root@k8s-master1 k8s-ha-install]# kubectl apply -f traefik/
  2. serviceaccount/traefik-ingress-controller created
  3. clusterrole.rbac.authorization.k8s.io/traefik-ingress-controller created
  4. clusterrolebinding.rbac.authorization.k8s.io/traefik-ingress-controller created
  5. configmap/traefik-conf created
  6. daemonset.extensions/traefik-ingress-controller created
  7. service/traefik-web-ui created
  8. ingress.extensions/traefik-jenkins created

浏览器访问 http://k8s-master-lb:30011/dashboard/ 即可看到:
📃 部署Traefik v1(已过时,仅归档记录) - 图1

创建测试应用

traefik-test.yaml

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: nginx-svc
  5. spec:
  6. template:
  7. metadata:
  8. labels:
  9. name: nginx-svc
  10. namespace: traefix-test
  11. selector:
  12. run: ngx-pod
  13. ports:
  14. - protocol: TCP
  15. port: 80
  16. targetPort: 80
  17. ---
  18. apiVersion: apps/v1beta1
  19. kind: Deployment
  20. metadata:
  21. name: ngx-pod
  22. spec:
  23. replicas: 4
  24. template:
  25. metadata:
  26. labels:
  27. run: ngx-pod
  28. spec:
  29. containers:
  30. - name: nginx
  31. image: nginx:1.10
  32. ports:
  33. - containerPort: 80
  34. ---
  35. apiVersion: extensions/v1beta1
  36. kind: Ingress
  37. metadata:
  38. name: ngx-ing
  39. annotations:
  40. kubernetes.io/ingress.class: traefik
  41. spec:
  42. rules:
  43. - host: traefix-test.com
  44. http:
  45. paths:
  46. - backend:
  47. serviceName: nginx-svc
  48. servicePort: 80

部署资源:

kubectl create -f traefik-test.yaml

过一会儿即可看到:
📃 部署Traefik v1(已过时,仅归档记录) - 图2
traefix-test.com 绑定到任一 node 节点即可访问
📃 部署Traefik v1(已过时,仅归档记录) - 图3

HTTPS 访问

创建证书, 若是线上服务器使用申请的域名证书即可

$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=traefix-test.com"
Generating a 2048 bit RSA private key
..................................+++
..........................................................+++
writing new private key to 'tls.key'
-----

创建保密字典:

kubectl -n default create secret tls nginx-test-tls --key=tls.key --cert=tls.crt

traefik-test-https.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-https-test
  namespace: default
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
    - host: traefix-test.com
      http:
        paths:
          - backend:
              serviceName: nginx-svc
              servicePort: 80
  tls:
    - secretName: nginx-test-tls

配置 tls.secretName 字段对应为保密字典即可

配置Path级别的路由

只需要在 spec.rules..http.paths..path 配置相应的路径即可:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-https-test
  namespace: default
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
    - host: traefix-test.com
      http:
        paths:
          - path: /pc
            backend:
              serviceName: nginx-svc1
              servicePort: 80
          - path: /mp
            backend:
              serviceName: nginx-svc2
              servicePort: 80
  tls:
    - secretName: nginx-test-tls

访问的是否使用 traefix-test.com/pctraefix-test.com/mp 实现相应服务的访问

二、手动部署

准备工作

创建命名空间
创建命名空间 traefik 用于测试

$ kubectl create ns traefik

为 node 打标签

kubectl label nodes k8s-master traefik=proxy
kubectl label nodes k8s-node1 traefik=proxy
kubectl label nodes k8s-node2 traefik=proxy

配置 ClusterRole

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
---
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: traefik

创建 ServiceAccount

apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  namespace: traefik

使用 DaemonSet 的方式部署

kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 60
      hostNetwork: true
      containers:
        - image: traefik
          name: traefik-ingress-lb
          ports:
            - name: http
              containerPort: 80
              hostPort: 80
            - name: admin
              containerPort: 8080
          securityContext:
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
          args:
            - --api
            - --kubernetes
            - --logLevel=INFO

创建 Service 与 Ingress

apiVersion: v1
kind: Service
metadata:
  name: traefik-web-ui
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
    - protocol: TCP
      targetPort: 8080
      port: 80
      name: web
    - protocol: TCP
      port: 8080
      nodePort: 30080
      name: admin
  type: NodePort
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik-web-ui
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
    - host: ui.traefik.com
      http:
        paths:
          - backend:
              serviceName: traefik-web-ui
              servicePort: 80

以上, 暴露 30080 用于外部反向代理使用, 并将 ui.traefik.com 解析到 traefik-web-ui 服务

在物理机中将域名加入 hosts 进行访问 [http://ui.traefik.com/](http://ui.traefik.com/)[http://192.168.126.129:30080/](http://192.168.126.129:30080/) 均可访问:
📃 部署Traefik v1(已过时,仅归档记录) - 图4
📃 部署Traefik v1(已过时,仅归档记录) - 图5

三、使用 HTTPS

绑定证书

# 创建证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=k8s-master-lb"
# 绑定证书到k8s
kubectl -n traefik create secret generic traefik-cert --from-file=tls.key --from-file=tls.crt
  • -n 指定命名空间
  • tls 保密字典类型, 绑定证书则使用 tls
  • traefik-cert 指定证书的名字
  • —key=/ssl/ssl.key 证书 key 路径
  • —cert=/ssl/ssl.pem 证书路径

📃 部署Traefik v1(已过时,仅归档记录) - 图6

创建 ConfigMap

编辑 traefik 配置文件:
traefik.toml

defaultEntryPoints = ["http", "https"]
[entryPoints]
  [entryPoints.http]
  address = ":80"
    # [entryPoints.http.redirect]
    # entryPoint = "https"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]
      [[entryPoints.https.tls.certificates]]
      certFile = "/ssl/tls.crt"
      keyFile = "/ssl/tls.key"
kubectl create configmap traefik-conf --from-file=traefik.toml -n traefik

也可使用 yaml 的形式创建:

kind: ConfigMap
apiVersion: v1
metadata:
  name: traefik-conf
  namespace: traefik
data:
  traefik-config: |+
    defaultEntryPoints = ["http", "https"]
    [entryPoints]
      [entryPoints.http]
      address = ":80"
        # [entryPoints.http.redirect]
        # entryPoint = "https"
      [entryPoints.https]
      address = ":443"
        [entryPoints.https.tls]
          [[entryPoints.https.tls.certificates]]
          certFile = "/ssl/tls.crt"
          keyFile = "/ssl/tls.key"

修改 DaemonSet

修改 DaemonSet 部署文件, apply 部署后直接删除原 traefik pod 进行配置更新:

kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress
  labels:
    k8s-app: traefik-ingress-lb
spec:
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      terminationGracePeriodSeconds: 60
      restartPolicy: Always
      serviceAccountName: traefik-ingress-controller
      containers:
        - image: traefik:latest
          name: traefik-ingress-lb
          ports:
            - name: http
              containerPort: 80
              hostPort: 80
            - name: https
              containerPort: 443
              hostPort: 443
            - name: admin
              containerPort: 8080
          args:
            - --configFile=/root/kube-config/apps/traefik/traefik.toml
            - -d
            - --web
            - --kubernetes
            - --logLevel=DEBUG
          volumeMounts:
            - name: traefik-config-volume
              mountPath: /opt/conf/k8s/conf
            - name: traefik-ssl-volume
              mountPath: /opt/conf/k8s/ssl
      volumes:
        - name: traefik-config-volume
          configMap:
            name: traefik-conf
            items:
              - key: traefik-config
                path: traefik.toml
        - name: traefik-ssl-volume
          secret:
            secretName: traefik-cert

端口监听测试

查看更新后 node 上的端口监听:

$ ss -ntlp | grep traefik
LISTEN     0      128         :::8080                    :::*                   users:(("traefik",pid=18337,fd=6))
LISTEN     0      128         :::80                      :::*                   users:(("traefik",pid=18337,fd=3))
LISTEN     0      128         :::443                     :::*                   users:(("traefik",pid=18337,fd=5))

示例: Kubernetes Dashboard (http 示例)

Dashboard 服务创建参考 在 Kubernetes 集群中部署 DashBoard

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kubernetes-dashboard-web-ui
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
    - host: ui.dashboard.com
      http:
        paths:
          - backend:
              serviceName: kubernetes-dashboard
              servicePort: 443
  tls:
    - secretName: traefik-cert # 证书名字, 若不指定则使用http方式访问

在物理机中将域名加入 hosts 进行访问 [http://ui.dashboard.com/](http://ui.dashboard.com/):

示例: 反向代理基于 nginx 的 web 容器 (https 示例)

有如下服务, 以 nginx 为例:
📃 部署Traefik v1(已过时,仅归档记录) - 图7

绑定到 traefik

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik-ingress
  namespace: traefik
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
    - host: k8s.nginx.test.xiaoyulive.top
      http:
        paths:
          - backend:
              serviceName: nginx-service
              servicePort: 80
  tls:
    - secretName: traefik-cert

成功后, 可以在访问权中看到
📃 部署Traefik v1(已过时,仅归档记录) - 图8

  • host 指定的外部访问域名, 需要域名解析到 k8s-master 的 IP
  • tls SSL 证书的名称, 为上面创建的证书, 如果指定 tls, 则可以使用 https 的方式访问, 不指定则只能使用 http 访问

在 Treafik 中查看

📃 部署Traefik v1(已过时,仅归档记录) - 图9

浏览器测试访问

浏览器输入 [http://k8s.nginx.test.xiaoyulive.top:30080/](http://k8s.nginx.test.xiaoyulive.top:30080/) 即可:
📃 部署Traefik v1(已过时,仅归档记录) - 图10