前言
结构图
-
Control Plane 是 k8s 的 master 节点,负责协调集群中的所有活动,例如调度应用程序、维护应用程序的所需状态、扩展应用程序和滚动更新。
control plane 和 master 是同义
-
Node 是 k8s 的工作节点,也就是实际主要跑容器的节点。
组件
https://kubernetes.io/docs/concepts/overview/components/
https://kubernetes.io/docs/reference/command-line-tools-reference/
Control Plane 节点组件
- kube-apiserver 是集群入口,对内(集群中的其他组件)和对外(用户)提供统一的 REST API,其他组件行为均通过 apiserver 进行通信。
- kube-controller-manager 维护管理各种类型的crontroller,例如常见的Deployment Controller,因此kube-controller-manager通过不同类型的Controller来实现故障检测、滚动升级、node扩展等,是集群所有资源对象的自动化管理中心。
- kube-scheduler 是负责 pod 的调度, 即如何将 pod 分发到 node。
- etcd 注册中心,保存集群状态。
Node 节点组件
-
kubelet 是节点代理程序,部署在 node 上。它是k8s master和k8s node之间的纽带。处理 pod 创建/启动/监控/重启/销毁等工作。
开启 register-node = true 的情况下 会自动向 apiserver 服务注册自己。
-
kube-proxy 是节点的网络代理,是 service 资源对象的一部分功能实现,解决节点上各资源的通信
-
Container Runtime 是节点上负责运行容器的环境。它可以是Docker、containerd等。
插件
常用的有DNS插件CoreDNS、网络插件Flannel、可视化插件DashBoard等
https://kubernetes.io/zh/docs/concepts/cluster-administration/addons/
对象
kubernetes 通过实体化的对象来表述资源、策略、状态。
正常情况下,kubernetes 将会尽可能的达到对象的期望状态。
上句话的意思就是,对象基本都包含两个字段,分别是 spec 和 status。
-
spec 表示对象应该拥有的状态特性
-
status 表示对象当前拥有的状态特性
kubernetes 总是想尽办法将 status 向 spec 靠拢。
创建一个对象,需要一份 yaml 配置,配置里包含如下必备信息:
apiVersion
- 创建该对象所使用的 Kubernetes API 的版本kind
- 想要创建的对象的类别metadata
- 帮助唯一性标识对象的一些数据,包括一个name
字符串、UID 和可选的namespace
spec
- 你所期望的该对象的状态
kubectl 命令调用配置,并将信息转换为 json 发给 Apiserver。
一个 yaml 配置例子如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
不同对象的 spec 必然是不一样的,通过 API 文档可以获取
介绍一些常用的对象:
-
Namespace
命名空间是一个逻辑概念,起到了隔离作用。通过它,你可以找到它内部的其它资源对象,例如 pod,svc,deployment等
-
Pod
pod 内包含多个容器,所以多个容器共享以下资源。
- PID命名空间: pod内的进程能互相看到PID
- 网络命名空间: pod中的多个容器共享一个ip (唯一)
- IPC命名空间: pod中的多个容器之间可以互相通信
- UTS命名空间: pod中的多个容器共享一个主机名 (唯一)
- 存储卷: pod多个容器可以共同访问pod定义的存储卷
-
Label
label用于表示资源,从而方便的被其它资源找到。它很重要。
标签定义
key: value
选择器:
key <= !=> value
key <not> in (value1, value2)
ReplicaSet 和 Service 通过 selector 选择器来选择 Pod 对象, 从而精细化的将 Pod 进行分组。一旦某个 pod 的 Label 被修改,那么这个 pod 将从 ReplicaSet 中脱离,而 ReplicaSet 会重新创建新的 pod 补足 ReplicaSet 定义的副本数。
-
Deployment
无状态副本集。用来部署一个 pod 组,它通过 ReplicaSet 来进行缩放, 并需要 pod 模板创建 pod, 需要 Label 监控 pod。Deployment 通过 ReplicaSet 严格执行配置所定义的pod副本数量。应该始终使用 Deployment 来创建 pod。
-
Satefulset
有状态副本集。
-
Service
svc 用来构建一个负载配置。可以比喻为aws的elb内网负载均衡器或者nginx的service proxy配置。
svc 通过 pod 定义的 label 发现一组 pod。这些 pod 本身有 endpoint 地址。
svc 创建后,会拿到一个集群内部ip和dns。kube-proxy 服务会将 svc 的 ip 和 pod 的 endpoint 地址关联起来。
最终,其它容器可以通过这个ip和dns来访问svc关联的pod资源。
-
Ingress
管理集群服务外部访问的API对象,典型的访问方式是 HTTP
对象操作实际转化
客户端对 api server 发起的请求,都会转化为 http 请求
例如发起一个针对 deployment.default 对象的请求,
其 request path 是:
http://
这里 /apps/v1 指的是 kubectl api-versions 列出的 versions。
可以针对对象发起的http请求动作是:
GET/POST/PUT/DELETE
转化为API的动作是:(即你用kubectl调用的动作)
get/list/create/update/patch/watch/proxy/redirect/delete/deletecollection
服务组件流程图
- apiserver 对内(集群中的其他组件)和对外(用户)提供统一的 REST API,其他组件行为均通过 apiserver 进行通信
- apiserver 也会直接调用 kubelet API(如 logs, exec, attach 等),默认不校验 kubelet 证书,但可以通过
--kubelet-certificate-authority
开启
以一个pod的构建为例:
- 用户通过提交请求到Apiserver创建一个 Pod,apiserver 将 pod 状态写入 etcd。
- scheduluer 通过 etcd 检测到未绑定 Node 的 Pod,开始调度并给pod分配node,并更新etcd的pod绑定状态。
- kubelet 通过 etcd 检测到有新的 Pod 调度过来,通过 container runtime 运行该 Pod,并更新Pod运行状态。