k8s介绍
⼀、编排分类
单机容器编排
:
docker-compose
容器集群编排
:
docker swarm
、
mesos+marathon
、
kubernetes
应⽤编排
:
ansible(
模块,剧本,⻆⾊
)
⼆、系统管理进化史
1.
传统部署时代
早期,各个组织是在物理服务器上运⾏应⽤程序。 由于⽆法限制在
物理服务器中运⾏的应⽤程序资源使⽤,因此会导致资源分配问
题。
例如,如果在同⼀台物理服务器上运⾏多个应⽤程序, 则可能会出
现⼀个应⽤程序占⽤⼤部分资源的情况,⽽导致其他应⽤程序的性
能下降。
⽽⼀种解决⽅案是将每个应⽤程序都运⾏在不同的物理服务器上,
但是当某个应⽤程序资源利⽤率不⾼时,剩余资源⽆法被分配给其
他应⽤程序,⽽且维护许多物理服务器的成本很⾼。
2.
虚拟化部署时代
⽽后,虚拟化技术被引⼊了。虚拟化技术允许在单个物理服务器的
CPU
上运⾏多台虚拟机
(VirtureMachine)
。 虚拟化能使应⽤程序在不
同
VM
之间被彼此隔离,且能提供⼀定程度的安全性, 因为⼀个应
⽤程序的信息不能被另⼀应⽤程序随意访问。
虚拟化技术能够更好地利⽤物理服务器的资源,并且因为可轻松地
添加或更新应⽤程序,⽽因此可以具有更⾼的可扩缩性,以及降低
硬件成本等等的好处。通过虚拟化,你可以将⼀组物理资源呈现为
可丢弃的虚拟机集群。
每个
VM
是⼀台完整的计算机,在虚拟化硬件之上运⾏所有组件,
包括其⾃⼰的操作系统,所以由此看来,虚拟机技术占⽤资源量
⼤,在⼀台主机上最多运⾏⼗⼏台,效率不⾼。
3.
容器部署时代
容器,衍⽣于虚拟技术,但具有更宽松的隔离特性,使容器可以在
共享操作系统的同时,还能保持其轻量级的特点。⽽且每个容器都
具有⾃⼰的⽂件系统、
CPU
、内存、进程空间等,且具有最良好的
可移植性和平台兼容性。
敏捷应⽤程序的创建和部署:
与使⽤
VM
镜像相⽐,提⾼了容
器镜像创建的简便性和效率
持续开发、集成和部署:通过快速简单的回滚
(
由于镜像不可变
性
)
,提供可靠且频繁的容器镜像构建和部署。
关注开发与运维的分离:
在构建、发布时创建应⽤程序容器镜
像,⽽不是在部署时,从⽽将应⽤程序与基础架构分离。
可观察性:
不可以显示
OS
级别的信息和指标,还可以显示应⽤
程序的运⾏状况和其他指标信。
跨开发、测试和⽣产的环境⼀致性:
在笔记本计算机上也可以和
在云中运⾏⼀样的应⽤程序。
跨云和操作系统发⾏版本的可移植性:
可在
Ubuntu
、
RHEL
、
CoreOS
、本地、
GoogleKubernetes Engine
和其他任何地⽅运
⾏。
以应⽤程序为中⼼的管理:
提⾼抽象级别,从在虚拟硬件上运⾏
OS
到使⽤逻辑资源在
OS
上运⾏应⽤程序。
松散耦合、分布式、弹性、解放的微服务:
应⽤程序被分解成较
⼩的独⽴部分, 并且可以动态部署和管理
-
⽽不是在⼀台⼤型单
机上整体运⾏。
资源隔离:
可预测的应⽤程序性能。
资源利⽤:
⾼效率和⾼密度。
三、
Kubernetes
简介
Kubernetes
缩写:
K8S
,
k
和
s
之间有⼋个字符,所以因此得名。
Kubernetes
由
google
的
Brog
系统作为原型,后经
Go
语⾔延⽤
Brog
的思路重写,并捐献给
CNCF
基⾦会开源。
Kubernetes
是⼀个可移植的、可扩展的开源平台,⽤于管理容器化
的⼯作负载和服务,可促进声明式配置和⾃动化。
官⽹:
https://kubernetes.io
Github
:
https://github.com/kubernetes/kubernetes
四、
Kubernetes
功能
Kubernetes
的⽬标是让部署容器化的应⽤简单并且⾼效,提供了应
⽤部署,规划,更新,维护的⼀种机制。
Kubernetes
在
Docker
等容器技术的基础上,为容器化的应⽤提供
部署运⾏、资源调度、服务发现和动态伸缩等⼀系列完整功能,提
⾼了⼤规模容器集群管理的便捷性。
主要功能:
1.
使⽤
Docker
等容器技术对应⽤程序包装
(package)
、实例化
(instantiate)
、运⾏
(run)
。
2.
以集群的⽅式运⾏、管理跨机器的容器,解决
Docker
跨机器容
器之间的通讯问题。
3. K8S
的⾃我修复机制使得容器集群总是运⾏在⽤户期望的状
态。
五、
Kubernetes
特性
五、
Kubernetes
特性
1.
⾃动装箱
:
Kubernetes
可以根据所需资源和其他限制条件智能
地定位容器,⽽不会影响可⽤性。
2.
弹性伸缩:
使⽤命令、
UI
或者基于
CPU
使⽤情况⾃动快速扩容
和缩容应⽤程序实例,保证应⽤业务⾼峰并发时的⾼可⽤性;业
务低峰时回收资源,以最⼩成本运⾏服务。
3.
⾃我修复:
在节点故障时重新启动失败的容器,替换和重新部
署,保证预期的副本数量;杀死健康检查失败的容器,并且在未
准备好之前不会处理客户端请求,确保线上服务不中断。
4.
服务发现和负载均衡:
K8S
为多个容器提供⼀个统⼀访问⼊⼝
(内部
IP
地址和⼀个
DNS
名称),并且负载均衡关联的所有容
器,使得⽤户⽆需考虑容器
IP
问题。
5.
⾃动发布(默认滚动发布模式)和回滚:
K8S
采⽤滚动策略更新
应⽤,⼀个更新⼀个
Pod
,⽽不是同时删除所有的
Pod
,如果更
新过程中出现问题,将回滚更改,确保升级不收影响业务。
6.
集中化配置管理和密钥管理:
管理机密数据和应⽤程序配置,⽽
不需要把敏感数据暴露在镜像⾥,提⾼敏感数据安全性,并可以
将⼀些常⽤的配置存储在
K8S
中,⽅便应⽤程序使⽤。
7.
存储编排:
⽀持外挂存储并对外挂存储资源进⾏编排,挂载外部
存储系统,⽆论是来⾃本地存储,公有云(如:
AWS
),还是
⽹络存储(如:
NFS
、
Glusterfs
、
Ceph
)都作为集群资源的⼀
部分使⽤,极⼤提⾼存储使⽤灵活性。
8.
任务批量处理运⾏:
提供⼀次性任务,定时任务,满⾜批量数据
处理和分析的场景。
六、
K8S
解决裸跑
Docker
的痛点
1.
单机使⽤,⽆法有效集群。
2.
随着容器数量的上升,管理成本攀升。
3.
没有有效的容灾、⾃愈机制。
4.
没有预设编排模板,⽆法实现快速、⼤规模容器调度。
5.
没有统⼀的配置管理中⼼⼯具。
6.
没有容器⽣命周期的管理⼯具。
7.
没有图形化运维管理⼯具。
七、
Kubernetes
架构
K8S
属于主从设备模型(
Mater-Slave
架构)
,由
Master
节点负责
集群的调度、管理和运维(分配活的),
Slave
节点是运算⼯作负载
节点(⼲活的),被称为
Worker Node
节点。
Master
需要占据⼀个独⽴服务器运⾏,因为其是整个集群的
“
⼤
脑
”
,⼀旦宕机或不可⽤,那么所有控制命令都将失效,可对主节点
进⾏⾼可⽤配置。
当
Worker Node
节点宕机时,其上的⼯作负载会被
Master
⾃动转
移到其他节点上。

1. Master
节点组件
API Server
*
整个集群的控制中枢,提供集群中各个模块之间的数据交换
*
,并将
集群状态和信息存储到分布式键
-
值
(key-value)
存储系统
Etcd
集群
中。
同时它也是集群管理、资源配额、提供完备的集群安全机制的⼊
⼝,为集群各类资源对象提供增删改查以及
watch
的
REST API
接
⼝。
Controller-manager
集群状态管理器,以保证
Pod
或其他资源达到期望值
*
。
*
当集群中
某个
Pod
的副本数或其他资源因故障和错误导致⽆法正常运⾏,没
有达到设定的值时,
Controller Manager
会尝试⾃动修复并使其达到
期望状态。
Scheduler
*
集群
Pod
的调度中⼼,主要是通过调度算法将
Pod
分配到最佳的
Node
节点
*
,它通过
APIServer
监听所有
Pod
的状态,⼀旦发现新
的未被调度到任何
Node
节点的
Pod(PodSpec.NodeName
为空
)
,就
会根据⼀系列策略选择最佳节点进⾏调度。
Etcd
*
⽤于可靠地存储集群的配置数据,是⼀种持久性、轻量型、分布式
的键
-
值
(key-value)
数据存储组件
*
,作为
Kubernetes
集群的持久化
存储系统。
注:⽣产环境建议存放到单个的
SSD
硬盘,并且做好冗余。
2. Work Node
节点
Kubelet
*
负责与
Master
通信协作,管理该节点上的
Pod
,对容器进⾏健康
检查及监控,同时负责上报节点和节点上⾯
Pod
的状态。
*
Kube-proxy
*
运⾏在每个
node
节点上,实现
pod
的⽹络代理,维护⽹络规则和
四层负载均衡规则
*
,负责写⼊规则到
iptables
或
ipvs
实现服务映射
访问。
Runtime
*
负责容器的管理
*
(
新版本
K8S
使⽤的是
Containerd)
。
CoreDNS
⽤于
Kubernetes
集群内部
Service
的解析
,可以让
Pod
把
Service
名称解析成
Service
的
IP
然后通过
Service
的
IP
地址进⾏
连接到对应的应⽤上。
Calico
符合
CNI
标准的⼀个⽹络插件,它
*
负责给每个
Pod
分配⼀个不会
重复的
IP
,并且把每个节点当做⼀各
“
路由器
”*
,这样⼀个节点的
Pod
就可以通过
IP
地址访问到其他节点的
Pod
。
Docker
*
运⾏容器,负责本机的容器创建和管理⼯作。
*
⼋、
Pod
概念
⼋、
Pod
概念
Pod
是
Kubernetes
中的基本构建块,它代表⼀个或⼀组相互关联的
容器。
Pod
是
Kubernetes
的最⼩部署单元,可以包含⼀个或多个容
器,这些容器共享存储、⽹络和运⾏配置。
容器之间可以使⽤
localhost:port
相互访问,可以使⽤
volume
等实
现数据共享。根据
Docker
的构造,
Pod
可被建模为⼀组具有共享命
令空间、卷、
IP
地址和
Port
端⼝的容器。
Pod
的主要特点包括:
1.
共享存储:
Pod
中的所有容器都可以访问同⼀个存储卷
(
Persistent Volume
),实现数据共享。
2.
共享⽹络:
Pod
中的所有容器都共享同⼀个⽹络命名空间,可
以相互通信。
3.
共享运⾏配置:
Pod
中的所有容器都共享相同的运⾏配置,例
如容器的启动参数、环境变量等。
Pause
容器:
Pod
的⽗容器,它主要负责僵⼫进程的回收管理,同时通过
Pause
容器可以使同⼀个
Pod
⾥⾯的不同容器进⾏共享存储、⽹络、
PID
、
IPC
等。
九、
Kubernetes
⼯作流程
九、
Kubernetes
⼯作流程
1.
运维⼈员使⽤
kubectl
命令⼯具向
API Server
发送请求,
API
Server
接收请求后写⼊到
Etcd
中。
2. API Server
让
Controller-manager
按照预设模板去创建
Pod
。
3. Controller-manager
通过
API Server
读取
Etcd
中⽤户的预设信
息,再通过
API Server
找到
Scheduler
,为新创建的
Pod
选择
最合适的
Node
⼯作负载节点。
4. Scheduler
通过
API Server
在
Etcd
找到存储的
Node
节点元信
息、剩余资源等,⽤预选和优选策略选择最优的
Node
节点。
5. Scheduler
确定
Node
节点后,通过
API Server
交给这个
Node
节点上的
Kubelet
进⾏
Pod
资源的创建。
6. Kubelet
调⽤容器引擎交互创建
Pod
,同时将
Pod
监控信息通
过
API Server
存储到
Etcd
中。
7.
当⽤户访问时,通过
Kube-proxy
负载、转发,访问相应的
Pod
。
8.
注:
决定创建
Pod
清单的是
Controller-manager
控制器,
Kubelet
和容器引擎只是⼲活的。

⼗、
K8S
创建
Pod
流程
1.
详细流程
⾸先
Kubectl
创建⼀个
Pod
,在提交时转化为
json
。
再经过
auth
认证
(
鉴权
)
,然后传递给
API Server
进⾏处理。
API Server
将请求信息存储到
Etcd
中。
Scheduler
和
Controller-manager
会监听
API Server
的请求。
在
Scheduler
和
Controller-manager
监听到请求后,
Scheduler
会提交给
API Server
⼀个
list
清单
——
包含的是获取
node
节点信
息。
当
API Server
从
Etcd
获取后端
Node
节点信息后,会同时被
Scheduler
监听到,然后
Scheduler
进⾏优选打分制,最后将评
估结果传递给
API Server
。
⽽后,
API Server
会提交清单给对应节点的
Kubelet
(代理)。
Kubelet
代理通过
K8S
与容器的接⼝
(
例如
containerd)
进⾏交
互,假设是
docker
容器,那么此时
kubelet
就会通过
dockershim
以及
runc
接⼝与
docker
的守护进程
docker-server
进⾏交互,来创建对应的容器,再⽣成对应的
Pod
。
Kubelet
同时会借助
Metric Server
收集本节点的所有状态信
息,然后提交给
API Server
。
最后
API Server
将该节点的容器和
Pod
信息存储到
Etcd
中。
2.
简化流程
⽤户通过
kubectl
或其他
API
客户端提交
Pod Spec
给
API
Server
。
API Server
尝试将
Pod
对象的相关信息存⼊
etcd
中,待写⼊操
作执⾏完成,
API Server
即会返回确认信息⾄客户端。
Controller
通过
API Server
的
Watch
接⼝发现新的
Pod
,将
Pod
加⼊到任务队列,并启动
Pod Control
机制创建与之对应的
Pod
。
所有
Controler
正常后,将结果存⼊
etcd
。
Scheduler
通过
API Server
的
Watch
接⼝监测发现新的
Pod
,
经过给主机打分之后,让
Pod
调度到符合要求的
Node
节点,
并将结果存⼊到
etcd
中。
Kubelet
每隔⼀段时间向
API Server
通过
Node name
获取⾃身
Node
上要运⾏的
Pod
并通过与⾃身缓存⽐较,来创建新
Pod
。
Containerd
启动容器。
最后
API Server
将本节点的容器和
Pod
信息存储到
etcd
。