简体   繁体   English

将 blazor 服务器应用程序部署到 Kubernetes 时出现问题

[英]Problem with deploying blazor server app to Kubernetes


Lately I am trying to do a test deploy of a Blazor server app on locally hosted Kubernetes instance running on docker desktop.最近,我正在尝试在 docker 桌面上运行的本地托管 Kubernetes 实例上测试部署 Blazor 服务器应用程序。

I managed to correctly spin up the app in a container, migrations were applied etc, logs are telling me that the app is running and waiting:我设法在容器中正确启动应用程序,应用迁移等,日志告诉我应用程序正在运行并等待:

[17:54:39 INF] Starting up... [17:54:39 INF] 正在启动...

[17:54:39 WRN] Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. [17:54:39 WRN] 将密钥存储在目录“/root/.aspnet/DataProtection-Keys”中,该目录可能不会保留在容器外。 Protected data will be unavailable when container is destroyed.当容器被销毁时,受保护的数据将不可用。

[17:54:40 WRN] No XML encryptor configured. [17:54:40 WRN] 未配置 XML 加密器。 Key {9d879e73-4b80-4e63-8761-7ad2922164a0} may be persisted to storage in unencrypted form.密钥 {9d879e73-4b80-4e63-8761-7ad2922164a0} 可能以未加密的形式保存到存储中。

[17:54:40 INF] AuthorizationPolicy Configuration started... [17:54:40 INF] AuthorizationPolicy 配置开始...

[17:54:40 INF] Policy 'LocationMustBeSady' was configured successfully. [17:54:40 INF] 策略“LocationMustBeSady”已成功配置。

[17:54:40 INF] AuthorizationPolicy Configuration completed. [17:54:40 INF] AuthorizationPolicy 配置完成。

[17:54:41 INF] Now listening on: http://[::]:80 [17:54:41 INF] 现在收听:http://[::]:80

[17:54:41 INF] Application started. [17:54:41 INF] 应用程序已启动。 Press Ctrl+C to shut down.按 Ctrl+C 关闭。

[17:54:41 INF] Hosting environment: Production [17:54:41 INF] 托管环境:生产

[17:54:41 INF] Content root path: /app [17:54:41 INF] 内容根路径:/app

The problem is when I am trying to connect from the local machine to said application using address set up in hosts file ( 127.0.0.1 scp.com )问题是当我尝试使用hosts文件中设置的地址( 127.0.0.1 scp.com )从本地计算机连接到所述应用程序时

My current settings are as follows:我目前的设置如下:

Application Dockerfile (builds fine):应用程序 Dockerfile(构建良好):

# https://hub.docker.com/_/microsoft-dotnet
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /source
EXPOSE 5000
EXPOSE 5001
EXPOSE 5005
EXPOSE 80
EXPOSE 443
ENV ASPNETCORE_ENVIRONMENT="docker"

LABEL name="ScanApp"

# copy csproj and restore as distinct layers
COPY ScanApp/*.csproj ScanApp/
COPY ScanApp.Application/*.csproj ScanApp.Application/
COPY ScanApp.Common/*.csproj ScanApp.Common/
COPY ScanApp.Domain/*.csproj ScanApp.Domain/
COPY ScanApp.Infrastructure/*.csproj ScanApp.Infrastructure/
COPY ScanApp.Tests/*.csproj ScanApp.Tests/
RUN dotnet restore ScanApp/ScanApp.csproj

# copy and build app and libraries
COPY ScanApp/ ScanApp/
COPY ScanApp.Application/ ScanApp.Application/
COPY ScanApp.Common/ ScanApp.Common/
COPY ScanApp.Domain/ ScanApp.Domain/
COPY ScanApp.Infrastructure/ ScanApp.Infrastructure/
COPY ScanApp.Tests/ ScanApp.Tests/
WORKDIR /source/ScanApp
RUN dotnet build -c release --no-restore

# test stage -- exposes optional entrypoint
# target entrypoint with: docker build --target test
FROM build AS test
WORKDIR /source/ScanApp.Tests
COPY tests/ .
ENTRYPOINT ["dotnet", "test", "--logger:trx"]

FROM build AS publish
RUN dotnet publish -c release --no-build -o /app

# final stage/image
# FROM mcr.microsoft.com/dotnet/runtime:5.0
FROM mcr.microsoft.com/dotnet/aspnet:5.0
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "ScanApp.dll"]

Kubernetes deployment for said app plus cluster ip - scanapp-depl.yaml : Kubernetes 部署用于所述应用程序加集群 ip - scanapp-depl.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
    name: scanapp-depl
spec:
    replicas: 1
    selector:
        matchLabels:
            app: scanapp
    template:
        metadata:
            labels:
                app: scanapp
        spec:
            containers:
                - name: scanapp
                  image: scanapp:1.0
---
apiVersion: v1
kind: Service
metadata:
    name: scanapp-clusterip-srv
spec:
    type: ClusterIP
    selector:
        app: scanapp
    ports:
        - name: ui
          protocol: TCP
          port: 8080
          targetPort: 80
        - name: ui2
          protocol: TCP
          port: 8081
          targetPort: 443
        - name: scanapp0
          protocol: TCP
          port: 5000
          targetPort: 5000
        - name: scanapp1
          protocol: TCP
          port: 5001
          targetPort: 5001
        - name: scanapp5
          protocol: TCP
          port: 5005
          targetPort: 5005

NodePort config - scanapp-np-srv.yaml NodePort 配置 - scanapp-np-srv.yaml

apiVersion: v1
kind: Service
metadata:
    name: scanappnpservice-srv
spec:
    type: NodePort
    selector:
        app: scanapp
    ports:    
        - name: ui
          port: 8080
          targetPort: 80
        - name: scanapp0
          protocol: TCP
          port: 5000
          targetPort: 5000
        - name: scanapp1
          protocol: TCP
          port: 5001
          targetPort: 5001
        - name: scanapp5
          protocol: TCP
          port: 5005
          targetPort: 5005

Ingress config - ingress-srv.yaml :入口配置 - ingress-srv.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-srv
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /    
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "affinity"
    nginx.ingress.kubernetes.io/session-cookie-expires: "14400"
    nginx.ingress.kubernetes.io/session-cookie-max-age: "14400"
spec:
  rules:
      - host: scp.com
        http:
            paths:
            - path: /
              pathType: Prefix
              backend:
                service:
                  name: scanapp-clusterip-srv
                  port:
                    number: 8080

In addition, there is also working sql server config with cluster ip and load balancer:此外,还有带有集群 ip 和负载均衡器的sql服务器配置:

apiVersion: apps/v1
kind: Deployment
metadata:
    name: mssql-depl
spec:
    replicas: 1
    selector:
        matchLabels:
            app: mssql
    template:
        metadata:
            labels:
                app: mssql
        spec:
            containers:
                - name: mssql
                  image: mcr.microsoft.com/mssql/server:2019-latest
                  ports:
                      - containerPort: 1433
                  env:
                      - name: MSSQL_PID
                        value: "Express"
                      - name: ACCEPT_EULA
                        value: "Y"
                      - name: SA_PASSWORD
                        valueFrom:
                            secretKeyRef:
                                name: mssql
                                key: SA_PASSWORD
                  volumeMounts:
                      - mountPath: /var/opt/mssql/data
                        name: mssqldb
            volumes:
                - name: mssqldb
                  persistentVolumeClaim:
                      claimName: mssql-claim
---
apiVersion: v1
kind: Service
metadata:
    name: mssql-clusterip-srv
spec:
    type: ClusterIP
    selector:
        app: mssql
    ports:
        - name: mssql
          protocol: TCP
          port: 1433
          targetPort: 1433
---
apiVersion: v1
kind: Service
metadata:
    name: mssql-loadbalancer
spec:
    type: LoadBalancer
    selector:
        app: mssql
    ports:        
        - protocol: TCP
          port: 1433
          targetPort: 1433

As stated in the beginning - I cannot, for the love of all, get into my blazor app from browser - I tried如开头所述 - 为了所有人的爱,我不能从浏览器进入我的 blazor 应用程序 - 我试过了

  • scp.com scp.com
  • scp.com:8080 scp.com:8080
  • scp.com:5000 scp.com:5000
  • scp.com:5001 scp.com:5001
  • scp.com:5005 scp.com:5005

Nothing seems to work, so there must be something wrong with my config files and I have no idea what could it be.似乎没有任何效果,所以我的配置文件一定有问题,我不知道可能是什么。

And just to be precise, additional details: Docker desktop is running along with Kubernetes准确地说,附加详细信息: Docker 桌面与 Kubernetes 一起运行

kubectl get ingress output: kubectl get ingress output:

NAME姓名 CLASS CLASS HOSTS主机 ADDRESS地址 PORTS端口 AGE年龄
ingress-srv入口-srv scp.com scp.com localhost本地主机 80 80 3h58m 3h58m



kubectl get pods output: kubectl get pods output:

NAME姓名 READY准备好 STATUS地位 RESTARTS重启 AGE年龄
mssql-depl-7f46b5c696-nc6cw mssql-depl-7f46b5c696-nc6cw 1/1 1/1 Running跑步 0 0 157m 157m
scanapp-depl-76f56bc6df-nstfd scanapp-depl-76f56bc6df-nstfd 1/1 1/1 Running跑步 0 0 73m 73m



kubectl get deployments output kubectl get deployments output

NAME姓名 READY准备好 UP-TO-DATE最新 AVAILABLE可用的 AGE年龄
mssql-depl mssql-depl 1/1 1/1 1 1 1 1 171m 171m
scanapp-depl扫描应用程序-depl 1/1 1/1 1 1 1 1 75m 75m



kubectl get services output: kubectl get services output:

NAME姓名 TYPE类型 CLUSTER-IP集群IP EXTERNAL-IP外部IP PORT(S)端口 AGE年龄
kubernetes kubernetes ClusterIP集群IP 10.96.0.1 10.96.0.1 443/TCP 443/TCP 28d 28天
mssql-clusterip-srv mssql-clusterip-srv ClusterIP集群IP 10.111.202.104 10.111.202.104 1433/TCP 1433/TCP 3h 3小时
mssql-loadbalancer mssql-负载均衡器 LoadBalancer负载均衡器 10.110.249.54 10.110.249.54 localhost本地主机 1433:30786/TCP 1433:30786/TCP 3h 3小时
scanapp-clusterip-srv scanapp-clusterip-srv ClusterIP集群IP 10.97.75.150 10.97.75.150 8080/TCP,8081/TCP,5000/TCP,5001/TCP,5005/TCP 8080/TCP,8081/TCP,5000/TCP,5001/TCP,5005/TCP 4h33m 4h33m
scanappnpservice-srv scanappnpservice-srv NodePort节点端口 10.103.33.184 10.103.33.184 8080:32119/TCP 8080:32119/TCP 4h46m 4h46m

First, you don't need a NodePort service, just a ClusterIP .首先,您不需要NodePort服务,只需要一个ClusterIP Nodeports are used if you want to access the service directly without going through the ingress controller.如果您想直接访问服务而不通过入口 controller,则使用节点端口。

In case you want to test this with a NodePort , you will need to define one, eg如果您想使用NodePort对此进行测试,则需要定义一个,例如

- name: ui
  port: 8080
  targetPort: 80
  nodePort: 38080  # needs to be higher than 30000

But looking at your ingress rule it seems a bit off.但看看你的入口规则,它似乎有点不对劲。 I would try the following:我会尝试以下方法:

spec:
  rules:
    - host: scp.com
      http:
        paths:
          - path: /
            backend:
              serviceName: scanapp-clusterip-srv
              servicePort: ui

I solved the problem, or at least I think so.我解决了这个问题,或者至少我是这么认为的。
In addition to @moonkotte suggestion to add the ingressClassName: nginx to ingress-srv.yaml I also changed the ingress port configuration so that it points to port 80 now.除了@moonkotte建议添加ingressClassName: nginxingress-srv.yaml我还更改了入口端口配置,使其现在指向端口80

Thanks to those changes using scp.com now correctly opens my app.感谢使用scp.com进行的这些更改,现在可以正确打开我的应用程序。 Also, using NodePort access I can visit my app using localhost:30080 , where the 30080 port was set automatically (I removed the nodePort configuration line from scanapp-np-srv.yaml )此外,使用 NodePort 访问,我可以使用localhost:30080访问我的应用程序,其中 30080 端口是自动设置的(我从scanapp-np-srv.yaml中删除了nodePort配置行)

Why does the port in ingress-srv.yaml have to be set to 80 if clusterIp configuration states to set port 8080 to target port 80 - I don't know, I do not fully understand the inner workings of Kubernetes configuration - All explanations are more than welcome.如果clusterIp配置状态将端口8080设置为目标端口80 ,为什么ingress-srv.yaml中的端口必须设置为 80 - 我不知道,我不完全了解 Kubernetes 配置的内部工作原理 -所有解释都是热烈欢迎。

Current state of main configuration files:当前state的主要配置文件:

ingress-srv.yaml : ingress-srv.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-srv
  annotations:  
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "affinity"
    nginx.ingress.kubernetes.io/session-cookie-expires: "14400"
    nginx.ingress.kubernetes.io/session-cookie-max-age: "14400"
spec:
  ingressClassName: nginx
  rules:
      - host: scp.com
        http:
            paths:
            - path: /
              pathType: Prefix
              backend:
                service:
                  name: scanapp-clusterip-srv
                  port:
                    number: 80



scanapp-np-srv.yaml : scanapp-np-srv.yaml

apiVersion: v1
kind: Service
metadata:
    name: scanappnpservice-srv
spec:
    type: NodePort
    selector:
        app: scanapp
    ports:    
        - name: ui
          port: 8080
          targetPort: 80
        - name: scanapp0
          protocol: TCP
          port: 5000
          targetPort: 5000
        - name: scanapp1
          protocol: TCP
          port: 5001
          targetPort: 5001
        - name: scanapp5
          protocol: TCP
          port: 5005
          targetPort: 5005



scanapp-depl.yaml : scanapp-depl.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
    name: scanapp-depl
spec:
    replicas: 1
    selector:
        matchLabels:
            app: scanapp
    template:
        metadata:
            labels:
                app: scanapp
        spec:
            containers:
                - name: scanapp
                  image: scanapp:1.0
---
apiVersion: v1
kind: Service
metadata:
    name: scanapp-clusterip-srv
spec:
    type: ClusterIP
    selector:
        app: scanapp
    ports:
        - name: ui
          protocol: TCP
          port: 8080
          targetPort: 80
        - name: ui2
          protocol: TCP
          port: 8081
          targetPort: 443
        - name: scanapp0
          protocol: TCP
          port: 5000
          targetPort: 5000
        - name: scanapp1
          protocol: TCP
          port: 5001
          targetPort: 5001
        - name: scanapp5
          protocol: TCP
          port: 5005
          targetPort: 5005

Rest of files remained untouched. Rest 文件保持不变。

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

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