Docker

( 建议使用 containerd

https://hub.docker.com/

入门教程 https://docker_practice.gitee.io/

CoreOS 搭配更佳。如果需要手动强制升级,使用:

update_engine_client -update

然后重启完成升级。

Debian 安装参考:https://docs.docker.com/install/linux/docker-ce/debian/

apt update
apt install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -

add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/debian \
   $(lsb_release -cs) \
   stable"

apt update
apt install -y docker-ce docker-ce-cli containerd.io

普通用户 foo 加权限:

usermod -a -G docker foo

CoreOS 需要 SELINUX,不然会有奇怪的错误。

vi /etc/selinux/config 

SELINUX=permissive
SELINUXTYPE=mcs

CoreOS系统经常自动重启,原因是系统自动升级,如不需要自动重启,编辑 /etc/coreos/update.conf

REBOOT_STRATEGY=off

然后

systemctl restart update-engine

但是后来好像还是自动重启了,干脆关了吧:

systemctl stop update-engine
systemctl disable update-engine

/var/lib/docker/

这是工作目录,images 和 containers 都在这里,可以考虑迁移到速度快容量大的磁盘。

/var/run/docker.sock

CentOS 或 Debian 的普通用户使用时,需要 docker 组的权限:

usermod -a -G docker YOU

常用工具

curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# https://github.com/bcicen/ctop/releases
wget https://github.com/bcicen/ctop/releases/download/v0.7.2/ctop-0.7.2-linux-amd64 -O /usr/local/bin/ctop

chmod +x /usr/local/bin/*

基础镜像

alpine 默认没开启 utf-8,可能有的软件会出现功能不全,比如 tmux, htop,设置环境变量 LANG 即可:

echo 'export LANG=C.UTF-8' >>~/.profile

常用容器

nsenter

Run a program with namespaces of other processes.

在宿主机上找到容器的命名空间后,在其中执行指令,例子:

nsenter -t 30069 -u hostname

# 查看 traefik 的网络链接
nsenter -t $(pgrep traefik) -n netstat -ntp

参考:https://stackoverflow.com/questions/40350456/docker-any-way-to-list-open-sockets-inside-a-running-docker-container

/dev/mqueue:

option: --ipc

docker run -it --ipc=host alpine sh

docker run -it --name=main alpine sh
docker run -it --ipc=container:main alpine sh

edge/testing packages

有的包较冷门,安装的话需要自己定义:

echo 'http://dl-cdn.alpinelinux.org/alpine/edge/testing' >>/etc/apk/repositories
apk add moosefs-client

alpine gcc

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

/opt/bin

可以把 docker 容器启动的工具放这里,如 htop, ctop

docker start -ia $(basename $0)

Dockerfile for Python

如果需要处理出现的僵尸进程,参考 Tini

FROM python:stretch as base

RUN apt-get update
RUN apt-get install -y libev-dev \
    && pip install -i https://pypi.douban.com/simple --user \
        gunicorn falcon pycrypto pyyaml requests redis pymysql psycopg2-binary pony

FROM python:slim-stretch
WORKDIR /root/
COPY --from=base /root/.local .local
COPY .gunicorn cfg.yaml *.py ./
EXPOSE 8000
ENV PATH /root/.local/bin:${PATH}
CMD [ "gunicorn", "-c", ".gunicorn", "xxx" ]

还有一种方法生成的镜像更小,pyinstaller 打包结果 + debian:stretch-slim,浅尝可用。 理论上可以用 pyinstaller on alpine,但是安装时失败,算了。

pyinstaller your-script.py
# or
PYTHONOPTIMIZE=2 pyinstaller -y -s your-script.py

生成的文件有部分不是必须的,如

视情况和心情剔除。

剩下的举例:

_bisect.cpython-37m-x86_64-linux-gnu.so
_blake2.cpython-37m-x86_64-linux-gnu.so
_heapq.cpython-37m-x86_64-linux-gnu.so
_md5.cpython-37m-x86_64-linux-gnu.so
_pickle.cpython-37m-x86_64-linux-gnu.so
_queue.cpython-37m-x86_64-linux-gnu.so
_random.cpython-37m-x86_64-linux-gnu.so
_sha1.cpython-37m-x86_64-linux-gnu.so
_sha256.cpython-37m-x86_64-linux-gnu.so
_sha3.cpython-37m-x86_64-linux-gnu.so
_sha512.cpython-37m-x86_64-linux-gnu.so
_struct
_struct.cpython-37m-x86_64-linux-gnu.so
base_library.zip
libpython3.7m.so
libz.so.1
math.cpython-37m-x86_64-linux-gnu.so
posix_ipc.cpython-37m-x86_64-linux-gnu.so
ts
zlib
zlib.cpython-37m-x86_64-linux-gnu.so

极限控制镜像包大小,先用 pyinstaller 打包,然后从 debian:stretch-slim 拷贝出 lib lib64,和 pyinstaller 打包出的文件夹一起打一个 tgz

tar czf XXX.tgz lib* XXX

如何极限精简打包,参考 https://gist.github.com/lwzm/f3dfb447f7927b78d70c040aa1c3a5e1 todo python 通用极限打包,参考 fsm-hub

最后:

FROM debian:stretch-slim as base
RUN mkdir /x && cp -a /lib* /tmp /x
FROM scratch
COPY --from=base /x /
COPY /t /app
CMD /app/t

上述方法打出来的镜像,可比肩 Golang,但是对代码质量和系统细节的掌控的要求比较高。

CAfile

容器访问 HTTPS 时,需要各种根证书,一般是基于原始系统的基本镜像,安装类似 ca-certificates 的包, 也可以自己挂载本机的 CAfile,如宿主机 Debian:

...
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt:ro
...

参考:

compose

docker-compose

swarm

https://docs.docker.com/engine/reference/commandline/swarm/

涉及到的子命令:

portainer 和 swarm 对接比较好,大部分信息都能看到,不用 agent 模式,在主 manage 上也可以用。