• 在Kubernetes上使用Traefik


    本节内容:

    • Traefik介绍
    • 部署测试用的两个服务
    • Role Based Access Control configuration (Kubernetes 1.6+ only)
    • 部署Traefik
    • 部署 Ingress
    • 部署Traefik UI
    • 访问测试
    • 健康检查

    一、Traefik介绍

    traefik 是一个前端负载均衡器,对于微服务架构尤其是 kubernetes 等编排工具具有良好的支持;同 nginx 等相比,traefik 能够自动感知后端容器变化,从而实现自动服务发现。

    由于微服务架构以及 Docker 技术和 kubernetes 编排工具最近几年才开始逐渐流行,所以一开始的反向代理服务器比如 nginx、apache 并未提供其支持,毕竟他们也不是先知;所以才会出现 Ingress Controller 这种东西来做 kubernetes 和前端负载均衡器如 nginx 之间做衔接;即 Ingress Controller 的存在就是为了能跟 kubernetes 交互,又能写 nginx 配置,还能 reload 它,这是一种折中方案;而 traefik 天生就是提供了对 kubernetes 的支持,也就是说 traefik 本身就能跟 kubernetes API 交互,感知后端变化,因此可以得知: 在使用 traefik 时,Ingress Controller 已经没什么用了,整体架构如下:

    二、部署测试用的两个服务

    部署两个服务nginx1-7和nginx1-8,后面用Traefik去负载这两个服务:

    apiVersion: v1
    kind: Service
    metadata:
      name: frontend
    spec:
      ports:
        - port: 80
          targetPort: 80
      selector:
        app: nginx1-7
    ---
    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
      name: nginx1-7-deployment
    spec:
      replicas: 2
      template:
        metadata:
          labels:
            app: nginx1-7
        spec:
          containers:
          - name: nginx
            image: nginx:1.7.9
            ports:
            - containerPort: 80
    nginx1-7.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: my-nginx
    spec:
      ports:
        - port: 80
          targetPort: 80
      selector:
        app: nginx1-8
    ---
    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
      name: nginx1-8-deployment
    spec:
      replicas: 2
      template:
        metadata:
          labels:
            app: nginx1-8
        spec:
          containers:
          - name: nginx
            image: nginx:1.8
            ports:
            - containerPort: 80
    nginx1-8.yaml

    运行两个服务:

    [root@node1 nginx_ingress]# kubectl create -f nginx1-7.yaml
    service "frontend" created
    deployment "nginx1-7-deployment" created
    [root@node1 nginx_ingress]# kubectl create -f nginx1-8.yaml
    service "my-nginx" created
    deployment "nginx1-8-deployment" created

    三、Role Based Access Control configuration (Kubernetes 1.6+ only)

    我这里部署的是1.6.0集群,开启了RBAC,授权需要使用角色和绑定角色。

    [root@node1 traefik]# pwd
    /opt/traefik
    [root@node1 traefik]# vim ingress-rbac.yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: ingress
      namespace: kube-system
    
    ---
    
    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      name: ingress
    subjects:
      - kind: ServiceAccount
        name: ingress
        namespace: kube-system
    roleRef:
      kind: ClusterRole
      name: cluster-admin
      apiGroup: rbac.authorization.k8s.io
    ingress-rbac.yaml

    四、部署Traefik

    [root@node1 traefik]# pwd
    /opt/traefik
    [root@node1 traefik]# vim traefik-deploy.yaml
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: traefik-ingress-lb
      namespace: kube-system
      labels:
        k8s-app: traefik-ingress-lb
    spec:
      template:
        metadata:
          labels:
            k8s-app: traefik-ingress-lb
            name: traefik-ingress-lb
        spec:
          terminationGracePeriodSeconds: 60
          hostNetwork: true
          restartPolicy: Always
          serviceAccountName: ingress
          containers:
          - image: traefik
            name: traefik-ingress-lb
            resources:
              limits:
                cpu: 200m
                memory: 30Mi
              requests:
                cpu: 100m
                memory: 20Mi
            ports:
            - name: http
              containerPort: 80
              hostPort: 80
            - name: admin
              containerPort: 8580
              hostPort: 8580
            args:
            - --web
            - --web.address=:8580
            - --kubernetes
    traefik-deploy.yaml

    其中 traefik 监听 node 的 80 和 8580 端口,80 提供正常服务,8580 是其自带的 UI 界面,原本默认是 8080,因为环境里端口冲突了,所以这里临时改一下。

    【注意】:这里用的是Deploy类型,没有限定该pod运行在哪个主机上。

    五、部署 Ingress

    [root@node1 traefik]# cat traefik.yaml 
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: traefik-ingress
      namespace: default
    spec:
      rules:
      - host: traefik.nginx.io
        http:
          paths:
          - path: /
            backend:
              serviceName: my-nginx
              servicePort: 80
      - host: traefik.frontend.io
        http:
          paths:
          - path: /
            backend:
              serviceName: frontend
              servicePort: 80
    traefik.yaml

    其中的backend中要配置default namespace中启动的service名字,如果你没有配置namespace名字,默认使用default namespace,如果你在其他namespace中创建服务想要暴露到kubernetes集群外部,可以创建新的ingress.yaml文件,同时在文件中指定该namespace,其他配置与上面的文件格式相同。path就是URL地址后的路径,如traefik.frontend.io/path,service将会接受path这个路径,host最好使用service-name.filed1.filed2.domain-name这种类似主机名称的命名方式,方便区分服务。

    根据实际环境中部署的service的名字和端口自行修改,有新service增加时,修改该文件后可以使用kubectl replace -f traefik.yaml来更新。

    六、部署Traefik UI

    traefik 本身还提供了一套 UI 供我们使用,其同样以 Ingress 方式暴露,只需要创建一下即可。

    [root@node1 traefik]# cat traefik-ui-service.yaml 
    apiVersion: v1
    kind: Service
    metadata:
      name: traefik-web-ui
      namespace: kube-system
    spec:
      selector:
        k8s-app: traefik-ingress-lb
      ports:
      - name: web
        port: 80
        targetPort: 8580
    ---
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: traefik-web-ui
      namespace: kube-system
    spec:
      rules:
      - host: traefik-ui.local
        http:
          paths:
          - path: /
            backend:
              serviceName: traefik-web-ui
              servicePort: web
    traefik-ui-service.yaml

    最后一起创建:

    [root@node1 traefik]# kubectl create -f .
    serviceaccount "ingress" created
    clusterrolebinding "ingress" created
    deployment "traefik-ingress-lb" created
    service "traefik-web-ui" created
    ingress "traefik-web-ui" created
    ingress "traefik-ingress" created

    七、访问测试

    查看traefik pod被分配到了哪台主机上: 

    [root@node1 traefik]# kubectl get pods -n kube-system -l k8s-app=traefik-ingress-lb -o wide                       
    NAME                                  READY     STATUS    RESTARTS   AGE       IP             NODE
    traefik-ingress-lb-4237248072-1dg9n   1/1       Running   0          2m        172.16.7.152   172.16.7.152

    浏览器输入http://172.16.7.152:8580/,将可以看到dashboard。

    左侧黄色部分部分列出的是所有的rule,右侧绿色部分是所有的backend。

    在Kubernetes集群的任意一个节点上执行。假如现在我要访问nginx的"/"路径。

    curl -H Host:traefik.nginx.io http://172.16.7.152/

    如果需要在kubernetes集群以外访问就需要设置DNS,或者修改本机的hosts文件。

    172.16.7.152 traefik.nginx.io
    172.16.7.152 traefik.frontend.io

    所有访问这些地址的流量都会发送给172.16.7.152这台主机,就是我们启动traefik的主机。

    Traefik会解析http请求header里的Host参数将流量转发给Ingress配置里的相应service。

    修改hosts后就就可以在kubernetes集群外访问以上两个service。

    八、健康检查

    关于健康检查,测试可以使用 kubernetes 的 Liveness Probe 实现,如果 Liveness Probe检查失败,则 traefik 会自动移除该 pod。

    【示例】:我们定义一个 test-health 的 deployment,健康检查方式是 cat /tmp/health,容器启动 2 分钟后会删掉这个文件,模拟健康检查失败。

    test-health的deployment:

    [root@node1 traefik]# cat test-health-deploy.yaml 
    apiVersion: v1
    kind: Deployment
    apiVersion: extensions/v1beta1
    metadata:
      name: test
      namespace: default
      labels:
        test: alpine
    spec:
      replicas: 1
      selector:
        matchLabels:
          test: alpine
      template:
        metadata:
          labels:
            test: alpine
            name: test
        spec:
          containers:
          - image: mritd/alpine:3.4
            name: alpine
            resources:
              limits:
                cpu: 200m
                memory: 30Mi
              requests:
                cpu: 100m
                memory: 20Mi
            ports:
            - name: http
              containerPort: 80
            args:
            command:
            - "bash"
            - "-c"
            - "echo ok > /tmp/health;sleep 120;rm -f /tmp/health"
            livenessProbe:
              exec:
                command:
                - cat
                - /tmp/health
              initialDelaySeconds: 20
    test-health-deploy.yaml

    test-health 的 service:

    [root@node1 traefik]# vim test-health-service.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: test 
      labels:
        name: test
    spec:
      ports:
      - port: 8123
        targetPort: 80
      selector:
        name: test
    test-health-service.yaml

    test-health的 Ingress:

    [root@node1 traefik]# vim test-health-ingress.yaml
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: test
    spec:
      rules:
      - host: test.com
        http:
          paths:
          - path: /
            backend:
              serviceName: test
              servicePort: 8123
    test-health-ingress.yaml

    全部创建好以后,进入 traefik ui 界面,可以观察到每隔 2 分钟健康检查失败后,kubernetes 重建 pod,同时 traefik 会从后端列表中移除这个 pod。

  • 相关阅读:
    vue+element-ui实现前端分页
    element-UI中table表格的row-click事件怎么获取一行数据的id
    使用一个for循环将N*N的二维数组的所有值置1
    http常见的状态码
    反转一个英文句子中的单词,并且对应位置大小写不改变
    用一条SQL语句查出每门课都大于80分的学生的姓名
    平滑重启原理及平滑更新
    php之命名空间
    php之trait-实现多继承
    C入门之一
  • 原文地址:https://www.cnblogs.com/zhaojiankai/p/7898282.html
Copyright © 2020-2023  润新知