文章目录
K8S深度解读:架构、组件、资源对象
一、k8s概述
1.2版本后摒弃使用docker
1.1、官网:github地址:https://github.com/kubernetes/kubernetes
1.2、k8s英文官方站点:https://kubernetes.io
1.3、k8s中文官方站点:https://kubernetes.io/zh/
1.4、k8s使用文档网址:https://kubernetes.io/docs/
1.5、k8s是什么
kubernetes是可移植、可扩展、开源的容器管理平台。简称k8s
可移植
在k8s中部署的应用都是基于镜像的,
镜像都是可移植的,可被多个环境使用,
可以从一个环境迁移到另一个环境,不受操作系统限制
可扩展
安装k8s物理节点可以根据业务规模动态扩容缩容,
k8s中的pod应用也可以实现自动扩容缩容
1.6、kubernetes提供了应用程序的快速部署,升级和回滚(可以按照指定版本回滚)的能力,
利用service可以实现服务注册,发现;通过kube-proxy(它是负责把service的ip传入到iptables)可以实现负载均衡,通过cordns可实现域名解析,通过ingress可以实现七层负载均衡.
DNS解析:bind做域名解析/K8S自带cordns做域名解析
二、kubernetes起源
kubernetes单词起源于希腊语,是"舵手"或"领航员、飞行员"的意思,来源于google的borg项目
2.1、borg
borg是谷歌内部的一个容器编排工具,谷歌业务90%以上都在borg上运行,borg在谷歌内部已使用大概15年,k8s是在borg的基础上开发出来的轻量级容器编排工具,k8s的根基非常牢固,是站在巨人的肩膀上发展起来的项目,开源之后,迅速称霸容器编排技术领域。
2.2、k8s版本迭代
2015.7k8s
2018.3月k8S发布1.10版本
2020.12.8月k8s1.20正式发布,宣布不再支持docker
2.3、k8s业界地位
京东:
2016年底,京东业务开始从Openstack切换到k8s,第一阶段迁移20%的业务到k8s,集群规模500+物理节点,2w+Pod容器
2020年,已经把90%业务迁移到k8s里
阿里巴巴:
管理数万个k8s集群,其中最大的集群约1万个物理节点,每个集群会运行几十万个pod应用
3、k8s架构(重点)
1、分为单节点和高可用架构
2、k8s物理架构是master/node(别称:控制节点/工作节点)(控制平面/工作节点)模式
3、k8s集群至少需要一个主节点(master)和多个工作节点(worker),主节点是集群的控制节点,负责整个集群的管理和控制,主节点主要用于暴露API,调度部署和节点的管理,工作节点主要是运行容器,部署pod
三、单master节点架构----适用于测试,或者用于非核心项目、开发、测试人员
其中在internet下还有CODNS域名解析,网络插件:
calico 已经不怎用flannel 。
因为calico功能强,既可以分配IP,又可以做网络策略
二进制守护进程K8S组件:
1、kubetcl:可以yum install安装 -----客户端命令行工具 增删改查命令 加载文件:config 不仅可以安装再控制节点,工作节点,其他机器上。习惯上安装再控制节点上
2、etcd:raft算法,强一致性和快照、高可用、键值对的数据库,保存K8S的资源状态信息、网络插件信息(flannel 、calico)
3、api server(核心组件):所有服务都指向apiserver,整个集群对外唯一的出口,整个系统的数据中心,所有东西都需要和它交互
4、scheduler 调度器,可做二次开发。根据调度策略经过筛选符合要求节点,选出最优,整个调度流程分为两个阶段:预选策略(Predicates)和优选策略(Priorities)。(预选和优选函数策略根据节点资源,CPU资源,性能,选择最优调度pod)
4.1、预选(Predicates):**输入是所有节点,输出是满足预选条件的节点。kube-scheduler根据预选策略过滤掉不满足策略的Nodes。例如,如果某节点的资源不足或者不满足预选策略的条件如“Node的label必须与Pod的Selector一致”时则无法通过预选。
4.2、优选(Priorities):**输入是预选阶段筛选出的节点,优选会根据优先策略为通过预选的Nodes进行打分排名,选择得分最高的Node。例如,资源越富裕、负载越小的Node可能具有越高的排名。
5、controller-manager控制器/管理器(replication伸缩副本数量、namespace、serviceacounts、endpoint管理网络请求.....):重点是:pod副本数/node节点/命名空间/服务端点/服务账号/资源配额/serviceacounts. 创建pod,由控制器创建,如果pod有问题,控制器将pod删除,再创建新的pod.**
6、kubelete 工作节点上kubelete,除了启动pod,还会定期调用apiserver 上报节点状态信息,API将信息保存到etc,kubelete 可通过apiserver watch监听创建pod信息,启动pod**
组件是可以运行的,资源是pod 安装好K8S后可以安装service生成IP 是vip,存在iptables/IPVS里,通过kube-proxy**
7、kube-proxy:提供负载均衡和代理,可以为service生成IPTABLES规则,实现service---pod的转发,service通过kube-proxy找到pod**
kubead安装
1、运行时全部都封装到pod当中,启动POD运行,依靠kubelet组件。
2、kubelet----创建pod,启动pod ,删除pod
3、calico控制节点也需要安装
组件
kubectl:管理 k8s 的命令行工具,可以操作 k8s 中的资源对象。
etcd: 是一个高可用的键值数据库,存储 k8s 的资源状态信息和网络信息的,etcd 中的数据变更
是通过 api server 进行的。
apiserver: 提供 k8s api,是整个系统的对外接口,提供资源操作的唯一入口,供客户端和其它组
件调用,提供了 k8s 各类资源对象(pod,deployment,Service 等)的增删改查,是整个系统的数据总
线和数据中心,并提供认证、授权、访问控制、API 注册和发现等机制,并将操作对象持久化到 etcd
中。相当于“营业厅”。
scheduler:负责 k8s 集群中 pod 的调度的 , scheduler 通过与 apiserver 交互监听到创建 Pod
副本的信息后,它会检索所有符合该 Pod 要求的工作节点列表,开始执行 Pod 调度逻辑。调度成功后将Pod 绑定到目标节点上,相当于“调度室”。
controller-manager:作为集群内部的管理控制中心,负责集群内的 Node、Pod 副本、服务端点
(Endpoint)、命名空间(Namespace)、服务账号(ServiceAccount)、资源定额
(ResourceQuota)的管理,当某个 Node 意外宕机时,Controller Manager 会及时发现并执行自动
化修复流程,确保集群始终处于预期的工作状态。
kubelet: 每个 Node 节点上的 kubelet 定期就会调用 API Server 的 REST 接口报告自身状态,
API Server 接收这些信息后,将节点状态信息更新到 etcd 中。kubelet 也通过 API Server 监听 Pod
信息,从而对 Node 机器上的 POD 进行管理:如创建、删除、更新 Pod
kube-proxy:提供网络代理和负载均衡,是实现 service 的通信与负载均衡机制的重要组件,
kube-proxy 负责为 Pod 创建代理服务,从 apiserver 获取所有 service 信息,并根据 service 信息创
建代理服务,实现 service 到 Pod 的请求路由和转发,从而实现 K8s 层级的虚拟转发网络,将到
service 的请求转发到后端的 pod 上。
Calico:Calico 是一个纯三层的网络插件,calico 的 bgp 模式类似于 flannel 的 host-gw,calico
在 kubernetes 中可提供网络功能和网络策略 flannel没有网络策略
Cordns:k8s1.11 之前使用的是 kube dns,1.11 之后才有 coredns,coredns 是一个 DNS 服务
器,能够为 Kubernetes services 提供 DNS 记录
DNS是域名解析成IP
Docker:是一个容器引擎,用于运行容器
附加组件:
Web UI(Dashboard):Dashboard 是 k8s 集群的一个 web ui 界面,通过这个界面可以对 k8s
资源进行操作,如创建 pod,创建存储,创建网络等,也可以监控 pod 和节点资源使用情况。
prometheus+alertmanager+Grafana:监控系统,可以对 kubernetes 集群本身的组件监控,
也可对物理节点,容器做监控,对监控到的超过报警阀值的数据进行报警,这个报警会发送到指定的目
标,如钉钉,微信,qq,slack 等。
efk-(全称 elasticsearch、fluentd、kibana):日志管理系统,可以对物理节点和容器的日志进行
统一收集,把收集到的数据在 kibana 界面展示,kibana 提供按指定条件搜索和过滤日志。
Metrics:用于收集资源指标,hpa 需要基于 metrics 实现自动扩缩容
四、多master节点架构-------生产环境
1、keepalive(心跳检测)主要做以VRRP协议做基础负载均衡 :保证集群高可用的一个服务软件,其功能类似于heartbeat,用来防止单点故障。提供VIP,做到VIP漂移
2、nginx 主要做反向代理 做upsteam反向代理池
3、两者达到高可用----主要是对apiserver做高可用
4、通过虚拟IP(VIP)保护内部的真实IP,VIP均匀的将请求分发给apiserver,达到分担高并发
4、k8s容器编排工具的优势
1、灵活部署
k8s支持在多种平台部署,可在私有云、公有云、混合云,openstack(不建议)、openshift、VMware vSphere,VMware Workstation,虚拟机,物理机(主流)等环境部署
2、安全高效,拥有完善的认证授权机制,自带审计功能
可以对多用户做细化的授权管理(如rbac授权),达到相互之间的操作完全隔离,互不影响,而且自身带有审计功能,可以对操作过程进行实时的日志记录,出现问题可以方便排查
rbac:基于角色的访问控制
在RBAC中,用户不再直接与权限相连,而是通过“角色”这一属性来间接的被赋予权限,用户通过成为适当的角色来的到这些角色固有的权限,这样处理就解耦了用户与权限的关系。这就极大地简化了权限的管理。在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色。角色可依新的需求和系统的合并而赋予新的权限,而权限也可根据需要而从某角色中回收。角色与角色的关系可以建立起来以囊括更广泛的客观情况。
3、负载均衡
支持四层IP和端口、七层域名、http、https负载均衡,可用于多种场景
4、可扩展性强
拥有强大的集群扩展能力,可以根据业务规模自动增加和缩减主机节点的数量,确保服务可以承受大量并发带来的压力,保证业务稳定运行
5、根据节点资源的使用情况对pod进行合理的调度
可以按照用户需要调度pod,例如保证pod只在资源足够的节点上运行,会尝试把同一个功能的Pod分散到不同的节点上,还会尝试平衡不同节点的资源使用率等
6、拥有完善的灾备预警方案
拥有多种灾备解决方案,支持备份和容灾,出现故障可以达到秒级切换,保证线上业务不受影响
5、k8s功能详解
1、多租户网络隔离
k8s支持多种网络插件,如flannel,calico,cannel(flannel和calico的结合,用的少)等,每个插件都有独特的性能,可以分别适用多种场景,我们可以利用calico的network policy网络策略,解决k8s中的网络隔离,对于多租户场景,可以每一个用户一个名称空间namespace,然后对这个名称空间设置网络隔离
2、高可用、高扩展性
k8s中支持多种高可用解决方案,如:keepalive+nginx,keepalive+haproxy等。可以使访问流量分发到不同的主机节点,减轻节点压力,如果某个节点出现故障,可以实现秒级切换,达到高可用,保证业务不中断
3、用户数据的持久化存储
k8s支持多种持久化存储的方案,保证数据可以得到很好的备份,降低用户数据丢失的风险,k8s中可使用的存储方案如下
本地存储:emptyDir,hostPath
网络连接类存储:
SAN 存储局域网络:ISCSI
NAS 网络附加存储:nfs cifs
分布式存储:gluterfs,ceph-块级别的存储,cephfs-文件系统级别的存储
云存储:Azure Disk等
4、拥有多种更新回滚策略
通过管理K8S的控制器和service等,可以实现灰度发布,蓝绿发布,金丝雀发布等,达到业务的快速部署和回滚等操作,用以满足不同客户的不同升级需求
istio+k8s==可以做流量置顶,控制流量策略,----超时重试、故障注入、降级、熔断
5、弹性伸缩
根据访问的流量压力,可以实现pod的水平扩容和缩减,达到秒级扩容,让pod始终处于满足业务正常时所需的数量即可,避免了资源的浪费
6、节省资源,优化硬件资源的使用
根据流量进行业务组件的扩缩容,可节省机器的资源
6、k8s企业实战应用场景分析
1、日志收集
之前使用elk:elastic logstask(插件多,灵活) kibana,
现在用efk:elastic filebeat(收集日志)交给logstask/fluentd然后交给es,kibana,可以加kafuka缓冲
如果ES数据量大的话,k8s可以实现集群中pod应用的水平扩展,完成应用的弹性扩容和收缩等操作,调整一下副本数
2、k8s在devops场景下使用
devops是运维开发流程,可以实现快速的构建、测试和发布软件,整个流程包括敏捷开发---->持续集成----->持续交付----->持续部署---->DEVOPS,通过K8S,我们可以实现容器在多个计算节点上的统一调度,可以将容器对接到持久存储,虚拟网络,还可以实现弹性伸缩,提高了产品的迭代速度
3、k8s在监控中的应用
常用的监控系统:nagios网络监视、zabbix物理节点监控、监控硬件、catti监控网卡流量、prometheus监控容器和k8s,提供服务发现,支持export,绑定mysql,redis tomcat等,直接根据export直接用
7、容器部署和传统部署对比分析
传统部署:物理机-----操作系统centos/ubantu/------二进制
虚拟化:底层硬件-----操作系统-------虚拟机/KVM/openstack/------》每个虚拟机-----》操作系统------》装二进制
容器部署:底层硬件----->操作系统-----》K8S------》POD里跑容器
8、k8s中的资源对象
1、最小调度单元Pod
pod是k8s中最小的最小调度单元,当指派容器时,容器实际上并不会指派到物理硬件上,容器会被分配到一个pod里,一个pod封装容器(也可以封装多个容器),pod里的容器共享存储、网络等,也就是说,应该把整个pod看作一个虚拟机,然后每个容器相当于运行在虚拟机里的进程,所有容器都被统一安排和调度,并运行在共享的下文中,对于具体应用而言,pod是它们的逻辑主机,pod包含业务相关的多个应用容器
2、如何通过K8S创建一个Pod资源?
编写一个资源清单文件
cat pod.yaml
apiVersion:v1
Kind:Pod
metadata:
name:tomcat-pod
namespace:Default
labels:
tomcat:tomcat-pod
spec:
containers:
-name:tomcat-pod-java
ports:
-containerport:8080
image:tomcat:8.5-jre8-alpine
imagePullpolicy:IfNotPresent
更新资源清单文件
kubectl apply -f pod.yaml
查看创建的资源
kubectl get pods| grep tomcat
3、资源对象标签label
label是标签的意思,k8s中的资源对象大都可以打上标签,如Node、pod、Service等,一个资源可以绑定任意多个label,k8s通过label可实现多维度的资源分组管理,后续可以通过label selector查询和筛选拥有某些label的资源对象,例如创建一个pod,给定一个label是app=tomcat.那么service可以通过label selector选择拥有app=tomcat的pod,和其相关联,也可通过app=tomcat删除拥有该标签的pod资源
label selector
4、控制器Deployment
1、Replicaset:低配版的Deployment
k8s中的副本控制器,管理POD,使pod副本的数量始终维持在预设的个数
2、Deployment
deployment管理replicaset和pod的副本控制器,deployment可以管理多个replicaset是比replicaset更高级的控制器,也就是说在创建deployment的时候,会自动创建replicaset,由replicaset再创建pod,deployment能对pod扩容、缩容、滚动更新和回滚,维持pod数量
3、如何创建一个 Deployment 资源?
cat deployment.yaml
apiVersion: apps/v1
kind: Deployment //类型是deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template: //字段
metadata:
labels://标签
run: my-nginx
spec:
containers: //自动创建容器
- name: my-nginx //容器名称是my-nginx
image: nginx
ports:
- containerPort: 80
#更新资源清单文件
kubectl apply –f deployment.yaml
#查看创建的 Deployment 资源
[root@master1 ~]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
my-nginx 2/2 2 2 36d
#查看创建的 Replicaset 资源
[root@master1 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
my-nginx-5b56ccd65f 2 2 2 36d
#查看创建的 Pod 资源
NAME READY STATUS RESTARTS AGE
my-nginx-5b56ccd65f-d67nn 1/1 Running 0 9m21s
my-nginx-5b56ccd65f-m5cq7 1/1 Running 0 9m21s
4、控制器statefulset
deployment控制器是用来管理无状态应用的:管理的所有Pod一模一样,提供同一个服务,也不考虑在哪台NODE运行,可随意扩容和缩容,这种应用称为"无状态".例如WEB服务,deployment部署的pod数据卷是共享的,创建3个pod都是用的同一个数据卷,对外提供统一服务
在实际的场景中,尤其是分布式应用,会部署多个实例,这些实例之间往往都有依赖关系,例如主从关系,主备关系,这种应用称为"有状态",例如MYSQL主从,ETCD集群
statefulset
statefulset控制器用于部署有状态应用,满足一些有状态场景的:
1、statefulset管控的每个pod对象都有固定的主机名和专有存储卷,即便被重构后亦能保持不变
2、pod有序的部署、扩容、删除和停止
3、pod分配一个稳定的且唯一的网络标识
4、pod分配一个独享的存储
5、控制器Daemonset
daemonset
Daemonset确保(每一个k8s节点运行一模一样的pod)全部(或者一些)Node上运行一个pod的副本,当有node加入(工作节点)集群时,也会给他们新增一个pod,当有node从集群内移除时,这些pod也会被回收,删除daemonset将会删除它创建的所有pod
使用daemonset的一些典型用法:
1、运行集群存储daemon,例如在每个Node上运行glusterd,ceph
2、日志收集,比如fluentd.logstash等
3、系统监控,比如prometheus Node Exporter,collectd,New Relic agent,Gangliagmond等
4、系统程序,比如Kube-proxy,kube-dns,glusterd,ceph等
6、控制器Job&&CroJob
Job 类似于计划任务
job负责批量处理任务:Job创建一个或者多个pod,并确保指定数量的pod成功终止,pod成功完成后,job将追踪成功完成的情况,当达到指定的成功完成次数时,任务(即job)就完成了,删除job将清除其创建的pod.简单的情况是创建一个job对象,以便可靠的运行一个pod来完成,如果第一个pod发生故障或被删除(例如,由于节点硬件故障或节点重启),则job对象将启动一个新的pod
CronJob 例如给MySQL做数据备份
cronjob:一个cronjob对象就像crontab文件中的一行,它用Cron格式进行编写,并周期性的给定调度时间执行job,在每次调度运行时间内大概会创建一个job对象,我们之所以说大概,因为在特定环境下可能会创建两个job,或者一个job都没创建
7、四层代理service 通过ip和端口访问
在k8s中,pod是有生命周期的,pod重启IP就会发生变化,
如果我们的服务都是将pod的IP地址写死,pod的挂掉或者重启,
和刚才重启的POD相关联的其他服务将会找不到他所关联的Pod,
为了解决这个问题,在K8S中定义了service资源对象,
service定义了一个服务访问的入口,
客户端通过这个入口即可访问服务背后的应用集群实例,service是一组pod的逻辑集合,
这一组pod能够被service访问到,通常是是通过Label selector实现的
8、(更多使用)ingress Controller 七层代理
ingress Controller配置好后,
写ingress规则------接收请求----找到关联的后端-----service----pod关联-----请求转发到pod
ingress可以把进入到集群内部的请求转发到集群中的一些服务上,从而可以把服务映射到集群外部,ingress能把集群内service配置成外网能够访问的URL,流量负载均衡,通过基于域名访问的虚拟主机等
ingress Controller可以理解成控制器,它通过不断的和k8s API交互,实时获取后端service,pod变化,比如新增、删除....
结合ingress定义的规则生成配置,然后动态更新上边的NGINX或者trafik负载均衡,并刷新使配置生效,来达到服务自动发现的作用,
定义了service资源对象,service定义了一个服务访问的入口,
客户端通过这个入口即可访问服务背后的应用集群实例,service是一组pod的逻辑集合,
这一组pod能够被service访问到,通常是是通过Label selector实现的