

























Kubernetes 是一个开源的容器编排平台,可以自动完成在部署、管理和扩展容器化应用过程中涉及的许多手动操作。Kubernetes 这个名字源于希腊语,意为“舵手”或“飞行员”。K8s 这个缩写是因为 k 和 s 之间有八个字符的关系。 Google 在 2014 年开源了 Kubernetes 项目。
“编排”(Orchestration)在云计算行业里不算是新词汇,它主要是指用户如何通过某些工具或者配置来完成一组虚拟机以及关联资源的定义、配置、创建、删除等工作,然后由云计算平台按照这些指定的逻辑来完成的过程。
而容器时代,“编排”显然就是对 Docker 等各类容器的一系列定义、配置和创建动作的管理。
虚拟机是在操作系统里面,装一款软件,通过这个软件虚拟出“子电脑”,在“子电脑”里,我们可以运行微信、QQ以及其他程序。同样,我们也可以模拟出更多“子电脑”,这些子电脑就是虚拟机了,虚拟之间相互隔离,互不影响。
容器技术本质上跟虚拟技术有一定的区别,虚拟机使用虚拟机管理程序运行在物理设备上,从系统可用资源分配虚拟机实例。换言之,虚拟机需要虚拟一个物理环境,紧接着构建一个完整的操作系统,供应用程序运行。对于容器技术而言,直接将容器层安装在主机操作系统上,直接利用了宿主机的内核,它不需要虚拟整个操作系统,抽象层比虚拟机更少,启动时间更短、占用空间更小。
那什么是容器呢,举个例子:
我们经常遇到这种情况,程序在自己机器上跑的好好的,结果到了别的机器上就不行了,因为两台机器的环境不一样,别人的机器需要重新配置环境才行。为了解决这个问题,容器就出现了,就是连程序带环境一块搬到目标机器上,环境都准备好了,直接就能跑。这个把程序和环境包在一块的东西,就叫容器。
一个“容器”,实际上是由 Linux Namespace、Linux Cgroups 和 rootfs 三种技术构建出来的进程的隔离环境。
简单来说,有互补,也有竞争(Docker有一款名为Docker Swarm的产品,是一个集群和调度工具,类似 K8s)。在一般的认知中,Kubernetes 和 Docker 是互补关系:
简单来说,K8s 是一个大管家。当你在服务器上装了各种容器,随着时间推移,你完全不知道自己有多少个容器,哪个容器负载小,哪个容器负载大,新来的应用要装在哪个容器等等,K8s 就是帮你管理和维护这些容器的。
OCI(Open Container Initiative)一个关于容器格式和运行时的标准或规范,是由多家公司共同成立的项目,包含运行时标准(runtime-spec )和容器镜像标准(image-spec)。运行时标准规定了怎么去运行一个容器,如何去表达容器的状态和生命周期、如何设置 namespace、cgroup、文件系统等等,可以理解为运行期的动态描述;而容器镜像标准规定了容器镜像的格式、配置、元数据等,可以理解为对镜像的静态描述。
在 K8s 1.5 版本之后,K8s 推出了自己的运行时接口 api–CRI(container runtime interface)。CRI 接口的推出,隔离了各个容器引擎之间的差异,通过统一的接口与各个容器引擎之间进行互动。CRI 将 Kubelet 代码与具体的容器运行时的实现代码解耦开,只要实现了这样一套接口,就能接入到 Kubernetes 的体系中。
为了进一步与 OCI 进行兼容,K8s 还孵化了CRI-O,成为了架设在 CRI 和 OCI 之间的一座桥梁。通过这种方式,可以方便更多符合 OCI 标准的容器运行时,接入 K8s 进行集成使用。


完整的 Kubernetes 集群是由 控制节点 master 、工作节点 node 构成,因此这种集群方式也分为 一主多从 和 多主多从,而每个节点上又会安装不同组件以提供服务。
集群的控制平面,负责集群的决策(管理),存在以下组件
集群的数据平面,负责为容器提供运行环境(干活),存在以下组件
K8s 中⼀切皆为资源,⼀切即可描述,⼀切皆可管理,下面几种资源是经常用到的:
命名空间(namespace)是 K8s 提供的组织机制,用于给集群中的任何对象组进行分类、筛选和管理,主要有两个方面的作用:
Pod 是 K8s 中能够创建和部署的最小单元,是 K8s 集群中的一个应用实例。Pod中包含了一个或多个容器,还包括了存储、网络等各个容器共享的资源。Pod 内部封装的是容器,容器内部运行的是应用程序。

Deployment 是 K8s 中常用的对象类型,通过对 ReplicaSet 和 Pod 进行组装支持了滚动更新、回滚以及扩容等高级功能,⽤于发布无状态应用使用。Dp 最核⼼的功能就是完成了 pod 的控制,建⽴RS(副本个数控制器,也就是⼏个实例)来控制⼀个服务后⾯的 Pod 数⽬,以及 pod 的生命周期,pod 使⽤的资源,pod 是否健康的检查,重启策略等等。日常使用中对于 K8s 的编排操作基本都是基于 dp 资源实现的。
StatefulSet本质上是 Deployment的一种变体,它为了解决有状态服务的问题,它所管理的 Pod 拥有固定的 Pod 名称,启停顺序,在StatefulSet中,Pod名字称为网络标识(hostname),还必须要用到共享存储。
在 K8s 平台上,Pod是有生命周期,为了可以给客户端一个固定的访问端点,因此需要在客户端和Pod 之间添加一个中间层,这个中间层称之为Service。
Service 服务是 K8s 里的核心资源对象之一,为 pod 稳定地提供服务发现和负载均衡的能力。Service 向上提供了外部网络的访问和 Pod 网络的访问;向下则通过负载均衡把请求分配到不同的Pod中去。
为什么需要 Servic?Kubernetes 的 Pod 是有生命周期的,如果使用 Deployment 或者 StatefulSet 来运行应用程序,则它们会动态创建和销毁 Pod,这也就意味着 Pod 的 IP 是不固定的。比如我们使用三副本的 Deployment 部署了 nginx 服务,每个 Pod 都会被分配一个 IP,由于 Pod 的生命周期不稳定,Pod 可能会被删除重建,而重建的话 Pod 的 IP 地址就会改变。也有一种场景,我们可能会对 nginx Deployment 进行扩缩容,从 3副本扩容为 5 副本或者缩容为 2 副本。当我们需要访问上述的nginx 服务时,客户端对于 nginx 服务的 IP 地址就很难配置和管理。
Ingress 是 Kubernetes 的一种 API 对象,将集群内部的 Service 通过 HTTP/HTTPS 方式暴露到集群外部,并通过规则定义 HTTP/HTTPS 的路由。
在 pod 中,容器销毁,则所有容器内部资源都会被销毁,但有些场景下我们希望容器被重新拉起时能保留原有的部分资源,这便有了持久化存储的概念。
持久卷(PersistentVolume,PV)是集群中由管理员配置的一段网络存储,描述一个具体的Volume属性,比如Volume的类型、挂载目录、远程存储服务器地址等。它是集群中的资源,就像节点是集群资源一样。
持久卷申领(PersistentVolumeClaim,PVC)表达的是用户对存储的请求。Pod 会耗用节点资源,而PVC申领会耗用 PV 资源。PVC 申领可以请求特定的大小和访问模式 (例如,可以要求 PV 卷能够以 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany 模式之一来挂载)。
标签和选择器。作⽤其实就是给每个容器贴个标签,然后呢,各个控制器通过 Selector 进⾏ pod 的控制管理,⽐如 Deployment,Service 都是这样控制的。
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
NodePort)暴露服务,提供对外访问。也就是说我们可以通过集群中任意一个节点 IP 地址和端口来访问后的 Pod 应用。(常用)apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
selector:
app: MyApp
ports: - port: 80
targetPort: 80 nodePort: 30001
LoadBalancer: 使用云提供商的负载均衡器向外部暴露服务。 外部负载均衡器可以将流量路由到自动创建的 NodePort 服务和 ClusterIP 服务上。
云提供商的 LoadBalancer 插件主流的实现方式:
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
type: ExternalName
externalName: mysql.database.bytedance.net
https://10.227.90.95/ 使用开发机搭建的 K8s 测试集群。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30007
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。