Alpine
Alpine
The operating system is a security-oriented light Linux
distribution . It is different from the usual Linux
distribution . It Alpine
adopts musl libc
and busybox
to reduce the size of the system and the consumption of runtime resources, but its functions are much busybox
more complete, so it is more and more favored by the open source community. While keeping the weight down, Alpine
it also provides its own package management tool apk
. You can query package information through the https://pkgs.alpinelinux.org/packages
website , or you can apk
directly query and install various software through commands.
1. Advantages and disadvantages
1.1. Advantages
-
Mirror size is small
Alpine
The goal is to reduce the construction cost of the basic image, so that the built image occupies less space, so the bottom layer must be a dynamic link relationship. But it is special. It does not use a heavy dynamic library such as GLIBC , but uses busybox + musl libc . Compared with glibc, the musl libc library is smaller, simpler and safer, which greatly reduces the space and maintains the same corresponding function. -
Package management tools are fast
Containers change frequently in the cycle. New images may be built regularly, and some debugging tools may be temporarily installed in the running container. If the installation speed of the software package is very slow, it will quickly wear out our patience, and The package management tool of the Alpine image is very fast, and the software installation experience is very smooth.
1.2. Disadvantages
-
Niche disadvantage
Unlike common operating systems like CentOS and Ubuntu
Alpine
, it is not maintained by a big company like Red Hat or Canonical, but is maintained by a non-commercial organization, so the number of packages is less than these distributions A lot (if you just look at the default out-of-the-box repositories, Alpine has only 10,000 packages, while Ubuntu, Debian, and Fedora all have more than 50,000).If you need to use a binary file linked by musl libc in the project, but the tool Alpine itself does not provide one, you need to compile and package it yourself. This process itself is a very complicated thing, and you must understand how to compile it with make . In the large stage state, it is necessary to debug when an error occurs, which is a waste of time.
-
Underlying Dependency Defects
The bottom layer uses musl libc as a dependent library. Its small size is an advantage, but it is also a disadvantage. It cannot have a complete underlying dynamic library like glibc. In the multi-layer construction process, it may occur that the relevant dependencies cannot be found. , this problem is also a buried point that causes Alpine to generate a large number of pits as the underlying image.
musl libc is commonly used in embedded systems, because the resources of such systems themselves are very scarce, and it is not suitable to use a large underlying library, so such small library dependencies must be used.
2. Common problems
-
Building a Python docker container with Alpine is 50 times slower
这是一篇博文中给出的数据验证,上面地址是他的具体情况链接, 这种情况是很好理解的,因为 Python 是一种解释型的语言,它内部的很多依赖都已经打包好了,用 PIP 可以直接进行一个引入安装,但这些都绑定了特定的 C 库,这就意味着在大多数使用 glibc 的镜像中都可以正常安装,但 Alpine 镜像就不行。如果非要在 Alpine 中安装,你需要安装很多依赖,重头构建,耗时又费力。
-
构建多层容器镜像时发生错误
Docker
的容器概念本来就是一个分层的多层文件系统,从底层开始一层一层的添加所属层来增加对于业务层的支撑,但是在这个问题中在超过 4 层就发生了构建错误...... -
DNS 转发失败
musl libc does not use
domain
orsearch
directives in the/etc/resolv.conf
file. For example, if you started your Docker daemon with--dns-search=service.consul
, and then tried to resolveconsul
from within an Alpine Linux container, it would fail as the nameconsul.service.consul
would not be tried. You will need to work around this by using fully qualified names.Another difference is parallel querying of name servers. This can be problematic if your first name server has a different DNS view (such as service discovery through DNS). For example, if you started your Docker daemon with
--dns=172.17.42.1 --dns=10.0.2.15
where172.17.42.1
is a local DNS server to resolve name for service discovery and10.0.2.15
is for external DNS resolving, you wouldn't be able to guarantee that172.17.42.1
will always be queried first. There will be sporadic failures.In both of these cases, it can help to run a local caching DNS server such as dnsmasq, that can be used for both caching and search path routing. Running dnsmasq with
--server /consul/10.0.0.1
would forward queries for the.consul
to 10.0.0.1. -
二进制编译不兼容
While there are binaries that will run on musl libc without needing to be recompiled, you will likely encounter binaries and applications that rely on specific glibc functionality that will fail to start up. An example of this would be Oracle Java which relies on specific symbols only found in glibc. You can often use
ldd
to determine the exact symbol:# ldd bin/java /lib64/ld-linux-x86-64.so.2 (0x7f542ebb5000) libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7f542ebb5000) libjli.so => bin/../lib/amd64/jli/libjli.so (0x7f542e9a0000) libdl.so.2 => /lib64/ld-linux-x86-64.so.2 (0x7f542ebb5000) libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f542ebb5000) Error relocating bin/../lib/amd64/jli/libjli.so: __rawmemchr: symbol not found
In this case, the upstream would need to remove the support for this offending symbol or have the ability to compile the software natively on musl libc. Be sure to check the Alpine Linux package index to see if a suitable replacement package already exists.
3、方案替换
如果程序仅用到了标准库或者依赖项和程序本身使用的是同一种语言,且无需调用 C 库和外部依赖,那么使用 Alpine 作为基础镜像一般是没有啥问题的。
一旦程序需要调用外部依赖,情况就复杂了,想继续使用 Alpine 镜像,就得安装这些依赖。
- 依赖库有针对 Alpine 的安装说明,一般会说明需要安装哪些软件包以及如何建立依赖关系。
- 依赖库没有针对 Alpine 的安装说明,我们可以通过对比找到与别的发行版的软件包相匹配的 Alpine 软件包。
- 依赖库没有针对 Alpine 的安装说明,也没有与之对应的软件,这种情况就必须从源码开始构建。
我们大概可以得出一个结论,Alpine 通过降低底层依赖来减少自身的一个体积成为了后续最大的问题隐患,在场景比较复杂的情况下我们就需要切换基础镜像,使用功能更加全面、体积也相对较为轻便的镜像。
通过 Docker hub 中的镜像比对,可以选择几款替代品,虽然在相对体积上还是比不上 Alpine ,但是容器上面体积小并不是最重要的一个指标,在一定条件下一个持续稳健的容器比一个精细的容器要更加的好。
下表是仓库中最新的 Alpine 和其他基础镜像的镜像大小比对(只比较了一个操作系统下的情况)
IMAGE | DIGEST | OS/ARCH | COMPRESSED SIZE |
---|---|---|---|
alpine | 4ff3ca912757 | linux/amd64 | 2.67 MB |
debian | 3345381beaed | linux/amd64 | 28.3 MB |
ubuntu | 386bace9fb0d592 | linux/amd64 | 29.01 MB |
fedora | 486fd5578f93 | linux/amd64 | 56.2 MB |
虽然 docker 极力想要把基础镜像从 ubuntu 迁移到 alpine ,但是考虑到用户的选择问题,还是做出了妥协,从docker 官方发布的镜像的发行版中可以看出一些的端倪,可以使用 debian 作为基础镜像的替换,彼此之间的体积差异也不是很大。