Kubernetes - 使 Nodeport 在所有节点上均可访问

Kubernetes - 使 Nodeport 在所有节点上均可访问

我正在运行 Kubernetes 裸机安装,并尝试使我的测试 nginx 应用程序(使用 创建kubectl create deployment nginx --image=nginx)从所有节点远程可见。我的想法是,然后我可以使用裸机 HAProxy 安装来适当地路由流量。

从我读到的所有内容来看,此配置应该可以工作,并允许通过端口跨节点进行访问。此外,执行 netstat 似乎确实显示节点端口正在监听所有节点 -

user@kube2:~$ netstat -an | grep :30196
tcp6       0      0 :::30196                :::*                    LISTEN

我的 service.yaml 文件 -

apiVersion: v1
kind: Service
metadata:
  name: test-svc
  namespace: default
spec:
  type: NodePort
  externalTrafficPolicy: Cluster
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http
  - port: 443
    targetPort: 443
    protocol: TCP
    name: https
  selector:
    app: nginx

我的节点网络配置 -

kube1 - 192.168.1.130 (master)
kube2 - 192.168.1.131
kube3 - 192.168.1.132

我的服务正在运行 -

user@kube1:~$ kubectl get svc -o wide
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE   SELECTOR
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP                      18m   <none>
test-svc     NodePort    10.103.126.143   <none>        80:30196/TCP,443:32580/TCP   14m   app=nginx

但是,尽管有上述所有情况,我的服务只能在其运行的节点 (kube3/192.168.1.132) 上访问。您知道这是为什么吗?还是我只是了解 Kubernetes?

我查看了负载均衡器和入口,但如果我将所有流量路由到我的主服务器进行分发(kube1),那么如果 kube1 发生故障怎么办?我肯定需要一个负载均衡器来定位我的负载均衡器吧?!

希望有人可以帮忙!

谢谢,克里斯。

答案1

如果您想要将服务暴露给外部集群,请使用服务类型 LoadBalancer 或 ingree。但是,使用 LoadBalancer 方法有其自身的限制。您无法配置 LoadBalancer 来终止 HTTPS 流量、虚拟主机或基于路径的路由。在 Kubernetes 1.2 中,为此目的引入了一个名为 Ingress 的单独资源。以下是 LoadBalancer 的示例。

apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-app
  name: nginx-svc
  namespace: default
spec:
  type: LoadBalancer  # use LoadBalancer as type here
  ports:
    - port: 80
  selector:
    app: nginx-app

$ kubectl get services -l app=nginx-app -o wide
NAME        TYPE           CLUSTER-IP       EXTERNAL-IP                                                                  PORT(S)        AGE       SELECTOR
nginx-svc   LoadBalancer   <ip>   a54a62300696611e88ba00af02406931-1787163476.myserver.com   80:31196/TCP   9m        app=nginx-app

发布测试网址

$curl a54a62300696611e88ba00af02406931-1787163476.myserver.com

答案2

为了访问本地 Kubernetes 集群 POD需要NodePort创建。NodePort将在每个节点使用其公共 IP 和端口。然后,您可以使用任何集群 IP 和分配的端口访问该服务。

在 Kubernetes 中定义 NodePort

apiVersion: v1
kind: Service
metadata:
  name: nginx-service-np
  labels:
    name: nginx-service-np
spec:
  type: NodePort
  ports:
    - port: 8082        # Cluster IP, i.e. http://10.103.75.9:8082
      targetPort: 8080  # Application port
      nodePort: 30000   # (EXTERNAL-IP VirtualBox IPs) i.e. http://192.168.50.11:30000/ http://192.168.50.12:30000/ http://192.168.50.13:30000/
      protocol: TCP
      name: http
  selector:
    app: nginx 

查看带有源代码的完整示例使用 Vagrant 和 Ansible 构建 Kubernetes 集群(无需 Minikube)

nginx 入口控制器也可以替换为Istio如果您想从服务网格架构中受益:

  • 负载平衡流量,外部或内部
  • 控制失败、重试、路由
  • 应用限制并监控服务之间的网络流量
  • 安全通信

在 VirtualBox 下的 Kubernetes 中安装 Istio(无需 Minikube)

答案3

另一个选择是公开 Nginx Ingress 控制器节点端口(虽然不推荐用于生产集群)。NodePort 类型仍然为您提供负载平衡功能,并且应将流量发送到哪个特定 Pod(支持服务端点),您可以使用“service.spec.sessionAffinity”和容器探测器

如果你的 Deployment 规范中有多个 nginx Pod 副本(例如这里),你可以通过以下方式控制 pod 到节点的分配pod 亲和性和反亲和性功能

相关内容