需要了解的知识
- 如何写Dockerfile,可参考文章 https://www.runoob.com/docker/docker-dockerfile.html
- 为了对比官方x86平台已经做好的镜像,需要了解docker分层特点,可参考文章
docker GraphDriver_leechm的博客-CSDN博客
官方镜像仓库:https://hub.docker.com/search?type=image
3. 了解docker常用命令
可参考文章https://www.runoob.com/docker/docker-container-usage.html
4. 为了测试镜像,还得了解k8s搭建及常用命令
可参考https://www.jianshu.com/p/fa2d827ac725
5. 由于移植的组件大多数是go语言写的,准备一个申威适配好的vendor目录,110路径/home/qimei.li/k8s/sw64-sys.tar.gz,还得了解常用golang编译命令,可参考https://www.cnblogs.com/itogo/p/8645441.html
案例演示:
做一个consul镜像,一般先去dockerhub上搜其他平台做好的
一般来讲在office image中,describtion中会有对应的github源码地址,其他未知。
[root@controllersw src]# git clone -b v1.5.1 https://hub.fastgit.org/hashicorp/consul.git
[root@controllersw consul]# ls
acl bench command GNUmakefile INTERNALS.md LICENSE main_test.go sdk snapshot testrpc ui-v2 version
agent build-support connect go.mod ipaddr logger NOTICE.md sentinel terraform tlsutil Vagrantfile website
api CHANGELOG.md demo go.sum lib main.go README.md service_os test types vendor
[root@controllersw consul]#
golang写的代码,若我们直接编译的话,报错如下:
这是缺少相关sw64的go代码导致,这个时候我们需要把适配好的vendor目录下所有的xxxxsw64.go相关文件名拷贝到consul中对应的目录下,当然这个也不是通用的,但这个xxxxsw64.go能解决你大部分报错,如出现其他错误的,一把比较少,再研究把。比较简单的例如:如下已经拷贝sw64.go文件,扔报错如下,像zsyscall_linux_sw64.go那个报错,就是vendor适配的时候,代码多了,删掉这一行所在的函数即可。socket的那个,就是少一些sw64的定义,把该目录下所有带64bit的文件加上sw64。
再加一个文件
再拷贝一份代码,走的是通用结构
[root@controllersw consul]# cp zsys_linux_mips64le.go zsys_linux_sw64.go
[root@controllersw consul]# cp vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go vendor/golang.org/x/net/ipv4/zsys_linux_sw64.go -af
[root@controllersw consul]# cp vendor/golang.org/x/net/ipv6/zsys_linux_mips64le.go vendor/golang.org/x/net/ipv6/zsys_linux_sw64.go -af
[root@controllersw consul]# cp /root/kubernetes/vendor/github.com/coreos/bbolt/bolt_sw64.go /root/go/src/github.com/hashicorp/consul/vendor/github.com/boltdb/bolt/ -af
这样加好之后,执行go build检验一下是否可以生成二进制文件,可根据官方文件来决定我们编译的二进制是动态的还是静态文件。然后一般来讲,go写的源码里面都会附带有一个dockerfile文件,我们就可以基于这个dockerfile做镜像,对于没有的,例如consul:1.5.1里面没有,在docker hub上面也只能看到,所以我们就只有根据这个来自己手动参考着敲了
这个时候去下个x86的镜像,除了跟平台相关的二进制文件,其他的都可以去x86镜像里面去拿来用,最后的dockerfile即用到的文件如下:
[root@controllersw dockerfile]# ls -l
总用量 83204
-rwxr-xr-x 1 root root 84279296 12月 14 14:52 consul
-rwxr-xr-x 1 root root 3859 12月 14 13:43 docker-entrypoint.sh
-rw------- 1 root root 730 12月 14 15:36 Dockerfile
-rwxr-xr-x 1 root root 890400 12月 14 13:51 dumb-init
-rwxr-xr-x 1 root root 17488 12月 14 15:35 su-exec
drwx------ 3 root root 21 12月 14 15:35 test
[root@controllersw dockerfile]# cat Dockerfile
FROM leechm/busybox-glibc:1.32.0-v10
MAINTAINER leechm
ENV CONSUL_VERSION=1.5.1
LABEL su-exec https://hub.fastgit.org/javabean/su-exec.git
RUN addgroup consul && adduser -S -G consul consul
COPY consul /bin
RUN mkdir -p /consul/data && \
mkdir -p /consul/config && \
chown -R consul:consul /consul \
&& mkdir -p /usr/bin \
&& mkdir -p /usr/local/bin/
RUN test -e /etc/nsswitch.conf || echo 'hosts: files dns' > /etc/nsswitch.conf
VOLUME /consul/data
EXPOSE 8300
EXPOSE 8301 8301/udp 8302 8302/udp
EXPOSE 8500 8600 8600/udp
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
COPY dumb-init /usr/bin
COPY su-exec /sbin/
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["agent", "-dev", "-client", "0.0.0.0"]
使用docker build命令打包镜像,运行一下
[root@controllersw dockerfile]# docker run leechm/consul:1.5.1
standard_init_linux.go:211: exec user process caused "not a directory"
[root@controllersw dockerfile]#
报错了,别慌,进去容器里面调试,看哪里出错了。
记得把ENTRYPOINT注释掉,这样才能进去容器里面调试,调试的方式也很简单粗暴,就是手动执行 ENTRYPOINT / CMD 的相关命令,然后看看为啥报错,对于这里,最后发现是su-exec这个的问题,经过在x86上使用同样的源码编译出来的su-exec,在x86的镜像中使用,也是同样的错误,因此判断是源码找错了,再次github上搜,发现另外一个仓库可以用,像这种情况,我一般就在dockerfile中备注了一个LABLE,以便后续碰到同样的问题好查找。
重新打包镜像,因为这个镜像的测试环境不需要搭建k8s集群,所以直接run起来,然后对比x86下测试结果,申威consul镜像测试暂通过。
使用push上传到个人仓库
[root@controllersw dockerfile]# docker push leechm/consul:1.5.1
结语:
大体的方向就是这样子把,还有一些细节问题,主要就是基本上百分之九十九的官方镜像都是基于U系做的,目前的话,申威这里只有一个kylin-V10和busybox的基础镜像,还有就是一些文件权限,版本对应,u系转r系的问题等等.....