K8s資源第三篇(Service)

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都將會付費,開銷比較大。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章