为什么部署到K8s时找不到bash文件?

为什么部署到K8s时找不到bash文件?,bash,docker,kubernetes,Bash,Docker,Kubernetes,我有一个dockerfile,其中一个自定义SQL server 2019安装运行一个bash脚本,该脚本反过来调用另一个bash脚本: FROM mcr.microsoft.com/mssql/server:2019-CU8-ubuntu-16.04 ARG BuildConfiguration=Debug USER root # Install Unzip RUN apt-get update \ && apt-get install unzip -y # In

我有一个dockerfile,其中一个自定义SQL server 2019安装运行一个bash脚本,该脚本反过来调用另一个bash脚本:

FROM mcr.microsoft.com/mssql/server:2019-CU8-ubuntu-16.04 
ARG BuildConfiguration=Debug

USER root
# Install Unzip
RUN apt-get update \
    && apt-get install unzip -y

# Install SQLPackage for Linux and make it executable
RUN wget -progress=bar:force -q -O sqlpackage.zip https://go.microsoft.com/fwlink/?linkid=2143497 \
    && unzip -qq sqlpackage.zip -d /opt/sqlpackage \
    && chmod +x /opt/sqlpackage/sqlpackage

USER mssql

# Create a config directory
RUN mkdir -p /usr/config
WORKDIR /usr/config

# Copy required source files
COPY entrypoint.sh /usr/config
COPY configure-db.sh /usr/config
COPY setup.sql /usr/config
COPY PrepareServer.sql /usr/config
COPY tSQLt.class.sql /usr/config
# Copy the dacpac, that we will be deploying. Make sure the project has built before you run the dockerfile!
COPY ./bin/${BuildConfiguration}/Database.dacpac /usr/config

ENTRYPOINT ["/bin/bash", "./entrypoint.sh"]

CMD ["tail -f /dev/null"]

HEALTHCHECK --interval=15s CMD /opt/mssql-tools/bin/sqlcmd -U sa -P $MSSQL_SA_PASSWORD -Q "select 1" && grep -q "MSSQL CONFIG COMPLETE" ./config.log
entrypoint.sh:

#!/bin/bash

/opt/mssql/bin/sqlservr &

/bin/bash /usr/config/configure-db.sh

eval $1
configure-db.sh:

#!/bin/bash
# wait for MSSQL server to start
export STATUS=1
i=0

while [[ $STATUS -ne 0 ]] && [[ $i -lt 30 ]]; do
    i=$i+1
    /opt/mssql-tools/bin/sqlcmd -t 1 -U sa -P $MSSQL_SA_PASSWORD -Q "select 1" >> /dev/null
    STATUS=$?
done

if [ $STATUS -ne 0 ]; then 
    echo "Error: MSSQL SERVER took more than thirty seconds to start up."
    exit 1
fi

echo "======= MSSQL SERVER STARTED ========"
# Run the setup script to create the DB and the schema in the DB
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $MSSQL_SA_PASSWORD -d master -i setup.sql
#install the tSQLt CLR for testing
echo "======= PREPARING FOR tSQLt ========"
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $MSSQL_SA_PASSWORD -d master -i PrepareServer.sql
echo "======= PREPARATION FOR tSQLt FINISHED ========"
echo "======= INSTALLING tSQLt ========"
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $MSSQL_SA_PASSWORD -d master -i tSQLt.class.sql
echo "======= INSTALLING tSQLt FINISHED========"

echo "======= Starting Deployment of Dacpac ========"
/opt/sqlpackage/sqlpackage /a:Publish /tsn:. /tdn:${MSSQL_DB} /tu:sa /tp:$MSSQL_SA_PASSWORD /sf:/usr/config/Database.dacpac

echo "======= Finished Deployment of Dacpac ========"
echo "======= MSSQL CONFIG COMPLETE ======="
然后将其部署到Kuberenetes,但在启动时,我会在日志中看到以下行:

./entrypoint.sh: line 2: $'\r': command not found
./entrypoint.sh: line 3: $'\r': command not found
./entrypoint.sh: line 4: $'\r': command not found
: No such file or directoryigure-db.sh
./entrypoint.sh: line 6: $'\r': command not found
我在记事本++和VSC中搜索了回车,但没有找到。记事本以及VSC显示,表明EOL设置为Unix(LF)

我已尝试在pod中使用bash手动运行configure-db.sh文件,并收到以下输出:

mssql@sql-dev:/usr/config$ /bin/bash configure-db.sh 
configure-db.sh: line 5: $'\r': command not found
configure-db.sh: line 33: syntax error: unexpected end of file
奇怪的是,与docker compose一起运行此功能可以完美地工作。我有什么地方做错了吗

更新 为了确保这一点,我没有意外地忽略任何事情,我继续进行,打开了WSL/Ubuntu上的解决方案文件夹,创建了一个entrypoint2.sh,其中包含
sudo chown+x./entrypoint2.sh
,并在dockerfile中引用了它。我确保行的结尾确实是LF/
\n
而不是CR-LF,然后检入文件并部署它。此外,我再次通过
dos2unix
运行该文件

结果是一样的。它使用docker compose工作,但使用Kubernetes时抛出错误:

./entrypoint2.sh: line 2: $'\r': command not found
./entrypoint2.sh: line 4: $'\r': command not found
./entrypoint2.sh: line 5: $'\r': command not found
: No such file or directoryusr/config/configure-db.sh
./entrypoint2.sh: line 7: $'\r': command not found

错误不是没有找到bash,而是没有找到
\r
。这表示您已使用Windows linefeed保存脚本,并尝试在Linux平台上运行该脚本。从编辑器中,使用Linux换行符(LF,而不是CR-LF)保存脚本。或者您可以使用dos2unix之类的工具从脚本中删除回车。

错误不是找不到bash,而是找不到
\r
。这表示您已使用Windows linefeed保存脚本,并尝试在Linux平台上运行该脚本。从编辑器中,使用Linux换行符(LF,而不是CR-LF)保存脚本。或者,您可以使用dos2unix之类的工具从脚本中删除回车符。

我已尝试在其上构建解决方案

  • 视窗10
  • Ubuntu 20.04
在这两种情况下,结果都很好。所以我排除了这种可能性,即它是开发机器上配置错误的git安装

这让我只能把我们的CI/CD管道作为可能的罪犯。因此,我创建了一个包含以下内容的
.gittributes
文件:

*.sh text eol=lf
解决了这个问题。文件现在已被签出并正确复制。运行时不再出现错误

作为替代方案,总是有可能在K8s上创建一个initContainer来安装dos2unix并修复那里的文件,但这感觉不那么优雅,更像是使用nukes猎兔


非常感谢BMitch给我提供建议,让我检查容器中的文件,而不仅仅是源文件。

我已尝试在其上构建解决方案

  • 视窗10
  • Ubuntu 20.04
在这两种情况下,结果都很好。所以我排除了这种可能性,即它是开发机器上配置错误的git安装

这让我只能把我们的CI/CD管道作为可能的罪犯。因此,我创建了一个包含以下内容的
.gittributes
文件:

*.sh text eol=lf
解决了这个问题。文件现在已被签出并正确复制。运行时不再出现错误

作为替代方案,总是有可能在K8s上创建一个initContainer来安装dos2unix并修复那里的文件,但这感觉不那么优雅,更像是使用nukes猎兔


非常感谢BMitch建议我检查容器内的文件,而不仅仅是源文件。

如前所述,我已经尝试过了,但我在两个文件中都找不到回车符。Dos2unix对这两个应用程序都应用零更改files@Marco你看过图像里面的文件了吗?现在我连吊舱都启动不了。尝试某些操作后,获取更多类型的错误\r不是命令。看起来他们真的被困在图像里了,我不明白为什么<代码>尾部:无法打开“/dev/null”$'\r”进行读取:没有这样的文件或目录。再一次。。。在docker本地表现不错-compose@Marco拉取在k8s中部署的映像,不要调试您在本地构建的映像,如果它不是问题发生的地方。并使用不同的入口点运行它,有一个
--entrypoint
标志可以用来将其更改为shell。我看到的另一个产生问题的地方是git本身,当配置为在签出文件时自动转换Windows的行结尾时。如前所述,我已经尝试过了,但我在这两个文件中都找不到回车符。Dos2unix对这两个应用程序都应用零更改files@Marco你看过图像里面的文件了吗?现在我连吊舱都启动不了。尝试某些操作后,获取更多类型的错误\r不是命令。看起来他们真的被困在图像里了,我不明白为什么<代码>尾部:无法打开“/dev/null”$'\r”进行读取:没有这样的文件或目录。再一次。。。在docker本地表现不错-compose@Marco拉取在k8s中部署的映像,不要调试您在本地构建的映像,如果它不是问题发生的地方。并使用不同的入口点运行它,有一个
--entrypoint
标志可以用来将其更改为shell。我看到的另一个产生问题的地方是git本身,当配置为在签出文件时自动转换Windows的行尾时。