news 2026/6/1 16:42:11

【Docker+K8s 实战·第六篇】K8s 网络与服务发现:Ingress 统一入口、TLS 证书管理与 NetworkPolicy 隔离

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Docker+K8s 实战·第六篇】K8s 网络与服务发现:Ingress 统一入口、TLS 证书管理与 NetworkPolicy 隔离

【Docker+K8s 实战·第六篇】K8s 网络与服务发现:Ingress 统一入口、TLS 证书管理与 NetworkPolicy 隔离

更新时间:2026-05-20 |阅读时长:约 23 分钟
系列:Docker + K8s 实战(共 8 篇)
环境:Kubernetes 1.30+,ingress-nginx,cert-manager
标签KubernetesIngress网络TLScert-managerNetworkPolicyCoreDNS服务发现


系列进度

篇次主题状态
第一篇Docker 基础
第二篇Dockerfile 进阶
第三篇Docker Compose
第四篇K8s 核心概念
第五篇K8s 配置与存储
第六篇(本篇)K8s 网络与服务发现
第七篇K8s 生产实践即将发布
第八篇CI/CD 完整流水线即将发布

目录

  • 一、K8s 网络模型概述
  • 二、CoreDNS:集群内服务发现
  • 三、Ingress:统一的 HTTP/HTTPS 入口
  • 四、ingress-nginx:安装与高级配置
  • 五、cert-manager:自动化 TLS 证书
  • 六、NetworkPolicy:网络隔离与安全
  • 七、完整实战:多服务 + TLS + 网络隔离

一、K8s 网络模型概述

K8s 网络的三个层次: ① Pod 网络(Pod-to-Pod) 每个 Pod 有独立 IP,同节点通过虚拟网桥 跨节点通过 CNI 插件(Flannel/Calico/Cilium) Pod 间可直接通信(无 NAT) ② Service 网络(Service-to-Pod) ClusterIP = 稳定虚拟 IP kube-proxy 维护 iptables/IPVS 规则实现负载均衡 ClusterIP 只在集群内可访问 ③ 外部流量进入 NodePort:节点 IP:端口暴露 LoadBalancer:云厂商创建外部 LB Ingress:七层(HTTP/HTTPS)统一路由 常用 CNI 插件: Flannel 简单,适合开发(不支持 NetworkPolicy) Calico 功能全,支持 NetworkPolicy(推荐生产) Cilium 基于 eBPF,高性能,可观测性强

二、CoreDNS:集群内服务发现

2.1 DNS 解析规则

Service DNS 完整格式: <service>.<namespace>.svc.cluster.local StatefulSet Pod DNS: <pod-name>.<headless-svc>.<namespace>.svc.cluster.local 例:mysql-0.mysql-headless.myapp.svc.cluster.local 搜索域(让短名称也能工作): 同 namespace 内:api → api.myapp.svc.cluster.local 跨 namespace: api.other-ns → api.other-ns.svc.cluster.local
# 在 Pod 内验证 DNSkubectl run-it--rmdebug--image=busybox:1.36--restart=Never --shcat/etc/resolv.confnslookupapinslookupmysql-0.mysql-headless.myapp

2.2 自定义 CoreDNS

# 修改 CoreDNS ConfigMap(kube-system namespace)# 添加内部 DNS 转发规则data:Corefile:|.:53 { errors health kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa } prometheus :9153 forward . /etc/resolv.conf cache 30 loop reload loadbalance } # 将 company.internal 转发到内部 DNS company.internal:53 { errors forward . 192.168.1.53 cache 30 }

三、Ingress:统一的 HTTP/HTTPS 入口

3.1 为什么需要 Ingress

没有 Ingress 的痛: 服务A:LoadBalancer → 外部IP:80 ← 一个 LB,收费! 服务B:LoadBalancer → 外部IP:80 ← 又一个 LB,又收费! 服务C:LoadBalancer → 外部IP:80 ← 再一个... Ingress 解决: 一个 LB(共享)作为统一入口 根据 host/path 路由到不同 Service 外部请求 ↓ 一个 LoadBalancer ↓ Ingress 控制器(Nginx) ├── example.com/api/* → api Service ├── example.com/ → frontend Service └── admin.example.com → admin Service

3.2 Ingress YAML 详解

apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:myapp-ingressnamespace:myappannotations:# 自动申请 TLS 证书cert-manager.io/cluster-issuer:letsencrypt-prodnginx.ingress.kubernetes.io/ssl-redirect:"true"# 请求体大小nginx.ingress.kubernetes.io/proxy-body-size:"50m"# 超时nginx.ingress.kubernetes.io/proxy-read-timeout:"300"# 速率限制nginx.ingress.kubernetes.io/limit-rps:"100"# 安全响应头nginx.ingress.kubernetes.io/configuration-snippet:|add_header Strict-Transport-Security "max-age=31536000" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always;spec:ingressClassName:nginxtls:-hosts:-example.com-www.example.comsecretName:example-com-tls# cert-manager 自动填充rules:-host:example.comhttp:paths:# API(优先匹配)-path:/apipathType:Prefixbackend:service:name:apiport:number:80# WebSocket-path:/wspathType:Prefixbackend:service:name:apiport:number:80# 前端(兜底)-path:/pathType:Prefixbackend:service:name:frontendport:number:80# 管理后台子域名-host:admin.example.comhttp:paths:-path:/pathType:Prefixbackend:service:name:admin-frontendport:number:80

四、ingress-nginx:安装与高级配置

4.1 安装

# minikubeminikube addonsenableingress kubectlwait--namespaceingress-nginx\--for=condition=ready pod\--selector=app.kubernetes.io/component=controller\--timeout=120s# Helm(生产)helm repoaddingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update helminstallingress-nginx ingress-nginx/ingress-nginx\--namespaceingress-nginx\--create-namespace\--setcontroller.service.type=LoadBalancer\--setcontroller.metrics.enabled=true# 查看外部 IPkubectl get svc-ningress-nginx

4.2 金丝雀发布

# 主版本 Ingress(正常)apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:api-stablenamespace:myappspec:ingressClassName:nginxrules:-host:example.comhttp:paths:-path:/apipathType:Prefixbackend:service:name:api-v1port:number:80---# 金丝雀 Ingress(10% 流量)apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:api-canarynamespace:myappannotations:nginx.ingress.kubernetes.io/canary:"true"nginx.ingress.kubernetes.io/canary-weight:"10"# 也可以按 Header 路由(测试用)# nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"# nginx.ingress.kubernetes.io/canary-by-header-value: "true"spec:ingressClassName:nginxrules:-host:example.comhttp:paths:-path:/apipathType:Prefixbackend:service:name:api-v2port:number:80

4.3 Basic Auth 保护

# 生成密码文件htpasswd-cauth admin kubectl create secret generic admin-basic-auth\--from-file=auth--namespace=myapp
metadata:annotations:nginx.ingress.kubernetes.io/auth-type:basicnginx.ingress.kubernetes.io/auth-secret:admin-basic-authnginx.ingress.kubernetes.io/auth-realm:"Admin Access Required"# IP 白名单nginx.ingress.kubernetes.io/whitelist-source-range:"203.0.113.0/24"

五、cert-manager:自动化 TLS 证书

5.1 安装

helm repoaddjetstack https://charts.jetstack.io helm repo update helminstallcert-manager jetstack/cert-manager\--namespacecert-manager\--create-namespace\--setinstallCRDs=true kubectl get pods-ncert-manager

5.2 配置 Let’s Encrypt ClusterIssuer

# 生产环境apiVersion:cert-manager.io/v1kind:ClusterIssuermetadata:name:letsencrypt-prodspec:acme:server:https://acme-v02.api.letsencrypt.org/directoryemail:admin@example.comprivateKeySecretRef:name:letsencrypt-prod-keysolvers:-http01:ingress:class:nginx---# 测试环境(速率限制宽松)apiVersion:cert-manager.io/v1kind:ClusterIssuermetadata:name:letsencrypt-stagingspec:acme:server:https://acme-staging-v02.api.letsencrypt.org/directoryemail:admin@example.comprivateKeySecretRef:name:letsencrypt-staging-keysolvers:-http01:ingress:class:nginx---# DNS-01 挑战(通配符证书 *.example.com)apiVersion:cert-manager.io/v1kind:ClusterIssuermetadata:name:letsencrypt-dnsspec:acme:server:https://acme-v02.api.letsencrypt.org/directoryemail:admin@example.comprivateKeySecretRef:name:letsencrypt-dns-keysolvers:-dns01:cloudflare:email:admin@example.comapiTokenSecretRef:name:cloudflare-api-tokenkey:api-token

5.3 手动创建 Certificate(更多控制)

apiVersion:cert-manager.io/v1kind:Certificatemetadata:name:example-com-certnamespace:myappspec:secretName:example-com-tlsissuerRef:name:letsencrypt-prodkind:ClusterIssuerdnsNames:-example.com-www.example.com-api.example.comduration:2160h# 90 天renewBefore:720h# 提前 30 天续期
# 查看证书状态kubectl get certificate-nmyapp kubectl describe certificate example-com-cert-nmyapp# 证书 Ready=True 说明申请成功# NAME READY SECRET AGE# example-com-cert True example-com-tls 5m

六、NetworkPolicy:网络隔离与安全

6.1 为什么需要

默认 K8s 网络:任何 Pod 都可以访问任何 Pod(无隔离!) 生产风险: 前端 Pod 直接访问数据库(不应该!) 被入侵的 Pod 横向扫描整个集群 测试 namespace 访问生产数据 NetworkPolicy: 白名单规则,默认拒绝 精确控制哪个 Pod 能访问哪个 Pod 需要 CNI 支持(Calico/Cilium,Flannel 不支持!)

6.2 关键策略配置

# 1. 默认拒绝所有进出流量(先封锁,再开白名单)apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:default-deny-allnamespace:myappspec:podSelector:{}policyTypes:-Ingress-Egress---# 2. 所有 Pod 允许 DNS 出站(否则域名解析失败!)apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:allow-dnsnamespace:myappspec:podSelector:{}policyTypes:-Egressegress:-to:-namespaceSelector:matchLabels:kubernetes.io/metadata.name:kube-systemports:-protocol:UDPport:53-protocol:TCPport:53---# 3. Ingress 控制器访问前端和 APIapiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:allow-from-ingressnamespace:myappspec:podSelector:{}policyTypes:-Ingressingress:-from:-namespaceSelector:matchLabels:kubernetes.io/metadata.name:ingress-nginx---# 4. API 访问数据库和缓存(出站)apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:allow-api-to-backendsnamespace:myappspec:podSelector:matchLabels:app:apipolicyTypes:-Egressegress:-to:-podSelector:matchLabels:app:postgresports:-port:5432-to:-podSelector:matchLabels:app:redisports:-port:6379---# 5. API 访问外部 HTTPS(出站)apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:allow-api-externalnamespace:myappspec:podSelector:matchLabels:app:apipolicyTypes:-Egressegress:-to:-ipBlock:cidr:0.0.0.0/0except:-10.0.0.0/8-172.16.0.0/12-192.168.0.0/16ports:-port:443-port:80---# 6. 允许 Prometheus 抓取指标apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:allow-prometheusnamespace:myappspec:podSelector:{}policyTypes:-Ingressingress:-from:-namespaceSelector:matchLabels:kubernetes.io/metadata.name:monitoringports:-port:9090-port:8080-port:9100

6.3 Namespace 间隔离

# 生产 namespace 只接受自身和 ingress-nginx 的流量apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:isolate-namespacenamespace:productionspec:podSelector:{}policyTypes:-Ingressingress:-from:-namespaceSelector:matchLabels:kubernetes.io/metadata.name:production-from:-namespaceSelector:matchLabels:kubernetes.io/metadata.name:ingress-nginx-from:-namespaceSelector:matchLabels:kubernetes.io/metadata.name:monitoring

七、完整实战:多服务 + TLS + 网络隔离

7.1 架构

外部 → Ingress(ingress-nginx,cert-manager 自动 TLS) example.com/ → frontend example.com/api/* → api admin.example.com → admin(Basic Auth + IP 白名单) NetworkPolicy: 默认拒绝所有 Ingress控制器 → frontend/api ✅ api → postgres:5432 ✅ api → redis:6379 ✅ api → 外网 HTTPS ✅ 所有Pod → CoreDNS:53 ✅ Prometheus → 所有Pod metrics ✅

7.2 目录结构

k8s/ ├── cert-manager/ │ └── cluster-issuer.yaml ├── ingress/ │ ├── ingress-main.yaml │ └── ingress-admin.yaml ├── network-policy/ │ ├── default-deny.yaml │ ├── allow-dns.yaml │ ├── allow-ingress.yaml │ ├── allow-api-backends.yaml │ ├── allow-api-external.yaml │ └── allow-prometheus.yaml └── deploy-networking.sh

7.3 部署脚本

#!/bin/bash# deploy-networking.shset-euopipefailNAMESPACE=myappDOMAIN=${DOMAIN:-example.com}echo"=== 1. 检查并安装 ingress-nginx ==="if!kubectl get ns ingress-nginx&>/dev/null;thenhelm upgrade--installingress-nginx ingress-nginx/ingress-nginx\--namespaceingress-nginx --create-namespace\--setcontroller.service.type=LoadBalancer kubectlwait--namespaceingress-nginx\--for=condition=ready pod\--selector=app.kubernetes.io/component=controller\--timeout=120sfiecho"=== 2. 检查并安装 cert-manager ==="if!kubectl get ns cert-manager&>/dev/null;thenhelm upgrade--installcert-manager jetstack/cert-manager\--namespacecert-manager --create-namespace\--setinstallCRDs=true kubectlwait--for=condition=ready pod\-lapp.kubernetes.io/instance=cert-manager\-ncert-manager--timeout=120sfiecho"=== 3. 创建证书颁发机构 ==="kubectl apply-fk8s/cert-manager/cluster-issuer.yamlecho"=== 4. 应用网络策略 ==="kubectl apply-fk8s/network-policy/-n${NAMESPACE}echo"=== 5. 应用 Ingress ==="kubectl apply-fk8s/ingress/-n${NAMESPACE}echo"=== 6. 等待证书申请 ==="echo"(Let's Encrypt HTTP-01 需要域名 DNS 已解析到集群 IP)"sleep10kubectl get certificate-n${NAMESPACE}EXTERNAL_IP=$(kubectl get svc ingress-nginx-controller\-ningress-nginx\-ojsonpath='{.status.loadBalancer.ingress[0].ip}'2>/dev/null||echo"pending")echo""echo"✅ 网络配置部署完成!"echo"外部 IP:${EXTERNAL_IP}"echo"请在 DNS 管理处添加 A 记录:"echo"${DOMAIN}A${EXTERNAL_IP}"echo" www.${DOMAIN}A${EXTERNAL_IP}"echo" admin.${DOMAIN}A${EXTERNAL_IP}"

7.4 常用验证命令

# 测试 Ingress 路由(本地,用 curl 指定 Host)curl-H"Host: example.com"http://$(minikubeip)/api/healthcurl-H"Host: example.com"https://example.com/api/health# 测试 NetworkPolicy(从 frontend Pod 尝试直连数据库,应失败)kubectlexec-nmyapp deploy/frontend --\timeout5bash-c"echo > /dev/tcp/postgres/5432"2>&1# 应超时(被 NetworkPolicy 阻止)# 测试 API 可以连接数据库(应成功)kubectlexec-nmyapp deploy/api --\bash-c"pg_isready -h postgres -p 5432"# 应返回 accepting connections# 查看证书状态kubectl get certificate-nmyapp kubectl describe certificate-nmyapp# 查看 Ingress 状态kubectl get ingress-nmyapp kubectl describe ingress myapp-main-nmyapp# 查看 NetworkPolicykubectl get networkpolicy-nmyapp

总结

组件作用关键点
CoreDNS集群内 DNS 解析<svc>.<ns>.svc.cluster.local
IngressHTTP/HTTPS 统一入口host/path 路由,共享 LB
ingress-nginxIngress 控制器实现注解驱动,金丝雀,限流,Basic Auth
cert-manager自动 TLS 证书Let’s Encrypt,自动续期
NetworkPolicy网络访问控制默认拒绝,白名单放行

核心生产原则:

  1. 用 Ingress 替代多个 LoadBalancer(省钱且统一管理)
  2. cert-manager 自动管理证书(永不过期)
  3. NetworkPolicy 最小权限原则(先 deny-all,再按需放行)
  4. DNS 放行必须最先配置(否则所有 Pod 解析失败)

下一篇预告:K8s 生产实践——HPA 自动扩缩容、滚动更新策略、Pod 优雅停机、ResourceQuota、PodDisruptionBudget。


💬你们 K8s 生产集群用的哪个 Ingress 控制器?NetworkPolicy 踩过什么坑?欢迎评论区分享!

🙏如果这篇帮到你,点赞 + 收藏,系列持续更新!


本文为原创技术分享。环境:Kubernetes 1.30+,ingress-nginx,cert-manager。最后更新:2026-05-20

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/1 16:41:17

【AI培训中台项目介绍】

AI智能培训中台 – 产品说明与技术设计文档 版本&#xff1a;v1.0 | 日期&#xff1a;2026-04-10 | 作者&#xff1a;田旭旭 一、产品概述 1.1 产品定位 AI智能培训中台&#xff08;YQG AI Training Center&#xff09;是一款面向金融催收行业的AI驱动全场景培训平台。平台通…

作者头像 李华
网站建设 2026/6/1 16:40:21

百度页面仿写总结

百度页面仿写总结 一、项目概述 本次百度页面仿写项目主要聚焦于 HTML 结构和 CSS 样式的实现&#xff0c;涵盖了搜索框、导航栏、热搜榜、页脚、浮动导航等核心模块。 二、搜索框设计 1. 占位符左上角对齐 默认的 input 占位符是垂直居中的&#xff0c;想要左上角对齐需要用 t…

作者头像 李华
网站建设 2026/6/1 16:39:25

3步实现QQ空间记忆永久保存的智能方案

3步实现QQ空间记忆永久保存的智能方案 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾深夜翻看QQ空间&#xff0c;看着那些十年前的说说&#xff0c;突然发现有些记忆已经模糊&…

作者头像 李华
网站建设 2026/6/1 16:36:57

多角色智能体实践

方式一&#xff1a;手动并行&#xff08;Git Worktrees&#xff09; 原理&#xff1a; 同一个 Git 仓库&#xff0c;checkout 出多个独立工作目录&#xff0c;每个目录开一个 Claude Code session。 # 主仓库 git worktree add ../feature-frontend feature/frontend git workt…

作者头像 李华
网站建设 2026/6/1 16:36:57

std::visit深入理解及源码分析

目录 1.简介 2.基础用法 3.高级技巧 4.注意事项 5.与其他访问方式对比 6.底层原理 6.1.原理分析 6.2.源码分析 6.2.1.从入参限制只允许传入 variant 6.2.2.std::visit 入口函数&#xff08;编译期核心&#xff09; 6.2.3._Visit_impl 策略选择器&#xff08;性能核心…

作者头像 李华