特性
- Service 通过 label 关联对应的 Pod
- Servcie 生命周期不跟 Pod 绑定,不会因为 Pod 重创改变 IP
- 提供了负载均衡功能,自动转发流量到不同 Pod
- 可对集群外部提供访问端口
- 集群内部可通过服务名字访问

创建 Service
创建 一个 Service,通过标签nginx-server跟对应的 Pod 关联上nginx-service.yaml
apiVersion: v1 # api版本声明kind: Service # 指定创建资源的类型metadata: # 资源的元数据/属性name: nginx-service # service名称namespace: demo # service的命名空间labels: # 定义标签name: nginx-service # service的标签名称spec: # 资源规格定义type: ClusterIP # 类型是NodePort。Service有四种type: ClusterIP(默认)、NodePort、LoadBalancer、ExternalName. 其中NodePort和LoadBalancer两类型的Services可以对外提供服务。selector: # 定义标签选择器app: nginx-server # 这里选择需要管理的pod的标签名ports: # 端口定义- port: 8081 # 集群内部通讯端口(自定义)targetPort: 80 # 容器对外暴露的端口,即containerPort
应用配置
$ kubectl apply -f nginx-service.yaml
查看服务
$ kubectl get svc -n demo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service ClusterIP 10.244.52.159 <none> 8081/TCP 4m49s
查看服务详情 kubectl describe svc nginx-service -n demo,可以发现 Endpoints 是各个 Pod 的 IP,也就是他会把流量转发到这些节点。
$ kubectl describe svc nginx-service -n demo
Name: nginx-service
Namespace: demo
Labels: name=nginx-service
Annotations: <none>
Selector: app=nginx-server
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.244.52.159
IPs: 10.244.52.159
Port: <unset> 8081/TCP
TargetPort: 80/TCP
Endpoints: 172.16.126.62:80
Session Affinity: None
Events: <none>
服务的默认类型是ClusterIP,只能在集群内部访问,我们可以进入到调试 Pod 里面访问:
$ kubectl run busybox --image=radial/busyboxplus:curl -n demo -i --tty --rm
If you don't see a command prompt, try pressing enter.
[ root@busybox:/ ]$ curl -w '%{http_code}' http://nginx-service.demo.svc.cluster.local:8081
999
如果要在集群外部访问,可以通过端口转发实现(只适合临时测试用):kubectl port-forward service/nginx-service --address 0.0.0.0 8888:8081 -n demo
如果你用 minikube,也可以这样
minikube service nginx-service
对外暴露服务
上面我们是通过端口转发的方式可以在外面访问到集群里的服务,如果想要直接把集群服务暴露出来,我们可以使用NodePort 和 Loadbalancer 类型的 Service
apiVersion: v1 # api版本声明
kind: Service # 指定创建资源的类型
metadata: # 资源的元数据/属性
name: nginx-service # service名称
namespace: demo # service的命名空间
labels: # 定义标签
name: nginx-service # service的标签名称
spec: # 资源规格定义
type: NodePort # 类型是NodePort。Service有四种type: ClusterIP(默认)、NodePort、LoadBalancer、ExternalName. 其中NodePort和LoadBalancer两类型的Services可以对外提供服务。
selector: # 定义标签选择器
app: nginx-server # 这里选择需要管理的pod的标签名
ports: # 端口定义
- protocol: TCP # 端口通讯协议
port: 8081 # 集群内部通讯端口(自定义)
targetPort: 80 # 容器对外暴露的端口,即containerPort
nodePort: 32334 # 所有的节点都会开放此端口,此端口供外部调用
应用配置 kubectl apply -f nginx-service.yaml
在节点上,我们可以 curl http://${node_ip}:32334 访问到应用
如果你是用 minikube,因为是模拟集群,你的电脑并不是节点,节点是 minikube 模拟出来的,所以你并不能直接在电脑上访问到服务
Loadbalancer 也可以对外提供服务,这需要一个负载均衡器的支持,因为它需要生成一个新的 IP 对外服务,否则状态就一直是 pendding,后面我们会讲更高端的 Ingress 来代替它。
总结
ClusterIP
NodePort
暴露端口到节点,提供了集群外部访问的入口
端口范围固定 30000 ~ 32767
LoadBalancer
需要负载均衡器(通常都需要云服务商提供,裸机可以安装 metallb 测试)
会额外生成一个 IP 对外服务
K8S 支持的负载均衡器:负载均衡器
Headless
适合数据库
clusterIp 设置为 None 就变成 Headless 了,不会再分配 IP,后面会再讲到具体用法
官网文档
