[虚拟化] K8S概述
1 K8S概述
1.1 K8S的简述
- Kubernetes(简称“K8s”或者“Kube”)是Google开源的、用于管理云平台中多个主机上的容器化应用的——容器集群管理系统。
- 其设计目标是在主机集群之间提供一个能够自动化部署、可拓展、应用容器可运营的平台。
- Kubernetes通常结合docker容器工具工作,并且整合多个运行着docker容器的主机集群
- Kubernetes不仅仅支持Docker,还支持Rocket,这是另一种容器技术。
- Kubernetes与Google。
- K8s最初由 Google 的工程师开发和设计
- Google 是最早研发 Linux 容器技术的企业之一,曾公开分享介绍 Google 云服务背后的技术- 如何将一切都运行于容器之中。
- Google 每周会启用超过 20 亿个容器全都由内部平台 Borg 支撑。
- Borg 是 Kubernetes 的前身,多年来开发 Borg 的经验教训成了影响 Kubernetes 中许多技术的主要因素。
1.2 K8S的诞生背景:为什么需要Kubernetes?
-
K8s的目标是让部署容器化的应用能够简单、且高效;它提供了应用部署、规划、更新、维护的一种机制。
-
K8s是一种可自动实施Linux 容器操作的开源平台。
- 它可以帮助用户省去应用容器化过程的许多手动部署和扩展操作。
- 也就是说,您可以将运行 Linux 容器的多组主机聚集在一起,借助 Kubernetes 编排功能,您可以构建跨多个容器的应用服务、跨集群调度、扩展这些容器,并长期持续管理这些容器的健康状况。
-
有了 Kubernetes,您便可切实采取一些措施来提高 IT 安全性。
-
而且这些集群可跨公共云、私有云或混合云部署主机。
-
Kubernetes 还需要与联网、存储、安全性、遥测和其他服务整合,以提供全面的容器基础架构。
-
综上,对于要求快速扩展的云原生应用而言,Kubernetes 是理想的托管平台。
- K8s于 2015 年发布,并迅速成为事实上的容器编排标准。
1.2 K8S的特点
- 自动推出和回滚
K8s 会逐步推出应用程序或其配置的更改,同时监控应用程序运行状况以确保它不会同时终止所有实例。
如果出现问题,K8s 会为您回滚(rollback)更改。
利用不断增长的部署解决方案生态系统。
- 服务发现和负载均衡
使用不熟悉的服务发现机制无需修改应用程序。
K8s 为 Pod 提供了自己的 IP 地址和一组 Pod 的单个 DNS 名称,并且可以在它们之间进行负载平衡。
- 存储编排
自动挂载选择的存储系统,无论是本地存储、公共云提供商,还是网络存储系统。
- 机密和配置管理
部署和更新机密和应用程序配置,而无需重建映像,也无需在堆栈配置中公开机密。
- 自动打包
根据资源需求和其他限制自动放置容器,而且不牺牲可用性。混合使用关键工作负载和尽力而为的工作负载,以提高利用率并节省更多资源。
- 批量执行
除了服务之外,K8s 还可以管理批处理和 CI(Continuously Integration) 工作负载,并根据需要替换出现故障的容器。
- IPv4/IPv6 双网络协议栈
将 IPv4 和 IPv6 地址分配给 Pod 和服务。
- 水平压缩扩展
使用简单的命令、UI 或根据 CPU 使用情况自动压缩扩展应用程序。
- 自我恢复
重新启动失败的容器,在节点故障时替换和重新安排容器,终止不响应用户定义健康检查的容器,并且在它们准备好提供服务之前不向客户端通告它们。
- 专为可扩展性而设计
在不更改上游源代码的情况下为 K8s 集群添加功能。
2 K8s的工作原理
2.1 运行架构
k8s 集群的架构,从左到右,分为两部分:
- 第1部分: Master 节点(对应图中的 Control Plane) / 整个集群的大脑
- Master 节点,一般包括四个组件:apiserver、scheduler、controller-manager、etcd
- Apiserver
- 上知天文下知地理,上连其余组件,下接ETCD,提供各类 api 处理、鉴权,和 Node 上的 kubelet 通信等
- 只有 apiserver 会连接 ETCD。
- Controller-manager:控制各类 controller,通过控制器模式,致力于将当前状态转变为期望状态。
- Scheduler:调度,打分,分配资源。
- Etcd:整个集群的数据库,也可不部署在 Master 节点,单独搭建。
- 第2部分是 Node 节点 / 运行 Master 节点调度的应用
- Node 节点,一般也包括3个组件,docker,kube-proxy,kubelet
- Kube-proxy:主要负责网络的打通,早期利用 iptables,现在使用 ipvs技术。
- Docker:具体跑应用的载体。
- Kubelet:agent,负责管理容器的生命周期。
2.2 k8s 组件调用流程
我们看下
kubectl create deployment redis-deployment --image=redis
下发之后,k8s 集群做了什么。
-
首先 controller-manager, scheduler, kubelet 都会和 apiserver 开始进行 List-Watch 模型
- List 是拿到当前的状态,Watch 是拿到期望状态
- k8s 集群会致力于将当前状态达到达期望状态。
-
kubectl 下发命令到 apiserver,鉴权处理之后将创建信息存入 etcd,Deployment 的实现是使用 ReplicaSet 控制器,当 controller-manager 提前拿到当前的状态(pod=0),接着接收到期望状态,需要创建 ReplicaSet(pod=1),就会开始创建 Pod。
-
然后 scheduler 会进行调度,确认 Pod 被创建在哪一台 Node 上。
-
之后 Node 上的 kubelet 真正拉起一个 docker。
这些步骤中,apiserver 的作用是不言而喻的,所以说上接其余组件,下连 ETCD;但是 apiserver 是可以横向扩容的,然后通过负载均衡,倒是 ETCD 在 k8s 架构中成了瓶颈。
最开始看这架构的时候,会想着为啥 apiserver, scheduler, controller-manager 不合成一个组件?
其实在 Google Borg 中,borgmaster 就是这样的,功能也是这些功能;
但是合在了一起,最后他们也发现集群大了之后 borgmaster 会有些性能上的问题,包括 kubelet 的心跳就是很大一块;
所以, k8s 从一开始开源,设计中有三个组件也是更好维护代码吧。
2.3 核心概念
Container
- 一般地,1个container只应包含1个应用进程
因为:这样能更好的监控container的状态
可理解为k8s监控的最小粒度是container
Pod
-
在Kubernetes中,基本调度单元称为“pod”
- 通过该种抽象类别可以把更高级别的抽象内容增加到容器化组件
-
pod = 0..N 个 container
- 一个Pod可承载一个或者多个相关的容器
- 假定 Container 为 Docker Container,则:
- 1个 Pod 中可以包含多个 Docker,这些 Docker 都会被调度到同一台 Node 上
- 这些 Docker 共享 NetWork Namespace,且可声明共享同一个 Volume 来共享磁盘空间
- 这样的好处是什么呢?
- 其实在真实的世界中,很多应用是有部署在同一台机器的需求的
- 比如, Redis 日志采集插件要采集日志,肯定需要和 Redis 部署在同一台机器(Pod)上才能读到 Redis 的日志
- 假定 Container 为 Docker Container,则:
- 但一般地,1个pod中只会有1个container
- 1个pod下的container只会部署在1个物理节点
- 一个Pod可承载一个或者多个相关的容器
意味着:1个pod下不同container的交互可通过localhost进行
- 同一pod存在多个container的情况一般是:
- 1个为主container
- 其他container负责做一些辅助任务
- 如:log agent负责上报主container生产的日志
ReplicationController & ReplicaSet
- 背景
- 如果我们都人工的去解决遇到的pod重启问题,似乎又回到了以前刀耕火种的时代了是吧?
- 如果有一种工具能够来帮助我们管理Pod就好了,Pod不够了自动帮我新增一个,Pod挂了自动帮我在合适的节点上重新启动一个Pod。
- 这样是不是遇到重启问题我们都不需要手动去解决了。
- 幸运的是,Kubernetes就为我们提供了这样的资源对象:
- Replication Controller:用来部署、升级Pod
- Replica Set:下一代的Replication Controller
- Deployment:可以更加方便的管理Pod和ReplicaSet
ReplicationController
- Replication Controller简称RC,RC是Kubernetes系统中的核心概念之一
- 简单来说,RC可以保证在任意时间运行Pod的副本数量,能够保证Pod总是可用的。
- 如果实际Pod数量比指定的多,那就结束掉多余的;如果实际数量比指定的少就新启动一些Pod,当Pod失败、被删除或者挂掉后,RC都会去自动创建新的Pod来保证副本数量。
- 所以,即使只有一个Pod,我们也应该使用RC来管理我们的Pod。
- 可以说,通过ReplicationController,Kubernetes实现了集群的高可用性。
ReplicaSet
-
Replication Set简称RS.
- 随着Kubernetes的高速发展,官方已经推荐我们使用RS和Deployment来代替RC了
- 实际上RS和RC的功能基本一致,目前唯一的一个区别:
- RC只支持基于等式的selector(env=dev或environment!=qa)
- 但RS还支持基于集合的selector(version in (v1.0, v2.0))
- 这对复杂的运维管理就非常方便了。
-
kubectl命令行工具中关于RC的大部分命令同样适用于我们的RS资源对象。
- 不过我们也很少会去单独使用RS
- 它主要被Deployment这个更加高层的资源对象使用,除非用户需要自定义升级功能或根本不需要升级Pod
-
在一般情况下,我们推荐使用 Deployment 而不直接使用 Replica Set。
小结
这里总结下关于RC/RS的一些特性和作用:
- 大部分情况下,我们可以通过定义一个RC实现的Pod的创建和副本数量的控制
- RC中包含一个完整的Pod定义模块(不包含apiversion和kind)
- RC是通过label selector机制来实现对Pod副本的控制的
- 通过改变RC里面的Pod副本数量,可以实现Pod的扩缩容功能
- 通过改变RC里面的Pod模板中镜像版本,可以实现Pod的滚动升级功能(但是不支持一键回滚,需要用相同的方法去修改镜像地址)
Deployment
定义与作用
- Deployment是k8s中用来管理发布的控制器,在开发的过程中使用非常频繁
- 声明式API
- 最终一致性
- 水平触发
- 资源对象
- Deployment 可定义多副本个 Pod,从而为应用提供迁移能力
- 若单纯使用 Pod,实际上当应用被调度到某台机器之后,机器宕机应用也无法自动迁移,但是使用 Deployment,则:
- 会调用 ReplicaSet(一种控制器) 来保证当前集群中的应用副本数和指定的一致。
- Deployment 定义一组pod的期望数量,controller会维持Pod的数量和期望的一致
- 其实deployment是通过管理 ReplicaSet 的状态来间接管理pod
- 配置Pod的发布方式,controller会按照给定的策略去更新pod资源,以此来保证更新过程中可用的pod数量和不可用的pod数量都在限定范围内。(MaxUnavailable以及MaxSurge字段)
- 支持回滚操作,可记录多个前置版本(数量可通过配置设置revisionHistoryLimit)
主要字段说明
Deployment 状态迁移
Deployment 控制流程
- 同样也是通过inform对事件进行list&watch,并调用相关的handle进行处理
- 其中关于Check Paused是对有关于一些Debugger模式下可以只同步replicas而不发布版本。
- 而对应RS控制器则更加简单了,只对pod数量进行控制管理就行。
- 相对而言,deployment更加复杂一些,同时能做的事情也更多。
Labels
- 所有k8s的资源都可以被打上标
比如pod、node
-
label为kv形式,且一个资源上能打上多种标签。
-
打完标签后,可通过label selectors来筛选出打上特定label的资源。
-
【案例】
可将不同版本的pod通过label打上不同的标签: version=v1/v2/…;
然后,利用label selectors就可将version=v1的pod全部取出。
- 【案例】label还可标示node资源
举个例子:
如果某些node底层是gpu,
可将这些nodes搭上label:gpu=true,
然后,在部署需要在gpu上运行的服务时,便可通过label selectors来指定特定的pods需要部署在gpu=true的nodes上。
namespace
1个pod可能会有多个label,但只会有1个namespace。
namespace的概念可类比于【租户】,通过namespace可指定到不同的租户的命名空间。
但需注意的是,namespace仅仅是个逻辑上的分类,在你指定了某个namespace后,你只能看到对应namespace的pod,但并不作其他方面的区分。
比如,不同namespace的pod仍可以互相调用。
service
service可理解为就是psm,提供了一类服务的入口。
本质上,replicaSets等负责管理pod,而service负责pod与内外部服务的交互。
在service定义时需要定义port和targetport,port代表service正在监听的端口,收到请求后,service会将请求转发到对应pod的targetport上。
3 实践应用
3.1 ReplicationController & ReplicaSet & Deployment
3.1.1 ReplicationController
- 【案例】
Step0 开始演示
# 启动k8s
minikube start
# 删除上次的pod
kubectl delete -f pod_nginx.yml
Step1 查看rc_nginx.yml
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 3
selector:
app: nginx
template:
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
上面的YAML文件:
- kind:ReplicationController
- spec.replicas: 指定Pod副本数量,默认为1
- spec.selector: RC通过该属性来筛选要控制的Pod
- spec.template: 这里就是我们之前的Pod的定义的模块,但是不需要apiVersion和kind了
- spec.template.metadata.labels: 注意这里的Pod的labels要和spec.selector相同,这样RC就可以来控制当前这个Pod了。
# 创建1个ReplicationController的横向扩展
kubectl create -f rc_nginx.yml
kubectl get pods
kubectl get rc
Step2 删除一个看看效果如何
通过delete pods 的方式删除一个容器,立刻就有一个新的容器起来
kubectl get rc
kubectl get pod
kubectl delete pods nginx-h2qbt
kubectl get pods
kubectl get rc
Step3 scale 水平扩展的数量
kubectl scale rc nginx --replicas=2
kubectl get rc
kubectl scale rc nginx --replicas=5
kubectl get pods -o wide
3.1.2 ReplicaSet
- 查看rc_nginx.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx
labels:
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
name: nginx
labels:
tier: frontend
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
#删除ReplicationController创建的pod
kubectl delete -f rc_nginx.yml
#创建一个ReplicationController的横向扩展
kubectl create -f rs_nginx.yml
kubectl get pods -o wide
kubectl get pods
kubectl get rc
- 删除一个看看效果如何
通过delete pods 的方式删除一个容器,立刻就有一个新的容器起来
kubectl get rs
kubectl get pod
kubectl delete pods nginx-h2qbt
kubectl get pods
kubectl get rs
- scale 水平扩展的数量
kubectl scale rs nginx --replicas=2
kubectl get rs
kubectl scale rs nginx --replicas=5
kubectl get pods -o wide
通过这次了解了pod的扩展,ReplicaSet和ReplicationController的方式,基本上可以抛弃上次的直接pod的方式创建app了。下次说说Deployment。
Y 推荐资源
- Kubernetes
- CNCF (Cloud Native Computing Fundation) : CNCF projects are the foundation of cloud native computing
- 《深入剖析Kubernetes》张磊,CNCF TOC 成员,at 阿里巴巴
- 《Kubernetes 权威指南》第五版
- 《Large-scale cluster management at Google with Borg》
X 参考文献
本文链接: https://www.cnblogs.com/johnnyzen
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!