速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

如何在 K8S 集群中部署 Traefik Ingress Controller

  • 2020-05-25
  • 本文字数:8841 字

    阅读完需:约 29 分钟

如何在K8S集群中部署Traefik Ingress Controller

在生产环境中,我们常常需要控制来自互联网的外部进入集群中,而这恰巧是 Ingress 的职责。


Ingress 的主要目的是将 HTTP 和 HTTPS 从集群外部暴露给该集群中运行的服务。这与 Ingress 控制如何将外部流量路由到集群有异曲同工之妙。接下来,我们举一个实际的例子来更清楚的说明 Ingress 的概念。


首先,想象一下在你的 Kubernetes 集群中有若干个微服务(小型应用程序之间彼此通信)。这些服务能够在集群内部被访问,但我们想让我们的用户从集群外部也能够访问它们。因此,我们需要做的是使用反向代理将每个 HTTP(S)(例如,service.yourdomain.com)路由与相应的后端关联,并在该服务的不同实例之间(如,pod)进行负载均衡。与此同时,由于 Kubernetes 的性质会不断发生变化,因此我们希望跟踪服务后端的更改,以便能够在添加或删除新 Pod 时将这些 HTTP 路由重新关联到新 Pod 实例。


使用 Ingress 资源和关联的 Ingress Controller,你可以实现以下目标:


  • 将你的域 app.domain.com 指向你的私有网络中的微服务应用程序

  • 将路径 domain.com/web 指向你的私有网络中的微服务 web

  • 将你的域 backend.domain.com 指向你的私有网络中的微服务后端,并在该微服务的多个实例之间(Pod)进行负载均衡


现在,你理解了 Ingress 的重要性。它能够帮助将 HTTP 路由指向在 Kubernetes 集群中特定的微服务。


但是,流量路由并不是 Ingress 在 Kubernetes 中的唯一功能。例如,还可以将 Ingress 配置为负载均衡流量到你的应用程序、终止 SSL、执行基于名称的虚拟主机、在不同服务之间分配流量、设置服务访问规则等。


Kubernetes 有一个特别的 Ingress API 资源,它能够支持上述所有功能。但是,简单地创建一个 Ingress API 资源是没有作用的。你还需要一个 Ingress Controller。目前,Kubernetes 支持许多 Ingress controller,如 Contour、HAProxy、NGINX 以及 Traefik。


在本文中,我将使用 Traefik Ingress Controller 创建 Ingress。它能够实现现代 HTTP 反向代理和负载均衡器的功能,从而简化了微服务的部署。此外,Traefik 对 Docker、Marathon、Consul、Kubernetes、Amazon ECS 等系统和环境都提供了强大的支持。


Traefik 对于诸如 Kubernetes 之类的灵活性较强的系统十分有用。在 Kubernetes 中,每天需要多次添加、删除或升级服务,而 Traefik 可以监听服务镜像仓库/编排器 API 并立即生成或更新路由,因此你的微服务无需手动配置即可与外界连接。


除此之外,Traefik 支持多个负载均衡算法、Let’s Encrypt 的 HTTPS(支持通配证书)、断路器、WebSoket、GRPC 和多个监控程序(Rest、Prometheus、Statsd、Datadog、InfluxDB 等)。有关 Traefik 中可用功能的更多信息,请参考其官方文档:


https://docs.traefik.cn/

Ingress 资源

在教程开始之前,我们先来简单地讨论一下 Ingress 资源是如何工作的。以下是隐式使用 Nginx Ingress Controller 的 Ingress 示例。


apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: ingress-example  annotations:    nginx.ingress.kubernetes.io/rewrite-target: /spec:  rules:  - http:      paths:      - path: /microservice1        backend:          serviceName: test          servicePort: 80
复制代码


以上 Ingress manifest 包含了一系列 HTTP 规则,它们用于规定 controller 如何路由流量。


可选主机。如果未指定主机(如上所示),则该规则适用于通过指定 IP 地址的所有入站 HTTP 流量。如果提供了主机(如 yourhost.com),则该规则仅适用于该主机。


一个路径列表(如,/microservice1),它指向由 serviceName 和 servicePort 定义的关联后端。


一个后端。向 Ingress 发出的 HTTP(和 HTTPS)请求将与给定规则的主机和路径匹配,然后将其路由到该规则中指定的后端服务。


在以上例子中,我们配置了一个名为”test“的后端,它将接收所有来自/microservice 路径的流量。然而,我们也可以配置一个默认后端,它将将为任何不符合规范中路径的用户请求提供服务。同时,如果不定义任何规则,Ingress 将路由所有流量到默认后端。例如:


apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: test-ingressspec:  backend:    serviceName: defaultbackend    servicePort: 80
复制代码


在本例中,所有流量都被转发到默认后端中 defaultbackend。现在,我们理解了 Ingress 资源的基本概念,接下来我们来看看一些具体的例子。

Step 0:前期准备

如上文我们所说的,定义一个 Ingress 资源没有任何作用,除非你使用了 Ingress Controller。在本教程中,我们在 Kubernetes 集群中将 Traefik 设置为 Ingress Controller。


要完成教程,你需要进行以下准备:


  • 一个正在运行的 Kubernetes 集群。

  • 一个安装好的命令行工具,kubectl。并配置为与集群通信。


请注意:以下示例均假设你在本地计算上使用 Minikube 运行 Kubernetes 集群。

Step 1:启用 RBAC

首先,我们需要向 Traefik 授予一些权限,以访问集群中运行的 Pod、endpoint 和服务。为此,我们将使用 ClusterRole 和 ClusterRoleBinding 资源。但是,你也可以对命名空间范围内的 RoleBindings 使用最小特权方法。通常,如果集群的命名空间不会动态更改,并且 Traefik 无法监视所有集群的命名空间,那么这是首选的方法。


让我们创建一个新的 ServiceAccount,为 Traefik 提供集群中的身份。


apiVersion: v1kind: ServiceAccountmetadata:  name: traefik-ingress  namespace: kube-system
复制代码


要创建一个 ServiceAccount,需要在 traefik-service-acc.yaml 中保存以上 manifest 并运行:


kubectl create -f traefik-service-acc.yamlserviceaccount "traefik-ingress" created
复制代码


接下来,让我们创建一个具有一组权限的 ClusterRole,该权限将应用于 Traefik ServiceAccount。通过 ClusterRole,Traefik 可以管理和监视集群中所有命名空间中的资源,例如服务、endpoint、secret 以及 Ingress。


kind: ClusterRoleapiVersion: rbac.authorization.k8s.io/v1beta1metadata:  name: traefik-ingressrules:  - apiGroups:      - ""    resources:      - services      - endpoints      - secrets    verbs:      - get      - list      - watch  - apiGroups:      - extensions    resources:      - ingresses    verbs:      - get      - list      - watch
复制代码


将这一规范保存到文件 traefik-cr.yaml 中,并运行:


kubectl create -f traefik-cr.yamlclusterrole.rbac.authorization.k8s.io “traefik-ingress” created
复制代码


最后,启用这些权限,我们应该将 ClusterRole 绑定到 Traefik ServiceAccount 中。使用 ClusterRoleBinding manifest 可以完成这一操作:


kind: ClusterRoleBindingapiVersion: rbac.authorization.k8s.io/v1beta1metadata:  name: traefik-ingressroleRef:  apiGroup: rbac.authorization.k8s.io  kind: ClusterRole  name: traefik-ingresssubjects:- kind: ServiceAccount  name: traefik-ingress  namespace: kube-system
复制代码


保存这一规范到 traefik-crb.yaml 中,并运行以下命令:


kubectl create -f traefik-crb.yamlclusterrolebinding.rbac.authorization.k8s.io “traefik-ingress” created
复制代码

Step 2:部署 Traefik 到集群

接下来,我们将部署 Traefik 到 Kubernetes 集群。官方 Traefik 文档支持三种类型的部署:使用 Deployment 对象、使用 DaemonSet 对象或使用 Helm Chart。


在本教程中,我们将使用 Deployment manifest。相比其他选项,Deployment 有诸多优势。例如,它们能确保更好的可伸缩性,并为滚动更新提供良好支持。


让我们看一下 Deployment manifest:


kind: DeploymentapiVersion: extensions/v1beta1metadata:  name: traefik-ingress  namespace: kube-system  labels:    k8s-app: traefik-ingress-lbspec:  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      terminationGracePeriodSeconds: 60      containers:      - image: traefik        name: traefik-ingress-lb        ports:        - name: http          containerPort: 80        - name: admin          containerPort: 8080        args:        - --api        - --kubernetes        - --logLevel=INFO
复制代码


这个 Deployment 将在 kube-system 命名空间中创建一个 Traefik 副本。Traefik 容器将使用此 manifest 中指定的端口 80 和 8080。


将这个 manifest 保存到 traefik-deployment.yaml 文件中,并运行以下命令创建 Deployment:


kubectl create -f traefik-deployment.yamldeployment.extensions “traefik-ingress” created
复制代码


现在,让我们检查以下 Traefik Pod 是否都成功创建了:


kubectl --namespace=kube-system get podsNAME                         READY     STATUS    RESTARTS   AGE....storage-provisioner           1/1       Running   3          23dtraefik-ingress-54d6d8d9cc-ls6cs 1/1       Running   0          1m
复制代码


如你所见,Deployment Controller 启动了一个 Traefik 副本,并在正在运行,敲棒的!

Step 3:为外部访问创建 NodePorts

让我们创建一个服务来从集群外部访问 Traefik。为此,我们需要一个暴露两个 NodePorts 的服务。


kind: ServiceapiVersion: v1metadata:  name: traefik-ingress-service  namespace: kube-systemspec:  selector:    k8s-app: traefik-ingress-lb  ports:    - protocol: TCP      port: 80      name: web    - protocol: TCP      port: 8080      name: admin  type: NodePort
复制代码


将这个 manifest 保存到 traefik-svc.yaml,并创建服务:


kubectl create -f traefik-svc.yamlservice “traefik-ingress-service” created
复制代码


现在,让我们验证该服务是否创建:


kubectl describe svc traefik-ingress-service --namespace=kube-systemName:                     traefik-ingress-serviceNamespace:                kube-systemLabels:                   <none>Annotations:              <none>Selector:                 k8s-app=traefik-ingress-lbType:                     NodePortIP:                       10.102.215.64Port:                     web  80/TCPTargetPort:               80/TCPNodePort:                 web  30565/TCPEndpoints:                172.17.0.6:80Port:                     admin  8080/TCPTargetPort:               8080/TCPNodePort:                 admin  30729/TCPEndpoints:                172.17.0.6:8080Session Affinity:         NoneExternal Traffic Policy:  ClusterEvents:                   <none>
复制代码


如你所见,我们现在有两个 NodePorts(web 和 admin),它们分别路由到 Traefik Ingress Controller 的 80 和 8080 容器端口。“admin” NodePort 将用于访问 Traefik Web UI,“web” NodePort 将用于访问通过 Ingress 暴露的服务。

Step 4:访问 Traefik

为了能在浏览器中访问 Traefik Web UI,你可以使用“admin”NodePort 30729(请注意,你的 NodePort 值可能会有所不同)。因为我们还没有添加任何前端,所以 UI 此时应该是空的。


由于我们尚未给 Traefik 进行任何配置,因此我们会收到 404 的响应。


curl $(minikube ip):30565404 page not found
复制代码

Step 5 :添加 Ingress 到集群

现在我们在 Kubernetes 集群中已经将 Traefik 作为 Ingress Controller 了。然而,我们依旧需要定义 Ingress 资源和暴露 Traefik Web UI 的服务。


首先,我们创建一个服务:


apiVersion: v1kind: Servicemetadata:  name: traefik-web-ui  namespace: kube-systemspec:  selector:    k8s-app: traefik-ingress-lb  ports:  - name: web    port: 80    targetPort: 8080
复制代码


保存 manifest 到 traefik-webui-svc.yaml 中,并运行:


kubectl create -f traefik-webui-svc.yamlservice “traefik-web-ui” created
复制代码


让我们验证服务是否已经创建:


kubectl describe svc traefik-web-ui --namespace=kube-systemName:              traefik-web-uiNamespace:         kube-systemLabels:            <none>Annotations:       <none>Selector:          k8s-app=traefik-ingress-lbType:              ClusterIPIP:                10.98.230.58Port:              web  80/TCPTargetPort:        8080/TCPEndpoints:         172.17.0.6:8080Session Affinity:  NoneEvents:            <none>
复制代码


如你所见,服务的 ClusterIP 是 10.98.230.58,并在 manifest 中分配指定端口。


接下来,我们需要创建一个 Ingress 资源,指向 Traefik Web UI 后端:


apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: traefik-web-ui  namespace: kube-systemspec:  rules:  - host: traefik-ui.minikube    http:      paths:      - path: /        backend:          serviceName: traefik-web-ui          servicePort: web
复制代码


本质上,Ingress 将所有请求路由到 traefik-ui.minikube,在上述步骤中创建的服务暴露 Traefik Web UI。


将规范保存到 traefik-ingress.yaml,并运行:


kubectl create -f traefik-ingress.yamlingress.extensions “traefik-web-ui” created
复制代码


为了能够通过 traefik-ui.minikube 在浏览器中可以访问 Traefik Web UI,我们需要添加新的条目到我们/etc/hosts 文件中。该条目将包含 Minikube IP 和主机名。你可以通过运行 minikube ip 来获取 minkube 实例的 IP 地址,然后将新主机的名称保存到/etc/hosts 文件中,如下所示:


echo "$(minikube ip) traefik-ui.minikube" | sudo tee -a /etc/hosts192.168.99.100 traefik-ui.minikube
复制代码


现在,你应该能够在浏览器中访问 http://traefik-ui.minikube:<AdminNodePort>并查看 Traefik Web UI。别忘了附加”admin”NodePort 到主机地址。



在 dashboard 中,你可以点击 Health 链接来查看应用程序的健康状况:


Step 6:实现基于名称的路由

现在,我们来演示如何使用 Traefik Ingress Controller 为前端列表设置基于名称的路由。我们将使用简单的单页网站创建 3 个 Deployment,并显示动物图像:熊、野兔和驼鹿。


---kind: DeploymentapiVersion: extensions/v1beta1metadata:  name: bear  labels:    app: animals    animal: bearspec:  replicas: 2  selector:    matchLabels:      app: animals      task: bear  template:    metadata:      labels:        app: animals        task: bear        version: v0.0.1    spec:      containers:      - name: bear        image: supergiantkir/animals:bear        ports:        - containerPort: 80---kind: DeploymentapiVersion: extensions/v1beta1metadata:  name: moose  labels:    app: animals    animal: moosespec:  replicas: 2  selector:    matchLabels:      app: animals      task: moose  template:    metadata:      labels:        app: animals        task: moose        version: v0.0.1    spec:      containers:      - name: moose        image: supergiantkir/animals:moose        ports:        - containerPort: 80---kind: DeploymentapiVersion: extensions/v1beta1metadata:  name: hare  labels:    app: animals    animal: harespec:  replicas: 2  selector:    matchLabels:      app: animals      task: hare  template:    metadata:      labels:        app: animals        task: hare        version: v0.0.1    spec:      containers:      - name: hare        image: supergiantkir/animals:hare        ports:        - containerPort: 80
复制代码


每个 Deployment 都将有两个 Pod 副本,而每个 Pod 将在 containerPort 80 上服务“动物“网站。


让我们保存这些 Deployment manifest 到 animals-deployment.yaml 中,并运行:


kubectl create -f animals-deployment.yamldeployment.extensions “bear” createddeployment.extensions “moose” createddeployment.extensions “hare” created
复制代码


现在,让我们为每个 Deployment 创建一个服务,使得 Pod 可以访问:


---apiVersion: v1kind: Servicemetadata:  name: bearspec:  ports:  - name: http    targetPort: 80    port: 80  selector:    app: animals    task: bear---apiVersion: v1kind: Servicemetadata:  name: moosespec:  ports:  - name: http    targetPort: 80    port: 80  selector:    app: animals    task: moose---apiVersion: v1kind: Servicemetadata:  name: hare  annotations:    traefik.backend.circuitbreaker: "NetworkErrorRatio() > 0.5"spec:  ports:  - name: http    targetPort: 80    port: 80  selector:    app: animals    task: hare
复制代码


请注意:第三项服务使用断路器 annotation。断路器是 Traefik 的一项功能,可防止发生故障的服务器承受高负载。在本例中,我们防止服务器上的高负载超过 50%。当此条件匹配时,CB 进入“跳闸“状态,在该状态中它会使用预定义的 HTTP 状态代码进行响应或重定向到另一个前端。


保存这些服务 manifest 到 animals-svc.yaml 并运行:


kubectl create -f animals-svc.yamlservice “bear” createdservice “moose” createdservice “hare” created
复制代码


最后,为每个 Deployment 创建一个有 3 个前后端对的 Ingress。bear.minikube、moose.minikube 和 hare.minikube 将是我们指向相应后端服务的前端。


Ingress manifest 如下所示:


apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: animals  annotations:    kubernetes.io/ingress.class: traefikspec:  rules:  - host: hare.minikube    http:      paths:      - path: /        backend:          serviceName: hare          servicePort: http  - host: bear.minikube    http:      paths:      - path: /        backend:          serviceName: bear          servicePort: http  - host: moose.minikube    http:      paths:      - path: /        backend:          serviceName: moose          servicePort: http
复制代码


保存规范到 animals-ingress.yaml 并运行:


kubectl create -f animals-ingress.yamlingress.extensions “animals” created
复制代码


现在,在 Traefik dashboard 内,你可以看到每个主机的前端以及相应的后端列表:



如果你再次编辑 etc/hosts,你应该能够在你的浏览器中访问动物网页:


echo “$(minikube ip) bear.minikube hare.minikube moose.minikube” | sudo tee -a /etc/hosts
复制代码


你应该使用“web“NodePort 来访问特定网页。例如,http://bear.minikube:<WebNodePort>


我们也可以将三个前端重新配置为在一个域下提供服务,如下所示:


apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: all-animals  annotations:    kubernetes.io/ingress.class: traefik    traefik.frontend.rule.type: PathPrefixStripspec:  rules:  - host: animals.minikube    http:      paths:      - path: /bear        backend:          serviceName: bear          servicePort: http      - path: /moose        backend:          serviceName: moose          servicePort: http      - path: /hare        backend:          serviceName: hare          servicePort: http
复制代码


如果你激活这个 Ingress,使用相应的路径,三个动物在一个域下都能够访问——animals.minikube。别忘了将这个域添加到/etc/hosts。


echo “$(minikube ip) animals.minikube” | sudo tee -a /etc/hosts
复制代码


请注意:我们正在配置 Traefik,以使用 traefik.frontend.rule.type 注释,从 URL 路径中删除前缀。这样我们可以直接使用上一个示例中的容器。由于 traefik.frontend.rule.type: PathPrefixStrip 规则,你必须使用 http://animals.minikube:32484/moose/ 而不是 http://animals.minikube:32484/moose

Step 7:实现流量分配

借助 Traefik,用户可以使用服务权重以受控方式在多个 deployment 之间分配 Ingress 流量。这一功能可用于金丝雀发布,它最初应该获得少量但持续增长的流量。


让我们使用以下 manifest 在两个微服务之间分配 Traefik:


apiVersion: extensions/v1beta1kind: Ingressmetadata:  annotations:    traefik.ingress.kubernetes.io/service-weights: |      animals-app: 99%      animals-app-canary: 1%  name: animals-appspec:  rules:  - http:      paths:      - backend:          serviceName: animals-app          servicePort: 80        path: /      - backend:          serviceName: animals-app-canary          servicePort: 80        path: /
复制代码


请注意 traefik.ingress.kubernetes.io/service-weights 的注释。它指定了流量如何在指定后端服务(animals-app 和 animals-app-canary)之间分配。Traefik 将把 99%的用户请求路由到 animals-app deployment 支持的 Pod,并将 1%的用户请求路由到 animals-app-canary deployment 支持的 Pod。


要使此设置正常工作,需要满足一些条件:


  • 所有服务后端必须共享相同的路径和主机。

  • 跨服务后端共享的请求总数应总计为 100%。

  • 百分比值应该在支持的精度范围内,目前 Traefik 支持 3 个小数位的权重。

总结

如你所见,Ingress 是将外部流量路由到 Kubernetes 集群中相应后端服务的强大工具。用户可以使用 Kubernetes 支持的许多 Ingress controller 来实现 Ingress。在本教程中,我们重点介绍了 Traefik Ingress controller,该控制器支持基于名称的路由,负载均衡以及 Ingress controller 的其他常见任务。


2020-05-25 16:392933

评论

发布
暂无评论
发现更多内容

Kotlin函数竟然如此简洁

Silently9527

Java kotlin

功能强大且灵活的虚拟插件Blue Cat Audio Blue Cat PatchWork mac蓝猫桥接插件

Rose

前端 Vuer,为自己的项目搭建一个 Playwright 测试环境吧,给自己多一点安全感!

OpenTiny社区

Vue 前端 OpenTiny

开源WIKI工具对比,助你轻松选择适合的系统

爱吃小舅的鱼

Wiki系统

mac苹果电脑风扇控制软件:Macs Fan Control Pro for mac 激活版

你的猪会飞吗

mac软件下载 Mac软件下载站 mac破解软件下载

CleanMyMac X for mac(Mac清理优化工具) v5beta中文激活版

Rose

Microsoft Office LTSC 2024 For Mac永久许可证

Rose

Redis集群slot迁移改造实践

vivo互联网技术

redis集群 slot迁移 水平扩缩容

中文汉化版Navicat数据库 Navicat Premium 15直装版 mac/win

Rose

移动医疗|基于音视频SDK和即时通讯IM技术实现线上问诊技术

ZEGO即构

直播技术 音视频sdk 互联网医疗 在线问诊 直播SDK

使用CLion进行ROS开发

梦笔生花

CLion 2023

flowjo for mac安装教程 Mac流式细胞分析软件 支持M1/M2

Rose

截图和屏幕录制工具 CleanShot X for mac v4.7.3激活版

Rose

Nova for Mac 代码编辑器 v11.10中文版

Rose

阿里云AMD护航,天谋科技携IoTDB登顶TPCx-IoT国际权威榜单

Apache IoTDB

数据资产入表全流程解析,助力企业数据要素价值释放

袋鼠云数栈

如何用 Scrapy 爬取网站数据并在 Easysearch 中进行存储检索分析

极限实验室

爬虫 Scrapy easysearch

一个故事理解限流熔断降级

老张

系统架构 服务治理 基础架构 流量治理

百度梁志祥:樱桃好吃树好栽 智能体让营销更简单

Geek_2d6073

为什么说Scrum是有效的?(Why does Scrum work)

ShineScrum

Python如何操作文件?

快乐非自愿限量之名

Python 开发语言

百度智能云向量数据库创新和应用实践分享

百度Geek说

数据库 百度云 数据 大模型 知识库

开源CRM系统分析:主流8款哪个最好?

爱吃小舅的鱼

开源

Why do customers choose IPQ9570 as WiFi 7 motherboard chip solution?

wifi6-yiyi

WiFi7 IPQ9570

9款优质开源知识管理系统推荐,助力团队协作

爱吃小舅的鱼

知识管理软件

Cisco ACI Simulator 6.0(7e)M 发布下载,新增功能简介

sysin

Cisco sdn 思科 ACI

iShowU Studio for mac(强大的屏幕录像编辑工具)v2.3.15激活版

Rose

黑神话云端开放!ToDesk 云电脑、青椒云、网易云,不用高配电脑也能畅玩!

阿Q说代码

青椒云云桌面 ToDesk云电脑 黑神话悟空 网易云游戏电脑

落地数仓数据模型自动、可持续长效治理之策

Aloudata

数据仓库 数据治理 数据模型 数据血缘 主动元数据

如何在K8S集群中部署Traefik Ingress Controller_文化 & 方法_Rancher_InfoQ精选文章