В разрешении контейнера Ubuntu Docker Отказано в написании потока

#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 устранила мою проблему.