? 基于容器的应用部署、维护和滚动升级;
? 负载均衡和服务发现;
? 跨机器和跨地区的集群调度;
? 自动伸缩;
? 无状态服务和有状态服务;
? 插件机制保证扩展性
? Node:计算节点的抽象,用来描述计算节点的资源抽象、健康状态等。
? Namespace:资源隔离的基本单位,可以简单理解为文件系统中的目录结构。
? Pod:用来描述应用实例,包括镜像地址、资源需求等。 Kubernetes 中最核心的对象,也是打通应用和基础架构的秘密武器。
? Service:服务如何将应用发布成服务,本质上是负载均衡和域名服务的声明
提供集群管理的 REST API 接口
提供其他模块之间的数据交互和通信的枢纽(其他模块通过 APIServer 查询或修改数据,只有 APIServer 才直接操作 etcd
APIServer 提供 etcd 数据缓存以减少集群对 etcd 的访问
APIServer 展开
集群的大脑
确保 Kubernetes 遵循声明式系统规范,确保系统的真实状态(ActualState)与用户定义的期望状态(Desired State)一致
是多个控制器的组合,每个 Controller 事实上都是一个control loop,负责侦听其管控的对象,当对象发生变更时完成配置
Controller 配置失败通常会触发自动重试,整个集群会在控制器不断重试的机制下确保最终一致性( Eventual Consistency)
控制器的工作流程
Informer 的内部机制
控制器的协同工作原理
kubectl get po –oyaml -w
kubectl describe po ubuntu-6fcf6c67db-xvmjh
kubectl exec
kubectl logs 查看 pod 的标准输入(stdout, stderr),与 tail 用法类似
? 核心层:Kubernetes 最核心的功能,对外提供 API 构建高层的应用,对内提供插件式应用执行环境。
? 应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS 解析
等)。
? 管理层:系统度量(如基础设施、容器和网络的度量)、自动化(如自动扩展、动态 Provision 等)、
策略管理(RBAC、Quota、PSP、NetworkPolicy 等)。
? 接口层:Kubectl 命令行工具、客户端 SDK 以及集群联邦。
? 生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴:
? Kubernetes 外 部 : 日 志 、 监 控 、 配 置 管 理 、 CI 、 CD 、 Workflow 、 FaaS 、 OTS 应 用 、
ChatOps 等;
? Kubernetes 内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等。
低层 API 根据高层 API 的控制需要设计
尽量避免简单封装,不要有在外部 API 无法显式知道的内部隐藏的机制
API 操作复杂度与对象数量成正比
API 对象状态不能依赖于网络连接状态
尽量避免让操作机制依赖于全局状态
? Self-hosting 是目标。
? 减少依赖,特别是稳态运行的依赖。
? 通过分层的原则管理依赖。
? 循环依赖问题的原则:
? 同时还接受其他方式的数据输入(比如本地文件等),这样在其他服务不可
用时还可以手动配置引导服务;
? 状态应该是可恢复或可重新发现的;
? 支持简单的启动临时实例来创建稳态运行所需要的状态,使用分布式锁或文
件锁等来协调不同状态的切换(通常称为 pivoting 技术);
? 自动重启异常退出的服务,比如副本或者进程管理器等
引入GKV(Group,Kind,Version)模型定义了一个对象的类型
Group
Kind
Version
? Node 是 Pod 真正运行的主机,可以物理机,也可以是虚拟机。
? 为了管理 Pod,每个 Node 节点上至少要运行 container runtime
(比如 Docker 或者 Rkt)、Kubelet 和 Kube-proxy 服务
? 通过存储卷可以将外挂存储挂载到 Pod 内部使用。
? 存储卷定义包括两个部分: Volume 和 VolumeMounts。
? Volume:定义 Pod 可以使用的存储卷来源;
? VolumeMounts:定义存储卷如何 Mount 到容器内部
apiVersion: v1
kind: Pod
metadata:
name: hello-volume
spec:
containers:
- image: nginx:1.15
name: nginx
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
emptyDir: {}
Pod的多个容器是共享网络 Namespace 的
同一个 Pod 中的不同容器可以彼此通过 Loopback 地址访问
这种方法常用于不同容器的互相协作
kubectl set resources deployment nginx-app -c=nginx --
limits=cpu=500m,memory=128Mi
apiVersion: v1
kind: Pod
metadata:
labels:
app: nginx
name: nginx
spec:
containers:
- image: nginx
name: nginx
resources:
limits:
cpu: "500m"
memory: "128Mi"
? LivenessProbe
? 探测应用是否处于健康状态,如果不健康则删除并重新创建容器。
? ReadinessProbe
? 探测应用是否就绪并且处于正常服务状态,如果不正常则不会接收来自 Kubernetes Service 的流量。
? StartupProbe
? 探测应用是否启动完成,如果在 failureThreshold*periodSeconds 周期内未就绪,则会应用进程会被重启。
? Exec
? TCP socket
? HTTP
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx-default
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: http
resources: {}
terminationMessagePath:
/dev/termination-log
terminationMessagePolicy: File
resources:
limits:
cpu: "500m"
memory: "128Mi"
ivenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 15
timeoutSeconds: 1
readinessProbe:
httpGet:
path: /ping
port: 80
initialDelaySeconds: 5
timeoutSeconds: 1
? ConfigMap 用来将非机密性的数据保存到键值对中。
? 使用时, Pods 可以将其用作环境变量、命令行参数或者存储卷中的配置文件。
? ConfigMap 将环境配置信息和 容器镜像解耦,便于应用配置的修改
? Secret 是用来保存和传递密码、密钥、认证凭证这些敏感信息的对象。
? 使用 Secret 的好处是可以避免把敏感信息明文写在配置文件里。
? Kubernetes 集群中配置和使用服务不可避免的要用到各种敏感信息实现登录、认
证等功能,例如访问 AWS 存储的用户名密码。
? 为了避免将类似的敏感信息明文写在所有需要使用的配置文件中,可以将这些信息
存入一个 Secret 对象,而在配置文件中通过 Secret 对象引用这些敏感信息。
? 这种方式的好处包括:意图明确,避免重复,减少暴漏机会
? 用户帐户对应的是人的身份,人的身份与服务的 Namespace 无关,所以用户账户是跨
Namespace 的;
? 而服务帐户对应的是一个运行中程序的身份,与特定 Namespace 是相关的
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- port: 8078 # the port that this service should serve on
name: http
# the container on each pod to connect to, can be a name
# (e.g. 'www') or a number (e.g. 80)
targetPort: 80
protocol: TCP
selector:
app: nginx
? Pod 只是单个应用实例的抽象,要构建高可用应用,通常需要构建多个同样的副本,提供同一个服务。
? Kubernetes 为此抽象出副本集 ReplicaSet,其允许用户定义 Pod 的副本数,每一个 Pod 都会被当作一
个无状态的成员进行管理,Kubernetes 保证总是有用户期望的数量的 Pod 正常运行
? 当某个副本宕机以后,控制器将会创建一个新的副本。
? 当因业务负载发生变更而需要调整扩缩容时,可以方便地调整副本数量
? 部署表示用户对 Kubernetes 集群的一次更新操作。
? 部署是一个比 RS 应用模式更广的 API 对象,可以是创建一个新的服务,更新一个新的服务,也可以是滚动升级一个服务。
? 滚动升级一个服务,实际是创建一个新的 RS,然后逐渐将新 RS 中副本数增加到理想状态,将旧 RS 中的副本数减小到 0 的
复合操作。
? 这样一个复合操作用一个 RS 是不太好描述的,所以用一个更通用的 Deployment 来描述。
? 以 Kubernetes 的发展方向,未来对所有长期伺服型的的业务的管理,都会通过 Deployment 来管理
? 对于 StatefulSet 中的 Pod,每个 Pod 挂载自己独立的存储,如果一个 Pod 出现故障,从其他节点启动一个同样名字的
Pod,要挂载上原来 Pod 的存储继续以它的状态提供服务。
? 适合于 StatefulSet 的业务包括数据库服务 MySQL 和 PostgreSQL,集群化管理服务 ZooKeeper、etcd 等有状态服务。
? 使用 StatefulSet,Pod 仍然可以通过漂移到不同节点提供高可用,而存储也可以通过外挂的存储来提供高可靠性,
StatefulSet 做的只是将确定的 Pod 与确定的存储关联起来保证状态的连续性
? Job 是 Kubernetes 用来控制批处理型任务的 API 对象。
? Job 管理的 Pod 根据用户的设置把任务成功完成后就自动退出。
? 成功完成的标志根据不同的 spec.completions 策略而不同:
? 单 Pod 型任务有一个 Pod 成功就标志完成;
? 定数成功型任务保证有 N 个任务全部成功;
? 工作队列型任务根据应用确认的全局成功而标志成功
? 长期伺服型和批处理型服务的核心在业务应用,可能有些节点运行多个同类业务的 Pod,有些节点上又没有这类 Pod 运行;
? 而后台支撑型服务的核心关注点在 Kubernetes 集群中的节点(物理机或虚拟机),要保证每个节点上都有一个此类 Pod 运行。
? 节点可能是所有集群节点也可能是通过 nodeSelector 选定的一些特定节点。
? 典型的后台支撑型服务包括存储、日志和监控等在每个节点上支撑 Kubernetes 集群运行的服务。
? PersistentVolume(PV)是集群中的一块存储卷,可以由管理员手动设置,
或当用户创建 PersistentVolumeClaim(PVC)时根据 StorageClass 动
态设置。
? PV 和 PVC 与 Pod 生命周期无关。也就是说,当 Pod 中的容器重新启动、
Pod 重新调度或者删除时,PV 和 PVC 不会受到影响,Pod 存储于 PV 里
的数据得以保留。
? 对于不同的使用场景,用户通常需要不同属性(例如性能、访问模式等)
的 PV
? CRD 就像数据库的开放式表结构,允许用户自定义 Schema。
? 有了这种开放式设计,用户可以基于 CRD 定义一切需要的模型,满足不同
业务的需求。
? 社区鼓励基于 CRD 的业务抽象,众多主流的扩展应用都是基于 CRD 构建
的,比如 Istio、Knative。
? 甚至基于 CRD 推出了 Operator Mode 和 Operator SDK,可以以极低的
开发成本定义新对象,并构建新对象的控制器。