转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。

在上节中,我们为大家介绍了Pod的基础内容,Kubernetes如何站在上帝视角上处理容器和容器之间的关系。但仅仅有Pod却还不够,对于大部分用户而言如何调度和管理自己的应用才是真正核心的问题,而对这一内容的解决方案才是Kubernetes最终极大杀器。

Pod间的编排管理

让我们从一个例子出发,假设现在的用户需求是:

以3机负载均衡的形式部署一个私有云客户的活字格应用,应该如何实现呢?

Docker的“古典”做法

在活字格公有云版开发组之前开发的版本中,实现方法大概是这样:使用三个不同的物理机,先把用户的应用run成容器,然后安装在在这三个物理机上,在三台服务器之外再买一个负载均衡服务,最后通过域名解析配置,将流量分别导向三个不同的服务机。

听起来似乎也挺简单的。

但是在现实中,我们会遇到考虑其他问题,比如: 如果我们只有两台服务器呢?如果有一台服务器中的container挂了呢?如果两台服务器CPU跑满了呢?

这些调度方面的内容看起来很简单,但是实现起来却需要长时间的编码和调试。而且一通输出之后,最终做出来也可能只是个Docker Swarm而已。

Kubernetes里的容器编排

现在我们把上述需求看做是我们最终的目标,来看kubernetes是如何一步一步进行容器编排从而解决了这个问题。相信大家看完这部分内容之后,以上问题便会迎刃而解。

Kubernetes所做的容器编排核心内容其实是Pod编排,如何让这些Pod配合起来协同工作,则是编排的核心。在上一节中我们一起了解了kubernetes所做的是将各种关系进行了抽象,这些关系本质其实是Pod之间的关系。kubernetes将Pod的关系抽象成了以下几种,并且为这些关系定义了相对的控制器便于进行编排管理:

l  无状态Pod副本之间的协同关系——Deployment

l  有状态Pod副本之间的拓扑关系——StatefulSet

l  容器化守护进程——DaemonSet

l  离线业务——Job和CronJob

这些概念看起来可能让你有些不知所云,其实这些内容只是不同上述的控制器对Pod的不同的管理方式而已。

限于篇幅和对这部分内容的理解深度,这里我们将只分享活字格公有云版开发组中最多使用到kubernetes最常用的一种控制器——Deployment。

Deployment控制器功能介绍

我们先解释什么是控制器:控制器是kubernetes中管理待编排对象的程序,我们把一个对象管理另一个对象的模式称为控制器模式。

kubernetes中的所有待编排对象都是通过控制器模式管理的。

其核心就是一个死循环,在循环中不停地判断当前编排对象的状态,如果不满足预期状态就更新它,如下的伪代码就是描述一个控制器的工作原理:

Deployment控制器的功能是:维护多个相同的无状态Pod副本以规定的数量运行,并且支持水平扩展以及滚动更新。

有了这个控制,为了实现我们的最终需求——负载均衡中的活字格服务,这个Pod就可以通过Deployment管理。我们可以通过Deployment让我们的Pod在kubernetes集群中始终以3个副本的形式存在。

只需要用Deployment来编排我们定义的Pod,并且要求副本数量是3,Deployment控制循环中就会不停地判断我们的Pod的副本数量是否是3,如果不是,就会触发水平扩展功能进行调整,最终达到满足期望状态(副本数==3)。

Deployment工作原理演示

介绍了这么多,我们从实例出发为大家演示Deployment是如何工作的。

由于活字格的镜像配置过于复杂,因此这里我们通过一个Nginx的多副本配置来感受一下Deployment控制器的控制结果。

我们可以通过以下yaml定义一个维护了3个nginx副本的deployment:

其实Kubernetes在最初的版本中只有ReplicaSet这种控制器模式,控制的是多副本Pod编排逻辑,后来出现了滚动更新逻辑,为了解决滚动更新的需求,在ReplicaSet基础上扩展出了Deployment。

apiVersion: apps/v1

kind: Deployment

metadata:

  name: sample-deployment-nginx

spec:

  selector:

    matchLabels:

      app: sample-deployment-nginx

  replicas: 3

  template:

    metadata:

      labels:

        app: sample-deployment-nginx

    spec:

      containers:

      - name: sample-nginx

        image: nginx:1.9.1

        ports:

        - containerPort: 80

这里出现了三个特殊字段:

1.     selector:选择器,类似于js中的选择器,其功能就是选择指定的pod运行,这个实例中我们指定所有app==sample-deployment-nginx的pod才会被这个Deployment所部署

2.     replicas:指明这个Deployment维护的副本个数

3.     template:控制器中提供了template这个语法,可以让我们直接在控制器的yaml中直接编写所需要编排的Pod信息

编写完这个sample-deployment-nginx.yaml后,执行一下:

kubectl apply -f sample-deployment-nginx.yaml

这个三副本的控制器就被成功运行了,使用该指令查看运行结果:

kubectl get pods -l app=sample-deployment-nginx

可以看到3副本Pod已经成功在kubernetes中运行了

如果这时我们执行以下命令删除podname==sample-deployment-nginx-54545f95cd-wtllm的副本

kubectl delete pod sample-deployment-nginx-54545f95cd-wtllm

可以自动生成一个新的pod来维持replicas==3:



通过上述实例,我们可以看到Deployment控制器对副本数量的控制结果,其实是ReplicaSet控制器在控制副本的数量。Deployment是ReplicaSet控制器的控制器,这种多层之间相互控制的模式在kubernetes也十分常见,其之间的关系如下图所示:

至此,一个deployment管理pod的所有功能都已经展示完成了,可以看到kubernetes中控制器管理之间的精巧关系:多个控制器协同工作,既能保证精准控制,也能拆分进程阻塞从而提升性能。

其他控制器的介绍

当你理解了deployment控制器,就很容易理解其他控制器的工作原理。

在这里我们简单做个说明,为大家介绍其他控制器的控制逻辑:

l  StatefulSet:控制满足有拓扑状态或者持久化存储的Pod,拓扑状态的意思就是Pod之间存在明确的先后生成关系,持久化存储就是当副本被删除或者修改了,其内部保存的数据还会存在

l  DaemonSet:守护进程控制器,是一个Node(服务器节点)仅能存在一个的Pod,比如系统的日志采集器等就应该用这种方式调度

l  Job与CronJob:Job就是任务调度,一个Pod在调度完成后就结束了不会再有新的任务产生,Job用于维护一个任务Pod运行中的各种状态正常,异常状态重启等。对应的CronJob就是定时任务,使用过Quartz的同学一定不陌生

总结

综上,kubernetes中就是通过上述的各种控制器维护所有Pod的编排工作的,并且其还提供了完善的API可以让用户自行定义满足自己需求的各种Pod编排控制器。但是对于deployment本文只是简单的展示了一些常用的功能点,其内部还有滚动更新的最大资源、金丝雀发布和灰度发布等各种功能需要继续细致的学习。

本章中以活字格公有云为例,为大家介绍了k8s容器编排部分的实现。在下节中我们将继续为大家分享,为了实现这个终极需求的另一部分——如何实现 “人与狗的交往过程”。

Docker与k8s的恩怨情仇(六)—— “容器编排”上演“终结者”大片的更多相关文章

  1. Docker与k8s的恩怨情仇(七)—— “服务发现”大法让你的内外交互原地起飞

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 第一章:Docker与k8s的恩怨情仇(一)-成为PaaS前浪的Cloud Foundry 第二章:Dock ...

  2. Docker与k8s的恩怨情仇(四)-云原生时代的闭源落幕

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 在本系列前几篇文章中,我们介绍了从Cloud Foundry到Docker等PaaS平台的发展迭代过程.今天 ...

  3. Docker与k8s的恩怨情仇(八)——蓦然回首总览Kubernetes

    在系统介绍了如何实际部署一个K8S项目后,作为本系列文章的最后一篇,我们一起来看看Kubernetes集群内容总览,再对一些更深层次的功能进行总结. Kubernetes总览 下图是一个k8s的总览结 ...

  4. Docker与k8s的恩怨情仇(五)——Kubernetes的创新

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 上节中我们提到了社区生态的发展使得Kubernetes得到了良性的发展和传播.比起相对封闭的Docker社区 ...

  5. Docker与k8s的恩怨情仇(二)—用最简单的技术实现“容器”

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 上次我们说到PaaS的发展历史,从Cloud Foundry黯然退场,到Docker加冕,正是Docker& ...

  6. Docker与k8s的恩怨情仇(一)—成为PaaS前浪的Cloud Foundry

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 大家在工作中或许或多或少都接触过Docker,那你知道Docker以及容器化背后的原理到底是什么吗? 容器化 ...

  7. Docker与k8s的恩怨情仇(三)—后浪Docker来势汹汹

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 上一节我们为大家介绍了Cloud Foundry等最初的PaaS平台如何解决容器问题,本文将为大家展示Doc ...

  8. Docker 与 K8S学习笔记(六)—— 容器的资源限制

    我们在启动Docker容器时,默认情况下容器所使用的资源是没有限制的,这样就会存在部分特别耗资源的容器会占用大量系统资源,从而导致其他容器甚至整个服务器性能降低,为此,Docker提供了一系列参数方便 ...

  9. DOCKER 学习笔记4 认识DockerCompose 多容器编排

    前言 通过上一节的学习,学会了如何在Linux 环境下搭建Docker并且部署Springboot 项目,并且成功的跑了起来,当然,在生产环境中,不只是需要一个后端的Web 项目,还需要比如 Ngin ...

随机推荐

  1. UiPath中恢复依赖项失败的解决方法

    目录 序言 正文 什么是依赖包? 如何查看项目使用了哪些版本的依赖包? 一.项目内查看 二.查看项目的 JSON 文件 问题根源 解决方法 一.「等」字诀 二.切换网络环境(根治) 三.手动复制依赖包 ...

  2. .NET Worker Service 作为 Windows 服务运行及优雅退出改进

    上一篇文章我们了解了如何为 Worker Service 添加 Serilog 日志记录,今天我接着介绍一下如何将 Worker Service 作为 Windows 服务运行. 我曾经在前面一篇文章 ...

  3. UF_MODL 建模操作

    Open C uc6560 uf5300uf5301uf5303uf5305uf5309uf5310uf5311uf5313uf5315uf5317uf5319uf5320uf5321uf5323uf ...

  4. 从架构师角度谈谈mybatis-plus可能存在的问题

    存在这么一个情况:对于缺营养的人来说,医生更倾向于建议他选择纯牛奶,而不是有机奶(因其有添加剂).然而,大部分人却更加倾向于选择有机奶, 因其口感不错,因此,对于选择纯牛奶还是有机奶,这是个博弈问题. ...

  5. Python3中最常用的5种线程锁你会用吗

    前言 本章节将继续围绕threading模块讲解,基本上是纯理论偏多. 对于日常开发者来讲很少会使用到本章节的内容,但是对框架作者等是必备知识,同时也是高频的面试常见问题. 官方文档 线程安全 线程安 ...

  6. Auto.js无障碍免root脚本开发学习

    Auto.js 简单入门 官方文档:https://hyb1996.github.io/AutoJs-Docs/#/ https://blog.csdn.net/QiHsMing/article/de ...

  7. nginx负载均衡与反向代理

    1.集群的特点 (1)高性能 (2)价格有效性 (3)可伸缩性 (4)高可用性 (5)透明性 2.负载均衡概述 负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡.分 ...

  8. nginx日志分析及其统计PV、UV、IP

    一.nginx日志结构 nginx中access.log 的日志结构: $remote_addr 客户端地址 211.28.65.253 $remote_user 客户端用户名称 -- $time_l ...

  9. php加密压缩文件

    前言 近几日,用爬虫采集的了一些数据,存放到硬盘中,随着数据量越来越多,所以想上传到网盘当中,可是不加下密又觉得不放心, 所以开始用PHP的zip模块进行压缩加密. 开始 $zipArc = new ...

  10. shell下读取文件数据

    参考:https://www.imzcy.cn/1553.html while和for对文件的读取是有区别的: 1. for对文件的读是按字符串的方式进行的,遇到空格什么后,再读取的数据就会换行显示 ...