容器网络实践笔记
这次做 Kubernetes 迁移,从 Docker 的简单网络到 Kubernetes 的 CNI,再到 Service Mesh,网络复杂度上升了好几个档次。
dblocalhostmyservice:80` 访问后端服务。
Docker 网络基础
Bridge 模式
最简单的网络模式,每个容器有自己的网络命名空间,通过 veth pair 连接到宿主机的网桥。
# 创建一个容器,默认使用 bridge 模式
docker run -d --name mycontainer nginx
# 查看网络配置
docker network inspect bridge
优势:简单,不需要额外配置 劣势:跨主机通信麻烦,需要端口映射
Host 模式
容器共享宿主机网络命名空间,直接使用宿主机的网络栈。
docker run -d --network host myapp
优势:性能好,网络开销小 劣势:端口冲突,容器间无隔离
自定义网络
可以创建自定义网络,容器之间通过服务名互相访问。
# 创建自定义网络
docker network create myapp-network
# 启动容器并连接到自定义网络
docker run -d --network myapp-network --name db postgres
docker run -d --network myapp-network --name web myapp
在 web 容器里可以通过 db 直接访问 postgres 容器。
Kubernetes 网络架构
Pod 网络
每个 Pod 都有唯一的 IP 地址,同一个 Pod 内的容器共享网络命名空间。
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: web
image: nginx
- name: logging
image: fluentd
web 容器和 logging 容器可以通过 localhost 互相访问。
Service 网络
Service 为 Pod 提供稳定的访问入口,解决 Pod IP 变化的问题。
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
type: ClusterIP
其他 Pod 可以通过 myservice:80 访问后端服务。
CNI 插件
CNI(Container Network Interface)是 Kubernetes 的网络插件接口,负责配置 Pod 网络。
Flannel
最简单的 CNI 插件,使用 VXLAN 封装实现跨节点通信。
# Flannel 配置
apiVersion: v1
kind: ConfigMap
metadata:
name: kube-flannel-cfg
namespace: kube-system
data:
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": "vxlan"
}
优势:配置简单,上手容易 劣势:性能一般,网络层级多
Calico
基于 BGP 的网络方案,支持网络策略。
# Calico 网络策略
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
优势:支持网络策略,性能好 劣势:配置复杂,需要 BGP
Cilium
基于 eBPF 的新一代 CNI 插件,性能极强。
# 安装 Cilium
cilium install --version 1.11.0
# 查看网络状态
cilium status
优势:性能极致,支持 Hubble 可观测性 劣势:较新,生态还在发展
Service Mesh 网络
Service Mesh 在服务网格层面处理网络通信,提供了更多高级功能。
Istio 架构
每个服务都有一个 Sidecar 代理,处理所有网络流量。
流量管理
# Istio 虚拟服务配置
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
可以基于 HTTP 头、Cookie 等进行流量路由。
实践中的选择
场景一:简单的容器化应用
Docker 自定义网络就够了,配置简单,维护方便。
场景二:中等规模的 Kubernetes 集群
Flannel 或 Calico 都可以,Flannel 简单,Calico 功能更全。
场景三:大型微服务架构
Istio 这样的 Service Mesh 提供了流量管理、安全、可观测性等功能。
踩过的坑
坑一:DNS 解析延迟
一开始 Pod 之间通过 Service DNS 访问,发现延迟有点高。
解决:使用 CoreDNS 的 NodeLocal 模式,DNS 解询直接在节点上完成,不需要跨节点。
坑二:网络策略配置错误
配置了网络策略,结果把合法流量也挡了。
解决:先测试网络策略,逐步放开,确保不影响合法流量。
坑三:Service Mesh 性能开销
上了 Service Mesh 之后,延迟确实增加了一些。
解决:
- 优化 Envoy 配置
- 关闭不必要的功能
- 对延迟敏感的服务 bypass Service Mesh
写在最后
容器网络这东西,从 Docker 的 bridge 到 Kubernetes 的 CNI,再到 Service Mesh,复杂度是逐步上升的。
选择方案的时候,不是选"最先进"的,而是选"最适合项目规模和团队能力"的。
对于小团队,Docker 网络或简单的 CNI 就够用。对于大团队,Service Mesh 提供的能力确实有价值。
这次网络调研下来,最大的收获是:网络不是孤立的问题,它和架构、运维、监控都有关系。设计网络方案的时候,要考虑到整个系统的需求。
可用性说明:本文发布于 2019 年 5 月,距今已超过五年。文中涉及的软件版本、接口、下载地址、命令参数和操作界面可能已经发生变化,部分方案在当前环境下可能失效。请结合官方最新文档核对后再操作,生产环境使用前务必先行验证。
版权声明: 本文首发于 指尖魔法屋-容器网络实践笔记(https://blog.thinkmoon.cn/post/53-container-networking-cni-service-mesh/) 转载或引用必须申明原指尖魔法屋来源及源地址!
评论
使用 GitHub 账号登录后即可留言,支持 Markdown。