Service 与网络
Service 为一组 Pod 提供稳定的网络访问入口,是 Kubernetes 实现服务发现和负载均衡的核心资源。
什么是 Service?
Service 是一个抽象层,为一组 Pod 提供稳定的 IP 地址和 DNS 名称,屏蔽了 Pod 的动态性。
Service 类型
1. ClusterIP(默认)
仅在集群内部可访问:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
# 访问 Service
# 在集群内通过 DNS 或 IP 访问
curl http://my-service.default.svc.cluster.local
curl http://10.0.0.100:80
2. NodePort
在每个节点的固定端口上暴露服务:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # 指定端口(30000-32767)
protocol: TCP
name: http
# 访问 Service
curl http://<node-ip>:30080
3. LoadBalancer
使用云提供商的负载均衡器:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
protocol: TCP
4. ExternalName
映射到外部域名:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ExternalName
externalName: my.external.domain
Service 端点
Service 自动维护 EndpointSlice,追踪后端 Pod:
apiVersion: v1
kind: Endpoints
metadata:
name: my-service
subsets:
- addresses:
- ip: 10.1.0.1
targetRef:
kind: Pod
name: pod-1
- ip: 10.1.0.2
targetRef:
kind: Pod
name: pod-2
ports:
- port: 80
protocol: TCP
服务发现
DNS 机制
Kubernetes 提供集群内 DNS 自动解析:
# Service DNS 格式
# <service-name>.<namespace>.svc.cluster.local
# 简写(同一命名空间)
curl http://my-service
# 跨命名空间
curl http://my-service.other-namespace.svc.cluster.local
无头服务(Headless Service)
不分配 ClusterIP,直接解析 Pod IP:
apiVersion: v1
kind: Service
metadata:
name: headless-service
spec:
clusterIP: None # 关键:设置为 None
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
# DNS 解析返回所有 Pod IP
nslookup headless-service.default.svc.cluster.local
Ingress
Ingress 是 HTTP/HTTPS 路由的入口:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
Ingress 配置示例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
# SSL 重定向
nginx.ingress.kubernetes.io/ssl-redirect: "true"
# 启用 CORS
nginx.ingress.kubernetes.io/enable-cors: "true"
spec:
tls:
- hosts:
- myapp.example.com
secretName: my-tls-secret
rules:
- host: myapp.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
NetworkPolicy
NetworkPolicy 用于控制 Pod 间的网络流量:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-network-policy
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: web
- namespaceSelector:
matchLabels:
name: production
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
常用场景
# 1. 拒绝所有入站流量(默认拒绝)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
spec:
podSelector: {}
policyTypes:
- Ingress
# 2. 允许同一命名空间内的流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-same-namespace
spec:
podSelector: {}
ingress:
- from:
- podSelector: {}
# 3. 允许特定标签的流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-frontend
spec:
podSelector:
matchLabels:
app: backend
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
DNS 服务
CoreDNS 配置
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
}
网络调试命令
# 查看 Service
kubectl get svc
# 查看 Endpoint
kubectl get endpoints
# 查看 Ingress
kubectl get ingress
# 查看 NetworkPolicy
kubectl get networkpolicy
# 描述 Service
kubectl describe svc my-service
# 测试 DNS 解析
kubectl exec -it busybox -- nslookup my-service
# 端口转发测试
kubectl port-forward svc/my-service 8080:80
最佳实践
1. 使用合适的 Service 类型
# 生产环境推荐:ClusterIP + Ingress
spec:
type: ClusterIP
2. 为 Service 添加标签
metadata:
labels:
app: my-app
tier: backend
3. 使用健康检查
确保 Pod 的就绪探针正常工作,Service 只会将流量路由到就绪的 Pod。
4. 使用 NetworkPolicy
# 限制 Pod 间访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
spec:
podSelector: {}
policyTypes:
- Ingress
服务网格(Service Mesh)
Istio 简介
Istio 是流行的服务网格解决方案,提供:
- mTLS 加密
- 流量管理
- 可观测性
- 安全策略
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: my-service
spec:
hosts:
- my-service
http:
- route:
- destination:
host: my-service
subset: v1
weight: 90
- destination:
host: my-service
subset: v2
weight: 10
小结
本章我们学习了:
- Service 概念:稳定的网络入口
- Service 类型:ClusterIP、NodePort、LoadBalancer、ExternalName
- 服务发现:DNS 解析和无头服务
- Ingress:HTTP/HTTPS 路由
- NetworkPolicy:网络策略控制
- 网络调试:常用命令和工具
练习
- 创建一个 NodePort 类型的 Service
- 配置 Ingress 实现基于路径的路由
- 创建 NetworkPolicy 限制 Pod 访问
- 使用 kubectl 调试服务连接
准备好继续学习了吗?点击下一章了解存储管理!