Kubernetes Service 筆記

Service

K8S Service可以簡單理解爲邏輯上的一組Pod。一種可以訪問Pod的策略,其他Pod可以通過這個Service訪問到這個Service代理的Pod。
相對於Pod而言,它會有一個固定的名稱,一旦創建就固定不變。可以簡單的理解成訪問一個或者一組Pod的時候,先去訪問Service,然後再去訪問的IP,Service的名稱的固定的,不管Pod是否更新或者重啓,都不影響用戶的使用

爲什麼需要Service

啓動 nginx

[root@master01 ~]# 
[root@master01 ~]# kubectl get po -owide 
NAME                                READY   STATUS    RESTARTS   AGE     IP               NODE       NOMINATED NODE   READINESS GATES
busybox                             1/1     Running   4          5d23h   172.18.71.31     master03   <none>           <none>
nginx-deployment-5787596d54-6ffh4   1/1     Running   1          24h     172.18.71.30     master03   <none>           <none>
nginx-deployment-5787596d54-7m47n   1/1     Running   1          24h     172.31.112.157   master01   <none>           <none>
nginx-deployment-5787596d54-cnjb8   1/1     Running   1          24h     172.21.231.156   node02     <none>           <none>

可以通過Pod IP 訪問

[root@master01 ~]# curl 172.31.112.157
<!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 一旦更新Ip就會發生變化

[root@master01 deployment]# kubectl get po -owide 
NAME                                READY   STATUS    RESTARTS   AGE     IP               NODE       NOMINATED NODE   READINESS GATES
busybox                             1/1     Running   4          5d23h   172.18.71.31     master03   <none>           <none>
nginx-deployment-559d658b74-4td67   1/1     Running   0          12s     172.31.112.159   master01   <none>           <none>
nginx-deployment-559d658b74-nkb72   1/1     Running   0          16s     172.31.112.158   master01   <none>           <none>
nginx-deployment-559d658b74-stql7   1/1     Running   0          14s     172.20.59.219    master02   <none>           <none>

[root@master01 deployment]# kubectl edit deployment nginx-deployment
deployment.apps/nginx-deployment edited

[root@master01 deployment]# kubectl get po -owide 
NAME                                READY   STATUS    RESTARTS   AGE   IP               NODE       NOMINATED NODE   READINESS GATES
busybox                             1/1     Running   4          6d    172.18.71.31     master03   <none>           <none>
nginx-deployment-5787596d54-7564h   1/1     Running   0          13m   172.31.112.160   master01   <none>           <none>
nginx-deployment-5787596d54-76txc   1/1     Running   0          13m   172.21.231.158   node02     <none>           <none>
nginx-deployment-5787596d54-j77s9   1/1     Running   0          13m   172.18.71.32     master03   <none>           <none>

通過 Service 可以這一層抽象,當Pod IP發生變化時,客戶端是無感的。

Service 是如何找到Pod

Service 創建的時候,k8s 會創建一個同名的 endpoint, endpoint 記錄的就是 Pod 的ip

kube-dns Service

[root@master01 deployment]# kubectl get svc  -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   14d
metrics-server   ClusterIP   10.109.10.62   <none>        443/TCP                  14d
[root@master01 deployment]# kubectl get ep -n kube-system 
NAME             ENDPOINTS                                           AGE
kube-dns         172.29.55.27:53,172.29.55.27:53,172.29.55.27:9153   14d
metrics-server   172.21.231.157:4443                                 14d
[root@master01 deployment]# kubectl get po -n kube-system -owide 
NAME                                       READY   STATUS    RESTARTS   AGE   IP               NODE       NOMINATED NODE   READINESS GATES
calico-kube-controllers-5f6d4b864b-k45q5   1/1     Running   10         14d   192.168.44.13    node01     <none>           <none>
calico-node-58hbg                          1/1     Running   10         14d   192.168.44.12    master03   <none>           <none>
calico-node-dlj65                          1/1     Running   10         14d   192.168.44.11    master02   <none>           <none>
calico-node-jqb6h                          1/1     Running   10         14d   192.168.44.14    node02     <none>           <none>
calico-node-r8fl5                          1/1     Running   11         14d   192.168.44.10    master01   <none>           <none>
calico-node-wv4vx                          1/1     Running   10         14d   192.168.44.13    node01     <none>           <none>
coredns-867d46bfc6-ljdjr                   1/1     Running   10         14d   172.29.55.27     node01     <none>           <none>
metrics-server-595f65d8d5-6k4wq            1/1     Running   18         14d   172.21.231.157   node02     <none>           <none>

包含 selector 的 Service

  1. nginx-svc.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app.kubernetes.io/name: proxy
spec:
  containers:
  - name: nginx
    image: nginx:stable
    ports:
      - containerPort: 80
        name: http-web-svc

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app.kubernetes.io/name: proxy
  ports:
  - name: name-of-service-port
    protocol: TCP
    port: 80
    targetPort: http-web-svc
  1. 創建 Service 和 Pod
[root@master01 service]# kubectl create -f nginx-svc.yaml 
pod/nginx created
service/nginx-service created

[root@master01 service]# kubectl get svc
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes      ClusterIP   10.96.0.1      <none>        443/TCP   14d
nginx-service   ClusterIP   10.98.35.249   <none>        80/TCP    21s
[root@master01 service]# kubectl get po -owide 
NAME      READY   STATUS    RESTARTS   AGE   IP               NODE       NOMINATED NODE   READINESS GATES
busybox   1/1     Running   4          6d    172.18.71.31     master03   <none>           <none>
nginx     1/1     Running   0          33s   172.31.112.161   master01   <none>           <none>

  1. 測試訪問 pod
    通過 pod IP
[root@master01 service]# curl 172.31.112.161
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
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 Ip

[root@master01 service]# curl 10.98.35.249
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
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@master01 service]# kubectl exec -it busybox -- sh
/ # wget http://nginx-service
Connecting to nginx-service (10.98.35.249:80)
index.html           100% |************************************************************************************************************|   615   0:00:00 ETA
/ # ls
bin         dev         etc         home        index.html  proc        root        sys         tmp         usr         var
/ # cat index.html 
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
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>

# 跨名稱空間訪問
/ # wget http://nginx-service.default
Connecting to nginx-service.default (10.98.35.249:80)
index.html           100% |************************************************************************************************************|   615   0:00:00 ETA
  1. 查看 endpoint
[root@master01 service]# kubectl get endpoints
NAME            ENDPOINTS                                                  AGE
kubernetes      192.168.44.10:6443,192.168.44.11:6443,192.168.44.12:6443   14d
nginx-service   172.31.112.161:80

不包含 Selector 的 Service

  • 希望在生產環境中使用某個固定的名稱而非IP地址進行訪問外部的中間件服務
  • 希望Service指向另一個Namespace中或其他集羣中的服務
  • 某個項目正在遷移至k8s集羣,一部分服務仍然在集羣外部,此時可以使用service代理至k8s集羣外部的服務

使用Service代理k8s外部應用

  1. 創建一個類型爲external的service,這個svc不會自動創建一個ep
[root@master01 service]# vim nginx-svc-external.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-svc-external
  name: nginx-svc-external
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
  sessionAffinity: None
  type: ClusterIP

[root@master01 service]# kubectl create -f nginx-svc-external.yaml 
service/nginx-svc-external created

  1. 查看svc
[root@master01 service]# kubectl get svc 
NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes           ClusterIP   10.96.0.1       <none>        443/TCP   14d
nginx-service        ClusterIP   10.110.20.106   <none>        80/TCP    8s
nginx-svc-external   ClusterIP   10.106.237.1    <none>        80/TCP    112s
  1. 查看 ep
[root@master01 service]# kubectl get ep 
NAME            ENDPOINTS                                                  AGE
kubernetes      192.168.44.10:6443,192.168.44.11:6443,192.168.44.12:6443   14d
nginx-service   172.31.112.162:80                                          37s

  1. 手動創建 ep, 名稱跟上面創建的svc關聯起來
[root@master01 service]# vim nginx-ep-external.yaml
apiVersion: v1
kind: Endpoints
metadata:
  labels:
    app: nginx-svc-external   #名字要跟svc的一致
  name: nginx-svc-external
  namespace: default
subsets:
- addresses:
  - ip: 14.215.177.39 # baidu
  ports:
  - name: http
    port: 80
    protocol: TCP

[root@master01 service]# kubectl create -f nginx-ep-external.yaml 
endpoints/nginx-svc-external created
  1. 查看ep
[root@master01 service]# kubectl get ep
NAME                 ENDPOINTS                                                  AGE
kubernetes           192.168.44.10:6443,192.168.44.11:6443,192.168.44.12:6443   14d
nginx-service        172.31.112.162:80                                          8m14s
nginx-svc-external   14.215.177.39:80                                           23s

  1. 訪問ep
# pod ip 
[root@k8s-master01 ~]# curl 220.181.38.148:80 -I
HTTP/1.1 200 OK
Date: Sat, 26 Dec 2020 16:00:57 GMT
Server: Apache
Last-Modified: Tue, 12 Jan 2010 13:48:00 GMT
ETag: "51-47cf7e6ee8400"
Accept-Ranges: bytes
Content-Length: 81
Cache-Control: max-age=86400
Expires: Sun, 27 Dec 2020 16:00:57 GMT
Connection: Keep-Alive
Content-Type: text/html

# service ip
[root@master01 service]# curl 10.106.237.1 -I
HTTP/1.1 302 Found
Connection: keep-alive
Content-Length: 17931
Content-Type: text/html
Date: Tue, 08 Nov 2022 17:09:49 GMT
Etag: "54d9748e-460b"
Server: bfe/1.0.8.18

Service 類型

  • ClusterIP 集羣內部使用
  • ExternalName 通過返回定義的 CNAME 別名
  • NodePort 在所有安裝 kube-proxy 的節點上打開一個端口,此端口可以代理至後端 Pod,集羣外部可以使用節點IP以及 NodePort端口號訪問集羣Pod服務。
  • LoadBalance 使用雲提供商的負載均衡器提供服務
[root@master01 service]# kubectl get svc -n kubernetes-dashboard -owide
NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE   SELECTOR
dashboard-metrics-scraper   ClusterIP   10.96.223.156   <none>        8000/TCP        14d   k8s-app=dashboard-metrics-scraper
kubernetes-dashboard        NodePort    10.107.33.199   <none>        443:30929/TCP   14d   k8s-app=kubernetes-dashboard


[root@master01 service]# kubectl get node -owide
NAME       STATUS   ROLES    AGE   VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION                CONTAINER-RUNTIME
master01   Ready    matser   14d   v1.20.0   192.168.44.10   <none>        CentOS Linux 7 (Core)   4.19.12-1.el7.elrepo.x86_64   docker://19.3.15
master02   Ready    <none>   14d   v1.20.0   192.168.44.11   <none>        CentOS Linux 7 (Core)   4.19.12-1.el7.elrepo.x86_64   docker://19.3.15
master03   Ready    <none>   14d   v1.20.0   192.168.44.12   <none>        CentOS Linux 7 (Core)   4.19.12-1.el7.elrepo.x86_64   docker://19.3.15
node01     Ready    <none>   14d   v1.20.0   192.168.44.13   <none>        CentOS Linux 7 (Core)   4.19.12-1.el7.elrepo.x86_64   docker://19.3.15
node02     Ready    <none>   14d   v1.20.0   192.168.44.14   <none>        CentOS Linux 7 (Core)   4.19.12-1.el7.elrepo.x86_64   docker://19.3.15

[root@master01 service]# curl https://192.168.44.14:30929
curl: (60) Issuer certificate is invalid.
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.

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