前段时间把玩了一下 96Core 128Memory 250SSD aarch64 Ubuntu-16.04 $0.50/hour 的服务器
记录一些使用 Docker 的项目构建的事情.

Why?

  • 之前需要将项目搬到 ARMv8 架构下的服务器, 所以找了个云服务商, 用了下 aarch64 下的 Linux 来构建 Docker 相关的项目.

Env

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$ uname -a
Linux xxx 4.10.0-38-generic #42~16.04.1-Ubuntu SMP Tue Oct 10 16:33:57 UTC 2017 aarch64 aarch64 aarch64 GNU/Linux

$ grep processor /proc/cpuinfo | wc -l
96

$ free -h
total used free shared buff/cache available
Mem: 125G 521M 125G 12M 197M 124G
Swap: 3.2G 0B 3.2G

$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 316.7G 0 disk
├─sda2 8:2 0 3.2G 0 part [SWAP]
├─sda3 8:3 0 313.1G 0 part /
└─sda1 8:1 0 500M 0 part /boot/efi

$ lscpu
Architecture: aarch64
Byte Order: Little Endian
CPU(s): 96
On-line CPU(s) list: 0-95
Thread(s) per core: 1
Core(s) per socket: 48
Socket(s): 2
NUMA node(s): 2
L1d cache: 32K
L1i cache: 78K
L2 cache: 16384K
NUMA node0 CPU(s): 0-47
NUMA node1 CPU(s): 48-95

开始构建吧!

apt

如果需要国内源, 在此 Ubuntu Ports 源使用帮助. 为什么是 debian 系? 主要是因为 Docker 官方的源没能提供除 ubuntu 外的 arm64 版本.

Docker

系统自带的 ubuntu 源直接安装 docker 会得到 1.12 还是 1.13 左右版本的 docker. 更新版本的 docker 即使官方网站, 也没能找到说支持 arm64 系统的源, 只能自己找了. 好在还是很简单的 download.docker.com/linux. 在 debian/ubuntu/raspbian 下有更新版本的 docker.

Docker images

aarch64 下 所有的原先项目的基础镜像都不能用, 需要修改 Dockerfile 的基础镜像到 Docker hub/arm64v8.

etcd

项目用到了 etcd, etcd 没能提供 aarch64 的 bin, 不仅需要自己编译(golang 项目的编译还是挺简单的, 大部分 go get 即可), 还需要在运行时加上 ETCD_UNSUPPORTED_ARCH=arm64 的环境变量, 否则直接 exit. (32-bit and other unsupported systems)

To avoid inadvertently running a possibly unstable etcd server, etcd on unstable or unsupported architectures will print a warning message and immediately exit if the environment variable ETCD_UNSUPPORTED_ARCH is not set to the target architecture.

pyinstaller

使用 pip install 下来的 pyinstaller 会没有在 aarch64 下的 bootloader. 所以需要自己编译 pyinstaller 的 bootloader. 即便如此, 在其实现上, 因为对系统架构判断逻辑的问题, 会导致其使用了错误的 bootloader. 暂时地将正确的 bootloader 给复制到了被 错误 使用的目录下来了…(正确方式: 提 issue + PR)

1
2
3
4
5
6
7
8
9
10
# 下载 3.3 版本的 pyinstaller
curl -LO https://github.com/pyinstaller/pyinstaller/archive/v3.3.tar.gz
tar -zxvf v3.3.tar.gz

# 需要在其目录下
cd pyinstaller-3.3/bootloader
python ./waf distclean all --target-arch=64bit

# 只能靠伪装了...看起来是没能正确识别系统架构 Linux-64bit-aarch/Linux-64bit
cp /usr/local/lib/python2.7/site-packages/PyInstaller-3.3+4e8e0ff7a-py2.7.egg/PyInstaller/bootloader/Linux-64bit-aarch/* /usr/local/lib/python2.7/site-packages/PyInstaller-3.3+4e8e0ff7a-py2.7.egg/PyInstaller/bootloader/Linux-64bit/

alpine

为了镜像小, 一般会用 alpine, 但是用了 pyinstaller 构建后会需要 glibc. 反正 aarch64 下的 glibc 要么找不到, 要么自己构建出错, 解决了重新构建又是很久. 就懒得用了…换了用其他大一点的基础镜像(用的起 aarch64 的也不差钱~).

其他

  • htop 看起来挺壮观的…
  • 另外 aarch64 下所有的构建都很慢…

Reference

Ubuntu Ports 源使用帮助
docker 官方源
arm64v8 基础镜像
ETCD Supported systems