K8S--SVC网络

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.

K8S--SVC网络

 K8S--SVC网络

 

 K8S--SVC网络

 

 

使用清单文件创建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(负载均衡器) 访问示意图

K8S--SVC网络

 K8S--SVC网络

 

 

ExternalName(外部名称 )模式

K8S--SVC网络

 K8S--SVC网络

 

 

把来自于同一个客户端的请求始终固定访问同一个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对象来实现图中的请求转发:
K8S--SVC网络

 

 

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地址)。

K8S--SVC网络

 

 

创建名称空间

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

 **定义一个ingress**

K8S--SVC网络

 

 

步骤

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

K8S--SVC网络

 

 

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

K8S--SVC网络

 

DaemonSet+HostNetwork+nodeSelector

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

 

 

自制证书

K8S--SVC网络

 

 K8S--SVC网络

上一篇:sklearn中SVC和SVR的参数说明


下一篇:SVM深入理解