Kubernetes Ingress with Traefik on AWS EC2 Instance
作者:禅与计算机程序设计艺术
1.简介
Kubernetes作为一个容器编排系统兼集群管理系统,在其出现之前云计算的发展就已初具规模。鉴于其便捷性及其高效的特性,在云计算领域内逐渐赢得广泛的应用与认可。然而,在实际应用场景中发现仅凭现有的技术手段难以满足所有需求:特别是在处理某些复杂场景时(如微服务架构下的通信问题),必须依赖额外的网络代理技术才能实现各服务间的有效交互。针对这一挑战,在相关解决方案中往往会引入Ingress控制器(亦称入口控制器)来进行功能扩展:该控制器作为一个辅助组件,在原有系统之上负责将外部请求精准地转发至对应的 Kubernetes 节点资源,并赋予每个服务独特的域名或IP地址标识。这样一来不仅提升了系统的可管理性还显著提升了用户体验:用户可以通过统一的域名或IP地址配置快速接入到各个服务实例上从而实现在 Service Mesh架构下不同微服务之间的高效通信机制。本文将深入探讨如何在现有环境中部署Traefik ingress控制器并结合AWS EC2实例构建一个完整的 Kubernetes集群环境下的 Service Mesh架构框架
1.背景介绍
在Kubernetes体系中,一个Service被视为一种虚拟概念,在此框架下用于描述一组具有相同功能功能的Pod集合。通常情况下,在Kubernetes环境中我们会将一组Pod映射至一个单一的IP地址与DNS名称以实现资源管理。然而,在一个多独立微服务构建的应用场景下,则需要借助Service Mesh这一技术来实现功能整合。其主要功能在于通过多层架构整合各子系统,并实现跨平台兼容性与可扩展性。
- 服务发现:通过ServiceMesh可以让应用程序不再受Kubernetes中Service的影响,并直接向其查询注册信息。
- 灰度发布/金丝雀发布:由于ServiceMesh实现了从旧版到新版服务之间流畅过渡。
- 请求路由:基于流量特征(如路径、headers或搜索参数),ServiceMesh能够将请求导向相应的服务实例。
借助 Service Mesh 技术,在 Kubernetes 平台上可以轻松实现多个相互独立的微服务的部署工作;无需为每个微服务单独设计其 Service 和 Endpoint 配置;从而只需专注于自身的业务逻辑即可;如下图所示
如图所示,在一个系统架构中(以蓝色方框标识),前端应用能够通过Service Mesh技术与后端提供的微服务集合实现无缝接入;而后端各微服务之间则借助于蓝色箭头所示的Sidebar代理机制进行通信交互。Sidebar代理机制不仅提供了标准化的服务对接接口还集成了一系列基础支持功能如服务定位、健康评估、日志解析以及性能监控等综合管理能力。
借助Service Mesh这一技术手段,在微服务架构下可以相对简便地支撑服务通信。然而,在实际应用中还应考虑多种其他的优秀功能特性。例如灰度发布/金丝雀发布能够实现快速验证新版本的效果,并且能够显著提升系统稳定性和应对突发负载压力的能力;熔断降级机制可以在发现性能异常时自动切换到备用方案;限流熔陷策略则能有效防止单点故障对系统造成严重损害;最后调用链跟踪功能有助于及时发现并定位故障源头。此外,Kubernetes自身也提供了相应的功能模块来支持Service mesh的应用,因此选择并配置适合的应用环境并不是一件复杂的工作,反而能够显著提升系统的稳定性和可靠性
2.基本概念术语说明
该开源服务网格项目由Google、IBM、Lyft和Tetrate联合推出。该项目最初它是Lyft开发的生产级服务网格方案。目前Tetrate继续负责开发和维护该项目。该平台提供了涵盖多个方面的完整解决方案,包括流量管理方案以及安全策略设计等多维度功能支持。此外它还涵盖了可观察性监测功能以及策略配置选项等关键组件支持。这些功能组合起来能够帮助开发者基于微服务架构构建分布式系统并实现高效的服务管理流程
Kubernetes 是一种容器化应用集群管理工具。它能够将容器化的应用程序部署至云平台或本地数据中心。 Kubernetes 提供了一个分布式系统内的资源管理、调度和协作框架,并简化了应用的部署、扩缩容及升级流程。
Envoy Proxy 是一个高性能代理库,默认由 Lyft 提供支持,并采用 C++ 编程语言开发完成。它旨在支持跨服务间通信、与外部网络交互以及在移动设备之间传输数据等功能。该开源项目由 Cloud Native Computing Foundation (CNCF) 托管运营以确保长期发展与稳定。
Envoy 可以作为一个独立的应用程序运行或通过 Sidecar 技术部署在应用容器中以实现负载均衡功能。
Sidecar 模式是一种简单的架构模式,在其应用场景下,“一个应用容器作为 Sidecar 接收并处理来自外部的数据流量,并将这些处理后的结果转发给另一个应用程序容器”。Istio 利用 Envoy Proxy 作为其核心数据传输平台来管理服务间的交互与通信。
Consul Connect
Consul Connect 是由 HashiCorp 开发的一款开源服务网格解决方案。它支持 Kubernetes 提供统一的服务定位和集成连接机制。
Prometheus
Prometheus 是一款免费的开放源代码平台, 专门用于实时监控与告警. 它的主要功能包括按预设规则定期收集时间序列数据, 并根据阈值设定自动触发警告或alarms. 该平台不仅支持在容器化环境中运行, 还能够集成到微服务架构中提供全面的应用状态管理. 在Kubernetes集群中, Prometheus 被广泛用于监控服务状态、资源利用率以及API调用频率等关键指标. 此外, 它还能通过配置实现对Kubernetes事件日志的支持, 从而辅助系统故障排查与性能优化.
Jaeger 是开源平台上的分布式追踪工具。
它能够协助我们在微服务架构中深入解析服务调用机制。
其功能则在于提供一种直观的方式呈现请求流程图。
这种工具能够让我们迅速识别出问题所在,并且还能有效地发现系统性能瓶颈点。
此外它还能支持多种编程语言如 Go Java Node.js Python C# 和 Ruby 等技术栈的应用场景。
这是一个开源软件平台。
它主要功能包括逆向代理服务器与负载均衡模块。
该软件提供丰富的配置设置,并支持Docker、Mesos、Marathon以及Consul等多种后端服务系统。
在Kubernetes等环境中能够实现服务定位与流量分配管理。
3.核心算法原理和具体操作步骤以及数学公式讲解
3.1 安装 Traefik
Traefik 可以被配置为 Kubernetes 环境中的 Deployment 对象。第一步,请创建一个名为 traefik-configmap.yaml 的 YAML 文件。其内容应如下所示:
kind: ConfigMap
apiVersion: v1
metadata:
name: traefik-config
data:
traefik.toml: |
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.traefik]
address = ":9000"
[traefik.http.services.dashboard.loadBalancer]
[[traefik.http.services.dashboard.loadBalancer.servers]]
url = "http://localhost:8080"
traefik_dynamic.json: |
{
"backends": {},
"frontends": {}
}
代码解读
- entryPoints.http:配置用于监听 HTTP 请求的具体端口号。
- entryPoints.traefik:配置用于管理 Traefik 后台服务所使用的端口号。
- services.dashboard:配置用于管理 Traefik 后台服务的日志地址。在此处设置时,默认值为 localhost,默认情况下仅允许本机计算机访问 Dashboard 应用程序。
- traefik.toml:这是 Traefik 配置文件路径所在位置。其中 configureEntryPoints 用于指定监听不同协议(如 HTTP/HTTPS)所需的端口信息;configureServices 用于指定期望的服务名称及其绑定 IP 地址;defineRoutersAndMiddlewares 用于定义应用中的路由规则和中间件功能;defineRoutersAndServices 用于详细说明各个路由对应的服务器功能模块及其匹配逻辑;defineTLSConfig 用于设定启用或禁用 HTTPS 的相关参数设置。
创建完成之后,可以通过 kubectl 命令创建 Deployment 对象:
kubectl create namespace traefik
kubectl apply -f traefik-rbac.yaml -n traefik
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v2.0/examples/k8s/traefik-deployment.yaml -n traefik
代码解读
- traefik-rbac.yaml 文件内容如下:
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
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: traefik
代码解读
此 RBAC 绑定角色和权限,使得 Traefik 能够管理 Kubernetes API Server。
- traefik-deployment.yaml 文件内容如下:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: traefik
labels:
app.kubernetes.io/name: traefik
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: traefik
template:
metadata:
labels:
app.kubernetes.io/name: traefik
spec:
serviceAccountName: traefik-ingress-controller
containers:
- image: traefik:v2.0
name: traefik
args:
- --global.checknewversion
- --global.sendanonymoususage
- --entrypoints.http.address=:80
- --entrypoints.traefik.address=:9000
- --providers.file.filename=/etc/traefik/dynamic.yaml
- --log
代码解读
- args参数列表详细说明了Traefik启动所需的各个参数及其作用。
- –global.checknewversion标志位设置是否启用新版本提醒功能。
- –global.sendanonymoususage标志位控制是否进行匿名使用统计数据收集。
- –entrypoints.http.address=**:80指定了HTTP服务使用的端口号(默认值80)。
- –entrypoints.traefik.address=**:9000指定了Traefik管理后台所使用的端口号(默认值9千)。
- –providers.file.filename=/etc/traefik/dynamic.yaml指定了Traefik程序读取配置文件的位置。
- –log标志位设置日志输出开关(默认关闭)。
创建完成后,执行以下命令查看 Traefik 是否正常工作:
kubectl get pod -l 'app.kubernetes.io/name=traefik' -n traefik
代码解读
如果看到类似下面这样的输出,就表明 Traefik 已经成功运行:
NAME READY STATUS RESTARTS AGE
traefik 1/1 Running 0 1m
代码解读
执行以下命令查看 Traefik 管理后台是否正常运行:
kubectl port-forward deployment/traefik 9000:9000 -n traefik
代码解读
在浏览器中打开 http://localhost:9000/dashboard 并访问 Traefik 管理后台界面。若成功看到 Traefik Dashboard 界面,则确认已成功配置。
3.2 配置 Traefik 动态配置
除了可以通过静态配置文件traefik.toml设置路由之外,还可以借助KubernetesCRD对象DynamicConfiguration来实现动态路由的配置。这种DynamicConfiguration方案不仅允许定义任何类型的路由规则,并且能够轻松地进行扩展而不必重启Traefik服务。
下面使用 Kubernetes CRD 对象实现 Traefik 动态配置。首先,创建一个名为 traefik_crd.yaml 的配置文件,内容如下:
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: testheader
middleware:
headers:
customRequestHeaders:
X-Added-By-Middleware: traefik
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami
routes:
- match: Host(`whoami.example.com`) && PathPrefix(`/`)
kind: Rule
services:
- name: whoami
port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami2
routes:
- match: Host(`whoami2.example.com`) && PathPrefix(`/`)
kind: Rule
services:
- name: whoami2
port: 80
代码解读
- Middleware:配置定制的头部字段,并创建响应头。
- IngressRoute:配置进出路由机制,并实现对不同服务的路由分配。
注意:
- 按照上述设定,在请求来自 domain name whoami.example.com 时, 该服务会被重定向至 corresponding deployment named whoami; 当请求来自 domain name whoami2.example.com 时, 则会被重定向至 corresponding deployment named whoami2.
- 因此无法设置诸如路径匹配之类的实际路由配置。
执行以下命令部署 traefik_crd.yaml 文件:
kubectl apply -f traefik_crd.yaml -n default
代码解读
当 pods 的状态变为 Ready 时,表明 Traefik 已配置新的动态路由规则。
3.3 创建 Traefik SSL 证书
注意:由于Markdown语法限制,在此示例中将所有数学公式 ... 原样保留
注意:由于Markdown语法限制,在此示例中将所有数学公式 ... 原样保留
---
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: wildcard-certificate
namespace: default
spec:
secretName: wildcard-certificate
issuerRef:
name: letsencrypt-prod
kind: Issuer
commonName: "*.example.com"
dnsNames:
- example.com
acme:
config:
- http01:
ingressClass: traefik
domains:
- '*.example.com'
代码解读
- secretParameter:指定证书存储的具体位置。
- certificateStorageLocation:确定用于存储证书的位置参数。
- issuerConfiguration:配置将使用哪个发行机构生成证书。
- issuerParameter:定义将使用的发行机构及其相关设置。
- primaryDomainName:设定证书的主要域名信息。
- additionalDomainNames:指定期望附加的域名列表。
- acmeConfiguration:配置涉及插件和域名的ACME相关设置项。
- httpChallengePluginConfiguration:配置与HTTP挑战相关的插件参数设置项。
- ingressClassType:选择并设置使用的ingress类型(此处已设置为traefikIngressType).
执行以下命令部署 tls.yaml 文件,申请证书:
kubectl apply -f tls.yaml
代码解读
查看证书状态:
kubectl describe certificate wildcard-certificate
代码解读
当 Status 字段显示为 ‘Issued’ 时,证书申请成功。
4.具体代码实例和解释说明
4.1 源码地址
你可以下载源码来本地调试或阅读源码。
Github: https://github.com/zhouhaoqian/aws-eks-ingress-with-traefik
4.2 Terraform 示例
通过 Terraform 自动化生成 EKS 集团与 ingress 代理服务器配置文件。Terraform 示例位于 examples/terraform 中。
4.3 EKS 创建流程
创建 EKS 集群的流程如下图所示:
- 用户或CI工具使用boto3/AWS CLI创建IAM用户,并从该用户中获取其Access Key ID与Secret Access Key。
- 用户或CI工具通过kubectl/awscli安装及配置aws-iam-authenticator以方便访问集群。
- 用户或CI工具通过Terraform创建EKS集群。
- Terraform将利用Cloudformation创建VPC、EKS集群、IAM角色、工件节点以及VPC端点等资源。
- 基于/.kube/config文件中的集群信息执行操作的kubectl/awscli将连接到该集群。
4.4 Traefik Ingress 安装流程
创建 Traefik Ingress Controller 的流程如下图所示:
- CI工具或用户将Terraform作为工具来部署Helm Chart,并因此能够顺利地安装Traefik ingress controller。
- Helm Charts会被用来通过Kubernetes REST API创建Deployments和Services从而启动Traefik ingress controller。
- 在Kubernetes API Server的帮助下,Traefik ingress controller获取了Ingress和Services的配置信息,并基于这些信息生成相应的路由规则。
4.5 Traefik Ingress 配置流程
访问集群中的 Traefik Ingress Controller 的流程如下图所示:
- 用户使用浏览器或命令行工具接入集群中的 Traefik Ingress Controller,并随后输入目标域名。
- Traefik 依据访问域名的类型(HTTP、HTTPS、TCP),确定相应服务并完成流量转发。
4.6 Kubernetes ServicMesh 安装流程
安装 Kubernetes ServicMesh 的流程如下图所示:
- 用户或自动化测试工具通过kubectl或Terraform生成一个ServiceMesh自定义资源定义(CustomResourceDefinition)对象。
- Traefik利用ServiceMesh自定义资源定义对象中的配置信息生成相应的Sidecar代理实例。
- 这些Sidecar代理通过插件机制注入到应用部署(Deployment)中,并对应用进行全面配置以确保服务具备可观察性特征。
4.7 Kubernetes ServicMesh 配置流程
配置 Kubernetes ServicMesh 的流程如下图所示:
- 开发人员或CI工具通过kubectl或Terraform执行操作来生成Service对象,并为其微服务指定不同的域名和IP地址。
- Traefik基于Service对象的配置自动生成调整路由规则以实现服务间的通信。
5.未来发展趋势与挑战
随着云计算技术的广泛应用推动下,微服务架构逐渐成为主流的应用架构模式。基于Kubernetes的服务发现、弹性伸缩以及健康监控等功能配合Service Mesh提供的流量管理和监控能力,在实际应用中使得将微服务架构迁移到Kubernetes集群中变得更加简便和高效。然而尽管Kubernetes Service Mesh具备诸多优势和功能
尽管 Kubernetes Service Mesh 提供了丰富且强大的功能支持,在实际应用中仍存在一定的局限性。例如在无法直接控制非Kubernetes平台的应用流量的情况下限制了其在复杂生态中的应用范围;此外Service Mesh所带来的复杂的架构模式不仅增加了运维人员的工作负担也给开发团队带来了额外的技术挑战。特别是在性能优化方面Service Mesh的表现仍需进一步提升尤其是在大规模集群环境下表现欠佳的问题尚未得到彻底解决
为了进一步完善Service Mesh技术栈的功能适应性和实用性云原生社区应运而生并逐渐形成雏形。该组织致力于解决Kubernetes平台中存在的关键功能和技术挑战并制定了一套开放式的参考架构和规范体系以促进Kubernetes生态系统的持续发展
6.常见问题解答
问:什么是 Service Mesh?
Kubernetes 作为容器编排系统和集群管理系统,其出现促进了云计算的发展。由于其便捷性和高效率,越来越多的公司开始采用 Kubernetes。但是,由于其开源、免费及自动扩展等特点,使得其受到众多公司青睐。一般来说,运行在 Kubernetes 上的应用可以直接通过访问 Kubernetes 节点上的端口进行服务访问,但是对于一些复杂场景,例如微服务架构,需要进一步的网络代理才能实现不同服务之间的通信。因此,在这些场景下,我们往往需要配置一个 Ingress 控制器(也叫做入口控制器)来对外暴露服务。Ingress 控制器是一个附加组件,它负责将外部请求转发到 Kubernetes 集群中的正确服务上,并且为每个服务分配不同的域名或 IP 地址。
Service Mesh (服务网格)是专门针对微服务架构设计的,旨在增强微服务之间进行可靠、可信、透明通信的能力。Service Mesh 通过控制微服务间的流量行为,努力打破单体应用中的服务边界,提供横向扩展、服务发现、熔断降级、流量加密、服务认证等多种优势。Service Mesh 的创始人兼技术总监 Thompson Brundage 曾经说过,“在一个大型复杂的分布式系统中,服务之间的通信成为一个难题。”
问:为什么要使用 Traefik Ingress Controller?
Traefik Ingress Controller 是一款开源的 Ingress 控制器,是目前最流行的开源 Ingress 控制器之一。Traefik Ingress Controller 简单易用、支持多种服务发现机制、支持动态配置、高性能、支持服务端流量切分、支持 WebSocket、支持 gRPC、支持服务质量(QoS)保证、支持负载均衡、支持速率限制、支持 TLS Termination、支持基于标签的流量路由、支持 Webhook、支持 Helm 安装等功能。
问:为什么要使用 Kubernetes ServicMesh?
Service Mesh (服务网格)是专门针对微服务架构设计的,旨在增强微服务之间进行可靠、可信、透明通信的能力。Kubernetes ServicMesh 提供的功能和优势包括:服务发现、弹性伸缩、健康检查、流量控制、可观察性、安全性、可靠性、可测试性等。Kubernetes ServicMesh 在分布式系统中扮演了重要角色,极大地促进了微服务架构的发展。
问:Service Mesh 优缺点有哪些?
Service Mesh (服务网格)有很多优点,包括:
-
去耦(Decoupling):服务间解耦,使得应用间耦合度降低,每个微服务只需要关注自己的核心业务逻辑。
-
通信简单(Simple Communication):通过 Sidecar proxy 的方式来实现服务间的通信,使得应用只需要和一个 Sidecar 代理通信,而不需要和每台服务器上的所有微服务通信。
-
低延迟(Low Latency):Sidecar 代理缓冲和转换请求,降低服务间的延迟。
-
服务可靠(Reliable Services):Sidecar 代理提供熔断、限流、超时重试等机制,确保微服务的高可用性。
-
服务治理(Service Governance):Service Mesh 提供丰富的工具和能力,如流量控制、服务间授权、健康检查、限流熔陷、故障恢复等,可以有效地管理微服务的生命周期。
-
可观测性(Observability):Service Mesh 基于统一的分布式追踪、日志和指标,使得微服务间的调用可追溯、可审计。
Service Mesh 有很多缺点,包括: -
性能开销(Performance Overhead):Sidecar 代理的引入会导致微服务运行时的性能消耗增加。
-
学习曲线(Learning Curve):掌握 Service Mesh 实现原理需要了解各子服务间的通信规范以及 Kubernetes 扩展功能的基础知识。
-
网络封闭(Network Partitioning):通过隔离各子服务以实现独立管理的 Service Mesh 架构设计,在实际应用中可能会导致网络通信范围受限。
-
测试复杂度(Test Complexity):开发基于 Service Mesh 的系统不仅需要编写专门的测试代码,还需要全面考虑各子服务之间的交互路径及其影响因素。
想了解 Traefik 和 Kubernetes ServicMesh 之间的区别吗?
Traefik 是一项开源解决方案,在支持 HTTP 引擎的同时具备负载均衡功能,并能在 Kubernetes 集群中部署为 Deployment 对象形式存在。它具备高度可扩展性,在多种场景下都能满足实际需求。
Kubernetes 提供了 Service_mesh 网格解决方案,在其基础架构上集成了 Istio 网络控制组件来实现流量管理等功能。
相较于 Traefik 方案,在功能上 Service_mesh 网格提供了更为丰富和全面的支持选项。
