K8s -- 云原生之路

简介: 上周,抽空听了两场云栖大会(一场关于k8s 云原生的发展趋势,一场是关于k8s安全的话题), 这几年, 容器领域的技术,发展太快了,工具层出不穷 , 也越来越容易使用了, 逐渐替代了一些硬件的功能; 传统的运维正面临前所未有的挑战, 如果不了解这个领域的技术,未来可想而知451 研究说未来 76%的企业将上云, 你觉得呢 ?Auther: Makr.

上周,抽空听了两场云栖大会(一场关于k8s 云原生的发展趋势,一场是关于k8s安全的话题), 这几年, 容器领域的技术,发展太快了,工具层出不穷 , 也越来越容易使用了, 逐渐替代了一些硬件的功能; 传统的运维正面临前所未有的挑战, 如果不了解这个领域的技术,未来可想而知

image

451 研究说未来 76%的企业将上云, 你觉得呢 ?

Auther: Makr.wei
当年Twitter飞速增长期,服务器的扩容常常跟不上用户的爆炸式增长,所以经常会出现宕机,这时候会出现一只小鸟拉着鲸鱼的图片, 就是著名的失败之鲸, 08/09年的Twitter,那绝对是Twitter的一段暗黑历史,可爱的失败鲸因此得以频频出镜。它不仅仅是宕机的标识,也象征了Twitter的程序猿在修复程序之时,这些粉丝真诚的相信Twitter会越来越好。

image

Twitter 急需一个资源管理系统来帮助他们摆脱可怕的“失败之鲸”,09年,参考Google Borg的开源工具Mesos,进入了Twitter的视野,被用于解决宕机问题。同时,几位大牛开始游说Google全球数据中心网络的负责人开放Borg,对于“是否要把运营Goolgle的秘密武器作为开源技术拱手让人?”这个问题让Google管理层十分纠结,一直犹豫不决, 但最终,谷歌批准发起开源项目Kubernetes(开源版的Borg),把这一重要工具贡献给世界,从此,Kubernetes和Docker成为黄金搭档,迅速传播开来。正是因为k8s社区的高度活跃,以及功能快速迭代, 在2019年5月,Twitter宣布放弃已经管理300000台主机,使用了十年之久的Mesos, 转投Kubernetes社区。

基于Cloud-native的Kubernetes是当今最流行的应用架构,相关技术通过模块化和复杂度转移,来减轻研发的痛苦。
从头开始创建微服务,或者把大系统拆解成微服务,可参考很多重要的理论文章和实践经验。这些实践都基于 Eric Evans 的 Domain-Drive Design, 和有界上下文(Bounded Context)和聚合的理论文章。 Bounded Context 为我们把大模型分解为各种小组件提供依据, 通过聚合有界内容组成模块,并定义事务边界。无论是否是分布式微服务系统,都围绕组织架构,体系结构和运行时状态提供解决方案,除了领域模型之外,还有一系列复杂的问题需要我们考虑。

Docker和Kubernetes,为我们提供了很多新的元素和抽象工具解决分布式系统的问题,为分布式系统带来了大量的便利,不过,遵循Garbage in ,Garbage out 定律,我们放进容器的是垃圾,那么,我们也将得到一个超级垃圾体。

image

代码层面: 每一个参数,方法,实例化对象都在将来的长期运维中起到非常重要的影响,无论使用什么容器工具,开发团队交付物都非常重要。程序员要尽可能的写出逻辑清晰的代码,完成足够的自动化测试,持续重构提升代码质量,这是一个具备工匠精神的程序员的本分。
领域设计: 领域驱动的设计是让软件实现尽可能贴近真实世界的一种思想。这个技术是OOP理论的延展,准确的业务模型,清晰的事务边界,易用的接口和丰富的API,是容器自动化的基础。
微服务架构, 为设计持续变化的分布式系统,提供了有价值的规范和实践指导,这些原则可以帮助实现常规的系统需求,比如动态扩展、弹性伸缩和快速跌代
容器可以帮助我们快速的搭建一套标准的分布式系统, 模块构建和容器复用是实现Cloud-native 应用的一个先决条件,当容器数量不断增长,维护系统正常运行,管理各种资源就需要一个强大的编排工具。
Cloud native用于描述自动化,集成化,微系统化,模块化和工具化的大规模服务平台。
Distributed Primitives
JVM在本地操作系统进程中编译运行,而Kubernetes提供分布式系统的基本单元和运行工具,可分布运行在多个Node的进程中,增加了一种高维视角。
我们仍然需要使用OOP构建系统的组件,但是我们可用Kubernetes的基本元素完成一些系统间的行为
基本元素和分布式基本元素有些共性,但不能直接替换,他们工作在不同系统的层面,比如,容器化,我们仍然需要使用Java编写程序,但我们可以用 K8s 中的Cron Job 来替代Java中的ExecutorService的实现

Container
容器是Cloud-native的一个基本构建单元,相对于OOP,容器的Image可以类比Class,而Container则类似于Object,我们可以继承Class,同样的的Image也可以继承其它的Image; Object可以组装功能,同理可以将相互协作的Container放入Pod来进行容器组合。k8s可以像Jvm一样实现多主机交互,并负责资源的运行和管理。Container初始化像Java的构造函数, DaemonSets 类似于java后台线程(Daemon thread)。Pod有时类似于IOC框架,当多个容器共享生命周期,可以直接相互访问。

Container是单个业务的功能单元
Image属于团队,拥有自己的发布周期
Image有自己的运行时依赖和资源需求
Image是自包含,自定义的,承载运行时依赖
Image是不可变的,一旦创建,不可更改,且已完成配置
Image已完成运行时依赖和资源需求
Image拥有明确的定义的Api来暴露功能
Container是一次性的,随时可以安全的扩容和缩减
除了上面这些特点之外,Image业务模块创建是基于参数化的,以便于在不同环境复用。并且Image也必须实现参数化以适应各种应用场景。 原子化,模块化, 可复用化的Image,类似于编程语言中的类库
Pods
容器的Image提供单一功能单元,属于单个团队,具有独立的发布周期,并提供部署和运行时资源隔离。 大多数情况下,一个微服务对应于一个Image。
但是,Cloud-Native 提供了一个新元素来管理Kubernetes中一组容器的生命周期,它被称为Pod。 Pod是一组容器调度,部署和运行的原子单元。 一个Pod里的所有容器始终安排在同一Node上,无论是扩展还是Node迁移,都可以一起部署,还可以共享文件系统,网络和NameSpace。 这个联合体生命周期内允许Pod中的容器通过文件系统相互交互或者网络交互。
在开发和创建期,微服务对应于一个开发团队的镜像,在运行时,微服务呈现为一个Pod,Pod是部署,编排,伸缩的单位,无论是扩展还是迁移,运行容器的唯一方法是通过Pod。

image

Pod的一些特性

Pod是调度任务的最小单元。 调度程序会尝试寻找满足Pod里的容器资源的Node。如果创建包含多个Container的Pod,调度程序会寻找满足所有container资源的Node。
托管容器, 同一Pod中的容器有独特交互方式,最常见的通信方式包括使用共享本地文件系统交换数据,网络层交互,或使用主机进程间通信(IPC)机制进行高性能交互
Pod具有属于它的所有容器共享的IP地址,名称和端口范围。必须仔细配置同一Pod中的容器以避免端口冲突,就像同一主机上并行的Unix进程一样。
Pod是我们的应用程序在Kubernetes系统的原子单元,不能直接访问,那么,我们该如何访问Pod的应用呢? 答案是Service
Service
Pods 可以随时启动或者销毁,比如在对Pod扩容或者缩减,健康心跳失败,或者迁移Node时。Pod的IP的地址只有在Pod启动后才会生效,假设当前运行的Node出问题,Pod也可能会自动迁移到其它Node。这就意味着Pod的生命周期中IP地址可能会发生变化,如果这时另外一个Pod里的资源,通过IP地址访问被迁移的POD里的资源,就会发生异常,而Service就可以作为隔离层隔离这种差异,实现自动的服务发现。
这就是Kubernetes Services发挥作用的地方。Service是一个简单但功能强大的Kubernetes抽象层,它将Service名称永久绑定到IP地址和端口上。 因此,Service代表访问应用程序的入口点。在最常见的场景中,Service充当一组Pod的入口点,但情况可能并非总是如此。 Service是一个通用元素,它也可能指向Kubernetes集群外部的资源。因此,Service可用于服务发现和负载平衡,允许在不影响服务使用者的情况下改变Pod。

Label
通过上面的内容,我们可以知道微服务在创建时时一个容器,运行时是一个Pod,那么,是么是由多个微服务组成的应用系统呢 ? 在这里,kubernetes提供了另外两个元素,可以帮助我们定义应用程序的概念:标签和名称空间。
在微服务出现之前,应用程序是具有版本控制和发布周期的单体部署单元。应用程序的采用.war,.ear或其打包格式。 但随后,应用程序被拆分为微服务,这些微服务是独立开发,发布,运行,设置或扩展的。 使用微服务,应用程序的概念会减少,并且我们不再需要在应用程序级别执行关键构建工作。但是,如果您仍需要一种方法来制定某些独立服务属于某个应用程序,则可以使用标签。让我们假设我们将一个单体应用程序拆分为三个微服务,将另一个应用程序拆分为两个微服务。
现在,我们有五个Pod定义(可能还有更多的Pod实例),这些定义独立于开发和运行时的观点。但是,我们可能仍需要指出前三个Pod代表一个应用程序,而另外两个Pod代表另一个应用程序。甚至Pod也可以是独立的,提供一个业务功能,但他们可能相互依赖。 例如,一个Pod负责前端的容器,另外两个Pod负责提供后端接口。如果这些Pod中的任何停机,那么从业务角度来看,应用程序是不可用的。使用标签选择器给我们能够查询和识别一组Pod,并作为一个逻辑单元进行管理 ,下图显示了如何使用标签对分布式应用程序的各个部分进行分组 。

image

ReplicaSet使用Label来保持特定Pod的某些实例运行。 这意味着每个Pod定义都需要具有用于调度的唯一标签组合
调度程序也大量使用标签。 调度程序使用标签来共置或传播Pod,以将Pod放置在满足Pods要求的节点上
Label可以指示一组Pod的逻辑分组,并为它们提供应用程序标识。
除了前面的典型用例之外,标签还可用于存储元数据。很难准确的说标签可以用于什么,但最好有足够的标签描述Pod的所有重要特征。 例如,使用标签来指明应用程序的逻辑分组,业务特征和关键性,指定的运行时依赖等等

调度程序可以使用这些标签进行更细粒度的调度,或者可以通过命令行使用相同的标签来大规模地管理匹配的Pod。 但是,我们不应该过分夸大并提前添加太多标签。我们应该根据实际需要创建标签。删除标签风险很大,因为没有很明确的方法可以表明标签的用途,此类操作可能导致的不可预知的影响

对于金融系统,监管对机房内服务器划分,访问权限,安全级别有严格的指导。通过标签定义,我们可以分配哪些Pod在指定节点(或者说指定的物理机,机柜)上创建。

image

Annotations
Annotation与Label类似,也使用key/value键值对的形式进行定义。Label具有严格的命名规则,它定义的是Kubernetes对象的元数据(Metadata),并且用于Label Selector。Annotation则是用户任意定义的“附加”信息,以便于外部工具进行查找。
用Annotation来记录的信息包括:

build信息、release信息、Docker镜像信息等,例如时间戳、release id号、PR号、镜像hash值、docker registry地址等;
日志库、监控库、分析库等资源库的地址信息;
程序调试工具信息,例如工具名称、版本号等;
团队的联系信息,例如电话号码、负责人名称、网址等
Namespaces
Namespaces是Kubernetes系统中的另一个非常重要的概念,通过将系统内部的对象“分配”到不同的Namespace中,形成逻辑上分组的不同项目、小组或用户组,当不同的分组在整个集群中使用共享资源的同时,还能被分别管理。
Kubernetes集群在启动后,会创建一个名为“default”的Namespace,通过Kubectl可以查看到。

Namespaces用于k8s的资源管理
Namespaces为Container,Pod,Service或ReplicaSet等资源提供工作范围。资源名称在Namespaces中必须是唯一的,而且不能跨越它们。
默认情况下,Namespaces为资源提供界限,但不会隔离这些资源,阻止一个资源访问另一个资源。例如,只要Pod IP地址已知,开发Namespaces中的Pod就可以从生产Namespaces访问另一个Pod。但是,如果需要,还有Kubernetes插件可提供网络隔离,以实现跨Namespaces的真正多租户模式。
每个k8s服务必须有Namespaces,有相应的DNS地址,Namespaces的命名格式如. .svc.cluster.local。所有k8s服务的URI都含有NameSpaces的名称地址。这个类似java 里class的package name, 作用也非常类似。
用ResourceQuotas约束Namespaces的资源。集群管理员可以使用ResourceQuotas控制Namespaces中创建的各种对象个数。 例如,开发人员可以限定Namespaces只允许5个ConfigMaps,5个Secrets,5个Services,5个ReplicaSet,5个PersistentVolumeClaims和10个Pod
用ResourceQuotas指定NameSpaces 资源配比。 例如,在容量为32 GB RAM和16个内核的群集中,可以为生产环境NameSpaces分配一半资源(16 GB RAM和8个内核),然后分配8 GB RAM和4个内核,4 GB RAM和2个内核用于开发,测试的NameSpaces。
PersistentVolume & PersistentVolumeClaims
PersistentVolume(PV)在集群中是由管理员配置的网络存储。 PV是容量插件,如Volumes,其生命周期独立于使用PV的任何单个pod。PV在k8s集群中的作用类似我们经常在Linux服务器上挂载的NFS,可以很方便的做mount 映射
PersistentVolumeClaim(PVC)是由用户进行存储的请求。 它类似于pod。 Pod可以请求特定级别的资源(CPU和内存)。 指定可用资源的大小和访问模式(例如,可以一次读/写或多次只读)。
虽然PersistentVolumeClaims允许用户端使用抽象存储资源,对于不同的问题,用户端通常需要使用不同资源(例如性能)。集群管理员要能够提供各种PersistentVolumes不同的方式,不仅仅是大小和访问模式,但用户端不需要了解这些数据卷实现的细节。
PV是群集中的资源。PVC是对这些资源的请求,并且还充当对资源可用性检查。PV和PVC之间的相互作用遵循以下生命周期:Provisioning ——-> Binding ——–>Using——>Releasing——>Recycling

准备Provisioning---通过集群外的存储系统或者云平台来提供存储持久化支持。
静态提供Static:集群管理员创建多个PV。 它们携带可供集群用户使用的真实存储的详细信息。
动态提供Dynamic:当管理员创建的静态PV都不匹配用户的PersistentVolumeClaim时,集群可能会尝试为PVC动态配置卷。 此配置基于StorageClasses:PVC必须请求一个类,并且管理员必须已创建并配置该类才能进行动态配置。
绑定Binding---用户创建pvc并指定需要的资源和访问模式。在找到可用pv之前,pvc会保持未绑定状态。
使用Using---用户可在pod中像volume一样使用pvc。
释放Releasing---用户删除pvc来回收存储资源,pv将变成“released”状态。由于还保留着之前的数据,这些数据需要根据不同的策略来处理,否则这些存储资源无法被其他pvc使用。
回收Recycling---pv可以设置三种回收策略:保留(Retain),回收(Recycle)和删除(Delete)。
保留策略:允许人工处理保留的数据。
删除策略:将删除pv和外部关联的存储资源,需要插件支持。
回收策略:将执行清除操作,之后可以被新的pvc使用,需要插件支持。
下面这张图是k8s元素相互关系的直观体现

image

K8S是一个完备的分布式系统支撑平台,具有完备的集群管理能力,多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和发现机制、內建智能负载均衡器、强大的故障发现和自我修复能力、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制以及多粒度的资源配额管理能力。同时Kubernetes提供完善的管理工具,涵盖了包括开发、部署测试、运维监控在内的各个环节, 减轻了以往运维手工操作的痛苦,为DevOps思想提供了强力的支撑。

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
Kubernetes Cloud Native Docker
云原生时代的容器化实践:Docker和Kubernetes入门
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术成为企业提升敏捷性和效率的关键。本篇文章将引导读者了解如何利用Docker进行容器化打包及部署,以及Kubernetes集群管理的基础操作,帮助初学者快速入门云原生的世界。通过实际案例分析,我们将深入探讨这些技术在现代IT架构中的应用与影响。
554 2
|
10月前
|
Cloud Native Serverless 数据中心
阿里云ACK One:注册集群支持ACS算力——云原生时代的计算新引擎
ACK One注册集群已正式支持ACS(容器计算服务)算力,为企业的容器化工作负载提供更多选择和更强大的计算能力。
|
10月前
|
Cloud Native Serverless 数据中心
阿里云ACK One:注册集群支持ACS算力——云原生时代的计算新引擎
阿里云ACK One:注册集群支持ACS算力——云原生时代的计算新引擎
322 10
|
12月前
|
存储 Kubernetes 开发者
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
Docker 是一种开源的应用容器引擎,允许开发者将应用程序及其依赖打包成可移植的镜像,并在任何支持 Docker 的平台上运行。其核心概念包括镜像、容器和仓库。镜像是只读的文件系统,容器是镜像的运行实例,仓库用于存储和分发镜像。Kubernetes(k8s)则是容器集群管理系统,提供自动化部署、扩展和维护等功能,支持服务发现、负载均衡、自动伸缩等特性。两者结合使用,可以实现高效的容器化应用管理和运维。Docker 主要用于单主机上的容器管理,而 Kubernetes 则专注于跨多主机的容器编排与调度。尽管 k8s 逐渐减少了对 Docker 作为容器运行时的支持,但 Doc
486 5
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
|
Kubernetes Cloud Native 开发者
云原生入门:Kubernetes的简易指南
【10月更文挑战第41天】本文将带你进入云原生的世界,特别是Kubernetes——一个强大的容器编排平台。我们将一起探索它的基本概念和操作,让你能够轻松管理和部署应用。无论你是新手还是有经验的开发者,这篇文章都能让你对Kubernetes有更深入的理解。
|
Kubernetes Cloud Native 微服务
云原生入门与实践:Kubernetes的简易部署
云原生技术正改变着现代应用的开发和部署方式。本文将引导你了解云原生的基础概念,并重点介绍如何使用Kubernetes进行容器编排。我们将通过一个简易的示例来展示如何快速启动一个Kubernetes集群,并在其上运行一个简单的应用。无论你是云原生新手还是希望扩展现有知识,本文都将为你提供实用的信息和启发性的见解。
|
运维 Kubernetes Cloud Native
云原生技术入门:Kubernetes和Docker的协同工作
【10月更文挑战第43天】在云计算时代,云原生技术成为推动现代软件部署和运行的关键力量。本篇文章将带你了解云原生的基本概念,重点探讨Kubernetes和Docker如何协同工作以支持容器化应用的生命周期管理。通过实际代码示例,我们将展示如何在Kubernetes集群中部署和管理Docker容器,从而为初学者提供一条清晰的学习路径。
|
Kubernetes 负载均衡 Cloud Native
探索Kubernetes:云原生应用的基石
探索Kubernetes:云原生应用的基石
|
Kubernetes 监控 负载均衡
深入云原生:Kubernetes 集群部署与管理实践
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术以其弹性、可扩展性成为企业IT架构的首选。本文将引导你了解如何部署和管理一个Kubernetes集群,包括环境准备、安装步骤和日常维护技巧。我们将通过实际代码示例,探索云原生世界的秘密,并分享如何高效运用这一技术以适应快速变化的业务需求。
196 1
|
运维 Kubernetes Cloud Native
Kubernetes云原生架构深度解析与实践指南####
本文深入探讨了Kubernetes作为领先的云原生应用编排平台,其设计理念、核心组件及高级特性。通过剖析Kubernetes的工作原理,结合具体案例分析,为读者呈现如何在实际项目中高效部署、管理和扩展容器化应用的策略与技巧。文章还涵盖了服务发现、负载均衡、配置管理、自动化伸缩等关键议题,旨在帮助开发者和运维人员掌握利用Kubernetes构建健壮、可伸缩的云原生生态系统的能力。 ####

推荐镜像

更多