#docker #ubuntu #.net-core
Вопрос:
У меня есть довольно простой контейнер docker, в котором работает приложение .Net Core 5. Файл docker для изображения является:
FROM mcr.microsoft.com/dotnet/runtime:5.0-focal
RUN apt-get update amp;amp; apt-get install -y libgdiplus
WORKDIR /dockercontext
COPY . ./
ENTRYPOINT ["dotnet", "myproject.dll"]
Хост работает под управлением Ubuntu 20.04.
Часть моего приложения имеет простой способ вывода в файл:
public async static Task WriteTextToFileAsync(string fileName, string text, bool append)
{
CreateDirectoryIfNotExists(fileName);
using (StreamWriter outfile = new StreamWriter(fileName, append))
{
await outfile.WriteAsync(text).ConfigureAwait(false);
}
}
Процесс завершается со следующей ошибкой:
[System.UnauthorizedAccessException: Access to the path '/mount/output/Runs/27a02b9a-179d-4794-a9de-8e4153fa0b41/Messages/message.xml' is denied.
---> System.IO.IOException: Permission denied
--- End of inner exception stack trace ---
at System.IO.FileStream.WriteNative(ReadOnlySpan`1 source)
at System.IO.FileStream.FlushWriteBuffer()
at System.IO.FileStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.IO.StreamWriter.CloseStreamFromDispose(Boolean disposing)
at System.IO.StreamWriter.Dispose(Boolean disposing)
at System.IO.TextWriter.Dispose()
at PKTestingSharedLibrary.HelperFunctions.WriteTextToFileAsync(String fileName, String text, Boolean append)
Контейнер docker имеет несколько смонтированных дисков:
sudo docker container create --name worker -v /mount/qzhzntgf6r5uaxjp2vov/prdct-other/prdct-test/configs:/mount/configs -v /mount/qzhzntgf6r5uaxjp2vov/prdct-other/prdct-test/catalogs:/mount/catalogs -v /mount/sgbatchprdctother/output:/mount/output imagename:tag
Эти подключенные диски являются общими файлами хранилища Azure, подключенными к хосту Linux. Я загрузил контейнер docker в работающий контейнер, и я могу записать компакт-диск в папку «Сообщения», и я могу записывать туда простые файлы с помощью bash. Я проверил все запущенные процессы внутри контейнера, и я вижу, что мое приложение работает от имени пользователя root:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 4.5 3582108 184988 ? Ssl Sep02 0:22 dotnet myproject.dll
Я не знаю, что еще попробовать. Мой хост Linux и контейнер docker не работают под управлением SE Linux. Файл создается в указанном месте, но не содержит содержимого.
Ответ №1:
Хорошо, после еще нескольких поисков я наткнулся на эту проблему: https://github.com/dotnet/runtime/issues/42790#issuecomment-817758887
Я столкнулся с этим и не смог изменить весь наш код, который записывает файлы в общие ресурсы CIFS. Я исследовал различные версии ядра, как это произошло после того, как мы обновили ОС на наших хостах. Оказалось, что он был введен в ядре v5.5.1, на самом деле это фиксация: torvalds/linux@d067799. Мне удалось обойти это, установив наши акции cifs с помощью опции nobrl. От https://linux.die.net/man/8/mount.cifs:
nobrl Не отправляет запросы на блокировку диапазона байтов на сервер. Это необходимо для некоторых приложений, которые нарушают обязательные блокировки диапазона байтов в стиле cifs (и большинство серверов cifs еще не поддерживают запрос консультативных блокировок диапазона байтов).
После повторного подключения акций, включая эту опцию, проблема исчезла.
Установка моей общей папки azure с помощью команды nobrl устранила мою проблему.