k8s 笔记
k3s 集群
问题“The connection to the server....:6443 was refused - did you specify the right host or port?”的处理!
k8s 解决的问题
Borg 解决的问题
谷歌在线和离线任务的混布(non-prod 、 prod),提高物理资源利用率 ==> 降本提效
解决的问题:计算中心集群管理——作业调度、应用隔离、故障转移……
k8s 解决的问题
开源的容器编排引擎和容器集群管理工具,用来对容器化应用进行自动化部署、 扩缩和管理。
容器编排:容器间的协作
- 自我修复
- 自动部署和回滚
- 滚动更新
- 自动扩缩容
- 打通 CI/CD 工具链
K8s 的架构

控制平面:
etcd : 配置中心
分布式数据库,k-v,服务发现、共享配置以及一致性保障
controller-manager : 控制器管理工具
Controller Manager 是集群的大脑,是确保整个集群动起来的关键;
其作用是确保 Kubernetes 遵循声明式系统规范,确保系统的真实状态(Actual State)与用户定义的期望状态(Desired State 一致);
Controller Manager 是多个控制器的组合,每个 Controller 事实上都是一个 control loop,负责侦听其管控的对象,当对象发生变更时完成配置;
Controller 配置失败通常会触发自动重试,整个集群会在控制器不断重试的机制下确保最终一致性( Eventual Consistency)。
scheduer : pod 调度器
特殊的 Controller,工作原理与其他控制器无差别;Scheduler 的特殊职责在于监控当前集群所有未调度的Pod,并且获取当前集群所有节点的健康状况和资源使用情况,为待调度 Pod 选择最佳计算节点,完成调度。
调度阶段分为:
- Predict:过滤不能满足业务需求的节点,如资源不足,端口冲突等。
- Priority:按既定要素将满足调度需求的节点评分,选择最佳节点。
- Bind:将计算节点与 Pod 绑定,完成调度。
api-service : 服务网关
提供集群管理的 REST API 接口,包括:
- 认证 Authentication;
- 授权 Authorization;
- 准入 Admission(Mutating & Valiating)。
提供其他模块之间的数据交互和通信的枢纽(其他模块通过 API Server 查询或修改数据,只有 API Server 才直接操作 etcd)。
APIServer 提供 etcd 数据缓存以减少集群对 etcd 的访问。
工作平面:
proxy-service:负载均衡器
它是一个分布式代理服务器,实现 service 的基础
kubelet:
Kubernetes 的初始化系统(init system)
kubelet 会在集群中每个节点(node)上运行。 它保证容器(containers)都运行在 Pod 中。
当控制平面需要在节点中执行某个操作时,kubelet 就会执行该操作。
负责汇报当前节点的资源信息和健康状态;
负责 Pod 的健康检查和状态汇报
资源对象

核心资源对象
- pod :
容器集合,共享除 PID 、文件之外的进程资源;对计算任务应用的描述;
k8s pod = borg non prod + prod;Kubernetes 中最核心的对象,也是打通应用和基础架构的秘密武器;
- node:
节点,对应物理机器/虚拟机,对计算资源的抽象
- replicaSet:
副本集,管理 pod,保证应用的高可用,生命期望
- deployment:
部署文件,对 应用部署/pod 的描述文件,表示用户对 Kubernetes 集群的一次更新操作
- service:
服务发布,负载均衡,pod 地址是易变的,service会对应一个集群内部有效的虚拟 IP,集群内部通过虚拟 IP 访问一个服务。在 Kubernetes 集群中微服务的负载均衡是由 Kube-proxy 实现的。
对象的通用设计
Deployment 示例:
- TypeMeta
- G(roup)
- K(ind)
- V(ersion)
- Metadata
- Namespace
- Name
- Labels & Annotation
设计思想
面向资源
- k8s 把分布式集群中的一切都看做资源;
- 工作荷载资源 pod 、deployment
- 存储资源 volume、
- 身份资源 limitRange
- 策略资源 role
- 声明式 API
- 最终一致性
控制器模式
- 各种 controller
- watch 机制

自动恢复:
Deployment -> ReplicaSet -> pod
滚动更新:
自动扩缩容:
Autoscaling -> Deployment -> ReplicaSet -> Pod
kubectl scale deploy nginx --replicas=5
容器技术底层技术
基于 linux 内核:
namespace :进程命名空间隔离
cgroups :资源限额
Union FS : 文件系统
指令笔记:
autoscaling:自动扩缩容
https://www.cnblogs.com/caonw/p/13273512.html
Namespace:资源隔离的基本单位,可以简单理解为文件系统中的目录结构;
kubectl create -f nginx.yaml
kubectl scale deploy nginx --replicas=5
kubectl apply -f nginx.yaml
https://juejin.cn/post/7056003117221380104
kubectl get po nginx-cd55c47f5-swm8q -oyaml
kubectl get svc nginx-service -oyaml
- 输出某个pods为yaml文件
// 查看 pod 及其标签
kubectl get pod --show-labels
// 过滤名称为 mynginx 的 pod(过滤)
[root@VM-16-13-centos mine]# kubectl get pod -l run=mynginxNAME READY STATUS RESTARTS AGEmynginx 1/1 Running 0 2d1h
// 添加注解(扩展)
kubectl annotate po nginx-cd55c47f5-swm8q a=b
// -v 9 打印日志(实际是一个 REST 调用)
kubectl create -f nginx.yaml -v 9
部署无状态服务
重点:
- 部署有状态服务的核心对象:pod、rs、deploy、service、namesapce
- 配置文件和命令
- 对象的正确使用方法 / 最佳实践
无状态服务
无状态服务
没有特殊状态的服务,各个请求对于服务器来说统一无差别处理,请求自身携带了所有服务端所需要的所有参数(服务端自身不存储跟请求相关的任何数据,不包括数据库存储信息);
有状态服务
与之相反,有状态服务在服务端保留之前请求的信息,用以处理当前请求,比如session等。
k8s 更推荐将应用设计为无状态服务,无状态服务可以调度到任意节点,更方便和灵活。
声明式 vs 命令式
声明式系统
在软件工程领域,声明式系统指程序代码描述系统应该做什么而不是怎么做。仅限于描述要达到什么目的,如何达到目的交给系统。

命令式系统
命令式系统在软件工程领域,命令式系统是写出解决某个问题,完成某个任务,或者达到某个目标的的明确步骤。此方法明确写出系统应该执行某指令,并且期待系统返回期望结果。

Kubernetes 将一切都看做是对象,一切皆对象的设计思想为 k8s 实现声明式配置系统提供支撑。k8s 的所有管理能力构建在对象抽象的基础上。
对比
- 命令行指令
例如,使用kubectl命令来创建和管理 Kubernetes 对象。
命令行就好比口头传达,简单、快速、高效。
但它功能有限,不适合复杂场景,操作不容易追溯,多用于开发和调试。
- 声明式配置
kubernetes使用yaml文件来描述 Kubernetes 对象。
声明式配置就好比申请表,学习难度大且配置麻烦。
好处是操作留痕,适合操作复杂的对象,多用于生产。
配置对象
k8s 配置对象支持 yaml 格式:
在创建的 Kubernetes 对象所对应的 yaml文件中,需要配置的字段如下:
- apiVersion - Kubernetes API 的版本
- kind - 对象类别,例如Pod、Deployment、Service、ReplicaSet等
- metadata - 描述对象的元数据,包括一个 name 字符串、UID 和可选的 namespace
- spec - 对象的配置
node
说明:
计算节点的抽象,用来描述计算节点的资源抽象,健康状态等;
对应在机器(物理机或虚拟机);
常用指令:
查看 node 信息
查看 node 的声明配置文件:
pod
说明
- 表示工作负载的资源对象
- 是一组容器的集合
- k8s 集群调度的最小单位
- pod 中容器共享存储、网络和配置声明(如资源限制)。
指令
直接创建 pod
删除 pod
配置文件
以 nginx 为例:
pod 的正确使用
对应微服务中的一个服务,在部署系统时,一般不会直接部署 pod ,而是通过编写 deployment 和 rs 控制 pod 的声明周期。直接创建的 pod 和直接在物理机上部署应用上没有任何优势。
而通过 deployment 和 rs 可以很轻松的实现服务自愈,手动/自动扩缩容/滚动发布等在直接在物理机上部署很难实现的功能。
踩坑
CrashLoopBackOff :循环重启
https://zhuanlan.zhihu.com/p/558957039
ReplaceSet(副本集)
说明
ReplicaSet(副本集)是一个Pod的集合。
它可以设置运行Pod的数量,确保任何时间都有指定数量的 Pod 副本在运行。
作用
- Pod 描述的是具体的应用实例,当 Pod 被删除后,就彻底消失了;为保证应用的高可用,引入副本集来确保应用的总副本数永远与期望一致;
- 若某个 Pod 隶属于某个副本集,若该 Pod 被删除,则 ReplicaSet Controller 会发现当前运行的副本数量与用户的期望不一致,则会创建新的 Pod。
配置文件
以 nginx rs 为例:
使用
通常我们不直接使用ReplicaSet,而是在Deployment中声明。
Deployment(部署)
参考官网地址: https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/
说明
- Deployment是对ReplicaSet和Pod更高级的抽象。
- 部署表示用户对 Kubernetes 集群的一次更新操作。
作用
- 部署是一个比 RS 应用模式更广的 API 对象,可以是创建一个新的应用,更新一个已存在的应用,也可以是滚动升级一个应用。
- 滚动升级一个服务,实际是创建一个新的 RS,然后逐渐将新 RS 中副本数增加到理想状态,将旧 RS 中的副本数减小到 0 的复合操作;这样一个复合操作用一个 RS 是不太好描述的,所以用一个更通用的Deployment 来描述。以 Kubernetes 的发展方向,未来对所有长期伺服型的的业务的管理,都会通过 Deployment 来管理。
示例 yaml 文件
k8s 镜像拉取策略: imagePullPolicy
k8s-imagePullPolicy拉取策略_中国lanwp的博客-CSDN博客_imagepullpolicy
Always :总是拉取 pull
imagePullPolicy: Always
IfNotPresent :默认值,本地有则使用本地镜像,不拉取
imagePullPolicy: IfNotPresent
Never :只使用本地镜像,从不拉取
imagePullPolicy: Never
使用方式
以上面的 nginx-deployment.yaml 为例:
- 创建新应用
- 更新应用
更新 yaml 文件并应用,应用指令:
- 滚动更新
滚动更新配置:
使用指令:
- 版本回滚
Service
参考官网地址:https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/
说明
- Service将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。
- Kubernetes Service 定义了这样一种抽象:
逻辑上的一组可以互相替换的 Pod,通常称为微服务。
Service 对应的 Pod 集合通常是通过选择算符来确定的。
举个例子,在一个Service中运行了3个nginx的副本。这些副本是可互换的,我们不需要关心它们调用了哪个nginx,也不需要关注 Pod的运行状态,只需要调用这个服务就可以了。
作用
- Service为一组 Pod 提供相同的 DNS 名,并且在它们之间进行负载均衡。
配置文件示例
假定有一组 Pod,它们对外暴露了 9376 端口,同时还被打上 app.kubernetes.io/name=MyApp 标签:
上述配置创建一个名称为 "my-service" 的 Service 对象,它会将请求代理到使用 TCP 端口 9376,并且具有标签 app.kubernetes.io/name=MyApp 的 Pod 上。
使用方式
Kubernetes 为 Pod 提供分配了IP 地址,但IP地址可能会发生变化。
集群内的容器可以通过service名称访问服务,而不需要担心Pod的IP发生变化。
ServiceType 取值
- ClusterIP:将服务公开在集群内部。kubernetes会给服务分配一个集群内部的 IP,集群内的所有主机都可以通过这个Cluster-IP访问服务。集群内部的Pod可以通过service名称访问服务。
- NodePort:通过每个节点的主机IP 和静态端口(NodePort)暴露服务。 集群的外部主机可以使用节点IP和NodePort访问服务。
- ExternalName:将集群外部的网络引入集群内部。
- LoadBalancer:使用云提供商的负载均衡器向外部暴露服务。

访问Service
外部主机访问:192.168.56.109:32296。
1.NodePort 端口是随机的,范围为:30000-32767。
2.集群中每一个主机节点的 NodePort 端口都可以访问。
3.如果需要指定端口,不想随机产生,需要使用配置文件来声明。

Namespace
说明
命名空间(Namespace)是一种资源隔离机制,将同一集群中的资源划分为相互隔离的组。
Kubernetes 会创建四个初始命名空间:
- default 默认的命名空间,不可删除,未指定命名空间的对象都会被分配到default中。
- kube-system Kubernetes 系统对象(控制平面和Node组件)所使用的命名空间。
- kube-public 自动创建的公共命名空间,所有用户(包括未经过身份验证的用户)都可以读取它。通常我们约定,将整个集群中公用的可见和可读的资源放在这个空间中。
- kube-node-lease 租约(Lease)对象使用的命名空间。每个节点都有一个关联的 lease 对象,lease 是一种轻量级资源。lease对象通过发送心跳,检测集群中的每个节点是否发生故障。
使用kubectl get lease -A查看lease对象
作用
命名空间可以在多个用户之间划分集群资源(通过资源配额)。
- 例如我们可以设置开发、测试、生产等多个命名空间。
使用方式
同一命名空间内的资源名称要唯一,但跨命名空间时没有这个要求。
命名空间作用域仅针对带有名称空间的对象,例如 Deployment、Service 等。
这种作用域对集群访问的对象不适用,例如 StorageClass、Node、PersistentVolume 等。
使用多个命名空间
●命名空间是在多个用户之间划分集群资源的一种方法(通过资源配额)。
例如我们可以设置开发、测试、生产等多个命名空间。
●不必使用多个命名空间来分隔轻微不同的资源。
例如同一软件的不同版本: 应该使用标签 来区分同一命名空间中的不同资源。
●命名空间适用于跨多个团队或项目的场景。
对于只有几到几十个用户的集群,可以不用创建命名空间。
●命名空间不能相互嵌套,每个 Kubernetes 资源只能在一个命名空间中。
ns
查看 ns
创建 ns
ns 使用说明
管理命名空间
切换当前命名空间
示例:
示例过程:
- pod 的直接使用
- 为什么不直接创建 pod -> 不保证高可用
- rs 的使用
- deploy 的使用
- 命令式 vs 声明式(结合 gitlab/gitbook 可追溯)
- 应用部署的正确打开方式:deploy -> rs -> pod
- 为什么不直接应用 rs 而是用 deploy -> deploy 功能更强大
- service 使用
- service 的作用 ->
- namespace 使用
https://blog.csdn.net/An1090239782/article/details/110129400
pod 的使用
直接创建 pod
kubectl run nginx-demo --image=nginx
删除 pod
kubectl delete pod nginx-demo --force
删除 pod 之后 pod 就会被彻底删除
rs 的使用
声明式 rs 使用
- 创建配置文件:pod_nginx_rs.yaml
应用配置文件:
kubectl create -f pod_nginx_rs.yaml
kubectl apply -f pod_nginx_rs.yaml
kubectl create VS kubectl apply
https://blog.csdn.net/textdemo123/article/details/104400985
删除 rs
kubectl delete rs nginx-rs
deployment
命令式:
直接创建 deployment
#创建deployment,部署3个运行nginx的Pod
kubectl create deployment nginx-deployment --image=nginx:1.22 --replicas=3
通常使用声明式配置文件:
查看创建 rs
kubectl get rs
查看创建 pod
kubectl get pod
pod 扩缩容
- 手动
- 自动
滚动更新
版本回滚
金丝雀发布
发布新版本的应用,镜像使用docker/getting-started,数量为 1。
应用文件:
kubectl apply -f deploy-canary.yaml
分配流量

●调整比例
待稳定运行一段时间后,扩大试用范围,将部署的v2版本数量调整为3,v1和v2的数量都是3个。
●下线旧版本
最后下线所有v1版本,所有服务升级为v2版本。
清空环境
使用namespace可以方便的清空环境:
