Kubernetes微服务架构应用实践

本文涉及的产品
任务调度 XXL-JOB 版免费试用,400 元额度,开发版规格
云原生网关 MSE Higress,422元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介:

谷歌于2015年正式推出的Kubernetes开源项目目前已经吸引了众多IT公司的关注,这些公司包括Redhat、CoreOS、IBM、惠普等知名IT公司,也包括国内如华为、时速云等公司。为什么Kubernetes会引发这么多公司的关注?最根本的原因是Kubernetes是新一代的基于先进容器技术的微服务架构平台,它将当前火爆的容器技术与微服务架构两大吸引眼球的技术点完美的融为一体,并且切切实实的解决了传统分布式系统开发过程中长期存在的痛点问题。

本文假设您已经很熟悉并掌握了Docker技术,这里不会再花费篇幅介绍它。正是通过轻量级的容器隔离技术,Kubernetes实现了“微服务”化的特性,同时借助于Docker提供的基础能力,使得平台的自动化能力得以实现。

概念与原理

作为一个架构师来说,我们做了这么多年的分布式系统,其实我们真正关心的并不是服务器、交换机、负载均衡器、监控与部署这些事物,我们真正关心的是“服务”本身,并且在内心深处,我们渴望能实现图1所示的下面的这段“愿景”:

我的系统中有ServiceA、ServiceB、ServiceC三种服务,其中ServiceA需要部署3个实例、而ServiceB与ServiceC各自需要部署5个实例,我希望有一个平台(或工具)帮我自动完成上述13个实例的分布式部署,并且持续监控它们。当发现某个服务器宕机或者某个服务实例故障的时候,平台能够自我修复,从而确保在任何时间点,正在运行的服务实例的数量都是我所预期的。这样一来,我和我的团队只需关注服务开发本身,而无需再为头疼的基础设施和运维监控的事情而烦恼了。

图1 分布式系统架构愿景

直到Kubernetes出现之前,没有一个公开的平台声称实现了上面的“愿景”,这一次,又是谷歌的神作惊艳了我们。Kubernetes让团队有更多的时间去关注与业务需求和业务相关的代码本身,从而在很大程度上提升了整个软件团队的工作效率与投入产出比。

Kubernetes里核心的概念只有以下几个:

Service

Pod

Deployments(RC)

Service表示业务系统中的一个“微服务”,每个具体的Service背后都有分布在多个机器上的进程实例来提供服务,这些进程实例在Kubernetes里被封装为一个个Pod,Pod基本等同于Docker Container,稍有不同的是Pod其实是一组密切捆绑在一起并且“同生共死”的Docker Container,从模型设计的角度来说,的确存在一个服务实例需要多个进程来提供服务并且它们需要“在一起” 的情况。

Kubernetes的Service与我们通常所说的“Service”有一个明显的的不同,前者有一个虚拟IP地址,称之为“ClusterIP”,服务与服务之间“ClusterIP+服务端口”的方式进行访问,而无需一个复杂的服务发现的API。这样一来,只要知道某个Service的ClusterIP,就能直接访问该服务,为此,Kubernetes提供了两种方式来解决ClusterIP的发现问题:

第一种方式是通过环境变量,比如我们定义了一个名称为ORDER_SERVICE 的Service ,分配的ClusterIP为10.10.0.3 ,则在每个服务实例的容器中,会自动增加服务名到ClusterIP映射的环境变量:ORDER_SERVICE_SERVICE_HOST=10.10.0.3,于是程序里可以通过服务名简单获得对应的ClusterIP。

第二种方式是通过DNS,这种方式下,每个服务名与ClusterIP的映射关系会被自动同步到Kubernetes集群里内置的DNS组件里,于是直接通过对服务名的DNS Lookup机制就找到对应的ClusterIP了,这种方式更加直观。

由于Kubernetes的Service这一独特设计实现思路,使得所有以TCP /IP 方式进行通信的分布式系统都能很简单的迁移到Kubernetes平台上了。如图2所示,当客户端访问某个Service的时候,Kubernetes内置的组件kube-proxy透明的实现了到后端Pod的流量负载均衡、会话保持、故障自动恢复等高级特性。

图2 Kubernetes负载均衡原理

Kubernetes是如何绑定Service与Pod的呢?它如何区分哪些Pod对应同一个Service?答案也很简单——“贴标签”。每个Pod都可以贴一个或多个不同的标签(Label),而每个Service都一个“标签选择器”,标签选择器(Label Selector)确定了要选择拥有哪些标签的对象,比如下面这段YAML格式的内容定义了一个称之为ku8-redis-master的Service,它的标签选择器的内容为“app: ku8-redis-master”,表明拥有“app= ku8-redis-master”这个标签的Pod都是为它服务的。

apiVersion: v1

kind: Service

metadata:

name: ku8-redis-master

spec:

ports:

  • port: 6379

selector:

app: ku8-redis-master

下面是对应的Pod的定义,注意到它的labels属性的内容:

apiVersion: v1

kind: Pod

metadata:

name: ku8-redis-master

labels:

app: ku8-redis-master

spec:

containers:

  • name: server

image: redis

ports:

  • containerPort: 6379

restartPolicy: Never

最后,我们来看看Deployment/RC的概念,它的作用是用来告诉Kubernetes,某种类型的Pod(拥有某个特定标签的Pod)需要在集群中创建几个副本实例,Deployment/RC的定义其实是Pod创建模板(Template)+Pod副本数量的声明(replicas):

apiVersion: v1

kind: ReplicationController

metadata:

name: ku8-redis-slave

spec:

replicas: 2

template:

metadata:

labels:

app: ku8-redis-slave

spec:

containers:

  • name: server

image: devopsbq/redis-slave

env:

  • name: MASTER_ADDR

value: ku8-redis-master

ports:

  • containerPort: 6379

Kubernetes开发指南

本节我们以一个传统的Java应用为例,来说明如何将其改造迁移到Kubernetes的先进微服务架构平台上来。

如图3所示,我们的这个示例程序是一个跑在Tomcat里的Web应用,为了简化,没有用任何框架,直接在JSP页面里通过JDBC操作数据库。

图3 待改造的Java Web应用

上述系统中,我们将MySQL服务与Web应用分别建模为Kubernetes中的一个Service,其中MySQL服务的Service定义如下:

apiVersion: v1

kind: Service

metadata:

name: mysql

spec:

ports:

  • port: 3306

selector:

app: mysql_pod

MySQL服务对应的Deployment/RC的定义如下:

apiVersion: v1

kind: ReplicationController

metadata:

name: mysql-deployment

spec:

replicas: 1

template:

metadata:

labels:

app: mysql_pod

spec:

containers:

  • name: mysql

image: mysql

imagePullPolicy: IfNotPresent

ports:

  • containerPort: 3306

env:

  • name: MYSQL_ROOT_PASSWORD

value: "123456"

下一步,我们需要改造Web应用中获取MySQL地址的这段代码,从容器的环境变量中获取上述MySQL服务的IP与Port:

String ip=System.getenv("MYSQL_SERVICE_HOST");

String port=System.getenv("MYSQL_SERVICE_PORT");

ip=(ip==null)?"localhost":ip;

port=(port==null)?"3306":port;

conn = java.sql.DriverManager.getConnection("jdbc:mysql://"+ip+":"+port+"?useUnicode=true&characterEncoding=UTF-8", "root","123456");

接下来,将此Web应用打包为一个标准的Docker镜像,名字为k8s_myweb_image,这个镜像直接从官方Tomcat镜像上添加我们的Web应用目录demo到webapps目录下即可,Dockerfile比较简单,如下所示:

FROM tomcat

MAINTAINER bestme

ADD demo /usr/local/tomcat/webapps/demo

类似之前的MySQL服务定义,下面是这个Web应用的Service定义:

apiVersion: v1

kind: Service

metadata:

name: hpe-java-web

spec:

type: NodePort

ports:

  • port: 8080

nodePort: 31002

selector:

app: hpe_java_web_pod

我们看到这里用了一个特殊的语法:NodePort,并且赋值为31002,词语法的作用是让此Web应用容器里的8080端口被NAT映射到kuberntetes里每个Node上的31002端口,从而我们可以用Node的IP和端口31002来访问Tomcat的8080端口,比如我本机的可以通过http://192.168.18.137:31002/demo/来访问这个Web应用。

下面是Web应用的Service对应的Deployment/RC的定义:

apiVersion: v1

kind: ReplicationController

metadata:

name: hpe-java-web-deployement

spec:

replicas: 1

template:

metadata:

labels:

app: hpe_java_web_pod

spec:

containers:

  • name: myweb

image: k8s_myweb_image

imagePullPolicy: IfNotPresent

ports:

  • containerPort: 8080

定义好所有Service与对应的Deployment/RC描述文件后(总共4个yaml文件),我们可以通过Kubernetes的命令行工具kubectrl –f create xxx.yaml提交到集群里,如果一切正常,Kubernetes会在几分钟内自动完成部署,你会看到相关的资源对象都已经创建成功:

-bash-4.2# kubectl get svc

NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE

hpe-java-web 10.254.183.22 nodes 8080/TCP 36m

kubernetes 10.254.0.1 443/TCP 89d

mysql 10.254.170.22 3306/TCP 36m

-bash-4.2# kubectl get pods

NAME READY STATUS RESTARTS AGE

hpe-java-web-deployement-q8t9k 1/1 Running 0 36m

mysql-deployment-5py34 1/1 Running 0 36m

-bash-4.2# kubectl get rc

NAME DESIRED CURRENT AGE

hpe-java-web-deployement 1 1 37m

mysql-deployment 1 1 37m

结束语

从上面步骤来看,传统应用迁移改造到Kubernetes上还是比较容易的,而借助于Kubernetes的优势,即使一个小的开发团队,也能在系统架构和运维能力上迅速接近一个大的研发团队的水平。

此外,为了降低Kubernetes的应用门槛,我们(惠普中国CMS研发团队)开源了一个Kubernetes的管理平台Ku8 eye,项目地址为https://github.com/bestcloud/ku8eye,Ku8 eye很适合用作为小公司的内部PaaS应用管理平台,其功能架构类似图4所示的Ku8 Manager企业版,Ku8 eye采用Java开发完成,是目前唯一一个开源的Kubernetes图形化管理系统,也希望更多爱好开源和有能力的同行参与进来,将它打造成为国内最好的云计算领域的开源软件。

图4 基于Kubernetes的PaaS平台架构

作者简介:吴治辉,惠普公司系统架构师,拥有超过15年的软件研发经验,专注于电信软件和云计算方面的软件研发,同时也是《Kubernetes权威指南》作者之一。

本文转自d1net(转载)

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
打赏
0
0
0
0
192
分享
相关文章
极氪汽车云原生架构落地实践
随着极氪数字业务的飞速发展,背后的 IT 技术也在不断更新迭代。极氪极为重视客户对服务的体验,并将系统稳定性、业务功能的迭代效率、问题的快速定位和解决视为构建核心竞争力的基石。
安全监控系统:技术架构与应用解析
该系统采用模块化设计,集成了行为识别、视频监控、人脸识别、危险区域检测、异常事件检测、日志追溯及消息推送等功能,并可选配OCR识别模块。基于深度学习与开源技术栈(如TensorFlow、OpenCV),系统具备高精度、低延迟特点,支持实时分析儿童行为、监测危险区域、识别异常事件,并将结果推送给教师或家长。同时兼容主流硬件,支持本地化推理与分布式处理,确保可靠性与扩展性,为幼儿园安全管理提供全面解决方案。
阿里云SLB深度解析:从流量分发到架构优化的技术实践
本文深入探讨了阿里云负载均衡服务(SLB)的核心技术与应用场景,从流量分配到架构创新全面解析其价值。SLB不仅是简单的流量分发工具,更是支撑高并发、保障系统稳定性的智能中枢。文章涵盖四层与七层负载均衡原理、弹性伸缩引擎、智能DNS解析等核心技术,并结合电商大促、微服务灰度发布等实战场景提供实施指南。同时,针对性能调优与安全防护,分享连接复用优化、DDoS防御及零信任架构集成的实践经验,助力企业构建面向未来的弹性架构。
127 76
云原生时代的应用架构演进:从微服务到 Serverless 的阿里云实践
云原生技术正重塑企业数字化转型路径。阿里云作为亚太领先云服务商,提供完整云原生产品矩阵:容器服务ACK优化启动速度与镜像分发效率;MSE微服务引擎保障高可用性;ASM服务网格降低资源消耗;函数计算FC突破冷启动瓶颈;SAE重新定义PaaS边界;PolarDB数据库实现存储计算分离;DataWorks简化数据湖构建;Flink实时计算助力风控系统。这些技术已在多行业落地,推动效率提升与商业模式创新,助力企业在数字化浪潮中占据先机。
55 12
# 模型上下文协议(MCP)详解:背景、架构与应用
模型上下文协议(MCP)是由Anthropic提出的开源标准,旨在解决大语言模型与外部数据源和工具集成的难题。作为AI领域的“USB-C接口”,MCP通过标准化、双向通信通道连接模型与外部服务,支持资源访问、工具调用及提示模板交互。其架构基于客户端-服务器模型,提供Python、TypeScript等多语言SDK,方便开发者快速构建服务。MCP已广泛应用于文件系统、数据库、网页浏览等领域,并被阿里云百炼平台引入,助力快速搭建智能助手。未来,MCP有望成为连接大模型与现实世界的通用标准,推动AI生态繁荣发展。
76 7
融合AMD与NVIDIA GPU集群的MLOps:异构计算环境中的分布式训练架构实践
本文探讨了如何通过技术手段混合使用AMD与NVIDIA GPU集群以支持PyTorch分布式训练。面对CUDA与ROCm框架互操作性不足的问题,文章提出利用UCC和UCX等统一通信框架实现高效数据传输,并在异构Kubernetes集群中部署任务。通过解决轻度与强度异构环境下的挑战,如计算能力不平衡、内存容量差异及通信性能优化,文章展示了如何无需重构代码即可充分利用异构硬件资源。尽管存在RDMA验证不足、通信性能次优等局限性,但该方案为最大化GPU资源利用率、降低供应商锁定提供了可行路径。源代码已公开,供读者参考实践。
59 3
融合AMD与NVIDIA GPU集群的MLOps:异构计算环境中的分布式训练架构实践
ACK Gateway with AI Extension:面向Kubernetes大模型推理的智能路由实践
本文介绍了如何利用阿里云容器服务ACK推出的ACK Gateway with AI Extension组件,在Kubernetes环境中为大语言模型(LLM)推理服务提供智能路由和负载均衡能力。文章以部署和优化QwQ-32B模型为例,详细展示了从环境准备到性能测试的完整实践过程。
ACK Gateway with AI Extension:大模型推理的模型灰度实践
本文介绍了如何使用 ACK Gateway with AI Extension 组件在云原生环境中实现大语言模型(LLM)推理服务的灰度发布和流量分发。该组件专为 LLM 推理场景设计,支持四层/七层流量路由,并提供基于模型服务器负载感知的智能负载均衡能力。通过自定义资源(CRD),如 InferencePool 和 InferenceModel,可以灵活配置推理服务的流量策略,包括模型灰度发布和流量镜像。
基于阿里云的开源应用智能管理架构设计与工程实践
本文以Websoft9技术方案为例,探讨企业级应用管理的范式。通过解析开源应用管理面临的部署复杂性、运维低效性和知识碎片化三大挑战,提出基于阿里云的三层架构:智能应用管理门户、核心功能层和基础设施层。文章详细阐述了应用编排标准化(IaC实践)、智能运维体系构建及知识资产数字化的技术实现路径,并结合金融与制造行业的案例,展示解决方案的实际效果。最后提供开发者资源与工具链支持,助力企业高效管理应用。
110 1
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等