如何配置kubernetes-aws中的集群IP?

sou*_*ics 5 amazon-ec2 amazon-web-services amazon-vpc docker kubernetes

我是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",它就不会连接.为什么它无法从主站连接?

2)每个节点内都有一个cbr0接口.每个minion节点的cbr0配置为10.244.x.0/24,master的cbr0配置为10.246.0.0/24.我可以从任何节点(包括主节点)ping到任何10.244.xx 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>
Run Code Online (Sandbox Code Playgroud)

Von*_*onC 10

Mark Betz( Olark的SRE)在三篇文章中介绍了Kubernetes网络:

对于pod,您正在查看:

pod网络

你发现:

  • etho0:一个"物理网络接口"
  • docker0/cbr0:用于连接两个以太网段的,无论其协议如何.
  • veth0,1,2:虚拟网络接口,每个容器之一.
    docker0默认网关veth0.它被命名为"自定义桥"的cbr0.
    Kubernetes通过共享相同的veth0来启动容器,这意味着每个容器必须暴露不同的端口.
  • pause:一个以" pause" 开头的特殊容器,用于检测发送到pod的SIGTERM,并将其转发给容器.
  • 节点:主机
  • 集群:一组节点
  • 路由器/网关

事情的最后一个方面是事情开始变得更加复杂:

Kubernetes为每个节点上的网桥分配总地址空间,然后根据构建网桥的节点分配该空间内的网桥地址.
其次,它将路由规则添加到10.100.0.1的网关,告诉它应该如何路由发往每个网桥的数据包​​,即eth0可以通过哪个节点到达网桥.

虚拟网络接口,网桥和路由规则的这种组合通常称为覆盖网络.

当pod与另一个pod联系时,它将通过一项服务.
为什么?

群集中的Pod网络是很好的东西,但是它本身不足以支持创建持久的系统.那是因为Kubernetes豆荚是短暂的.
您可以使用pod IP地址作为端点,但无法保证下次重新创建pod时地址不会更改,这可能由于多种原因而发生.

这意味着:您需要一个反向代理/动态负载均衡器.而且它更有弹性.

服务是一种kubernetes资源,可以将代理配置为将请求转发到一组pod.
将接收流量的一组容器由选择器确定,该选择器匹配在创建容器时分配给容器的标签

该服务使用自己的网络.默认情况下,其类型为" ClusterIP "; 它有自己的IP.

这是两个pod之间的通信路径:

两个豆荚网络

它使用kube-proxy.
此代理自身使用netfilter.

netfilter是一个基于规则的数据包处理引擎.
它在内核空间中运行,并查看其生命周期中各个点的每个数据包.
它根据规则匹配数据包,当它找到匹配它的规则时,将采取指定的操作.
它可以采取的许多行动包括将数据包重定向到另一个目的地.

kube-proxy和netfilter

在这种模式下,kube-proxy:

  • 在本地主机接口上打开一个端口(上例中的10400)以侦听对测试服务的请求,
  • 插入netfilter规则,将目的地为服务IP的数据包重新路由到自己的端口,以及
  • 将这些请求转发到端口8080上的pod.

这就是请求10.3.241.152:80神奇地成为请求的方式10.0.2.2:8080.
鉴于对使所需网络过滤的功能,这一切对于任何服务的所有工作,是KUBE-代理打开一个端口,然后插入该服务的正确的网络过滤规则,它确实在响应从变化的主API服务器通知集群.

但:

这个故事还有一点点扭曲.
我在上面提到过,由于编组数据包,用户空间代理很昂贵.在kubernetes 1.2中,kube-proxy获得了在iptables模式下运行的能力.

在这种模式下,KUBE-代理大多不再是集群间的连接代理,而是委托给Netfilter的检测结合的服务的IP数据包,并将其重定向到荚,所有这些都发生在内核空间的工作.
在这种模式下,kube-proxy的工作或多或少局限于保持netfilter规则同步.

网络架构变为:

netfilter在行动

但是,这不适合需要外部固定IP的外部(面向公众)通信.

您有专门的服务:nodePortLoadBalancer:

NodePort类型的服务是具有附加功能的ClusterIP服务:它可以在节点的IP地址以及服务网络上分配的群集IP上访问.
这样做的方式非常简单:

当kubernetes创建NodePort服务时,kube-proxy分配范围为30000-32767的端口,并eth0在每个节点的接口上打开此端口(因此名称为"NodePort").

与此端口的连接将转发到服务的群集IP.

你得到:

负载均衡器/节点端口

Loadbalancer更先进,允许使用stand端口公开服务.
请参阅此处的映射:

$ 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
Run Code Online (Sandbox Code Playgroud)

然而:

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
Run Code Online (Sandbox Code Playgroud)

入口控制器负责通过将环境中的资源驱动到必要状态来满足该请求.
使用Ingress时,您可以创建类型为NodePort的服务,并让入口控制器弄清楚如何获取节点的流量.

GCE负载平衡器,AWS弹性负载平衡器以及NGiNX和HAproxy等流行代理都有入口控制器实现.