K8S 基本概念与组件

Kubernetes 基本概念与组件

Kubernetes(简称 K8S) 的出现是容器化技术发展的必然结果,容器化是应用程序级别的虚拟化,运行单个内核上有多个独立的用户空间实例,这些实例就是容器;容器提供了将应用程序的代码、运行时、系统工具、系统库和配置打包到一个实例中的标准方法,而且容器是共享一个内核的;由于容器技术的兴起,导致大量的容器应用出现,所以就出现了一些用来支持应用程序容器化部署和组织的容器编排技术,一些流行的开源容器编排工具有 Docker Swarm、Kubernetes 等,但是在发展过程中 Kubernetes 现在已经成为了容器编排领域事实上的一个标准了。

Kubernetes 是 Google 团队发起的一个开源项目,它的目标是管理跨多个主机的容器,用于自动部署、扩展和管理容器化的应用程序,主要实现语言为 Go 语言,他的理论基础来源与 Google 内部的 Borg 项目,所以 Kubernetes 项目的理论基础就比其他开源项目要“先进”很多,因为 Borg 系统一直依赖就被称为 Google 公司内部最强大的“私密武器”。

架构¶

Kubernetes 项目依托着 Borg 项目的理论优势,确定了一个如下图所示的全局架构图:

从上面我们可以看出 Kubernetes 由 Master 和 Node 两种节点组成,这两种角色分别对应着控制节点和工作节点(可以理解为老板和员工)。

其中 Master 节点由三个独立的组件组成,它们分别是负责整个集群通信的 API 服务的 kube-apiserver、负责容器调度的 kube-scheduler 以及负责维护集群状态的 kube-controller-manager 组件。整个集群的数据都是通过 kube-apiserver 保存到 etcd 数据库中的,而其他所有组件的通信也都是通过 kube-apiserver 和 etcd 数据库进行通信的,都不会直接和 etcd 进行通信。

工作节点上最核心的组件就是 kubelet,当然还有底层的容器运行时,比如 Docker,其中 kubelet 就是主要来实现和底层的容器运行时进行通信的,这个通信的过程也被 Kubernetes 抽象成了一个 CRI(Container Runtime Interface)的远程调用接口,这个接口里面定义了容器运行时的所有标准操作,比如创建容器、删除容器等等。所以对于 Kubernetes 来说他根本不关心你部署的到底是什么容器运行时,只要你这个容器运行时可以实现 CRI 接口就可以被 Kubernetes 来管理。

kubelet 的另外一个重要功能就是调用网络插件(CNI)和存储插件(CSI)为容器配置网络和存储功能,同样的 kubelet 也是把这两个重要功能通过接口暴露给外部了,所以如果我们想要实现自己的网络插件,只需要使用 CNI 就可以很方便的对接到 Kubernetes 集群当中去。

可能下面的架构图看上去更清晰一些:

组件¶

上面我介绍了 Kubernetes 集群的整体架构,下面我们再来更加详细的了解下这些组件的功能。

kube-apiserver¶

API Server 提供了资源对象的唯一操作入口,其它所有组件都必须通过它提供的 API 来操作资源数据。只有 API Server 会与 etcd 进行通信,其它模块都必须通过 API Server 访问集群状态。API Server 作为 Kubernetes 系统的入口,封装了核心对象的增删改查操作。API Server 以 RESTFul 接口方式提供给外部客户端和内部组件调用,API Server 再对相关的资源数据(全量查询 + 变化监听)进行操作,以达到实时完成相关的业务功能。以 API Server 为 Kubernetes 入口的设计主要有以下好处:

kube-controller-manager¶

Controller Manager 用于实现 Kubernetes 集群故障检测和恢复的自动化工作。主要负责执行各种控制器:

kube-scheduler¶

Scheduler 是负责整个集群的资源调度的,主要的职责如下所示:

kubelet¶

kubelet 是负责容器真正运行的核心组件,主要的职责如下所示:

kube-proxy¶

kube-proxy 是为了解决外部网络能够访问集群中容器提供的应用服务而设计的,Proxy 运行在每个Node 上。

每创建一个 Service,kube-proxy 就会从 API Server 获取 Services 和 Endpoints 的配置信息,然后根据其配置信息在 Node 上启动一个 Proxy 的进程并监听相应的服务端口。

当接收到外部请求时,kube-proxy 会根据 Load Balancer 将请求分发到后端正确的容器处理。

kube-proxy 不但解决了同一宿主机相同服务端口冲突的问题,还提供了 Service 转发服务端口对外提供服务的能力。

kube-proxy 后端使用随机、轮循等负载均衡算法进行调度。

kubectl¶

Kubectl 是 Kubernetes 的集群管理命令行客户端工具集。通过 Kubectl 命令对 API Server 进行操作,API Server 响应并返回对应的命令结果,从而达到对 Kubernetes 集群的管理

核心资源对象¶

上面我们都是在架构层面了解 Kubernetes,但是似乎没有发现关于容器的说明,Kubernetes 作为容器编排引擎,那么他是怎么去对容器进行编排的呢?在 Kubernetes 集群中抽象了很多集群内部的资源对象,我们可以通过这些资源对象去操作容器的编排工作。

Pod¶

Pod 是一组紧密关联的容器集合,它们共享 PID、IPC、Network 和 UTS namespace,是Kubernetes 调度的基本单位。Pod 的设计理念是支持多个容器在一个 Pod 中共享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。我们知道容器本质上就是进程,那么 Pod 实际上就是进程组了,只是这一组进程是作为一个整体来进行调度的。

在 Kubernetes 中,所有资源对象都使用资源清单(yaml或json)来定义,比如我们可以定义一个简单的 nginx 服务,它包含一个镜像为 nginx 的容器:(nginx-pod.yaml)

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80

定义了这样一个资源清单文件后,我们就可以利用上面我们提到的 Kubectl 工具将这个 Pod 创建到 Kubernetes 集群中:

kubectl apply -f nginx-pod.yaml

Pod 在 Kubernetes 集群中被创建的基本流程如下所示:

Label¶

Label 标签在 Kubernetes 资源对象中使用很多,也是非常重要的一个属性,Label 是识别 Kubernetes 对象的标签,以 key/value 的方式附加到对象上(key最长不能超过63字节,value 可以为空,也可以是不超过253字节的字符串)上面我们定义的 Nginx 的 Pod 就添加了一个 app=nginx 的 Label 标签。Label 不提供唯一性,并且实际上经常是很多对象(如Pods)都使用相同的 Label 来标志具体的应用。Label 定义好后其他对象可以使用 Label Selector 来选择一组相同 Label 的对象(比如 Service 用 Label 来选择一组 Pod)。Label Selector 支持以下几种方式:

Namespace¶

Namespace(命名空间)是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的 Pods、Services、Deployments 等都是属于某一个 Namespace 的(默认是default),比如上面我们的 Nginx Pod 没有指定 namespace,则默认就在 default 命名空间下面,而 Node, PersistentVolumes 等资源则不属于任何 Namespace,是全局的。

注意它并不是 Linux Namespace,二者没有任何关系,它只是 Kubernetes 划分不同工作空间的一个逻辑单位。

Deployment¶

我们说了 Pod 是 Kubernetes 集群中的最基本的调度单元,但是如果想要创建同一个容器的多份拷贝,需要一个一个分别创建出来么,那么能否将 Pods 划到一个逻辑组里面呢?Deployment 就是来管理 Pod 的资源对象。

Deployment 确保任意时间都有指定数量的 Pod“副本”在运行。如果为某个 Pod 创建了 Deployment 并且指定3个副本,它会创建3个 Pod,并且持续监控它们。如果某个 Pod 不响应,那么 Deployment 会替换它,始终保持总数为3。

如果之前不响应的 Pod 恢复了,现在就有4个 Pod 了,那么 Deployment 会将其中一个终止保持总数为3。如果在运行中将副本总数改为5,Deployment 会立刻启动2个新 Pod,保证总数为5。持回滚和滚动升级。

当创建 Deployment 时,需要指定两个东西:

现在已经创建了 Pod 的一些副本,那么这些副本上如何进行负载呢?如何把这些 Pod 暴露出去呢?这个时候我们就需要用到 Service 这种资源对象了。

Service¶

Service 是应用服务的抽象,通过 Labels 为应用提供负载均衡和服务发现。匹配 Labels 的 Pod IP 和端口列表组成 Endpoints,由 kube-proxy 负责将服务 IP 负载均衡到这些 Endpoints 上。

每个 Service 都会自动分配一个 cluster IP(仅在集群内部可访问的虚拟地址)和 DNS 名,其他容器可以通过该地址或 DNS 来访问服务,而不需要了解后端容器的运行。

迁移

了解了上面的几个基本概念后,我们就完全可以把我们的容器服务迁移到 Kubernetes 集群上了。当然我们还得先搭建好我们的 Kubernetes 集群环境。

展开阅读全文

页面更新:2024-04-25

标签:组件   副本   节点   集群   容器   对象   状态   操作   资源   信息

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top