Kubernetes基础概念及组件、POD、网络通信方式
Kubernetes基础概念及组件
基础概念
Kubernetes(简称 K8S) 的出现是容器化技术发展的必然结果,一些流行的开源容器编排工具有 Docker Swarm、Apache Mesos、Kubernetes 等,但是在发展过程中 Kubernetes 现在已经成为了容器编排领域上的一个标准了。
Kubernetes 是 Google 团队发起的一个开源项目,它的目标是管理跨多个主机的容器,用于自动部署、扩展和管理容器化的应用程序,主要实现语言为 Go 语言
# 优势:
轻量级、开源、弹性伸缩、负载均衡
# 相关网站:
Kubernetes (k8s) 官网:https://kubernetes.io/
Kubernetes (k8s) 官方文档:https://kubernetes.io/docs/home/
Kubernetes(k8s)中文文档:https://www.kubernetes.org.cn/k8s
Kubernetes (k8s) 中文社区:https://www.kubernetes.org.cn/tags/cncf
整体架构
Kubernetes 由 Master 和 Node 两种节点组成,这两种角色分别对应着控制节点和工作节点。
Master 节点由三个独立的组件组成,它们分别是负责整个'集群通信'的 API 服务的 'kube-apiserver'、负责'容器调度'的 'kube-scheduler' 以及负责'维护集群状态'的 'kube-controller-manager' 组件。整个集群的数据都是通过 kube-apiserver 保存到 etcd 数据库中的,而其他所有组件的通信也都是通过 kube-apiserver 和 etcd 数据库进行通信的,都不会直接和 etcd 进行通信。
工作节点上最核心的组件就是 'kubelet',主要用来'实现和底层的容器运行时进行通信的',这个通信的过程被 Kubernetes 抽象成了一个 'CRI'(Container Runtime Interface)的'远程调用接口',这个接口里面定义了容器运行时的所有标准操作.只要你这个容器运行时可以实现 CRI 接口就可以被 Kubernetes 来管理.
kubelet 的另外一个重要功能就是调用网络插件(CNI)和存储插件(CSI)为容器配置网络和存储功能,同样的 kubelet 也是把这两个重要功能通过接口暴露给外部了,所以如果我们想要实现自己的网络插件,只需要使用 CNI 就可以很方便的对接到 Kubernetes 集群当中去。
ETCD
etcd 的官方将它定位成一个可信赖的分布式键值存储服务,它能够为整个分布式集群存储一些关键数据,协助分布式集群的正常运转
Raft 从一开始就被设计成一个易于理解和实现的共识算法。每一个 Raft 集群中都包含多个服务器,在任意时刻,每一台服务器只可能处于 Leader、Follower 以及 Candidate 三种状态;在处于正常的状态时,集群中只会存在一个 Leader,其余的服务器都是 Follower
基础组件
kube-apiserver
Server 作为 Kubernetes 系统的入口,封装了核心对象的增删改查操作,API Server 以 RESTFul 接口方式提供给外部客户端和内部组件调用,维护的 REST 对象持久化到 Etcd 中存储。
kube-controller-manager
用于实现 Kubernetes 集群故障检测和恢复的自动化工作,负责维护集群的状态,如:故障检测,自动扩展,滚动更新等。新建立的 Pod 进行节点 (node) 选择(即分配机器),负责集群的资源调度。组件抽离,可以方便替换成其他调度器。
kube-scheduler
Scheduler 是负责整个集群的资源调度的,
kubelet
kubelet 是负责容器真正运行的核心组件,负责维护容器的生命周期,同时也负责Volume(CSI)和网络(CNI)的管理
kube-proxy
负责为Server提供cluster内部的服务发现和负载均衡,kube-proxy 是为了解决外部网络能够访问集群中容器提供的应用服务而设计的,Proxy 运行在每个Node 上。
kubectl
Kubectl 是 Kubernetes 的集群管理命令行客户端工具集。通过 Kubectl 命令对 API Server 进行操作,API Server 响应并返回对应的命令结果,从而达到对 Kubernetes 集群的管理
Container runtime
负责镜像管理以及Pod和容器的真正运行(CRI)。
CoreDNS
负责为整个集群提供DNS
Ingress Controller
为Kubernetns中的服务提供外网入口
Prometheus
为整个集群提供资源监控能力,未来监控的标准。
Dashboard
提供 B/S 的访问体系,允许用户通过 web 进行集群管理及设置
Federation
提供跨可用区的集群,提供不同数据中心的 K8S 集群的管理能力
POD概念
Pod定义、原理
Pod是Kubernetes 最基本的调度单元。
pod也是一个容器,装载就是docker创建的容器,pod用来封装容器的一个容器,pod是一个虚拟化分组,有自己的ip和主机名,相当于一个独立的沙箱环境。
pod相当于独立主机,可以封装一个或者多个容器。
pod的作用:在部署的时候,使用pod来管理一组相关的服务---一个pod中要么部署一个服务,要么部署一组相关服务。
一组相关服务:nginx,web,MySQL等待----在吊式链路上的服务
实现集群:实现多个pod的副本
K8S扩容---就是POD的数量增加
pause容器---------共享网络,共享存储,一组容器访问是通过localhost
pod的底层:创建容器之前,必须创建pause
POD类型创建方式
# 自主式 pod
简单自我管理,不具备自愈功能
# 控制器管理的 Pod
无状态服务 有状态服务
无状态服务:RC、RS、Deployment、Daemonset、job、Cronjob
有状态服务:Statefulset
守护进程、脚本处理
守护进程:RC、RS、Deployment、Daemonset、statefulSet
脚本:job 、cronjob
有且只有一个节点运行:Daemonset
POD控制器类型
RC RS Deployment HPA
ReplicationController 用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的 Pod 来替代;而如果异常多出来的容器也会自动回收,在新版本的 Kubernetes 中建议使用 ReplicaSet 来取代 ReplicationControlle
ReplicaSet 跟 ReplicationController 没有本质的不同,只是名字不一样,并且 ReplicaSet 支持集合式的 selector
虽然 ReplicaSet 可以独立使用,但一般还是建议使用 Deployment 来自动管理 ReplicaSet ,这样就无需担心跟其他机制的不兼容问题(比如 ReplicaSet 不支持 rolling-update 但 Deployment 支持)
Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义 (declarative) 方法,用来替代以前的 ReplicationController 来方便的管理应用。典型的应用场景包括
# 定义 Deployment 来创建 Pod 和 ReplicaSet
# 滚动升级和回滚应用
# 扩容和缩容
# 暂停和继续 Deployment
Horizontal Pod Autoscaling 仅适用于 Deployment 和 ReplicaSet ,在 V1 版本中仅支持根据 Pod 的 CPU 利用率扩所容,在 v1alpha 版本中,支持根据内存和用户自定义的 metric 扩缩容
SstatefulSet
StatefulSet 是为了解决有状态服务的问题(对应 Deployments 和 ReplicaSets 是为无状态服务而设计),其应用场景包括:
'稳定的持久化存储',即 Pod 重新调度后还是能访问到相同的持久化数据,基于 PVC 来实现
'稳定的网络标志',即 Pod 重新调度后其 PodName 和 HostName 不变,基于 Headless Service (即没有 Cluster IP 的 Service )来实现
'有序部署',有序扩展,即 Pod 是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从 0 到 N-1,在下一个 Pod 运行之前所有之前的 Pod 必须都是 Running 和 Ready 状态),基于 init containers 来实现
'有序收缩',有序删除(即从 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
Job Cronjob
Job 负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个 Pod 成功结束
# Cron Job管理基于时间的Job,即:
在给定时间点只运行一次
周期性地在给定时间点运行
网络通讯方式
网络通讯模式
Kubernetes 的网络模型假定了所有 Pod 都在一个可以直接连通的扁平的网络空间中,这在 GCE(Google Compute Engine)里面是现成的网络模型,Kubernetes 假定这个网络已经存在。而在私有云里搭建 Kubernetes 集群,就不能假定这个网络已经存在了。我们需要自己实现这个网络假设,将不同节点上的 Docker 容器之间的互相访问先打通,然后运行 Kubernetes
同一个 Pod 内的多个容器之间:lo(回环接口)
各 Pod 之间的通讯:Overlay Network
Pod 与 Service 之间的通讯:各节点的 Iptables 规则
1.14 iptables
1.15 ipvs
网络解决模式 Kubernetes + Flannel
Flannel 是 CoreOS 团队针对 Kubernetes 设计的一个网络规划服务,简单来说,它的功能是'让集群中的不同节点主机'创建的 Docker 容器都'具有全集群唯一的虚拟IP地址'。而且它还能在这些 IP 地址之间建立一个覆盖网络(Overlay Network),通过这个覆盖网络,将数据包原封不动地传递到目标容器内
# ETCD 之 Flannel 提供说明:
存储管理 Flannel 可分配的 IP 地址段资源
监控 ETCD 中每个 Pod 的实际地址,并在内存中建立维护 Pod 节点路由表
不同情况的网络通讯方式
同一个 Pod 内部通讯:同一个 Pod 共享同一个网络命名空间,共享同一个 Linux 协议栈Pod1 至 Pod2
Pod1 与 Pod2 不在同一台主机,Pod的地址是与docker0在同一个网段的,但docker0网段与宿主机网卡是两个完全不同的IP网段,并且不同Node之间的通信只能通过宿主机的物理网卡进行。将Pod的IP和所在Node的IP关联起来,通过这个关联让Pod可以互相访问
Pod1 与 Pod2 在同一台机器,由 Docker0 网桥直接转发请求至 Pod2,不需要经过 Flannel
演示
Pod 至 Service 的网络:目前基于性能考虑,全部为 iptables 维护和转发ipvs
Pod 到外网:Pod 向外网发送请求,查找路由表, 转发数据包到宿主机的网卡,宿主网卡完成路由选择后,iptables执行Masquerade,把源 IP 更改为宿主网卡的 IP,然后向外网服务器发送请求
Kubernetes 网络状态
Kubernetes 默认没有覆盖性网络,后期可以通过一些开源项目补全,比如 flannel calios
Pod 间的不同容器:lo(可以参考 docker run --network container:xxx )
Pod 间的互相访问
同主机:通过 Docker0 进行数据报文转发,Pod 间速率最大化,后期项目的优化也基于此点
跨主机:通过网络插件,实现扁平化网络,比如 flannel 通过 UDP 数据报文二次封装,以及 etcd 与 flannel 维护的路由表进行数据报文传递
注:本文为博主查阅多方资料整理而成,如有侵权请留言联系博主删除。
学习新东西,不要忘记复习旧知识,这样你才能更好!