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

时间:2018-07-21 17:31:59

标签: reactjs docker tomcat kubernetes dockerfile

我正在尝试将Dockerized React应用程序部署到Kubernetes。我相信我已经正确地对其进行了docker化,但是在访问暴露的pod时遇到了问题。

我没有Docker或Kubernetes的经验,因此将不胜感激。

我的React应用只是从Tomcat提供的静态文件(来自npm run build)。

我的Dockerfile在下面。总而言之,我将应用程序放置在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"]

我构建并将Docker映像推送到Private Docker Registry。 我通过这样运行来验证容器是否正常运行:

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

然后,如果我转到localhost:8080,我会看到我的React应用程序的主页。

现在,我遇到的麻烦是部署到Kubernetes并从外部访问该应用程序。

这是我的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

我通过运行创建了部署和服务     kubectl --namespace = dev创建-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>

现在我不知道我应该使用哪个IP和端口来访问该应用程序。 我尝试了每种组合,但没有一个加载我的应用程序。我相信端口应该是80,所以如果我只有IP,我应该能够转到浏览器并通过访问http://来访问React应用。

有人有建议吗?

2 个答案:

答案 0 :(得分:2)

简短的版本是,该服务正在集群(34604)的每个节点上侦听同一TCP / IP端口,如describe service的输出所示:

NodePort:                 <unset>  34604

如果希望通过“ nice” URL访问应用程序,则需要一个负载均衡器,该负载均衡器可以将主机名转换为群集内IP和端口组合。这就是Ingress控制器的设计目的,但这不是唯一的方法-如果您正在Kubernetes知道如何在云环境中运行的环境中,将Service更改为type: LoadBalancer将为您做到这一点以编程方式为您创建负载均衡器。

答案 1 :(得分:0)

我相信您现在已经找到答案了:),因为我正面临这个问题,所以我来到了这里。自我解决,希望对大家有帮助。

以下是可以帮助您的:

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

将服务端口发布为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 :(样本)

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: {}

在浏览器上访问应用程序:

http://<Host>:32250/index

是运行pod的节点ip。 如果您的应用程序在多个节点上运行(已缩放)。它是每个节点上的NodePort设置。 可以访问应用程序:

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