Kubernetes笔记_0
架构
一个Kubernetes集群至少包含一个控制平面,以及一个或多个工作节点
控制平面
- 负责管理工作节点和维护集群状态,所有任务的分配都来自控制平面
- 为集群做出去全局决策,比如资源的调度、检测和响应集群事件
kube-apiserver
- 如果与
Kubernetes集群进行交互,需要通过API apiserver是Kubernetes控制平面的前端,用于处理内部和外部请求
kube-scheduler
- 集群状态是否良好,如果需要创建新的容器,需要将他们放在哪里,由调度程序关注
scheduler调度程序考虑容器集的资源需求,比如CPU或者内存,以及集群的运行状态,然后将容器集安排到适当的计算节点
kube-controller-manager
- 控制器负责实际运行集群,
controller-manager控制器管理器将多个控制器功能合并,降低了程序的复杂性
controller-manager包含以下控制器:
- 节点控制器(
Node Controller): 负责在节点出现故障时进行通知和响应 - 任务控制器(
Job Controller): 检测代表一次性任务的Job对象,然后创建Pods来运行这些任务直到完成 - 端点控制器(
Endpoints Controller): 填充端点Endpoints对象,即加入Service和Pod - 服务账户和令牌控制器(
Service Account & Token Controllers): 为新的命名空间创建默认账户和API访问令牌
etcd
- 键值对数据库,存储配置数据和集群状态信息
可选组件cloud-controller-manager
- 云控制管理器,允许将集群了解到云提供商的
API之上,将该云平台交互的组件与自己的集群交互组件分离开。如果在自己的环境中运行Kubernetes或者在本地计算机中运行学习环境,则所部署的集群不需要有云控制管理器
各组件之间的关系
工作节点
- 负责执行由控制平面分配的请求任务,运行实际的应用和工作负载
Node组件
- 节点组件会在每个工作节点上运行,负责维护运行的
Pod并提供Kubernetes运行环境
Pod
Pod是包含一个或者多个容器的容器组,是Kubernetes中创建和管理的最小对象
特点
- 是
Kubernetes的最小调度单位(原子单元),Kubernetes直接管理Pod而不是容器 - 同一个
Pod中的容器总是会被自动安排到集群中的同一个节点(物理机或者虚拟机上),并且一起调度 Pod可以理解为运行特定应用的逻辑主机,容器共享存储、网络和配置声明(比如资源限制)- 每个
Pod有唯一的IP地址,IP地址分配给Pod,在同一个Pod内,所有容器共享一个IP地址和端口空间,Pod内的容器可以使用localhost相互通信
创建和管理
- 创建
Pod:kubectl run <Pod名称> --imgae=<容器镜像>- 执行一次性任务,退出
Pod时自动删除容器:kubectl run <Pod名称> --image=<容器镜像> -it --rm
- 执行一次性任务,退出
- 查看容器状态:
kubectl get pod- 显示详细
Pod信息:kubectl get pod -owide
- 显示详细
- 查看
Pod运行日志:kubectl logs -f <Pod名称> - 查看
Pod的一些信息:kubesctl describe pod <Pod名称>- 创建分为四个步骤
- 分配节点
Successfully assigned default/Pod名称 to k8s-worker2 - 拉取镜像
Container image "容器镜像" already present on machine - 创建容器
Created container Pod名称 - 启动容器
Started container Pod名称
- 分配节点
- 创建分为四个步骤
- 进入
Pod容器:kubectl exec -it Pod名称 -- /bin/bash - 删除容器:
kubectl delete pod Pod名称
Deployment部署和ReplicaSet副本集
Deployment是对ReplicaSet和Pod的更高级别的抽象,使Pod拥有多副本,自愈,扩缩容,滚动升级等能力ReplicaSet副本集是一个Pod的集合,设置运行Pod的数量,确保任何时间都有指定数量的Pod副本在运行。
- 通常,我们不直接使用
ReplicaSet,而是在Deployment中声明
- 创建
Deployment:kubectl create deployment <部署名称> --imgae=<镜像名称> --replicas=<副本数量>Deployment通过副本集控制Pod的数量- 如果手动删除一个
Pod,副本集会自动生成一个新的Pod,维持副本数量不变。这就是自愈
- 查看
Deployment状态:kubectl get deploy
缩放
- 查看副本集:
kubectl get replicaSet- 查看副本集缩放过程:
kubectl get replicaSet --watch
- 查看副本集缩放过程:
手动缩放
- 手动修改
Deployment中的副本集数量:kubectl scale deploy <部署名称> --replicas=<新的副本数量>
自动缩放
kubectl autoscale deployment/<部署名称> --min=<最小副本数> --max=<最大副本数> --cpu-percent=75--cpu-percent=75是使得自动缩放保持所有的Pod的平均cpu占用维持在75%以下
- 查看自动缩放:
kubectl get hpa - 删除自动缩放:
kubectl delete hpa <部署名称>
滚动更新
- 滚动更新部署版本:
kubectl set image deploy/部署名称 容器名=镜像版本 - 如果一个
Deployment中有三个Pod,运行滚动更新命令时,会创建一个新的副本集。- 当新的副本集有一个
Pod就绪了,就会下线旧副本集中的一个Pod,直到旧副本集中所有的Pod均下线
- 当新的副本集有一个
- 版本回滚:
- 查看历史版本:
kubectl rollout history deploy/部署名称 - 查看历史版本详情:
kubectl rollout history deploy/部署名称 --revision=版本号 - 回滚到指定的版本:
kubectl rollout undo deploy/部署名称 --to-revision=版本号
- 查看历史版本:
Service
- 将一组
Pods上的应用程序公开为网路服务的抽象方法 - 将一组
Pod提供相同的DNS名,并进行负载均衡 Kubernetes为Pod提供分配了IP地址,但是IP地址可能发生变化,集群内的容器可以通过service名称访问服务,不需要担心Pod的IP发生变化
Service定义的抽象:
- 逻辑上一组可以互相替换的
Pod,通常称为微服务 Service对应的Pod集合通过选择符关联- 在一个
Service上运行了三个Nginx副本,副本之间可以相互替换,我们不需要关心它调用了哪一个Nginx,也不需要关注Pod的运行装填,只需要调用这个服务就可以了
- 将部署公开为服务:
kubectl expose deploy/部署名称 --name=服务名称 --port=服务端口 --target-port=对应pod端口
ServiceType
ClusterIP(默认)
- 将服务公开在集群内部,
Kubernetes会给服务分配一个集群内部的IP,集群内的所有主机都可以通过这个Cluster-IP访问服务。集群内部的Pod可以通过Service名称访问服务。
NodePort
- 通过每个节点的主机和静态端口(
NodePort)暴露服务,集群外部的主机可以使用节点IP和NodePort访问服务
ExternalName
- 将集群外部的网络引入集群内部
LoadBalancer
- 使用云提供商的负载均衡器向外部暴露服务
使用--type=NodePort即可,本地集群不需要使用LoadBalancer
命名空间
- 一种资源隔离机制,将同一个集群中的资源划分为互相隔离的组。命名空间可以在多个用户之间划分集群资源(通过资源配额)
- 比如可以设置开发、测试、生产多个命名空间
- 同一个命名空间内资源名称唯一,跨命名空间时没有这个要求
- 命名空间作用域仅仅针对带有名字空间的对象,比如
Deployment、Service等 - 作用域对集群访问对象不适用,比如
StorageClass、Node、PersistentVolume等 - 查看命名空间:
kubectl get namespaceKubernetes默认创建四个命名空间:default: 默认命名空间,不可删除,没有指定命名空间的对象都会分配到这里kube-system: 系统对象(控制平面和Node组件)使用的命名空间kube-public: 自动创建的公共命名空间,所有用户(包括没有身份验证的用户)都可以读取,将集群中公用的可见和可读的资源放在这个空间中kube-node-lease: 租约(Lease)对象使用的命名空间。每个节点都有一个关联的Lease对象,Lease是一种轻量级的资源,通过发送心跳,检测集群中的每个节点是否发生故障- 查看
lease对象:kubectl get lease -A
- 查看
- 查看指定命名空间的
Pod:kubectl get pod -n=命名空间名称 - 创建命名空间:
kubectl create ns 命名空间名称 - 运行容器指定命名空间:
kubectl run pod名称 --image=镜像名称 -n=命名空间名称 - 修改默认命名空间的名称(
default):kubectl config set-context $(kubectl config current-context) --namespace=新的名称 - 删除命名空间:
kubectl delete ns 命名空间名称- 删除命名空间会删除其中所有内容,如果有些对象无法被删除(对象处于错误状态,或者对象资源被占用),则命名空间也无法被删除。需要手动删除对象以后才能删除命名空间
管理对象
命令行指令
- 使用
kubectl创建和管理Kubernetes对象。简单高效,但是功能有限,不适合复杂场景,不容易追溯操作,用于开发和调试。
声明式配置
Kubernetes使用yaml文件描述Kubernetes对象,学习难度大并且配置麻烦,但是操作留痕,适合操作复杂的对象,多用于生产。- 使用命令行指令,无法指定
NodePort端口,是随机生成的。但是yaml文件中可以指定NodePort
常用命令缩写
| 名称 | 缩写 | Kind |
|---|---|---|
| namespace | ns | Namespace |
| nodes | no | Node |
| pods | po | Pod |
| services | svc | Service |
| deployment | deploy | Deployment |
| replicasets | rs | ReplicaSet |
| statefulsets | sts | StatefulSet |
使用yaml文件配置KUbernetes对象
apiVersion:Kubernetes API版本kind: 对象类别,比如Pod、Deployment、Service、ReplicaSet等metadata: 描述对象的元数据,包括一个name字符串,UID(系统自动生成)和可选的namespacespec: 对象的配置
yaml内容在官网都可以找到
- 使
yaml文件生效:kubectl apply -f xxx.yaml - 删除
yaml文件:kubectl delete -f xxx.yaml
标签
- 附加在对象
Pod上的键值对,用于补充对象的描述信息。标签使用户可以以松散的方式管理对象映射,不需要客户端存储这些映射。 - 格式
- 键:
- 前缀(可选) / 名称(必须)
- 有效的名称和值:
- 字符数量小于等于63
- 如果不为空,以字母和数字字符开头结尾
- 包含破折号-,下划线_,点和字母或者数字
- 键:
- 查看所有
Pod的标签:kubectl get pod --show-labels- 查看指定
Pod的标签:kubectl get pod -l "指定的Pod描述"
- 查看指定
选择器
- 标签通常配合选择器使用,标签选择器可以识别一组对象,标签不支持唯一性
- 标签选择器最常见的用法是为
Service选择一组Pod作为后端 - 标签选择运算,基于等值的和基于集合的
- 多个条件使用逗号分割,相当于
AND - 基于等值的直接使用键值对即可
- 基于集合的可以使用
IN, NOT IN
- 多个条件使用逗号分割,相当于
容器运行时接口(CRI)
Kubelet运行在每个节点上,用于管理和维护Pod和容器的状态- 容器运行时接口是
Kubelet和容器运行时之间通信的主要协议,将Kubelet于容器运行时解耦,实现了CRI接口的容器引擎,都可以所谓Kubernetes的容器运行时。 Docker没有实现CRI接口,Kubernetes使用dockershim来兼容dockercrictl是一个兼容CRI的容器运行时命令,跟docker命令一个样,可以用来检查和调试底层的运行时容器- 比
docker命令稍微少一些,比如无法实现导入导出 - 因此导入导出使用
ctr命令,也只用来导入导出,因为ctr也不是很好用1
2
3
4
5docker pull alpine:3.15
docker save apline:3.15 > alpine-3.15.tar # 保存成tar
ctr -n k8s.io images import alpine-3.15.tar --platform linux/amd64 # 导入镜像
kubernetes 中所有的镜像都在k8s.io这个命名空间中
ctr -n k8s.io images export alpine.tar docker.io/library/alpine:3.15 --platform linux/amd64 # 导出镜像
- 比
金丝雀发布(canary deployment)
- 生产环境中小范围部署新的应用代码,一旦应用签署发布,只有少数用户被路由到他,最大限度降低影响。如果没有错误发生,则将新版本逐渐推广到整个基础设施
- 默认的金丝雀发布有一定的局限
- 不能根据用户的注册时间、地区等请求中的内容属性进行流量分配
- 同一个用户如果多次调用该
Service,可能第一次请求到了旧版本的Pod,第二次请求到了新版本的Pod - 因为
Kubernetes Service只在TCP层面解决负载均衡问题,不对请求响应的消息内容做任何解析和识别,如果更完善的实现金丝雀日发布,可以考虑Istio灰度发布
搭建MySQL
创建mysql-pod.yaml
1 | apiVersion: v1 |
挂载数据卷
hostPath卷: 将主机节点上的文件或目录挂在到Pod中
| type | 含义 |
|---|---|
| DirectoryOrCreate | 目录不存在则自动创建 |
| Directory | 挂载已经存在的目录,不存在会报错 |
| FileOrCreate | 文件不存在则自动创建,不会自动创建文件的父目录,必须确保文件路径存在 |
| File | 挂载已经存在的文件,不存在会报错 |
| Socket | 挂在UNIX套接字,比如挂载/var/run/docker.sock 进程 |
ConfigMap
Docker中可以使用绑定挂载的方式将配置文件挂载到容器里,但是在Kubernetes集群中,容器可能被调度到任意的节点中,配置文件需要能在集群的任意节点上访问、分发和更新ConfigMap用来在etcd中保存非加密的数据,一般用来保存配置文件- 可以用作环境变量,命令行参数或者存储卷
- 将配置信息与容器镜像解耦,便于配置的修改
- 在设计上不是用来保存大量数据的
- 保存的数据不能超过1MB
- 超出这个限制,需要考虑存储卷或者访问文件存储服务
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Sangs Blog!



