《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命令能够查看node

1.4 工做原理

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

为了缓解集群访问压力,各模块都使用缓存,按期从ApiServer获取资源信息,保存到本地linux

2. 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被建立

3. Scheduler

3.1 概述

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

3.2 默认调度流程

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

3.3 预选策略

  • 默认的预选策略包括5个维度的筛选,只有都经过了才做为候选节点
  • 预选策略说明:
    • NoDiskConfilct:Volume相关冲突检测
    • PodFitsResources:资源是否知足的检测
    • PodSelectorMatches:pod标签选择器的检测
    • PodFitsHost:是否指定被调度到特定Node的检测
    • CheckNodeLabelPresense:判断label设定备选节点时,是否选择备选节点

3.4 优选策略

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

4. 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的变化:docker

  • 若是发现有新的绑定到该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,文件,内存等指标信息

5. 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和端口,与提供的不一致,引发配置的复杂性

2. docker网络基础

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

  • 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

3. Docker的网桥实现

标准docker支持四种网络模式:缓存

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

3.1 docker的Bridge网桥模型

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

docker网络模型安全

3.2 Docker网络的局限性

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

4. 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的网络

5. 开源网络组件

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
相关文章
相关标签/搜索