文章目录
- 什么是云原生?
- 第二讲 容器的基本概念
- 什么是容器?
- 容器运行时的生命周期
- 容器项目的架构
- 容器和VM的差异
- 第三讲 Kubernetes核心概念
- 什么是Kubernetes
- Kubernetes架构
- Kubernetes核心概念和API
- 第四讲 理解Pod和容器设计模式
- 为什么Pod必须是原子调度单位?
- Pod实现机制
什么是云原生?
不同企业对云原生有不同的解释,最为广泛接受的是:云原生是一类技术的统称 或者 是一套指导进行软件架构设计的思想,通过云原生技术,我们可以构建出更易于弹性扩展的应用程序。它包含了当前业界的一些热门的技术,比如:容器、微服务、DevOps等。
第二讲 容器的基本概念
什么是容器?
容器是一个视图隔离(能够看见部分进程等 namespace)、资源可限制(限制资源使用率 cgroup)、独立文件系统(chroot)。
容器运行时所需要的所有文件集合称为容器镜像。通常采用Dockerfile构建镜像。
容器运行时的生命周期
-
单进程模型
启动容器时,会选择相应的文件系统(镜像来提供),以及指定相应的运行程序,那么这个运行程序我们称为init进程。在容器运行过程中,我们会发现,当这个init进程启动了,那么这个容器也启动了,当这个init进程退出了,那么这个容器也就随之退出了。所以,init进程的生命周期与容器生命周期一致。
-
数据持久化
数据卷volume,独立于容器的生命周期;
容器项目的架构
-
moby容器引擎架构
moby daemon会提供关于容器、镜像、网络以及volume的管理。它依赖的最重要的组件是containerd(容器运行时管理引擎),独立于moby daemon,containerd-shim管理容器生命周期,可被containerd动态接管。
容器和VM的差异
VM是利用Hypervisor虚拟化技术来模拟硬件资源,需要Guest OS(装在VM上的系统),可以提供更好的隔离效果。但是,我们需要将一部分的计算资源交给虚拟化,导致很难充分利用计算资源,并且每个Guest OS需要占用大量的磁盘空间。
容器无需Guest OS,只需要一个独立的文件系统。所有的隔离级别都是进程级别的;启动时间更快;但隔离效果较弱。
第三讲 Kubernetes核心概念
什么是Kubernetes
自动化的容器编排平台
核心功能:
- 服务发现与负载均衡;
- 容器自动装箱(把一个容器放到某个集群的某个机器上);
- 存储编排;
- 自动容器恢复(节点健康检查,将有问题的节点上的容器迁移到其他节点上去);
- 自动发布与回滚;
- 配置与密文管理;
- 批量执行;
- 水平伸缩(业务负载检查,可以对负载过高的服务进行扩容);
Kubernetes架构
- API Server:消息传送;
- Controller:完成对集群状态的管理;
- Scheduler:调度;
- etcd:分布式存储,API Server中所需要的信息都放在etcd中;
用户可以通过ui或cli向kubernetes提供一个pod进行部署,API Server会将相关信息存储到etcd中,Scheduler会通过API Server的watch或者notification机制得到这个信息(有一个pod需要被调度),Scheduler会根据它的资源状态进行一次调度决策,在完成这次调度之后,Scheduler会向API Server通知这个pob需要被调度到某个节点上,API Server会将调度的结果再次写入到etcd中。然后,API Server会通知对应的节点进行pob的启动和执行。相应节点的kubelet会得到这个通知,调用Container runtime来配置、启动这个容器的运行环境,去调用Storage Plugin来配置存储,调用Network Plugin来配置网络。
Kubernetes核心概念和API
-
Pod
- 最小的调度以及资源单位;
- 由一个或者多个容器组成;
- 在Pob中可以定义容器运行的方式(Command、环境变量等);
- 提供给容器共享的运行环境(网络、进程空间,pob与pob之间是有隔离的);
-
Volume
- 用来声明容器的访问目录(Pob中的容器可以访问的文件目录);
- 一个volume可以被挂载在一个Pob中的一个或多个容器的指定路径下;
- volume是一个抽象的概念,它可以支持多种后端的存储(分布式、云存储…);
-
Deployment
-
定义一组Pob的副本数目、版本等;
-
通过Colltroller维持Pob的数目,Controller可以自动恢复失败的Pod;Deployment中Pob的数目是通过Controller来指定的,当一个Pod失败时,Controller可以检测到,来生成新的Pob。
-
可以通过Controller以指定的策略控制版本:滚动升级、重新生成、回滚;
-
Service
- 提供访问一个或多个Pod实现的稳定访问地址(负载均衡);
-
Namespace
- 一个集群内部的逻辑隔离机制(鉴权、资源调度);
- 每个资源都属于一个Namespace;
- 同一个Namespace中的资源命名唯一;
第四讲 理解Pod和容器设计模式
由四个进程共同组成的应用helloworld,在kubernates中会被定义为拥有四个容器的Pod。Pob只是一个逻辑单位,真正启来的实际上是四个容器。
为什么Pod必须是原子调度单位?
举例:两个紧密协作(需要部署在一台机器上)的容器App和LogCollector;
内存要求:App—1G、LogCollector:0.5G;
当前可用内存:Node_A:1.25G、Node_B:2G;
如果App先被调度到了Node_A上,那么就会导致LogCollector调度失败。
这就是Task co-scheduling问题:
- Mesos的解决办法:资源囤积;所有设置了Affinity约束的任务都到达时,才开始同一进行调度;带来的问题是:调度效率损失、死锁;
- Google Omega:乐观调度;不管冲突,出现冲突之后回滚;
- Kubernetes:Pod;不存在上面的问题;App和LogCollector属于一个Pob,一起被调度;
亲密关系:两个应用需要运行在同一台宿主机上(Pod之间);通过调度解决;
超亲密关系:会发生直接的文件交换;使用localhost或者socket文件进行本地通信;会发生非常频繁的RPC调用;会共享某些Linux Namespace(比如:一个容器要加入另一个容器的Network Namespace,就可以看到另一个容器的网络设备以及网络信息);通过Pod解决;
Pod实现机制
容器之间原本是被Linux Namespace和cgroups隔离开的,那么如何让一个Pod里的多个容器之间最高效的共享某些资源和数据?
-
共享网络
在每一个Pod里会启动一个Infra container小容器来共享整个Pod的Network Namespace。Pob内部容器直接使用localhost进行通信;每个容器看到的网络设备跟Infra容器看到的一样;一个Pod只有一个IP地址,也就是这个Pod的Network Namespace对应的IP地址;所有网络资源都是一个Pod一份,并且被该Pod中的所有容器共享;整个Pod的生命周期跟Infra容器一致,而与内部的其他容器无关;
-
共享存储
挂载到同一个volume;