我正在尝试配置Docker容器,以便可以ssh进入它(该容器将在Azure上运行)。我设法创建了一个镜像,该镜像使用户可以ssh到从该镜像创建的容器中,Dockerfile看起来像这样(不是我的,我在互联网上找到了它):
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
EXPOSE 2222
RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd
COPY sshd_config /etc/ssh
RUN echo 'root:Docker' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile
CMD ["/usr/sbin/sshd", "-D"]
我正在使用
mcr.microsoft.com/dotnet/core/sdk:2.2-stretch
,因为这是以后运行该应用程序所需要的。有了上面的Dockerfile,我运行
docker build . -t ssh
。我可以确认可以通过以下说明将ssh放入从ssh
图像创建的容器中:docker run -d -p 0.0.0.0:2222:22 --name ssh ssh
ssh root@localhost -p 2222
我的应用程序的Dockerfile:
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src
COPY ["Application.WebAPI/Application.WebAPI.csproj", "Application.WebAPI/"]
COPY ["Processing.Dependency/Processing.Dependency.csproj", "Processing.Dependency/"]
COPY ["Processing.QueryHandling/Processing.QueryHandling.csproj", "Processing.QueryHandling/"]
COPY ["Model.ViewModels/Model.ViewModels.csproj", "Model.ViewModels/"]
COPY ["Core.Infrastructure/Core.Infrastructure.csproj", "Core.Infrastructure/"]
COPY ["Model.Values/Model.Values.csproj", "Model.Values/"]
COPY ["Sql.Business/Sql.Business.csproj", "Sql.Business/"]
COPY ["Model.Events/Model.Events.csproj", "Model.Events/"]
COPY ["Model.Messages/Model.Messages.csproj", "Model.Messages/"]
COPY ["Model.Commands/Model.Commands.csproj", "Model.Commands/"]
COPY ["Sql.Common/Sql.Common.csproj", "Sql.Common/"]
COPY ["Model.Business/Model.Business.csproj", "Model.Business/"]
COPY ["Processing.MessageBus/Processing.MessageBus.csproj", "Processing.MessageBus/"]
COPY [".Processing.CommandHandling/Processing.CommandHandling.csproj", "Processing.CommandHandling/"]
COPY ["Processing.EventHandling/Processing.EventHandling.csproj", "Processing.EventHandling/"]
COPY ["Sql.System/Sql.System.csproj", "Sql.System/"]
COPY ["Application.Common/Application.Common.csproj", "Application.Common/"]
RUN dotnet restore "Application.WebAPI/Application.WebAPI.csproj"
COPY . .
WORKDIR "/src/Application.WebAPI"
RUN dotnet build "Application.WebAPI.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "Application.WebAPI.csproj" -c Release -o /app
FROM ssh AS final
WORKDIR /app
EXPOSE 80
EXPOSE 443
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Application.WebApi.dll"]
如您所见,在最后阶段,我将
ssh
图像用作基础图像。即使我能够将其引导到由ssh
镜像创建的容器中,也无法将其引导至由后者的Dockerfile创建的容器中。这是我正在使用的docker-compose.yml,以便于启动容器:version: '3.7'
services:
application.webapi:
image: application.webapi
container_name: webapi
ports:
- "0.0.0.0:5000:80"
- "0.0.0.0:2222:22"
build:
context: .
dockerfile: Application.WebAPI/Dockerfile
environment:
- ASPNETCORE_ENVIRONMENT=docker
当我运行
docker exec -it webapi bash
并执行service ssh status
时,我会得到[FAIL] sshd is not running ... failed!
-但是当我执行service ssh start
并尝试将其放入该容器时,它可以工作。不幸的是,这种方法是 Not Acceptable ,ssh守护程序应该在启动时启动。我尝试使用debian上提供的cron和其他功能,但它是一个 slim 的版本,而systemd在那里不可用-我也不喜欢在 slim 的版本上安装数百个东西。
您有什么想法在这里可能出什么问题吗?
最佳答案
您的最终镜像中的启动命令定义有冲突。请注意,CMD
不仅在图像中运行命令,它还定义了启动命令,并且与ENTRYPOINT
有复杂的交互作用(简而言之:如果两者都存在,CMD
只会为ENTRYPOINT
提供额外的参数)。
您可以在Dockerfile文档中查看可能性表:https://docs.docker.com/engine/reference/builder/。另外,当在不同的层中混合并匹配CMD
和ENTRYPOINT
时,会带来额外的复杂性:
Note: If CMD is defined from the base image, setting ENTRYPOINT will reset CMD to an empty value. In this scenario, CMD must be defined in the current image to have a value.
据我所知,仅通过分层图像就无法获得想要的东西。您将需要在最终镜像中创建一个启动脚本,该脚本同时运行
sshd -D
然后运行dotnet Application.WebApi.dll
。
关于docker - Docker-ASP.CORE 2.2应用程序和SSH,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58392649/