最新消息:

traefik负载均衡器介绍(Kubernetes环境)

Linux ipcpu 1169浏览

traefik.md

一、Kubernetes 服务暴露介绍

从 kubernetes 1.2 版本开始,kubernetes提供了 Ingress 对象来实现对外暴露服务;到目前为止 kubernetes 总共有三种暴露服务的方式:

LoadBlancer Service
NodePort Service
Ingress

1.1、LoadBlancer Service

LoadBlancer Service 是 kubernetes 深度结合云平台的一个组件;当使用 LoadBlancer Service 暴露服务时,实际上是通过向底层云平台申请创建一个负载均衡器来向外暴露服务;目前 LoadBlancer Service 支持的云平台已经相对完善,比如国外的 GCE、DigitalOcean,国内的 阿里云,私有云 Openstack 等等,由于 LoadBlancer Service 深度结合了云平台,所以只能在一些云平台上来使用

1.2、NodePort Service

NodePort Service 顾名思义,实质上就是通过在集群的每个 node 上暴露一个端口,然后将这个端口映射到某个具体的 service 来实现的,虽然每个 node 的端口有很多(0~65535),但是由于安全性和易用性(服务多了就乱了,还有端口冲突问题)实际使用可能并不多

1.3、Ingress

Ingress 这个东西是 1.2 后才出现的,通过 Ingress 用户可以实现使用 nginx 等开源的反向代理负载均衡器实现对外暴露服务,以下详细说一下 Ingress,毕竟 traefik 用的就是 Ingress

使用 Ingress 时一般会有三个组件:

反向代理负载均衡器
Ingress Controller
Ingress

1.3.1、反向代理负载均衡器

反向代理负载均衡器很简单,说白了就是 nginx、apache 什么的;在集群中反向代理负载均衡器可以自由部署,可以使用 Replication Controller、Deployment、DaemonSet 等等,不过个人喜欢以 DaemonSet 的方式部署,感觉比较方便

1.3.2、Ingress Controller

Ingress Controller 实质上可以理解为是个监视器,Ingress Controller 通过不断地跟 kubernetes API 打交道,实时的感知后端 service、pod 等变化,比如新增和减少 pod,service 增加与减少等;当得到这些变化信息后,Ingress Controller 再结合下文的 Ingress 生成配置,然后更新反向代理负载均衡器,并刷新其配置,达到服务发现的作用

1.3.3、Ingress

Ingress 简单理解就是个规则定义;比如说某个域名对应某个 service,即当某个域名的请求进来时转发给某个 service;这个规则将与 Ingress Controller 结合,然后 Ingress Controller 将其动态写入到负载均衡器配置中,从而实现整体的服务发现和负载均衡

有点懵逼,那就看图

从上图中可以很清晰的看到,实际上请求进来还是被负载均衡器拦截,比如 nginx,然后 Ingress Controller 通过跟 Ingress 交互得知某个域名对应哪个 service,再通过跟 kubernetes API 交互得知 service 地址等信息;综合以后生成配置文件实时写入负载均衡器,然后负载均衡器 reload 该规则便可实现服务发现,即动态映射

了解了以上内容以后,这也就很好的说明了我为什么喜欢把负载均衡器部署为 Daemon Set;因为无论如何请求首先是被负载均衡器拦截的,所以在每个 node 上都部署一下,同时 hostport 方式监听 80 端口;那么就解决了其他方式部署不确定 负载均衡器在哪的问题,同时访问每个 node 的 80 都能正确解析请求;如果前端再 放个 nginx 就又实现了一层负载均衡。

二、Traefik 概述

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

三、Traefik 安装

Traefik官方的git提供了部署yaml文件,位置是 https://github.com/containous/traefik/tree/v1.4.0/examples/k8s

我的Kubernetes是1.5版本,没有RBAC。

建议采用DaemonSet方式,然后traefik-ui也是一个单独文件。

部署完毕后,在设置几个ingress就可以从UI上看到了,UI上只能查看搜索,不能执行其他操作。

TIPS:如果部署完成traefik和traefik-ui,并且设置了ingress,但是UI显示为空,请逐个检查DaemonSet是否生效(查看80端口),kubernetes的apiserver相关的密钥key是否正确部署。

YAML配置文件内容如下:

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
---
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:
          privileged: true
        args:
        - -d
        - --web
        - --kubernetes
---
kind: Service
apiVersion: v1
metadata:
  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: NodePort

四、HTTPS设置

traefik使用https要比nginx ingress controller要麻烦一些,按照如下步骤操作:

4.1 创建一个Secret用来存放https证书

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

4.2 创建一个configmap用来存储traefik配置

cat >> traefik.toml <<EOF
# traefik.toml
defaultEntryPoints = ["http","https"]
[entryPoints]
  [entryPoints.http]
  address = ":80"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]
      [[entryPoints.https.tls.certificates]]
      CertFile = "/ssl/tls.crt"
      KeyFile = "/ssl/tls.key"
EOF

kubectl create configmap traefik-conf --from-file=traefik.toml --namespace=kube-system

这里没有设置http向HTTP的转跳,有需要的可以自行设置,如下

  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
      entryPoint = "https"

4.3 修改traefik的DaemonSet配置文件,并重新创建

      containers:
      - image: traefik
        name: traefik-ingress-lb
        volumeMounts:
        - mountPath: "/ssl"
          name: "ssl"
        - mountPath: "/config"
          name: "config"
          [省略]
      volumes:
      - name: ssl
        secret:
          secretName: traefik-cert
      - name: config
        configMap:
          name: traefik-conf

需要修改的地方有2个:

  1. containers 部分增加volumeMounts挂载点
  2. volumes设置挂载点的类型和位置(分别使用了secret和configMap,没有使用hostPath映射Node机器上的目录)

4.4 测试

创建ingress后,配置hosts并测试,HTTP和HTTPS均访问正常。

[root@k80 ~]# curl -I https://foo.ipcpu.com/
HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 521
Content-Type: text/html
[root@k80 ~]# curl -I http://foo.ipcpu.com/
HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 521
Content-Type: text/html

五、参考资料

https://docs.traefik.io/
https://mritd.me/2016/12/06/try-traefik-on-kubernetes/
https://ipfans.github.io/2016/08/introduce-traefik-load-balance/
https://medium.com/@patrickeasters/using-traefik-with-tls-on-kubernetes-cb67fb43a948
https://blog.osones.com/en/kubernetes-ingress-controller-with-traefik-and-lets-encrypt.html

转载请注明:IPCPU-网络之路 » traefik负载均衡器介绍(Kubernetes环境)