K8S知识点结构
2024-05-06 14:56:37 0 举报
AI智能生成
登录查看完整内容
K8S知识点结构梳理
作者其他创作
大纲/内容
为一组具有相同功能的容器应用提供一个统一的入口地址,并将请求负载分发到后端各个容器应用中,提供负载均衡
Service工作TCP/IP层上,IP+Port的访问方式
概念
通过label标签关联一组pod
服务发现
使用iptables或ipvs为一组pod提供负载均衡
负载均衡
功能
无头服务,无需Cluster-IP,直接绑定具体Pod的IP,无头服务常用于StatefulSet有状态应用的部署
Headless Service
ClusterIP:集群内部pod的访问,默认
NodePort:暴露公网,集群外访问,使用宿主机本机的IP+端口
LoadBalancer:对外访问,用于公有云环境,公有云环境的负载均衡器进行服务的负载分发。需在 spec.status.loadBalancer 字段配置负载均衡器的IP地址
类型
service默认的转发规则
kube-proxy设置Linux内核的iptables规则,实现service转发到后端的endpoint列表进行负载分发规则,效率高
该模式适合中小型的K8S集群使用,因大规模的K8S集群中,集群节点、Pod数量多, 会频繁的同步iptables规则(如同步Pod IP变化情况),给Linux 内核造成巨大开销
iptables
kube-proxy设置Linux内核接口设置的ipvs规则,转发效率和支持的吞吐量高
启用ipvs模式:需Linux内核启用ipvs模块,如操作系统未启用ipvs内核模块,kube-proxy会自动切换iptables模式
该模式适合大规模的K8S集群,大大减少iptables模式中同步iptables规则的开销,提升K8S集群扩展
rr 简单轮询
lc 最少连接数
sh 源地址哈希
dh 目的地址哈希
几种负载调度算法
ipvs
优点:匹配规则灵活,功能强大
缺点:匹配规则多,一个pod会有多个匹配规则。规则一遍历或更新,呈线性时延,很影响性能
集成在linux内核中,工作在内核中,性能优。不像iptables工作在用户态上
支持的调度算法多:rr 、wrr、lc、wlc、ip hash 等
建议生产环境service网络模式修改为ipvs
iptables 与 ipvs 比较
负载均衡机制
环境变量方式(不推荐)
部署CoreDNS
会生成servicename.namespace.svc.cluster.local的域名,解析到service对应的clusterIP上
pod间的调用可简写:servicename.namespace
同一namespace下,pod访问甚至可简写成 servicename
普通Service
clusterIP设置为none,会被解析成指定pod的IP
通过 podname.servicename.namespace.svc.cluster.local 域名访问pod
k8s会为其设置一个 pod-ip.namespace.pod.cluster.local的域名
普通pod
k8s为pod都以IP地址+controller名称起一个DNS域名
deployment格式dns域名:pod-ip.deployment_name.namespace.svc.cluster.local
daemonset格式dns域名:pod-ip.daemonset_name.namespace.svc.cluster.local
deployment、daemonset类型的pod
Pod格式dns域名:pod-ip.namespace.pod.cluster.local
验证:进入Pod里,nslookup下
Pod类型的pod
pod的DNS域名
pod.spec.dnsPolicy 设置
配置DNS策略
Default:继承Pod所在Node主机的DNS
ClusterFirst(默认DNS策略):优先K8S集群环境配置的DNS服务(CoreDNS),如果该环境中无法解析域名则转发到Node主机继承DNS服务
ClusterFirstWithHostNet:HostNetWork网络模式下Pod使用的DNS策略
dnsConfig配置自定义DNS:
Pod被创建后,容器内的 /etc/resolv.conf 会根据这个信息进行配置
None:忽略K8S环境的DNS配置,自定义DNS配置,通过 spec.dnsConfig字段指定DNS配置信息
4种策略
pod的DNS策略
DNS域名相关特性
K8S集群默认DNS服务,以Pod方式运行在K8S集群中。CoreDNS服务监视Kubernetes API,为每一个Service创建DNS记录用于域名解析
CoreDNS服务默认在kube-system namespace下
CoreDNS
CoreDNS工作流程图:
nslookup方式:
验证CoreDNS解析
service DNS解析
DNS方式
服务发现机制
service网络原理图:
node节点的Kubelet启动Pod实例,由Kubelet将Pod IP列表信息注册到Mater节点上
服务注册
service为服务分配相应Cluster IP,并也注册在Master节点,记录Cluster IP 和 Pod IP的映射关系。Kube-proxy会监听Master节点Cluster IP 和 Pod IP的映射关系,并修改本地Linux iptables的转发规则 - 接收到目标为Cluster IP 时进行负载均衡,转发到目标Pod IP
service网络原理(基于DNS + Service Registry)
深入Service
configmap
secret
ServiceAccount Token
K8S中的资源对象映射存储卷
emptyDir 临时存储
hostPath 宿主机本地存储
K8S管理的宿主机本地存储类型
PVC申请
CephFS网络共享存储
NFS网络共享存储
GlusterFS网络共享存储
CSI容器存储接口(存储供应商提供存储服务)
...
持久化存储PV和网络共享存储类型
Volume类型
与Pod同生命周期
随Pod的删除而销毁空卷
挂载node节点目录或文件到Pod中。同Docker创建的容器通过 -v 挂载宿主机目录到容器中一样
hostPath存储方式是node节点一直存在情况,或Pod一直被调度到该node节点的话,可实现Pod存储。如果该node节点停机,存储在该节点的数据无法访问。
存储不会因Pod删除而自动删除,需手动delete
Cephfs存储
Glusterfs存储
OpenEBS存储
node节点本地存储
PV(PersistenVolume)持久化卷,资源存储的抽象,存储定义为一种容器应用可使用的资源
PV由管理员创建、配置,是静态供给方式(Static Provisioning)
PV独立于使用它的Pod,不因Pod的删除而销毁,EmptyDir类型存储除外
PV
PVC是对存储资源的一个是申请,PVC消耗PV资源
PVC可申请存储的大小、访问模式
PVC
资源存储抽象的定义,用户PVC申请无需关心后端存储细节,只管PVC申请,无需关心PV的创建和绑定,实现动态资源供给
动态供给(Dynamic Provisioning)的关键就是StorageClass,由它来实现,作用就是创建PV模板
StorageClass
是K8S集群和外部存储系统间建立一套标准的存储管理api接口,具体存储驱动和程序由存储供应商提供,通过标准的接口为容器提供存储服务
类似CRI、CNI,目的是将K8S的代码与存储相关代码进行解耦
CSI
持久化的PV、PVC、SC
1)、资源供给:创建PV、PVC
2)、资源绑定:PVC绑定到PV
3)、资源使用:Pod使用PVC
4)、资源回收:删除PVC,回收PV资源
PV、PVC生命周期
手动创建PV
静态供给(Static Provisioning)
通过StorageClass设置对后端存储的描述,包括存储类型、大小等特征
用户创建PVC对存储类型申请,系统自动完成PV的创建及与PVC的绑定
动态供给(Dynamic Provisioning)
资源供给
静态供给绑定:PV和PVC一对一的绑定,PV被PVC绑定上就独占该PV
动态供给绑定:根据配置的Provisioner,系统自动为PVC找到合适的StorageClass,自动创建PV并完成该PVC的绑定
资源绑定
Pod使用资源,在Volume的定义中引用PVC类型和存储卷,PVC挂载到容器的目录使用
# 存储对象保护机制说明1)、存储对象(PV、PVC)相对于Pod是独立的管理资源,可单独删除操作2)、删除资源时,系统会检查当前存储资源是否正在被使用,如果被使用,相关存储资源对象会推迟删除操作,直到存储资源没有被使用才执行删除操作
资源使用
# 资源回收说明1)、使用完存储资源后,可以删除PVC。与该PVC绑定的PV会标记为“已释放(Released)”。此时Released状态的PV还不能立刻与其他的PVC绑定2)、因之前绑定的PVC写入的数据可能还在该PV上,只能删除PV的数据后,该PV才能再次使用
1)、删除PVC后,之前绑定的PV不会被删除,只是PV状态标记为Released2)、PV的数据还保留,不能被其他PVC绑定使用,需清理PV数据后才可继续使用
# PV清理数据步骤1)、删除PV对象2)、清理PV存储的数据3)、再次创建一个PV对象
Retain(数据保留)
清除PVC后,自动删除PV资源对象和后端存储数据
动态供给创建的PV,默认PV回收策略是Delete
Delete(数据删除)
Recycle(清除PV数据已弃用)
PV资源回收策略
资源回收
PV、PVC生命周期详解
# 设置存储空间capacity: storage: 10Gi
存储容量
# 设置访问模型accessModes: - ReadWriteMany - ReadWriteOnce - ReadOnlyMany
ReadWriteMany:读写权限,可被多个node挂载
ReadWriteOnce:读写权限,只能一个node挂载
ReadOnlyMany:只读权限,可被多个node挂载
访问模式
PV可设置节点亲和性nodeAffinity来限制只能某个node节点访问Volume,PV定义中使用nodeAffinity字段设置
公有云提供的存储卷Volume自动完成节点亲和性设置,无需手动设置
节点亲和性nodeAffinity
Available(可用):空闲资源未与其他PVC绑定
Bound(已绑定):卷已经被声明绑定
Released(已释放):与绑定的PVC已被删除,但资源还未被回收,不能被其他PVC绑定
Failed(失败):该卷的自动回收失败
PV几种状态
PV详解
PVC(PersistenVolumeClaim)持久化卷申明
PVC是PV存储的一种申明,绑定PV
PVC和Pod类似,Pod消耗的是节点,PVC消耗的是PV资源,Pod可以请求CPU、内存资源,PVC可以请求特定的存储空间和访问模式。对于真正使用存储的用户而言,不关心底层的存储实现细节,只需直接使用PVC即可
PVC依赖K8S某个namespace
PVC详解
1)、PV属性,如存储类型、Volume大小等
2)、创建PV需使用的存储插件,如Ceph、aws、Glusterfs等
以上2部分信息确定好之后,最终效果是K8S根据用户提交的PVC,包含存储类型、大小等,找到符合定义的StorageClass,K8S会调用该StorageClass声明的存储插件,会为其自动创建PV并进行绑定
创建StorageClass对象会定义2部分内容
name:名称
parameters:后端存储资源提供者的参数设置
StorageClass示例:
存储资源PV的提供厂家,即后端存储驱动
K8S内置的Provisioner都以“kubernetes.io”开头,用户也可自定义后端存储提供者。
provisioner存储提供者
type有n多种
parameters存储参数
Delete(默认)
Retain
reclaimPolicy资源回收策略
true时,允许用户通过编辑PVC存储空间自动完成PV扩容注:只支持扩容,不支持缩容
allowVolumeExpansion是否允许扩容
系统为动态创建的PV设置挂载选项
mountOptions挂载选项
一个PVC创建后,动态创建的PV立即该PVC绑定
Immediate立即绑定(默认)
当Pod使用PV时,PVC才绑定该PV
WaitForFirstCustomer延时绑定
volumeBindingMode存储绑定模式
StorageClass主要参数
provisioner: ceph.rook.io/block
Ceph
provisioner: kubernetes.io/aws-ebs
AWS EBS卷
provisioner: kubernetes.io/glusterfs
Glusterfs
provisioner: kubernetes.io/gce-pd
GCE(Kubernetes内置的GCE PD存储插件)
https://kubernetes.io/docs/concepts/storage/storage-classes/
K8S支持动态供给Dynamic Provisioning的存储插件:
常见后端存储提供者provisioner厂家
StorageClass详解
PV、PVC、SC存储详解
PV、PVC、SC工作原理
存储原理
K8S存储
Linux网络协议栈引入网络命名空间,处于不同命名空间的网络栈完全是隔离的,无法进行网络通信
网络空间的隔离,能在同一宿主机上虚拟出多个不同的网络环境
Docker利用网络名称空间的特性,实现不同容器的网络隔离
网络命名空间概念
为支持独立的协议栈,相关全局变量必须修改为协议栈私有。让这些全局变量变成一个net namespace的变量的成员,为协议栈的函数调用加一个namespace参数。这是Linux实现网络命名空间的核心
网络命名空间实现
网络命名空间
引入veth设备对就是为了实现不同的网络命名空间之间的通信,veth设备对将2个网络命名空间连接起来
veth设备对
网桥是一个虚拟的2层网络,将若干个网络接口“连接”起来,使得不同网络接口间的报文能互相转发
网桥解析收发的报文,读取目标的Mac地址信息,与自己记录的Mac地址表结合,来决策、路由转发哪个目标网络接口
网桥概念
Linux内核通过一个虚拟网络设备(Net Device)实现网络桥接的
网桥会绑定多个以太网的网络接口,将这些网络接口桥接起来
网桥在数据链路层实现,上层无需关心桥接细节,协议栈上层只需将报文发送到网桥br0即可
Linux网桥实现
网桥bridge
--net=host 指定
Host仅主机模式
--net=container:name 指定
Container模式
--net=node 指定
node模式
--net=bridge 指定,为Docker默认设置,K8S通常情况也使用该模式
bridge模式下,Docker daemon在首次启动会自动创建一个虚拟网桥,默认名称为docker0,会分配一个子网
由docker创建的每一个容器,都会创建一个虚拟以太网设备-veth设备对,一端在网桥上,另一端在容器内的eth0设备上,在网桥地址段内给这个eth0接口分配一个IP地址
bridge桥接模式(最常用)
Docker网络实现
Linux系统包含一个完整的路由功能,当Ip层在处理数据发送或转发的时候,会使用路由表来决定发往的目的地
路由
Docker网络基础
每个Pod都有一个独立的IP地址,所有Pod在一个扁平化的网络中,能互相连接通信
不管Pod落哪个node节点,都可连接通信
Pod的IP和所在node节点的IP关联起来
K8S网络模式设计基础原则
每个Pod一个IP地址
IP-per-Pod模型
所有Pod间通信不在Nat模式下直接通信
K8S网络模型
# K8S网络中解决几个不同的网络问题1)、容器到容器网络2)、Pod到Pod网络3)、Pod到Service网络4)、Service到互联网网络
K8S四层网络模型:
同一个Pod的容器处在同一网络命名空间,共享Linux协议栈,
Pod中的容器共享一个IP,通过localhost访问彼此
容器到容器网络
不同Pod都通过veth设备对连接docker0网桥
不同的Pod默认路由都是docker0地址,Pod在非本地网络空间通信都通过docker0网关路由出去
Pod都关联在docker0网桥上,同一地址段,Pod间能直接通信
同node节点下Pod间的通信
整个K8S集群对Pod的IP分配进行规划,不能有IP冲突。需node节点对docker0的IP地址规划,保证每个node节点docker0地址不冲突
需将Pod的IP和所在node节点的IP关联起来
需要满足2个条件
# 前提1)、底层网络时可控的,比如企业内部机房网络,网络设备自己能控制2)、无额外的性能开销
一类是路由方案
# 前提底层网络无法控制,如公有云网络
是在现有网络之上再建立一个虚拟网络,覆盖在已有宿主机网络之上
实现技术如 flannel、calico、weave等,都是采用隧道封装技术实现,会有额外的性能开销,包的封装、解封装的开销
Overlay网络是在underlay网络之上构建出的一个虚拟逻辑网络,属叠加网络
Overlay 网络方案
另一类是覆盖(Overlay)网络方案-隧道封装技术
技术方案实现
不同node节点下Pod间的通信
Pod到Pod网络
K8S中Pod的IP不是固定的,会随着应用的扩容、缩容、节点重启等操作导致Pod的IP变化。K8S通过Service对象来解决
Service管理一组Pod,Service为一组Pod分配一个虚拟的VIP地址,客户端流量通过VIP关联到对应的Pod
创建Service时,会创建一个新的虚拟IP(也称之 ClusterIP),K8S集群中任何地方,发往虚拟IP的流量都将负载均衡到与Service关联的一组Pod
服务发现:Account-Service提供统一的Cluster-IP来提供服务发现,Client端只需通过Cluster-IP就可访问后端Pod集群,无需关心集群中Pod的IP和Pod的数量,Cluster-IP会屏蔽Pod 的IP的变化。
负载均衡:Account-Service 具有负载均衡的能力,支持不同的负载均衡策略访问集群中的Pod实例
Client与Pod集群之间引入一层Account-Service
Service网络模型
Service底层如何实现代理转发到后端的Pod,实现Pod的负载均衡?
Pod到Service网络
# 主要是解决流量入K8S集群的问题,内部服务暴露公网3种方式:1)、Loadbalancer2)、NodePort3)、Ingress controller
LoadBalancer一般由云供应商负责创建负载均衡器(阿里云、腾讯云、AWS等)将负载均衡器的IP地址暴露给公网提供服务
本地部署的K8S集群默认不支持Loadbalancer(安装相应组件可支持)主流的公有云负载均衡器都支持Loadbalance
创建type类型为Loadbalancer的service,会获取一个公网IP。示例:
公有云的负载均衡器,K8S集群环境也应在公有云环境中
Loadbalancer
每个node节点上都启用一个端口来暴露服务,用于在集群外部访问,也可指定分配一个内部集群IP端口,默认不指定会随机分配一个端口
访问地址:<任一节点IP>:<NodePort>端口范围:30000 - 32767 (手动指定NodePort端口范围也必须在该范围内指定)
实际场景中,会在每个节点的nodePort前加一个负载均衡器Nginx、Haproxy等
NodePort示例:
NodePort
1)、Service类型暴露公网的NodePort场景中,随着业务量增加,需对外暴露的端口多,管理、规划端口变得复杂。并且只支持4层协议负载均衡
2)、公有云上LoadBalance + IP需花钱购买。一个暴露公网的服务对应一个LoadBalancer + IP,即创建一个service服务就要使用一个LoadBalancer公网IP,如果有10个service服务,就得购买10个LoadBalancer + IP,显然浪费
NodePort + LoadBalancer可将内部服务暴露到互联网中,为啥还要引入Ingress?
Ingress模型图:
1)、公开了从集群外部到集群内service的HTTP和HTTPs路由规则的集合,具体实现流量路由由Ingress Controller处理2)、Ingress是K8S的一个组件,yaml来配置,ingress对象作用是定义请求如何转发到service的规则,ingress通过http、https暴露集群内部service,给service提供外部URI、负载均衡、SSL/TLS能力及基于域名的反向代理3)、ingress配置的路由规则具体实现由ingress-controller来完成
Ingress
1)、Ingress Controller 是具体实现反向代理和负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发2)、ingress-controller会动态感知集群中Ingress规则的变化,并读取它3)、ingress-controller并不是K8S自带的组件,实际上ingress-controller只是一个统称,使用者可选择不同的ingress-controller实现,目前,由K8S维护的ingress-controller只有Google云的GCE、Ingress-nginx两个,还有其他第三方维护的ingress-controller,如Nginx、Kong等4)、ingress-controller的形式也是一个Pod,Pod中跑着daemon程序和反向代理程序,daemon程序负责监听集群变化,根据ingress对象生成配置并应用新配置到反向代理,如:ingress-nginx就是动态生成nginx配置(可进入到该Pod中查看),动态更新upstream,并根据需要时候reload配置信息。5)、官方推荐使用的ingress-controller是Ingress Nginx
Ingress-controller
Ingress模型
ingress工作原理:
1)、ingress-controller 通过 Kubernetes APIserver交互,动态获取K8S集群中Ingress规则(创建的ingress yaml文件)的变化并读取2)、获取最新Ingress规则,按照自定义规则,规则中配置了哪个域名对应哪个service,将这些ingress规则映射翻译成nginx配置信息3)、将配置再写到 nginx-ingress-controller 这个Pod中,ingress-controller 这个Pod中是运行一个Nginx服务,控制器会将生成的Nginx配置写入到 /etc/nginx.conf文件中,并会reload使配置生效
Ingress工作原理
1)、适合Ingress服务部署在公有云平台上,用Deployment部署ingress-controller,创建type类型为LoadBalancer的Service关联这个Pod2)、大部分公有云都支持为LoadBalancer的service创建负载均衡器
Deployment + LoadBalancer模式 Service
1)、用DaemonSet + NodeSelector来部署ingress-controller到特定的Node节点上2)、使用HostNetwork直接把该Pod与宿主机Node的网络打通,直接使用宿主机80/433端口访问。此时,ingress-controller所在Node节点类似一个访问入口的Nginx服务器3)、该方式优点是请求链路简单,性能相对NodePort模式更好。缺点是由于直接使用宿主机节点的网络和端口,一个Node节点只能部署一个ingress-controller这个Pod4)、适合大并发场景使用
DaemonSet+ HostNetwork + NodeSelector模式
1)、用Deployment部署ingress-controller,创建type类型为NodePort的Service关联这个Pod,这样,Ingress会暴露在集群Node节点特定的IP和端口上2)、由于NodePort暴露的端口是随机的,一般会在前面再搭建一套负载均衡器来转发请求3)、NodePort方式一般用于宿主机是相对固定的IP环境下使用4)、NodePort方式暴露Ingress简单,但是NodePort多了一层Nat,在请求量级很大时对性能有一定影响
Deployment +NodePort模式 Service
Ingress Controller暴露端口方式
将具体应用服务端口暴露出去(类似nginx中创建server_name虚拟主机)
annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2
url重写rewrite
annotations: nginx.ingress.kubernetes.io/permanent-redirect: https://www.baidu.com
域名重定向 permanent-redirect
annotations: nginx.ingress.kubernetes.io/force-ssl-redirect: \"true\" nginx.ingress.kubernetes.io/ssl-redirect: \"true\"
强制https如果http请求,会301 redirect到https
annotations: nginx.ingress.kubernetes.io/use-regex: \"true\" # 后面rules定义的path使用正则表达式 nginx.ingress.kubernetes.io/proxy-connect-timeout: \"60\
请求超时
annotations: nginx.ingress.kubernetes.io/enable-cors: \"true\
跨域访问
annotations: nginx.ingress.kubernetes.io/proxy-body-size: \"10m\"
客户端请求最大body大小
annotations: nginx.ingress.kubernetes.io/limit-rps: \"5\" # rps 限制每秒请求数 nginx.ingress.kubernetes.io/limit-rpm: \"300\" # rpm 限制每分请求数 nginx.ingress.kubernetes.io/limit-connections: \"10\" # connections 限制连接数
限流
annotations: nginx.ingress.kubernetes.io/whitelist-source-range: \
白名单
annotations: nginx.ingress.kubectl.io/server-snippet: deny 192.168.1.10;allow all; # 黑名单
黑名单
设置黑白名单
注解Annotations常用配置
ssl证书配置
ssl证书存储secret
tls
Prefix:以 / 分隔的uri路径前缀匹配。匹配区分大小写,并且对路径中的元素逐个完成
Exact:精确匹配uri路径,且区分大小写
ImplementationSpecific:路径类型,匹配方法取决于 IngressClass
PathType 路径类型
定义后端转发规则,正则匹配
设置后端service
rules规则
示例:根据HTTP请求uri将应用流量路由到对应service中,创建ingress规则的yaml文件
Ingress配置规则
Service到互联网网络
K8S网络实现
CNI(Container Network Interface)是一个容器网络规范,K8S网络遵循CNI网络规范,主要解决Pod容器跨主机节点的网络通信问题
K8S默认不提供网络功能,所有Pod的网络功能,都依赖于宿主机的Docker。Pod的IP都依赖于本地的docker0网桥分配虚拟IP
Node节点的Pod可直接通信。跨Node节点的Pod需要通信,需要解决:1)、整个K8S集群中的Pod的IP进行重新规划,不能有IP冲突2)、Pod的IP和Node的IP需关联,通过Node的IP转发到Pod的IP
K8S主流的网络组件有Flannel、Calico等,都遵循CNI标准
CNI插件存放位置:
CNI
Flannel是一种典型的“覆盖网络(overlay network)”,将TCP数据包,包装在另一种网络包里面(建立网络叠加,实现网络的虚拟化),进行路由转发和通信。
目前已经支持UDP、VxLAN、Host-GW等数据转发方式,默认的node节点间数据通信方式是UDP转发
Flannel网络概述
1)、Pod的IP在集群中有唯一的虚拟IP地址
2)、建立一个overlay network,数据包在这个虚拟网络里进行路由转发
3)、数据包进行分组封装,封装的数据包转发到对端后,进行解封装
4)、创建一个虚拟网卡-flannel0,接收docker0网桥数据,通过本地维护的路由表,对接收到的数据包的封装、解封装、转发
5)、etcd数据库保证所有node节点的flanneld读取到的配置一致,node节点的flanneld进程实时监听etcd数据变化,实时获取node节点最新信息
Flannel网络实现原理
纯静态路由方式,要求所有node节点在同一个局域网内
将node节点主机的物理网卡作为网关
Pod要跨node主机节点通信,直接将数据包发送给node节点主机的物理网卡
node节点主机查询本地路由表进行转发,通过二层网络发包,少了数据的封装、解封装的过程,效率高
# 缺点:如果K8S集群规模大,node节点多情况,要维护node节点路由表,压力就大,因此,此方式不适合太复杂的网络环境
修改 kube-flannel.yml 文件
node节点主机查看ip,有cni0网桥
命令查看
修改为Host-GW方式
部署
Host-GW方式(路由)
# VxLAN:虚拟可扩展局域网(Virtual Extensible LAN),是Linux自身支持的一种网络虚拟化技术。VxLAN完全运行在内核态中,在内核态中实现数据封装与解封装。通过隧道技术,构建出一个(Overlay Network)覆盖网络
# 流程解析:1)、数据包从源Pod的容器发出,经本机docker0虚拟网桥转发到Flannel网络的flannel.1虚拟网卡,再转发给flanneld服务(agent代理)监听2)、Flannel在etcd数据库中维护了一张Node节点的路由表3)、源Node节点的flanneld服务将数据包内容UDP封装后,根据自身路由表投递到目的Node节点上的flanneld服务,数据包(帧)到达后被解封装,直接进入目的节点的flannel.1虚拟网卡,然后转发到目的Node节点的docker0网桥,最后经docker0到达目的Pod上
Flannel网络架构(VxLAN模式)图:
Cni0网桥:网桥设备,创建Pod都会创建一对veth pair。一端在Pod中为eth0,另一端在Cni0网桥中的端口。Pod中的eth0发出的流量都会发送到Cni0网桥设备上。
flannel0:UDP模式下,引入的虚拟设备flannel0(TUN),工作在三层网络。数据的封装、解封装在用户态完成。flannel0由flanneld进程创建,会将容器数据包经flanneld封装转到宿主机网络。
flannel.1:VxLAN模式下,虚拟隧道设备-flanne.1,工作在二层网络。数据的封装、解封装在内核态完成。
flanneld:作为flannel网络在每个node节点的agent,会为所在主机从集群网络空间中获取一个网段subnet,Pod容器IP从这里获取。同时flanneld监听etcd数据库,为flannel.1虚拟网络设备提供封装数据时必要的mac、ip等信息
Flannel网络架构组件(VxLAN模式)
修改 kube-flannel.yml 文件,指定虚拟网段
node节点主机查看ip,有cni0网桥、flannel.1虚拟网络
VxLAN方式(隧道)
此方式性能差,不维护
UDP方式
主要无需flannel.1中间设备,node节点主机的物理网卡作为网关,性能损失大约10%,性能最好
Host-GW方式
使用flannel.1进行数据包的封装、解封装,Linux内核原生支持,性能损失大约20%- 30%,性能较好
VxLAN方式
使用flannel0进行数据包的封装、解封装,Linux内核原生不支持,上下文切换开销大,性能最差
Flannel网络模式对比
Flannel网络数据转发模式
Flannel
Flannel是典型的Overlay网络,要Underlay网络(基础物理网络)作为基础之上建立叠加的逻辑网络,实现网络资源虚拟化
Calico 是一个纯三层网络方案,无需Overlay开销(无需数据包封装、解封装过程),将2、3层数据流量转换成3层数据流量,通过node节点作为路由器,使用BGP同步路由,使用iptables做安全访问策略,实现流量跨node节点通信和网络隔离
Calico网络概述
更好的资源利用:2层网络依赖消息广播,广播消息的开销与Host主机数量呈指数级增加;Calico则是纯3层网络路由,抑制了广播,减少资源开销
可扩展性:Calico支持网络的可扩展性
简单:无2层网络的Tunnel隧道,路由路径短,配置少
依赖少、适配性高:Calico仅依赖3层路由,并适配各种虚拟机、容器等场景
Calico优点
Calico网络架构图:
Felix:node节点上的agent进程,监听ETCD中心数据存储,监听、路由、Arp管理、ACL管理等。从中获取事件,如用户在这台机器加一个IP、创建容器等。创建Pod后,Felix负责将网卡、IP、Mac都设置好,然后写入到Kernel内核中的路由表中,注明IP到这张网卡。如果此时用户有制定了隔离策略,Felix同样会将该策略创建到ACL中,以实现隔离
ETCD:存储网络元数据,确保Calico网络状态准确性
BIRD:标准的路由程序,作为BGP Client部署在node节点上。用于监听node上由Felix注入的路由信息,写入到内核,通过BGP协议广播到其他node节点,实现网络互通
架构组件
Calico网络架构
Calico默认配置。一个IP数据包又套在一个IP数据包中,即IP层封装到IP层的一个隧道Tunnel。相当于一个基于IP层的网桥。普通网桥而言是基于Mac的,无需IP,而IPIP则是通过两端的路由做一个Tunnel,将本来不通的两个网络点对点的连接起来。
连接方式:
连接方式(tunl0隧道)
默认的IPIP模式,会在每台node主机创建一个tunl0网口(ip a命令能查看到),这个tunl0隧道连接所有的node节点网络
node节点的的tunl0虽为不同的网段,但可连接各node节点的网络
IPIP(隧道)
BGP是边界网关协议(Border Gateway Protocol),是互联网上一个去中心化的自治路由协议
修改calico.yaml文件,在DaemonSet部分calico-node的pod的变量中,修改CALICO_IPV4POOL_IPIP值为off:
修改BGP模式网络
BGP(路由)
calicoctl 常用命令
Calico网络模式
Calico
CNI网络插件
K8S网络
nginx ingress-controller部署
应用部署
Prometheus+Grafana+Alertmanger集群监控告警
资源层监控套件
安装Kuboard套件
监控告警管理
Grafana+Loki+promtail日志收集系统
日志管理
kubeconfig配置文件
集群相关证书
自签证书
证书管理
node节点配额和内核参数调整
etcd数据库
apiserver配置
pod配置
K8S集群优化
K8S运维管理
应用服务编排
健康检查
滚动更新
弹性伸缩
资源监控
ABAC
RBAC
认证和授权管理
K8S功能
单Master多Worker节点
多Master多Worker节点
K8S集群架构
是整个K8S系统的数据总线和数据中心,核心功能是为各类资源对象(Pod、service、PV等)的交互CRUD提供接口,集群内部各个功能模块间数据交互的中心枢纽
K8S集群管理的API入口,资源配置配额的入口,提供完备的集群安全机制
唯一可以直接同etcd数据库进行直接数据交互的组件
以RESTful方式提供各种API接口,K8S除为本身各类资源对象的CRUD提供API,还有为健康检查、日志、性能指标、UI等运维监控提供相关API
API层
客户端访问API接口时,访问控制层会对用户身份鉴权、验证用户身份,核准用户对K8S哪些资源对象的访问权限
访问控制层
K8S所有资源对象都保存在注册表(register)中,注册表中的各类资源对象都定义了类型,如何创建资源对象、如何将资源对象编码和解码为JSON进行存储
注册表层
用于K8S资源对象进行持久化存储(key-value)
etcd的watch接口,apiserver通过该接口可管理超大规模集群,及处理集群各类事件
提供存储:节点健康状况、节点名称、节点资源、节点信息、docker版本信息、kubelet版本信息等
apiserver架构
kube-apiserver
K8S集群内部的管理控制中心,发生故障导致某个资源对象状态发生变化时,controller会将其状态调整为期望的状态
名称空间控制器
namespace controller
通过apiserver获取各个node节点状态
node controller
也是副本控制器
使用Deployment无需担心还要管理它创建的ReplicaSet,Deployment比ReplicaSet更高级的概念,会管理ReplicaSet并提供其它有用的特性。Deployment不直接管理Pod,由Deployment管理ReplicaSet,再由ReplicaSet负责管理Pod对象
deployment controller
集群访问控制的控制器,进行身份鉴权和身份验真
ServiceAccount controller
副本控制器
ReplicaSet controller
确保资源对象在任何时候都不会超量占用node节点的物理资源,避免某些业务进程存在设计缺陷导致整个系统资源耗光而宕机
作用于Pod、Container
Limit
作用于namespace
ResourceQuota
资源配额通过准入控制(Adminssion Controller)来控制,2种方式提供配额约束
ResourceQuota controller 资源配额
endpoint controller
service controller
安全相关控制器
token controller
volume controller
controller-manger内部包含n多controller
controller-manger
作用:负责Pod节点的调度,起“承上启下”作用,“承上”是负责接收controller-manger创建的Pod,根据调度算法调度到合适的node节点上,“启下”是Pod落到哪个node节点后,由该node节点的kubelet服务接管后续工作,负责Pod生命周期的“下半生”
负责创建的Pod调度哪个node节点合适
schedule只同apiserver打交道
遍历集群所有节点,刷选出合适的node节点,过滤掉不符合要求的node节点
如果一个node节点都不合适,则将该Pod状态设置为Pending
预选节点
在预选节点中,采用优选策略计算出每个候选节点的积分,Pod调度到积分高的节点
优选节点
Pod调度过程
schedule
运行在每个node节点上,是master节点派到node节点上的Agent,管理本机Pod的生命周期,创建、启动、停止、销毁、挂载卷等
kubelet服务向apiserver注册本node节点的信息,定期向master节点汇报本节点资源使用情况,监控节点和pod容器资源
kubelet服务
通过kubel启动参数“--register-node”,是否向apiserver注册
--register-node = true 是注册,--apiserver:apiserver地址--kubeconfig文件用于访问apiserver配置--cloud-provider:云服务产商地址,用于公有云中
节点管理
静态Pod配置文件目录
http配置Pod文件路径
apiserver:kubelet通过apiserver监听etcd数据库信息,同步Pod列表
Pod管理
容器监控检查
docker runtime
kubelet作用
kubelet
每个节点都会运行一个kube-proxy-xxxx的Pod
负责Pod网络管理,各节点中的Pod网络请求、转发
监听pod变化,一旦变化,及时更新service对应pod的IP信息
kube-proxy
K8S核心组件的运行机制
K8S集群的控制节点
kube-controller-manger
kube-schedule
运行服务
Master
K8S集群的工作节点
Worker
集群类
最小部署单元,一个或多个容器的集合每个Pod都有一个特殊的pause容器。kubernetes直接管理pod,而非容器
一个Pod中的容器共享网络空间、存储资源
Pod临时短暂的,重启发布会销毁
Pod只有一个IP,Pod里的容器共享这个IP
Pod的Event,记录事件最早产生的时间、最后出现时间、重复次数、发起者、事件类型,及事件产生的原因等
pod
Pod的访问策略,一个虚拟的cluster IP,创建service时K8S会自动分配一个虚IP
Service通过Label标签关联一组Pod
Service使用iptables或ipvs为一组Pod提供负载均衡
作用
无头服务,无需Cluster-IP,直接绑定具体Pod的IP,无头服务常用于StatefulSet的有状态应用部署
Headless Service
service类型
service
Pod里的一个进程服务对外通信地址
一个Pod可对应多个endpoint
endpoint
label是一个key-value的键值对,key和value用户自己定义
label可被附加到各种资源对象上,如deployment、service、Pod等
label
某个资源对象定义了label后,相当于打了tag标签,通过selector查询或筛选有这些label的资源对象
selector
label与selector标签选择器
ConfigMap明文存储数据,存储一些非机密敏感数据,如一些应用的配置文件
ConfigMap是一个或多个 key/value 形式保存在K8S中,管理变量或配置文件内容
ConfigMap必须先于Pod创建,并只能处于相同namespace中的Pod才可引用
kubectl create configmap configmap-dir --from-file=/data/yaml/configmap/configdir
基于目录创建configmap
kubectl create configmap configmap-file --from-file=/data/yaml/configmap/ui.properies
基于文件创建configmap
kubectl create configmap special-config --from-literal=special.type=charm
基于文字值创建configmap
configmap创建方式
Secret秘文存储数据,存储一些敏感信息,账户密码、秘钥、token、ssl证书等
Opaquekubernetes.io/service-accout-tokenkubernetes.io/basic-authkubernetes.io/ssh-authbootstrap.kubernetes.io/tokenkubernetes.io/rbd
generic:通用型类型,基于base64编码存储密码、公钥等,可通过base64 --decode解码获得原始数据,因此安全性弱。子类型有:
kubernetes.io/dockercfg(旧版)kubernetes.io/dockerconfigjson(新版)
docker registry:用于存储docker registry的认证信息,子类型有:
kubernetes.io/tls
tls:保存TLS/SSL用到的证书和配对的私钥,常见子类型有:
secret类型
手动创建secret
kubectl命令创建dockerconfigjson类型的用于docker registry认证的secret# kubectl create secret docker-registry harbor-pull-secret --docker-server=gjharbor.aaa.cn --docker-username=admin --docker-password=****** --docker-email=xxx@abc.com -n test
kubectl创建secret
Kustomize提供资源生成器创建Secret和ConfigMapKustomize生成器要在当前目录内的kustomization.yaml中指定。生成Secret后,使用kubectl apply 在API服务器上创建对象
生成器Kustomize创建secret
secret创建方式
key/value 形式可导出到环境变量通过目录、文件形式进行挂载,volume挂载配置信息可热更新
相同点
Secret可被ServiceAccount关联Secret可存储 docker register的鉴权信息,用在 imagePullSecrets 参数中,用于拉取私有仓库镜像Secret支持Base64 加密Secret分 generic、docker registry、tls 类型,而ConfigMap不区分类型
不同点
ConfigMap与Secret对比
configmap与secret
job运行一次任务,job控制的Pod副本任务结束后,job也结束
job
周期性执行某个定时任务,类似Linux的crontab
cronjob
job与cronjob
K8S的HPA Controller已实现一套简单的自动扩缩容逻辑。默认每30s检测一次指标,只要检测到了配置HPA的目标值,则会计算出预期的工作负载和Pod的副本数,再进行扩缩容
基于CPU自动扩缩容
基于内存自动扩缩容
资源限制requests、limits
自动扩缩容
容器水平伸缩
依据deployment的replicas配置的参数,设置Pod的副本数
Pod层面
K8S集群Node节点的扩容、缩容,目前云主机支持
Node节点层面
扩缩容种类
HPA v1:根据CPU指标来进行自动扩缩容
HPA v2后需安装Metrics Server这个数据采集组件
这样CPU、内存等metric指标信息通过Metrics API来获取,HPA通过这些metrics信息(kubectl top命令)来实现动态扩缩容
Metrics Server 是一个集群范围内的资源使用情况的metric指标监控器。
Metrics Server只显示数据,不存储数据。关注的是资源Metrics API的实现,如CPU、内存、请求延时等metrics指标,Metrics Server收集数据给K8S集群内使用,如 HPA、kubectl等。
Metrics Server:数据采集组件
HPA v2:根据CPU、内存指标和自定义指标来进行自动扩缩容
扩缩容指标
HPA(常用)
容器垂直伸缩
VPA
容器定时伸缩
CronHPA
应用资源类
定义在Pod中,被Pod中容器挂载具体目录使用
Pod重启Volume数据不丢失
Volume
创建Pod时自动在node节点上开辟一块空卷
临时的空卷,随Pod的删除而销毁空卷
实际用途:Pod中多个容器间数据共享,多用于获取应用容器的log
emptyDir
hostPath
K8S集群运行在公有云环境中,可使用此类Volume
EBS
亚马逊云
GCE
谷歌云
公有云Volume
nfs
glusterfs
ceph的设备共享存储挂载Pod中
rdb
iscsi
其他类型Volume
Volume存储类型
K8S集群中某个网络存储对应的存储区域,集群之外的存储。
PV不在Pod中定义,Pod关联上这个PV
亚马逊云 EBS
Azure
NFS
GlusterFS
CephFS
RBD
PV支持的类型
PV(PersistenVolume)持久化卷
存储类
api server是Kubernetes集群内部各组件进行通信的中介,也是外部控制的入口,所以Kubernetes的安全机制围绕保护api server设计的。
# 访问Kubernetes集群资源需过以下3关:如 kubectl 向apiserver请求资源,需过经过 认证(Authentication)、鉴权(Authorization)、准入控制(Admission Control)这3到关卡,才能使用K8S创建资源。
SSL证书认证:X509客户端证书认证,基于CA证书签名的数字证书认证。如kubelet连接apiserver、kube-proxy连接apiserver均采用Https传输方式
Token令牌认证:通过一个Token来识别用户,客户端携带一个Token来请求Server端,如果Server端有该Token,则认证成功,否则,不认证通过
账户密码方式认证:此方式在K8S中基本不用
认证(Authentication):客户端用户身份识别认证
用户端身份识别认证通过后,对集群哪些资源组件有哪些权限?RBAC来完成Authorization工作
根据api请求属性,决定允许还是拒绝?API组namespace资源资源组usergroupAPI请求路径Http请求方法
鉴权(Authorization):
判断操作是否符合K8S集群要求,能不能这么干?
Admission Control实际是一个准入控制器插件列表,发送到apiserver的请求需经过这个列表中的每个准入控制器插件的检查。特别对一些写操作,要遵循对操作资源的合规性检查。
准入控制(Admission Control):
K8S安全框架
RBAC-基于角色的访问控制,允许通过Kubernetes API动态配置策略,是K8S集群默认的访问控制策略
Role:授权特定namespace的访问权限
ClusterRole:授权所有namespace的访问权限
角色
RoleBinding:将角色绑定到subject主体
ClusterRoleBinding:将集群角色绑定到subject主体
角色绑定
Role 和 RoleBinding对应、ClusterRole 和 ClusterRoleBinding对应
namespace
资源对象
get
watch
list
操作
创建的RBAC权限策略yaml文件配置信息
Rules
user用户
group用户组
ServiceAccount服务账号
主体Subject
文件:/etc/kubernetes/manifests/kube-apiserver.yaml
RBAC(Role-Based Access Controller)
普通用户User或用户组Group由K8S集群之外的独立管理服务,如LDAP、管理员分配私钥等,kubectl命令连接K8S集群就是普通用户
普通用户权限需求将Role与User(Group)进行绑定
普通用户UA(User Account)
ServiceAccount是Kubernetes API管理的用户,K8S集群内使用。Kubernetes直接创建:kubectl create sa。绑定到特定namespace,如Pod服务进程,通过API来完成权限认证、创建。
ServiceAccount与存储为Secrets的一组证书关联,挂载到Pod中,以便K8S集群进程与Kubernetes API进行通信。登录K8S集群的DashBoard、Kuboard都使用ServiceAccount进行登录
创建的namespace空间都会有个default的sa账户。如创建Pod时会集成个sa账户,而默认的sa账号为default
服务账户SA(ServiceAccount)
K8S集群的资源操作,实际都是通过node节点的kubelet和Master节点的apiserver间的通信实现,而K8S的认证目录中有其专用的通信认证证书 apiserver-kubelet-client.crt,可通过该文件来检查两者之间的关系
管理员用户组system:master的权限,如将某个用户添加到K8S集群中的 system:masters 组中,则该用户具有管理员的权限。
用户组system:master权限
K8S用户
安全机制类
K8S基础概念及术语
最小部署单元
一个或一组容器的集合
K8S直接管理Pod,而非容器
Pod资源共享机制,一个Pod中的容器共享网络空间、存储资源
Pod基础概述
Infrastructure Container:基础容器,维护整个Pod的网络空间,创建Pod会默认自动创建,无需人为维护
InitContainers:初始化容器,先于业务容器开始执行,为业务容器初始化工作
Containers:业务容器,并行启动
Pod里3种容器类型
pod生命周期流程图:
# 流程:1)、发送创建指令到API Server2)、通知Scheduler调度到合适的node节点上init容器,初始化容器,独立于主容器之外;Pod可拥有多个init容器,init容器按顺序执行,最后一个init容器执行完成,才启动主容器;init容器不支持探针Probe检测,主要是为主容器准备运行环境的功能,如准备配置文件、检测主容器依赖服务等3)、启动后钩子函数PostStart hook,与主容器同时运行4)、检测容器状态,启动Pod探针 startup probe、探针Liveiness probe、探针Readiness probe5)、Service关联Pod6)、接收用于请求7)、关闭Pod前先执行钩子Pre stop hook8)、关闭Pod
Pod生命周期流程
Pending:apiserver已创建pod,pod未被调度,或pod已调度正在拉取的镜像启动容器
Running:Pod运行中,Pod内容器已创建,且至少一个容器已启动状态
Success: Pod内容器运行成功后退出
Failed:Pod内容器运行停止退出
Unknown:Master节点与Node节点失联,Pod状态无法正常获取
Pod生命周期几种状态
Always:当容器终止退出后会自动重启,默认的策略
OnFailure:当容器异常退出(退出的状态码非0)时,kubelet自动重启容器,定时任务场景使用
Never:当容器终止退出,kubelet从不重启容器。静态Pod场景使用
Pod重启策略
Pod生命周期与重启策略
关键字envFrom,指定挂载的configmap,根据configmap的key=value
环境变量方式
VolumeMount方式
Pod中使用configmap
ConfigMap
VolumeMount方式挂载
使用方式
Secret
ServiceAccount
Pod配置管理
1 CPU = 1000millicpu,即 1core = 1000m
Cgroup里CPU资源单位换算
1M = 1024K
内存为不可压缩资源,容器过渡使用,易达到内存资源的上限
内存单位换算
Pod资源配置
判断容器是否为Running状态LivenessProbe探测到容器不健康,kubelet将容器杀死,根据Pod的restartPolicy策略来操作,再进行重启
Pod存活检查-LivenessProbe
判断容器是否为Ready状态,可接收处理流量请求如果检查失败,Pod状态为不可用False时,K8S会把该Pod从service endpoint中剔除。等Pod为Ready状态时,才将该Pod加回到endpoint中
Pod应用就绪检查-ReadinessProbe
Pod启动检查
Pod启动检查-StartupProbe
httpGet:发送http请求,返回200-400状态码为成功
exec:执行shell命令返回状态码是0为成功,非0失败,执行非0失败的策略
tcpSocket:发起TCP Socket建立成功
支持检测方法
Pod健康检查-探针Probe
Pod创建流程图:
# Pod创建流程解析:1)、用户通过Kubelet或其他 REST API 提交Pod创建指令create pod2)、API Server将创建Pod的相关信息写入到etcd中,完成后 API Server 再反馈给用户端3)、Scheduler检测到有未绑定到Node节点的Pod,开始调度并更新Pod绑定到哪个Node节点上,并发送给API Server4)、API Server 将该Pod绑定的节点信息写入到Etcd和Scheduler 本地留一份5)、Node节点上的 Kubelet通过API Server查看绑定的Pod,检测到有新的Pod被调度过来,就开始将该Pod的信息传递给Container runtime,如Docker,运行该Pod6)、Docker将运行的信息传递给Container runtime,Kubelet可Container runtime这里获取到Pod状态,将状态更新到API Server中,API Server最后将状态写入到Etcd中
Pod创建的基本流程
过滤不满足条件的node
预选predicate
node优先级排序打分
优选priorities
优选中选择打分最高的node
调度器调优
查看默认PriorityClass对象
需先定义PriorityClass对象
Pod优先级定义
创建PriorityClass对象
Pod的 spec.priorityClassName 中指定已定义的PriorityClass名称
使用这个PriorityClass对象
优先级调度
调度流程
避免集群中某个节点Pod容器资源异常,CPU、内存等资源被无限制消耗,影响其他节点的资源开销,故对Pod容器资源进行限制resources: {}
Pod资源限制-resources
1)、node节点打label标签
2)、添加nodeSelector字段到Pod配置中
nodeSelector:将Pod调度到匹配的Label标签的Node上,如未匹配成功的标签会调度失败
匹配更多的逻辑组合,不只是字符串的完全相等
软策略调度示例:
调度可分为软策略(required)、硬策略(preferred)操作符 operator 有:In、NotIn、Exists、DoesNotExists、Gt、Lt
nodeAffinity :同nodeSelector作用一样,但相比更具灵活性
节点标签选择器nodeSelector、节点亲和性nodeAffinity
Taint:不让Pod调度到标记的node节点上
Tolerations:允许Pod调度到持有Taints的node节点上
# [effect] 可取值:NoSchedule:一定不能被调度(最常用)PreferNoSchedule:尽量不要调度到NoExecute:不仅不被调度到,而且会驱逐node已有的Pod
1)、第一步添加Taint污点
2)、第二步添加Tolerations污点容忍字段到Pod配置中,给添加了污点的node节点添加污点容忍,使之能在该node节点上创建pod
流程
去除污点:
去除污点
Taint(污点)、Tolerations(污点容忍)
主要解决Pod要同哪些Pod在同一区域。跨集群、跨机房区域场景使用
Pod亲和性PodAffinity
影响Pod调度属性
Pod创建、调度
由kubelet创建、管理的仅运行在特定node上的Pod
不通过apiserver进行管理的,不与deployment、RC等关联
kubelet中设置staticPodPath
配置文件方式
kubelet启动参数 --manifest-url
http方式
静态Pod创建
静态Pod
Pod创建成功后的一些信息,Pod名称、IP、Label、容器级别等,Pod中要使用这些信息,K8S提供Download API机制,可将这些信息注入到容器中
Pod信息设置为容器内的环境变量
Container信息设置为容器内的环境变量
环境变量
Pod信息设置为容器内的文件
Container信息设置为容器内的文件
Volume挂载
Pod和容器信息注入到容器内部
容器中获取Pod信息-Download API
Pod资源清单
每种controller处理不同的任务,主要用来控制管理Pod的状态和行为
controller控制器
deployment为无状态应用
主要功能:管理的多个副本的Pod的迁移、自动扩缩容、自动灾难恢复、一键回滚
常用场景:线上一个应用的更新,只需更新容器镜像版本,然后修改deployment里的镜像,deployment会滚动更新(rolling update)升级现有Pod。可做到线上服务不中断进行应用的更新
更新了一个pod后,在更新后续pod
rolling update(默认策略)
删除旧的,再创建新的
Recreate重建策略
滚动更新策略
maxSurge: 一次滚动更新可添加多少个Pod。确保更新启动的Pod数量比期望(replicas)Pod数量最大多出25%。可使用数字表示
maxUnavailable: 滚动更新过程期间最大多少个Pod是不可用。即保证75% Pod是可用的。可使用数字表示
minReadySeconds:
滚动更新策略示例:
kubectl rollout 命令行回滚发布版本实际使用情况较少,一般情况下通过更新、回滚镜像,在滚动升级进行版本回滚
回滚命令:
版本回滚rollout
增加副本数
较少副本数
水平伸缩
deployment
statefulset有状态且有序启动的应用。有状态应用一般具备一致性,有固定的网络标记、持久化存储、顺序部署和扩展、顺序滚动更新等
使用场景:一些集群应用,如redis集群、zookeeper集群、elasticsearch集群等一般都会使用StatefulSet进行有状态的应用部署
上面集群有一些共同点:Pod有唯一的标识符,有状态的,Pod数据持久化有独立的存储
StatefulSet创建的Pod使用Headless Service(无头服务)进行通信,没有ClusterIP的,使用Endpoint进行通信
StatefulSet存储,Pod存储必须由PersistentVolume Provisioner(持久化配置卷)根据请求配置StorageClass,或先手动配置存储
StatefulSet删除不会删除与StatefulSet关联的卷,可手动删除PVC、PV
StatefulSet删除时,不保证对Pod的终止,要在StatefulSet中实现Pod的有序和正常终止,可在删除之前将StatefulSet副本设置为0
注意事项:
statefulset
部署守护进程,K8S集群所有node节点运行这个后台服务,也就是在集群所有节点上部署Pod副本,如果有新node节点加入K8S集群,DaemonSet会自动在该节点运行部署的Pod副本,相反如果有节点退出K8S集群,DaemonSet会自动移除部署在该节点的Pod副本
概述:
集群每个node节点会运行这个Pod实例
新node节点加入K8S集群,该Pod会自动在新节点上被创建运行起来
当有node节点删除,相应的Pod也会从集群中回收
daemonset特性
网络插件的Agent组件,如(Flannel,Calico)需要运行在每一个节点上,处理这个节点上的容器网络
存储插件的Agent组件,如(Ceph,Glusterfs)需要运行在每一个节点上,在这个节点上挂载远程存储目录
监控系统的数据收集组件,如(Prometheus Node Exporter,Zabbix agent)需要运行在每一个节点上,负责这个节点上的监控信息搜集
日志系统的数据收集组件,如(Filebeat,Logstash)需要运行在每一个节点上,负责这个节点上的日志信息搜集
daemonset使用场景
常规情况下,pod运行哪个node有k8s的调度策略(预选、优选等)决定,daemonset创建的pod已提前确定pod运行哪个node上(pod创建指定的.spec.nodeName)
daemonset调度器未启动,daemonset控制器也可创建pod
daemonset先从etcd中获取node节点列表,遍历所有node节点
根据资源对象定义是否有调度配置,分别检查node列表是否符合要求
node节点上检查是否有对应的pod。如果没有,创建pod;如果有,并且pod数量大于1的,删除多余pod,保证只有一个pod;如果正好一个,说明情况正常
daemonset控制器如何保证每个node节点运行一个可管理的pod?
rolling update滚动更新(默认策略)
Ondelete
更新策略
daemonset调度
daemonset
HPA
深入Pod编排
K8S知识点结构
0 条评论
回复 删除
下一页