Kubernetes中Service的使用

簡介

Service是Kubernetes的核心概念,經過建立Service,能夠爲一組具備相同功能的容器應用提供一個統一的入口地址,而且將請求負載分發到後端的各個容器應用上。html

Service從邏輯上表明瞭一組Pod,具體是哪組Pod則是由label來挑選的前端

在Kubernetes中Service的Cluster IP實現數據報文請求的轉發,都離不開node上部署的重要組件 kube-proxynode

kube-proxy做用nginx

  • 實時監聽kube-api,獲取創建service的創建,升級信息,增長或刪除pod信息。來獲取Pod和VIP的映射關係
  • 維護本地Netfileter iptables IPVS內核組件
  • 經過修改和更新ipvs規則來實現數據報文的轉發規則
  • 構建路由信息,經過轉發規則轉發報文到對應的pod上

1. Service資源定義

apiVersion: v1
kind: Service
metadata:
 name: nginx-svc
 labels:
   app: nginx
spec:
 type: ClusterIP
 ports:
   - port: 80
      targetPort: 80
 selector:
   app: nginx

1.1 Service Type

根據建立Service的type不一樣 能夠分爲如下幾種類型web

  • ClusterIP
    默認方式,根據是否生成ClusterIP又能夠分爲普通Service和Headless Service兩類docker

    此方式僅用於集羣內部之間實現通訊的後端

  • NodePortapi

    NodePort模式除了使用cluster ip外,也將service的port映射到每一個node的一個指定內部port上,映射的每一個node的內部port都同樣。能夠經過訪問Node節點的IP實現外部通訊瀏覽器

  • LoadBalancer
    要配合支持公有云負載均衡使用好比GCE、AWS。其實也是NodePort,只不過會把 : 自動添加到公有云的負載均衡當中 網絡

  • ExternalName

    外部IP;若是集羣外部須要有一個服務須要咱們進行訪問;那麼就須要在service中指定外部的IP讓service與外部的那個服務進行訪問;那麼接下的集羣內部到外部那個數據包走向即是:數據包先到service而後由service交給外部那個服務;回來的數據包是:交給node node交給service service交給Pod

下面說下生產經常使用的類型定義以及使用

ClusterIP

定義一個web應用

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deploy
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myappnginx
      release: stable
  template:
    metadata:
      labels:
        app: myappnginx
        release: stable
    spec:
      containers:
      - name: nginxweb
        image: nginx:1.14-alpine
        imagePullPolicy: IfNotPresent

建立service資源基於ClusterIP類型

apiVersion: v1
kind: Service
metadata:
  name: webservice          #service名字;也就是後面驗證基於主機名訪問的名字
  namespace: default        #名稱空間要與剛纔建立的Pod的名稱空間一致,service資源也是基於namespace隔離的
spec:
  selector:                         #標籤選擇器很重要決定是要關聯某個符合標籤的Pod
    app: myappnginx         #標籤要與剛纔定義Pod的標籤一致;由於service是經過標籤與Pod關聯的
    release: stable      
  type: ClusterIP               #類型是ClusterIP
  ports:                          #暴露的端口設置
  - port: 88                     #service暴露的端口
    targetPort: 80             #容器自己暴露的端口,和dockerfile中的expose意思同樣

查看service狀態

[root@master replicaset]# kubectl get svc -o wide
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE    SELECTOR
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   3d9h   <none>
webservice   ClusterIP   10.102.99.133   <none>        88/TCP    13s    app=myappnginx,release=stable

[root@master replicaset]# kubectl describe svc webservice
Name:              webservice
Namespace:         default
Labels:            <none>
Annotations:       kubectl.kubernetes.io/last-applied-configuration:
                     {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"webservice","namespace":"default"},"spec":{"ports":[{"port":88,"t...
Selector:          app=myappnginx,release=stable
Type:              ClusterIP
IP:                10.102.99.133        
Port:              <unset>  88/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.27:80,10.244.2.27:80
Session Affinity:  None
Events:            <none>

鏈接一個客戶端Pod進行測試

[root@master replicaset]# kubectl exec -it web-deploy-75bfb496f9-fm29g -- /bin/sh
/ # wget -O - webservice:88   #基於coredns進行解析的
Connecting to webservice:88 (10.102.99.133:88)
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
無頭service

無頭IP只能使用CluserIP類型就是沒有clusterip 而是將解析的IP 解析到後端的Pod之上

該服務不會分配Cluster IP,也不經過kube-proxy作反向代理和負載均衡。而是經過DNS提供穩定的網絡ID來訪問,DNS會將headless service的後端直接解析爲podIP列表。主要供StatefulSet使用

[root@master replicaset]# cat svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: webservice
  namespace: default
spec:
  selector:
    app: myappnginx
    release: stable
  clusterIP: None           定義cluserIP爲空
  ports:
  - port: 88
    targetPort: 80


[root@master replicaset]# kubectl get svc -o wide
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE     SELECTOR
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   3d10h   <none>
webservice   ClusterIP   None         <none>        88/TCP    7s      app=myappnginx,release=stable
[root@master replicaset]# kubectl exec -it web-deploy-75bfb496f9-fm29g -- /bin/sh
/ # cat /etc/resolv.conf 
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
/ # nslookup webservice
nslookup: can't resolve '(null)': Name does not resolve

Name:      webservice
Address 1: 10.244.2.27 10-244-2-27.webservice.default.svc.cluster.local
Address 2: 10.244.1.27 web-deploy-75bfb496f9-fm29g
/ #
NodePort
[root@k8s-master01 daem]# cat deploy.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: default
  name: nginxapp
  labels:
    app: nginx-deploy
spec:
  replicas: 2
  selector:
    matchLabels:
      app: mynginx
  template:
    metadata:
      labels:
        app: mynginx
    spec:
      containers:
      - name: nginxweb1
        image: nginx:1.15-alpine
您在 /var/spool/mail/root 中有新郵件
[root@k8s-master01 daem]# cat svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
  labels:
    app: nginx-svc
spec:
  ports:
  - name: http
    port: 80                #service暴露的端口,能夠基於內部集羣訪問
    protocol: TCP
    nodePort: 30001   #node節點的映射端口 能夠經過外部訪問
    targetPort: 80
  selector:
    app: mynginx
  sessionAffinity: None
  type: NodePort

能夠基於內部集羣訪問

[root@k8s-master01 daem]# kubectl get svc 
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        8d
nginx-svc    NodePort    10.99.184.91   <none>        80:30001/TCP   5s
您在 /var/spool/mail/root 中有新郵件
[root@k8s-master01 daem]# curl 10.99.184.91 
<!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@k8s-master01 daem]#

外部瀏覽器訪問

sessionAffinity實現源地址session綁定
apiVersion: v1
kind: Service
metadata:
  name: webservice
  namespace: default
spec:
  selector:
    app: myappnginx
    release: stable
  sessionAffinity: ClientIP     未來自贊成客戶端的請求調度到後端的同一個Pod上
  type: NodePort
  ports:
  - port: 88
    nodePort: 30001
    targetPort: 80

直接經過Pod的IP地址和端口號能夠訪問到容器應用內的服務,可是Pod的IP地址是不可靠的,例如當Pod所在的Node發生故障時,Pod將被Kubernetes從新調度到另外一個Node,Pod的IP地址將發生變化。更重要的是,若是容器應用自己是分佈式的部署方式,經過多個實例共同提供服務,就須要在這些實例的前端設置一個負載均衡器來實現請求的分發。Kubernetes中的Service就是用於解決這些問題的核心組件。

相關文章
相關標籤/搜索