Loading

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.

posted @ 2022-11-09 01:31  平凡键客  阅读(47)  评论(0编辑  收藏  举报