1. 为什么需要掌握Service创建与验证?
在Kubernetes集群中,Service是连接应用组件的关键抽象层。我刚开始准备CKA考试时,曾天真地认为只要会创建Deployment就万事大吉,直到在实际工作中遇到前端服务无法访问后端API的窘境才真正理解Service的重要性。
Service主要解决三大核心问题:
- 动态Pod寻址:当Pod因扩缩容或故障重建时,IP地址会变化,Service提供稳定的访问端点
- 负载均衡:自动将请求分发到多个Pod实例
- 服务发现:通过DNS名称使集群内部组件能相互定位
在CKA考试环境中,Service相关的操作占实操题目的20%以上权重。根据最新考试大纲,2025年新版试题特别强调对Service类型选择和多端口配置的实操考核。下面这个表格对比了考试中最常测试的Service类型:
| 类型 | 典型用例 | 考试重点 | 配置复杂度 |
|---|---|---|---|
| ClusterIP | 内部服务通信 | YAML字段校验 | ★★☆ |
| NodePort | 开发测试环境 | 端口范围规则 | ★★★ |
| LoadBalancer | 云环境生产部署 | 与Ingress结合 | ★★★★ |
| Headless | 有状态服务 | DNS记录验证 | ★★★★ |
提示:考试时遇到Service题目,一定要先判断题目要求的服务暴露方式,这是最常见的扣分点。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 实验环境准备要点
2.1 最小化集群搭建
我用kubeadm快速搭建了一个符合考试要求的集群:
bash复制# 控制平面节点初始化
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=192.168.56.101
# 安装Calico网络插件
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
# 加入工作节点(在worker节点执行)
kubeadm join 192.168.56.101:6443 --token xxxx \
--discovery-token-ca-cert-hash sha256:xxxx
验证集群状态时,这几个命令必须烂熟于心:
bash复制kubectl get nodes -o wide # 查看节点Ready状态和IP
kubectl cluster-info # 确认核心组件健康
kubectl get cs # 传统方式检查组件状态
2.2 常见环境问题排查
在虚拟机环境中经常遇到这些问题:
- 时间不同步:导致证书验证失败
bash复制sudo timedatectl set-ntp true - 内存不足:控制平面组件频繁崩溃
bash复制free -h # 确保至少2GB可用内存 - 网络插件冲突:Flannel与Calico混用导致Pod无法通信
注意:考试环境通常是预配置好的,但自己练习时这些问题会浪费大量时间。建议使用2CPU/4GB内存以上的虚拟机配置。
3. Service创建全流程实操
3.1 从Deployment到Service
先创建一个用于测试的Nginx Deployment:
yaml复制# nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-test
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
应用配置后,创建对应的ClusterIP Service:
yaml复制# nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
关键验证步骤:
bash复制kubectl get svc nginx-service -o wide # 查看分配的ClusterIP
kubectl get endpoints nginx-service # 验证Endpoint是否正确关联Pod
curl <cluster-ip> # 从集群内部测试访问
3.2 NodePort服务暴露
将上述Service改为NodePort类型:
yaml复制# nginx-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
spec:
type: NodePort
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080 # 手动指定端口(可选)
创建后验证:
bash复制kubectl get svc nginx-nodeport
# 通过节点IP访问
curl http://<node-ip>:30080
重要限制:
- 默认NodePort范围:30000-32767
- 生产环境不应直接使用NodePort,应配合LoadBalancer或Ingress
3.3 多端口Service配置
对于需要暴露多个端口的应用(如HTTP+HTTPS):
yaml复制# multi-port-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
- name: https
protocol: TCP
port: 443
targetPort: 8443
验证时需指定端口名称:
bash复制kubectl port-forward svc/web-service 8080:http 8443:https
4. 高级调试与验证技巧
4.1 端点(Endpoint)手动管理
当Service没有正确关联Pod时,可以检查Endpoint对象:
bash复制kubectl describe endpoints nginx-service
kubectl get pods -l app=nginx -o wide # 验证Pod IP是否匹配
手动创建Endpoint的典型场景:
yaml复制# external-endpoint.yaml
apiVersion: v1
kind: Service
metadata:
name: external-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: v1
kind: Endpoints
metadata:
name: external-service
subsets:
- addresses:
- ip: 192.168.1.100 # 外部服务IP
ports:
- port: 80
4.2 DNS解析验证
在Pod内验证Service的DNS解析:
bash复制kubectl run -it --rm --image=busybox:1.28 test-pod -- sh
# 在容器内执行
nslookup nginx-service
wget -O- http://nginx-service
常见DNS问题:
- CoreDNS Pod未运行
- Service没有正确设置标签选择器
- 网络策略阻止了DNS查询
4.3 会话保持测试
测试SessionAffinity配置效果:
yaml复制# session-affinity.yaml
apiVersion: v1
kind: Service
metadata:
name: sticky-service
spec:
sessionAffinity: ClientIP
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
验证方法:
bash复制# 在多个终端同时运行
while true; do curl http://<service-ip>/hostname; sleep 1; done
# 应看到请求总是落到同一个Pod
5. CKA考试特别注意事项
5.1 时间管理策略
Service相关题目通常需要完成以下操作:
- 创建/修改Service定义(6-8分钟)
- 验证连通性(2-3分钟)
- 故障排查(如有问题,5分钟内解决)
建议的解题流程:
mermaid复制graph TD
A[审题明确要求] --> B[创建临时YAML文件]
B --> C[apply配置]
C --> D[立即验证]
D -->|失败| E[检查describe输出]
E --> F[修正问题]
F --> C
D -->|成功| G[进行下一题]
5.2 必会的kubectl命令
这些命令必须肌肉记忆:
bash复制# 查看Service详情(含标签选择器)
kubectl describe svc <name>
# 快速暴露临时访问端口
kubectl port-forward svc/<name> <local-port>:<target-port>
# 查看Service关联的Pod
kubectl get pods -l <selector>
# 查看原始YAML配置(考试时常用)
kubectl get svc <name> -o yaml
5.3 典型扣分点
根据考生反馈,这些错误最常见:
- 混淆port/targetPort/nodePort字段
- 忘记设置selector或标签不匹配
- 错误使用hostPort代替Service
- 未考虑命名空间的影响
- 直接修改系统服务的配置(如kube-dns)
我在模拟考试中犯过的错误:
- 将ClusterIP误写为clusterIP(大小写敏感)
- 在多端口配置中遗漏了端口名称
- 忘记删除临时测试Service影响后续题目
6. 生产环境进阶实践
6.1 流量管理策略
通过Service实现金丝雀发布:
yaml复制# canary-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: main-service
spec:
selector:
app: main-app
ports:
- port: 80
---
apiVersion: v1
kind: Service
metadata:
name: canary-service
spec:
selector:
app: canary-app
ports:
- port: 80
配合Ingress实现流量切分:
yaml复制# canary-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: canary-ingress
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "20"
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: canary-service
port:
number: 80
6.2 服务网格集成
在Istio中Service的特殊表现:
- 自动注入Sidecar后,Service流量会被劫持
- VirtualService资源会覆盖K8s原生Service行为
- 需要特别处理headless service
验证Istio服务发现:
bash复制istioctl proxy-config endpoints <pod> --cluster outbound|<port>||<svc>.<ns>.svc.cluster.local
6.3 性能优化技巧
提升Service性能的方法:
- 使用IPVS代理模式(kube-proxy设置)
bash复制kubectl edit cm -n kube-system kube-proxy # 修改mode: "ipvs" - 合理设置EndpointSlice
yaml复制apiVersion: discovery.k8s.io/v1 kind: EndpointSlice metadata: name: example-abc labels: kubernetes.io/service-name: example addressType: IPv4 ports: - name: http protocol: TCP port: 80 endpoints: - addresses: - "10.1.2.3" conditions: ready: true - 避免过多的Service导致DNS查询压力
7. 故障排查手册
7.1 连接超时问题
排查流程:
- 检查Service selector与Pod标签是否匹配
bash复制
kubectl get pods --show-labels kubectl get svc -o wide - 验证网络插件是否正常工作
bash复制
kubectl get pods -n kube-system | grep -e flannel -e calico -e coredns - 测试Pod到Pod的直接连通性
bash复制kubectl run -it --rm --image=nicolaka/netshoot test -- bash # 在容器内测试 ping <target-pod-ip> curl http://<target-pod-ip>
7.2 DNS解析失败
常见原因及解决方案:
| 现象 | 可能原因 | 排查命令 |
|---|---|---|
| 完全无法解析 | CoreDNS未运行 | kubectl get pods -n kube-system |
| 部分服务无法解析 | 网络策略限制 | kubectl describe networkpolicy |
| 解析延迟高 | 大量Service导致DNS压力 | kubectl top pods -n kube-system |
7.3 端口冲突处理
当遇到类似错误时:
code复制Error creating: endpoints "nginx-service" is forbidden:
port 80 is already in use by service default/old-service
解决方法:
- 查找冲突Service
bash复制
kubectl get svc --all-namespaces - 删除或修改旧Service
bash复制
kubectl delete svc old-service - 或者为新Service指定不同端口
8. 备考资源推荐
8.1 官方文档精读
必须掌握的官方文档章节:
8.2 模拟环境搭建
我使用的练习环境配置:
- 虚拟机:VirtualBox + Ubuntu 22.04
- 集群工具:kubeadm 1.29 + Calico 3.26
- 资源分配:
- Master: 2CPU/4GB RAM
- Worker: 1CPU/2GB RAM × 2
一键重置练习环境脚本:
bash复制kubectl delete all --all && \
kubectl delete pvc --all && \
kubectl delete configmap,secret --all
8.3 真题模拟网站
这些平台提供最接近真实考试的体验:
- Killer.sh(官方合作平台)
- Katacoda(已归档但可离线使用)
- Play with Kubernetes(免费临时环境)
我在考前两周的练习节奏:
- 每天完成3-5个Service相关题目
- 记录每个操作耗时,优化命令输入速度
- 整理错题本,重点复习标签选择器错误
