DevOps丨Alpine上安装docker

945 阅读3分钟

Alpine Linux包管理器community镜像源中包含了Docker安装包,可直接使用包管理器apk命令安装。

替换镜像源(可选步骤)

Alpine 的源文件为:

/etc/apk/repositories

这里面的默认配置例如:

http://dl-cdn.alpinelinux.org/alpine/v3.11/main
http://dl-cdn.alpinelinux.org/alpine/v3.11/community

可以使用以下命令来进行源的切换(阿里云源):

sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories

中国科技大学的源:

sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories

清华源:

sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories

目前 Docker 官方已开始推荐使用 Alpine 替代之前的 Ubuntu 做为基础镜像环境。

Alpine 使用 apk 来进行包管理。

可以在 Docker file 中添加以下语句,来加速 apk 的包管理。

...
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories
RUN apk add --no-cache gcc musl-dev linux-headers
...

注: sed 可依照脚本的指令来处理、编辑文本文件。 Sed 主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。

安装 Docker

apk add docker

配置 Docker

添加开机启动

安装开机启动配置服务

apk add openrc

启动 openrc

openrc
touch /run/openrc/softlevel

设置Docker开机启动

rc-update add docker boot

启动 Docker 服务

service docker start

更改 Docker 镜像源

vi /etc/docker/daemon.json

添加内容

{
  "registry-mirrors": [
    "https://hub-mirror.c.163.com",
    "https://ustc-edu-cn.mirror.aliyuncs.com",
    "https://docker.mirrors.ustc.edu.cn"
  ]
}

重启Docker服务

service docker restart

可能遇到的问题

启动docker报错

hostname: sethostname: Operation not permitted                                                                                                                         [ !! ]
 * ERROR: hostname failed to start
 * ERROR: cannot start networking as hostname would not start
 * ERROR: cannot start docker as hostname would not start

输入下面的命令解决

# Tell openrc loopback and net are already there, since docker handles the networking
echo 'rc_provide="loopback net"' >> /etc/rc.conf

启动报错2

failed to start daemon: Error initializing network controller: error obtaining controller instance: failed to create NAT chain DOCKER: iptables failed: iptables -t nat -N DOCKER: iptables v1.8.8 (legacy): can't initialize iptables table `nat': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
 (exit status 3)

解决方法:/etc/docker/daemon.json中添加:"iptables": false

{
  "registry-mirrors": [
    "https://hub-mirror.c.163.com",
    "https://ustc-edu-cn.mirror.aliyuncs.com",
    "https://docker.mirrors.ustc.edu.cn"
  ],
  "iptables": false
}

stackoverflow中对于alpine中使用openrc的建议

A container doesn't really "boot". You simply choose what process starts when the container starts -- maybe that's a process manager, like openrc, but more generally it's a specific service.

If we're designing a container to work with openrc, we could start with something like this:

FROM docker.io/alpine:latest

RUN apk add openrc mdevd-openrc
RUN sed -i '/getty/d' /etc/inittab

CMD ["/sbin/init"]

A container that runs a couple of services under the control of openrc might look like this:

FROM openrc-base

RUN apk add openssh-server openssh-server-common-openrc darkhttpd darkhttpd-openrc 
RUN rc-update add sshd default && rc-update add darkhttpd default

RUN mkdir -p -m 700 /root/.ssh
COPY id_rsa.pub /root/.ssh/authorized_keys
RUN chmod 600 /root/.ssh/authorized_keys

If we build an image from that Dockerfile and run it...

docker run --rm -p 2200:22 -p 8080:80 openrc-multiservice

...we'll see output like this:

 * /proc is already mounted
 * /run/openrc: creating directory
 * /run/lock: correcting mode
 * /run/lock: correcting owner
   OpenRC 0.52.1 is starting up Linux 6.7.10-200.fc39.x86_64 (x86_64)

 * Caching service dependencies ... [ ok ]
 * /var/log/darkhttpd: correcting owner
 * Starting darkhttpd web server ... [ ok ]
ssh-keygen: generating new host keys: RSA ECDSA ED25519
 * Starting sshd ... [ ok ]

No errors, I didn't have to enable "softlevel" mode, and our services start up as expected. But maybe someone only wants to run a single service without using openrc! In that case, they can override CMD on the command line:

docker run --rm -p 8080:80 openrc-multiservice darkhttpd /etc --port 80

That works, too.


In general, images based on our openrc image should be designed with the fact that openrc is an option in mind (they should install rc files for any provided services, etc), but they can have any ENTRYPOINT script they want as long as it respects CMD and ultimately starts /sbin/init.

At the same time, they can support single-service instances as well.