1 Service定义

Kubernetes通过Service为具有相同功能的容器提供统一的入口地址,并将请求负载均衡分发到各个Pod上。

2 Service模板

apiVersion: v1
kind: Service
metadata:
  name: string
  namespace: string
  labels:
    - name: string
  annotations:
    - name: string
spec:
  # Label Selector配置,将具有指定Label的Pod纳入管理
  selector: []
  # Service类型,默认为ClusterIP
  # 1) ClusterIP:虚拟服务的IP地址
  # 2) NodePort:宿主机的端口
  # 3) LoadBalancer:使用外部负载均衡器,需要定义status.loadBalancer中定义外部IP地址,并同时定义nodePort和clusterIP
  type: string
  # 虚拟服务IP地址
  clusterIP: string
  # 是否支持Session
  sessionAffinity: string
  # 端口列表
  ports:
    # 端口名称
    - name: string
      # 端口协议,支持TCP和UDP,默认为TCP
      protocol: string
      # 服务监听的端口号
      port: int
      # 需要转发到后端Pod的端口号
      targetPort: int
      # 需要映射到物理机的端口号
      nodePort: int
# 当spec.type = LoadBalancer时,需要设置负载均衡器地址
status:
  loadBalancer:
    ingress:
      # 外部负载均衡器IP地址
      - ip: string
        # 外部负载均衡器主机名
        hostname: string

3 Service用法

新建两个Nginx Pod

pod-nginx-1.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx-1
  labels:
    app: nginx
spec:
  containers:
    - name: nginx-1
      image: nginx
      ports:
        - containerPort: 80

pod-nginx-2.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx-2
  labels:
    app: nginx
spec:
  containers:
    - name: nginx-2
      image: nginx
      ports:
        - containerPort: 80

新建一个Service指向Label app=nginx,端口80转发到Pod中的80端口
service-nginx.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  ports:
    - port: 80
      targetPort: 80
  selector:
    app: nginx

测试Service的负载均衡

$ kubectl get service -o wide
NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE    SELECTOR
nginx-service   ClusterIP   10.108.172.195   <none>        80/TCP    16m    app=nginx

# 多执行几次,方便查看Pod日志
$ curl -G 10.108.172.195

<!DOCTYPE html>
<html>
<head>
    <title>Welcome to nginx!</title>
    <style>
        html { color-scheme: light dark;}
        body { width: 35em;margin: 0 auto;font-family: Tahoma, Verdana, Arial, sans-serif;}
    </style>
</head>
<body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p>
    <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p>
    <p><em>Thank you for using nginx.</em></p>
</body>
</html>

查看两个Pod的日志,可以看到请求被转发到了两个Pod上

$ kubectl logs nginx-1
10.244.0.0 - - [05/Feb/2022:12:46:29 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"

$ kubectl logs nginx-2
10.244.0.0 - - [05/Feb/2022:12:46:30 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"

4 Service外部访问

Service和Pod默认情况下,是无法在集群外访问的,如果需要被外部客户端,需要设置NodePort

apiVersion: v1
kind: Service
metadata:
  name: nginx-service-node-port
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
      nodePort: 31000
  selector:
    app: nginx

注:端口号需要在30000-32767之间

查看service所在的node

$ kubectl get service -o wide

NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE    SELECTOR
nginx-service-node-port   NodePort    10.105.55.119   <none>        80:31000/TCP   9s     app=nginx

通过浏览器访问该Service,可以看到外网已经能通过31000端口访问Nginx

image.png