谷歌于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 <bestme@hpe.com>
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 <none> 443/TCP 89d
mysql 10.254.170.22 <none> 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平台架构
http://geek.csdn.net/news/detail/99478
相关推荐
本实践主要围绕Kubernetes微服务自动化架构,介绍Trident项目及其在不同场景的应用,旨在解决K8s部署和管理过程中的挑战。 首先,Kubernetes获得了广泛的认可,但在中国的网络环境下,从本地开发环境(minikube)过渡...
微服务架构是一种现代软件开发的方法论,它将大型复杂应用分解为一组小的、独立的服务,每个服务都专注于完成特定的业务功能。这种架构模式强调服务的松耦合、高内聚,允许团队独立地开发、部署和扩展各自的服务,...
总的来说,基于Kubernetes和Spring Cloud的微服务化实践为开发团队提供了全面的解决方案,帮助他们应对微服务架构带来的复杂性,并通过持续的实践和反馈改进容器云平台。这种实践不仅提高了应用的交付效率,还增强了...
《微服务架构与实践》这本书深入探讨了当今软件开发领域中的一个重要趋势——微服务架构。微服务架构是一种将单一应用程序分解为一组小型、独立的服务的软件设计模式,每个服务都运行在其自己的进程中,通常与轻量级...
本实践分为多个章节,从基础概念到具体实践,全面解析了微服务架构的原理和实践。 在【初识微服务】部分,首先提到了Web应用的整体框架,这是理解微服务的基础。传统的Web应用架构通常由前端、后端、数据库等组成,...
微服务架构是一种现代软件开发的方法论,它将大型复杂应用分解为一组小的、独立的服务,每个服务都专注于完成特定的业务功能。这种架构模式强调服务的松耦合、高内聚,允许团队独立地开发、部署和扩展各自的服务,...
《Kubernetes微服务实践》是一门深度探讨如何在Kubernetes平台上实施微服务架构的课程。源码包"k8s-msa-in-action.zip"包含了该课程的所有实例代码和相关资源,帮助学习者通过实践理解Kubernetes在微服务场景中的...
通过本课程的学习,你将掌握 Kubernetes 的基本概念和操作,了解如何在实践中运用这些知识构建和管理微服务架构。此外,你还将学习到如何解决在实际操作中可能遇到的问题,提升你的 IT 系统运维能力。
微服务架构是一种将大型复杂应用拆分为一组小型、独立的服务的方法,每个服务都专注于完成一个特定功能。Kubernetes为实现微服务提供了理想的环境,因为它支持服务发现、负载均衡、自动伸缩和容错等功能。例如,通过...
唯品会微服务架构演进之路 微服务架构是当前软件 industrie 中最流行的架构模式之一。...通过了解唯品会微服务架构的演进之路,我们可以更好地理解微服务架构的优点和挑战,並将其应用于实际项目中。
微服务架构是一种分布式系统架构...上述知识点均是基于文档内容的片段进行合理的推测和解释,具体的应用和实践细节未能完整呈现,实际工作中需结合具体业务场景、技术栈以及团队协作模式来进行微服务架构的设计和优化。
传统架构迁移到微服务架构的方案设计是一个复杂的过程,它涉及对现有系统的深入分析和理解,以及对新技术的采纳和应用。...这一过程要求团队具备扎实的技术基础和丰富的实践经验,才能够顺利推进微服务架构的转型工作。
在今天的云计算开源产业大会中,景韵分享了关于基于Kubernetes与微服务架构实现端到端流水线驱动的DevOps落地的峰会PPT材料。这一主题强调了在DevOps时代背景下,端到端流水线对于驱动DevOps实践落地的重要性。...
"Canva的微服务架构及最佳实践" 微服务架构是当今软件开发领域中的热门话题之一。Canva作为一家技术驱动型公司,已经成功地实施了微服务架构。那么,什么是微服务架构?微服务架构是一种软件开发架构风格,它将应用...
【标题】"基于微服务架构改造单体架构的实践总结" 在现代软件开发领域,微服务架构已经成为一种主流的设计模式,特别是在大型企业级应用中。本文将深入探讨华为讲师李林峰在2016年中国软件峰会上分享的关于如何从...
【金融行业微服务架构落地实践】 微服务架构在金融行业的应用相比互联网企业较少,原因包括行业特性、IT系统建设模式及对稳定性的高要求。本文将探讨微服务架构的几个关键方面,帮助传统金融行业更好地理解和实施...
微服务架构体系的深度治理是现代企业级应用开发的关键领域,尤其在Java技术栈中,这一概念已经被广泛应用。本文将深入探讨微服务架构的核心概念、治理策略以及在Java环境下的实践。 微服务架构是一种将单一应用程序...