K8s Service

Service 的分类

Service 类型共有四种 ExternalName, ClusterIP(默认,仅用于集群内部), NodePort(对外), LoadBalancer(基于云平台的Service)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@k8s001 ~]# kubectl explain svc.spec.type
KIND: Service
VERSION: v1

FIELD: type <string>

DESCRIPTION:
type determines how the Service is exposed. Defaults to ClusterIP. Valid
options are ExternalName, ClusterIP, NodePort, and LoadBalancer.
"ExternalName" maps to the specified externalName. "ClusterIP" allocates a
cluster-internal IP address for load-balancing to endpoints. Endpoints are
determined by the selector or if that is not specified, by manual
construction of an Endpoints object. If clusterIP is "None", no virtual IP
is allocated and the endpoints are published as a set of endpoints rather
than a stable IP. "NodePort" builds on ClusterIP and allocates a port on
every node which routes to the clusterIP. "LoadBalancer" builds on NodePort
and creates an external load-balancer (if supported in the current cloud)
which routes to the clusterIP. More info:
https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types

ClusterIP

资源文件

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: default
spec:
selector:
app: redis
type: ClusterIP
ports:
- port: 6379
targetPort: 6379

当 type 为 ClusterIP 时,我们还可以指定 ClusterIP,不过这样要确保指定的 ip 不会冲突。

1
2
[root@k8s001 ~]# kubectl apply -f redis-svc.yaml 
service/redis created
1
2
3
4
[root@k8s001 ~]# kubectl get svc 
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 47h
redis ClusterIP 10.111.72.202 <none> 6379/TCP 8s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@k8s001 ~]# kubectl describe svc redis
Name: redis
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"redis","namespace":"default"},"spec":{"ports":[{"port":6379,"targ...
Selector: app=redis
Type: ClusterIP
IP: 10.111.72.202
Port: <unset> 6379/TCP
TargetPort: 6379/TCP
Endpoints: <none>
Session Affinity: None
Events: <none>

Endpoints 代表后端地址,因为我们有对应的 Pod,所以为 none。

NodePort

资源文件

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
selector:
app: myapp
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30080

这里的 port 是 svc 的端口,targetPort 是 Pod 的端口,nodePort 是对外的,节点的端口。当 type 为 NodePort 时候,可以指定 nodePort,比如这里的 30080,不过不建议指定,因为容易冲突。

1
2
[root@k8s001 ~]# kubectl apply -f myapp-svc.yaml 
service/myapp created
1
2
3
4
[root@k8s001 ~]# kubectl get svc 
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d
myapp NodePort 10.98.100.188 <none> 80:30080/TCP 20s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@k8s001 ~]# kubectl describe svc myapp
Name: myapp
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"myapp","namespace":"default"},"spec":{"ports":[{"nodePort":30080,...
Selector: app=myapp
Type: NodePort
IP: 10.98.100.188
Port: <unset> 80/TCP
TargetPort: 80/TCP
NodePort: <unset> 30080/TCP
Endpoints: 10.244.1.16:80,10.244.1.17:80,10.244.2.11:80 + 2 more...
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>

我们将之前的标签为 app=myapp 的 Pod 关联上了刚刚创建的 svc,所以这里的 Endpoints 不为空。我们在本机上测试访问一下。通过测试,从本机访问三台机器都可以访问到服务。