[TOC]
描述:Docker是一个开放源代码软件项目(开源的应用容器引擎
),让应用程序部署在软件货柜下的工作可以自动化进行,借此在Linux操作系统上,提供一个额外的软件抽象层,以及操作系统层虚拟化
的自动管理机制。
补充说明:
此处Kubernetes使用的容器技术来创建容器。
描述:etcd 是兼具一致性和高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库。
是集群所有组件当中唯一一个有状态服务
,对于高可用的集群建议采用 3 或 5 节点的 etcd 集群。
关于etcd进一步学习请参考: Etcd基础学习之架构及工作原理
Q:什么是Kubernetes? A:Kubernetes(k8s)是自动化容器操作的开源平台,这些操作包括部署,调度和节点集群间扩展, 可以将K8s看做Docker容器技术的上层插件,它不仅仅支持Docker还支持Rocket容器技术;
功能作用:
自动化容器的部署和复制
随时扩展或收缩容器规模
将容器组织成组,并且提供容器间的负载均衡
很容易地升级应用程序容器的新版本
提供容器弹性,Node节点故障业务系统自动恢复,如果容器失效就替换它,等等
K8s架构一览图:
WeiyiGeek.架构
k8s与vSphere之间的对比:
Postgresql / oralce
)里面存放了集群中所有虚拟机以及集群有关的信息
,而K8s中则是采用etcd数据库它用来持久化存储k8s集群中所有资源的信息
。vCenter 相当于主节点、管理节点、控制节点
,是一个控制平面,而 ESXi 主机则是工作节点、虚拟机运行的节点,是应用负载的一个平面。WeiyiGeek.
描述:集群是一组节点,这些节点可以是物理服务器或者虚拟机,之上安装了Kubernetes平台
典型的Kubernetes架构图:
WeiyiGeek.
描述: Kubernetes Master提供集群的独特视角,且集群需要一个以上的Master节点;
Master 节点作用:
描述:它是 Kubernetes 控制面的前端,主节点上负责提供 Kubernetes API 服务的组件
API-Server作为K8s最核心的组件,其他组件(kubelet、kubectl、调度器、控制器管理器等
)都会去调用它。
应用场景:
API-Server 接收到请求后会先经过一系列安全防护的处理,包括授权插件和准入控制插件
控制平面可以请求订阅资源被创建、修改或删除的通知, 这使得组件可以在集群元数据变化时候执行任何需要做的任务。
客户端通过创建到 API 服务器的 HTTP 连接来监听变更。通过此连接,客户端会接收到监听对象的一系列变更通知,当更新对象时 API 服务器给所有监听者发送更新过的对象:
描述: 该组件运行在Master节点之上监视那些新创建的未指定运行节点的Pod,并选择节点让 Pod 在上面运行。
我们通常不会去指定 pod 应该运行在哪个集群节点上而是将这项工作交给调度器。
API-server 更新 pod 的定义
然后 API server 再去通知 Kubelet
,当目标节点上的 Kubelet 发现该 pod 被调度到本节点,它就会创建并且运行 pod 的容器;调度器为 pod 查找可用节点需要检查关键项:
schedulerName
来设置指定的调度器。描述:API server 只做了存储资源到 etcd 和通知客户端有变更的工作。调度器则只是给 pod 分配节点,所以需要有活跃的组件确保系统真实状态的 API 服务器定义的期望的状态收敛
,该工作由控制器管理器里的控制器来实现;
k8s 内部的控制工作都通过 APIServer 这一声明式的数据存储进行了解耦,而控制器就是复杂保持各个不同资源间一致性的一种异步的管理工具。
控制器做了许多不同的事情,但是它们都通过 API 服务器监听资源(部署、服务等)变更
,并且不论是创建新对象还是更新、删除已有对象,都对变更执行相应操作。
大多数情况下,这些操作涵盖了新建其他资源或者更新监听的资源本身(例如更新对象的 status)。
调和
循环,将实际状态调整为期望状态(在资源 spec 部分定义),然后将新的实际状态写入资源的 status 部分。控制器利用监听机制来订阅变更, 但是由于使用监听机制并不保证控制器不会漏掉时间,所以仍然需要定期执行重列举操作来确保不会丢掉什么。
不会直接和 kubelet 通信或者发送任何类型的指令
。控制器更新 APIServer 的一个资源后,kubelet 会负责做它该做的工作(它通过监听 APIServer 获取变更),所以Kubelet与控制器都不知道对方的存在;
Kubernetes 在 kube-controller-manager 中运行了大量的内建控制器(例如,Deployment Controller、Job Controller、StatefulSet Controller、DaemonSet Controller 等)。这些内建控制器提供了 Kubernetes 非常重要的核心功能。Kubernetes 可以运行一个 master 集群,以实现内建控制器的高可用。
描述:Replication Controller(简称RC
)确保任意时间都有指定数量的Pod“副本”在运行;当创建RC时,需要指定两个东西:
RC示例图:
RC
补充说明:
类比这样方式缩小Pod,该特性在执行滚动升级时很有用
)注意事项:
描述:Worker节点(Node)是k8s中的工作计算机,可能是VM或物理计算机,具体取决于群集。
补充说明:
描述:Node(节点)是 kubernetes 集群中的计算机,可以是虚拟机或物理机,它由master进行管理;
PS: Worker 节点 等同于 Node 节点
比如下图:显示一个Node(节点)上含有4个 Pod(容器组)
WeiyiGeek.
补充说明:
自动调度 Pod(容器组)到最佳的 Node(节点)上
。注意事项:
负责下载镜像、创建和运行容器等
。 描述:负责 master 节点和 worker 节点之间通信的进程(node processes), 管理 Pod(容器组)和 Pod(容器组)内运行的 Container(容器); 简单地说 Kubelet 就是负责所有运行在工作节点上内容的组件。 它第一个任务就是在 API 服务器中创建一个 Node 资源来注册该节点。然后需要持续监控 API 服务器是否把该节点分配给 pod 然后启动 pod 容器。
具体实现方式是告知配置好的容器运行时(Docker、CoreOS 的 Rkt,或者其他一些东西)来从特定容器镜像运行容器。
描述:Kube-prxoy是运行在每个工作节点上,用于确保客户端可以通过 kubernetes API 连接到你定义的服务。 kube-proxy 确保对服务 IP 和端口的连接最终能够到达支持服务的某个pod,如果有多个 pod 它还负责做负载均衡。
kube-proxy 服务去 watch kubernetes 集群的Service
和Endpoint
对象,当这两个资源对象有状态变化时,会把它们保存在ServiceMap
和EndPonintMap
中,然后会通过async.BoundedFrequencyRunner
去异步的执行syncProxyRules
去下发规则。
kube-proxy在使用iptables和ipvs实现对Service的负载均衡区别?
时间复杂度为O(n)
。具体的性能对比可以参照 kube-proxy 模式对比iptables 还是 IPVS 文章
描述: Pod 容器组是k8s中的一个抽象的概念,它是集群上的最基本的单元
且总是在 Node 节点上运行
,用于存放应用程序实例的container(可包含一个或多个 container 容器
)以及这些 container (容器)的一些共享资源;
在这里补充一下Pod与容器间的关系? 容器的设计原则就是为了隔离,即在单一的容器内运行单一的进程,而 Pod 将这些单一的进程聚集在一起。从某种程度上来说这样的 Pod 就像是运行多个进程的操作系统,而比操作系统更加轻量。
共享资源包括:
共享该IP地址
;WeiyiGeek.Pods概述
补充说明:
它将应用的容器、存储资源以及独立的网络 IP 地址等资源打包到了一起
;示例解释:
假定有2个后台Pod,并且定义后台Service的名称为backend-service,label选择器为(tier=backend, app=myapp)
的Service会完成如下两件重要的事情:
通过每个Node上运行的代理(kube-proxy)完成
);下述动画展示了Service的功能:
功能
注意事项:
可用节点(Node)上运行相同的 Pod
(从同样的镜像创建 Container,使用同样的配置但是IP 地址不同,Pod 名字不同
)。使用 localhost + 端口号互相访问
,同时同一个Pod内的容器端口不能冲突;F&Q
(1) 如果Pod是短暂的,那么我怎么才能持久化容器数据使其能够跨重启而存在呢?
(2) 是否手动创建Pod,如果想要创建同一个容器的多份拷贝,需要一个个分别创建出来么?
(3) 如果Pod是短暂的,那么重启时IP地址可能会改变,那么怎么才能从前端容器正确可靠地指向后台容器呢?
描述:Services(服务)是分布式集群架构的核心, 并且Kubernetes 中的 Service(服务) 提供了这样的一个抽象层,它选择具备某些特征的 Pod(容器组)并为它们定义一个访问方式。
它通过 LabelSelector
选择了一组 Pod(容器组),把这些 Pod 的指定端口公布到到集群外部,并支持负载均衡和服务发现。
作用:
原本从一个 Pod 中访问另外一个 Pod,需要知道对方的 IP 地址
),公布 Pod 的端口以使其可访问;示例:下图中有两个服务Service A(黄色虚线)和Service B(蓝色虚线)
WeiyiGeek.services
补充说明:
LabelSelector(标签选择器)
来决定。在容器组失效后重新创建容器组,增加或者减少同一个 Deployment 对应容器组的数量等
)。描述: 通过在Deployment的yaml文件中配置Labels标签,可以灵活定位一个或多个资源;Label是attach到Pod的一对键/值对组成,用来传递用户定义的属性,可以使用 Selectors 选择带有特定Label的Pod,并且将Service或者Replication Controller应用到上面。
示例:你可能创建了一个”tier”和“app”标签,通过Label(tier=frontend, app=myapp)
来标记前端Pod容器,使用Label(tier=backend, app=myapp)
标记后台Pod。
补充说明:
描述:Service使用 Labels、LabelSelector(标签和选择器)
匹配一组 Pod。Labels(标签)是附加到 Kubernetes 对象的键/值对;
标签用途有多种:
区别不同应用软件版本
示例:下图体现了 Labels(标签)和 LabelSelector(标签选择器)之间的关联关系:
通过 Deployment B 创建的 Pod 包含标签为 app=B
)WeiyiGeek.LabelSelector
补充说明:
描述:对于K8s初学者来说K8s中各工作节点与Pod中网络的配置就会让您欲仙欲死,所以这里我们需要对其有个大致了解即可;
简单图解(从下往上):
WeiyiGeek.网络模型示意图
(1) v1.19.3 api 资源对象一览 描述: api-resources 名称下需要非常注意SHORTNAMES(别名)已经所属对象以及APIGROUP和是否可用使用NAMESPACE名称空间进行隔离限制;
$ kubectl api-resources
# NAME SHORTNAMES APIGROUP NAMESPACED KIND
# bindings true Binding
# componentstatuses cs false ComponentStatus
# configmaps cm true ConfigMap
# endpoints ep true Endpoints
# events ev true Event
# limitranges limits true LimitRange
# namespaces ns false Namespace
# nodes no false Node
# persistentvolumeclaims pvc true PersistentVolumeClaim
# persistentvolumes pv false PersistentVolume
# pods po true Pod
# podtemplates true PodTemplate
# replicationcontrollers rc true ReplicationController
# resourcequotas quota true ResourceQuota
# secrets true Secret
# serviceaccounts sa true ServiceAccount
# services svc true Service
# mutatingwebhookconfigurations admissionregistration.k8s.io false MutatingWebhookConfiguration
# validatingwebhookconfigurations admissionregistration.k8s.io false ValidatingWebhookConfiguration
# customresourcedefinitions crd,crds apiextensions.k8s.io false CustomResourceDefinition
# apiservices apiregistration.k8s.io false APIService
# controllerrevisions apps true ControllerRevision
# daemonsets ds apps true DaemonSet
# deployments deploy apps true Deployment
# replicasets rs apps true ReplicaSet
# statefulsets sts apps true StatefulSet
# tokenreviews authentication.k8s.io false TokenReview
# localsubjectaccessreviews authorization.k8s.io true LocalSubjectAccessReview
# selfsubjectaccessreviews authorization.k8s.io false SelfSubjectAccessReview
# selfsubjectrulesreviews authorization.k8s.io false SelfSubjectRulesReview
# subjectaccessreviews authorization.k8s.io false SubjectAccessReview
# horizontalpodautoscalers hpa autoscaling true HorizontalPodAutoscaler
# cronjobs cj batch true CronJob
# jobs batch true Job
# certificatesigningrequests csr certificates.k8s.io false CertificateSigningRequest
# leases coordination.k8s.io true Lease
# endpointslices discovery.k8s.io true EndpointSlice
# events ev events.k8s.io true Event
# ingresses ing extensions true Ingress
# ingressclasses networking.k8s.io false IngressClass
# ingresses ing networking.k8s.io true Ingress
# networkpolicies netpol networking.k8s.io true NetworkPolicy
# runtimeclasses node.k8s.io false RuntimeClass
# poddisruptionbudgets pdb policy true PodDisruptionBudget
# podsecuritypolicies psp policy false PodSecurityPolicy
# clusterrolebindings rbac.authorization.k8s.io false ClusterRoleBinding
# clusterroles rbac.authorization.k8s.io false ClusterRole
# rolebindings rbac.authorization.k8s.io true RoleBinding
# roles rbac.authorization.k8s.io true Role
# priorityclasses pc scheduling.k8s.io false PriorityClass
# csidrivers storage.k8s.io false CSIDriver
# csinodes storage.k8s.io false CSINode
# storageclasses sc storage.k8s.io false StorageClass
# volumeattachments storage.k8s.io false VolumeAttachment
# api 资源组版本
$ kubectl api-versions
# admissionregistration.k8s.io/v1
# admissionregistration.k8s.io/v1beta1
# apiextensions.k8s.io/v1
# apiextensions.k8s.io/v1beta1
# apiregistration.k8s.io/v1
# apiregistration.k8s.io/v1beta1
# apps/v1
# authentication.k8s.io/v1
# authentication.k8s.io/v1beta1
# authorization.k8s.io/v1
# authorization.k8s.io/v1beta1
# autoscaling/v1
# autoscaling/v2beta1
# autoscaling/v2beta2
# batch/v1
# batch/v1beta1
# certificates.k8s.io/v1
# certificates.k8s.io/v1beta1
# coordination.k8s.io/v1
# coordination.k8s.io/v1beta1
# discovery.k8s.io/v1beta1
# events.k8s.io/v1
# events.k8s.io/v1beta1
# extensions/v1beta1
# networking.k8s.io/v1
# networking.k8s.io/v1beta1
# node.k8s.io/v1beta1
# policy/v1beta1
# rbac.authorization.k8s.io/v1
# rbac.authorization.k8s.io/v1beta1
# scheduling.k8s.io/v1
# scheduling.k8s.io/v1beta1
# storage.k8s.io/v1
# storage.k8s.io/v1beta1
# v1
问:Deployment(部署)、Pod(容器组) 和 Node(节点) 之间的关系吗?
kubernetes与容器
kubernetes在初期版本里,就对多个容器引擎做了兼容,因此可以使用docker、rkt对容器进行管理。以docker为例,kubelet中会启动一个docker manager,通过直接调用docker的api进行容器的创建等操作。
在k8s 1.5版本之后,kubernetes推出了自己的运行时接口api–CRI(container runtime interface)。cri接口的推出,隔离了各个容器引擎之间的差异,而通过统一的接口与各个容器引擎之间进行互动。
与oci不同,cri与kubernetes的概念更加贴合,并紧密绑定。cri不仅定义了容器的生命周期的管理,还引入了k8s中pod的概念,并定义了管理pod的生命周期。在kubernetes中,pod是由一组进行了资源限制的,在隔离环境中的容器组成。而这个隔离环境,称之为PodSandbox。在cri开始之初,主要是支持docker和rkt两种。其中kubelet是通过cri接口,调用docker-shim,并进一步调用docker api实现的。
如上文所述,docker独立出来了containerd。kubernetes也顺应潮流,孵化了cri-containerd项目,用以将containerd接入到cri的标准中。
WeiyiGeek.
为了进一步与oci进行兼容,kubernetes还孵化了cri-o,成为了架设在cri和oci之间的一座桥梁。通过这种方式,可以方便更多符合oci标准的容器运行时,接入kubernetes进行集成使用。可以预见到,通过cri-o,kubernetes在使用的兼容性和广泛性上将会得到进一步加强。
Kubernetes 与 CRI 以及 Docker-manager 关系图:
WeiyiGeek.