runtime
来运行容器=
从上自下依次是:
stable
=
基本工作原理:
NET namespace
和存储资源
lo
直接通信MNT/USER/PID
等namespace上保持隔离Deployment
负责确保指定的Pod的副本数量维持在指定值,否则多退少补Service
kube-proxy
生成的iptables
或ipvs
规则)kube-proxy
都会将其所在节点上的每个Service的定义转换为ipvs
或iptables
规则!!!!!!!Selector
选定一组Pod,并为这组Pod定义一个统一的固定访问入口(如:ClusterIP)# 服务发现
'定义:针对客户端访问的服务,找到对应的的后端服务实例
'在K8s集群中,客户端需要访问的服务就是 Service对象
每个 Service 会对应一个集群内部的有效的虚拟IP,集群内部通过 虚拟IP 访问一个确定的服务。
# 负载均衡
'集群中微服务的负载均衡是由 Kube-proxy 实现的
Kube-proxy 是一个分布式代理服务器,集群上'每个【工作节点】都有一个Kube-proxy
需要访问服务的节点越多,提供负载均衡能力的 Kube-proxy 就越多,高可用节点也随之增多
persisent volume
)之上是kubernetes集群中资源对象的标识符
namespace
用于资源隔离,形成逻辑分组
创建资源对象(如Pod、Service)时,若不指定namespace
,则默认属于default namespace
注:Pod、Service都是namespace
级别的资源对象!也存在其他级别的资源!!!
# Master(控制节点)
apiserver # 各组件交互中心
scheduler # 调度。为Pod分配合适的节点
controller-manager # 控制中心。终极目标:维持spec期望状态
ETCD # 强一致的分布式K/V数据库。实现集群信息的持久化(自身已实现高可用)
# Node(工作节点)
kubelet # 与容器引擎进行交互,管理Pod的生命周期
kube-proxy # 解决网络问题。将service转化为 iptables/ipvs 规则
Container engine # 容器引擎
注:
apiserver
组件运行时的程序文件名为 kube-apiserver
,其他类似=
apiserver
提供的接口进行的,所有其他组件通过它进行交互apiserver
的高可用,由前端的负载均衡服务器实现(通过健康监测功能实现)keepalived
设置VIP来实现apiserver
与Etcd
基于https
通信,状态信息都保存在后者,因此apiserver
本身实现了无状态,因此设计冗余的时候不必设置过多,两三台已经足够(与实际业务规模相关)API-Server
所有可用资源,为Pod调度最佳NodeAPI-Server
确认Pod对象的创建请求之后,接下来便需要Scheduler
进行调度选择Node创建Pod注:kubernetes也支持用户自定义调度
Controller
的集合control loop
确保集群的实际状态不断逼近期望状态(维持副本的期望数量)raft
一致性算法实现,是一个强一致性的分布式K/V
存储系统(注册中心)key-value
数据存储系统/var/lib/etcd
,一定要对该目录做好备份 !!!整个kubernetes系统中一共有两个服务需要用到etcd用来协同和存储配置:
flannel
、对于其它网络插件也需要用到 etcd存储网络的配置信息kubernetes
本身,包括各种对象的状态和元信息配置API-Server
上注册当前节点的工作节点,定期向Master汇报节点资源使用情况cAdvisor
监控API-Server
中Service
的变化间接获得来自于scheduler
的指令,kube-proxy
都会把整个集群的每个Service转换为自己的ipvs
或iptables
规则,注:Kubernetes 网络代理运行在 Node 上,它反映了 Node 上 Kubernetes API 中定义的服务,并可以通过一组后端进行简单的 TCP、UDP 流转发或循环模式(round robin
)的 TCP、UDP 转发,用户必须使用apiserver API
创建一个服务来配置代理,其实就是kube-proxy
通过在主机上维护网络规则并执行连接转发来实现 Kubernetes服务访问
runtime
环境以下载镜像并运行容器kubelet
以插件的方式载入配置的容器环境kube-apiserver
是各组件的交互中心,并且是唯一能与ETCD交互的组件,直接负责集群数据存储
kube-controller-manager
是许许多多的controller
的集合(司令部,决策中心)
kubelet
通过某些协议基于HTTPS与kube-apiserver
进行连接**(双向证书认证)**
kubelet
监视kube-apiserver
上与自己所在节点相关的Pod的状态(并不是监听所有数据)
kubelet
包括三个接口
docker
是可被替代的kube-proxy
解决客户端的访问
每个节点的kube-proxy
都会把整个集群的每个Service转换为自己的ipvs
或iptables
规则
因此能实现服务的映射访问目的
每个worker node
都要运行kubelet / kube-proxy / Container engine
三个组件,这三个组件都只需与apiserver
建立联系,他们都是apiserver
的客户端!因此apiserver
是整体的交互中心!
但是apiserver
并不负责控制,其主要功能是借助ETCD来保存客户端所提交的、希望被存储的数据(实现状态存储),实际上起控制作用的控制中心是controller-manager
controller-manager
不会直接指挥kubelet
,而是监视apiserver
中与自己相关的 Pod 的状态,当状态异常时,就发起请求进行修复;同时,kubelet
也会监视apiserver
,因此kubelet
会实时察觉到apiserver
中与自己所在节点相关的Pod的状态的改变,于是通过控制器(如Depolyment
)唤起容器引擎进行相关操作,以维持副本的期望状态
注:
kubelet
,注册监听apiserver
中与自己相关的Pod的变动信息Depolyment
是controller-manager
的组件之一,也会注册监听apiserver
中与自己相关的内容Depolyment
的实际操作是运行一个control loop
实现监控(控制器的常规做法)Master组件、Node组件,再加上一些核心附件,才能构成完整的集群
Elasticsearch Logstash Kibana
)或 EFK(Elasticsearch Filebeat Kibana
)Loki Grafana
)# Logstash是基于Java编译器的Ruby语言开发,占用内存很大
# 而Filebeat相同情况下,内存占用可能只需要前者的千分之一!
# Loki是仿照prometheus构建的工具
# Elasticsearch由Java开发(非云原生),而Loki是标准云原生工具
kubeDNS
的实现方案已经发展到第三代,产品名为CoreDNS
API-Server
中的每一个Service
的定义,将其动态解析为自己的记录(A、PTR、SRV)Ingress
是在应用层实现的http(s)
负载均衡机制Ingress
本质是一组路由规则的集合,需要由Ingress Controller
发挥作用nginx、Envoy、HAprox...
各容器之间通信:
NET namespace
,直接回环通信Pod与Pod之间的通信:
cni0
(相当于docker
内容器通信使用docker0
)Pod之间的通信(使用叠加或承载):
flannal.1
通信(隧道接口附着在节点的网卡上)jumbo frames
,是指有效负载超过IEEE 802.3
标准所限制的1500字节的以太网帧)总结:Pod之间通信,无论是否跨主机,都需要借助网络插件来实现
kube-proxy
都会把整个集群的每个 Service 转换为自己的ipvs
或iptables
规则iptables
规则之中使用Service的重要意义:实现【服务注册】与【服务发现】
唯一入口:节点网络(节点网卡)
亲密关系
非亲密关系
flannel
插件实现)
kubelet
插件或CNI
插件实现kube-proxy
配置为iptables
或ipvs
规则,# Node IP
宿主机的IP地址
# Pod IP
# 由网络插件配置指定,比如 flannel 的 10.244.0.0/16
假设有3个Node:
则可分配 Node1= 10.244.1.0/24
Node2= 10.244.2.0/24
Node3= 10.244.3.0/24
此时每个节点上可运行 256 个容器
'Pod网络配置在 Pod内部的容器的网卡之上!!!!!!!
# Cluster IP:虚拟IP,通过iptables规则访问服务
# 在使用 flannel 的 10.244.0.0/16 的情况下
一般 Service网络是 10.96.0.0/12 (则可使用网段为 96~112)
`注意:Service网络不会出现在某个网卡上!!!
'出现在 iptables/ipvs规则 之中,作为访问的入口或端点
'也会出现在DNS解析记录中,将Service的名称解析为其对应的IP地址
=
Kubernetes本身并不提供网络功能,只是把网络接口开放出来,通过插件的形式实现(CNI)
Kubernetes管理的是集群
Kubernetes中的网络要解决的核心问题就是每台主机的IP地址网段划分,以及单个容器的IP地址分配
概括为:
当前最常用的两种CNI解决方案为:flannel
、Project calico
flannel
:仅实现了网络(简单易用易理解)Project calico
:实现了网络和网络策略(生产环境使用居多)flannel
的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址,而且它还能在这些IP地址之间建立一个覆盖网络(Overlay Network),通过这个覆盖网络,将数据包原封不动地传递到目标容器内
Flannel是作为一个二进制文件的方式部署在每个node上,主要实现两个功能:
# flannel网络架构
- 节点网络:对应各个主机的IP(自定义)
- Pod网络:对应CNI的网段,配置在Pod内部容器的网卡上(如flannel的`10.244.0.0/16`)
- service网络:只出现在`iptables`或`ipvs`规则之中,作为访问入口使用(由`kube-proxy`管理)
Calico创建和管理一个扁平的三层网络(不需要overlay),每个容器会分配一个可路由的IP。由于通信时不需要解包和封包,因此网络性能损耗小,易于排查,且易于水平扩展
API-Server
访问集群,完成管理任务kubectl
或者图形工具Dashboard
,或者通过API接口localhost
)kube-proxy
通信kube-proxy
通过service网卡通信(通过注册中心)借助 Service
的调度算法将流量调度到Pod
由 Ingress
调度直接到达Pod(但是Ingress
会先借助Service识别一个服务后的所有Pod资源)
Kubernetes 作为云原生应用的基础调度平台,相当于云原生的操作系统,为了便于系统的扩展,Kubernetes中开放的以下接口,可以分别对接不同的后端,来实现自己的业务逻辑:
以上三种资源相当于一个分布式操作系统的最基础的几种资源类型,而Kuberentes是将他们结合在一起的纽带
CRI中定义了容器和镜像的服务的接口,因为容器运行时与镜像的生命周期是彼此隔离的,因此需要定义两个服务。该接口使用Protocol Buffer,基于gRPC
Container Runtime实现了CRI gRPC Server,包括RuntimeService
和ImageService
。该gRPC Server需要监听本地的Unix socket,而kubelet则作为gRPC Client运行
Kubernetes 1.9中的CRI接口定义中 包含了两个gRPC服务:
通过CRI接口可以指定使用其它容器运行时作为Pod的后端 ,而不一定是使用 docker
cri-o
:cri-o是Kubernetes的CRI标准的实现,并且允许Kubernetes间接使用OCI兼容的容器运行时cri-containerd
:基于Containerd的Kubernetes CRI 实现rkt
:由CoreOS主推的用来跟docker抗衡的容器运行时frakti
:基于hypervisor的CRIdocker
:kuberentes最初就开始支持的容器运行时,目前还没完全从kubelet中解耦,docker公司同时推广了OCI标准注:K8s与docker交互,接入点在container-shim
处,在此之上的部分与集群无关(包括Daemon)
因此 Podman作为一个无守护进程的容器引擎,也能实现与K8s协同工作!!!
CNI(Container Network Interface)是 CNCF 旗下的一个项目,由一组用于配置 Linux 容器的网络接口的规范和库组成,同时还包含了一些插件。CNI 仅关心容器创建时的网络分配,和当容器被删除时释放网络资源
Kubernetes 源码的 vendor/github.com/containernetworking/cni/libcni
目录中已经包含了 CNI 的代码,也就是说 kubernetes 中已经内置了 CNI
CNI 插件负责将网络接口插入容器网络命名空间(例如,veth 对的一端),并在主机上进行任何必要的改变(例如将 veth 的另一端连接到网桥)。然后将 IP 分配给接口,并通过调用适当的 IPAM 插件来设置与 “IP 地址管理” 部分一致的路由
相关要点:
IP 分配:
作为容器网络管理的一部分,CNI 插件需要为接口分配(并维护)IP 地址,并安装与该接口相关的所有必要路由。这给了 CNI 插件很大的灵活性,但也给它带来了很大的负担。众多的 CNI 插件需要编写相同的代码来支持用户需要的多种 IP 管理方案
为了减轻负担,使 IP 管理策略与 CNI 插件类型解耦,我们定义了 IP 地址管理插件(IPAM 插件)。CNI 插件的职责是在执行时恰当地调用 IPAM 插件。 IPAM 插件必须确定接口 IP/subnet,网关和路由,并将此信息返回到 “主” 插件来应用配置。 IPAM 插件可以通过协议(例如 dhcp)、存储在本地文件系统上的数据、网络配置文件的 “ipam” 部分或上述的组合来获得信息
可用插件举例:
CSI 代表容器存储接口,CSI 试图建立一个行业标准接口的规范,借助 CSI 容器编排系统(CO)可以将任意存储系统暴露给自己的容器工作负载
CSI 持久化卷支持是在 Kubernetes v1.9 中引入的,作为一个 alpha 特性,必须由集群管理员明确启用