腾讯云中部署traefik的步骤

修改node标签

在使用traefik时,通过label来筛选node。所以先为当前所有的node增加label.

  1. 获取所有node
    • kubectl get nodes --show-labels
  2. 增加label
    • kubectl label node <node name> traefik=proxy

部署Traefik服务

腾讯云禁止通过UI在kube-system空间创建服务,因此使用配置文件创建服务. 使用下面的配置文件创建traefik服务.

---
apiVersion: v1  
kind: ServiceAccount  
metadata:  
  name: traefik-ingress-controller
  namespace: kube-system
---
kind: Deployment  
apiVersion: extensions/v1beta1  
metadata:  
  name: traefik-ingress-controller
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:  
  replicas: 1
  selector:
    matchLabels:
      k8s-app: traefik-ingress-lb
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      serviceAccountName: traefik-ingress-controller
      # 筛选label=traefik:proxy的node
      nodeSelector:
        traefik: proxy
      terminationGracePeriodSeconds: 60
      containers:
      - image: traefik
        name: traefik-ingress-lb
        ports:
        - name: http
          containerPort: 80
        - name: admin
          containerPort: 8080
        args:
        - --api
        - --kubernetes
        - --logLevel=DEBUG #如果不需要输出debug日志,可以修改为INFO
        - --accesslog
---
kind: Service  
apiVersion: v1  
metadata:  
  # 如果需要创建内网LB,则必须添加这两个注解,否则腾讯云会创建为公网LB
  annotations:
    service.kubernetes.io/qcloud-loadbalancer-clusterid: <集群ID>
    service.kubernetes.io/qcloud-loadbalancer-internal-subnetid: <子网ID>
  name: traefik-ingress-service
  namespace: kube-system
spec:  
  selector:
    k8s-app: traefik-ingress-lb
  ports:
    - protocol: TCP
      port: 80
      name: web
    - protocol: TCP
      port: 8080
      name: admin
  type: LoadBalancer
  externalTrafficPolicy: Cluster

执行 kubectl apply -f xxxx.yml来创建traefik服务。

执行成功之后,可以通过 kuberctl get all --namespace kube-system 来查看LB地址,也可以通过登录腾讯云UI查看访问地址。

部署traefik ui 服务

Traefik服务对外提供两个服务,80是真正的负载服务,8080提供DashBoard服务。 这里准备创建的UI服务,则对应的是8080的DashBoard服务。 其实通过上一步骤获取的访问地址,通过IP:8080也能访问到UI。 所以比步骤非必须部署,可以跳过。

如果使用traefik提供的默认配置文件,则会生成一个公网VIP。 下面演示如何生成一个VPC内的IP.

apiVersion: extensions/v1beta1  
kind: Ingress  
metadata:  
  annotations:
    kubernetes.io/ingress.subnetId: subnet-xxxxx
  name: traefik-web-ui
  namespace: kube-system
spec:  
  rules:
  - host: ui.traefik.chinazt.cc
    http:
      paths:
      - path: /
        backend:
          serviceName: traefik-ingress-service
          servicePort: 8080

在官方提供的配置文件中,会生成一个针对traefik的LB Service,然后再生成一个对此LB的负载Ingress。 没有想明白为什么要这么做,所以我直接生成了一个对应traefik service的Ingress。 也就是由原来两次转发简化成了一次转发,如下图所示:

      |----------------------|     |----------------------|
官方   |      Ingress         |简化  |         Ingress      |
      |----------------------|     |----------------------|
                |                                |
                |                                |
                |                                |
                |                                |
      |----------------------|     |----------------------|
      |     LB  Service      |     |    traefik Service   |
      |----------------------|     |----------------------|
                |
                |     
                |
      |----------------------|
      |      traefik Service |
      |----------------------|

部署后端服务

这里使用我自己写的一个简易webserver。 vikings/tiny-srv。 这个服务对外暴露了三个接口:

  • _ping 用于ping测试,返回字符串 I am tiny-srv
  • /v1/echo 回显request中的header,body,query信息
  • /v1/test 回复一个固定字符串 U sucd!

部署tiny-srv服务的方式没有需要注意的地方,可以在UI直接创建服务,也可以通过配置文件创建(只需要保证网络负载为公网/VPC/集群内其中一个就可以)。 我直接在UI中创建了tiny-srv服务。

然后开始创建Ingress服务, 此处创建Ingress服务不能通过UI,必须通过配置文件。(初步猜测是腾讯云有些特殊处理,如果通过UI创建Ingress,traefik无法拦截到此次事件)

apiVersion: extensions/v1beta1  
kind: Ingress  
metadata:  
  annotations:
    kubernetes.io/ingress.subnetId: subnet-xxxxx
  name: test-create-in-yml
  namespace: zhangtao-env2
spec:  
  rules:
  - host: test.tiny.chinazt.cc
    http:
      paths:
      - path: /
        backend:
          serviceName: echo-tiny-zhangtao-env2-1538273151
          servicePort: 8000

执行成功之后,在traefik ui界面中会实时看到新增加的Frontend和对应的Backend。 腾讯云创建LB会慢一些,可以不用等待LB创建完成,只要traefik中frontend和backend显示正确,就可以视为成功了。

验证

假设第一步部署的traefik-ingress-controller VIP是192.168.1.155. 那么192.168.1.155:80则是所有请求的入口, 192.168.1.155:8080则是traefik ui的入口(第二步创建了一个traefik ui来对应8080端口,所以不需要直接访问8080端口)。

第三步中部署的后端访问域名是 test.tiny.chinazt.cc。 这个域名是杜撰的,因此修改本地hosts文件,添加:

192.168.1.155 test.tiny.chinazt.cc  

然后直接请求 curl -i test.tiny.chinazt.cc/_ping 就可以看到正确的响应。

多次部署

如果我们调整tiny-srv的实例个数,在traefik ui中可以看到对应的backend个数会有相应的增加或者减少。

如果我们重复第三步,在部署一个新的backend服务,域名为: echo.tiny.chinazt.cc。 当部署完成后,可以在traefik ui中观察到新增加的frontend和与此相对应的backend。

在hosts中增加 192.168.1.155 echo.tiny.chinazt.cc ,然后请求 curl -i echo.tiny.chinazt.cc 同样可以看到返回结果。

如果部署的是公网域名,在DNS中,将这些域名统一指到traefik的公网IP中。那么当部署成功时,就可以直接访问了。

此时traefik就承担了整个k8s集群的流量入口功能。