k8s组件调用关系及其网络

看完本章能掌握的知识

k8s基本架构图
k8s重要组件的功能和原理
k8s各个组件之间如何交互
k8s网络模型
k8s网络解决了docker网络的哪些局限性

一. 架构图回顾

在这里插入图片描述

apiServer:资源统一入口和管理
etcd:资源存储
controller-manager:状态控制
scheduler:调度
kubelet:容器生命周期管理

二. 核心组件原理

  1. APIServer
    在这里插入图片描述

1.1 功能和作用

整个系统的数据总线和数据中心,负责各模块通讯
提供各类资源对象(pod,service等)的增、删、改、查等Restful接口
集群内各个功能模块之间数据交互和通信的中心枢纽
集群的API入口
资源配额入口
提供安全机制

1.2 存在形式

运行在master节点上的一个叫 kube-apiserver 的进程提供服务
暴露的端口:http-8080,https-6443

1.3 如何交互

通过kubectl命令行工具
通过curl命令访问
通过编程调用

apiserver在k8s中也是一个Service对象,名字叫做kubernetes, 通过kubectl get svc命令可以查看

1.4 工作原理

作为集群的核心,负责各功能模块之间的通讯
各功能模块通过ApiServer将信息写入Etcd
获取数据时,通过ApiServer提供的Restful接口实现

为了缓解集群访问压力,各模块都使用缓存,定期从ApiServer获取资源信息,保存到本地
  1. Controller-Manager

在这里插入图片描述
2.1 功能和作用

集群内部的管理控制中心
负责集群内资源对象的管理,比如:pod,service,node,namespace
内部包含各种Controller,每种Controller负责一种具体的控制流程

2.2 常用的控制器

在这里插入图片描述
2.3 ReplicationController

确保集群中Pod副本一直保持预设状态
确保集群中有正确数量的副本(spec.replicas)
通过修改spec.replicas实现扩容和缩容
通过修改pod模板实现系统滚动升级

2.4 NodeController

作用:通过apiserver实时获取node相关信息,实现管理和监控Node的功能
监控、管理功能举例:

设置节点状态信息:Ready、Not Ready、UnKnown
长时间未收到kubelet的心跳信息则删除etcd中的存储信息

2.5 ResourceQuotaController

作用:听资源配额管理,确保资源占用不会超过系统物理资源
管理维度包括:

容器级别:对CPU和Memory进行限制
Pod级别:对pod内所有容器的可用资源进行限制
Namespace级别:

pod数量
service数量
secret数量
pv数量

2.6 NamespaceController

作用:定时通过Apiserver获取保存在etcd中的namespace,并控制namespace的创建、删除等操作

2.7 Endpoints Controller

什么是endpoints? 一个service对应的所有pod的访问地址

作用:负责生成和维护所有的endpoint对象,供给kube-proxy做负载均衡

2.8 Service Controller

作用:k8s与外部云平台之间的接口控制器,监听service的变化,确保正确的loadbalance被创建

  1. Scheduler

在这里插入图片描述
3.1 概述

作用:将待调度的pod按照调度算法绑定到合适的Node上

3.2 默认调度流程

预选调度:遍历所有节点,选出符合要求的候选节点
确定最优节点:基于上一步,采用优选策略,计算出候选节点积分,最高分为分配的节点

3.3 预选策略

默认的预选策略包括5个维度的筛选,只有都通过了才作为候选节点
预选策略说明:

NoDiskConfilct:Volume相关冲突检测
PodFitsResources:资源是否满足的检测
PodSelectorMatches:pod标签选择器的检测
PodFitsHost:是否指定被调度到特定Node的检测
CheckNodeLabelPresense:判断label设定备选节点时,是否选择备选节点

3.4 优选策略

LeastRequestedPriority:选出资源消耗最小的节点
CalcuateNodeLabelPriority:通过调用用户注册的策略计算
BalancedResourceAllocation:选出各项资源使用率最均衡的节点

  1. Kubelet

在这里插入图片描述

4.1 概述

每个Node节点上都会启动一个kubelet服务进程
用于处理Master节点下发到该节点的任务,管理pod及pod中的容器

4.2 kubelet与ApiServer交互原理

kubelet定期调用ApiServer的接口,汇报自身状态。ApiServer收到信息后将状态信息更新到etcd
kubelet通过监听ApiServer的watch接口监听pod信息,如果监听到pod信息变更,会在本机做相应的操作

在这里插入图片描述

4.3 Pod管理
kublet通过ApiServer监听pod的变化:

如果发现有新的绑定到该Node的pod,则创建pod

创建pod的数据目录
从ApiServer获取pod信息
为pod挂载volume
下载pod的secret
检查运行在节点中的pod,并删除无效的
为pod创建pasue容器
下载镜像,启动业务容器

如果发现有删除该Node的pod,则删除pod

4.4 容器健康检查
pod通过两类探针检查容器的监控状况

LivenessProbe:判断容器是否健康,定期调用
ReadnessProbe:判断容器是否启动完成

4.5 资源监控

k8s提供基本的监控平台,由Heapster项目提供
Heapster作为pod运行在k8s中
Heapster通过kublet发现集群信息,并查看资源状况
kubelet通过cAdvisor获取节点和容器的数据,并推送到可配置的后端
cAdvisor采集cpu,文件,内存等指标信息

  1. Kube-Porxy

在这里插入图片描述
5.1 概述

kube-proxy运行在每个Node节点上
作为Service的代理和负载均衡器
核心功能是将Service的请求转发到后端多个pod实例
默认负载均衡策略是轮询

5.2 实现细节

kube-proxy检查和监听APIServer中Service与Endpoint的变化
kube-proxy为每个service都建立服务代理对象
服务代理对象是kube-proxy的数据结构,内部包含SocketServer,用来接收请求
kube-proxy内部也创建一个负载均衡器LoadBalance
LoadBalance保存service到endpoint的动态转发路由表

三. 网络原理

  1. k8s网络模型
    1.1 k8s网络模型的原则:

每个pod都拥有唯一个独立的ip地址,称Ip-Per-Pod模型
所有pod都在一个可连通的网络环境中
不管是否在同一个node,都可以通过ip直接通讯
pod被看作一台独立的物理机或虚拟机

目前原生docker和kubernetes还不能打通容器与容器的通讯,以支持该模型,必须依靠第三方网络插件实现,比如:flannel

1.2 设计这个原则的原因:

用户不需要额外考虑如何建立pod之间的连接
用户不需要考虑将容器端口映射到主机端口的问题
可以兼容过去跑在宿主机和KVM的应用

1.3 Ip-Per-Pod与Docker端口映射的区别

docker:端口映射到宿主机会引入端口管理的复杂性
docker:最终被访问的ip和端口,与提供的不一致,引起配置的复杂性

  1. docker网络基础
    docker技术依赖于linux内核虚拟化技术的发展,对linux内核特性有很强依赖。docker用到的linux技术包括:

network namespace
veth设备对
iptables、netfliter
网桥
路由

2.1 netork namespace

为了支持网络协议栈多个实例,linux在网络栈中引入了命名空间
处于不同命名空间的网络栈是彼此隔离,无法通信的
为了隔离协议栈,需要纳入命名空间的元素有:

进程
套接字
网络设备

实现核心:

将全局变量变为net namespace的成员
函数都加入namespace的参数

2.2 veth设备对

veth可以将两个命名空间连通,实现通信
veth设备成对出现,像一根管子,连通两端

2.3 网桥

网桥将liunx不同的端口连接起来,实现多对多通信
网桥解析收到的报文,读取mac地址,决定转发的端口
网桥的实现:

通过一个虚拟的网桥设备实现桥接
虚拟设备可以绑定多个以太网设备
虚拟网桥充当代理的角色

2.4 iptables/netfilter

linux提供一套机制对网络协议栈中关心的数据进行操作
实现:通过回调函数的挂载点,挂接钩子函数对数据进行过滤、修改、丢弃等操作。挂节点技术叫iptables和netfilter
netfilter工作在内核模式,执行各种挂接规则
iptables工作在用户模式的进程,协助维护netfilter规则表

2.5 路由

ip层处理数据或转发时,会使用路由表决定发往哪里
路由功能由ip层维护的路由表实现
路由表格式:

目的ip地址:主机地址或网络地址
下一个路由器的ip地址
标志:下一个路由器是真实路由还是直连端口、目的ip是主机地址还是网络地址等
网络接口规范:与报文一起转发

路由查看:ip route list

  1. Docker的网桥实现
    标准docker支持四种网络模式:

host模式
container模式
none模式
bridge模式,默认模式

3.1 docker的Bridge网桥模型

docker第一次启动时,会创建虚拟网桥docker0
为docker0分配一个子网
docker创建每个容器时,会创建veth设备对,一端关联到网桥上,另一端使用linux的网络命名空间技术连接到容器内,并给容器内eth0设备分配一个ip地址

docker网络模型

在这里插入图片描述
3.2 Docker网络的局限性

Docker网络模型没有考虑到多主机互联的网络解决方案,崇尚简单为美
同一机器内的容器之间可以直接通讯,但是不同机器直接容器无法通讯
为了跨节点通讯,必须在主机的地址上分配端口,通过端口路由或代理到容器
分配和管理容器特别困难,特别是水平扩展时

  1. K8s的网络实现
    k8s网络实现

在这里插入图片描述
4.1 容器与容器的通讯

同一个容器的pod直接共享同一个linux协议栈
就像在同一台机器上,可通过localhost访问
可类比一个物理机上不同应用程序的情况

4.2 pod与pod的通讯
同一Node内的pod之间通讯

同一Node内的pod都是通过veth连接在同一个docker0网桥上,地址段相同,所以可以直接通讯

不同Node的pod之间通讯

docker0网段与宿主机不在同一个网段,所以不同pod之间的pod不能直接通讯
不同node之间通讯只能通过宿主机物理网卡
前面说过k8s网络模型需要不同的pod之间能通讯,所以ip不能重复,这就要求k8s部署时要规划好docker0的网段
同时,要记录每个pod的ip地址挂在哪个具体的node上
为了达到这个目的,有很多开源软件增强了docker和k8s的网络

  1. 开源网络组件
    5.1 Flannel
    实现的功能

协助k8s给每个Node上的docker容器分配互不冲突的ip地址
能在这些ip地址之间建立覆盖网络(Overlay Network),将数据传递到目标容器

底层原理

Flannel创建名为flannel0的网桥
flannel0网桥一端连接docker0网桥,另一端连接flanneld进程
flanneld进程一端连接etcd,利用etcd管理分配的ip地址资源,同时监控pod地址,建立pod节点路由表
flanneld进程一端连接docker0和物理网络,配合路由表,完成数据包投递,完成pod之间通讯

缺点

引入多个网络组件,带来网络时延和损耗
默认使用udp作为底层传输协议,具有不可靠性

5.2 其他网络组件

Open vSwitch
Calico

作者:kinnylee
链接:https://juejin.im/post/6844903893957083149
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值