讲解了K8S集群中运维相关的补充知识,包括网络策略、外部服务暴露、资源限制等内容。
NetworkPolicy
在Kubernetes中,NetworkPolicy是一种API对象,用于定义和控制Pod之间的网络通信策略,可以基于IP地址或端口(OSI第3层或第4层)来管理网络流量。
Kubernetes集群默认情况下,一个名字空间中的所有Pod对入站和出站流量都是非隔离的,即所有连接都是被允许的。NetworkPolicy的作用就是改变这种默认行为,通过定义策略来对Pod间的网络通信进行精细化控制,以实现更高的网络安全性。
NetworkPolicy的局限性
- 强制集群内部流量经过某个公用网关:这类场景更适合通过服务网格(Service Mesh)或其他代理来实现
- 与TLS相关的场景:可以考虑使用服务网格或Ingress控制器来解决
- 特定于节点的策略:虽然可以通过CIDR来表达此需求,但无法使用节点在Kubernetes中的其他标识信息来识别目标节点
- 基于名字选择服务或名字空间来选择目标Pod
- 创建或管理由第三方实际完成的“策略请求”
- 实现适用于所有名字空间或Pods的默认策略
- 高级的策略查询或可达性相关工具
- 生成网络安全事件日志的能力(例如,被阻塞或接收的连接请求)
- 显式地拒绝策略的能力:目前,NetworkPolicy的模型默认采用拒绝操作,其唯一的能力是添加允许策略
- 禁止本地回路或指向宿主的网络流量:Pod无法阻塞localhost访问,也无法禁止来自所在节点的访问
基本语法
一个典型的NetworkPolicy YAML文件包括以下几个部分:
apiVersion
:networking.k8s.io/v1
kind
:NetworkPolicy
metadata
:包含策略的name
和所在的namespace
。spec
:核心部分,用于定义策略规则。podSelector
:通过标签选择器(matchLabels
)来指定该策略作用于哪些Pod。如果podSelector
为空,则选择该名字空间下的所有Pod 。policyTypes
:定义策略的类型,可以是Ingress
(入站)或Egress
(出站)。如果未指定,默认只设置Ingress
。ingress
:入站规则,通过from
部分来指定允许哪些来源的流量访问目标Pod。egress
:出站规则,通过to
部分来指定目标Pod可以访问哪些目的地。from
和to
部分可以包含以下四种选择器:podSelector
:基于Pod标签。namespaceSelector
:基于名字空间标签。namespaceSelector
和podSelector
的组合。ipBlock
:基于CIDR IP地址块
1 | apiVersion: networking.k8s.io/v1 |
默认策略
- 拒绝所有入站流量:创建一个
podSelector: {}
且policyTypes: Ingress
的策略,但不包含任何ingress
规则
1 | apiVersion: networking.k8s.io/v1 |
规定了Ingress规则,但没写任何匹配条目,意思就是没有流量能访问
- 允许所有入站流量:创建一个
podSelector: {}
且ingress: {}
的策略 。
1 | apiVersion: networking.k8s.io/v1 |
规定了Ingress规则,匹配条目为”{}“,代表任意,意思就是任何流量都能访问
Egress的默认策略编写同理
外部服务暴露
Kubernetes 中的 Pod 默认只能在集群内部访问,如果要让外部用户访问,需要通过暴露服务的方式。
Expose
kubectl expose
用来基于已有的 Pod / Deployment /
ReplicaSet 创建一个 Service,从而将应用端口暴露出来。
本质上就是用命令帮你快速创建一个Service资源
1 | kubectl expose deployment myapp --port=80 --target-port=8080 --type=NodePort |
意思是把 deployment myapp
的 8080 容器端口暴露为集群
Service 的 80 端口,同时通过 NodePort 暴露到每个节点。
Port-forward
kubectl port-forward
将本地端口和某个 Pod/Service
的端口建立临时转发。
1 | kubectl port-forward pod/myapp-pod 8080:80 |
本地 http://localhost:8080
的请求会被转发到 Pod 的
80
端口。
- 仅作用在当前 kubectl 会话,关闭终端/CTRL+C 后失效。
- 只绑定到
localhost
,外部机器无法直接访问。 - 不依赖 Service、Ingress 等,快速调试用。
如果需要外部访问,则改成
1 kubectl port-forward pod/myapp-pod 8080:80 --address 0.0.0.0这样它就会监听
0.0.0.0:32222
,即所有IP,包括任意外部主机发送到这个节点上的流量否则它只认127.0.0.1的IP地址
Ingress
前面单独有讲
限制资源
单个Pod中对特定容器
1 | apiVersion: v1 |
特性 | requests | limits |
---|---|---|
调度决策 | 用于调度 Pod 到节点(Scheduler 根据 requests 判断节点是否有足够资源) | 不影响调度,运行时才生效 |
保证资源 | Pod 至少能使用 requests 的资源 | Pod 不会超过 limits 的资源 |
超过时处理 | 不会超额 | CPU 超额限速,内存超额 OOMKill |
requests
= 调度门槛limits
= 运行上限
HPA
HPA 的核心目标是 根据负载自动增加或减少 Pod 数量,保证应用在流量高峰时有足够的资源,同时在流量低时节省资源。
例如:
- 当 CPU 使用率超过 80% 时,HPA 会增加 Pod 副本。
- 当 CPU 使用率降到 30% 时,HPA 会减少 Pod 副本。
HPA 工作原理
指标采集:
HPA 通过 Kubernetes 的 Metrics Server 获取 Pod 的实时指标,如 CPU、内存使用率,或者自定义指标(通过 Prometheus Adapter 等)。
计算副本数:
HPA 根据公式计算所需副本数:
例如: 当前 Pod 副本数:3
CPU 使用率:90%
目标 CPU 使用率:50%
那么:
调整副本:
- HPA 会修改对应 Deployment/ReplicaSet 的副本数,使集群资源动态适配负载。
HPA 配置示例
假设有一个 Deployment 名为 my-app
,希望基于 CPU
使用率自动扩缩:
1 | apiVersion: autoscaling/v2 |
minReplicas
: 最少 2 个 PodmaxReplicas
: 最多 10 个 Podtarget.averageUtilization
: CPU 目标利用率 50%
Pod QoS (服务质量等级)
Kubernetes 根据 Pod 的 requests/limits 配置,分配不同 QoS 等级:
BestEffort(最低优先级)
- 没有设置任何 requests/limits(该pod可以使用任意多的资源)。
- 容易被驱逐。
Burstable(中优先级)
- 设置了 requests或limits,或者两个都设置了但不相等。
- 在资源紧张时,可能被驱逐。
Guaranteed(最高优先级)
- 设置了 requests == limits。
- 不会轻易被驱逐,保障性最好。
LimitRange
用于 命名空间级别下单独每个pod 的资源限制,避免用户随意配置。
可以指定每个容器可申请的最小/最大 CPU、内存。
还可以设置默认的 requests/limits,简化配置。
1 | apiVersion: v1 |
ResourceQuota
用于 限制整个命名空间 的资源总量。
控制一个 namespace 内的 Pod 数量、总 CPU、总内存、PVC 使用量等。
1 | apiVersion: v1 |