理解Kubernetes中Traefik Ingress是什么

Kubernetes Traefik Ingress

由于traefik 2.x和traefik 1.x的版本配置改动的比较多,这里先介绍1.x版本的配置。目前来说traefik 2.0是2019年12月份发布的,大部分企业还是使用1.x。我们跳槽去人家公司不能说光会2.x不会1.x版本,所以traefik会出2个版本的文档。目前我们使用的版本的1.7.20,为1.x版本的最后一个版本,更新时间为2019年12月10日


https://docs.traefik.io/migration/v1-to-v2/

ngress 其实就是集群外部访问的一个入口,将外部的请求转发到不同的Server上,其实就相当于Nginx、Haproxy等负载均衡器。

Ingress实际上是通过服务发现的功能进行实现,通过Ingress controller来提供路由信息的刷新

Ingress controller可以理解为一个监视器,不断监听kube-apiserver,实时感知service、Pod的变化,Ingress controller再结合Ingress的配置,更新反向代理负载均衡器,达到服务发现的作用。

目前可以提供Ingress controller有很多,比如traefik、nginx-ingress、Kubernetes Ingress Cpmtrper for Kong、HAProxy Ingress controller等。

目前常见的负载均衡有Nginx-Ingress和traefik

这里使用traefik进行演示,主要是目前traefik已经成为主流。并且traefik有漂亮的dashboard界面,配置简单,已经已经深入和prometheus集成,nginx-ingress需要有3个组件镜像,traefik只有2个


Traefik
traefik是一款开源的反向代理和负载均衡工具,最大的优点是能够和常见的微服务系统直接整合,可以实现自动化动态配置。目前支持Docker、Swarm、Mesos、Mesos、Kubernetes、Consul、ETCD、Zookeeper等等后端模型

image_1e08sgoti1ne5u8516p8n986e9.png-790kB

左边的是我们用户访问的域名,当请求到达traefik上,traefik会去监听API(kube-apiserver)监听访问的更新,这个简单的可以理解为Nginx的后端健康检查,实时监控Pod的状态。


核心概念

当启动Traefik时,需要定义entrypoints,然后通过entrypoints的路由来分析传入的请求,来查看他们是否是一组规则匹配,如果匹配,则路由可能将请求通过一系列的转换过来在发送到服务上去。

image_1e08t24ls1hb0o46kv11apr4mrm.png-513.4kB

[√] Providers用来自动发现平台上的服务,可以是编排工具、容器引擎
[√] Entrypoints监听传入的流量,是网络的入口点,定义了接受请求的端口(HTTP或者TCP)
[√] Routers分析请求(host,path,headers,SSL等),负责将传入的请求连接到可以处理这些请求的服务上去
[√] Service将请求转发给应用,负责配置如何最终将处理传入请求的实际服务
[√] Middlewares中间件,用来修改请求或者根据请求来做出判断,中间件被附件到路由上,是一种在请求发送到服务之前调整请求的一种方法



Traefik Install

apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
---
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: kube-system
---
kind: Deployment
apiVersion: apps/v1
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
      terminationGracePeriodSeconds: 60
      tolerations:
      - operator: "Exists"
      nodeSelector:
        kubernetes.io/hostname: kubernetes-m
      containers:
      - image: traefik:v1.7.17
        name: traefik-ingress-lb
        ports:
        - name: http
          containerPort: 80
        - name: admin
          containerPort: 8080
        args:
        - --api
        - --kubernetes
        - --logLevel=INFO
---
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
  
  
  [root@kubernetes-m mnt]# kubectl create -f pod.yaml 
serviceaccount/traefik-ingress-controller created
clusterrole.rbac.authorization.k8s.io/traefik-ingress-controller created
clusterrolebinding.rbac.authorization.k8s.io/traefik-ingress-controller created
deployment.apps/traefik-ingress-controller created
service/traefik-ingress-service created
[root@kubernetes-m mnt]# kubectl get pod -A
NAMESPACE     NAME                                          READY   STATUS    RESTARTS   AGE
kube-system   coredns-7ff77c879f-rmf7p                      1/1     Running   1          8d
kube-system   coredns-7ff77c879f-xsm54                      1/1     Running   1          8d
kube-system   etcd-kubernetes-m                             1/1     Running   1          13d
kube-system   kube-apiserver-kubernetes-m                   1/1     Running   1          13d
kube-system   kube-controller-manager-kubernetes-m          1/1     Running   1          13d
kube-system   kube-flannel-ds-amd64-42lg9                   1/1     Running   1          13d
kube-system   kube-flannel-ds-amd64-bxr5c                   1/1     Running   1          13d
kube-system   kube-flannel-ds-amd64-wvr6d                   1/1     Running   2          13d
kube-system   kube-proxy-89plc                              1/1     Running   1          13d
kube-system   kube-proxy-9554v                              1/1     Running   1          13d
kube-system   kube-proxy-n4mrg                              1/1     Running   1          13d
kube-system   kube-scheduler-kubernetes-m                   1/1     Running   1          13d
kube-system   traefik-ingress-controller-56b7f444f9-4gpgq   1/1     Running   0          4s
[root@kubernetes-m mnt]# kubectl get svc -A
NAMESPACE     NAME                      TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                       AGE
default       kubernetes                ClusterIP   100.1.0.1      <none>        443/TCP                       13d
kube-system   kube-dns                  ClusterIP   100.1.0.10     <none>        53/UDP,53/TCP,9153/TCP        13d
kube-system   traefik-ingress-service   NodePort    100.1.56.142   <none>        80:31209/TCP,8080:31021/TCP   15s

Ingress 对象
现在我们是通过 NodePort 来访问 traefik 的 Dashboard 的,那怎样通过 ingress 来访问呢? 首先,需要创建一个 ingress 对象:(ingress.yaml)

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik-web-ui
  namespace: kube-system
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: traefik.duxt.com
    http:
      paths:
      - backend:
          serviceName: traefik-ingress-service
          servicePort: 8080
要注意上面的 ingress 对象的规则,特别是 rules 区域,我们这里是要为 traefik 的 dashboard 建立一个 ingress 对象,所以这里的 serviceName 对应的是上面我们创建的 traefik-ingress-service,端口也要注意对应 8080 端口,为了避免端口更改,这里的 servicePort 的值也可以替换成上面定义的 port 的名字:admin

创建完成后,我们应该怎么来测试呢?


第一步,在本地的/etc/hosts里面添加上 traefik.duxt.com 与 master 节点外网 IP 的映射关系
第二步,在浏览器中访问:http://traefik.haimaxy.com 我们会发现并没有得到我们期望的 dashboard 界面,这是因为我们上面部署 traefik 的时候使用的是 NodePort 这种 Service 对象,所以我们只能通过上面的 31021 端口访问到我们的目标对象:
http://traefik.duxt.com:31021/dashboard/

加上端口后我们发现可以访问到 dashboard 了,而且在 dashboard 当中多了一条记录,正是上面我们创建的 ingress 对象的数据,我们还可以切换到 HEALTH 界面中,可以查看当前 traefik 代理的服务的整体的健康状态

第三步,上面我们可以通过自定义域名加上端口可以访问我们的服务了,但是我们平时服务别人的服务是不是都是直接用的域名啊,http 或者 https 的,几乎很少有在域名后面加上端口访问的吧?为什么?太麻烦啊,端口也记不住,要解决这个问题,怎么办,我们只需要把我们上面的 traefik 的核心应用的端口隐射到 master 节点上的 80 端口,是不是就可以了,因为 http 默认就是访问 80 端口,但是我们在 Service 里面是添加的一个 NodePort 类型的服务,没办法映射 80 端口,怎么办?这里就可以直接在 Pod 中指定一个 hostPort 即可,更改上面的 traefik.yaml 文件中的容器端口:

containers:
- image: traefik
name: traefik-ingress-lb
ports:
- name: http
  containerPort: 80
  hostPort: 80
- name: admin
  containerPort: 8080
  
添加以后hostPort: 80,然后更新应用:
[root@kubernetes-m mnt]# kubectl apply -f traefik-ingress.yaml 
ingress.extensions/traefik-web-ui created
第四步,正常来说,我们如果有自己的域名,我们可以将我们的域名添加一条 DNS 记录,解析到 master 的外网 IP 上面,这样任何人都可以通过域名来访问我的暴露的服务了。

如果你有多个边缘节点的话,可以在每个边缘节点上部署一个 ingress-controller 服务,然后在边缘节点前面挂一个负载均衡器,比如 nginx,将所有的边缘节点均作为这个负载均衡器的后端,这样就可以实现 ingress-controller 的高可用和负载均衡了。

到这里我们就通过 ingress 对象对外成功暴露了一个服务
posted @ 2021-12-17 11:16  Layzer  阅读(523)  评论(0编辑  收藏  举报