.NET应用在Docker中运行正常但Kubernetes部署失败
问题
我用一个小型应用测试Kubernetes、Secrets等功能。Docker和docker-compose启动应用完全正常,但部署到Kubernetes时启动失败,提示找不到应用程序dll。
Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base WORKDIR /app EXPOSE 80 EXPOSE 443 FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build WORKDIR /src COPY ["KubernetesTestWithSecrets/KubernetesTestWithSecrets.csproj", "KubernetesTestWithSecrets/"] RUN dotnet restore "KubernetesTestWithSecrets/KubernetesTestWithSecrets.csproj" COPY . . WORKDIR "/src/KubernetesTestWithSecrets" RUN dotnet build "KubernetesTestWithSecrets.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "KubernetesTestWithSecrets.csproj" -c Release -o /app/publish /p:UseAppHost=false FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "/app/KubernetesTestWithSecrets.dll"]
docker-compose.yaml
version: '3.4' services: test: restart: "always" image: privateRepoServerUri:5001/path/kubernetestestwithsecrets:latest ports: - 9443:9443 - 8000:80 volumes: - ./ssl:/ssl:ro
Kubernetes部署配置
apiVersion: apps/v1 kind: Deployment metadata: labels: app: kubernetestestwithsecrets name: kubernetestestwithsecrets spec: replicas: 1 selector: matchLabels: app: kubernetestestwithsecrets template: metadata: labels: app: kubernetestestwithsecrets spec: imagePullSecrets: - name: quay-at-myprivateregistry containers: - name: kubernetestestwithsecrets image: privateRepoServerUri:5001/path/kubernetestestwithsecrets:latest imagePullPolicy: Always volumeMounts: - name: volume-key-pfx mountPath: /app/ssl readOnly: true - name: volume-secret-appsettings-json mountPath: /app/private readOnly: true - name: volume-appsettings-json mountPath: /app readOnly: false restartPolicy: Always volumes: - name: volume-appsettings-json configMap: name: configmap-appsettings.json - name: volume-secret-appsettings-json secret: secretName: secret-secret-appsettings.json - name: volume-key-pfx secret: secretName: secret-key.pfx --- apiVersion: v1 kind: Service metadata: name: kubernetestestwithsecrets-service spec: selector: app: kubernetestestwithsecrets type: LoadBalancer ports: - name: port-80 protocol: TCP port: 80 targetPort: 80 nodePort: 30080 - name: port-443 protocol: TCP port: 443 targetPort: 443 nodePort: 30443
错误日志
执行kubectl logs kubernetestestwithsecrets-<随机后缀>得到:
The command could not be loaded, possibly because: * You intended to execute a .NET application: The application '/app/KubernetesTestWithSecrets.dll' does not exist. * You intended to execute a .NET SDK command: No .NET SDKs were found. Download a .NET SDK: https://aka.ms/dotnet/download Learn about SDK resolution: https://aka.ms/dotnet/sdk-not-found
排查操作
已确认镜像拉取正常,容器内文件存在,在minikube ssh中执行以下操作验证:
镜像历史
IMAGE CREATED CREATED BY SIZE COMMENT sha256:d6ad638d95ae5cb2c34b7f0ec51a20db177b55559b14ccdfebbf7ded540a690a About an hour ago ENTRYPOINT ["dotnet" "/app/KubernetesTestWithSecrets.dll"] 0B buildkit.dockerfile.v0 <missing> About an hour ago COPY /app/publish . # buildkit 3.84MB buildkit.dockerfile.v0 <missing> 4 days ago WORKDIR /app 0B buildkit.dockerfile.v0 <missing> 4 days ago EXPOSE map[443/tcp:{}] 0B buildkit.dockerfile.v0 <missing> 4 days ago EXPOSE map[80/tcp:{}] 0B buildkit.dockerfile.v0 <missing> 4 days ago WORKDIR /app 0B buildkit.dockerfile.v0 <missing> 12 days ago /bin/sh -c #(nop) COPY dir:92bf025ac6ae2fcccb56b9250069db943d8934aa484232b9e95ab8719fbda315 in /usr/share/dotnet/shared/Microsoft.AspNetCore.App 21.8MB <missing> 12 days ago /bin/sh -c #(nop) ENV ASPNET_VERSION=7.0.5 0B <missing> 12 days ago /bin/sh -c ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet 24B <missing> 12 days ago /bin/sh -c #(nop) COPY dir:d047d158ec6d05333fed3029665c06808b52d4d8225a0c71387ffeda7735c7bb in /usr/share/dotnet 73.2MB <missing> 12 days ago /bin/sh -c #(nop) ENV DOTNET_VERSION=7.0.5 0B <missing> 12 days ago /bin/sh -c #(nop) ENV ASPNETCORE_URLS=http://+:80 DOTNET_RUNNING_IN_CONTAINER=true 0B <missing> 12 days ago /bin/sh -c apt-get update && apt-get install -y --no-install-recommends ca-certificates libc6 libgcc1 libgssapi-krb5-2 libicu67 libssl1.1 libstdc++6 zlib1g && rm -rf /var/lib/apt/lists/* 37MB <missing> 12 days ago /bin/sh -c #(nop) CMD ["bash"] 0B <missing> 12 days ago /bin/sh -c #(nop) ADD file:11b1acca3f68b5c5787e292ff8dbdd114964a7272bf3519ab07710cbc01a0838 in /
验证容器内文件
执行docker create --name="tmp_$$" privateRepoServer:5001/path/kubernetestestwithsecrets后,执行docker export tmp_$$ | tar -t |grep app得到:
app/KubernetesTestWithSecrets.deps.json app/KubernetesTestWithSecrets.dll app/KubernetesTestWithSecrets.pdb app/KubernetesTestWithSecrets.runtimeconfig.json app/Microsoft.AspNetCore.OpenApi.dll app/Microsoft.OpenApi.dll app/Swashbuckle.AspNetCore.Swagger.dll app/Swashbuckle.AspNetCore.SwaggerGen.dll app/Swashbuckle.AspNetCore.SwaggerUI.dll app/appSettings.Development.json app/web.config
执行docker export tmp_$$ | tar -t |grep 7.0.5返回大量.NET库文件。
解决方案
问题出在Kubernetes部署中的volumeMounts配置:你将volume-appsettings-json这个ConfigMap直接挂载到了/app目录,这会覆盖容器镜像中原有的/app目录内容——原本存在的KubernetesTestWithSecrets.dll被ConfigMap的内容替换,自然找不到文件。
修复步骤
- 修改Deployment中的
volumeMounts配置,不要直接挂载到/app,而是挂载到/app下的子目录,比如/app/config:volumeMounts: - name: volume-key-pfx mountPath: /app/ssl readOnly: true - name: volume-secret-appsettings-json mountPath: /app/private readOnly: true - name: volume-appsettings-json mountPath: /app/config # 修改为子目录 readOnly: false - 确保.NET应用能读取该子目录下的配置文件,可通过两种方式实现:
- 修改应用代码,指定配置文件加载路径;
- 在容器启动时设置环境变量或通过
dotnet命令参数指定配置路径。
另外,需确认ConfigMap中包含正确的appsettings.json内容,保证应用能正常加载配置。
内容的提问来源于stack exchange,提问作者Rachel Ambler
相关产品推荐
相关产品推荐

