k8s面试题总结
一、网络插件 calico 的工作模式有哪几种
Calico 在 Kubernetes 中的工作模式主要分为以下几种,你在部署时可以根据集群环境、需求和底层网络选择不同模式:
1. BGP 模式
原理:每个节点运行
calico/node,节点之间通过 BGP(Border Gateway Protocol) 交换路由信息。特点:
Pod IP 在整个集群中是可路由的,不需要 NAT。
不依赖 Overlay(隧道),性能好,延迟低。
常见有两种拓扑:
Full-mesh BGP:所有节点互相建立 BGP 对等关系,适合小规模集群(几十个节点)。
Route Reflector 模式:大规模集群时,用一部分节点做 BGP Route Reflector 来减少对等连接数。
2. IP-in-IP 模式
原理:在节点之间使用 IP-in-IP 封装(类似 Overlay 网络),解决节点之间路由不可达的问题。
特点:
适合没有配置 BGP 或底层网络不支持 Pod CIDR 直通的环境。
数据包经过一次封装,性能比 BGP 模式稍差。
默认模式之一,部署简单。
3. VXLAN 模式
原理:和 IP-in-IP 类似,但使用 VXLAN 封装。
特点:
通常在云环境或底层网络受限时使用。
VXLAN 隧道更通用(大多数云厂商都支持),兼容性强。
性能比纯三层(BGP 模式)差一些。
4. CrossSubnet 模式
原理:结合 BGP 和隧道(IP-in-IP 或 VXLAN)。
特点:
同一子网内节点之间直接路由,不走隧道。
跨子网节点之间才使用隧道封装。
在性能和兼容性之间做平衡。
5. Policy-only 模式
原理:只使用 Calico 的 网络策略(NetworkPolicy) 功能,不负责 Pod 的网络互通。
特点:
依赖 CNI 提供网络(比如 Flannel、Cilium、AWS VPC CNI),Calico 仅作为策略控制器。
适合只想用 Calico 强大的安全策略功能的场景。
总结一下常见选择:
高性能裸机/自建数据中心 → BGP 模式(大规模用 Route Reflector)。
云环境 / 无法直通路由 → VXLAN 或 IP-in-IP 模式。
混合环境 → CrossSubnet。
只要策略,不要网络 → Policy-only。
这是 Calico 各种工作模式的对比图(性能、兼容性、安全性 评分 1~5):
BGP:性能最佳,但兼容性取决于底层网络是否支持。
IP-in-IP / VXLAN:兼容性强,适合云环境,但性能比直连稍差。
CrossSubnet:性能和兼容性折中。
Policy-only:依赖其他 CNI 提供网络,安全策略功能最强。
二、cgroup 和 ns 的区别
在 **Linux 容器技术**里,cgroup(control group)和 namespace(命名空间)是两大核心概念,它们解决的问题完全不同,但又经常配合使用。
1. cgroup(控制组)
作用:限制和管理进程可以使用的资源。
核心点:资源隔离 + 限额控制。
常见控制的资源:
CPU(限制某个进程组最多使用多少 CPU 时间)
内存(限制最大内存使用,超过时 OOM Kill)
磁盘 I/O(限制读写带宽)
网络带宽(在某些扩展里支持)
使用场景:
Docker 限制容器 CPU、内存用量
Kubernetes Pod 资源请求/限制(requests/limits)
类比:像给进程“配额”,规定它能吃多少饭、喝多少水。
2. namespace(命名空间)
作用:提供进程间的隔离环境。
核心点:视图隔离 + 资源虚拟化。
常见类型:
PID namespace:进程号隔离(容器里的 PID 1 不会看到宿主机 PID)
NET namespace:网络隔离(容器有独立网卡、IP、路由)
IPC namespace:进程间通信隔离(消息队列、信号量)
UTS namespace:主机名隔离(容器可有不同 hostname)
MNT namespace:挂载点隔离(不同文件系统视图)
USER namespace:用户和权限隔离(容器里 root 映射到宿主机普通用户)
使用场景:
让容器拥有独立的文件系统、进程树、网络栈
类比:像给进程戴上“VR 眼镜”,它只能看到自己虚拟出来的世界。
三、ns 隔离资源的原理
要理解 **namespace(命名空间)是如何实现隔离的,得从 Linux 内核的设计原理** 说起。
1. 基础概念
在 Linux 内核里,**一切都是全局的**:
默认情况下,所有进程共享同一套 **进程号表、网络协议栈、挂载点表、主机名、IPC 资源**。
如果没有特殊机制,所有进程看到的都是同一个“系统”。
Namespace 的作用:就是在内核中创建多个“虚拟副本”,让进程只能访问自己那份副本,从而实现隔离。
2. 工作原理
(1)内核数据结构“虚拟化”
内核会为某些全局资源,设计一层 **namespace 抽象层**。
当新建一个 namespace 时,内核会生成该资源的“独立副本”。
不同 namespace 下的进程,指向的是 **不同的内核对象**。
例如:
PID namespace:每个 namespace 都有独立的 PID 映射表。容器里的 PID 1,其实在宿主机可能是 2345。
NET namespace:每个 namespace 有自己的网卡、路由表、iptables 规则。容器之间网络互不影响。
MNT namespace:挂载点表被隔离,不同容器看到的文件系统层次不同。
(2)进程与 namespace 的绑定
每个进程在内核中都有一个
task_struct结构体。里面包含指针,指向该进程所属的 **namespace 对象**(pid_ns、net_ns、mnt_ns…)。
所以 **同一宿主机上的进程,可以属于不同的 namespace**。
(3)系统调用支持
Linux 提供了
clone()、unshare()、setns()等系统调用,用来创建或切换 namespace。容器运行时(Docker、containerd、K8s)启动容器时,会调用这些 API:
clone(CLONE_NEWNET)→ 创建新的网络栈clone(CLONE_NEWPID)→ 创建新的 PID 空间clone(CLONE_NEWNS)→ 创建新的挂载空间
3. 类比理解
namespace 就像一个 隔板,把原本全局共享的大空间分隔成多个小房间,每个进程只能在自己的房间里活动。
进程看不到房间外的东西,所以它“以为”自己独占了系统。
🔹 总结
原理:namespace 通过内核抽象层,把全局资源复制/虚拟化成多个实例,每个进程只绑定到自己的实例。
关键点:
数据结构隔离(不同 namespace,资源表不同)
进程与 namespace 绑定(task_struct 记录所属 ns)
系统调用支持(clone/unshare/setns 管理 ns 生命周期)
⚡ 一句话:namespace 通过在内核中为全局资源建立多个副本 + 进程绑定不同副本,实现“视图隔离”。
四、k8s 创建 pod 的流程
Kubernetes 创建一个 Pod,其实涉及 **API Server、调度器、kubelet、容器运行时** 等多个核心组件。我给你梳理下 从用户提交 YAML 到 Pod 运行起来 的完整流程。
1. 用户提交请求
用户通过
kubectl apply -f pod.yaml或 API 调用,向 API Server 发送创建 Pod 的请求。API Server:
接收请求
校验 YAML(合法性、schema、资源配额、Admission Webhook…)
存储 Pod 对象到 **etcd**
👉 此时,Pod 对象已经存在于 etcd,但还没运行。
2. 调度流程
调度器(kube-scheduler) 会监听到新 Pod 处于
Pending状态。调度器:
根据调度策略(资源请求/限制、亲和性/反亲和性、污点/容忍度、优先级等)筛选可用节点
选择一个最优节点
把调度结果(Pod → 节点)写回 **API Server**
👉 此时,Pod 还是 Pending,但已经绑定到某个 Node。
3. kubelet 创建 Pod
目标节点上的 **kubelet** 监听到有 Pod 调度过来。
kubelet 执行以下步骤:
向 API Server 拉取 Pod 的定义
创建 **PodSandbox**(通常是一个 pause 容器,充当 Pod 的网络 & namespace 容器)
配置 Pod 网络(CNI 插件:Calico、Flannel…,为 Pod 分配 IP)
配置存储卷(挂载 PV、PVC、本地目录、ConfigMap、Secret 等)
拉取镜像(containerd / CRI-O / Docker shim)
启动 Pod 中定义的各个容器
👉 此时,容器运行起来,Pod 进入 Running 状态。
4. Pod 生命周期管理
kubelet 持续监控容器状态,上报给 API Server。
API Server 把状态写入 etcd。
用户通过
kubectl get pod看到的状态,其实是从 etcd → API Server → kubectl 返回的结果。如果容器异常退出,kubelet 会按 Pod 的
restartPolicy(Always/OnFailure/Never)决定是否重启。
5. 事件流总结
kubectl / API → 请求创建 Pod
API Server → 校验、存储到 etcd
调度器 → 选择节点,更新 Pod 绑定信息
kubelet(目标节点) → 创建 PodSandbox、网络、存储、拉镜像、启动容器
Pod Running → 状态通过 kubelet 上报 API Server
🔹 总结
API Server:前台,接收请求,存储对象
Scheduler:选人(决定 Pod 跑在哪个节点)
Kubelet:干活的工人(在节点上真正创建容器)
etcd:存档,保存集群所有状态
⚡一句话:用户提交 YAML → API Server 存储 → Scheduler 分配 → Kubelet 创建 → Pod Running。
五、svc 暴露端口用到的是哪个组件
bernetes 里,**Service (svc)** 暴露端口时用到的核心组件主要是 kube-proxy。
Service 暴露端口的实现组件
1. kube-proxy
运行在每个节点上。
作用:
监听 API Server 上的 Service 和 Endpoints 变化。
在节点上设置转发规则,让访问
ServiceIP:Port能被转发到后端 Pod。
实现方式:
iptables 模式(常用):基于 iptables 的 DNAT 规则转发流量。
ipvs 模式:基于 Linux IPVS,性能更好,支持更多调度算法(rr、lc、dh 等)。
userspace 模式(很少用,性能差)。
👉 **核心点:Pod 内部或节点上访问 Service ClusterIP,流量先经过 kube-proxy 配置的规则**,再转发到某个 Pod。
2. Service 类型决定是否需要其他组件
ClusterIP(默认):
仅集群内部可访问。
依赖 kube-proxy 实现端口转发。
NodePort:
在每个 Node 上打开一个端口(30000–32767)。
仍由 kube-proxy 维护规则,把访问 Node:Port 的流量转发到 Pod。
LoadBalancer:
需要依赖云厂商的 **云负载均衡器**(比如 AWS ELB、阿里云 SLB)。
kube-proxy 仍然负责节点内部转发。
ExternalName:
不依赖 kube-proxy,只是 DNS CNAME 到外部地址。
🔹 总结
核心组件:
kube-proxy(iptables 或 ipvs 规则,负责转发 Service 流量)。扩展组件:
NodePort → 依赖 kube-proxy
LoadBalancer → 依赖 **云厂商 LB + kube-proxy**
ExternalName → 依赖 DNS,不走 kube-proxy
⚡一句话:Kubernetes Service 暴露端口的底层实现,核心就是 kube-proxy,它在每个节点配置转发规则,把 Service IP/端口映射到后端 Pod。
六、云上以及二进制部署的k8s 怎样扩容集群
☁️ 云上 K8s 扩容
(典型:阿里云 ACK、腾讯云 TKE、AWS EKS、GKE、AKS)
1. 控制平面扩容
大多数云厂商已经提供了高可用的 API Server / etcd 管理,用户通常不需要手动扩容控制平面。
如果支持 **专有集群 / 自管控制平面,一般通过控制台或 API 新增 Master 节点**,云平台会自动调整
etcd和kube-apiserver。
2. Node 扩容
方式一:**控制台/CLI 一键加节点**
在控制台选择“添加节点” → 选择云服务器规格、数量。
系统自动安装 kubelet / kube-proxy,并加入集群。
方式二:**弹性伸缩 (Cluster Autoscaler)**
开启自动伸缩,云平台会自动创建/释放节点。
常用于弹性业务场景。
👉 云上扩容的关键是:节点由云厂商提供初始化脚本,自动向 API Server 注册。
🖥 二进制部署 K8s 扩容
(二进制方式:kubeadm 之外的纯手工安装,常见于生产环境或大规模私有云)
1. 扩容 Master 节点
需要手动准备新服务器,安装:
kube-apiserver、kube-scheduler、kube-controller-manager。将新 Master 加入现有的 etcd 集群:
在 etcd 上添加新成员 → 同步数据
修改所有 Master 配置 → 让它们都能访问完整 etcd 集群
配置 kube-apiserver 使用新的 etcd 集群。
配置高可用入口(Nginx/HAProxy/Keepalived/VIP)来统一 API Server 地址。
2. 扩容 Node 节点
步骤:
在新机器上安装必要组件:
kubelet
kube-proxy
CNI 插件(Calico/Flannel/Cilium 等)
配置 kubelet:
指定
--kubeconfig指向 API Server设置节点名、证书、工作目录
启动 kubelet → kubelet 会向 API Server 注册自己。
管理员在 Master 上
kubectl get nodes查看新节点状态。
3. 注意点
证书签发:如果启用了 TLS,需要新节点的 kubelet 证书由集群 CA 签发。
网络:确保新节点与 Pod 网段、Service 网段互通。
负载均衡:如果是 Master 扩容,记得更新 LB 配置,把新 Master 加入。
🔹 总结对比
⚡一句话:
云上扩容 → 控制台点几下,节点自动加进来。
二进制扩容 → 自己装 kubelet/kube-proxy/网络插件,搞证书,搞 etcd/LB。
七、k8s有几种探针以及区别 探针失败了 k8s 会咋样
exec TCPSoket HTTPGet
在 Kubernetes 里 **Pod 的健康检查是靠 探针 (Probe)** 实现的,一共有三种:
1. 探针类型
✅ Liveness Probe(存活探针)
作用:判断容器是否“还活着”。
失败时行为:kubelet 会 杀掉容器并重启(遵循
restartPolicy)。典型用途:容器进程卡死、死循环、死锁时,用它来自动重启恢复。 例子
livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 10 periodSeconds: 5
解释:
容器启动后 10 秒开始检测。
每 5 秒检查一次
/healthz接口。如果接口连续失败,k8s 会重启容器。
2. Readiness Probe(就绪探针)
作用:检查容器是否 准备好接收流量。
行为:如果 Readiness 探针失败,Pod 会 从 Service 的 Endpoints 中移除,不会被流量路由到。
典型场景:应用启动慢,或者加载了大数据才真正可用。
示例:
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5解释:
容器启动 5 秒后开始检查
/ready接口。接口失败则表示容器暂时不接收流量,但不会被重启。
3. Startup Probe(启动探针)
作用:用于检测 容器启动是否成功,适用于启动慢的应用。
行为:
在容器启动阶段,Startup Probe 失败会 **直接重启容器**。
启动完成后,Startup Probe 会停止工作,交给 Liveness Probe 监控。
典型场景:Java、数据库等启动很慢的服务。
例子
startupProbe:
httpGet:
path: /healthz
port: 8080
failureThreshold: 30
periodSeconds: 10解释:
每 10 秒检查一次
/healthz。连续失败 30 次才重启容器,适合启动时间较长的应用。
4. 区别总结表
5. 举例说明容器探针失败后的行为
假设我们有一个 Nginx 容器:
containers:
- name: nginx
image: nginx
livenessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 5
periodSeconds: 2如果
/healthz接口返回非 200,连续失败:k8s 会杀掉 nginx 容器并重启。
如果我们加了 Readiness Probe:
Pod 会暂时被 Service 下线,不会被访问,直到探针恢复。
八、k8s组件总览
1️⃣ 命名空间 / 资源隔离相关
Namespace(命名空间):Kubernetes 内置,用于逻辑隔离资源。
NetworkPolicy:控制 Pod 间网络访问策略,实现隔离。
RBAC(Role/ClusterRole):权限隔离。
ResourceQuota / LimitRange:资源使用隔离。
类似 “ns” 的概念,主要是做逻辑分组、隔离和权限控制。
2️⃣ 服务发现 / DNS
CoreDNS:
默认集群 DNS 组件。
为 Pod 提供
service-name.namespace.svc.cluster.local解析。
kube-dns(旧版,已被 CoreDNS 替代)。
ExternalDNS:
将 Kubernetes Service 的域名自动同步到外部 DNS(如 Route53、阿里云 DNS)。
核心功能是名字解析和服务发现,类似 Linux 下的
nslookup/hosts功能,但在集群内部自动化。
3️⃣ 网络 / CNI 相关
CNI 插件(Container Network Interface):
Calico:提供网络策略和安全组功能。
Flannel:简单的 L2/L3 网络实现。
Weave Net:支持加密和跨节点 Pod 通信。
Cilium:基于 eBPF 的高级网络和安全策略。
kube-proxy:
实现 ClusterIP、Service 负载均衡。
这些组件都和 Pod 通信、网络路由、服务发现有关系。
4️⃣ 配置 / 配置管理
ConfigMap:管理非敏感配置信息。
Secret:管理敏感信息(密码、证书)。
ServiceAccount / Token:提供 Pod 对 API Server 的访问凭证。
配置、密钥、访问控制也是“命名和资源管理”的一部分。
5️⃣ 高级服务发现 / 服务网格
Istio / Linkerd / Consul:
提供微服务间流量管理、服务发现、可观测性。
结合 Envoy 代理实现 L7 层流量控制。
💡 总结: ** “类似 ns 的组件”,可以理解为 命名、隔离、发现、路由**相关的系统组件,主要包括:
命名空间、RBAC、资源配额(隔离)
CoreDNS / kube-dns / ExternalDNS(服务发现)
CNI 插件、kube-proxy(网络和路由)
配置管理组件(ConfigMap / Secret)
高级服务网格(Istio / Consul / Linkerd)
九、Deployment StatefulSet 有状态的和无状态的服务之间的区别
在 **Kubernetes** 中,Deployment 和 StatefulSet 是两种常见的 工作负载控制器,主要用于管理 无状态服务 和 有状态服务。它们的区别主要体现在以下几个方面:
1. 适用场景
Deployment(无状态服务)
用于 **无状态应用**,比如 Nginx、前端应用、微服务 API、负载均衡器等。
每个 Pod 都是相同的,之间没有身份差异,随时可替换或扩缩容。
StatefulSet(有状态服务)
用于 **有状态应用**,比如 MySQL、Redis(主从)、Zookeeper、Kafka、Etcd。
每个 Pod 都有 **固定身份**(编号、存储),不能随便替换。
2. Pod 标识(Identity)
Deployment
Pod 名称是随机的,比如:
nginx-5c9c7d8c9f-abc12。删除一个 Pod,再起的新 Pod 名字不同。
所有 Pod **对外是一样的**。
StatefulSet
Pod 有固定的编号,比如:
mysql-0,mysql-1,mysql-2。删除
mysql-1后,新建的 Pod 还是mysql-1。Pod 之间有顺序和唯一身份。
3. 存储(Storage)
Deployment
一般配合 **临时存储(emptyDir)** 或共享存储。
Pod 删除后数据也会丢失。
StatefulSet
支持 **稳定的持久化存储(PVC)**,通常由
volumeClaimTemplates生成。即使 Pod 被删除或迁移,数据依然会保留,并重新挂载到同编号的 Pod 上。
4. 启动顺序与依赖
Deployment
Pod 可以 **无序并行启动**,因为它们没有依赖关系。
StatefulSet
Pod 有顺序:先启动
pod-0,再启动pod-1……删除时也是 **逆序删除**。
适合需要 **主从/集群初始化** 的场景。
5. 网络标识(DNS)
Deployment
Pod 的 DNS 名字是随机的,只能通过 Service 访问。
StatefulSet
每个 Pod 都有稳定的 DNS 名字:
<pod-name>.<service-name>.<namespace>.svc.cluster.local 比如:mysql-0.mysql.default.svc.cluster.local方便应用之间直接通过固定域名访问。
6. 典型使用场景
Deployment(无状态)
Web 服务(Nginx、Tomcat)
API 服务
静态内容服务
StatefulSet(有状态)
数据库(MySQL、Postgres、MongoDB)
分布式协调服务(ZooKeeper、Etcd、Consul)
消息队列(Kafka、RabbitMQ)
📌 总结一句话
如果应用 **不依赖持久存储、Pod 身份、启动顺序** → 用 Deployment。
如果应用 **需要固定身份、稳定存储、顺序启动** → 用 StatefulSet。
十、yaml方式介绍deploy有哪些组件
qexo
# 前置准备
# 设置污点
# kubectl taint nodes k8s1 tag=heima:NoExecute
# # 去除污点
# kubectl taint nodes k8s1 tag:NoExecute-
# # 例子
# kubectl taint nodes gegewu node-role.kubernetes.io/control-plane:NoSchedule-
# # 查看污点设置是否成功
# kubectl describe nodes |grep Taints
# # Taints: tag=heima:NoExecute
# # Taints: <none>
# # 设置节点标签
# kubectl label nodes k8s1 nodeenv=pro
# kubectl get nodes --show-labels
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: qexo
namespace: dev
spec:
replicas: 3 # 修改为3副本
# 定义滚动更新
# ● 重建更新 Recreate: 在创建出该label下新的Pod之前会先杀掉所有已存在的Pod
# ● 滚动更新: 可以通过strategy指定策略类型, 支持两个属性
revisionHistoryLimit: 3 # 保留历史版本,是为了版本回退
paused: false # 暂停部署,默认是false 即创建完deploy立即开始部署pod
progressDeadlineSeconds: 600 # 部署超时时间(s),默认是600
strategy: # 策略
type: RollingUpdate # 滚动更新策略 或 Recreate 重建更新
rollingUpdate: # 滚动更新
maxSurge: 25% # 在更新过程中,最多可以增加的 Pod 数量
maxUnavailable: 30% # 最大不可用状态的 Pod 的最大值,可以为百分比,也可以为整数
# 重建更新(另一种方式)
# strategy:
# type: Recreate
selector:
matchLabels:
app: qexo # 必须与 .spec.template.metadata.labels 匹配
template:
metadata:
labels:
app: qexo # 必须与 .spec.selector.matchLabels 匹配
spec:
terminationGracePeriodSeconds: 10
containers:
- name: qexo
image: registry.cn-hangzhou.aliyuncs.com/zznn/mycentos:qexo-3.6.0
ports:
- containerPort: 8000
name: qexo
# command: ["/bin/sh","-c","while true;do /bin/echo $(date +%T);sleep 60; done;"]
# 环境变量
env:
- name: "username"
value: "admin"
- name: "password"
value: "123456"
# 资源配额
resources:
limits: # 限制资源(上限)
cpu: "2" # CPU限制,单位是core数
memory: "10Gi" # 内存限制
requests: # 请求资源(下限)
cpu: "1" # CPU请求,单位是core数
memory: "1000Mi" # 内存请求
# 磁盘挂载
volumeMounts:
- name: qexo-volume
mountPath: /app/db # 挂载到目录而不是单个文件
# 勾子函数
# ● post start:容器创建之后执行,如果失败了会重启容器
# ● pre stop :容器终止之前执行,执行完成之后容器将成功终止,在其完成之前会阻塞删除容器的操作
# 钩子处理器支持使用下面三种方式定义动作:
# ● Exec命令:在容器内执行一次命令
# ● 相当于 docker 中 docker exec -it centos ls 这样的命令
# lifecycle:
# postStart:
# exec: # 在容器启动的时候执行一个命令,修改掉nginx的默认首页内容
# command: ["/bin/sh", "-c", "echo postStart... > /usr/share/nginx/html/index.html"]
# preStop:
# exec: # 在容器停止之前停止nginx服务
# command: ["/usr/sbin/nginx","-s","quit"]
# 容器探针
# ● liveness probes:存活性探针,用于检测应用实例是否存活,如果不是,k8s会重启容器
# ● readiness probes:就绪性探针,用于检测实例是否可以接收请求,如果不能,k8s不会转发流量
# ● livenessProbe 决定是否重启容器,readinessProbe 决定是否将请求转发给容器
# 上面两种探针支持三种探测方式:
# ● Exec命令、● HTTP请求、● TCP Socket
# livenessProbe:
# httpGet: # 实际就是访问 http://127.0.0.1:8000/
# scheme: HTTP # 协议,http 或 https
# port: 8000 # 端口号
# path: / # URI地址
livenessProbe:
tcpSocket:
port: 8000 # 尝试访问8080端口
# 宿主机挂载目录(不存在就创建)
volumes:
- name: qexo-volume
hostPath:
path: /opt/qexo/app/db # 宿主机目录
type: DirectoryOrCreate
# 污点与容忍
# ● PreferNoSchedule:尽量避免调度,但非强制
# ● NoSchedule:不会调度到带此污点的节点,但已有Pod不受影响
# ● NoExecute:不会调度,并驱逐已有Pod
# 如果污点的效果是NoExecute,需在容忍规则中设置 effect: "NoExecute"
# 也可以省略 effect,用 operator: "Exists" 容忍任意效果
tolerations:
- key: "tag"
operator: "Exists"
# 亲和性设置(软限制)
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution: # 软限制
- weight: 1
preference:
matchExpressions: # 匹配 nodeenv 标签的值在 ["pro","yyy"] 中的节点
- key: nodeenv
operator: In
values: ["pro","yyy"]
# 亲和性设置(硬限制)
# affinity:
# podAffinity: # 设置pod亲和性
# requiredDuringSchedulingIgnoredDuringExecution: # 硬限制
# - labelSelector:
# matchExpressions: # 匹配podenv的值在 ["xxx","yyy"] 的标签
# - key: podenv
# operator: In
# values: ["xxx","yyy"]
# topologyKey: kubernetes.io/hostname # 基于节点调度
---
# 暴露qexo端口
apiVersion: v1
kind: Service
metadata:
namespace: dev
name: qexo-service
spec:
selector:
app: qexo
ports:
- protocol: TCP
port: 8000
targetPort: 8000
sessionAffinity: ClientIP
type: NodePort # 将服务暴露为 NodePort 类型
nginx
# 前置准备
# 设置污点
# kubectl taint nodes k8s1 tag=heima:NoExecute
# # 去除污点
# kubectl taint nodes k8s1 tag:NoExecute-
# # 例子
# kubectl taint nodes gegewu node-role.kubernetes.io/control-plane:NoSchedule-
# # 查看污点设置是否成功
# kubectl describe nodes |grep Taints
# # Taints: tag=heima:NoExecute
# # Taints: <none>
# # 设置节点标签
# kubectl label nodes k8s1 nodeenv=pro
# kubectl get nodes --show-labels
apiVersion: apps/v1 # 版本
kind: Deployment # 类型
metadata: # 源数据
name: deploy-nginx # 当前deployment所属的名字
namespace: dev # 命名空间
labels: # 当前deploy的标签
version: "label-test"
# 此栏目配置滚动更新配置
spec:
replicas: 3 # 定义副本数
# 定义滚动更新
# ● 重建更新Recreate 在创建出该label下新的Pod之前会先杀掉所有已存在的Pod
# ● 滚动更新,可以通过strategy指定策略类型,支持两个属性:
revisionHistoryLimit: 3 # 保留历史版本 是为了版本回退
paused: false # 暂停部署,默认是false 即创建完deploy立即开始部署pod
progressDeadlineSeconds: 600 # 部署超时时间(s),默认是600
strategy: # 策略
type: RollingUpdate # 滚动更新策略 或Recreate重建更新
rollingUpdate: # 滚动更新
# 违规词汇: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数
maxSurge: 25% # 在更新过程中,最多可以增加的 Pod 数量
maxUnavailable: 30% # 最大不可用状态的 Pod 的最大值,可以为百分比,也可以为整数
# 重建更新
#strategy: # 策略
#type: Recreate # 重建更新
selector: # 标签选择器 选择标签进行操作
matchLabels: # 选择nginx标签
version: label-test
template: # 以下为pod 模板
metadata:
labels: # 标签
version: label-test # 定义标签为label-test
spec:
# 镜像信息等
containers:
- name: nginx-test
image: registry.cn-hangzhou.aliyuncs.com/zznn/mycentos:nginx-latest
imagePullPolicy: IfNotPresent # 用于设置镜像拉取策略
# cmd变量与端口
ports:
- containerPort: 80
protocol: TCP
command: ["/bin/sh","-c","while true;do /bin/echo $(date +%T);sleep 60; done;"]
env: # 设置环境变量列表
- name: "username"
value: "admin"
- name: "password"
value: "123456"
# 资源配额
resources:
limits: # 限制资源(上限)
cpu: "2" # CPU限制,单位是core数
memory: "10Gi" # 内存限制
requests: # 请求资源(下限)
cpu: "1" # CPU限制,单位是core数
memory: "10Mi" # 内存限制
# 勾子函数
lifecycle:
postStart:
exec: # 在容器启动的时候执行一个命令,修改掉nginx的默认首页内容
command: ["/bin/sh", "-c", "echo postStart... > /usr/share/nginx/html/index.html"]
preStop:
exec: # 在容器停止之前停止nginx服务
command: ["/usr/sbin/nginx","-s","quit"]
# nodeName: node1 # 定向调度
# ● PreferNoSchedule:kubernetes将尽量避免把Pod调度到具有该污点的Node上,除非没有其他节点可调度
# ● NoSchedule:kubernetes将不会把Pod调度到具有该污点的Node上,但不会影响当前Node上已存在的Pod
# ● NoExecute:kubernetes将不会把Pod调度到具有该污点的Node上,同时也会将Node上已存在的Pod驱离
# tag=heima:NoExecute
# 如果污点的效果是NoExecute,那么您需要在容忍规则中设置effect: "NoExecute"。
# 如果污点的效果不确定,也可以省略effect字段,用operator: "Exists"来容忍任何效果。例如:
tolerations: # 添加容忍
- key: "tag" # 要容忍的污点的key
operator: "Equal" # 操作符(等于操作符)
value: "heima" # 容忍的污点的value
effect: "NoExecute" # 添加容忍的规则,这里必须和标记的污点规则相同
# 容忍任何效果
#- key: "tag"
# operator: "Exists"
# 亲和性设置(软限制)
affinity:
nodeAffinity: # 设置node亲和性
preferredDuringSchedulingIgnoredDuringExecution: # 软限制
- weight: 1
preference:
matchExpressions: # 匹配env的值在["xxx","yyy"]中的标签(当前环境没有)
- key: nodeenv
operator: In
values: ["pro","yyy"]
# # 亲和性设置(硬限制)
# affinity:
# podAffinity: # 设置pod亲和性
# requiredDuringSchedulingIgnoredDuringExecution: # 硬限制
# - labelSelector:
# matchExpressions: # 匹配env的值在["xxx","yyy"]中的标签
# - key: podenv
# operator: In
# values: ["xxx","yyy"]
# topologyKey: kubernetes.io/hostname # 基于节点调度
~