如果你现在使用的系统架构不是x86,amd等架构,想要编译一版docker是何等的困难,官方提供的是在容器里编译,编译过程去官方仓库拉取需要的image层,可是在像mips这样的架构下,官方的镜像层是不可能拉取来使用的,一定会报错,那怎么办?于是本人尝试下载docker的github源码来编译,过程如下:

方法一.编译rpm包(推荐使用这种方法)

1.下载相应的rpm包

$wget https://mirrors.ustc.edu.cn/fedora/updates/25/SRPMS/d/docker-1.12.6-6.gitae7d637.fc25.src.rpm

如果上命令无法下载,可以去koji或者rpm search搜索下载

2.安装下载的xxx.src.rpm

$rpm -ivh xxx.src.rpm

3.进入rpmbuild/SPECS目录,就会看到有个文件docker.spec

$cd ~/rpmbuild/SPECS

4.执行编译,修改出错,再编译,这里面改错,一定会用的打patch的方法,见本人另一篇博客《rpmbuild编译一个软件时如何加入自己的补丁patch

$rpmbuild -ba docker.spec

具体内容没保存日志,略

方法二.编译github源码

  • 安装依赖包
#yum install -y glibc-static btrfs-progs-devel device-mapper-devel golang libselinux-static libsepol-static

#yum install -y libuuid-devel libattr-devel zlib-devel libacl-devel e2fsprogs-devel libb

  • 开始编译

#cd  docker目录

#sh -x ./hack/make.sh dynbinary  ;;动态编译,小红帽系列的操作系统都得动态编译,静态编的话是sh -x ./hack/make.sh binary

    ' github.com/docker/docker/cmd/docker
# github.com/docker/docker/pkg/system
.gopath/src/github.com/docker/docker/pkg/system/stat_linux.go:13: cannot use s.Rdev (type uint32) as type uint64 in field value
# github.com/docker/docker/pkg/signal
.gopath/src/github.com/docker/docker/pkg/signal/signal_linux.go:33: undefined: syscall.SIGSTKFLT
.gopath/src/github.com/docker/docker/pkg/signal/signal_linux.go:41: undefined: syscall.SIGUNUSED

解决办法
1.uint64(s.Rdev)
2.syscall.SIGSTKFLT-->16
3.syscall.SIGUNUSED-->31

继续编译

    ' github.com/docker/docker/cmd/dockerd
# github.com/docker/docker/vendor/github.com/boltdb/bolt
.gopath/src/github.com/docker/docker/vendor/github.com/boltdb/bolt/db.go:101: undefined: maxMapSize
.gopath/src/github.com/docker/docker/vendor/github.com/boltdb/bolt/db.go:101: invalid array bound maxMapSize
# github.com/docker/docker/vendor/github.com/vishvananda/netns
.gopath/src/github.com/docker/docker/vendor/github.com/vishvananda/netns/netns_linux.go:29: undefined: SYS_SETNS
# github.com/docker/docker/vendor/github.com/tonistiigi/fifo
.gopath/src/github.com/docker/docker/vendor/github.com/tonistiigi/fifo/handle_linux.go:39: cannot use stat.Dev (type uint32) as type uint64 in field value
.gopath/src/github.com/docker/docker/vendor/github.com/tonistiigi/fifo/handle_linux.go:65: invalid operation: stat.Dev != h.dev (mismatched types uint32 and uint64)
# github.com/docker/docker/vendor/github.com/google/certificate-transparency/go/x509
.gopath/src/github.com/docker/docker/vendor/github.com/google/certificate-transparency/go/x509/x509.go:342: undefined: elliptic.P224
.gopath/src/github.com/docker/docker/vendor/github.com/google/certificate-transparency/go/x509/x509.go:355: undefined: elliptic.P224
.gopath/src/github.com/docker/docker/vendor/github.com/google/certificate-transparency/go/x509/x509.go:1461: undefined: elliptic.P224
# github.com/docker/docker/pkg/loopback
.gopath/src/github.com/docker/docker/pkg/loopback/loopback.go:56: invalid operation: dev == targetDevice (mismatched types uint64 and uint32)
# github.com/docker/docker/pkg/platform
.gopath/src/github.com/docker/docker/pkg/platform/architecture_linux.go:15: undefined: charsToString

解决办法
1.创建 vendor/github.com/boltdb/bolt/bolt_mips64le.go文件,内容如下:
    [bolt_mips64le.go]
    // +build mips64le

    package bolt

    // maxMapSize represents the largest mmap size supported by Bolt.
    const maxMapSize = 0x3FFFFFFF // 1GB
    // maxAllocSize is the size used when creating array pointers.
    const maxAllocSize = 0x3FFFFFFF

    // Are unaligned load/stores broken on this arch?
    var brokenUnaligned = false
2.创建vendor/github.com/vishvananda/netns/netns_linux_mips64le.go文件,内容如下
    [netns_linux_mips64le.go]
    // +build linux,mips64le

    package netns

    const (
            SYS_SETNS                  = 5303
    )
3.将handle_linux.go  39,65行 stat.Dev-->uint64(stat.Dev)
4.x509.go按照patch修改,具体网址忘记了,内容如下,去掉P224的地方:
    diff --git a/vendor/src/github.com/google/certificate-transparency/go/x509/x509.go b/vendor/src/github.com/google/certificate-transparency/go/x509/x509.go
            old mode 100755
            new mode 100644
            index cda7220..d879b91
            --- a/vendor/src/github.com/google/certificate-transparency/go/x509/x509.go
            +++ b/vendor/src/github.com/google/certificate-transparency/go/x509/x509.go
            @@ -330,7 +330,6 @@ func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) PublicKeyAlgorithm
             //
             // NB: secp256r1 is equivalent to prime256v1
             var (
            -    oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33}
                 oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}
                 oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34}
                 oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35}
            @@ -338,8 +337,6 @@ var (
            
             func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve {
                 switch {
            -    case oid.Equal(oidNamedCurveP224):
            -        return elliptic.P224()
                 case oid.Equal(oidNamedCurveP256):
                     return elliptic.P256()
                 case oid.Equal(oidNamedCurveP384):
            @@ -352,8 +349,6 @@ func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve {
            
             func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) {
                 switch curve {
            -    case elliptic.P224():
            -        return oidNamedCurveP224, true
                 case elliptic.P256():
                     return oidNamedCurveP256, true
                 case elliptic.P384():
            @@ -1458,7 +1453,7 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub interf
                     hashFunc = crypto.SHA1
                 case *ecdsa.PrivateKey:
                     switch priv.Curve {
            -        case elliptic.P224(), elliptic.P256():
            +        case elliptic.P256():
                         hashFunc = crypto.SHA256
                         signatureAlgorithm.Algorithm = oidSignatureECDSAWithSHA256
                     case elliptic.P384():
5.将loopback.go    56行 targetDevice-->uint64(targetDevice)
6.在architecture_linux.go中添加函数
    // Convert the OS/ARCH-specific utsname.Machine to string
    // given as an array of signed int8
    func charsToString(ca [65]int8) string {
            s := make([]byte, len(ca))
            var lens int
            for ; lens < len(ca); lens++ {
                    if ca[lens] == 0 {
                            break
                    }
                    s[lens] = uint8(ca[lens])
            }
            return string(s[0:lens])
    }

继续编译
.gopath/src/github.com/docker/docker/daemon/graphdriver/devmapper/deviceset.go:1558: cannot use dev (type uint32) as type uint64 in argument to major
.gopath/src/github.com/docker/docker/daemon/graphdriver/devmapper/deviceset.go:1559: cannot use dev (type uint32) as type uint64 in argument to minor
.gopath/src/github.com/docker/docker/daemon/graphdriver/devmapper/deviceset.go:1752: cannot use sysSt.Dev (type uint32) as type uint64 in argument to major
.gopath/src/github.com/docker/docker/daemon/graphdriver/devmapper/deviceset.go:1752: cannot use sysSt.Dev (type uint32) as type uint64 in argument to minor

1.将dev-->uint64(dev)转换为64位,将sysSt.Dev-->uint64(sysSt.Dev)

继续编译,编译成功

#cd bundles

#tree

会出现下图的结果

此时,到dynbinary-client下执行docker -v会有如下图输出

到这一步,我疑惑,服务怎么启动,docker 守护进程怎么起,看了许多,X86平台的很多帖子都说到这一步就成功了,成功何在??

感情是替换原来的docker二进制文件,本人试了,结果很遗憾,只能停留在这一步,希望有人解决这个疑惑。

Logo

开源、云原生的融合云平台

更多推荐