ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

K8S--SVC网络

2021-11-21 19:02:28  阅读:266  来源: 互联网

标签:ingress service -- SVC svc nginx pod K8S 80


Service网络

Why:pod重启或者重建ip会发生改变,pod之间访问会有问题;
What:解耦了服务和应用。(集群内部服务之间调用填写service域名/IP即可;
How:声明一个service对象

一般常用的有两种:
k8s集群内部的service:selector指定pod,自动创建Endpoints
k8s集群外的service:手动创建Endpoints,指定外部服务的ip、端口和协议。

k8s 三种网络

node network
pod network
cluster network,也称作virtual IP虚拟网络—service

kube-proxy监听k8s-apiserver,一旦service资源发生变化,kube-proxy就会生成对应的负载调度的调整,这样就保证service的最新状态。

service 三种工作模式

userspace
iptabels
ipvs 最新版本

service类型

ExternalName

Cluster IP

Node Port

Load Balancer

资源记录

SVC_NAME.NS_NAME.DOMAIN.LTD.
DOMAIN.LTD 集群域名后缀默认为svc.cluster.local.

 

 

 

 

 

使用清单文件创建service资源

apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: default
spec:
  selector:
    app: nginx
    role: logstor
  clusterIP: 10.97.97.97    //默认为clusterIP,不指定会自动分配
  type: ClusterIP
  ports:
  - port: 80             //service端口
    targetPort: 80   //容器端口
master yaml]# kubectl   get svc -o wide      //查看创建的SVC
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE   SELECTOR
kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP   28d   <none>
nginx        ClusterIP   10.97.97.97   <none>        80/TCP    13m   app=nginx,role=logstor

模拟匹配pod作为后端资源

master yaml]# kubectl  apply -f test.yaml
master yaml]# kubectl  label pods nginx app=nginx
master yaml]# kubectl  describe svc nginx
Name:              nginx
Namespace:         default
Labels:            <none>
Annotations:       kubectl.kubernetes.io/last-applied-configuration:
                     {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"nginx","namespace":"default"},"spec":{"clusterIP":"10.97.97.97","...
Selector:          app=nginx,role=logstor
Type:              ClusterIP
IP:                10.97.97.97
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         <none>         //可以看到当svc标签与pod标签只匹配一个时,service未关联到pod资源
Session Affinity:  None
Events:            <none>

master yaml]# kubectl  label pods nginx role=logstor   //手动匹配所有标签

master yaml]# kubectl   get svc -o wide
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE   SELECTOR
kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP   28d   <none>
nginx        ClusterIP   10.97.97.97   <none>        80/TCP    13m   app=nginx,role=logstor

master yaml]# kubectl  get pods   --show-labels    
NAME                           READY   STATUS    RESTARTS   AGE     LABELS
nginx                          1/1     Running   0          10m     app=nginx,role=logstor      //此时标签已全匹配

master yaml]# kubectl  describe svc nginx       //再次查看发现已匹配后端资源
Name:              nginx
Namespace:         default
Labels:            <none>
Annotations:       kubectl.kubernetes.io/last-applied-configuration:
                     {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"nginx","namespace":"default"},"spec":{"clusterIP":"10.97.97.97","...
Selector:          app=nginx,role=logstor    //svc标签
Type:              ClusterIP
IP:                10.97.97.97
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.84:80     //标签一致,匹配到的后端pod资源
Session Affinity:  None
Events:            <none>

结论:servie根据SELECTOR标签选择器关联pod资源

查看svc关联的pod

]# kubectl   get svc -A
NAMESPACE              NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE
default                kubernetes                  ClusterIP   10.96.0.1       <none>        443/TCP                  236d
kube-system            kube-dns                    ClusterIP   10.96.0.10      <none>        53/UDP,53/TCP,9153/TCP   236d
kube-system            metrics-server              ClusterIP   10.105.89.199   <none>        443/TCP                  15d
kubernetes-dashboard   dashboard-metrics-scraper   ClusterIP   10.109.95.129   <none>        8000/TCP                 15d
kubernetes-dashboard   kubernetes-dashboard        NodePort    10.98.147.122   <none>        443:30002/TCP            15d
linux40                ng-deploy-80                NodePort    10.97.239.161   <none>        81:30019/TCP             20d

]# kubectl   get pods -n linux40   -o wide
NAME                                READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
nginx-deployment-55fb8c9d77-9qlkp   1/1     Running   9          20d   10.244.1.98   node1   <none>           <none>
nginx-deployment-55fb8c9d77-sj8bs   1/1     Running   3          15d   10.244.2.29   node2   <none>           <none>

# 查看endpoint,svc关联的pod资源
]# kubectl   get  ep  -n  linux40
NAME           ENDPOINTS                       AGE
ng-deploy-80   10.244.1.98:80,10.244.2.29:80   20d

 

资源记录

SVC_NAME.NS_NAME.DOMAIN.LTD.
集群默认后缀DOMAIN.LTD.:svc.cluster.local.

所以上面创建的服务记录为:nginx.default.svc.cluster.local

 

使用资源清单创建类型为nodeport的svc

apiVersion: v1
kind: Service
metadata:
  name: myapp
  namespace: default
spec:
  selector:
    app: myapp
    release: canary
  clusterIP: 10.99.99.99
  type: NodePort
  ports:
  - port: 80       //service端口
    targetPort: 80    //pod端口
    nodePort: 30080   //映射节点端口,后续可以直接访问该节点端口,DNAT到service端口,再到pod端口

master yaml]# kubectl   get svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP        28d
myapp        NodePort    10.99.99.99   <none>        80:30080/TCP   38m                 //网络类型为节点网络
nginx        ClusterIP   10.97.97.97   <none>        80/TCP         76m

访问servic

]# curl http://172.18.0.68:30080    //在集群外部机器访问该集群内IP加端口,servie后端须关联pod资源才可以被访问

注:此时可以在节点前面做代理服务器来访问service地址

 

Load Balancer(负载均衡器) 访问示意图

 

 

 

ExternalName(外部名称 )模式

 

 

 

把来自于同一个客户端的请求始终固定访问同一个pod资源

master yaml]# kubectl patch svc myapp -p ‘{“spec”:{“sessionAffinity”:“ClientIP”}}’
master yaml]# kubectl  describe svc myapp    //查看service详情
Name:                     myapp
Namespace:                default
Labels:                   <none>
Annotations:              kubectl.kubernetes.io/last-applied-configuration:
                            {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"myapp","namespace":"default"},"spec":{"clusterIP":"10.99.99.99","...
Selector:                 app=myapp,release=canary
Type:                     NodePort
IP:                       10.99.99.99
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30080/TCP
Endpoints:                10.244.2.84:80   //后端pod资源
Session Affinity:         ClientIP           //此参数说明相同客户端访问相同pod资源;若为“none”则为负载均衡调度。
External Traffic Policy:  Cluster
Events:                   <none>

无头service:将service名称解析到后端pod ip地址来实现访问

apiVersion: v1
kind: Service
metadata:
  name: myapp-svc
  namespace: default
spec:
  selector:
    app: myapp
    release: canary
  clusterIP: "None"    //指定service IP地址为空
  ports:
  - port: 80
    targetPort: 80
master yaml]# 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   29d

master yaml]# dig  -t A myapp-svc.default.svc.cluster.local. @10.96.0.10
 ......
;; ANSWER SECTION:
myapp-svc.default.svc.cluster.local. 30 IN A    10.244.1.97      //可以看到解析SVC资源记录地址为pod地址,当关联到时
myapp-svc.default.svc.cluster.local. 30 IN A    10.244.2.101
myapp-svc.default.svc.cluster.local. 30 IN A    10.244.2.100
myapp-svc.default.svc.cluster.local. 30 IN A    10.244.1.96
myapp-svc.default.svc.cluster.local. 30 IN A    10.244.2.104 
......

master yaml]# kubectl get pods -o wide --show-labels //查看pod标签,与无头service 标签完全匹配
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
myapp-deploy-f476f4fcf-jltjs 1/1 Running 3 6d1h 10.244.1.85 k8s-node1 <none> <none> app=myapp,pod-template-hash=f476f4fcf,releas=canary
myapp-deploy-f476f4fcf-nbqwv 1/1 Running 3 6d1h 10.244.2.86 k8s-node2 <none> <none> app=myapp,pod-template-hash=f476f4fcf,releas=canary
nginx                        1/1 Running 1 7h26m 10.244.2.85 k8s-node2 <none> <none> app=myapp,release=canary

master yaml]# kubectl get svc -o wide //查看service标签,与pod 标签完全匹配时,可解析service name到pod地址
NAME           TYPE       CLUSTER-IP      EXTERNAL-IP    PORT(S)       AGE   SELECTOR
kubernetes    ClusterIP   10.96.0.1       <none>         443/TCP       29d   <none>
myapp         NodePort    10.99.99.99     <none>         80:30080/TCP  7h49m app=myapp,release=canary
myapp-svc     ClusterIP   None            <none>         80/TCP        3m23s app=myapp,release=canary //SVC地址为空
nginx         ClusterIP   10.97.97.97     <none>         80/TCP        8h    app=nginx,role=logstor

 

2.如何让集群内资源访问到互联网资源

待定

 

k8s ingress以及ingress Cintroller

参考文档:

https://segmentfault.com/a/1190000019908991

service的作用体现在两个方面,对集群内部,它不断跟踪pod的变化,更新endpoint中对应pod的对象,提供了ip不断变化的pod的服务发现机制,对集群外部,他类似负载均衡器,可以在集群内外部对pod进行访问。但是,单独用service暴露服务的方式,在实际生产环境中不太合适:
ClusterIP的方式只能在集群内部访问。
NodePort方式的话,测试环境使用还行,当有几十上百的服务在集群中运行时,NodePort的端口管理是灾难。
LoadBalance方式受限于云平台,且通常在云平台部署ELB还需要额外的费用。

所幸k8s还提供了一种集群维度暴露服务的方式,也就是ingress。ingress可以简单理解为service的service,他通过独立的ingress对象来制定请求转发的规则,把请求路由到一个或多个service中。这样就把服务与请求规则解耦了,可以从业务维度统一考虑业务的暴露,而不用为每个service单独考虑。
举个例子,现在集群有api、文件存储、前端3个service,可以通过一个ingress对象来实现图中的请求转发:

 

 

ingress的部署
ingress的部署,需要考虑两个方面:

ingress-controller是作为pod来运行的,以什么方式部署比较好
ingress解决了把如何请求路由到集群内部,那它自己怎么暴露给外部比较好
下面列举一些目前常见的部署和暴露方式,具体使用哪种方式还是得根据实际需求来考虑决定。

Deployment+LoadBalancer模式的Service
如果要把ingress部署在公有云,那用这种方式比较合适。用Deployment部署ingress-controller,创建一个type为LoadBalancer的service关联这组pod。大部分公有云,都会为LoadBalancer的service自动创建一个负载均衡器,通常还绑定了公网地址。只要把域名解析指向该地址,就实现了集群服务的对外暴露。

Deployment+NodePort模式的Service
同样用deployment模式部署ingress-controller,并创建对应的服务,但是type为NodePort。这样,ingress就会暴露在集群节点ip的特定端口上。由于nodeport暴露的端口是随机端口,一般会在前面再搭建一套负载均衡器来转发请求。该方式一般用于宿主机是相对固定的环境ip地址不变的场景。
NodePort方式暴露ingress虽然简单方便,但是NodePort多了一层NAT,在请求量级很大时可能对性能会有一定影响。

DaemonSet+HostNetwork+nodeSelector
用DaemonSet结合nodeselector来部署ingress-controller到特定的node上,然后使用HostNetwork直接把该pod与宿主机node的网络打通,直接使用宿主机的80/433端口就能访问服务。这时,ingress-controller所在的node机器就很类似传统架构的边缘节点,比如机房入口的nginx服务器。该方式整个请求链路最简单,性能相对NodePort模式更好。缺点是由于直接利用宿主机节点的网络和端口,一个node只能部署一个ingress-controller pod。比较适合大并发的生产环境使用。

ingress与ingress-controller
要理解ingress,需要区分两个概念,ingress和ingress-controller:

ingress对象:
指的是k8s中的一个api对象,一般用yaml配置。作用是定义请求如何转发到service的规则,可以理解为配置模板。
ingress-controller:
具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发。
简单来说,ingress-controller才是负责具体转发的组件,通过各种方式将它暴露在集群入口,外部对集群的请求流量会先到ingress-controller,而ingress对象是用来告诉ingress-controller该如何转发请求,比如哪些域名哪些path要转发到哪些服务等等。

ingress Cintroller

重要:可以使用DaemonSet结合nodeselector来部署ingress-controller到特定的node(打上污点)上,然后使用HostNetwork直接把该pod与宿主机node的网络打通,直接使用宿主机的80/433端口就能访问服务。

一组独立运行的一组pod资源,可以理解为应用程序,可以实现七层调度负载均衡。
若集群中存在N多个Node节点,可以通过DaemonSet 控制器运行一个为集群接入七层调度的负载均衡pod,用于转发至后端pod。
此pod监听nNodeIP+port,可以在前面搭建四层代理转发至这几台node节点,在通过这几个pod实现七层负载均衡至后端pod。

如何对后端pod进行分组
还必须要借助service 的标签选择器来将后端代理的pod来分组,仅仅用来对后端pod资源功能分组,upstream 里面写入service地址,ingress Cintroller pod还是直接访问后端pod地址。

ingress 与 ingress Cintroller 并不是一回事
ingress资源

ingress 定义了期望 ingress Cintroller 如何建立一个前端,可能是一个虚机,也有可能是url映射。

如何实现对后端pod进行实时监控

同时定义了upstream service,可以通过service 来得到有几个主机并识别出后端pod的ip地址,并反馈注入到配置文件中。
可以保存为配置文件,一旦ingress发现serrvice 关联的pod资源发生改变(重建、修改等),会及时反应到ingress中并及时注入到 ingress Cintroller pod的配置文件中,pod中的主容器进程重新加载配置文件(因为upstream中配置的 service并不会实现负载均衡功能,仅仅用来实现分组分类,实际上还是ingress Cintroller pod还是直接访问后端pod地址)。

 

 

创建名称空间

apiVersion: v1
kind: Namespace
metadata:
     name: ingress-nginx

 **定义一个ingress**

 

 

步骤

定义service 模式为Deployment+NodePort模式的Service
同样用deployment模式部署ingress-controller,并创建对应的服务,但是type为NodePort。这样,ingress就会暴露在集群节点ip的特定端口上。由于nodeport暴露的端口是随机端口,一般会在前面再搭建一套负载均衡器来转发请求。该方式一般用于宿主机是相对固定的环境ip地址不变的场景。
NodePort方式暴露ingress虽然简单方便,但是NodePort多了一层NAT,在请求量级很大时可能对性能会有一定影响。

 

 

定义 ingress。host定义了访问域名,这个域名必须可以解析

 

DaemonSet+HostNetwork+nodeSelector

用DaemonSet结合nodeselector来部署ingress-controller到特定的node上,然后使用HostNetwork直接把该pod与宿主机node的网络打通,直接使用宿主机的80/433端口就能访问服务。这时,ingress-controller所在的node机器就很类似传统架构的边缘节点,比如机房入口的nginx服务器。该方式整个请求链路最简单,性能相对NodePort模式更好。缺点是由于直接利用宿主机节点的网络和端口,一个node只能部署一个ingress-controller pod。比较适合大并发的生产环境使用。

 

 

自制证书

 

 

标签:ingress,service,--,SVC,svc,nginx,pod,K8S,80
来源: https://www.cnblogs.com/rtnb/p/15585424.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有