(五) Kubernetes基础之Service

292 阅读3分钟

Service

可以简单理解为逻辑上的一组Pod。一种可以访问Pod的策略,而且其他Pod可以通过这个Service访问到这个Service代理的Pod。相对于Pod而言,它会有一个固定的名称,一旦创建就固定不变。

创建一个Service

 apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  ports:
  - name: http
    port: 80  #Service自己的端口
    targetPort: 80  #后端应用的端口 
    protocol: TCP  #UDP TCP SCTP  default:TCP
  - name: https
    port: 443  #Service自己的端口
    targetPort: 443  #后端应用的端口 
    protocol: TCP  #UDP TCP SCTP  default:TCP
  selector:
    app: nginx    
  sessionAffinity: None
  type: ClusterIP
» kubectl create -f service.yaml

» kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP          28h
my-web-0     NodePort    10.105.106.72    <none>        80:32445/TCP     24m
nginx        ClusterIP   None             <none>        80/TCP           3h
nginx-svc    ClusterIP   10.100.224.240   <none>        80/TCP,443/TCP   160m

使用Service代理k8s外部应用

例如:
希望在生产环境中使用某个固定的名称而非IP地址进行访问外部的中间件服务(mysql、rabbitmq等。 可以在测试环境、开发环境、生产环境配置同一个名称,代理的ip指向不同环境的地址).
某个项目正在迁移至K8s集群,但是一部分服务仍然在集群外部,此时可以使用service代理至k8s集群外部的服务。

# vi svc-nginx-external.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-svc-external
  name: nginx-svc-external
spec:
  ports:
  - name: http
    port: 80  #Service自己的端口
    targetPort: 80  #后端应用的端口 
    protocol: TCP  #UDP TCP SCTP  default:TCP
  sessionAffinity: None
  type: ClusterIP
» kubectl create -f svc-nginx-external.yaml
service/nginx-svc-external created

» kubectl get svc
NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes           ClusterIP   10.96.0.1        <none>        443/TCP          28h
my-web-0             NodePort    10.105.106.72    <none>        80:32445/TCP     35m
nginx                ClusterIP   None             <none>        80/TCP           3h11m
nginx-svc            ClusterIP   10.100.224.240   <none>        80/TCP,443/TCP   171m
nginx-svc-external   ClusterIP   10.97.68.85      <none>        80/TCP           9s

-- 并没有创建同名的ENDPOINTS
» kubectl get ep
NAME         ENDPOINTS                                              AGE
kubernetes   192.168.65.4:6443                                      28h
my-web-0     10.1.0.60:80                                           36m
nginx        10.1.0.60:80,10.1.0.61:80                              3h13m
nginx-svc    10.1.0.60:443,10.1.0.61:443,10.1.0.60:80 + 1 more...   173m

--复制一个
» kubectl get ep nginx-svc -oyaml > nginx-ep-external.yaml
--修改
» vi nginx-ep-external.yaml
» cat nginx-ep-external.yaml
apiVersion: v1
kind: Endpoints
metadata:
  labels:
    app: nginx-svc-external
  name: nginx-svc-external
  namespace: default
subsets:
- addresses:
  - ip: 220.181.38.148 #外部服务ip地址 ,这里是百度
  ports:
  - name: http
    port: 80 # 外部服务端口号
    protocol: TCP
    
» kubectl create -f nginx-ep-external.yaml
-- 以后需要变更地址,只需要kubectl edit ep nginx-svc-external 就行了

使用Service代理k8s外部域名

➜ cp svc-nginx-external.yaml svc-nginx-externalname.yaml
➜ vi svc-nginx-externalname.yaml

➜ cat svc-nginx-externalname.yaml
apiVersion: v1
kind: Service
metadata:
 labels:
   app: nginx-externalname
 name: nginx-externalname
spec:
 type: ExternalName
 externalName: www.baidu.com

➜ kubectl apply -f svc-nginx-externalname.yaml
service/nginx-externalname created

➜ kubectl get svc
NAME                 TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)          AGE
kubernetes           ClusterIP      10.96.0.1        <none>          443/TCP          40h
my-web-0             NodePort       10.105.106.72    <none>          80:32445/TCP     12h
nginx                ClusterIP      None             <none>          80/TCP           15h
nginx-externalname   ExternalName   <none>           www.baidu.com   <none>           66s
nginx-svc            ClusterIP      10.100.224.240   <none>          80/TCP,443/TCP   14h
nginx-svc-external   ClusterIP      10.97.68.85      <none>          80/TCP           12h

➜ kubectl get po
NAME    READY   STATUS    RESTARTS      AGE
web-0   1/1     Running   1 (13m ago)   15h
web-1   1/1     Running   1 (13m ago)   15h

➜ kubectl exec -it web-0 bash
root@web-0:/# apt-get update && apt-get install wget

-- 跨域导致 403了,但是请求通了,110.242.68.4也是百度的ip
root@web-0:/# wget nginx-externalname
--2022-07-04 02:30:19--  http://nginx-externalname/
Resolving nginx-externalname (nginx-externalname)... 110.242.68.4, 110.242.68.3
Connecting to nginx-externalname (nginx-externalname)|110.242.68.4|:80... connected.
HTTP request sent, awaiting response... 403 Forbidden
2022-07-04 02:30:19 ERROR 403: Forbidden.

-- 直接请求ip地址
root@web-0:/# wget 110.242.68.4
--2022-07-04 02:33:46--  http://110.242.68.4/
Connecting to 110.242.68.4:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2381 (2.3K) [text/html]
Saving to: 'index.html'

index.html                              100%[===============================================================================>]   2.33K  --.-KB/s    in 0s

2022-07-04 02:33:46 (14.7 MB/s) - 'index.html' saved [2381/2381]

root@web-0:/# cat index.html
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>

Service常用类型

spec.type

  • ClusterIP:在集群内部使用的,默认类型
  • ExternalName:反代到指定的域名上。
  • LoadBalancer:使用云服务商提供的IP地址。成本太高。
  • NodePort:在每个宿主机上暴露一个随机端口,30000-32767,--service-node-port-range,集群外部可访问。