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 状态。
  • 调度器:
    1. 根据调度策略(资源请求/限制、亲和性/反亲和性、污点/容忍度、优先级等)筛选可用节点
    2. 选择一个最优节点
    3. **把调度结果(Pod → 节点)写回 **API Server

**👉 此时,Pod 还是 **Pending,但已经绑定到某个 Node。

3. kubelet 创建 Pod

  • **目标节点上的 **kubelet 监听到有 Pod 调度过来。
  • kubelet 执行以下步骤:
    1. 向 API Server 拉取 Pod 的定义
    2. **创建 **PodSandbox(通常是一个 pause 容器,充当 Pod 的网络 & namespace 容器)
    3. 配置 Pod 网络(CNI 插件:Calico、Flannel…,为 Pod 分配 IP)
    4. 配置存储卷(挂载 PV、PVC、本地目录、ConfigMap、Secret 等)
    5. 拉取镜像(containerd / CRI-O / Docker shim)
    6. 启动 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. 事件流总结

  1. kubectl / API → 请求创建 Pod
  2. API Server → 校验、存储到 etcd
  3. 调度器 → 选择节点,更新 Pod 绑定信息
  4. kubelet(目标节点) → 创建 PodSandbox、网络、存储、拉镜像、启动容器
  5. 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 节点,云平台会自动调整 etcdkube-apiserver

2. Node 扩容

方式一:****控制台/CLI 一键加节点

  • 在控制台选择“添加节点” → 选择云服务器规格、数量。
  • 系统自动安装 kubelet / kube-proxy,并加入集群。

方式二:****弹性伸缩 (Cluster Autoscaler)

  • 开启自动伸缩,云平台会自动创建/释放节点。
  • 常用于弹性业务场景。

**👉 **云上扩容的关键是:节点由云厂商提供初始化脚本,自动向 API Server 注册。

🖥 二进制部署 K8s 扩容

(二进制方式:kubeadm 之外的纯手工安装,常见于生产环境或大规模私有云)

1. 扩容 Master 节点

  • 需要手动准备新服务器,安装:kube-apiserverkube-schedulerkube-controller-manager
  • 将新 Master 加入现有的 etcd 集群:
    • 在 etcd 上添加新成员 → 同步数据
    • 修改所有 Master 配置 → 让它们都能访问完整 etcd 集群
  • 配置 kube-apiserver 使用新的 etcd 集群。
  • 配置高可用入口(Nginx/HAProxy/Keepalived/VIP)来统一 API Server 地址。

2. 扩容 Node 节点

步骤:

  1. 在新机器上安装必要组件:
    • kubelet
    • kube-proxy
    • CNI 插件(Calico/Flannel/Cilium 等)
  2. 配置 kubelet:
    • **指定 **--kubeconfig 指向 API Server
    • 设置节点名、证书、工作目录
  3. 启动 kubelet → kubelet 会向 API Server 注册自己。
  4. **管理员在 Master 上 **kubectl get nodes 查看新节点状态。

3. 注意点

  • 证书签发:如果启用了 TLS,需要新节点的 kubelet 证书由集群 CA 签发。
  • 网络:确保新节点与 Pod 网段、Service 网段互通。
  • 负载均衡:如果是 Master 扩容,记得更新 LB 配置,把新 Master 加入。

🔹 总结对比

部署方式Master 扩容Node 扩容
云上托管云厂商自动维护,用户无需操作控制台/CLI 添加节点,或启用弹性伸缩
二进制自建手动安装组件,加入 etcd,配置 LB手动安装 kubelet/kube-proxy,配置证书,加入 API Server

⚡一句话:

  • 云上扩容 → 控制台点几下,节点自动加进来
  • 二进制扩容 → 自己装 kubelet/kube-proxy/网络插件,搞证书,搞 etcd/LB。

七、k8s有几种探针以及区别 探针失败了 k8s 会咋样

exec TCPSoket HTTPGet

**在 Kubernetes 里 **Pod 的健康检查是靠 探针 (Probe) 实现的,一共有三种:

1. 探针类型

✅ Liveness Probe(存活探针)

  • 作用:判断容器是否“还活着”。
  • 失败时行为:kubelet 会 杀掉容器并重启(遵循 restartPolicy)。
  • 典型用途:容器进程卡死、死循环、死锁时,用它来自动重启恢复。
    例子
    1
    2
    3
    4
    5
    6
    livenessProbe:
    httpGet:
      path: /healthz
      port: 8080
    initialDelaySeconds: 10
    periodSeconds: 5

解释:

  • 容器启动后 10 秒开始检测。
  • **每 5 秒检查一次 **/healthz 接口。
  • 如果接口连续失败,k8s 会重启容器。

2. Readiness Probe(就绪探针)

  • 作用:检查容器是否 准备好接收流量
  • 行为:如果 Readiness 探针失败,Pod 会 从 Service 的 Endpoints 中移除,不会被流量路由到。
  • 典型场景:应用启动慢,或者加载了大数据才真正可用。

示例

1
2
3
4
5
6
readinessProbe:
httpGet:
  path: /ready
  port: 8080
initialDelaySeconds: 5
periodSeconds: 5

解释:

  • **容器启动 5 秒后开始检查 **/ready 接口。
  • 接口失败则表示容器暂时不接收流量,但不会被重启。

3. Startup Probe(启动探针)

  • 作用:用于检测 容器启动是否成功,适用于启动慢的应用。
  • 行为
    • **在容器启动阶段,Startup Probe 失败会 **直接重启容器
    • 启动完成后,Startup Probe 会停止工作,交给 Liveness Probe 监控。
  • 典型场景:Java、数据库等启动很慢的服务。

例子

1
2
3
4
5
6
startupProbe:
httpGet:
  path: /healthz
  port: 8080
failureThreshold: 30
periodSeconds: 10

解释:

  • **每 10 秒检查一次 **/healthz
  • 连续失败 30 次才重启容器,适合启动时间较长的应用。

4. 区别总结表

探针类型触发动作典型用途
Liveness失败 → 容器重启死锁、进程挂掉
Readiness失败 → Pod 从 Service 移除应用暂时不可用
Startup失败 → 容器重启(仅启动阶段)启动慢的应用

5. 举例说明容器探针失败后的行为

假设我们有一个 Nginx 容器:

1
2
3
4
5
6
7
8
9
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 中,DeploymentStatefulSet 是两种常见的 工作负载控制器,主要用于管理 无状态服务有状态服务。它们的区别主要体现在以下几个方面:


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 名字:
      1
      2
      <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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# 前置准备
# 设置污点
# 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# 前置准备
# 设置污点
# 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 # 基于节点调度

~