Service

将一组Pods公开为网络服务的抽象方法。也可以理解为Pod的服务发现与负载均衡。

服务发现与负载均衡:Service会检测pod的状态,流量只会较为平均得分发到正常的pod中。

alt

创建Service

暴露Deploy。端口8000。

  • 命令行方式
[root@k8s-master ~]# kubectl expose deployment my-app --port=8000 --target-port=80
service/my-app exposed
[root@k8s-master ~]# kubectl get service
  • yaml方式,service.yml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: my-app
  name: my-app
spec:
  selector:
    app: my-app
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 80
[root@k8s-master ~]# kubectl apply -f service.yml 
service/my-app created
[root@k8s-master ~]# 

查看Service

[root@k8s-master ~]# kubectl get service -n default
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP    23h
my-app       ClusterIP   10.96.2.98   <none>        8000/TCP   6s
[root@k8s-master ~]#

可以看到我们上面创建的Service的ip为10.96.2.98

[root@k8s-worker2 ~]# curl 10.96.2.98:8000
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
...
</html>
[root@k8s-worker2 ~]#

注意:我们这里可以使用ip:8000的形式在集群内的任意节点访问。我们也可以在pod内使用域名:端口的形式访问。域名的形式:service名称.命名空间.svc:端口。例如:my-app.default.svc:8000

扩展

查看pod标签

[root@k8s-master ~]# kubectl get pod [podname] --show-labels
NAME                      READY   STATUS    RESTARTS   AGE   LABELS
my-app-5ff664f457-l7792   1/1     Running   1          20h   app=my-app,pod-template-hash=5ff664f457
my-app-5ff664f457-r69z5   1/1     Running   1          20h   app=my-app,pod-template-hash=5ff664f457
my-app-5ff664f457-w2d6q   1/1     Running   1          20h   app=my-app,pod-template-hash=5ff664f457
my-app-5ff664f457-xsz9l   1/1     Running   1          20h   app=my-app,pod-template-hash=5ff664f457
[root@k8s-master ~]# 

使用标签检索Pod

[root@k8s-master ~]# kubectl get pod -l app=my-app
NAME                      READY   STATUS    RESTARTS   AGE
my-app-5ff664f457-l7792   1/1     Running   1          20h
my-app-5ff664f457-r69z5   1/1     Running   1          20h
my-app-5ff664f457-w2d6q   1/1     Running   1          20h
my-app-5ff664f457-xsz9l   1/1     Running   1          20h
[root@k8s-master ~]# 

删除Service

[root@k8s-master ~]# kubectl delete service my-app
service "my-app" deleted
[root@k8s-master ~]# 

ClusterIP

alt

我们上面方式创建Service默认使用的是ClusterIP,称为集群ip,只能在集群内部使用。等同于:

kubectl expose deployment my-app --port=8000 --target-port=80 --type=ClusterIP
apiVersion: v1
kind: Service
metadata:
  labels:
    app: my-app
  name: my-app
spec:
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 80
  selector:
    app: my-app
  type: ClusterIP

NodePort

alt

这种方式创建的Service在集群外也可以访问。因为他会在每个pod上映射一个新的端口。

  • 命令行方式
[root@k8s-master ~]# kubectl expose deploy my-app --port=8000 --target-port=80 --type=NodePort
service/my-app exposed
[root@k8s-master ~]#
  • yaml方式。service.yml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: my-app
  name: my-app
spec:
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 80
  selector:
    app: my-app
  type: NodePort
kubectl apply -f service.yml
[root@k8s-master ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP          25h
my-app       NodePort    10.96.198.191   <none>        8000:32047/TCP   39s
[root@k8s-master ~]# 

对比发现在PORT(S)中多了一个映射端口32047,这个端口在每个节点上都有,可以通过节点ip:30247的方式在集群外进行访问。

alt

NodePort除了可以在集群外访问以外,其余和ClusterIP一致。

小结

  • NodePort范围在 30000-32767 之间随机生成。
  • ClusterIP只能在集群内使用。
  • NodePort可以通过 节点ip:新端口的方式在集群外访问。
  • 无论是ClusterIP还是NodePort,都会生成 CLUSTER-IP,可在集群内使用。
  • 使用 ip:端口要在集群节点上使用,而 域名:端口要在pod内使用。
  • 域名的写法:服务名.所在名称空间.svc

本文由 mdnice 多平台发布

Logo

开源、云原生的融合云平台

更多推荐