Service 与 Ingress
核心知识点
1. Service 详解
1.1 Service 的概念
Service 是 Kubernetes 中用于定义一组 Pod 的访问策略的抽象,它提供稳定的网络端点、负载均衡和服务发现功能。
┌─────────────────────────────────────────────────────┐
│ Service 架构 │
├─────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ │
│ │ Service │ │
│ │ │ │
│ │ IP: 10.0.0.1│ │
│ │ Port: 80 │ │
│ └──────┬───────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────┐ │
│ │ Pods (Selector) │ │
│ │ ┌─────┐ ┌─────┐ ┌─────┐ │ │
│ │ │Pod 1│ │Pod 2│ │Pod 3│ │ │
│ │ │:8080│ │:8080│ │:8080│ │ │
│ │ └─────┘ └─────┘ └─────┘ │ │
│ └─────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────┘1.2 Service 类型
┌─────────────────────────────────────────────────────┐
│ Service 类型对比 │
├─────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ClusterIP │ │NodePort │ │LoadBalancer │ │
│ │ │ │ │ │ │ │
│ │仅集群内部 │ │节点端口 │ │外部负载均衡 │ │
│ │访问 │ │访问 │ │访问 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ ExternalName │ │
│ │ │ │
│ │ 映射到外部 DNS 名称 │ │
│ └─────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────┘1.3 Service 配置示例
apiVersion: v1
kind: Service
metadata:
name: my-service
labels:
app: myapp
spec:
type: ClusterIP
selector:
app: myapp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
- name: https
protocol: TCP
port: 443
targetPort: 8443
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 108002. Service 类型详解
2.1 ClusterIP Service
apiVersion: v1
kind: Service
metadata:
name: clusterip-service
spec:
type: ClusterIP
selector:
app: web
ports:
- port: 80
targetPort: 8080
protocol: TCP2.2 NodePort Service
apiVersion: v1
kind: Service
metadata:
name: nodeport-service
spec:
type: NodePort
selector:
app: web
ports:
- port: 80
targetPort: 8080
nodePort: 30080
protocol: TCP
externalTrafficPolicy: Local2.3 LoadBalancer Service
apiVersion: v1
kind: Service
metadata:
name: loadbalancer-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
spec:
type: LoadBalancer
selector:
app: web
ports:
- port: 80
targetPort: 8080
protocol: TCP
loadBalancerSourceRanges:
- 10.0.0.0/8
- 192.168.0.0/162.4 ExternalName Service
apiVersion: v1
kind: Service
metadata:
name: external-dns
spec:
type: ExternalName
externalName: example.com3. Ingress 详解
3.1 Ingress 的概念
Ingress 是 Kubernetes 中用于管理外部访问集群内服务的 API 对象,它提供 HTTP 和 HTTPS 路由规则。
┌─────────────────────────────────────────────────────┐
│ Ingress 架构 │
├─────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ │
│ │ Client │ │
│ └──────┬───────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ Ingress │ │
│ │ Controller │ │
│ └──────┬───────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────┐ │
│ │ Services │ │
│ │ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Service │ │ Service │ │ │
│ │ │ A │ │ B │ │ │
│ │ └────┬────┘ └────┬────┘ │ │
│ └───────┼────────────┼───────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────────────┐ │
│ │ Pods │ │
│ └─────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────┘3.2 Ingress Controller
Ingress Controller 是实现 Ingress 功能的组件,常见的有:
- NGINX Ingress Controller:最流行的 Ingress Controller
- Traefik:自动服务发现和配置
- HAProxy Ingress:高性能负载均衡
- Istio Gateway:服务网格集成
- AWS ALB Ingress Controller:AWS 集成
3.3 Ingress 配置示例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- example.com
- www.example.com
secretName: example-tls
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
- host: api.example.com
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80804. Service 管理命令
4.1 创建和查看 Service
# 创建 Service
kubectl apply -f service.yaml
# 查看 Service 列表
kubectl get services
# 查看 Service 详细信息
kubectl describe service my-service
# 查看 Service 端点
kubectl get endpoints my-service
# 查看 Service YAML 配置
kubectl get service my-service -o yaml
# 删除 Service
kubectl delete service my-service
# 查看 Service 的 Cluster IP
kubectl get service my-service -o jsonpath='{.spec.clusterIP}'
# 查看 Service 的端口
kubectl get service my-service -o jsonpath='{.spec.ports}'4.2 Service 调试
# 测试 Service 连通性
kubectl run test-pod --image=busybox --rm -it -- wget -O- http://my-service
# 查看 Service 的 DNS 解析
kubectl run test-pod --image=busybox --rm -it -- nslookup my-service
# 查看 Service 的端点
kubectl get endpoints my-service -o wide
# 查看 Service 事件
kubectl describe service my-service
# 查看 Service 关联的 Pod
kubectl get pods -l app=myapp5. Ingress 管理命令
5.1 创建和查看 Ingress
# 创建 Ingress
kubectl apply -f ingress.yaml
# 查看 Ingress 列表
kubectl get ingress
# 查看 Ingress 详细信息
kubectl describe ingress my-ingress
# 查看 Ingress YAML 配置
kubectl get ingress my-ingress -o yaml
# 删除 Ingress
kubectl delete ingress my-ingress
# 查看 Ingress 地址
kubectl get ingress my-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}'5.2 Ingress 调试
# 查看 Ingress Controller 日志
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller
# 查看 Ingress Controller 状态
kubectl get pods -n ingress-nginx
# 测试 Ingress 路由
curl -H "Host: example.com" http://<ingress-ip>/
# 查看 Ingress 配置
kubectl exec -n ingress-nginx deployment/ingress-nginx-controller -- cat /etc/nginx/nginx.conf
# 重新加载 Ingress Controller
kubectl exec -n ingress-nginx deployment/ingress-nginx-controller -- nginx -s reload6. 高级配置
6.1 Service 会话保持
apiVersion: v1
kind: Service
metadata:
name: session-service
spec:
selector:
app: web
ports:
- port: 80
targetPort: 8080
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 108006.2 Service 健康检查
apiVersion: v1
kind: Service
metadata:
name: health-check-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-healthcheck-path: /health
service.beta.kubernetes.io/aws-load-balancer-healthcheck-interval: "30"
service.beta.kubernetes.io/aws-load-balancer-healthcheck-timeout: "5"
service.beta.kubernetes.io/aws-load-balancer-healthcheck-healthy-threshold: "2"
service.beta.kubernetes.io/aws-load-balancer-healthcheck-unhealthy-threshold: "3"
spec:
type: LoadBalancer
selector:
app: web
ports:
- port: 80
targetPort: 80806.3 Ingress 路由规则
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: advanced-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rate-limit: "100"
spec:
ingressClassName: nginx
tls:
- hosts:
- example.com
secretName: tls-secret
rules:
- host: example.com
http:
paths:
- path: /api(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: api-service
port:
number: 8080
- path: /web
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
- path: /admin
pathType: Prefix
backend:
service:
name: admin-service
port:
number: 80816.4 Ingress 认证
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: auth-ingress
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"
spec:
ingressClassName: nginx
rules:
- host: secure.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: secure-service
port:
number: 8080实用案例分析
案例 1:部署 Web 应用并暴露服务
场景描述
部署一个 Nginx Web 应用,使用 Service 暴露服务。
操作步骤
# 1. 创建 Deployment
cat > web-deployment.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
EOF
kubectl apply -f web-deployment.yaml
# 2. 创建 ClusterIP Service
cat > web-service-clusterip.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
name: web-service-clusterip
spec:
type: ClusterIP
selector:
app: web
ports:
- port: 80
targetPort: 80
protocol: TCP
EOF
kubectl apply -f web-service-clusterip.yaml
# 3. 查看 Service
kubectl get services
# 4. 测试 Service 连通性
kubectl run test-pod --image=busybox --rm -it -- wget -O- http://web-service-clusterip
# 5. 创建 NodePort Service
cat > web-service-nodeport.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
name: web-service-nodeport
spec:
type: NodePort
selector:
app: web
ports:
- port: 80
targetPort: 80
nodePort: 30080
protocol: TCP
EOF
kubectl apply -f web-service-nodeport.yaml
# 6. 查看 NodePort Service
kubectl get services
# 7. 通过节点端口访问
curl http://<node-ip>:30080
# 8. 清理资源
kubectl delete -f web-deployment.yaml
kubectl delete -f web-service-clusterip.yaml
kubectl delete -f web-service-nodeport.yaml案例 2:配置 Ingress 实现域名路由
场景描述
使用 Ingress 配置多个服务的域名路由。
操作步骤
# 1. 安装 NGINX Ingress Controller
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml
# 2. 等待 Ingress Controller 就绪
kubectl wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=120s
# 3. 创建 Web 应用
cat > web-app.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
EOF
kubectl apply -f web-app.yaml
# 4. 创建 API 应用
cat > api-app.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-app
spec:
replicas: 2
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: kennethreitz/httpbin
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: api-service
spec:
selector:
app: api
ports:
- port: 80
targetPort: 80
EOF
kubectl apply -f api-app.yaml
# 5. 创建 Ingress
cat > multi-host-ingress.yaml << 'EOF'
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-host-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: web.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
EOF
kubectl apply -f multi-host-ingress.yaml
# 6. 查看 Ingress
kubectl get ingress
# 7. 获取 Ingress IP
kubectl get ingress multi-host-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
# 8. 测试路由(添加域名到 /etc/hosts)
echo "<ingress-ip> web.example.com api.example.com" | sudo tee -a /etc/hosts
curl -H "Host: web.example.com" http://<ingress-ip>/
curl -H "Host: api.example.com" http://<ingress-ip>/get
# 9. 清理资源
kubectl delete -f web-app.yaml
kubectl delete -f api-app.yaml
kubectl delete -f multi-host-ingress.yaml
kubectl delete -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml案例 3:配置 HTTPS Ingress
场景描述
使用 Let's Encrypt 配置 HTTPS Ingress。
操作步骤
# 1. 安装 cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
# 2. 等待 cert-manager 就绪
kubectl wait --namespace cert-manager \
--for=condition=ready pod \
--selector=app.kubernetes.io/instance=cert-manager \
--timeout=120s
# 3. 创建 ClusterIssuer
cat > cluster-issuer.yaml << 'EOF'
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: your-email@example.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
EOF
kubectl apply -f cluster-issuer.yaml
# 4. 创建应用
cat > secure-app.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: secure-app
spec:
replicas: 2
selector:
matchLabels:
app: secure
template:
metadata:
labels:
app: secure
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: secure-service
spec:
selector:
app: secure
ports:
- port: 80
targetPort: 80
EOF
kubectl apply -f secure-app.yaml
# 5. 创建 HTTPS Ingress
cat > https-ingress.yaml << 'EOF'
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: https-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- secure.example.com
secretName: secure-tls
rules:
- host: secure.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: secure-service
port:
number: 80
EOF
kubectl apply -f https-ingress.yaml
# 6. 查看 Ingress
kubectl get ingress
# 7. 查看证书状态
kubectl get certificate
# 8. 查看证书详情
kubectl describe certificate secure-tls
# 9. 测试 HTTPS 连接
curl -k https://secure.example.com
# 10. 清理资源
kubectl delete -f secure-app.yaml
kubectl delete -f https-ingress.yaml
kubectl delete -f cluster-issuer.yaml
kubectl delete -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml最佳实践
使用 ClusterIP 作为默认 Service 类型:仅在需要外部访问时使用其他类型。
使用 Headless Service 进行有状态应用:直接暴露 Pod IP。
apiVersion: v1
kind: Service
metadata:
name: headless-service
spec:
clusterIP: None
selector:
app: stateful
ports:
- port: 80
targetPort: 8080- 配置会话保持:确保同一客户端连接到同一 Pod。
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800使用 Ingress 统一管理外部访问:避免为每个服务创建 LoadBalancer。
配置 TLS 证书:使用 cert-manager 自动管理证书。
tls:
- hosts:
- example.com
secretName: tls-secret设置健康检查:确保 Service 只路由到健康的 Pod。
使用命名空间隔离:不同环境使用不同的命名空间。
监控 Service 和 Ingress:使用 Prometheus 和 Grafana 监控服务性能。
总结
本教程详细介绍了 Kubernetes 中 Service 和 Ingress 的概念、配置和管理。通过实际案例,我们学习了如何创建和管理服务、配置负载均衡以及实现外部访问。掌握这些知识后,可以构建完整的容器化应用网络架构,实现高可用和高性能的服务部署。