简体   繁体   English

无法访问 Kubernetes 上公开的 Dockerized React 应用程序

[英]Cannot access exposed Dockerized React app on Kubernetes

I'm trying to deploy my Dockerized React app to Kubernetes.我正在尝试将我的 Dockerized React 应用程序部署到 Kubernetes。 I believe I've dockerized it correctly, but i'm having trouble accessing the exposed pod.我相信我已经正确地对其进行了 dockerized,但是我在访问暴露的 pod 时遇到了问题。

I don't have experience in Docker or Kubernetes, so any help would be appreciated.我没有 Docker 或 Kubernetes 的经验,所以任何帮助将不胜感激。

My React app is just static files (from npm run build) being served from Tomcat.我的 React 应用程序只是由 Tomcat 提供的静态文件(来自 npm run build)。

My Dockerfile is below.我的 Dockerfile 在下面。 In summary, I put my app in the Tomcat folder and expose port 8080.总之,我将我的应用程序放在 Tomcat 文件夹中并公开端口 8080。

FROM private-docker-registry.com/repo/tomcat:latest

EXPOSE 8080:8080

# Copy build directory to Tomcat webapps directory
RUN mkdir -p /tomcat/webapps/app
COPY /build/sample-app /tomcat/webapps/app

# Create a symbolic link to ROOT -- this way app starts at root path 
(localhost:8080)

RUN ln -s /tomcat/webapps/app /tomcat/webapps/ROOT

# Start Tomcat
ENTRYPOINT ["catalina.sh", "run"]

I build and pushed the Docker image to the Private Docker Registry.我构建并将 Docker 映像推送到私有 Docker 注册表。 I verified that container runs correctly by running it like this:我通过像这样运行它来验证容器是否正确运行:

docker run -p 8080:8080 private-docker-registry.com/repo/sample-app:latest

Then, if I go to localhost:8080, I see the homepage of my React app.然后,如果我转到 localhost:8080,我会看到我的 React 应用程序的主页。

Now, the trouble I'm having is deploying to Kubernetes and accessing the app externally.现在,我遇到的问题是部署到 Kubernetes 并从外部访问应用程序。

Here's my deployment.yaml file:这是我的 deployment.yaml 文件:

kind: Deployment
apiVersion: apps/v1beta2
metadata:
  name: sample-app
  namespace: dev
  labels:
    app: sample-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
      - name: sample-app
        image: private-docker-registry.com/repo/sample-app:latest
        ports:
        - containerPort: 8080
          protocol: TCP
      nodeSelector:
        TNTRole: luxkube
---
kind: Service
apiVersion: v1
metadata:
  name: sample-app
  labels:
    app: sample-app
spec:
  selector:
    app: sample-app
  type: NodePort
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP

I created the deployment and service by running kubectl --namespace=dev create -f deployment.yaml我通过运行 kubectl --namespace=dev create -f deployment.yaml 创建了部署和服务

Output of 'describe deployment'

    Name:                   sample-app
    Namespace:              dev
    CreationTimestamp:      Sat, 21 Jul 2018 12:27:30 -0400
    Labels:                 app=sample-app
    Annotations:            deployment.kubernetes.io/revision=1
    Selector:               app=sample-app
    Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
    StrategyType:           RollingUpdate
    MinReadySeconds:        0
    RollingUpdateStrategy:  25% max unavailable, 25% max surge
    Pod Template:
      Labels:  app=sample-app
      Containers:
       sample-app:
        Image:        private-docker-registry.com/repo/sample-app:latest
        Port:         8080/TCP
        Host Port:    0/TCP
        Environment:  <none>
        Mounts:       <none>
      Volumes:        <none>
    Conditions:
      Type           Status  Reason
      ----           ------  ------
      Available      True    MinimumReplicasAvailable
      Progressing    True    NewReplicaSetAvailable
    OldReplicaSets:  <none>
    NewReplicaSet:   sample-app-bb6f59b9 (1/1 replicas created)
    Events:          <none>

Output of 'describe service'

Name:                     sample-app
Namespace:                fab-dev
Labels:                   app=sample-app
Annotations:              <none>
Selector:                 app=sample-app
Type:                     NodePort
IP:                       10.96.29.199
Port:                     <unset>  80/TCP
TargetPort:               8080/TCP
NodePort:                 <unset>  34604/TCP
Endpoints:                192.168.138.145:8080
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

Now I don't know which IP and port I should be using to access the app.现在我不知道应该使用哪个 IP 和端口来访问应用程序。 I have tried every combination but none has loaded my app.我尝试了所有组合,但没有一个已加载我的应用程序。 I believe the port should be 80, so if I just have the IP, i shuold be able to go to the browser and access the React app by going to http://.我相信端口应该是 80,所以如果我只有 IP,我应该能够进入浏览器并通过访问 http:// 来访问 React 应用程序。

Does anyone have suggestions?有没有人有建议?

The short version is that the Service is listening on the same TCP/IP port on every Node in your cluster ( 34604 ) as is shown in the output of describe service :简短版本是服务正在侦听集群中每个节点 ( 34604 ) 上的相同 TCP/IP 端口, describe service的输出所示:

NodePort:                 <unset>  34604

If you wish to access the application through a "nice" URL, you'll want a load balancer that can translate the hostname into the in-cluster IP and port combination.如果您希望通过“不错”的 URL 访问应用程序,您需要一个负载均衡器,它可以将主机名转换为集群内 IP 和端口组合。 That's what an Ingress controller is designed to do, but it isn't the only way -- changing the Service to be type: LoadBalancer will do that for you, if you're running in a cloud environment where Kubernetes knows how to programmatically create load balancers for you.这就是 Ingress 控制器的设计目的,但这不是唯一的方法——将 Service 更改为type: LoadBalancer将为您完成此操作,如果您在 Kubernetes 知道如何以编程方式创建的云环境中运行负载均衡器。

I believe you found the answer by now :), I landed here as I was facing this issue.我相信你现在已经找到了答案:),当我面临这个问题时,我来到了这里。 Solved for self, hope this helps everyone.自行解决,希望对大家有帮助。

Here's what can help:以下是可以提供帮助的内容:

  1. Deploy your app (say: react-app).部署您的应用程序(例如:react-app)。
  2. Run below command: kubectl expose deployment <workload> --namespace=app-dev --name=react-app --type=NodePort --port=3000 output: service/notesui-app exposed运行以下命令: kubectl expose deployment <workload> --namespace=app-dev --name=react-app --type=NodePort --port=3000 output: service/notesui-app exposed

Publish the service port as 3000, Target Port 3000, Node Port (auto selected 32250)发布服务端口为 3000,目标端口 3000,节点端口(自动选择 32250)

kubectl get svc react-app --namespace=notesui-dev
NAME          TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
react-app   NodePort   10.23.22.55   <none>        3000:32250/TCP   48m

Yaml: (sample) Yaml:(示例)

apiVersion: v1
kind: Service
  name: react-app
  namespace: app-dev
spec:
  selector: <workload>
  ports:
  - nodePort: 32250
    port: 3000
    protocol: TCP
    targetPort: 3000

  type: NodePort
status: {}

Access the app on browser:在浏览器上访问应用程序:

http://<Host>:32250/index

is your node ip where pod is running.是运行 pod 的节点 IP。 If you have app running in multiple nodes (scaled).如果您的应用程序在多个节点中运行(已缩放)。 It is a NodePort setting on every node.它是每个节点上的 NodePort 设置。 App can be accessed:可以访问应用程序:

http://<Host1>:32250/index
http://<Host2>:32250/index

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM