You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker镜像AKS启动失败:DLL丢失问题排查求助

问题:Docker构建.NET 8镜像部署AKS后缺失目标DLL

我无法定位问题原因,需要帮忙排查:用以下Dockerfile构建.NET 8镜像时,Azure DevOps Pipeline构建任务中的RUN ls命令显示/app目录包含预期文件,但镜像部署到AKS后,容器启动提示找不到指定DLL。替换ENTRYPOINT查看/app目录,发现仅存在符号链接和appsettings.json,目标DLL缺失。


相关配置及信息

Dockerfile

ARG base_image=mcr.microsoft.com/dotnet/runtime
ARG base_image_version=8.0
ARG port=80
# Use a runtime image as the base image
#FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
FROM ${base_image}:${base_image_version} AS runtime
# The name of DLL which needs to be used for starting the application
ARG DLL_NAME
ENV env_dll_name=${DLL_NAME}

# Set the working directory in the container
WORKDIR /app

# Copy the published application files
COPY --chown=$APP_UID:$APP_UID . ./

# Change ownership of the files to the dedicated user
RUN chown -R $APP_UID:$APP_UID /app

# Switch to the dedicated user
USER $APP_UID

# List the contents of the /app directory to verify the files copied
RUN ls -la /app

# List the DLL to be executed
RUN echo "DLL to execute: ${env_dll_name}"
# Expose the port that the application will listen on
EXPOSE ${port}

RUN ls -la .

# Define the entry point for the container
ENTRYPOINT ["sh", "-c", "dotnet ${env_dll_name}"]

Azure DevOps Pipeline构建任务

- script: |
    pwd
    ls -la .
    ls -la $(Build.ArtifactStagingDirectory)
    ls -la $(Build.ArtifactStagingDirectory)/PublishOutput

- task: Docker@2  
  displayName: 'Docker - Build'  
  inputs:
    command: build
    #containerRegistry: $(ACR_LOGIN_SERVER)
    repository: $(ACR_LOGIN_SERVER)/$(dockerImageName)
    Dockerfile: '$(Build.Repository.LocalPath)/Dockerfile'  # Path to your Dockerfile
    buildContext: '$(Build.ArtifactStagingDirectory)/PublishOutput'
    arguments: '--progress=plain --build-arg DLL_NAME=$(project_name).dll'
    tags: |-
      $(releaseVersion)
      latest

.NET发布步骤

- task: DotNetCoreCLI@2
  inputs:
    command: 'publish'
    projects: |
      **/*.csproj
      !**/*Test.csproj
      !**/*Tests.csproj
    arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/PublishOutput'
    zipAfterPublish: false
    modifyOutputPath: false
    publishWebProjects: false
  displayName: 'dotnet - Publish Project'

替换ENTRYPOINT后/app目录内容

drwxrwxrwx 3 root root 4096 Jul  8 17:37 .
drwxr-xr-x 1 root root 4096 Jul  9 04:38 ..
drwxr-xr-x 2 root root 4096 Jul  8 17:37 ..2024_07_08_17_37_44.4116578998
lrwxrwxrwx 1 root root   32 Jul  8 17:37 ..data -> ..2024_07_08_17_37_44.4116578998
lrwxrwxrwx 1 root root   23 Jul  8 17:37 appsettings.json -> ..data/appsettings.json

排查及解决方案

1. 检查APP_UID变量定义

Dockerfile中使用了$APP_UID但未定义该变量(无ARG/ENV声明),会导致COPY --chown和chown命令执行异常,可能造成文件复制不完整或权限错误。

  • 解决:在Dockerfile开头添加ARG APP_UID=10001(指定你需要的用户ID),或构建时通过--build-arg APP_UID=xxx传入参数。

2. 排查AKS部署的Volume挂载

从/app目录的符号链接结构(..data)来看,大概率是AKS Deployment将ConfigMap/Secret挂载到了/app目录,覆盖了镜像中原有的文件。

  • 解决:检查Deployment的YAML配置,确认是否存在挂载到/app的volumeMounts,修改挂载路径为/app/config等子目录,避免覆盖整个/app。

3. 验证镜像实际内容

构建时的RUN ls仅在构建阶段有效,需确认镜像实际内容:

# 拉取镜像
docker pull <你的镜像地址>:latest
# 运行容器查看目录
docker run -it --rm <你的镜像地址>:latest sh
# 进入容器后执行
ls -la /app

如果容器内无DLL,说明构建过程有问题;如果有,则是AKS部署配置导致文件被覆盖。

4. 优化Dockerfile的权限流程

调整文件复制、用户创建、权限修改的顺序,避免权限问题:

ARG base_image=mcr.microsoft.com/dotnet/runtime
ARG base_image_version=8.0
ARG port=80
ARG APP_UID=10001
ARG DLL_NAME

FROM ${base_image}:${base_image_version} AS runtime

ENV env_dll_name=${DLL_NAME}
WORKDIR /app

# 先以root身份复制文件
COPY . ./

# 创建专用用户(若基础镜像不存在)
RUN useradd -u $APP_UID -m appuser

# 修改文件权限
RUN chown -R $APP_UID:$APP_UID /app

# 切换用户
USER $APP_UID

RUN ls -la /app
RUN echo "DLL to execute: ${env_dll_name}"
EXPOSE ${port}

# 直接使用dotnet作为入口,无需sh -c
ENTRYPOINT ["dotnet", "${env_dll_name}"]

内容的提问来源于stack exchange,提问作者Jörg Lang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 03:10:59