kubernete中的原子调度单位:pod
在前面的文章中,我们介绍了容器技术,他的本质是操作系统上的一个进程,那么打包的容器镜像其实就是一个安装包,类似于windows操作系统中的exe文件,那容器所在的kubernete集群其实就是一个操作系统。
容器和操作系统中进程一样,并不是独立的运行,而是和其他容器之间有着关联的关系。假如我们有3个进程,因为相互之间的关系需要部署在同一台宿主机上,这3个进程每个需要分配1G内存,但是有2个宿主机,A机器有3G内存,B机器有2.5G内存,如果不能统一调度,其中2个进程调度到B机器后,因为内存不足,第3个进程启动失败。而如果我们使用kubernete中的pod,pod会对3个容器统一管理和调度,这样就会直接选择A宿主机。
调度在一个pod的中的容器,一般具有某些关联关系,比如共享Linux namespace,共享volume,通过localhost进行通信。像Tomcat和它所依赖的war包,就是这样的一个例子。在pod的,实现这个功能,依靠的是一个infra容器,这个容器使用的镜像是k8s.gcr.io/pause,只有不到200k,它的状态永远是pause,作用是启动后控制namespace,pod中的其他容器启动后就可以加入当前这个namespace中,这样pod中的容器共享一份namespace,就可以通过localhost进行通信了。如下图所示:
因此,infra容器是一个基础容器,它控制着namespace和整个pod的生命周期。
下面我们看一个yaml文件,Tomcat和war在同一个pod的不同容器中
apiVersion: v1
kind: Pod
metadata:
name: javaweb-2
spec:
initContainers:
- image: zjj2006forever/spingboot-rabbitmq
name: war
command: ["cp", "/spingboot-rabbitmq.war", "/app"]
volumeMounts:
- mountPath: /app
name: app-volume
containers:
- image: tomcat:jdk8-openjdk-slim
name: tomcat
command: ["sh","-c","/root/apache-tomcat-8.5.54-v2/bin/start.sh"]
volumeMounts:
- mountPath: /root/apache-tomcat-8.5.54-v2/webapps
name: app-volume
ports:
- containerPort: 8080
hostPort: 8001
volumes:
- name: app-volume
emptyDir: {}
上面的yaml文件中,定义了一个pod,这个pod中有2个容器,其中一个是运行标准Tomcat8镜像,一个是存放Tomcat下的war包,这儿使用的是我之前做的一个springboot-rabbitmq的镜像。同时我们也看到war包所在的容器类型是initContainer,这个镜像的特点是会比spec.containers中的容器先启动。而且,这2个容器都挂载了一个叫app-volume的volume,这个volume的路径是/app,war包容器启动时会把war包copy到/app目录下,这样Tomcat容器的/root/apache-tomcat-8.5.54-v2/webapps下就可以看到这个war包了。这就是kubernete容器编排的高明之处。
如果没有pod,那就是两种处理方式,要不就是在Tomcat容器下启动一个war包容器,这种方式不方便升级war包;要不就是把war包放在宿主机上,挂载在容器中,但这种情况不适合分布式场景。
上面这个配置所使用的设计模式,叫做sidecar,也就是在pod中启动一个辅助容器来配合主容器进程的工作,上面的war容器就是一个sidecar。sidecar有很多场景可以应用,比如pod中可以启动一个sidecar来收集日志。
- 剑指OFFER之数组中出现次数超过一半的数字(九度OJ1370)
- 如何成为一名10x的数据分析师?
- 肥料生产商全套三拼在手:拟融资1.47亿元
- 《外媒Cointelegraph专访Qtum量子链Jordan Earls》—浅谈目前Dapps的主要问题
- ASP .Net Core 2.0 修改默认端口
- 不满一岁的潜力股:2017年3D打印机器人盘点
- Reporting Service报表开发
- 不要信任云:这不只是安全的问题
- C#温故而知新—闲话.Net
- c# IO&&线程 打造 定时打开指定程序
- 前FDIC主席:比特币政策不应打击加密货币发展
- 任何人都不应该控制区块链供应链
- c# IO操作(带进度的文件复制器,读取文本文件的指定行)
- 高科技来了!玩游戏一样开船的时代来了……
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android中oncreate中获得控件高度或宽度的实现方法
- Android编程自定义对话框(Dialog)位置及大小的方法
- android端实现验证码随机生成功能
- Android编程实现切换imageView的方法分析
- 猿实战20——商品发布之sku与笛卡尔乘积的那些事儿
- 浅谈Android单元测试的作用以及简单示例
- linux上传并配置jdk和tomcat的教程详解
- Android SQLite事务处理结合Listview列表显示功能示例
- Android开发之如何自定义数字键盘详解
- 在Android上实现HttpServer的示例代码
- Linux /etc/network/interfaces配置接口方法
- Android中Service和Activity相互通信示例代码
- Android编程实现定时发短信功能示例
- Android实现新浪微博一键分享的实例代码
- Android实现常见的验证码输入框实例代码