Kubernetes 介绍基本概念
简介
首先,他是一个全新的基于容器技术的分布式架构领先方案。Kubernetes(k8s)是Google开源的容器集群管理系统(谷歌内部:Borg)。在Docker技术的基础上,为容器化的应用提供部署运行、资源调度、服务发现和动态伸缩等一系列完整功能,提高了大规模容器集群管理的便捷性。
Kubernetes是一个完备的分布式系统支撑平台,具有完备的集群管理能力,多扩多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和发现机制、內建智能负载均衡器、强大的故障发现和自我修复能力、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制以及多粒度的资源配额管理能力。同时Kubernetes提供完善的管理工具,涵盖了包括开发、部署测试、运维监控在内的各个环节。
集群
集群是一组节点,这些节点可以是物理服务器或者虚拟机,在他上面安装了Kubernetes环境。
Master
负责管理集群。 master 协调集群中的所有活动,例如调度应用程序、维护应用程序的所需状态、扩展应用程序和滚动更新。
节点是 Kubernetes 集群中的工作机器,可以是物理机或虚拟机。 每个工作节点都有一个 kubelet,它是管理节点并与 Kubernetes Master 节点进行通信的代理。节点上还应具有处理容器操作的容器运行时,例如 Docker 或 rkt。一个 Kubernetes 工作集群至少有三个节点。
Master 管理集群,而 节点 用于托管正在运行的应用程序。
当您在 Kubernetes 上部署应用程序时,您可以告诉 master 启动应用程序容器。Master 调度容器在集群的节点上运行。 节点使用 Master 公开的 Kubernetes API 与 Master 通信。用户也可以直接使用 Kubernetes 的 API 与集群交互。
Pod
Pod是一组紧密关联的容器集合,它们共享PID、IPC、Network和UTS namespace,是Kubernetes调度的基本单位。Pod的设计理念是支持多个容器在一个Pod中共享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。
在Kubernetes中,所有对象都使用manifest(yaml或json)来定义,比如一个简单的nginx服务可以定义为nginx.yaml,它包含一个镜像为nginx的容器:
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
Label
Label是识别Kubernetes对象的标签,以key/value的方式附加到对象上(key最长不能超过63字节,value可以为空,也可以是不超过253字节的字符串)。
Label不提供唯一性,并且实际上经常是很多对象(如Pods)都使用相同的label来标志具体的应用。
Label定义好后其他对象可以使用Label Selector来选择一组相同label的对象(比如Service用label来选择一组Pod)。Label Selector支持以下几种方式:
- 等式,如app=nginx和env!=production
- 集合,如env in (production, qa)
- 多个label(它们之间是AND关系),如app=nginx,env=test
Namespace
Namespace是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的pods, services,和deployments等都是属于某一个namespace的(默认是default),而 Node, PersistentVolumes等则不属于任何namespace。
Deployment
否手动创建Pod,如果想要创建同一个容器的多份拷贝,需要一个个分别创建出来么,能否将Pods划到逻辑组里?
Deployment确保任意时间都有指定数量的Pod“副本”在运行。如果为某个Pod创建了Deployment并且指定3个副本,它会创建3个Pod,并且持续监控它们。如果某个Pod不响应,那么Deployment会替换它,保持总数为3.
如果之前不响应的Pod恢复了,现在就有4个Pod了,那么Deployment会将其中一个终止保持总数为3。如果在运行中将副本总数改为5,Deployment会立刻启动2个新Pod,保证总数为5。Deployment还支持回滚和滚动升级。
当创建Deployment时,需要指定两个东西:
- Pod模板:用来创建Pod副本的模板
- Label标签:Deployment需要监控的Pod的标签。
现在已经创建了Pod的一些副本,那么在这些副本上如何均衡负载呢?我们需要的是Service。
Service
Service是应用服务的抽象,通过labels为应用提供负载均衡和服务发现。匹配labels的Pod IP和端口列表组成endpoints,由kube-proxy负责将服务IP负载均衡到这些endpoints上。
每个Service都会自动分配一个cluster IP(仅在集群内部可访问的虚拟地址)和DNS名,其他容器可以通过该地址或DNS来访问服务,而不需要了解后端容器的运行。
基本概念与组件
Kubernetes中的绝大部分概念都抽象成Kubernetes管理的一种资源对象,一些资源对象:
-
Master:Master节点是Kubernetes集群的控制节点,负责整个集群的管理和控制。Master节点上包含以下组件:
-
kube-apiserver:集群控制的入口,提供HTTP REST服务
-
kube-controller-manager:Kubernetes集群中所有资源对象的自动化控制中心
-
kube-scheduler:负责Pod的调度
-
Node: Node节点是Kubernetes集群中的工作节点,Node上的工作负载由Master节点分配,工作负载主要是运行容器应用。Node节点上包含以下组件:
kubelet:负责Pod的创建、启动、监控、重启、销毁等工作,同时与Master节点协作,实现集群管理的基本功能。 -
kube-proxy:实现Kubernetes Service的通信和负载均衡
运行容器化(Pod)应用 -
Pod: Pod是Kubernetes最基本的部署调度单元。每个Pod可以由一个或多个业务容器和一个根容器(Pause容器)组成。一个Pod表示某个应用的一个实例
-
ReplicaSet:是Pod副本的抽象,用于解决Pod的扩容和伸缩
-
Deployment:Deployment表示部署,在内部使用ReplicaSet来实现。可以通过Deployment来生成相应的ReplicaSet完成Pod副本的创建
-
Service:Service是Kubernetes最重要的资源对象。Kubernetes中的Service对象可以对应微服务架构中的微服务。Service定义了服务的访问入口,服务的调用者通过这个地址访问Service后端的Pod副本实例。 Service通过Label Selector同后端的Pod副本建立关系,Deployment保证后端Pod副本的数量,也就是保证服务的伸缩性。
image
-
Kubernetes * 主要由以下几个核心组件组成:
-
etcd 保存了整个集群的状态,就是一个数据库;
-
apiserver 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制;
-
controller manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
-
scheduler 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上;
-
kubelet 负责维护容器的生命周期,同时也负责 Volume(CSI)和网络(CNI)的管理;
-
Container runtime 负责镜像管理以及 Pod 和容器的真正运行(CRI);
-
kube-proxy 负责为 Service 提供 cluster 内部的服务发现和负载均衡;
当然了除了上面的这些核心组件,还有一些推荐的插件:
- kube-dns 负责为整个集群提供 DNS 服务
- Ingress Controller 为服务提供外网入口
- Heapster 提供资源监控
- Dashboard 提供 GUI
组件通信
Kubernetes 多组件之间的通信原理为
- apiserver 负责 etcd 存储的所有操作,且只有 apiserver 才直接操作 etcd 集群
- apiserver 对内(集群中的其他组件)和对外(用户)提供统一的 REST API,其他组件均通过 apiserver 进行通信
controller manager、scheduler、kube-proxy 和 kubelet 等均通过 apiserver watch API 监测资源变化情况,并对资源作相应的操作
所有需要更新资源状态的操作均通过 apiserver 的 REST API 进行 - apiserver 也会直接调用 kubelet API(如 logs, exec, attach 等),默认不校验 kubelet 证书,但可以通过 –kubelet-certificate-authority 开启(而 GKE 通过 SSH 隧道保护它们之间的通信)
用户通过 REST API 创建一个 Pod
- apiserver 将其写入 etcd
- scheduluer 检测到未绑定 Node 的 Pod,开始调度并更新 Pod 的 Node 绑定
- kubelet 检测到有新的 Pod 调度过来,通过 container runtime 运行该 Pod
- kubelet 通过 container runtime 取到 Pod 状态,并更新到 apiserver 中