Kubernetes Pod概念与网络通讯模式

前身:Google通过go语言对Borg进行编写开发出K8S,K8s采用HTTP协议进行C/S结构的开发

Kubernetes 特点

  • 轻量级:消耗资源小
  • 开源
  • 弹性伸缩
  • 负载均衡:IPVS

要掌握的知识点

  • 基础概念:什么是Pod,控制器类型,K8s网络通讯模式,

  • Kubernetes安装:构建K8S集群

  • 资源清单:资源,掌握资源清单的语法,编写Pod,掌握Pod的生命周期

  • Pod控制器:掌握各种控制器的特点以及使用定义方式

  • 服务发现:掌握SVC原理及其构建方式

  • 存储:掌握多种存储类型的特点,并且能够在不同环境中选择合适的存储方案。(有自己的见解)

  • 调度器:掌握调度器原理,能够根据要求把Pod定义到想要的节点运行

  • 安全:集群的认证、鉴权、访问控制原理及其流程

  • HELM:就像Linux yum命令,HELM是部署集群,掌握HELM原理,HELM模板自定义,HELM部署一些常用的插件

  • 运维:修改Kubeadm 达到证书可用期限为10年,能够构建高可用的集群

服务分类

  • 有状态服务:DBMS
  • 无状态服务:LVS、APACHE

etcd的官方将它定位成一个可信赖的分布式键值存储服务务,它能够为整个分布式集群存储一些关键数据,协助分布式集群的正常运转
etcd v2会把数据写入到内存中
etcd v3会引入本地卷持久化操作

ETCD是K8s集群中一个重要的存储
在这里插入图片描述

kublet、kube proxy、container
kublet会与docker进行交互,操作docker去创建对应的容器,kublet会维持pod的生命周期。
kube proxy可以监听负载操作,操作防火墙,实现pod的映射。

高可用集群副本数据最好是 >=3

主要组件:

  • API SERVER:所有服务访问统一入口
  • CrontrollerManager:维持副本期望数目
  • Scheduler:负责介绍人物,选择合适的节点进行分配任务
  • ETCD:键值对数据库,存储K8S集群所有重要信息(持久化)
  • Kublet:直接跟容器引擎交互实现容器的生命周期管理
  • Kube-proxy:负责写入规则至IPTABLES、IPVS实现服务器映射访问的

其他插件说明

  • COREDNS:可以为集群中的SVC创建一个域名IP的对应关系解析
  • DASHBOARD:给K8s集群提供一个B/S结构访问体系
  • INGRESS CONTROLLER:官方只能石实现四层代理,INGRESS可以实现七层代理
  • FEDETATION:提供一个可以跨集群中心多K8S统一管理功能
  • Prometheus:提供K8s集群的监控能力
  • ELK:提供K8s集群日志统一分析介入平台

Pod概念

一个Pod封装多个容器,两个Pod共用Pause的网络栈(意味着两个Pod没有自己独立的IP地址)。

Pause是pod的根容器,pod中所有的container共享pod的网络栈和挂载存储
在这里插入图片描述

Pod控制类型

控制器概念
k8s中内建了很多controller(控制器),这些相当于一个状态机,用来控制Pod的具体状态和行为

生命周期不同分类

  • 自主式Pod:Pod退出了,此类型的Pod不会被创建

  • 控制器管理的Pod:在控制器的生命周期里,始终要维持Pod的副本数目

ReplicationController&ReplicaSet&Deplovment

ReplicationController(RC)用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的Pod来替代;而如果异常多出来的容器也会自动回收。
在新版本的Kubernetes中建议使用ReplicaSet来取代ReplicationControlle

ReplicaSet跟ReplicationController没有本质的不同,只是名字不一样,并且ReplicaSet 支持集合式的 selector(创建pod的时候会打上标签,但有一天想删除,修改的时候,RS就支持这种方案。RC不支持。)

虽然ReplicaSet 可以独立使用,但一般还是建议使用Deployment来自动管理ReplicaSet,这样就无需担心跟其他机制的不兼容问题(比如ReplicaSet不支持rolling-update但Deployment 支持)
(达到滚动更新,回滚操作)

Deployment是通过rs去管理Pod的
在这里插入图片描述

★Deployment

Deployment为Pod和ReplicaSet提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController来方便的管理应用。典型的应用场景包括:

  • 定义Deployment来创建Pod和ReplicaSet
  • 滚动升级和回滚应用
  • 扩容和缩容
  • 暂停和继续 Deployment

声明式例子,如mysql创建数据库,无需告知具体步骤:
mysql的create database xx

声明式(Delpoyment):apply(优) create
命令式(rs):create(优) apply

Deployment是通过rs去管理Pod的
在这里插入图片描述

滚动更新和回滚操作原理图(删除的时候把副本数目降低)
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

HPA(HorizontalPodAutoScale)

Horizontal Pod Autoscaling 仅适用于Deployment和ReplicaSet,在V1版本中仅支持根据Pod的CPU利用率扩所容,在vlalpha版本中,支持根据内存和用户自定义的metric扩缩容
(达到水平自动扩展)

StatefullSet

Docker主要面对的是无状态服务,无状态服务即含义没有对应的存储需要实时保留,如Apache、LVS调度器。

有状态服务,MySQL,MongoDB,需要实时的进行数据的更新及存储。

StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为无状态服务而设计),其应用场景包括:

  • 稳定的持久化存储,即Pod 重新调度后还是能访问到相同的持久化数据,基于PVC来实现
  • 稳定的网络标志,即Pod 重新调度后其PodName和HostName不变,基于Headless Service
    (即没有ClusterIP的Service)来实现
  • 有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现
    (为什么不是start stop readiness实现?原因是它们需要更改pod内部容器的镜像,但对于init container来说是不需要更改的。只需要在pod容器运行之前加init C,并不会对原有Pod结构发生改变)
  • 有序收缩,有序删除(即从N-1到0

DaemonSet

DaemonSet确保全部(或者一些)Node上运行一个Pod的副本。当有Node加入集群时,也会为他们新增一个Pod。当有Node 从集群移除时,这些Pod也会被回收。删除DaemonSet 将会删除它创建的所有Pod

使用DaemonSet的一些典型用法:

  • 运行集群存储 daemon,例如在每个Node上运行glusterd、ceph。
  • 在每个Node上运行日志收集daemon,例如fluentd、logstash。
  • 在每个Node上运行监控daemon,例如Prometheus Node Exporter。(Zabbix监控每一个node)

Job,Cronjob

contab没有脚本纠错能力
Job会有自己的纠错能力,如果在运行的脚本没有以0状态码退出的话,会重新执行这个程序

Job负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束
Job的生命周期是等于Pod运行成功数目

Cron Job管理基于时间的Job(在特定的时间循环创建Job),即:

  • 在给定时间点只运行一次
  • 周期性地在给定时间点运行,例如:数据库备份、发送邮件

总结:

  • 需要无状态服务部署到RS、Deployment
  • 需要以node为节点的,部署到DaemonSet
  • 需要批处理任务的,部署到Job和CronJob
  • 需要有状态服务,部署到StatefulSet
  • HPA就像是一个控制器的附属品,比如先部署了Deployment,再去创建个HPA去管理Deployment,可以实现自动的扩容收发,比如CPU大于60%的时候,扩容到10个节点。
    (K8s默认是不支持这种的,需要有一个资源收集方案,给HPA提供一个性能指标)

Docker主要面对的是无状态服务,无状态服务即含义没有对应的存储需要实时保留,如Apache、LVS调度器。
有状态服务,MySQL,MongoDB,需要实时的进行数据的更新及存储。

服务发现

service去收集Pod是通过标签选择得到的
在这里插入图片描述

网络通讯模式

网络通讯模式说明

网络通讯模式 - 1
Kubernetes的网络模型假定了所有Pod都在一个可以直接连通的扁平的网络空间(所有的Pod都可以通过对方的IP直接到达)中,这在GCE(Google Compute Engine)里面是现成的网络模型,Kubernetes假定这个网络已经存在。
而在私有云里搭建Kubernetes集群,就不能假定这个网络已经存在了。我们需要自己实现这个网络假设,将不同节点上的Docker容器之间的互相访问先打通,然后运行Kubernetes

网络通讯模式 - 2

  • 同一个Pod内的多个容器之间:lo,同一个Pod中的容器通过Pause容器网络栈的网卡lo进行访问
  • 各Pod之间的通讯:Overlay Network
  • Pod 与Service之间的通讯:各节点的Iptables规则

网络解决方案 Kubernetes + Flannel

Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址。而且它还能在这些IP地址之间建立一个覆盖网络(Overlay Network),通过这个覆盖网络,将数据包原封不动地传递到目标容器内

backend是访问池,图中的Destination是192.168.66.12
Flanneld开启网桥Flannel0,专门收集Docker0转发出来的数据报
在这里插入图片描述

ETCD之Flannel提供说明:

  • 存储管理Flannel 可分配的IP地址段资源
    (即Flannel启动之后会向ETCD去插入可以被分配的网段,记录分配网段的机器,防止已分配的网段被Flannel利用出现IP冲突。)
  • 监控ETCD中每个Pod的实际地址,并在内存中建立维护Pod节点路由表
    (即根据Pod节点路由表,Pod网段10.1.15.0/24对应的物理主机是192.168.66.11)

不同情况下网络通信方式

同一个Pod内部通讯: 同一个Pod共享同一个网络命名空间,共享同一个Linux协议栈,共享Pause协议栈,通过localhost回环网卡通讯

Pod1至Pod2

Pod1与Pod2不在同一台主机,Pod的地址是与docker0在同一个网段的,但docker0网段与宿主机网卡是两个完全不同的IP网段,并且不同Node之间的通信只能通过宿主机的物理网卡进行。将Pod的IP和所在Node的IP关联起来,通过这个关联让Pod可以互相访问(上面图是其实就代表了不同主机之间的访问)
 
Pod1与Pod2在同一台机器,由Docker0网桥直接转发请求至Pod2,不需要经过Flannel

Pod1与Pod2在同一台机器的情况
在这里插入图片描述

Pod至Service的网络: 目前基于性能考虑,全部为iptables或LVS维护和转发

Pod 到外网: Pod向外网发送请求,查找路由表,转发数据包到宿主机的网卡,宿主网卡完成路由选择后,iptables执行Masquerade,把源IP更改为宿主网卡的IP,然后向外网服务器发送请求

MASQUERADE,地址伪装,算是snat中的一种特例,可以实现自动化的snat。

外网访问Pod: Service

组件通讯模式说明

真实的网络只有一个:节点网络
虚拟网络:Pod网络,Service网络
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_39578545/article/details/106031623