【问题标题】:Exposing bare metal kubernetes cluster to internet将裸机 kubernetes 集群暴露在互联网上
【发布时间】:2019-01-14 00:12:39
【问题描述】:

我正在尝试在裸机专用服务器上设置自己的单节点 kubernetes 集群。我在开发运维方面没有那么丰富的经验,但我需要为我自己的项目部署一些服务。我已经使用jujuconjure-up kubernetesLXD 进行了集群设置。我的集群运行得很好。

$ juju status

Model                         Controller                Cloud/Region         Version  SLA          Timestamp
conjure-canonical-kubern-3b3  conjure-up-localhost-db9  localhost/localhost  2.4.3    unsupported  23:49:09Z

App                    Version  Status  Scale  Charm                  Store       Rev  OS      Notes
easyrsa                3.0.1    active      1  easyrsa                jujucharms  195  ubuntu
etcd                   3.2.10   active      3  etcd                   jujucharms  338  ubuntu
flannel                0.10.0   active      2  flannel                jujucharms  351  ubuntu
kubeapi-load-balancer  1.14.0   active      1  kubeapi-load-balancer  jujucharms  525  ubuntu  exposed
kubernetes-master      1.13.1   active      1  kubernetes-master      jujucharms  542  ubuntu
kubernetes-worker      1.13.1   active      1  kubernetes-worker      jujucharms  398  ubuntu  exposed

Unit                      Workload  Agent  Machine  Public address  Ports           Message
easyrsa/0*                active    idle   0        10.213.117.66                   Certificate Authority connected.
etcd/0*                   active    idle   1        10.213.117.171  2379/tcp        Healthy with 3 known peers
etcd/1                    active    idle   2        10.213.117.10   2379/tcp        Healthy with 3 known peers
etcd/2                    active    idle   3        10.213.117.238  2379/tcp        Healthy with 3 known peers
kubeapi-load-balancer/0*  active    idle   4        10.213.117.123  443/tcp         Loadbalancer ready.
kubernetes-master/0*      active    idle   5        10.213.117.172  6443/tcp        Kubernetes master running.
  flannel/1*              active    idle            10.213.117.172                  Flannel subnet 10.1.83.1/24
kubernetes-worker/0*      active    idle   7        10.213.117.136  80/tcp,443/tcp  Kubernetes worker running.
  flannel/4               active    idle            10.213.117.136                  Flannel subnet 10.1.27.1/24

Entity  Meter status  Message
model   amber         user verification pending

Machine  State    DNS             Inst id        Series  AZ  Message
0        started  10.213.117.66   juju-b03445-0  bionic      Running
1        started  10.213.117.171  juju-b03445-1  bionic      Running
2        started  10.213.117.10   juju-b03445-2  bionic      Running
3        started  10.213.117.238  juju-b03445-3  bionic      Running
4        started  10.213.117.123  juju-b03445-4  bionic      Running
5        started  10.213.117.172  juju-b03445-5  bionic      Running
7        started  10.213.117.136  juju-b03445-7  bionic      Running

我还部署了 Hello world 应用程序,在 pod 内的端口 8080nginx-ingress 上输出一些 hello,以便将流量重新路由到指定主机上的此服务。

NAME                               READY   STATUS    RESTARTS   AGE
pod/hello-world-696b6b59bd-fznwr   1/1     Running   1          176m

NAME                      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/example-service   NodePort    10.152.183.53   <none>        8080:30450/TCP   176m
service/kubernetes        ClusterIP   10.152.183.1    <none>        443/TCP          10h

NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/hello-world   1/1     1            1           176m

NAME                                     DESIRED   CURRENT   READY   AGE
replicaset.apps/hello-world-696b6b59bd   1         1         1       176m

当我按预期执行curl localhost 时,我有connection refused,它看起来仍然很好,因为它没有暴露在集群中。当我在端口30450 上使用公共地址10.213.117.136 卷曲kubernetes-worker/0(我从kubectl get all 获得)

$ curl 10.213.117.136:30450
Hello Kubernetes!

一切都像魅力一样(这很明显)。当我这样做时

curl -H "Host: testhost.com" 10.213.117.136
Hello Kubernetes!

它再次像魅力一样起作用!这意味着入口控制器正在根据host 规则成功路由端口80 以纠正服务。在这一点上,我 100% 确定集群可以正常工作。

现在我正在尝试通过 Internet 从外部访问此服务。当我加载&lt;server_ip&gt; 时,显然没有加载,因为它位于自己的lxd 子网中。因此,我正在考虑将端口 80 从服务器 eth0 转发到此 IP。所以我在 iptables 中添加了这条规则

sudo iptables -t nat -A PREROUTING -p tcp -j DNAT --to-destination 10.213.117.136(例如,让我们路由所有内容,而不仅仅是端口 80)。现在,当我在我的电脑上打开 http://&lt;server_ip&gt; 时,它会加载!

所以真正的问题是如何在生产中做到这一点?我应该在 iptables 中设置此转发规则吗?那是正常的方法还是骇人听闻的解决方案,并且我缺少一些“标准”?问题是使用静态worker 节点添加此规则将使集群完全静态。 IP 最终会改变,我可以为工人移除/添加单位,它会停止工作。我正在考虑编写脚本,该脚本将从 juju 获取此 IP 地址,如下所示:

$ juju status kubernetes-worker/0 --format=json | jq '.machines["7"]."dns-name"'
"10.213.117.136"

并将其添加到 IP 表中,这是比硬编码 IP 更合适的解决方案,但我仍然觉得这很棘手,必须有更好的方法。

作为最后一个想法,我可以在集群外直接在机器上运行HAProxy,并将流量转发给所有可用的工作人员。这最终也可能奏效。但是我仍然不知道答案是什么correct 解决方案以及在这种情况下通常使用什么。谢谢!

【问题讨论】:

    标签: kubernetes juju bare-metal-server


    【解决方案1】:

    所以真正的问题是如何在生产中做到这一点?

    在生产系统中执行此操作的正常方法是使用Service

    最简单的情况是您只希望您的应用程序可以从您的节点上的外部访问。在这种情况下,您可以使用Type NodePort 服务。这将创建必要的 iptables 规则,将流量从主机 IP 地址转发到提供服务的 pod。

    如果您只有一个节点(不建议在生产环境中使用!),此时您已经准备就绪。

    如果您的 Kubernetes 集群中有多个节点,所有节点都将由 Kubernetes 配置以提供对服务的访问(您的客户端可以使用其中任何一个节点来访问服务)。但是,您必须解决客户端如何知道可以联系哪些节点的问题...

    有几种方法可以解决这个问题:

    • 使用客户端理解的协议发布当前可用的IP地址(例如DNS),

    • 使用由 Kubernetes 节点上的某些软件(例如起搏器/corosync)管理的浮动(故障转移、虚拟、HA)IP 地址,并将客户端定向到该地址,

    • 使用单独配置的外部负载平衡器将流量转发到某些操作节点,

    • 使用由 Kubernetes 使用云提供商集成脚本(通过使用 Type LoadBalancer 服务)自动配置的外部负载平衡器,将流量转发到某些操作节点。

    【讨论】:

    • 太棒了!谢谢你。几天前我开始使用kubernetes,我只是不知道Service 也在维护iptables。最初我认为它将 pod 暴露给其他 pod 可访问(例如,后端连接到不同 pod 上的 db)。你的回答完全给了我一个更好的画面! (关于生产我知道,但它仍然是开发的暂存实例,但暴露在互联网上是可访问的:) 在生产中,它肯定会在多个节点上运行。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2020-09-28
    • 2019-09-04
    • 2020-08-05
    • 2017-06-21
    • 2019-10-16
    • 2020-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多