展开

Service

最后发布时间 : 2023-11-19 17:18:33 浏览量 :

特性

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

创建 Service

创建 一个 Service,通过标签test-k8s跟对应的 Pod 关联上

apiVersion: v1
kind: Service
metadata:
  name: test-k8s
spec:
  selector:
    app: test-k8s
  type: ClusterIP
  ports:
    - port: 8080        # 本 Service 的端口
      targetPort: 8080  # 容器端口

应用配置 kubectl apply -f service.yaml
查看服务

 kubectl get svc
 kubectl get service

查看服务详情kubectl describe svc test-k8s,可以发现 Endpoints 是各个 Pod 的 IP,也就是他会把流量转发到这些节点。

Name:              test-k8s
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=test-k8s
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.102.6.186
IPs:               10.102.6.186
Port:              <unset>  8080/TCP
TargetPort:        8080/TCP
Endpoints:         10.244.0.49:8080,10.244.0.50:8080,10.244.0.51:8080 + 2 more...
Session Affinity:  None
Events:            <none>
NAME                        READY   STATUS    RESTARTS   AGE     IP            NODE       NOMINATED NODE   READINESS GATES
test-k8s-6c97f5c8d5-c9sb6   1/1     Running   0          3m11s   10.244.0.49   minikube   <none>           <none>
test-k8s-6c97f5c8d5-ltn9d   1/1     Running   0          3m11s   10.244.0.53   minikube   <none>           <none>
test-k8s-6c97f5c8d5-s56ck   1/1     Running   0          3m11s   10.244.0.52   minikube   <none>           <none>
test-k8s-6c97f5c8d5-wkbhf   1/1     Running   0          3m11s   10.244.0.51   minikube   <none>           <none>
test-k8s-6c97f5c8d5-xlbwz   1/1     Running   0          3m11s   10.244.0.50   minikube   <none>           <none>

服务的默认类型是ClusterIP,只能在集群内部访问,我们可以进入到 Pod 里面访问:

 kubectl exec -it test-k8s-6c97f5c8d5-c9sb6  -- bash
root@test-k8s-6c97f5c8d5-c9sb6:/app# curl http://test-k8s:8080
index page 

如果要在集群外部访问,可以通过端口转发实现(只适合临时测试用):
kubectl port-forward service/test-k8s 8888:8080

如果你用 minikube,也可以这样minikube service test-k8s

对外暴露服务

上面我们是通过端口转发的方式可以在外面访问到集群里的服务,如果想要直接把集群服务暴露出来,我们可以使用NodePortLoadbalancer类型的 Service

apiVersion: v1
kind: Service
metadata:
  name: test-k8s
spec:
  selector:
    app: test-k8s
  # 默认 ClusterIP 集群内可访问,NodePort 节点可访问,LoadBalancer 负载均衡模式(需要负载均衡器才可用)
  type: NodePort
  ports:
    - port: 8080        # 本 Service 的端口
      targetPort: 8080  # 容器端口
      nodePort: 31000   # 节点端口,范围固定 30000 ~ 32767

应用配置 kubectl apply -f service.yaml
在节点上,我们可以 curl http://localhost:31000/hello/easydoc 访问到应用
并且是有负载均衡的,网页的信息可以看到被转发到了不同的 Pod

docker exec -it minikube bash
root@minikube:/# curl http://localhost:31000/

如果你是用 minikube,因为是模拟集群,你的电脑并不是节点,节点是 minikube 模拟出来的,所以你并不能直接在电脑上访问到服务

Loadbalancer 也可以对外提供服务,这需要一个负载均衡器的支持,因为它需要生成一个新的 IP 对外服务,否则状态就一直是 pendding,这个很少用了,后面我们会讲更高端的 Ingress 来代替它。

总结

ClusterIP
默认的,仅在集群内可用

NodePort
暴露端口到节点,提供了集群外部访问的入口
端口范围固定 30000 ~ 32767

LoadBalancer
需要负载均衡器(通常都需要云服务商提供,裸机可以安装 METALLB 测试)
会额外生成一个 IP 对外服务
K8S 支持的负载均衡器:负载均衡器

Headless
适合数据库
clusterIp 设置为 None 就变成 Headless 了,不会再分配 IP,后面会再讲到具体用法
官网文档

在 Kubernetes 中,ClusterIP 和 NodePort 是用于访问服务的两种不同的方式,它们在负载均衡方面有一些区别。

  • ClusterIP:ClusterIP 是 Kubernetes 默认的服务类型,它为服务分配一个 Cluster IP 地址,该地址只在集群内部可用。通过 ClusterIP,其他服务或 Pod 可以通过服务名称来访问该服务。ClusterIP 并不直接提供负载均衡功能,它将流量均匀地分发到后端 Pod,但不涉及跨节点的流量均衡。如果需要跨节点的负载均衡,需要使用其他类型的服务或负载均衡器。

  • NodePort:NodePort 是一种服务类型,它在每个节点上开放一个固定的端口,用于将外部流量转发到服务。通过 NodePort,可以从集群外部直接访问服务。NodePort 提供了一定程度的负载均衡,因为流量将分发到各个节点上的后端 Pod。但是它并不是一种智能的负载均衡机制,它只是将流量均匀地分发到节点上的 Pod,而不考虑节点的负载情况。

综上所述,ClusterIP 和 NodePort 提供了一定程度的负载均衡,但并不是全面的负载均衡解决方案。如果您需要更高级的负载均衡功能,例如智能的负载均衡算法、健康检查、会话保持等,可以考虑使用 Kubernetes 提供的其他负载均衡解决方案,如使用 Ingress 控制器结合负载均衡器、使用外部负载均衡服务(如 AWS ELB、GCP Load Balancer)等。这些方案可以提供更强大和灵活的负载均衡能力,以满足不同的需求。