阅读 759

alpine的Docker镜像使用避坑汇总

建议目前基于alpine的python因较慢,且可能存在不稳定,使用python:3.8-slim-buster来代替制作python Docker

1、标准的PyPI wheel在Alpine上无效:

参考 cloud.tencent.com/developer/n…

pythonspeed.com/articles/ba…

blog.csdn.net/dianfu2892/…

2、大多数Linux发行版使用标准C库的GNU版本(glibc),Python以及几乎所有的C程序都需要它。但是Alpine Linux使用musl,这些二进制wheel是针对glibc编译的,因此Alpine禁用了Linux wheel支持。

现在,大多数Python包都包含了PyPI上的二进制wheel,这大大缩短了安装时间。但是,如果你使用的是Alpine Linux,那么你就需要编译你所使用的每个Python包中的所有C代码。

3、Alpine Linux会导致意料之外的运行时Bug 虽然理论上,Alpine使用的musl C库与其他Linux发行版使用的glibc基本兼容,但在实践中,这种差异可能会导致问题。当问题确实发生时,可能会很奇怪且出乎意料。

下面是一些例子:

Alpine线程的默认堆栈大小更小,这可能导致Python崩溃。

Alpine的一位用户发现,由于musl分配内存的方式与glibc不同,他们的Python应用程序要慢很多。

在使用WeWork工作空间的WiFi时,我曾经无法在minikube(虚拟机中的Kubernetes)上运行的Alpine镜像中查找DNS。原因是WeWork糟糕的DNS设置、Kubernetes和minikube实现DNS的方式,以及musl对这种边缘情况的处理与glibc的方式不同。musl没有错(它符合RFC),但是我不得不浪费时间找出问题所在,然后切换到基于glibc的镜像。

另一个用户发现了时间格式和解析的问题。

坑1 : 解决apk add 下载慢、pip慢

解决:

#echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.4/main" > /etc/apk/repositories \
#&& echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.4/community" >> /etc/apk/repositories \
#&& echo "https://mirror.tuna.tsinghua.edu.cn/alpine/edge/testing" >> /etc/apk/repositories
#或:
sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories

#解决pip install 慢
pip config set global.index-url https://mirrors.aliyun.com/pypi/simple \
	&& pip config set install.trusted-host mirrors.aliyun.com \
复制代码

坑2: 找不到包

解决: 搜索 pkgs.alpinelinux.org/packages ,加入指定的“Branch”和“Repository”的源到/etc/apk/repositories,就可以apk add

坑3: 安装失败

ERROR: mirror.tuna.tsinghua.edu.cn/alpine/v3.4… Bad file descriptor WARNING: Ignoring APKINDEX.79f426e4.tar.gz: Bad file descriptor ERROR: unsatisfiable constraints: openssh (missing): required by: world[openssh] 解决:

apk add  openssh --no-cache #加--no-cache, 另外,还能减少镜像体积
复制代码

坑4:镜像体积大,想删除不再使用的包

apk add 加 -t 参数

-t, --virtual NAME Instead of adding all the packages to 'world', create a new virtual package with the listed dependencies and add that to 'world'; the actions of the command are easily reverted by deleting the virtual package 这意味着当您安装软件包时,这些软件包不会添加到全局软件包中。这种变化可以很容易地回滚/删除。所以,如果我需要gcc来编译程序,但是一旦程序被编译,我就不再需要gcc了。

我可以在虚拟包中安装gcc和其他必需的包,并且可以删除所有依赖项,并删除此虚拟包名称。以下是示例用法

apk add --virtual mypacks gcc vim
apk del mypacks
复制代码

使用第一个命令安装的所有18个软件包将被下一个命令删除。

注意:同一个-t参数会覆盖之前的所有安装包,对动态链接库最好不使用-t ,或者保证此参数不重复。

坑5:时间不同步

echo "Asia/Shanghai" > /etc/timezone
apk add –no-cache tzdata
TZ=Asia/Shanghai
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# 或简单点的直接复制宿主机时区配置
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtim 
复制代码

坑6:用户(组)和宿主机不兼容

解决:

addgroup -g 1200 -S www \
     && adduser -u 1200 -D -S -G www www
复制代码

坑7:不兼容glibc

解决:

使用最新稳定版本的alpine,

#再安装编译环境
apk add --virtual .build-base --no-cache 
autoconf \
automake \ 
g++ \ 
make \

linux-headers \
bsd-compat-headers 
复制代码

坑8:pip安装慢

解决:更换安装源

 pip config set global.index-url https://mirrors.aliyun.com/pypi/simple \
	&& pip config set install.trusted-host mirrors.aliyun.com \
复制代码

坑9:Docker容器中或build 时不能访问外网

解决,添加运行参数:

--net=host

坑10:Docker容器如通过代理才能访问外网

解决,添加环境变量

需在Dockerfile文件中需求访问网络的操作前添加命令行,或直接在容器中运行以上两个命令行:

export http_proxy=http://16.15.0.1:9011

#和:

export https_proxy=http://16.15.0.1:9011
复制代码