一、定义
由于Pod是不可靠的,会被创建或者销毁,而且每次重新创建都会使用不同的IP,因此直接访问Pod是不可靠的。而Service就是在Pod之上,对Pod做了一层抽象,从而对上层服务屏蔽了下面具体的Pod。这样即使下面的Pod发生了改变,上层的服务看到的依然是同一个Service。
Service的模板如下:
yaml
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
其中:
selector
:定义了选择哪些Podprotocol
:支持TCP,UDP和SCTPport
:Srevice暴露出来的端口,其它服务通过这个端口来访问该ServicetargetPort
:Pod的端口,默认和port
一致
其中targetPort
不仅可以是一个数字,还可以是一个字符串,用来指向Pod的端口的名字,这样即使Pod改变了端口,Service也依然不用改变。例如:
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:latest
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 8000
targetPort: ngxin-port
如果一个Service需要暴露多个端口的话,需要对每个端口指定名字。端口名字只能是小写字母、数字以及连字符,且不能以连字符开始或者结束。例如:
yaml
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
- name: https
protocol: TCP
port: 443
targetPort: 9377
二、Service Type
通常来说,我们不仅需要可以在集群内访问Service,也经常会需要将Service暴露到集群外。Service的type
字段可以定义Service的类型,从而可以控制Service的访问。Service Type有以下几种:
ClusterIP
:默认的类型,Service只能在集群内被访问NodePort
:对外提供服务,可以通过<NodeIP>:<NodePort>
来访问ServiceLoadBalancer
:通过云服务提供商的负载均衡暴露ServiceExternalName
:结合externalName
字段来使用,externalName
的值可以为例如foo.bar.example.com
这样的格式
下面是使用NodePort
的一个例子:
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:latest
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
selector:
app: nginx
ports:
- protocol: TCP
port: 8000
targetPort: 80
然后通过kubectl get service
可以看到:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service NodePort 10.101.53.78 <none> 8000:31483/TCP 2m
然后访问localhost:31483
即可,也就是说,Service的8000端口被映射到了节点的31483端口。映射到节点的端口是被随机分配的,且在--service-node-port-range
选项所指定的范围内(默认为30000-32767),也可以通过添加nodePort
字段来指定某一个端口,例如:
yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
selector:
app: nginx
ports:
- protocol: TCP
port: 8000
nodePort: 31234
targetPort: 80
这样就可以访问localhost:31234
了。