1. 简介
Service 的背后是一个拥有相同标签的 Pod 集合,且这些 Pod 都提供着相同的功能。
Kubernetes 为每个 Pod 都赋予了一个唯一的 IP 地址,因为 Pod 可以动态地销毁和重建,故而其 IP 地址也是动态变化的。不同于 Pod,Kubernetes 为 Service 赋予了一个 DNS 名称,且 Service 不会动态地销毁和重建,故而在其生命周期内,其对应的 IP 地址是不会改变的。
Service 为我们提供了一种服务发现机制,通过访问 Service 的 DNS 名称即可访问相应的服务。此外, Kubernetes 会将请求在后端 Pod 之间进行负载均衡。
2. 用法
svc.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: v1
kind: Pod
metadata:
name: kubia
spec:
containers:
- name: kubia
image: luksa/kubia
imagePullPolicy: IfNotPresent
targetPort
指的是 Pod 上开放的端口。
-
创建
$ kubectl apply -f svc.yaml deployment.apps/nginx-deployment created service/nginx-service created pod/kubia created
-
罗列
$ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 20m nginx-service ClusterIP 10.105.41.65 <none> 80/TCP 2m43s
-
查看详细信息
$ kubectl describe svc nginx-service Name: nginx-service Namespace: default Labels: <none> Annotations: <none> Selector: app=nginx Type: ClusterIP IP Families: <none> IP: 10.105.41.65 IPs: 10.105.41.65 Port: <unset> 80/TCP TargetPort: 80/TCP Endpoints: 172.18.0.6:80,172.18.0.7:80,172.18.0.8:80 Session Affinity: None Events: <none>
-
访问
在主机上:
$ curl http://10.105.41.65 <!DOCTYPE html> <html> ...
在集群中:
$ kubectl exec kubia -it -- curl http://nginx-service.default.svc.cluster.local <!DOCTYPE html> <html> ...
集群中的 Pod 可以根据 Service 的 FQDN 名称
ServiceName.Namespace.Domain.LTD
来访问它,且Domain.LTD
默认为svc.cluster.local
。 -
删除
$ kubectl delete -f svc.yaml deployment.apps "nginx-deployment" deleted service "nginx-service" deleted pod "kubia" deleted
3. 服务类型
通过 Service 的 spec.type
字段可以指定服务类型:
ClusterIP
:默认的服务类型。只在集群内部暴露服务。NodePort
:在每个节点的指定端口上暴露服务,可以通过<NodeIP>:<NodePort>
的形式在集群外访问该服务。LoadBalancer
:通过云服务提供商提供的负载均衡器来暴露服务。ExternalName
:请求该服务即请求externalName
字段指定的外部服务。
例子:
-
NodePort
apiVersion: v1 kind: Service metadata: name: my-service spec: type: NodePort selector: app: MyApp ports: - port: 80 targetPort: 80 nodePort: 30007
可用端口范围:30000-32767。
-
ExternalName
apiVersion: v1 kind: Service metadata: name: my-service namespace: prod spec: type: ExternalName externalName: my.database.example.com