我有一个运行2个小兵的kubernetes集群 . 目前,我通过两个步骤访问我的服务:
-
启动复制控制器和pod
-
获取minion IP(使用
kubectl get minions
)并将其设置为服务的publicIPs .
向公众公开服务的建议做法是什么?我的方法似乎是错误的,因为我对单个minion IP-s的IP进行了硬编码 . 它似乎也绕过了kubernetes服务的负载 balancer 功能,因为客户端必须直接访问在各个minions上运行的服务 .
要设置复制控制器和pod,我使用:
id: frontend-controller
kind: ReplicationController
apiVersion: v1beta1
desiredState:
replicas: 2
replicaSelector:
name: frontend-pod
podTemplate:
desiredState:
manifest:
version: v1beta1
id: frontend-pod
containers:
- name: sinatra-docker-demo
image: madisn/sinatra_docker_demo
ports:
- name: http-server
containerPort: 4567
labels:
name: frontend-pod
要设置服务(在获得minion ip-s之后):
kind: Service
id: frontend-service
apiVersion: v1beta1
port: 8000
containerPort: http-server
selector:
name: frontend-pod
labels:
name: frontend
publicIPs: [10.245.1.3, 10.245.1.4]
5 回答
正如我在上面的评论中提到的,createExternalLoadBalancer是您正在寻找的适当的抽象,但遗憾的是它尚未针对所有 Cloud 提供程序实现,特别是对于您在本地使用的vagrant .
一种选择是将群集中所有minions的公共IP用于要外部化的所有服务 . 发往该服务的流量将最终出现在其中一个minions上,它将被kube-proxy进程拦截并重定向到与该服务的标签选择器匹配的pod . 这可能会导致网络上的额外跳跃(如果您降落在没有本地运行的pod的节点上),但对于对网络延迟不是非常敏感的应用程序,这可能不会引人注意 .
正如罗伯特在回答中所说,这是即将到来的事情,但遗憾的是还没有 .
我目前正在数据中心网络上运行Kubernetes集群 . 我有1个主人和3个小兵都在CentOS 7虚拟机(vcenter)上运行 . 我处理这个问题的方法是创建一个专用的“kube-proxy”服务器 . 我基本上只是运行Kube-Proxy服务(连同Flannel用于网络),然后将“公共”IP地址分配给连接到此服务器的网络适配器 . 当我说公开时,我指的是我们本地数据中心网络上的地址 . 然后,当我创建一个我想在集群外部访问的服务时,我只需将publicIPs值设置为kube-proxy服务器上的一个可用IP地址 . 当某人或某物尝试从群集外部连接到此服务时,它将命中kube-proxy,然后被重定向到正确的minion .
虽然这似乎是一种解决方法,但这实际上与我们预期在他们提出针对此问题的内置解决方案时所期望的相似 .
如果您在本地运行集群,我使用的解决方案是使用服务定义中的nodeport指令在kubernetes节点上公开服务,然后使用HAproxy将集群循环到集群中的每个节点 .
这是暴露nodeport的样子:
注意:您指定的值必须在节点端口的配置范围内 . (默认:30000-32767)
这会在群集中的每个节点上公开给定节点端口上的服务 . 然后,我在运行haproxy的内部网络上设置了一个单独的机器,并且在您要公开的指定节点端口上可以从外部访问防火墙 .
如果你在你的一个主机上查看你的nat表,你可以看到它正在做什么 .
特别是这一行
最后,如果您查看netstat,您可以看到kube-proxy正在侦听并等待该端口上的该服务 .
Kube-proxy将侦听每个服务的端口,并将网络地址转换到容器所在的虚拟子网中 . (我想?)我使用了法兰绒 .
对于双节点群集,该HAproxy配置可能看起来与此类似:
现在,您可以通过HAproxy在端口80上访问您的服务 . 如果您的任何节点发生故障,由于复制控制器,容器将被移动到另一个节点,并且HAproxy将仅路由到您的活动节点 .
我很好奇其他人使用过什么方法,这就是我想出来的 . 我通常不会发布堆栈溢出,所以如果我没有遵循约定或正确的格式,请道歉 .
这是给MrE的 . 我在评论区域没有足够的空间来发布这个答案,所以我不得不创建另一个答案 . 希望这可以帮助:
发布此回复后,我们实际上离开了Kubernetes . 如果我没记错的话虽然我真的必须要做的是在专用的CentOS VM上运行kube-proxy可执行文件 . 这是我做的:
首先,我删除了Firewalld并将iptables放到位 . Kube-proxy依赖于iptables来处理其NAT和重定向 .
其次,您需要安装flanneld,这样您就可以在与您的minions上运行的Docker服务相同的网络上拥有一个桥接适配器 .
然后我做的是为机器上安装的本地网络适配器分配多个IP地址 . 这些是您在设置服务时可以使用的IP地址 . 这些将是您的群集外的可用地址 .
一旦完成所有工作,您就可以启动代理服务 . 它将连接到Master,并获取法兰绒桥网络的IP地址 . 然后它将同步所有IPtables规则,你应该设置 . 每次添加新服务时,它都会创建代理规则并在所有minions(和您的代理)中复制这些规则 . 只要您在代理服务器上指定了可用的IP地址,该代理服务器就会将该IP地址的所有流量转发到适当的minion .
希望这更清楚一点 . 请记住,虽然我现在还没有参加Kubernetes项目大约6个月,所以我不确定自从我离开后发生了什么变化 . 他们甚至可能有一个处理这类事情的功能 . 如果不希望这有助于你得到它照顾 .
您可以使用Ingress资源来允许来自Kubernetes群集外部的外部连接到达群集服务 .
假设您已经部署了Pod,那么您现在需要一个服务资源,例如:
apiVersion: v1 kind: Service metadata: name: frontend-service labels: tier: frontend spec: type: ClusterIP selector: name: frontend-pod ports: - name: http protocol: TCP # the port that will be exposed by this service port: 8000 # port in a docker container; defaults to what "port" has set targetPort: 8000
并且您需要一个Ingress资源:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: frontend-ingress spec: rules: - host: foo.bar.com http: paths: - path: / backend: serviceName: frontend-service # the targetPort from service (the port inside a container) servicePort: 8000
为了能够使用Ingress资源,您需要部署一些ingress controller .现在,假设您知道您的Kubernetes主IP,您可以从Kubernetes集群外部访问您的应用程序:
curl http://<master_ip>:80/ -H 'Host: foo.bar.com'
如果您使用某个DNS服务器,您可以添加此记录:
foo.bar.com IN A <master_ip>
或将此行添加到您的/etc/hosts
文件:<master_ip> foo.bar.com
现在您可以运行:curl foo.bar.com
请注意,这样您将始终使用端口80访问
foo.bar.com
. 如果您想使用其他端口,我建议使用NodePort类型的服务,仅适用于那个非-80端口 . 它将使该端口可以解析,无论您使用哪个Kubernetes VM IP(任何主或任何minion IP都可以) . 此类服务的示例:apiVersion: v1 kind: Service metadata: name: frontend-service-ssh labels: tier: frontend spec: type: NodePort selector: name: frontend-pod ports: - name: ssh targetPort: 22 port: 22 nodePort: 2222 protocol: TCP
如果您的/ etc / hosts文件中有<master_ip> foo.bar.com
,则可以访问:foo.bar.com:2222