Service:

 Service是定义在集群中一组运行Pod集合的抽象资源,它提供了所有相同的功能,当一个Service资源被创建后,将会分配一个唯一的IP,也叫做集群IP,这个IP地址将存在于Service的整个生命资源中,Service一旦被创建,整个IP无法进行修改。

Pod可以通过Service进行通信,并且所有的通信将会通过Service自动负载均衡到所有的Pod中的容器。

  • Service是真实应用服务的抽象。
  • Service通常用来将浮动的资源与后端真实提供服务的容器进行关联。
  • Service对外表现为一个单一的访问接口,外部不需要了解后端的规模与机制。
Server工作模式:
  • userspace:1.1版本以及之前的版本所使用。
  • iptables:被1.10版本以及之前的版本所使用。
  • ipvs:被1.11版本以及以上的版本所使用。
Service类型:
  • ClusterIP:默认方式,根据是否生成ClusterIP又可分为Service和Headless Service。
    • Service:通过Kubernetes的Service分配一个集群内部可访问的固定虚拟。
    • Headless Service:该服务不会分配Cluster IP,也不会通过kube-proxy做反向代理和负载均衡。而是通过DNS提供稳定的网络ID来访问,DNS会将Headless Service的后端直接解析为PodIP列表,主要提供StatefulSet使用。
  • NodePort:除了使用Cluster IP之外,还通过将Service的port映射到集群内每个节点的相同一个端口,实现通过NodeIP:NodePort从集群外访问。
  • LoadBalancer:和NodePort类似,不过除了使用一个Cluster IP和NodePort之外还会向所使用的公有云申请一个负载均衡器(负载均衡器后端映射到各节点的NodePort),实现集群外通过LB访问服务。
  • ExternalName:是Service的特例,此模式主要面向在集群外部的服务,通过它可以将外部服务映射到k8s集群,且具备k8s内服务的一些特征(如namesapce等属性),来为集群内部提供服务。此模式要求k8s-dns的版本为1.7或以上,这种模式和前三种模式(除了Headless Service)最大的不同是重定向依赖的是DNS层次,而不是通过kube-proxy。
ClusterIP:

 创建Service时k8s默认为ClusterIP,创建好Service,会生成一个ClusterIP,集群内可以访问这个ClusterIP,集群外部无法访问它。

#创建一个service
[root@k8smaster data]# vim redis.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
      role: logstor
  template:
    metadata:
      labels:
        app: redis
        role: logstor
    spec:
      containers:
      - name: redis
        image: redis:4.0-alpine
        ports:
          - name: redis
            containerPort: 6379

---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: filebeat-ds
  namespace: default
spec:
  selector:
    matchLabels:
      app: filebeat
      release: stable
  template:
    metadata:
      labels:
        app: filebeat
        release: stable
    spec:
      containers:
      - name: filebeat
        image: ikubernetes/filebeat:5.6.5-alpine
        env:
        - name: REDIS_HOST
          value: redis.default.svc.cluster.local
        - name: REDIS_LOG_LEVEL
          value: info
[root@k8smaster data]# kubectl apply -f redis.yaml 
deployment.apps/redis created
daemonset.apps/filebeat-ds unchanged
[root@k8smaster data]# vim redis-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: default
spec:
  selector:
    app: redis
    role: logstor
  clusterIP: 10.97.97.97
  type: ClusterIP
  ports:
  - port: 6379
    targetPort: 6379
[root@k8smaster data]# kubectl get svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP    44d
redis        ClusterIP   10.97.97.97   <none>        6379/TCP   17m
[root@k8smaster data]# kubectl apply -f redis-svc.yaml 
service/redis created
[root@k8smaster data]# 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":{"clusterIP":"10.97.97.97","...
Selector:          app=redis,role=logstor
Type:              ClusterIP
IP:                10.97.97.97
Port:              <unset>  6379/TCP
TargetPort:        6379/TCP
Endpoints:         10.244.2.147:6379
Session Affinity:  None
Events:            <none>

#使用命令创建
[root@k8smaster kubernetes]# kubectl create deployment  nginx-deployment --image=nginx
deployment.apps/nginx-deployment created
[root@k8smaster kubernetes]# kubectl get pods -o wide
NAME                                READY   STATUS    RESTARTS   AGE     IP            NODE       NOMINATED NODE   READINESS GATES
nginx-deployment-6f77f65499-dbhvp   1/1     Running   0          2m33s   10.244.1.95   k8snode1   <none>           <none>
[root@k8smaster kubernetes]# kubectl create service clusterip nginx-deployment --tcp=80:80
service/nginx-deployment created
[root@k8smaster kubernetes]# kubectl get services
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP   2d20h
nginx-deployment   ClusterIP   10.103.139.34   <none>        80/TCP    12s
[root@k8smaster kubernetes]# kubectl describe service/nginx-deployment
Name:              nginx-deployment
Namespace:         default
Labels:            app=nginx-deployment
Annotations:       <none>
Selector:          app=nginx-deployment
Type:              ClusterIP
IP:                10.103.139.34
Port:              80-80  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.95:80   #Endpoints为关联的Pod的IP
Session Affinity:  None
Events:            <none>
[root@k8smaster kubernetes]# curl 10.103.139.34
<!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>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
如果删除Pod:
[root@k8smaster kubernetes]# kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-6f77f65499-dbhvp   1/1     Running   0          5m38s
[root@k8smaster kubernetes]# kubectl delete  pods nginx-deployment-6f77f65499-dbhvp
pod "nginx-deployment-6f77f65499-dbhvp" deleted
[root@k8smaster kubernetes]# kubectl get pods -o wide
NAME                                READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
nginx-deployment-6f77f65499-f8xtb   1/1     Running   0          26s   10.244.2.87   k8snode2   <none>           <none>
[root@k8smaster kubernetes]# kubectl describe service/nginx-deployment
Name:              nginx-deployment
Namespace:         default
Labels:            app=nginx-deployment
Annotations:       <none>
Selector:          app=nginx-deployment
Type:              ClusterIP
IP:                10.103.139.34
Port:              80-80  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.2.87:80   #删掉原来的Pod,Endpoints关联到了新的Pod。
Session Affinity:  None
Events:            <none>
[root@k8smaster kubernetes]# curl 10.103.139.34
<!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>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
访问Service:
[root@k8smaster kubernetes]# curl nginx-deployment
curl: (6) Could not resolve host: nginx-deployment; Unknown error
[root@k8smaster kubernetes]# kubectl get service -n kube-system
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   2d21h
[root@k8smaster kubernetes]# kubectl get service -n kube-system
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   2d21h
[root@k8smaster kubernetes]# vim /etc/resolv.conf 
# Generated by NetworkManager
nameserver 10.96.0.10
# nameserver 2408:84e1:a3:98c4::f7
[root@k8smaster kubernetes]# curl nginx-deployment.default.svc.cluster.local
<!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>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
如果删除Service:
[root@k8smaster kubernetes]# kubectl get service
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP   2d21h
nginx-deployment   ClusterIP   10.103.139.34   <none>        80/TCP    15m
[root@k8smaster kubernetes]# kubectl delete service/nginx-deployment
service "nginx-deployment" deleted
[root@k8smaster kubernetes]# kubectl create service clusterip nginx-deployment --tcp=80:80
service/nginx-deployment created
[root@k8smaster kubernetes]# kubectl describe service/nginx-deployment
Name:              nginx-deployment
Namespace:         default
Labels:            app=nginx-deployment
Annotations:       <none>
Selector:          app=nginx-deployment
Type:              ClusterIP
IP:                10.101.21.249
Port:              80-80  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.2.87:80  #只要关联到Pods的名字,就能实现访问,不管IP变没变。
Session Affinity:  None
Events:            <none>
[root@k8smaster kubernetes]# curl 10.101.21.249
[root@k8smaster kubernetes]# curl 10.101.21.249
<!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>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
实时伸缩:
[root@k8smaster ~]# kubectl delete deployment nginx-deployment
deployment.extensions "nginx-deployment" deleted
[root@k8smaster kubernetes]# kubectl create deployment myapp-deployment --image=ikubernetes/myapp:v1
deployment.apps/myapp-deployment created
[root@k8smaster kubernetes]# kubectl create service clusterip myapp-deployment --tcp=80:80
service/myapp-deployment created
[root@k8smaster kubernetes]# kubectl scale --replicas=3 deployment myapp-deployment
deployment.extensions/myapp-deployment scaled
[root@k8smaster ~]# kubectl get pods -o wide
NAME                                READY   STATUS    RESTARTS   AGE   IP             NODE       NOMINATED NODE   READINESS GATES
myapp-deployment-558f94fb55-plk4v   1/1     Running   0          85m   10.244.2.93    k8snode2   <none>           <none>
myapp-deployment-558f94fb55-rd8f5   1/1     Running   0          99m   10.244.2.91    k8snode2   <none>           <none>
myapp-deployment-558f94fb55-zzmpg   1/1     Running   0          85m   10.244.1.101   k8snode1   <none>           <none>
[root@k8smaster ~]# kubectl describe service/myapp-deployment
Name:              myapp-deployment
Namespace:         default
Labels:            app=myapp-deployment
Annotations:       <none>
Selector:          app=myapp-deployment
Type:              ClusterIP
IP:                10.110.41.201
Port:              80-80  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.101:80,10.244.2.91:80,10.244.2.93:80   #发现关联了3个。
Session Affinity:  None
Events:            <none>
[root@k8smaster ~]# curl 10.110.41.201/hostname.html
myapp-deployment-558f94fb55-zzmpg
[root@k8smaster ~]# curl 10.110.41.201/hostname.html
myapp-deployment-558f94fb55-rd8f5
[root@k8smaster ~]# curl 10.110.41.201/hostname.html
myapp-deployment-558f94fb55-zzmpg
#发现Service自动实现了Pod的负载均衡。(调度方式是随机调度)
NodePort:

 NodePort时引导外部流量到集群内服务最原始的方式,NodePort,正如这个名字所示,在所有节点上开发一个特定的端口,任何发送到该端口的流量都被转发到对应服务。

  • 端口范围为30000~32767。
  • 节点的IP可能会发生变化。

 不建议在生成环境上用这种方式暴露服务,如果运行的服务不要求一直可用,或者对成本笔记敏感,你可以使用这种方法。

[root@k8smaster ~]# kubectl delete service/myapp-deployment
service "myapp-deployment" deleted
[root@k8smaster ~]# kubectl create service nodeport myapp-deployment --tcp=80:80
service/myapp-deployment created
[root@k8smaster ~]# kubectl get services
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP        2d23h
myapp-deployment   NodePort    10.107.69.16    <none>        80:30930/TCP   79s  #30930为宿主机端口,我们来访问以下。
myweb-deployment   ClusterIP   10.99.246.129   <none>        80/TCP         162m
nginx-deployment   ClusterIP   10.101.21.249   <none>        80/TCP         169m
LoadBalancer:

 这种方式也会在节点上开放一个端口,所有通过该端口的流量都会被转发到对应的服务上,它没有过滤规则,没有路由。这意味着你可以发送任何协议的流量,如HTTP,TCP,UDP,Websocket,gRPC或其他任意协议,这种方式会通过给你一个公网ip的方式来将服务暴露在公网上,但是每个使用LoadBalancer的服务都用于一个公网IP,每个公网IP都将会付费,开销比较大。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐