我已经从我自己在 C# 上开发的应用程序运行了一个 docker 容器 mysql,并将数据持久化配置到这个路径:
C:\ProgramData\Persistence\data\mysql
当我开始时一切顺利,因为没有数据(第一次运行)
一旦我开始开发(创建数据库......等等)并且由于某种原因我重新启动了电脑并再次打开docker-desktop并启动容器,它就不再起作用了......
我已经确定问题出在目录权限、只读属性上(我仍在调查原因……):
我已经调查过,并尝试使用以下方法解决:
从CMD:icacls "C:\ProgramData\Persistence" /grant Everyone:(OI)(CI)F /T
表单 PowerShell:Get-ChildItem -Path "C:\ProgramData\Persistence" -Recurse | ForEach-Object { $_.Attributes -= "ReadOnly" }
这些命令是由我的个人用户以具有活动管理员权限并以管理员权限运行 CMD 和 Powershell 执行的。
但问题仍然存在...我找不到编程方式或在 YML 文件中解决它,这是我唯一的兴趣......
日志内容:
2024-04-15 16:31:39+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.3.0-1.el8 started.
2024-04-15 16:31:39+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2024-04-15 16:31:39+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.3.0-1.el8 started.
ln: failed to create symbolic link '/var/lib/mysql/mysql.sock': Permission denied
2024-04-15T16:31:39.941325Z 0 [System] [MY-015015] [Server] MySQL Server - start.
2024-04-15T16:31:40.118455Z 0 [Warning] [MY-010915] [Server] 'NO_ZERO_DATE', 'NO_ZERO_IN_DATE' and 'ERROR_FOR_DIVISION_BY_ZERO' sql modes should be used with strict mode. They will be merged with strict mode in a future release.
2024-04-15T16:31:40.123899Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.3.0) starting as process 1
2024-04-15T16:31:40.127250Z 0 [Warning] [MY-010159] [Server] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive
mysqld: File './binlog.index' not found (OS errno 13 - Permission denied)
2024-04-15T16:31:40.128854Z 0 [ERROR] [MY-010119] [Server] Aborting
2024-04-15T16:31:40.129566Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.3.0) MySQL Community Server - GPL.
2024-04-15T16:31:40.129575Z 0 [System] [MY-015016] [Server] MySQL Server - end.
我已经验证手动更改形状属性可以解决这个问题,但这不是我想要的。
更新 1
我尝试对我的 YML 文件和 docker 文件进行一些更改:
volumes:
- ./data/mysql:/var/lib/mysql:rw
- ./log/mysql:/var/log/mysql:rw
和
RUN mkdir -p /var/log/mysql
RUN chmod -R 0755 /var/lib/mysql /var/log/mysql /etc/mysql
我的期望是这样的一件事能够奏效。
更新 2
我一直在评估,由于某种原因,问题与docker的工作方式和目录结构有关......以及与第三方软件的交互......
问题发生的方式如下:
- 一旦 docker 第一次启动容器和 mysql 内容,一切都会顺利...
- 如果碰巧另一个第三方软件或工具使用或进入持久性数据所在的路径,这些。
- 当您重新启动系统时,它会停止正常工作。好像在第三方应用程序和重新启动之间发生了一些权限问题......这听起来很愚蠢,但似乎那一刻确实发生了一些事情。
这是我的 PS 脚本
我想认为有一种方法可以从构建结构和docker /容器环境的yml中本地解决问题,但到目前为止我还没有解决它...因此我求助于解决这个问题,每次出现这种情况时,您都需要在powershell中手动运行此脚本:
# Define the path to the directory
$directoryPath = "C:\ProgramData\Persistence"
# Get the current ACL (Access Control List) for the directory
$acl = Get-Acl $directoryPath
# Define the permission rule to grant full control to everyone
$permission = "Everyone", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow"
# Create a new access rule
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
# Add the access rule to the ACL
$acl.AddAccessRule($accessRule)
# Set the ACL for the directory
Set-Acl -Path $directoryPath -AclObject $acl
# Check if the permissions were applied successfully
Get-Acl $directoryPath
所以:
虽然这个脚本解决了手动启动/检测的问题,但这不是我期望解决问题的方式,我仍然在寻找一种替代方案防止这个情况。
答案1
我不是 Docker 专家,但是来自联合航空从立场来看,你所遇到的事情对我来说微不足道.ProgramData
是系统文件夹,所有子文件夹和文件都将继承其权限。这意味着,虽然任何进程都可以创建文件,但用户对此类文件只有只读权限。一旦您终止创建文件的进程,此类文件将不再有“所有者/创建者”:从那时起,只有管理员(或系统)可以修改此类文件。
因此,您需要一个管理员帐户,该帐户将您文件的必要权限授予当前用户(或所有用户)。通常,这由安装程序处理(需要管理员权限)。但您的情况是没有安装程序,因此需要额外的脚本。
通过 Docker 处理此问题的第一种方法是需要您的容器以管理员权限运行,但我认为通常情况并非如此。
如果您想避免更改权限,那么可以在ProgramData
文件夹外进行操作:%AppData%
这是进行此类操作的正确位置。
要在 Docker 内部找到解决方案,最好的办法是Stackowflow
答案2
对于在用户模式下运行的程序来说,该文件夹C:\ProgramData
不是最佳选择。如您所见,其权限为:
虽然管理员组具有完全控制权限,但用户组仅对该文件夹具有读取和执行权限。
然而,如果你查看它的子文件夹,你会看到不同的景象。一些子文件夹给予用户组或当前用户完全控制权,而其他子文件夹只给予读取和执行权限。
造成这种差异的原因在于用户是否需要写入此子文件夹或仅从中读取。子文件夹本身由相关产品的安装程序在以管理员身份执行提升模式时创建。安装程序可以为此子文件夹分配所需的任何权限,但不能超过此权限。在标准用户模式下操作的用户不能超出其预期权限。
您的解决方案是执行您已经完成的操作,并在管理员模式下执行时为您自己的子文件夹授予所需的权限。
我强烈建议不要修改文件夹的权限
C:\ProgramData
,因为更改 Windows 安装参数(不同于 Microsoft 设置的参数)可能会在长期内造成问题。此类更改将传播到其他产品的其他子文件夹,从而取消安装程序创建这些子文件夹时所设定的保护。