首页 > 其他分享 >kubernetes网络模式

kubernetes网络模式

时间:2023-07-14 17:57:11浏览次数:20  
标签:kubernetes service ip Service 网络 模式 NodePort Pod pod

 

一个K8s的集群中至少有三个网络:

  • 集群节点所在的网络,这个网络就是你的主机所在的网络,通常情况下是你的网络基础设施提供。如果你的node处于不同的网段,那么你需要保证路由可达。如上图中的 192.168.10.0/24和10.0.0.0/8这两个网络

  • 第二个网络是Pod的网络, K8s中一个Pod由多个容器组成,但是一个pod只有一个IP地址,Pod找那个所有的容器共享同一个IP。这个IP启动pod时从一个IP池中分配的, 叫做 pod CIDR, 或者叫network_cidr(如图,默认配置是10.1.0.0/16)。可以在配置文件中配置。

  • 第三个网络是K8S服务网络, service_cluster_ip_range(如图,默认的配置是的10.0.0.1/24)

K8S中Container是如何互联互通的

1.Pod内部通信:

  同一pod中的任何容器都将共享相同的名称空间和本地网络,容器可以容易地与其他容器在相同的容器中进行通信,k8s中每个pod中管理着一组容器,这些容器共享同一网络空间,他们之间可以通过localhost相互访问,(可见pod内部的通信是不经过数据ip数据通信网络的)。

2.同节点的pod之间通信:

  不同pod之间的通信,就是使用Linux虚拟以太网设备或者说是由两个虚拟接口组成的以太网接口对使不同的网络命名空间连接起来,这些虚拟接口分布在多个pod上,通过网桥把不同的pod组成为一个以太网,直接进行二层以太网通信。

3.不同节点的pod之间通信:

  当跨pod通信时,本节点内无法找到目的pod的MAC地址,则会查找三层路由表转发,这需要依靠不同节点的网络配置来实现,对于如何来配置网络,k8s在网络这块自身并没有实现网络规划的具体逻辑,而是制定了一套CNI接口规范,开放给社区来实现,目前主流的网络配置方案有:Flannl、weave、calico等。

4.外部网络与pod之间通信:

  pod之间通过他们自己的ip地址进行通信,但是pod的ip地址是不持久的,当集群中pod的规模缩减或者pod故障或者node故障重启后,新的pod的ip就可能与之前的不一样的。每个service有一个虚拟ip,要访问service管理的pod上的服务只需要访问你这个虚拟ip就可以了,这个虚拟ip是固定的,当service下的pod规模改变、故障重启、node重启时候,对使用service的用户来说是无感知的,因为他们使用的service的ip没有变。当数据包到达service虚拟ip后,数据包会被通过k8s给service自动创建的负载均衡器路由到背后的pod容器。

Service有很多种类型,默认是ClusterIP

  ClusterIP:一个Pod如果想和自己通信,只需要用localhost即可。如果想用别的Pod的服务,就要知道别的Pod对应的Serice的DNS名称,解析到期ClusterIP。ClusterIP会被每个Node上的Kube-Proxy修改iptables和ipvs等路由信息,这样保证发往ClusterIP的IP包,实际上被发往在这个Node上的Pod的IP地址和端口。

apiVersion: v1
 kind: Service
 metadata:
  name: service-clusterip
 spec:
  ports:
  - port: 3000
    protocol: TCP
    targetPort: 443
   # clusterIP: 10.233.3.127   ##可配可不配,不配的话系统会分配一个随机的IP并保持不变
  selector:
    app: pod-clusterip
  type: ClusterIP        ##type可以不配,不配的话默认就是ClusterIP类型

NodePort:NodePort是在ClusterIP之上建造的Service。

如果想让外网访问Pod的业务,最简单的办法就是通过Node的公网地址,生成一个NodePort类型的Service. 本质就是把ClusterIP Service暴露到集群中所有Node的高端端口(default 30000-32767)。所有的Node都会监这个端口,即使这个Node中没有这个service的Pod,如果设置了.spec.externalTrafficPolicy属性是local,则只有运行Pod的Node会监听,这样就避免了多跳一次。

 
 apiVersion: v1
 kind: Service
 metadata:
  name: service-nodeport
 spec:
  ports:
  - port: 3000
    protocol: TCP
    targetPort: 443
    nodePort: 30080    ##可配可不配,不配的话系统会分配一个随机的端口并保持不变
  selector:
    app: pod-nodeport
  type: NodePort

 

如果有一个4层负载均衡,并且要从外网方位K8S中的服务,就需要是指负载均衡,把业务数据分发到所有的有Pod的Node上对应的NodePord的端口,并且能够通过健康检查,来动态获得哪些工作Node上有对应的Pod。

 

 

LoadBalancer:是在NodePort之上建造的服务,他能够自动设置私有云或者公有云提供的负载均衡,把NodePort暴露给外网,并且动态监听那些pod在那些工作Node上。

 apiVersion: v1
 kind: Service
 metadata:
  name: service-loadbalancer
 spec:
  ports:
  - port: 3000
    protocol: TCP
    targetPort: 443
    nodePort: 30080
  selector:
    run: pod-loadbalancer
  type: LoadBalancer

 

ExternalName:  Service的ExternalName方式实现,即设置Service的type为ExternalName。这样做的好处就是内部服务访问外部服务的时候通过别名来访问的,屏蔽了外部服务的真实信息,外部服务对内部服务透明,外部服务的修改基本上不会影响到内部服务的访问,做到了内部服务和外部服务解耦合。

 kind: Service
 apiVersion: v1
 metadata:
  name: service-externalname
 spec:
  ports:
  - port: 3000
    protocol: TCP
    targetPort: 443
  type: ExternalName
  externalName: remote.server.url.com

K8S服务发现

    k8s中,Pod如果想要与另一个pod通信,通常不会直接记住pod的ip(因为动态的),也不会记住pod形成的Service的ip(相对比较稳定,但也是动态的),因为IP不好记,通常情况是通过其对应的service名字来访问的。那么就需要一个服务,能够把service的名字翻译为ip,此服务就是kube-dns。

目前k8s的kube-dns通常使用CoreDNS

  • kubernetes的Service Name被解析成其ClusterIp(是服务网络中的ip,是内部的,不是Node的外部地址)

  • 每个K8s网络在安装的时候指定一个Cluster Domain,默认是: cluster.local
  • k8s中每个namespace对应一个子域

 

K8S中的Ingress:用于实现用域名的方式访问k8s内部应用。

  k8s通过Ingress,把K8s集群中的服务,通过http和https路由暴露给外部用户。路径等信息通过Ingress的资源文件配置。

有了service为什么需要Ingress资源

Kubernetes 具有强大的副本控制能力,能保证在任意副本(Pod)挂掉时自动从其他机器启动一个新的,还可以动态扩容等,总之一句话,这个 Pod 可能在任何时刻出现在任何节点上,也可能在任何时刻死在任何节点上;那么自然随着 Pod 的创建和销毁,Pod IP 肯定会动态变化;那么如何把这个动态的 Pod IP 暴露出去?这里借助于 Kubernetes 的 Service 机制,Service 可以以标签的形式选定一组带有指定标签的 Pod,并监控和自动负载他们的 Pod IP,那么我们向外暴露只暴露 Service IP 就行了;这就是 NodePort 模式:即在每个节点上开起一个端口,然后转发到内部 Pod IP 上。

 

采用 NodePort 方式暴露服务面临一个问题,服务一旦多起来,NodePort 在每个节点上开启的端口会及其庞大,而且难以维护

 

Ingress 工作原理

  • ingress-controller通过和kubernetes APIServer交互,动态的去感知集群中ingress规则变化;

  • 然后读取它,按照自定义的规则,规则就是写明了那个域名对应那个Service,生成一段配置;
  • 在写到nginx-ingress-controller的pod里,这个ingress-controller的pod里运行着一个Nginx服务,控制器会把生成的Nginx配置写入/etc/nginx.conf中‘;
  • 然后reload一下是配置生效。以此达到域名区分配置和动态更新的作用。  

ingress 暴露服务的方式

●Deployment+LoadBalancer 模式的 Service

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

●DaemonSet+HostNetwork+nodeSelector

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

●Deployment+NodePort模式的Service

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

 

 

标签:kubernetes,service,ip,Service,网络,模式,NodePort,Pod,pod
From: https://www.cnblogs.com/yypc/p/17554447.html

相关文章

  • ubuntu网络防火墙设置
    sudoufwstatus 查看防火墙状态sudoufwenable 开启防火墙sudoufwdisable 关闭防火墙sudoufwdefaultdeny  禁止所有外部访问sudoufwallow80  允许访问80sudoufwdeleteallow80  禁止访问80sudoufwallowfrom192.168.1.1  ......
  • 网络字节序和主机字节序之间的转换
    使用标准库函数:htons():将16位整数从主机字节序转换为网络字节序。htonl():将32位整数从主机字节序转换为网络字节序。ntohs():将16位整数从网络字节序转换为主机字节序。ntohl():将32位整数从网络字节序转换为主机字节序。例子:#include<iostream>#include<arpa/inet.h>//L......
  • msmpeng.exe 是 Windows Defender 的后台服务进程,也称为 Windows Defender Antimalwar
    msmpeng.exe是MicrosoftWindowsDefender的主要组件之一。WindowsDefender是Windows操作系统内置的杀毒软件和安全防护工具,用于检测和清除计算机上的潜在恶意软件、病毒和其他安全威胁。具体来说,msmpeng.exe是WindowsDefender的后台服务进程,也称为WindowsDefender......
  • KingbaseES V8R6集群运维案例之---single-pro模式备份
    案例说明:KingbaseESV8R6集群物理备份配置参数_target_db_style,可选single或cluster或single-pro。single对应单机模式的目标数据库实例,cluster对应集群模式的目标数据库实例,single-pro对应集群模式的每个DB节点独立备份。本案例详细描述集群架构在singl-pro模式下的备份。适用......
  • Ubuntu部署Kubernetes
    Docker安装信任Docker的GPG公钥:curl-fsSLhttps://repo.huaweicloud.com/docker-ce/linux/ubuntu/gpg|sudoapt-keyadd-`添加软件仓库:sudoadd-apt-repository"deb[arch=amd64]https://repo.huaweicloud.com/docker-ce/linux/ubuntu$(lsb_release-cs)stable"......
  • mongodb4.4.22主从(副本集附仲裁节点)部署带认证模式
    环境:OS:CentOS7DB:4.4.22机器角色:192.168.1.102:29001主192.168.1.104:29001从192.168.1.105:29001仲裁节点 1.下载相应的版本https://www.mongodb.com/download-center/community我这里下载的是mongodb-linux-x86_64-rhel70-4.4.22.tgz 2.创建安装目录192.168.1.102......
  • JAVA设计模式之责任链模式
    设计模式设计模式(DesignPattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。总体来说设计模式分为三大类:创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、......
  • Q:如何实现notepad++列编辑模式
    列编辑:txt编辑器大家都非常熟悉,当需要修改多行的时候只能一行一行的修改。而notepad可以同时修改多行的数据。1、鼠标移动光标到要选择的列 2、按住 alt 键,从上到下选择多列,光标会变成列模式 3、输入要插入或者修改的数据。同理按delete也可以实现按列删除 ......
  • 关于 flannel、calico、cililum 工作模式的说明
    https://docs.projectcalico.org/networking/determine-best-networkinghttps://kubernetes.io/docs/concepts/cluster-administration/networking/#the-kubernetes-network-modelflannel、calico、cililumEncapsulation#封装是指在附加层中加入网络数据包以提供其他上下文......
  • java设计模式实现结论
    Java设计模式实现结论场景描述在软件开发过程中,我们经常会遇到一些常见的问题和需求。为了提高代码的复用性、可维护性和可扩展性,使用设计模式是一个非常好的选择。设计模式是一种被反复验证的、经过优化的解决方案,可以解决特定问题的代码设计问题。流程概述为了实现设计模式,我......