Skip to content

Service

类型

  • ClusterIP:默认类型,会分配一个集群内可访问的虚拟 IP
  • NodePort:会暴露一个端口出去,通过 <NodeIP>:<NodePort> 可以访问
  • LoadBalancer:使用云服务商提供的负载均衡器对外提供服务
  • ExternalName:转发到其它服务上

创建 Service

ClusterIP

yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80

其中 port 是 Service 对外暴露的端口,targetPort 是目标 Pod 的端口。在不声明的情况下,targetPort 默认和 port 保持一致。

NodePort

NodePort 类型的 Service 可以使用 <NodeIP>:<NodePort> 来访问,例如:

yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 32080

如果不指定 nodePort,系统会默认分配一个端口。默认的端口范围是 30000-32767

更多详情参考 Type NodePort

LoadBalancer

通过云服务商提供的负载均衡器对外暴露服务。

更多详情参考 Type LoadBalancer

ExternalName

ExternalName 类型的 Service 可以在 DNS 解析阶段,将服务地址解析成另一个外部服务的地址,从而进行访问。例如:

yaml
apiVersion: v1
kind: Service
metadata:
  name: httpbin
spec:
  type: ExternalName
  externalName: httpbin.org

更多详情参考 Type ExternalName

多端口

一个 Service 可以对外暴露多个端口,此时应当为每个端口指定一个 name

yaml
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 9376
  - name: https
    protocol: TCP
    port: 443
    targetPort: 9377

服务发现

环境变量

详情参考 Environment variables

由于对服务启动顺序有依赖,因此实际很少使用。

DNS

服务之间可以通过 service-name.namespacee 的方式来互相访问,如果两个服务在同一个 namespace 下,可以直接通过 service-name 来互相访问。

例如:

bash
$ kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
nginx        ClusterIP   10.107.254.54   <none>        80/TCP    1d

$ kubectl run -it --rm busybox --image=busybox:1.28.4 sh
If you don't see a command prompt, try pressing enter.
/ # wget http://nginx
Connecting to nginx (10.107.254.54:80)
index.html           100% |******************************|   612   0:00:00 ETA
/ #
/ # nslookup nginx.default
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      nginx.default
Address 1: 10.107.254.54 nginx.default.svc.cluster.local

可以看到 DNS 解析 nginx.default 的地址就是 nginx Service 的 ClusterIP。

更多详情参考 DNS for Services and Pods

Headless Service

如果显式指定 clusterIPNone,那么创建出来的就是 Headless Service,通过这种方式用户可以定制负载均衡的方式。

Headless Service 不会被自动分配 ClusterIP,而且 DNS 解析也会直接解析为 Pod 的地址。

yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  clusterIP: None
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
bash
$ kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
nginx        ClusterIP   None         <none>        80/TCP    16s

$ kubectl get po -owide
NAME                     READY     STATUS    RESTARTS   AGE       IP          NODE
nginx-65fc954674-lcvcj   1/1       Running   0          22s       10.1.0.62   docker-for-desktop
nginx-65fc954674-nsnz2   1/1       Running   0          22s       10.1.0.60   docker-for-desktop
nginx-65fc954674-s7rmj   1/1       Running   0          22s       10.1.0.61   docker-for-desktop

$ kubectl run -it --rm busybox --image=busybox:1.28.4 sh
If you don't see a command prompt, try pressing enter.
/ # nslookup nginx.default
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      nginx.default
Address 1: 10.1.0.62
Address 2: 10.1.0.60
Address 3: 10.1.0.61

对外提供服务

参考