runsisi's

technical notes

在 Alpine 中构建 Ceph

2019-09-09 runsisi#ceph#alpine

最近在做 Alpine 中构建 Ceph 的需求,这里简单进行一下相关的记录。

首先创建容器,并指定相关的代理:

$ docker pull alpine
$ docker run -e http_proxy -e https_proxy -e no_proxy -it alpine

安装 sdk(其实就是 GCC 之类的,类似于 Ubuntu 下的 build-essential),并创建普通用户(创建非 root 用户不是必须的,不过我一般习惯使用非 root 用户):

# apk add alpine-sdk
# adduser -D runsisi
# echo 'runsisi:123456' | chpasswd
# addgroup runsisi abuild
# echo 'runsisi ALL=(ALL:ALL) NOPASSWD: ALL' > /etc/sudoers.d/runsisi
# su runsisi
$ cd

安装必要的工具,比如 openssh 之类的是因为代码放在 gerrit 上面,需要 ssh 进行克隆:

// no_proxy environment variable ignored by wget
// https://github.com/gliderlabs/docker-alpine/issues/259
$ sudo -E apk add bash python2 openssh openssh-keygen socat wget grep
$ bash
$ echo $-
himBHs
$ export PS1="[\u@ \w]\\$ "
$ alias sudo='sudo -E'

配置 git,用于从 gerrit 克隆代码(使用配置 core.sshCommand 的方式以 ssh 方式克隆代码要求 git 的版本为 2.10+,详情请参考 git clone ssh repo 时使用 http 代理):

$ ssh-keygen
$ git --version
git version 2.22.0
$ git config --global core.sshCommand 'ssh -o StrictHostKeyChecking=no -F /dev/null -i ~/.ssh/id_rsa -o "proxycommand socat - PROXY:192.168.5.2:%h:%p,proxyport=3334"'
$ git config --global user.name luo.runbing
$ git config --global user.email luo.runbing@example.com

将 SSH 公钥拷贝至 gerrit:

$ cat ~/.ssh/id_rsa.pub

克隆 Ceph 代码(基于社区 12.2.12 版本),并打上必要的 补丁(我的需求其实只是需要 Ceph 的客户端,因此我禁用了 RGW 等组件),apk 构建所需的 spec 文件主要参考了 Alpine 官方的 aports,然后根据 rpm 的 spec 对依赖等做了部分修改:

$ patch -p1 < ../p1.diff 
patching file CMakeLists.txt
patching file alpine/APKBUILD.in
patching file src/client/hypertable/CephBroker.cc
patching file src/common/ceph_time.h
patching file src/common/common_init.cc
patching file src/common/module.c
patching file src/common/secret.c
patching file src/dmclock/src/dmclock_util.cc
patching file src/dmclock/src/dmclock_util.h
patching file src/test/libcephfs/test.cc
patching file src/tools/rbd_nbd/rbd-nbd.cc

最后执行 Ceph 源代码目录下的 make-apk.sh 脚本即可进行构建:

$ ./make-apk.sh

当然也可以自己写个脚本,将 apk 签名所需的密钥独立出来,这样公钥可以独立发布,而不是每次发布 apk 包都需要发布一个公钥。

如果需要在容器内使用 ceph-fuse,需要注意在创建容器时加上 --cap-add SYS_ADMIN --device /dev/fuse 的选项,否则会出现如下的错误:

# lsmod | grep fuse
fuse                   91926  1
# ceph-fuse /cfs/
ceph-fuse[666]: starting ceph client
fuse: device not found, try 'modprobe fuse' first
ceph-fuse[666]: fuse failed to start

参考资料

Alpine Developer Documentation

https://wiki.alpinelinux.org/wiki/Developer_Documentation

fuse: device not found, try ‘modprobe fuse’ first

https://github.com/s3fs-fuse/s3fs-fuse/issues/647#issuecomment-392697838