【问题标题】:Cluster Kubernetes - Deploy httpd and access from externalCluster Kubernetes - 部署 httpd 并从外部访问
【发布时间】:2025-12-11 09:05:03
【问题描述】:

我创建了我的 Kubernetes 集群并尝试部署这个 yaml 文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd-deployment
spec:
  selector:
    matchLabels:
      app: httpd
  replicas: 1
  template:
    metadata:
      labels:
        app: httpd
    spec:
      containers:
      - name: httpd
        image: httpd
        ports:
        - containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
  name: httpd-service
spec:
  selector:
    app: httpd-app
  ports:  
    - protocol: TCP
      port: 8080
      targetPort: 80
      nodePort: 30020
      name: httpd-port
  type: NodePort

这是配置:

[root@BCA-TST-K8S01 httpd-deploy]# kubectl get all -o wide
NAME                                    READY   STATUS    RESTARTS   AGE     IP          NODE               NOMINATED NODE   READINESS GATES
pod/httpd-deployment-57fc687dcc-rggx9   1/1     Running   0          8m51s   10.44.0.1   bcc-tst-docker02   <none>           <none>

NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE     SELECTOR
service/httpd-service   NodePort    10.102.138.175   <none>        8080:30020/TCP   8m51s   app=httpd-app
service/kubernetes      ClusterIP   10.96.0.1        <none>        443/TCP          134m    <none>

NAME                               READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES   SELECTOR
deployment.apps/httpd-deployment   1/1     1            1           8m51s   httpd        httpd    app=httpd

NAME                                          DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES   SELECTOR
replicaset.apps/httpd-deployment-57fc687dcc   1         1         1       8m51s   httpd        httpd    app=httpd,pod-template-hash=57fc687dcc

但我无法连接到worker或从集群IP:

curl http://bcc-tst-docker02:30020
curl: (7) Failed to connect to bcc-tst-docker02 port 30020: Connection refused

我该如何解决这个问题? 如何使用内部 Matser IP 暴露集群(例如我需要从主 IP 10.100.170.150 访问 httpd-deploy 打开同一网络中的浏览器)

更新:

我修改了我的yaml文件如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd-deployment
spec:
  selector:
    matchLabels:
      app: httpd-app
  replicas: 2
  template:
    metadata:
      labels:
        app: httpd-app
    spec:
      containers:
      - name: httpd
        image: httpd
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: http-service
spec:
  externalIPs:
  - 10.100.170.150               **--> IP K8S**
  externalTrafficPolicy: Cluster
  ports:
  - name: httpd-port
    protocol: TCP
    port: 8080
    targetPort: 80
    nodePort: 30020
  selector:
    app: httpd-app
  sessionAffinity: None
  type: LoadBalancer

这些是我运行应用命令后的结果:

[root@K8S01 LoadBalancer]# kubectl get all -o wide
NAME                                    READY   STATUS    RESTARTS   AGE   IP          NODE               NOMINATED NODE   READINESS GATES
pod/httpd-deployment-65d64d47c5-72xp4   1/1     Running   0          60s   10.44.0.2   bcc-tst-docker02   <none>           <none>
pod/httpd-deployment-65d64d47c5-fc645   1/1     Running   0          60s   10.36.0.1   bca-tst-docker01   <none>           <none>

NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE   SELECTOR
service/http-service   LoadBalancer   10.100.236.203   10.100.170.150   8080:30020/TCP   60s   app=httpd-app
service/kubernetes     ClusterIP      10.96.0.1        <none>           443/TCP          13d   <none>

NAME                               READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES   SELECTOR
deployment.apps/httpd-deployment   2/2     2            2           60s   httpd        httpd    app=httpd-app

NAME                                          DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES   SELECTOR
replicaset.apps/httpd-deployment-65d64d47c5   2         2         2       60s   httpd        httpd    app=httpd-app,pod-template-hash=65d64d47c5

但现在当我尝试使用 K8S IP 连接到 httpd 时,我收到以下错误:

[root@K8S01 LoadBalancer]# curl http://10.100.170.150:8080
curl: (7) Failed to connect to 10.100.170.150 port 8080: No route to host
[root@K8S01 LoadBalancer]# curl http://10.100.236.203:8080
curl: (7) Failed to connect to 10.100.236.203 port 8080: No route to host

如果我尝试直接连接到我可以连接的节点:

[root@K8S01 LoadBalancer]# curl http://bca-tst-docker01:30020
<html><body><h1>It works!</h1></body></html>
[root@K8S01 LoadBalancer]# curl http://bcc-tst-docker02:30020
<html><body><h1>It works!</h1></body></html>

【问题讨论】:

  • 您是如何引导集群的?库比德姆?迷你库?你在运行什么操作系统?如果我理解正确,您希望使用 nodePort 从外部访问您在集群中运行的 httpd 服务?
  • 你有多少个节点?我可以假设它只是一个/主人?你有防火墙吗?你能用sudo netstat -tulpn | grep LISTEN检查30020端口是否真的打开了吗?
  • 我使用 Kubeadm 创建了我的集群。操作系统为 Oracle Linux 8.3,docker 版本 20.10.5 和 Kubernetes 版本 Client Version: version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.5", GitCommit:"6b1d87acf3c8253c123756b9e61dac642678305f", GitTreeState: “干净”,构建日期:“2021-03-18T01:10:43Z”,GoVersion:“go1.15.8”,编译器:“gc”,平台:“linux/amd64”}。如果可能的话,我的范围是使用 LoadBalancer。有防火墙,并且在工作节点上打开了范围端口 30000-32767

标签: kubernetes


【解决方案1】:

您将获得connection refused,因为该服务没有任何端点,因为您的标签选择器与部署级别不同。

部署有httpd 标签,而服务试图捕获所有带有httpd-app 的部署。您可以在下面找到更正的选择器:

kind: Service
apiVersion: v1
metadata:
  name: httpd-service
spec:
  selector:
    app: httpd  <-------
  ports:  
    - protocol: TCP
      port: 8080
      targetPort: 80
      nodePort: 30020
      name: httpd-port
  type: NodePort

您始终可以验证服务是否具有端点。 Kubernetes 有一个很棒的关于调试服务的部分,其中一个叫做:Does the Service have any Endpoints?

【讨论】:

  • 感谢您的回复。现在我可以直接连接到工作节点,但是我无法使用 k8s ip 作为 LoadBalancer 连接。
  • 但是你有没有配置负载均衡器?如果是,是什么样的?一些云一?金属布?
  • 不,我没有配置任何 LB,k8s 是 LB as services 吗?
  • 请查看(本指南)[weave.works/blog/…,了解如何在裸机上为 Kubernetes 路由流量。负载均衡器类型通常用于云环境中,它会自动为您提供负载均衡器。对于裸机,您需要使用其他选项,例如 Metallb,或者只需将入口与入口控制器一起使用。
  • 使用您提供的 ExternalIP 选项,Kubernetes 不再负责 IP 地址,但您负责。所以你应该使用与你节点的主接口关联的 IP(例如 eth0)