我是kubernetes的新手,并且刚刚在AWS上使用kube-up获得了kubernetes v.1.3.5群集。到目前为止,我一直在玩kubernetes来理解它的机制(节点,pods,svc和东西)。基于我最初(或可能粗略)的理解,我几乎没有问题:
1)如何在此处路由到群集IP(即在kube-aws中)?我看到服务的IP在10.0.0.0/16范围内。我使用rc = 3的股票nginx进行了部署,然后通过暴露节点端口将服务附加到它。一切都很棒!我可以从我的开发机器连接到该服务。此nginx服务的群集IP为10.0.33.71:1321。现在,如果我ssh到其中一个minions(或节点或VMS)并执行" telnet 10.0.33.71 1321",它会按预期连接。但我无法理解这是如何工作的,我无法在kubernetes的VPC设置中找到与10.0.0.0/16相关的任何路由。在这里引起了什么确实会导致像telnet这样的app成功连接?但是,如果我进入主节点并执行" telnet 10.0.33.71 1321",它就不会连接。为什么无法从master连接?
2)每个节点内都有一个cbr0接口。每个minion节点的cbr0配置为10.244.x.0 / 24,master的cbr0配置为10.246.0.0/24。 我可以从任何节点(包括master)ping到任何10.244.x.x pod。但是我无法从任何一个minion节点ping 10.246.0.1(主节点内的cbr0)。这可能发生什么?
这里是由kubernetes在aws中建立的路线。 VPC。
Destination Target
172.20.0.0/16 local
0.0.0.0/0 igw-<hex value>
10.244.0.0/24 eni-<hex value> / i-<hex value>
10.244.1.0/24 eni-<hex value> / i-<hex value>
10.244.2.0/24 eni-<hex value> / i-<hex value>
10.244.3.0/24 eni-<hex value> / i-<hex value>
10.244.4.0/24 eni-<hex value> / i-<hex value>
10.246.0.0/24 eni-<hex value> / i-<hex value>
答案 0 :(得分:10)
Mark Betz (SRE at Olark)在三篇文章中介绍了Kubernetes网络:
对于pod,您正在查看:
你找到:
veth0
,1
,2
:虚拟网络接口,每个容器一个。pause
&#34;中启动了一个特殊容器,用于检测发送到pod的SIGTERM,并将其转发到容器。最后一个因素是事情开始变得更加复杂:
Kubernetes为每个节点上的网桥分配一个总地址空间,然后根据构建网桥的节点分配该空间内的网桥地址。
其次,它将路由规则添加到10.100.0.1的网关,告诉它应该如何路由发往每个网桥的数据包,即可以通过哪个节点eth0
到达网桥。虚拟网络接口,网桥和路由规则的这种组合通常称为 overlay network 。
当pod与另一个pod联系时,它会通过 service 为什么呢?
群集中的Pod网络是很好的东西,但是它本身不足以启用持久系统的创建。那是因为Kubernetes中的 pod是短暂的 您可以使用pod IP地址作为端点,但无法保证下次重新创建pod时地址不会更改,这可能由于多种原因而发生。
这意味着:您需要一个反向代理/动态负载均衡器。而且它更有弹性。
服务是一种kubernetes资源,可以将代理配置为将请求转发到一组pod 。
将接收流量的一组pod由选择器确定,该选择器匹配在创建pod时分配给pod的标签
该服务使用自己的网络。默认情况下,其类型为&#34; ClusterIP &#34 ;;它有自己的IP。
以下是两个pod之间的通信路径:
它使用 kube-proxy 此代理使用 netfilter 。
netfilter是一个基于规则的数据包处理引擎 它在内核空间中运行,并查看其生命周期中各个点的每个数据包 它根据规则匹配数据包,当它找到匹配它的规则时,将采取指定的操作 它可以采取的许多行动包括将数据包重定向到另一个目的地。
在此模式下,kube-proxy:
- 在本地主机接口上打开一个端口(上例中为10400),以侦听对测试服务的请求,
- 插入netfilter规则,将目的地为服务IP的数据包重新路由到自己的端口,
- 将这些请求转发到端口8080上的窗格。
这就是
10.3.241.152:80
的请求神奇地成为对10.0.2.2:8080
的请求的方式 鉴于netfilter的功能,所有这些都需要使所有服务都能用于 kube-proxy来打开端口并为该服务插入正确的netfilter规则,这是为了响应来自集群中更改的主api服务器。
可是:
这个故事还有一点点扭曲 我在上面提到过用户空间代理由于封送数据包而很昂贵。 在kubernetes 1.2中, kube-proxy获得了在iptables模式下运行的能力。
在这种模式下,kube-proxy通常不再是集群间连接的代理,而是委托netfilter检测绑定服务IP的数据包并将其重定向到pods,所有这些都发生在内核空间中。
在这种模式下,kube-proxy的工作或多或少局限于保持netfilter规则同步。
网络架构变为:
但是,这不适合外部(面向公众)通信,这需要外部固定IP。
您有专门的服务:nodePort and LoadBalancer:
NodePort 类型的服务是具有附加功能的ClusterIP服务:它可以在节点的IP地址以及服务网络上分配的群集IP上访问。
实现这一目标非常简单:当kubernetes创建NodePort服务时, kube-proxy分配范围为30000-32767的端口,并在每个节点的
eth0
接口上打开此端口(因此名称为“NodePort”)强>此端口的连接将转发到服务的群集IP。
你得到:
Loadbalancer更先进,允许使用支持端口公开服务 请参见此处的映射:
$ kubectl get svc service-test
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
openvpn 10.3.241.52 35.184.97.156 80:32213/TCP 5m
然而:
LoadBalancer类型的服务有一些限制。
- 您无法配置lb以终止https流量。
- 您无法执行虚拟主机或基于路径的路由,因此您无法使用单个负载均衡器以任何实际有用的方式代理多个服务。
这些限制导致在版本1.2中添加了用于配置负载均衡器的单独kubernetes资源,称为 Ingress 。
Ingress API支持TLS终止,虚拟主机和基于路径的路由。它可以轻松设置负载均衡器来处理多个后端服务 该实现遵循基本的kubernetes模式:资源类型和管理该类型的控制器 在这种情况下,资源是Ingress,其包括对网络资源的请求
例如:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
kubernetes.io/ingress.class: "gce"
spec:
tls:
- secretName: my-ssl-secret
rules:
- host: testhost.com
http:
paths:
- path: /*
backend:
serviceName: service-test
servicePort: 80
入口控制器负责通过将环境中的资源驱动到必要的状态来满足此请求 使用Ingress时,您可以将服务创建为NodePort类型,并让入口控制器弄清楚如何获得节点流量。
GCE负载平衡器,AWS弹性负载平衡器以及NGiNX和HAproxy等流行代理都有入口控制器实现。