操作系统个人学习笔记(四):K8s基础

Pod

Pod 是 K8s 的最小调度单位,里面可以有一个或多个容器,这些容器共享网络、存储等资源。

Pod 里的容器共享什么
资源 是否共享 说明
网络 namespace 共享 同一个 Pod 内容器共用 IP、端口空间,可以用 localhost 通信
UTS namespace 共享 主机名相同
IPC namespace 共享 可以用共享内存、信号量
存储卷 Volume 可共享 多个容器可以挂同一个 volume
PID namespace 默认不共享 设置 shareProcessNamespace: true 才共享
MNT namespace 默认不共享 每个容器有自己的 rootfs

所以同一个 Pod 里:

  • 容器之间可以用 localhost 访问
  • 端口不能冲突
  • 主机名一样
  • 文件系统默认各自独立
  • 可以通过 volume 共享数据

通常一个 Pod 里放几个容器?

大多数情况:一个 Pod 一个主容器。

多容器常见于:

  • sidecar:日志收集、代理
  • init container:启动前初始化
  • adapter:格式转换

它们生命周期和调度绑定在一起。

设计时,多个容器是否放在一个Pod内的关键考虑因素
维度 适合同 Pod 的信号 应该拆开的信号
网络 必须用 localhost 通信,共享端口空间 通过 Service、API、消息队列通信即可
存储 必须共享同一个 volume,低延迟读写同一批文件 用 PVC、对象存储、数据库交换数据即可
生命周期 一起创建、一起删除,生命周期基本一致 一个长期运行,一个按任务创建销毁
调度 必须调度到同一节点 可以分散到不同节点
安全隔离 两者可信程度相同,安全要求一致 一个跑不可信代码,需要强隔离
扩缩容 副本数和扩缩容节奏一致 一个要扩,一个不用扩,或比例不同
资源边界 可以共享同一套资源限制和 QoS 需要独立 CPU/内存 limits、独立 QoS
失败影响 一个挂掉可以接受影响另一个 一个崩溃不应影响另一个

Node

节点(Node)就是 K8s 集群里的一台工作机器(虚拟机or物理机),Pod 最终跑在节点上。

节点一般可以根据职责分为两类------控制节点和工作节点

工作负载

Deployment

Deployment 是 K8s 里最常用的工作负载控制器,用来管理无状态 Pod 的副本

StatefulSet

StatefulSet 是专门用来管理有状态Pod的工作负载控制器

StatefulSet 和 Deployment 的核心区别

维度 Deployment StatefulSet
Pod 身份 随机名字,可互换 固定名字,如 web-0、web-1
网络标识 通常用 Service 负载均衡 每个 Pod 有稳定 DNS
存储 通常无状态,共享存储可选 每个 Pod 独立 PVC
启动顺序 并行启动 默认按顺序启动
扩缩顺序 随意 有序扩缩
更新顺序 滚动更新,任意替换 默认逆序更新
适用 无状态、可水平扩展 有状态、需要稳定标识和存储

Deployment + 普通 Service的K8s内部请求链路

复制代码
客户端
  -> DNS: web.default.svc.cluster.local
  -> 得到 ClusterIP: 10.96.0.10
  -> 向 ClusterIP 发请求
  -> 节点内核按 kube-proxy 规则 DNAT
  -> 转发到任意一个 Ready Pod(如 web-7d8f9c-abcde)

特点:

  • Pod 名字随机,客户端不关心连的是哪个
  • Service 做负载均衡
  • Pod 挂了、扩缩容,EndpointSlice 更新,规则自动变

StatefulSet + Headless Service的K8s内部请求链路

复制代码
客户端
  -> DNS: web.default.svc.cluster.local
  -> 得到所有 Pod IP 列表:[10.244.0.5, 10.244.0.6, 10.244.0.7]
  -> 客户端自己选一个 Pod IP
  -> 直连 Pod

特点:

  • 没有 ClusterIP
  • 不经过 kube-proxy VIP 转发
  • 负载均衡由客户端自己做
  • 适合 gRPC 客户端自己维护连接池

客户端(集群内部的其他Pod)如何知道DNS的Key(FQDN)的?------通过配置文件提前配置
有状态的Pod是不是就一定不能用Deployemnt?------不一定,如果不考虑可用性,Pod是单实例的话,那用Deployment也可以。核心决定性因素在于------Pod 挂掉重建后,能不能还以原来的身份,挂回原来分配给它的那个卷。单副本情况下不需要做多副本的区分,所以可以

Service------把IP:Port路由到具体的Pod

Service(服务) 是 Kubernetes 中用于为 Pod 提供稳定网络访问入口和负载均衡的核心组件,它抽象了 Pod 的网络访问方式,使得外部客户端或其他 Pod 可以通过 Service 访问后端 Pod,而无需关心 Pod 的具体 IP 地址或生命周期。Service本身也只是规则,真正处理流量的是kube-proxy。负责K8s的四层路由

Service的所有类型

K8s 里 Service 的 spec.type 官方只有 4 种:

类型 作用 外部能否访问 典型场景
ClusterIP 分配一个集群内部虚拟 IP 不能,默认仅集群内 集群内服务互访,默认类型
NodePort 在ClusterIP的基础上在每个节点上开一个端口 能,节点IP:端口 测试、简单暴露、无云 LB
LoadBalancer 向云/基础设施申请外部负载均衡器 能,外部LB IP:端口 生产环境暴露服务
ExternalName 用 DNS CNAME 指向外部域名 不代理流量,只做 DNS 映射 集群内访问外部服务

另外还有两个容易混淆的概念:

  • Headless Service :不是独立类型,而是 ClusterIP: None 的特殊 ClusterIP。
  • ExternalIPs :spec.externalIPs 字段,不是 Service 类型。
  • Ingress:不是 Service 类型,是七层入口,通常后端再接 Service。

ClusterIP

ClusterIP 是 K8s 给 Service 分配的一个集群内部虚拟 IP ,用来在集群内稳定地访问一组 Pod。

查看机器中的所有Service和其ClusterIP

复制代码
root@knowledgeskilltest:/home/zn# kubectl get services --all-namespaces
NAMESPACE                  NAME                               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE
default                    kubernetes                         ClusterIP   10.96.0.1       <none>        443/TCP                  8d
dynamic-test-runtime       dynamic-test-admission-projector   ClusterIP   10.96.211.7     <none>        9443/TCP                 6d1h
dynamic-test-runtime       dynamic-test-run                   ClusterIP   None            <none>        <none>                   6d1h
dynamic-test               dynamic-test-api                   ClusterIP   10.96.65.96     <none>        8010/TCP                 6d18h
dynamic-test               dynamic-test-gateway               ClusterIP   10.96.4.159     <none>        9444/TCP                 6d18h
dynamic-test               dynamic-test-projector             ClusterIP   10.96.122.184   <none>        8443/TCP                 6d18h
dynamic-test               minio                              ClusterIP   10.96.225.52    <none>        9000/TCP,9001/TCP        6d19h
dynamic-test               mock-event-sink                    ClusterIP   10.96.170.115   <none>        8443/TCP                 6d18h
dynamic-test               mock-model-provider                ClusterIP   10.96.252.70    <none>        8443/TCP                 6d18h
dynamic-test               mysql                              ClusterIP   10.96.3.129     <none>        3306/TCP                 6d19h
dynamic-test               registry                           ClusterIP   10.96.250.62    <none>        5000/TCP                 6d1h
dynamic-test               skillhub-mock                      ClusterIP   10.96.4.147     <none>        8443/TCP                 6d18h
kube-system                kube-dns                           ClusterIP   10.96.0.10      <none>        53/UDP,53/TCP,9153/TCP   8d
opensandbox-dynamic-test   opensandbox-ingress-gateway        ClusterIP   10.96.184.95    <none>        80/TCP                   7d
opensandbox-dynamic-test   opensandbox-server                 ClusterIP   10.96.152.62    <none>        8443/TCP                 6d23h

可以看到dynamic-test-run 这个Service其ClusterIP为None,这种Service 就是前文提到的Headless Service

查看机器中的所有Pod

复制代码
root@knowledgeskilltest:/home/zn# kubectl get pods -A -o wide
NAMESPACE                  NAME                                                 READY   STATUS      RESTARTS   AGE     IP             NODE                         NOMINATED NODE   READINESS GATES
dynamic-test-runtime       dynamic-test-admission-projector-7b967f54d8-vjs6j    1/1     Running     0          5d20h   10.244.0.165   dynamic-test-control-plane   <none>           <none>
dynamic-test-runtime       dynamic-test-admission-projector-7b967f54d8-x286g    1/1     Running     0          5d20h   10.244.0.164   dynamic-test-control-plane   <none>           <none>
dynamic-test-runtime       dynamic-test-run-0                                   1/1     Running     0          43h     10.244.0.18    dynamic-test-control-plane   <none>           <none>
dynamic-test-runtime       dynamic-test-run-1                                   1/1     Running     0          42h     10.244.0.22    dynamic-test-control-plane   <none>           <none>
dynamic-test-runtime       dynamic-test-run-2                                   1/1     Running     0          42h     10.244.0.21    dynamic-test-control-plane   <none>           <none>
dynamic-test-runtime       dynamic-test-runtime-reaper-7dbcddcb78-bzn9q         1/1     Running     0          5d20h   10.244.0.167   dynamic-test-control-plane   <none>           <none>
dynamic-test-runtime       dynamic-test-runtime-reaper-7dbcddcb78-kwlx5         1/1     Running     0          5d20h   10.244.0.163   dynamic-test-control-plane   <none>           <none>
dynamic-test               dynamic-test-api-556d6cbbbb-8949c                    1/1     Running     0          23h     10.244.0.36    dynamic-test-control-plane   <none>           <none>
dynamic-test               dynamic-test-assistant-96bfc89bd-4252m               1/1     Running     0          7d16h   10.244.0.123   dynamic-test-control-plane   <none>           <none>
dynamic-test               dynamic-test-image-74f65fdc7d-8f6xd                  1/1     Running     0          47h     10.244.0.238   dynamic-test-control-plane   <none>           <none>
dynamic-test               dynamic-test-migration-8bgfk                         0/1     Completed   0          7d17h   10.244.0.59    dynamic-test-control-plane   <none>           <none>
dynamic-test               dynamic-test-model-gateway-747dc9c58f-r5bps          1/1     Running     0          43h     10.244.0.6     dynamic-test-control-plane   <none>           <none>
dynamic-test               dynamic-test-projector-6d5684d6f9-67wpj              1/1     Running     0          7d16h   10.244.0.118   dynamic-test-control-plane   <none>           <none>
dynamic-test               dynamic-test-projector-6d5684d6f9-sbvjw              1/1     Running     0          7d16h   10.244.0.119   dynamic-test-control-plane   <none>           <none>
dynamic-test               dynamic-test-registry-d66678795-8spdp                1/1     Running     0          7d      10.244.0.135   dynamic-test-control-plane   <none>           <none>
dynamic-test               dynamic-test-relay-5c74788d86-x6drs                  1/1     Running     0          7d16h   10.244.0.121   dynamic-test-control-plane   <none>           <none>
dynamic-test               minio-59c78bffbd-kqqbp                               1/1     Running     0          7d17h   10.244.0.41    dynamic-test-control-plane   <none>           <none>
dynamic-test               mock-event-sink-7c966d5f7c-gzcmh                     1/1     Running     0          7d16h   10.244.0.107   dynamic-test-control-plane   <none>           <none>
dynamic-test               mock-model-provider-857bd94db8-8cq2h                 1/1     Running     0          44h     10.244.0.250   dynamic-test-control-plane   <none>           <none>
dynamic-test               mysql-6fcfccb8f8-92mld                               1/1     Running     0          7d17h   10.244.0.37    dynamic-test-control-plane   <none>           <none>
dynamic-test               skillhub-mock-5d785786c9-kz4bn                       1/1     Running     0          7d16h   10.244.0.114   dynamic-test-control-plane   <none>           <none>
ingress-nginx              ingress-nginx-controller-b6b495bc9-rrnrs             1/1     Running     0          4m22s   10.244.0.44    dynamic-test-control-plane   <none>           <none>
kube-system                coredns-559f6c778d-4wdfq                             1/1     Running     0          9d      10.244.0.3     dynamic-test-control-plane   <none>           <none>
kube-system                coredns-559f6c778d-mzqb8                             1/1     Running     0          9d      10.244.0.4     dynamic-test-control-plane   <none>           <none>
kube-system                etcd-dynamic-test-control-plane                      1/1     Running     0          9d      172.18.0.2     dynamic-test-control-plane   <none>           <none>
kube-system                kindnet-kkmdv                                        1/1     Running     0          9d      172.18.0.2     dynamic-test-control-plane   <none>           <none>
kube-system                kube-apiserver-dynamic-test-control-plane            1/1     Running     0          9d      172.18.0.2     dynamic-test-control-plane   <none>           <none>
kube-system                kube-controller-manager-dynamic-test-control-plane   1/1     Running     0          9d      172.18.0.2     dynamic-test-control-plane   <none>           <none>
kube-system                kube-proxy-vhnbx                                     1/1     Running     0          9d      172.18.0.2     dynamic-test-control-plane   <none>           <none>
kube-system                kube-scheduler-dynamic-test-control-plane            1/1     Running     0          9d      172.18.0.2     dynamic-test-control-plane   <none>           <none>
local-path-storage         local-path-provisioner-75f7fc7dc5-lh46q              1/1     Running     0          9d      10.244.0.2     dynamic-test-control-plane   <none>           <none>
opensandbox-dynamic-test   opensandbox-controller-manager-5d44fcc5f7-r7gvp      1/1     Running     0          2d      10.244.0.186   dynamic-test-control-plane   <none>           <none>
opensandbox-dynamic-test   opensandbox-ingress-gateway-656fb874c-sf8tv          1/1     Running     0          2d      10.244.0.187   dynamic-test-control-plane   <none>           <none>
opensandbox-dynamic-test   opensandbox-server-7b497b4b5c-nzm7s                  2/2     Running     0          46h     10.244.0.244   dynamic-test-control-plane   <none>           <none>

name为coredns开头的,就是负责将FQDN转化为IP的组件

  • 对于普通Service,其会将FQDN解析为ClusterIP
  • 对于Headless Service,其会将FQDN解析为后端Pod IP列表
  • StatefulSet 工作负载下的POD,会有稳定的POD名,也会有稳定的FQDN,coreDNS能将其转化为单个Pod 的IP

neme为kube-proxy开头的,就是负责将ClusterIP/NodePort流量转发到具体Pod的组件

NodePort

在每个节点 上开放同一个端口 ,把这个端口收到的流量,转发到 Service 后面的 Pod。一个端口对应一个Service

注意启用了NodePort后,整个Service一般依旧会有一个ClusterIP------NodePort负责对外,ClusterIP负责对内

LoadBalancer

本质上是 NodePort 的上一层封装 :在 NodePort 基础上,再向云厂商或基础设施申请一个独立的负载均衡器 IP。刚需公网IP

Q:LB怎么知道过来请求到底要访问哪个NodePort?

A:一个云 LB 可以为多个端口创建一个监听器,每个监听器分别映射到对应的后端------一个IP不同,但是Port相同的IP:Port列表。

K8s 原生 LoadBalancer 的语义是"一个 Service 一个 LB"------所以一个LoadBalancer虽然可以对应多个NodePort,但是其后端都是同一组Pod。也就是说不存在只使用一个公网IP+LoadBalancer就完成多个Service的暴露的情况。或者说K8s原生中,没有LB这个对象,有的只是LoadBalancer这种Service类型,因此也就没有LB-Service的一对多关系。

但是云厂商天生就需要对LB和公网IP做管理,因此实现一套这样的逻辑成本相对低------而且用户也有需求。

所以其实在云上,完全可以用 一个公网 IP + 一个负载均衡器(LB),不用 Ingress,就对外提供多个服务。限制就是必须依靠不同的端口来区分不同的服务。

Ingress------把HTTP 请求(域名、路径)路由到Service

Ingress 是 K8s 里的一种 API 对象,用来定义"外部 HTTP/HTTPS 流量怎么进入集群、路由到哪些 Service"。它本身只是规则,真正处理流量的是 Ingress Controller(一组以DaemonSet工作负载形式部署的Pod)。负责K8s的七层路由

复制代码
root@knowledgeskilltest:/home/zn# kubectl get pods -A -o wide | grep ingress
ingress-nginx              ingress-nginx-controller-b6b495bc9-rrnrs             1/1     Running     0          7m21s   10.244.0.44    dynamic-test-control-plane   <none>           <none>

这个筛选出来的Pod就是ingress Controller实例,它里面通常跑着 ingress-nginx 的 controller 逻辑和 Nginx 进程。真正直接承接外部 HTTP/HTTPS 请求、按 Ingress 规则转发的,就是这个 Pod 里的 Nginx。

Ingress Controller的Service一般是前文中提到的LoadBalancer或者NodePort,通过IP(一般LB是公网,NodePort是内网)提供一个4层入口,然后Ingress Controller内部的nginx再解析 Host/Path,将请求根据Ingress规则反向代理到到后端 Service 对应的 Pod(四层)

外部流量路径

复制代码
外部用户
  -> DNS 解析到入口 IP
  -> 四层入口:云 LB / Service type=LoadBalancer / NodePort 
  -> Ingress Controller Pod
       └── TCP 承载到达(四层)
       └── Nginx / Traefik / Envoy 解析 HTTP(七层)
  -> 根据 Ingress 规则选择后端
  -> 通过 TCP 连接发往后端 Pod IP:Port(四层)
       Service / Endpoint 提供服务发现,可能不经过 ClusterIP
  -> 业务应用解析 HTTP,处理业务(七层)
相关推荐
有范先生1 小时前
懒人代餐即食米饭:常温全能型,让一顿热饭不受厨房和冰箱限制
笔记
高山有多高2 小时前
【Linux笔记】Linux基本指令
linux·运维·笔记
司南-70492 小时前
AI infra 学习笔记(三):预处理·第一步——QKV 投影到底算了多少
人工智能·笔记·学习
sevenez2 小时前
AiMaMi 介绍及与 CC Switch 对比
笔记
喜欢打篮球的普通人2 小时前
MiniMind 学习笔记(十):优化器、学习率和数据设置——训练稳定性的三块基石
笔记·python·学习
老王爱玩车2 小时前
深入理解指针5
c语言·开发语言·学习
喜欢打篮球的普通人2 小时前
MiniMind 学习笔记(十三):SFT 导言——从“续写文本“到“回答用户“
人工智能·笔记·学习
键盘鼓手苏苏3 小时前
ESLint 规则渐进式升级:从 0 警告到全面开启的迁移策略(续篇)
云原生·kubernetes·k8
我命由我123453 小时前
Photoshop - 将Photoshop图像置入其他应用程序
学习·ui·职场和发展·求职招聘·职场发展·学习方法·photoshop