从宏观上来看 Kubernetes 的整体架构,包括 Master、Node 以及 etcd。
Master 即主节点,负责控制整个 Kubernetes 集群。它包括 API Server、Scheduler、Controller 等组成部分。它们都需要和 etcd 进行交互以存储数据。
- API Server:主要提供资源操作的统一入口,这样就屏蔽了与 etcd 的直接交互。功能包括安全、注册与发现等。
- Scheduler:负责按照一定的调度规则将 Pod 调度到 Node 上。
- Controller:资源控制中心,确保资源处于预期的工作状态。
- Node 即工作节点,为整个集群提供计算力,是容器真正运行的地方,包括运行容器、kubelet、kube-proxy。
- kubelet:主要工作包括管理容器的生命周期、结合 cAdvisor 进行监控、健康检查以及定期上报节点状态。
- kube-proxy:主要利用 Service 提供集群内部的服务发现和负载均衡,同时监听 Service/Endpoints 变化并刷新负载均衡。
## 资源类型
资源类型
- 常见标准资源类型:
- Pod: 为最小应用运行单位,一个服务实例对应一个Pod
- Deployment: 需要批量运行配置类似的Pod时,可以使用Deployment对Pod进行批量创建和管理, 需要注意的是Deployment 只能部署无状态的实例.
当一个应用满足以下几点时就可以称为无状态实例.
1. 一个事务可以被任意实例处理并且结果一致,反例: kafka消息推送只能由topic当前leader处理.
2. 多个实例可以共享同一份持久化数据并且不会冲突
- StatefulSet: 作用和Deployment类似,既可以用来部署无状态的服务也可以用来部署有状态的服务,但是不推荐用来部署无状态的服务.具体原因具体讲解时说明.有状态服务条件和无状态相反,并且只需满足一个条件.
- DaemonSet: 当应用需要在满足条件的节点上运行且只运行一个时,可以使用该配置.主要用于部署后台服务.类似日志收集一类的服务.
- ConfigMap: 主要用于应用所需要的静态文件
- Secret: 用于需要加密的静态文件:
- Service: 将一组满足条件的Pod的指定端口暴露给其它内部或者外部服务.也可以用来给Statefulset所属Pod配置可以被其它pod可以解析的主机名.
- PersistentVolumeClaim(PVC)/PV/StorageClass:
- Node:
- ServiceAccount
流程
Deployment 是用于编排 Pod 的一种控制器资源,我们会在后面做介绍。这里以 Deployment 为例,来看看架构中的各组件在创建 Deployment 资源的过程中都干了什么。
首先是 kubectl 发起一个创建 deployment 的请求
-
apiserver 接收到创建 deployment 请求,将相关资源写入 etcd;之后所有组件与 apiserver/etcd 的交互都是类似的
-
deployment controller list/watch 资源变化并发起创建 replicaSet 请求
-
replicaSet controller list/watch 资源变化并发起创建 Pod 请求
-
scheduler 检测到未绑定的 Pod 资源,通过一系列匹配以及过滤选择合适的 Node 进行绑定
-
kubelet 发现自己 Node 上需创建新 Pod,负责 Pod 的创建及后续生命周期管理
-
kube-proxy 负责初始化 Service 相关的资源,包括服务发现、负载均衡等网络规则
至此,经过 Kubernetes 各组件的分工协调,完成了从创建一个 deployment 请求开始到具体各 Pod 正常运行的全过程。
格式
apiVersion: v1
kind: Pod
metadata:
labels:
app: nginx
name: nginx
namespace: default
spec:
containers:
- env:
- name: CHANNEL_ID
value: '1'
image: '10.32.233.112/library/nginx:1.12'
imagePullPolicy: IfNotPresent
name: nginx
resources:
limits:
cpu: "1"
memory: "200Mi"
request:
cpu: "1"
memory: "200Mi"
securityContext:
capabilities:
add:
- NET_ADMIN
drop:
- MKNOD
- env:
- name: CLIENT_ID
value: vpn_agent
image: '10.32.233.112/library/busybox'
imagePullPolicy: Always
name: busybox
volumeMounts:
- mountPath: /etc/properties
name: kfiot-configmap
volumes:
- configMap:
defaultMode: 420
name: kfiot-configmap
name: kfiot-configmap
首先一个标准的Kubernetes yaml分为以下几部分
apiVersion
必填
该资源的api版本号,可以认为是对资源的分组. 如果改值为v1,apps/v1,那么可以认为该资源为kubernetes已经定义好的标准资源.类似Pod,Service这种.如果该值包含了平台的字符串,例如openshift,redhat一类的字样,这说明该资源为该平台自定义的资源,是不可在其他kubernetes 发行版里面使用的.
如果该值包含了beta 例如,betav1.那么说明该资源是或者曾是一个测试资源类型.
Kubernete 官方为了考虑使用k8s平台的人yaml的兼容性.所以当一个资源类型从beta版本变为了正式版时,在未来的好几个kubernetes版本中该资源会同时属于 betav1 和 v1组. 所以短期来看用betav1和用v1都一样.但是kubernets迟早会将该资源从betav1中去除.
所以如果出现一个yaml导入,在低版本中可以正常导入并且apiVersion中带有beta字符串,但是在高版本中报错说找不到该资源,那么将beta删除,大概率可以解决该问题.
kind
必填
资源类型
- 常见标准资源类型:
- Pod:为最小应用运行单位,一个服务实例对应一个Pod
- Deployment: 需要批量运行配置类似的Pod时,可以使用Deployment对Pod进行批量创建和管理, 需要注意的是Deployment 只能部署无状态的实例.
当一个应用满足以下几点时就可以称为无状态实例.
1. 一个事务可以被任意实例处理并且结果一致,反例: kafka消息推送只能由topic当前leader处理.
2. 多个实例可以共享同一份持久化数据并且不会冲突
- StatefulSet: 作用和Deployment类似,既可以用来部署无状态的服务也可以用来部署有状态的服务,但是不推荐用来部署无状态的服务.具体原因具体讲解时说明.有状态服务条件和无状态相反,并且只需满足一个条件.
- DaemonSet: 当应用需要在满足条件的节点上运行且只运行一个时,可以使用该配置.主要用于部署后台服务.类似日志收集一类的服务.
- ConfigMap: 主要用于应用所需要的静态文件
- Secret: 用于需要加密的静态文件:
- Service: 将一组满足条件的Pod的指定端口暴露给其它内部或者外部服务.也可以用来给Statefulset所属Pod配置可以被其它pod可以解析的主机名.
- PersistentVolumeClaim(PVC)/PV/StorageClass:
- Node:
- ServiceAccount
- Openshift 独有资源类型:
- Route
- SecurityContextConstraints
metadata
必填
资源元数据,配置资源的一些基本信息
- annotations(非必填): 一般用于给资源附加一些额外信息,平台程序会用这些信息去做一些额外配置
- label(必填): 标签,可以认为是给pod分组,便于给Service或者其它程序指向改组资源
- name(必填): 资源名称
- namespace(分情况): 资源所属namespace,在openshift中使用页面创建会直接把资源导入至当前所选namespace,不一致会报错,使用命令行创建会使用该值作为实际的namspace进行创建.
不是所有资源都属于一个namespace,有些资源是集群资源
- StorageClass
- SecurityContextConstraints
spec
必填
资源主要配置部分