K8S网络策略全解-NetworkPolicy与GlobalNetworkPolicy实战

Kubernetes 网络策略全解:从 NetworkPolicy 到 GlobalNetworkPolicy 实战

导读 :在默认情况下,K8S 集群中所有 Pod 之间是完全互通 的------任何 Pod 都可以访问任何其他 Pod 的任何端口。这在开发测试环境没问题,但在生产环境中是巨大的安全风险。本文将从零开始,结合真实的生产级 YAML 和验证命令,系统讲解 K8S 网络策略的三种控制维度(ipBlock / namespaceSelector / podSelector),对比 K8S 原生 NetworkPolicy 与 Calico 增强 GlobalNetworkPolicy 的差异,并提供可直接落地的最佳实践方案。


一、为什么需要网络策略?

1.1 默认网络模型的隐患

K8S 集群安装完成后,所有 Pod 之间的网络通信没有任何限制

复制代码
┌─────────────────────────────────────────────────┐
│              K8S 默认网络模型                      │
│                                                   │
│   Pod A (前端)  ──→  Pod B (数据库)    ✅ 可访问  │
│   Pod C (日志)  ──→  Pod B (数据库)    ✅ 可访问  │
│   Pod D (任意)  ──→  Pod B (数据库)    ✅ 可访问  │
│                                                   │
│   ⚠️ 任何 Pod 都可以访问任何端口,无安全隔离        │
└─────────────────────────────────────────────────┘

这意味着:

  • 开发环境的 Pod 可以直连生产数据库
  • 被入侵的 Pod 可以横向渗透到整个集群
  • 敏感服务(支付、认证)暴露给所有 Pod

1.2 NetworkPolicy 解决什么?

NetworkPolicy 是 K8S 原生的网络策略资源,用于控制 Pod 之间以及 Pod 与外部之间的网络通信规则

复制代码
┌──────────────────────────────────────────────────┐
│              启用 NetworkPolicy 后                  │
│                                                    │
│   Pod A (前端)  ──→  Pod B (数据库)    ✅ 允许     │
│   Pod C (日志)  ──→  Pod B (数据库)    ✅ 允许     │
│   Pod D (任意)  ──→  Pod B (数据库)    ❌ 拒绝     │
│                                                    │
│   ✅ 精细化控制:谁可以访问谁、访问哪些端口           │
└──────────────────────────────────────────────────┘

1.3 前提条件:CNI 插件必须支持

关键前提:NetworkPolicy 的实际执行依赖 CNI 网络插件。不是所有 CNI 都支持:

CNI 插件 是否支持 NetworkPolicy
Flannel 不支持(需配合 Calico 等策略组件)
Calico 完整支持
Cilium 完整支持(还支持 L7 策略)
Weave Net 支持

重要 :如果你使用 Flannel 作为 CNI,编写 NetworkPolicy 不会生效!需要切换到 Calico 或 Cilium。这也是很多初学者踩过的坑------NetworkPolicy 写了但"没有效果"。


二、三大主流 CNI 插件对比

特性 Flannel Calico Cilium
性能 中等(VXLAN 封装开销) 高(三层路由,无封装或 VXLAN) 极高(eBPF 内核加速)
网络策略 不支持 L3/L4 强策略 L3/L4/L7(HTTP/gRPC)
安全 中(IPsec 可选) 强(eBPF + WireGuard)
可观测性 一般 强(内置 Hubble)
复杂度 低(一键部署) 较高(内核 5.10+)
适用规模 小集群(< 50 节点) 中大型(50-500 节点) 任意规模
适用场景 开发/测试、快速搭建 生产集群、多租户隔离 高性能网关、服务网格

三、Flannel 切换 Calico 实战

如果你的集群当前使用 Flannel,需要先完全卸载再安装 Calico,否则会产生网络冲突。

3.1 卸载 Flannel

bash 复制代码
# 1. 删除 Flannel 的 K8S 资源
kubectl delete -f kube-flannel-v0.27.0.yml

# 2. 所有节点清理 Flannel 残留文件和配置
rm -rf /run/flannel/subnet.env \
       /opt/cni/bin/flannel \
       /etc/cni/net.d/10-flannel.conflist \
       /var/lib/cni/

# 3. 删除 Flannel 创建的虚拟网卡
ip link delete cni0
ip link delete flannel.1

# 4. 重启 kubelet
systemctl restart kubelet.service

# 5. 确认节点变为 NotReady(预期行为)
kubectl get nodes
NAME        STATUS     ROLES                  AGE   VERSION
master231   NotReady   control-plane,master   17d   v1.23.17
worker232   NotReady   <none>                 17d   v1.23.17
worker233   NotReady   <none>                 17d   v1.23.17

注意 :以上操作需要在所有节点上执行。

3.2 安装 Calico

bash 复制代码
# 1. 所有节点导入 Calico 镜像(master 节点完成后 scp 到其他节点)
bash batch-load-calico-v3.5.2-images.sh 14

# 2. 安装 Tigera Calico Operator
kubectl create -f tigera-operator.yaml

# 3. 配置 Calico 网络参数
cat custom-resources.yaml
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
  name: default
spec:
  calicoNetwork:
    ipPools:
    - blockSize: 24           # 每个 Node 分配的 IP 段大小
      cidr: 10.100.0.0/16     # Pod 网段(需与 kubeadm init 一致)
      encapsulation: VXLANCrossSubnet
      natOutgoing: Enabled
      nodeSelector: all()

---

apiVersion: operator.tigera.io/v1
kind: APIServer
metadata:
  name: default
spec: {}

# 4. 应用配置
kubectl create -f custom-resources.yaml

# 5. 验证 Calico 组件正常运行
kubectl get pods -n calico-system -o wide
NAME                                      READY   STATUS    RESTARTS   AGE   IP
calico-kube-controllers-76d5c7cfc-tjg8c   1/1     Running   0          48s   10.100.141.2
calico-node-v79vw                         1/1     Running   0          49s   10.0.0.231
calico-node-vzhfk                         1/1     Running   0          49s   10.0.0.232
calico-node-wls9l                         1/1     Running   0          49s   10.0.0.233
calico-typha-6887f66bf8-jbxfn             1/1     Running   0          45s   10.0.0.232
calico-typha-6887f66bf8-w5ggv             1/1     Running   0          49s   10.0.0.231

# 6. 确认节点恢复 Ready
kubectl get nodes
NAME        STATUS   ROLES                  AGE   VERSION
master231   Ready    control-plane,master   17d   v1.23.17
worker232   Ready    <none>                 17d   v1.23.17
worker233   Ready    <none>                 17d   v1.23.17

四、NetworkPolicy 核心概念

4.1 策略模型

NetworkPolicy 的核心思想是白名单模型

没有 NetworkPolicy 的时候,所有流量都允许;一旦创建了 NetworkPolicy,则只有明确允许的流量才能通过,其余全部拒绝。

4.2 资源结构

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: <策略名称>
  namespace: <策略所在命名空间>     # ⚠️ 只在同一个命名空间内生效
spec:
  podSelector: {}                   # 选择本命名空间中哪些 Pod 应用此策略
  policyTypes:                      # 策略类型:入站/出站/双向
  - Ingress
  - Egress
  ingress:                          # 入站规则列表
  - from:                           # 流量来源(3种匹配方式)
    - ipBlock: {}
    - namespaceSelector: {}
    - podSelector: {}
    ports:
    - port: <端口号>
      protocol: TCP
  egress:                           # 出站规则列表
  - to:                             # 流量目标
    - ipBlock: {}
    - namespaceSelector: {}
    - podSelector: {}
    ports:
    - port: <端口号>
      protocol: TCP

4.3 三种流量匹配方式

这是 NetworkPolicy 最重要的概念,所有的策略都围绕这三种匹配方式展开:

匹配方式 作用范围 典型场景
podSelector 同一命名空间内的 Pod 同命名空间微服务间访问控制
namespaceSelector 其他命名空间 跨命名空间隔离(如 dev/staging/prod)
ipBlock 外部 IP 地址段 限制外部访问来源(如办公网/VPN)

4.4 podSelector 详解

podSelector 有两种匹配模式:

yaml 复制代码
# 模式一:空选择器 {} → 匹配命名空间内所有 Pod
spec:
  podSelector: {}           # 本命名空间的每个 Pod 都受此策略影响

# 模式二:指定标签 → 只匹配特定 Pod
spec:
  podSelector:
    matchLabels:
      apps: xiuxian         # 只影响带有 apps=xiuxian 标签的 Pod

五、NetworkPolicy 实战案例

5.1 环境准备

yaml 复制代码
# 准备两个命名空间和测试 Pod
# 01-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: net-demo

---
apiVersion: v1
kind: Namespace
metadata:
  name: net-target

---
# net-demo 命名空间的测试 Pod
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-v1
  namespace: net-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      apps: xiuxian
  template:
    metadata:
      labels:
        apps: xiuxian
    spec:
      containers:
      - name: c1
        image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1
        ports:
        - containerPort: 80

---
# net-target 命名空间的目标 Pod(被访问方)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-v2
  namespace: net-target
spec:
  replicas: 1
  selector:
    matchLabels:
      apps: xiuxian
  template:
    metadata:
      labels:
        apps: xiuxian
    spec:
      containers:
      - name: c1
        image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v2
        ports:
        - containerPort: 80

5.2 案例一:基于 ipBlock 限制外部访问

场景:只允许特定 IP 段(如 10.0.0.0/8 内网)访问目标 Pod。

yaml 复制代码
# network-policy-ipblock.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: policy-ipblock
  namespace: net-target
spec:
  podSelector:
    matchLabels:
      apps: xiuxian             # 作用于标签为 apps=xiuxian 的 Pod
  policyTypes:
  - Ingress
  ingress:
  - from:
    - ipBlock:
        cidr: 10.0.0.0/8        # 只允许 10.0.0.0/8 网段访问
        except:                 # 排除以下网段
        - 10.0.1.0/24           # 10.0.1.x 被排除
    ports:
    - port: 80
      protocol: TCP
bash 复制代码
kubectl apply -f network-policy-ipblock.yaml -n net-target

# 验证策略生效
kubectl get networkpolicy -n net-target
NAME              POD-SELECTOR   AGE
policy-ipblock    apps=xiuxian   10s

效果

  • 10.0.0.0/8 网段的请求 → 允许访问 80 端口
  • 10.0.1.0/24 网段的请求 → 被拒绝(被 except 排除)
  • 其他网段的请求 → 被拒绝

注意 :ipBlock 中 except 的优先级高于 cidr

5.3 案例二:基于 namespaceSelector 的跨命名空间隔离

场景:只允许特定命名空间的 Pod 访问目标 Pod。

yaml 复制代码
# network-policy-ns.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: policy-namespace
  namespace: net-target
spec:
  podSelector:
    matchLabels:
      apps: xiuxian
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:         # 按命名空间标签匹配
        matchLabels:
          access: allowed        # 只允许带有 access=allowed 标签的命名空间
    ports:
    - port: 80
      protocol: TCP
bash 复制代码
# 1. 给 net-demo 命名空间打上"允许访问"标签
kubectl label namespace net-demo access=allowed

# 2. net-target 不打标签(或打其他标签)
# 默认情况下命名空间没有 access 标签

# 3. 应用策略
kubectl apply -f network-policy-ns.yaml -n net-target

效果

  • net-demo 命名空间的 Pod(有 access=allowed 标签) → 允许访问
  • 其他命名空间的 Pod → 被拒绝

5.4 案例三:基于 podSelector 的同命名空间精细控制

场景:在同一命名空间内,只允许特定 Pod 访问目标 Pod。

yaml 复制代码
# network-policy-pod.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: policy-pod
  namespace: net-demo
spec:
  podSelector:
    matchLabels:
      apps: xiuxian             # 作用于 xiuxian Pod
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:              # 只允许同命名空间内特定 Pod 访问
        matchLabels:
          role: frontend        # 只有 role=frontend 的 Pod 能访问
    ports:
    - port: 80
      protocol: TCP

5.5 综合案例:多规则组合

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: policy-combined
  namespace: net-target
spec:
  podSelector:
    matchLabels:
      apps: xiuxian
  policyTypes:
  - Ingress
  - Egress                     # 同时控制入站和出站
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          access: allowed       # 来自允许的命名空间
    - ipBlock:
        cidr: 10.0.0.0/8       # 或来自内网 IP 段
    ports:
    - port: 80
      protocol: TCP
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/8       # 只允许访问内网
    ports:
    - port: 3306
      protocol: TCP            # 如:只允许出站访问数据库

六、GlobalNetworkPolicy(Calico 增强)

6.1 为什么需要 GlobalNetworkPolicy?

K8S 原生 NetworkPolicy 有一个致命局限 :它只在同一个命名空间内生效。如果你需要跨命名空间的统一网络策略(比如"所有命名空间的 Pod 都禁止访问外部网络"),就需要逐个命名空间创建策略,管理成本极高。

Calico 提供了 GlobalNetworkPolicy(GNP) 作为增强方案,支持集群级别的全局网络策略

6.2 NetworkPolicy vs GlobalNetworkPolicy

对比项 NetworkPolicy (K8S 原生) GlobalNetworkPolicy (Calico)
生效范围 单个命名空间 整个集群(跨命名空间)
管理方式 kubectl calicoctl
命名空间选择 只能选本命名空间的 Pod 可以指定任意命名空间
动作类型 Allow(隐式)/ Deny(全拒绝) Allow / Deny / Pass
优先级 支持指定优先级(order 字段)
协议深度 L3/L4 L3/L4
eBPF offload 不支持 支持
出站规则 支持 支持

6.3 GNP 的三种动作类型

这是 GNP 相比 NP 最核心的差异:

动作 含义 典型场景
Allow 明确允许通过 开放特定端口访问
Deny 明确拒绝(K8S 原生 NP 不支持 封禁特定 IP 或端口
Pass 跳过此规则,交给下一条规则判断 实现复杂的规则链

关键区别:K8S 原生 NetworkPolicy 只有"白名单"模式(Allow),无法实现"黑名单"模式(Deny)。Calico GNP 同时支持 Allow 和 Deny,可以实现更精细的控制。

6.4 GNP 实战:全局拒绝特定端口的出站流量

yaml 复制代码
# global-network-policy.yaml
# 使用 calicoctl apply -f global-network-policy.yaml
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: deny-egress-db
spec:
  order: 100                     # 优先级,数字越小优先级越高
  selector: all()                # 作用于所有 Pod(全局生效)
  types:
  - Egress
  egress:
  - action: Deny                 # 拒绝(K8S 原生 NP 做不到!)
    destination:
      ports:
      - 3306                     # 拒绝所有出站到 3306 的流量
  - action: Deny
    destination:
      ports:
      - 6379                     # 拒绝所有出站到 6379 的流量
  - action: Allow                # 其余出站流量放行
bash 复制代码
# 使用 calicoctl 应用 GNP
calicoctl apply -f global-network-policy.yaml

# 查看已创建的 GNP
calicoctl get globalnetworkpolicy
NAME             ORDER   SELECTOR
deny-egress-db   100     all()

6.5 GNP 实战:基于命名空间的全局隔离

yaml 复制代码
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: namespace-isolation
spec:
  order: 200
  selector: all()
  types:
  - Ingress
  ingress:
  # 允许同一命名空间内的 Pod 互访
  - action: Allow
    source:
      selector: all()
      namespaceSelector:
        name: ""               # 同一命名空间
  # 允许来自 DNS 的查询
  - action: Allow
    protocol: UDP
    destination:
      ports:
      - 53
  # 其余入站流量全部拒绝
  - action: Deny

6.6 calicoctl 与 kubectl 的关系

对比维度 kubectl calicoctl
归属 K8S 官方原生客户端 Calico 专属运维工具
管理范围 所有 K8S 原生资源 Calico CRD(IPPool、BGP、GNP 等)
策略类型 仅 NetworkPolicy NetworkPolicy + GlobalNetworkPolicy
生效范围 单个命名空间 命名空间级 + 集群全局
语法 K8S 标准 YAML 与 kubectl 语法一致,零学习成本
bash 复制代码
# 安装 calicoctl(推荐 kubectl 插件方式)
wget https://github.com/projectcalico/calico/releases/download/v3.25.2/calicoctl-linux-amd64 \
  -O /usr/local/bin/kubectl-calico
chmod +x /usr/local/bin/kubectl-calico

# 验证版本(客户端必须与集群 Calico 版本一致)
kubectl calico version
Client Version:    v3.25.2
Cluster Version:   v3.25.2
Cluster Type:      typha,kdd,k8s,operator,bgp,kubeadm

# 查看 BGP 状态
calicoctl node status
Calico process is running.

IPv4 BGP status
+--------------+-------------------+-------+----------+-------------+
| PEER ADDRESS |     PEER TYPE     | STATE |  SINCE   |    INFO     |
+--------------+-------------------+-------+----------+-------------+
| 10.0.0.232   | node-to-node mesh | up    | 08:52:20 | Established |
| 10.0.0.233   | node-to-node mesh | up    | 08:52:20 | Established |
+--------------+-------------------+-------+----------+-------------+

七、生产环境最佳实践

7.1 网络策略设计原则

复制代码
原则1:默认拒绝 → 最小权限开放
  ├── 集群级别:所有入站默认拒绝
  ├── 命名空间级别:按需开放跨命名空间访问
  └── Pod 级别:只开放必要端口

原则2:从外到内分层控制
  ├── 外部 → 集群:Ingress/LoadBalancer 层控制
  ├── 集群内跨命名空间:namespaceSelector 控制
  └── 命名空间内:podSelector 精细控制

原则3:必须放行 DNS
  └── UDP 53 端口必须始终开放,否则 Pod 无法解析域名

7.2 推荐的基线策略

第一步:全局默认拒绝所有入站(使用 Calico GNP)

yaml 复制代码
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: default-deny-ingress
spec:
  order: 1000                  # 低优先级(兜底规则)
  selector: all()
  types:
  - Ingress
  ingress:
  - action: Deny

第二步:放行 DNS(必须!)

yaml 复制代码
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: allow-dns
spec:
  order: 500
  selector: all()
  types:
  - Egress
  egress:
  - action: Allow
    protocol: UDP
    destination:
      ports:
      - 53
  - action: Allow
    protocol: TCP
    destination:
      ports:
      - 53
  - action: Allow
    destination:
      namespaceSelector: name == "kube-system"
      selector: k8s-app == "kube-dns"

第三步:按业务逐个开放访问

yaml 复制代码
# 例如:允许前端命名空间访问后端命名空间的 8080 端口
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: backend
spec:
  podSelector:
    matchLabels:
      apps: backend-api
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          team: frontend
    ports:
    - port: 8080
      protocol: TCP

7.3 命名空间标签规划

bash 复制代码
# 按环境打标签
kubectl label namespace production env=prod
kubectl label namespace staging env=staging
kubectl label namespace development env=dev

# 按业务团队打标签
kubectl label namespace payment team=payment
kubectl label namespace user-service team=user

# 按访问权限打标签
kubectl label namespace monitoring access=allowed
kubectl label namespace logging access=allowed

八、网络策略排障指南

8.1 网络策略不生效的常见原因

原因 排查方法 解决方案
CNI 不支持 NetworkPolicy kubectl get pods -n calico-system 切换到 Calico/Cilium
策略写在了错误的命名空间 检查 metadata.namespace 确保 NP 在目标 Pod 所在命名空间
DNS 未放行 Pod 内 nslookup 失败 始终放行 UDP/TCP 53 端口
podSelector 标签不匹配 kubectl get pods --show-labels 检查标签是否一致
多条策略冲突 列出所有 NetworkPolicy 检查是否有其他策略覆盖

8.2 排障命令速查

bash 复制代码
# 查看命名空间内的所有网络策略
kubectl get networkpolicy -n <namespace>

# 查看策略详细信息
kubectl describe networkpolicy <name> -n <namespace>

# 查看 Calico 全局网络策略
calicoctl get globalnetworkpolicy

# 查看 Calico 节点 BGP 状态
calicoctl node status

# 进入 Pod 测试网络连通性
kubectl exec -it <pod-name> -n <namespace> -- curl <target-ip>:<port>

# 查看 Pod 的 IP
kubectl get pods -o wide -n <namespace>

九、面试高频考点速查

问题 答案要点
K8S 默认网络模型? 所有 Pod 完全互通,没有任何隔离
NetworkPolicy 的前提条件? CNI 插件必须支持(如 Calico/Cilium),Flannel 不支持
NetworkPolicy 的默认行为? 没有 NP = 全部允许;有 NP = 只允许明确放行的流量
三种流量匹配方式? podSelector (Pod 标签)、namespaceSelector (命名空间标签)、ipBlock(IP 段)
GNP 和 NP 的核心区别? GNP 跨命名空间全局生效 ,支持 Deny 动作和优先级
GNP 三种动作? Allow (允许)、Deny (拒绝)、Pass(跳过交给下条规则)
为什么必须放行 DNS? Pod 依赖 DNS 进行服务发现,阻断 DNS 会导致集群内部域名无法解析
Calico 的 BGP 模式? node-to-node mesh(默认全互联)或 Route Reflector(大规模)
calicoctl 版本要求? 客户端版本必须与集群 Calico 版本严格一致

十、总结

本文从三个层次系统讲解了 K8S 网络策略:

  1. 基础概念:理解 K8S 默认的"全互通"模型和 NetworkPolicy 的白名单机制,明确 CNI 插件支持是前提条件
  2. NetworkPolicy 实战:掌握 ipBlock(IP 段)、namespaceSelector(命名空间标签)、podSelector(Pod 标签)三种匹配方式的实际运用
  3. GlobalNetworkPolicy 进阶:理解 Calico GNP 的跨命名空间全局能力、Allow/Deny/Pass 三种动作、优先级机制

生产建议

  • 必须使用支持 NetworkPolicy 的 CNI(推荐 Calico),Flannel 无法生效
  • 采用"默认拒绝 + 最小权限开放"的策略设计原则
  • 始终放行 DNS(UDP/TCP 53),否则集群服务发现将全部失效
  • 命名空间标签要提前规划,便于 namespaceSelector 策略管理
  • 对于跨命名空间的统一管控,使用 Calico GNP 替代逐个命名空间创建 NP

环境信息

  • Kubernetes: v1.23.17
  • CNI: Calico v3.25.2
  • 部署方式: kubeadm
  • calicoctl: v3.25.2
相关推荐
运维开发故事1 天前
基于 Arthas 的多集群在线诊断系统设计与实现
kubernetes
Patrick_Wilson3 天前
从「改个端口」到 502:Next.js on k8s 的容器端口、Service 映射与 env 覆盖
docker·kubernetes·next.js
探索云原生3 天前
K8s 1.36 这个 GA 特性,把 initContainer 拉模型的 hack 干掉了
ai·云原生·kubernetes
云恒要逆袭3 天前
运行你的第一个Docker容器
后端·docker·容器
Java之美4 天前
一次k8s升级引发的DevicePlugin注册失败
云原生·kubernetes
程序员老赵5 天前
10 分钟部署 OpenCode:Docker 一键安装,浏览器打开就能用 AI 写代码(附完整命令与排错)
docker·容器·ai编程
武子康8 天前
调查研究-183 Apple container:Mac 上用轻量 VM 跑 Linux 容器,Swift 会改写本地容器体验吗?
docker·容器·apple
网络研究院11 天前
2026年网络安全
网络·安全·法律·法规·趋势·发展
酣大智11 天前
ARP代理--工作原理
运维·网络·arp·arp代理