一、网络插件 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)。

  • 典型用途:容器进程卡死、死循环、死锁时,用它来自动重启恢复。 例子

    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. 区别总结表

探针类型

触发动作

典型用途

Liveness

失败 → 容器重启

死锁、进程挂掉

Readiness

失败 → Pod 从 Service 移除

应用暂时不可用

Startup

失败 → 容器重启(仅启动阶段)

启动慢的应用


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** 中,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 名字:

      <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  # 基于节点调度
​

~

文章作者: 楚少爱看雪
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 楚少爱看雪
学习 Study
喜欢就支持一下吧