MySQL Docker文件:sed:无法打开临时文件。

4

我正在尝试创建新的MySQL镜像并在Kubernetes中部署。

FROM oraclelinux:7-slim
USER root
ARG MYSQL_SERVER_PACKAGE=mysql-community-server-minimal-8.0.19
ARG MYSQL_SHELL_PACKAGE=mysql-shell-8.0.19

# Install server
RUN yum install -y https://repo.mysql.com/mysql-community-minimal-release-el7.rpm \
      https://repo.mysql.com/mysql-community-release-el7.rpm \
  && yum-config-manager --enable mysql80-server-minimal \
  && yum install -y \
      $MYSQL_SERVER_PACKAGE \
      $MYSQL_SHELL_PACKAGE \
      libpwquality \
  && yum clean all \
  && mkdir /docker-entrypoint-initdb.d

VOLUME /var/lib/mysql

COPY docker-entrypoint.sh /entrypoint.sh
COPY healthcheck.sh /healthcheck.sh
ENTRYPOINT ["/entrypoint.sh"]
HEALTHCHECK CMD /healthcheck.sh
EXPOSE 3306 33060

RUN chmod +rwx /entrypoint.sh
RUN chmod +rwx /healthcheck.sh

RUN groupadd -r mysql && useradd -r -g mysql mysql

EXPOSE 3306
CMD ["mysqld"]

在容器中正常工作,但是在Kubernetes部署时会报以下错误:

enter image description here

我该如何理解这个问题?

添加内容:

docker-entrypoint.sh:

if [ -n "$MYSQL_LOG_CONSOLE" ] || [ -n "console" ]; then
        # Don't touch bind-mounted config files
        if ! cat /proc/1/mounts | grep "/etc/my.cnf"; then
            sed -i 's/^log-error=/#&/' /etc/my.cnf
        fi
fi

附言:我已经添加了文件的内容。


你能展示一下 entrypoint.sh 脚本的内容吗?显然它使用 sed 执行一些操作,但为什么会有临时文件保存到 /etc 目录中呢?有很多更好的位置可以用,比如 /tmp,这样就不需要特权升级了。 - mario
如果您对Docker有更多的问题,请考虑关注此网站https://area51.stackexchange.com/proposals/124022/docker-container/。 - bjornsing
我已经添加了内容 @mario - Sanjay Chintha
你标签中有 kubernetes 这个词,这意味着你正在 kubernetes 中运行该 docker 镜像,很可能要么挂载了 /etc 卷,要么使用了 securityContext: 切换了容器运行的用户(很可能是你 Dockerfile 中显示的 mysql 用户)。为了得到答案,你需要包含这些相关细节。 - mdaniel
1个回答

6
问题与sed的“原地”编辑实现有关。当您使用-i或--in-place选项编辑文件时,编辑实际上并没有发生在原地。sed将更改保存到临时文件中,然后使用它来替换原始文件。
可能发生这样的情况:您没有写入/etc目录的权限,而sed正试图创建其临时文件。
如建议中所述,最有可能的是该命令由用户mysql运行。毫无疑问,它不是以root身份运行的,因为它具有足够的特权可以写入/etc。
bash-4.2# ls -ld /etc
drwxr-xr-x 1 root root 4096 Mar 27 15:04 /etc

如您所见,others 没有写入权限。更改 /etc 目录的权限或所有者本身是一个非常糟糕的想法,我也不会建议您以 root 用户身份运行此命令。
最简单的解决方案是放弃使用 --in-place 选项,在每个人都可以访问的目录(例如 /tmp)中保存结果。
bash-4.2# ls -ld /tmp
drwxrwxrwt 1 root root 4096 Mar 27 16:39 /tmp

然后用临时文件的内容替换原始文件的内容。

您的命令可能看起来像这样:

sed 's/^log-error=/#&/' /etc/my.cnf > /tmp/my.cnf && cat /tmp/my.cnf > /etc/my.cnf

一个重要的警告:

您需要确保您对/etc/my.cnf文件具有写权限。正如下面所示,默认情况下,您也没有这样的权限,因此当命令尝试写入原始配置文件时,将会出现错误。

bash-4.2# ls -l /etc/my.cnf
-rw-r--r-- 1 root root 1239 Mar 27 15:04 /etc/my.cnf

您需要在您的Dockerfile中进行修改,可以通过使其对所有人可编辑来实现:
RUN chmod 666 /etc/my.cnf

或更好的选择:

RUN chown mysql /etc/my.cnf

将其所有者更改为mysql,如果这是执行entrypoint.sh脚本的用户。请告诉我这是否有帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接