docker源碼編譯
經過研究docker的官方編譯腳步,發現本地編譯也很簡單,只需要在docker源碼的目錄下執行如下命令即可:
./hack/make.sh binary
上面這條命令就只會生成docker的二進制文件,不過肯定不會這么順利的,執行這個命令你就會發現錯誤。如果第一次執行報的錯誤應該是找不到相應的go依賴包。那麼現在就開始解決第一個問題,go依賴包。
解決go依賴包最直接的方法就一個一個去github或者其他地方去下載到本地,但是這樣做很麻煩,docker依賴的go語言包很多,然後依賴包可能又依賴其他包。這里有一個簡單實用的辦法,也是go語言管理項目的方便之處。通過go get命令來自動下載,例如發現報錯的是docker某一個目錄下的依賴包,那麼可以如下執行:
go get -v ./src/github.com/docker/docker/...
這條命令執行以後整個docker目錄下源文件依賴的包都會被自動下載。如果發現其他目錄下源文件也報同樣的錯誤,可以按照次方法解決。不過這里需要強調一點, 這些下載都是會下載最新的包,如果編譯老的docker肯定會出問題 ,如果編譯最新的docker代碼肯定不會有問題,因為官方的編譯是這種方式。
上面執行的命令都是建立在go語言環境建立成功的基礎上,我安裝的go遇到是1.3.3版本的,採用源碼方式安裝。安裝在/export/servers/go下面,然後所有的go語言工程源碼目錄放在 /export/servers/gopath。然後配置環境變數在用戶的根目錄下的.bashrc文件裡面如下:
export GOPATH=/export/servers/gopath
export GOROOT=/export/servers/go
export GOARCH=amd64
export GOOS=linux
然後docker的代碼目錄如下:/export/servers/gopath/src/github.com/docker/docker。這樣才能在gopath下面進行依賴包的下載。通過上面的方法把所有依賴包下載完以後就可以進行編譯了。
在繼續編譯的過程中還會遇到缺少c語言依賴包缺少的問題,主要有三個,(1)sqlite3;(2)device-mapper;(3)btrfs.
第一個sqlite3可以使用如下命令安裝依賴:yum install sqlite-devel.x86_64
B. 生產環境,測試環境中,Docker 可以做什麼
上次有人說不敢在生產環境中用 Docker,所以 SegmentFault 社區組織翻譯 8 個你可能不知道的 Docker 知識 這篇文章,和大家介紹一下生產環境中的 Docker 用例。
自從上世紀 90 年代硬體虛擬化被主流的技術廣泛普及之後,對數據中心而言,發生的最大的變革莫過於容器和容器管理工具,例如:Docker。在過去的一年內,Docker 技術已經逐漸走向成熟,並且推動了大型初創公司例如 Twitter 和 Airbnb 的發展,甚至在銀行、連鎖超市、甚至 NASA 的數據中心都贏得了一席之地。當我幾年前第一次直到 Docker 的時候,我還對 Docker 的未來持懷疑的態度,我認為他們是把以前的 Linux 容器的概念拿出來包裝了一番推向市場。但是使用 Docker 成功進行了幾個項目 例如 Spantree 之後,我改變了我的看法:Docker 幫助我們節省了大量的時間和經歷,並且已經成為我們技術團隊中不可或缺的工具。
GitHub 上面每天都會催生出各式各樣的工具、形態各異的語言和千奇百怪的概念。如果你和我一樣,沒有時間去把他們全部都測試一遍,甚至沒有時間去親自測試 Docker,那麼你可以看一下我的這篇文章:我將會用我們在 Docker 中總結的經驗來告訴你什麼是 Docker、為什麼 Docker 會這么火。
Docker 是容器管理工具
Docker 是一個輕量級、攜帶型、與外界隔離的容器,也是一個可以在容器中很方便地構建、傳輸、運行應用的引擎。和傳統的虛擬化技術不同的是,Docker 引擎並不虛擬出一台虛擬機,而是直接使用宿主機的內核和硬體,直接在宿主機上運行容器內應用。也正是得益於此,Docker 容器內運行的應用和宿主機上運行的應用性能差距幾乎可以忽略不計。
但是 Docker 本身並不是一個容器系統,而是一個基於原有的容器化工具 LXC 用來創建虛擬環境的工具。類似 LXC 的工具已經在生產環境中使用多年,Docker 則基於此提供了更加友好的鏡像管理工具和部署工具。
Docker 不是虛擬化引擎
Docker 第一次發布的時候,很多人都拿 Docker 和虛擬機 VMware、KVM 和 VirtualBox 比較。盡管從功能上看,Docker 和虛擬化技術致力於解決的問題都差不多,但是 Docker 卻是採取了另一種非常不同的方式。虛擬機是虛擬出一套硬體,虛擬機的系統進行的磁碟操作,其實都是在對虛擬出來的磁碟進行操作。當運行 CPU 密集型的任務時,是虛擬機把虛擬系統里的 CPU 指令「翻譯」成宿主機的CPU指令並進行執行。兩個磁碟層,兩個處理器調度器,兩個操作系統消耗的內存,所有虛擬出的這些都會帶來相當多的性能損失,一台虛擬機所消耗的硬體資源和對應的硬體相當,一台主機上跑太多的虛擬機之後就會過載。而 Docker 就沒有這種顧慮。Docker 運行應用採取的是「容器」的解決方案:使用 namespace 和 CGroup 進行資源限制,和宿主機共享內核,不虛擬磁碟,所有的容器磁碟操作其實都是對 /var/lib/docker/ 的操作。簡言之,Docker 其實只是在宿主機中運行了一個受到限制的應用程序。
從上面不難看出,容器和虛擬機的概念並不相同,容器也並不能取代虛擬機。在容器力所不能及的地方,虛擬機可以大顯身手。例如:宿主機是 Linux,只能通過虛擬機運行 Windows,Docker 便無法做到。再例如,宿主機是 Windows,Windows 並不能直接運行 Docker,Windows上的 Docker 其實是運行在 VirtualBox 虛擬機里的。
Docker 使用層級的文件系統
前面提到過,Docker 和現有容器技術 LXC 等相比,優勢之一就是 Docker 提供了鏡像管理。對於 Docker 而言,鏡像是一個靜態的、只讀的容器文件系統的快照。然而不僅如此,Docker 中所有的磁碟操作都是對特定的Copy-On-Write文件系統進行的。下面通過一個例子解釋一下這個問題。
例如我們要建立一個容器運行 java Web 應用,那麼我們應該使用一個已經安裝了 JAVA 的鏡像。在 Dockerfile(一個用於生成鏡像的指令文件)中,應該指明「基於 JAVA 鏡像」,這樣 Docker 就會去 Docker Hub Registry 上下載提前構建好的 JAVA 鏡像。然後再 Dockerfile 中指明下載並解壓 Apache Tomcat 軟體到 /opt/tomcat 文件夾中。這條命令並不會對原有的 JAVA 鏡像產生任何影響,而僅僅是在原有鏡像上面添加了一個改動層。當一個容器啟動時,容器內的所有改動層都會啟動,容器會從第一層中運行 /usr/bin/java 命令,並且調用另外一層中的 /opt/tomcat/bin 命令。實際上,Dockerfile 中每一條指令都會產生一個新的改動層,即便只有一個文件被改動。如果用過 Git 就能更清楚地認識這一點,每條指令就像是每次 commit,都會留下記錄。但是對於 Docker 來說,這種文件系統提供了更大的靈活性,也可以更方便地管理應用程序。
我們Spantree的團隊有一個自己維護的含有 Tomcat 的鏡像。發布新版本也非常簡單:使用 Dockerfile 將新版本拷貝進鏡像從而創建一個新鏡像,然後給新鏡像貼上版本的標簽。不同版本的鏡像的不同之處僅僅是一個 90 MB 大小的 WAR 文件,他們所基於的主鏡像都是相同的。如果使用虛擬機去維護這些不同的版本的話,還要消耗掉很多不同的磁碟去存儲相同的系統,而使用 Docker 就只需要很小的磁碟空間。即便我們同時運行這個鏡像的很多實例,我們也只需要一個基礎的 JAVA / TOMCAT 鏡像。
Docker 可以節約時間
很多年前我在為一個連鎖餐廳開發軟體時,僅僅是為了描述如何搭建環境都需要寫一個 12 頁的 Word 文檔。例如本地 Oracle 資料庫,特定版本的 JAVA,以及其他七七八八的系統工具和共享庫、軟體包。整個搭建過程浪費掉了我們團隊每個人幾乎一天的時間,如果用金錢衡量的話,花掉了我們上萬美金的時間成本。雖然客戶已經對這種事情習以為常,甚至認為這是引入新成員、讓成員適應環境、讓自己的員工適應我們的軟體所必須的成本,但是相比較起來,我們寧願把更多的時間花在為客戶構建可以增進業務的功能上面。
如果當時有 Docker,那麼構建環境就會像使用自動化搭建工具 Puppet / Chef / Salt / Ansible 一樣簡單,我們也可以把整個搭建時間周期從一天縮短為幾分鍾。但是和這些工具不同的地方在於,Docker 可以不僅僅可以搭建整個環境,還可以將整個環境保存成磁碟文件,然後復制到別的地方。需要從源碼編譯 Node.js 嗎?Docker 做得到。Docker 不僅僅可以構建一個 Node.js 環境,還可以將整個環境做成鏡像,然後保存到任何地方。當然,由於 Docker 是一個容器,所以不用擔心容器內執行的東西會對宿主機產生任何的影響。
現在新加入我們團隊的人只需要運行 docker-compose up 命令,便可以喝杯咖啡,然後開始工作了。
Docker 可以節省開銷
當然,時間就是金錢。除了時間外,Docker 還可以節省在基礎設施硬體上的開銷。高德納和麥肯錫的研究表明,數據中心的利用率在 6% - 12% 左右。不僅如此,如果採用虛擬機的話,你還需要被動地監控和設置每台虛擬機的 CPU 硬碟和內存的使用率,因為採用了靜態分區(static partitioning)所以資源並不能完全被利用。。而容器可以解決這個問題:容器可以在實例之間進行內存和磁碟共享。你可以在同一台主機上運行多個服務、可以不用去限制容器所消耗的資源、可以去限制資源、可以在不需要的時候停止容器,也不用擔心啟動已經停止的程序時會帶來過多的資源消耗。凌晨三點的時候只有很少的人會去訪問你的網站,同時你需要比較多的資源執行夜間的批處理任務,那麼可以很簡單的便實現資源的交換。
虛擬機所消耗的內存、硬碟、CPU 都是固定的,一般動態調整都需要重啟虛擬機。而用 Docker 的話,你可以進行資源限制,得益於 CGroup,可以很方便動態調整資源限制,讓然也可以不進行資源限制。Docker 容器內的應用對宿主機而言只是兩個隔離的應用程序,並不是兩個虛擬機,所以宿主機也可以自行去分配資源。
C. 如何在Docker上運行Ubuntu Core
對於Docker的安裝在官網上針對不同的操作系統分別進行了描述,Ubuntu上安裝Docker,對於ubuntu操作系統來說必須是64位的,因為Docker的官網上只是提供了64位的docker,如果需要32位的docker則需要下載源碼進行編譯,這里有篇文章介紹了Docker源碼如何進行編譯成32位,編譯32位的Docker。但是對於我使用的Ubuntu來說正好是32位的。通過下面的兩條命令可以看出操作系統的位數和Linux的內核版本。
root@ubuntu:/tmp#uname -a
Linux e529c1b7772a 3.13.0-12-generic #32-Ubuntu SMP Fri Feb 21 17:44:24 UTC 2014 i686 i686 i686 GNU/Linux
root@ubuntu:/tmp#file /sbin/init
/sbin/init: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=, stripped
如果想在32為的Ubuntu操作系統上運行Docker的話,就必須安裝32位的Docker。在Ubuntu中提供docker1.01-32位的deb包,可以直接點擊「docer1.01-32位deb包」跳轉到下載頁面。下載完成後,直接使用dpkg –i進行安裝。
dpkg -i docker.io_1.0.1~dfsg1-0ubuntu1~ubuntu0.14.04.1_i386.deb
Selecting previously unselected package docker.io.
(Reading database ... 150021 files and directories currently installed.)
Preparing to unpack docker.io_1.0.1~dfsg1-0ubuntu1~ubuntu0.14.04.1_i386.deb ...
Unpacking docker.io (1.0.1~dfsg1-0ubuntu1~ubuntu0.14.04.1) ...
Setting up docker.io (1.0.1~dfsg1-0ubuntu1~ubuntu0.14.04.1) ...
docker.io start/running, process 10456
Processing triggers for ureadahead (0.100.0-16) ...
Processing triggers for man-db (2.6.6-1) ...
也可以參考下面的這篇文章《Docker 1.0.1 已經可以在 Ubuntu 14.04 LTS 上測試了!》進行安裝。安裝完成後,可以使用下面的命令確定安裝的版本和基本的信息。由於docker使用go語言進行編寫的,所以要依賴於GO的編譯工具和庫文件。
oot@ubuntu:/tmp# docker version
Client version: 1.0.1
Client API version: 1.12
Go version (client): go1.2.1
Git commit (client): 990021a
Server version: 1.0.1
Server API version: 1.12
Go version (server): go1.2.1
Git commit (server): 990021a
root@ubuntu:/tmp# docker info
Containers: 1
Images: 7
Storage Driver: aufs
Root Dir: /var/lib/docker/aufs
Dirs: 10
Execution Driver: native-0.2
Kernel Version: 3.13.0-12-generic
WARNING: No swap limit support
官方安裝方式docker pull imagename從docker的索引中心下載,imagename是鏡像名稱,例如docker pull ubuntu就是下載base ubuntu並且tag是latest。
root@ubuntu:/# docker pull ubuntu:14.04
Pulling repository ubuntu
c4ff7513909d: Download complete
511136ea3c5a: Download complete
1c9383292a8f: Download complete
9942dd43ff21: Download complete
d92c3c92fa73: Download complete
0ea0d582fd90: Download complete
cc58e55aa5a5: Download complete
root@ubuntu:~/Downloads# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu 14.04 c1b5399bd2ee 8 minutes ago 205.3 MB
learn/tutorial latest 8dbd9e392a96 17 months ago 128 MB
root@ubuntu:/# docker run -i -t ubuntu /bin/bash
2014/09/04 13:04:28 exec format error
docker run -i -t learn/tutorial /bin/bash
2014/09/04 14:45:13 exec format error
PS:在安裝完成Dokcer後,使用Pull命令sudo docker pull ubuntu:14.04從鏡像倉庫獲取ubuntu的鏡像後,然後使用run命令docker run -i -t ubuntu /bin/bash直接運行該鏡像時,會出現下面的錯誤信息,後來我又嘗試著使用官方演示使用的learn/tutorial鏡像,還是出現同樣的問題,現在懷疑可能是由於我安裝的DOcker是32位的,而Image是64位的不匹配造成的。前面說過Docker默認提供的都是64位,其中提供的Image自然也都是64位,所以會出現下面的錯誤信息。在Docker Hub Registry里的大多數鏡像都是64位。這里有一個關於該錯誤的討論帖「Ddocker.io: Docker should recommend
linux-image-amd64 」。所以,如果想在32位的Docker基礎上運行Ubuntu的Image那要求Ubuntu的image也必須是32位。這就需要製作32位Ubuntu的Image。這里有一個官方提供的可用的Ubuntu image的列表,Ubuntu Image tag。
D. 如何在"特殊"的網路環境下編譯 Docker
由於 Docker 編譯需要依賴於 Docker Daemon ,所以只能在 64 位的 Linux 環境下先安裝 Docker 程序,再從 Github 上克隆 Docker 的代碼進行編譯。
在 Docker 的目錄下執行 make 命令將默認執行 Makefile 中 make binary 指令進行編譯。
?
default: binary
all: build
$(DOCKER_RUN_DOCKER) hack/make.sh
binary: build
$(DOCKER_RUN_DOCKER) hack/make.sh binary
cross: build
$(DOCKER_RUN_DOCKER) hack/make.sh binary cross
從以上的 Makefile 可以看出,執行 make、make binary、make all 或 make cross 都可以得到可運行的 Docker 程序。
在 Mac OS 環境下使用 brew 的命令安裝 Docker ,只能得到一個 docker client 的二進製程序,如果以 daemon 的方式運行,會得到 『This is a client-only binary - running the Docker daemon is not supported.』 的錯誤提示信息。
方法 1.
使用 VirtualBox 或者 VMWare Workstation 安裝一個 Linux 的虛擬機。宿主機使用 VPN 等方案使網路「正常」訪問各種「服務」,虛擬機網卡使用 NAT 模式。在 Linux 虛擬機內使用 make 進行編譯 Docker 不會有任何網路問題。只是編譯速度受限於 VPN 等網路解決方案,有可能等待時間很長。
方法 2.
Docker 每次發布新版本,都會在 docker-dev 的鏡像倉庫發布一個新的標簽,這個鏡像倉庫包含了編譯 Docker 鏡像所依賴的所有環境,只需替換 Docker 代碼目錄下的 Dockerfile 即可實現編譯 Docker 。
?
FROM docker.cn/docker/docker-dev:v1.2.0
VOLUME /var/lib/docker
WORKDIR /go/src/github.com/docker/docker
ENV DOCKER_BUILDTAGS apparmor selinux
ENTRYPOINT [「hack/dind」]
COPY . /go/src/github.com/docker/docker
Dockerfile 中只保留必要的步驟就可以實現編譯了。
方法 3.
對 Docker 代碼中的 Docker 進行徹底的改造,用國內的各種鏡像替換其中不能在「正常」網路條件下訪問的鏡像,使得代碼能夠快速編譯通過。
?
FROM docker.cn/docker/ubuntu:14.04.1
MAINTAINER Meaglith Ma <[email protected]> (@genedna)
RUN echo "deb http://mirrors.aliyun.com/ubuntu trusty main universe" > /etc/apt/sources.list && echo "deb-src http://mirrors.aliyun.com/ubuntu/ trusty main restricted" >> /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted" >> /etc/apt/sources.list && echo "deb-src http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted" >> /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/ubuntu/ trusty universe" >> /etc/apt/sources.list && echo "deb-src http://mirrors.aliyun.com/ubuntu/ trusty universe" >> /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/ubuntu/ trusty-updates universe" >> /etc/apt/sources.list && echo "deb-src http://mirrors.aliyun.com/ubuntu/ trusty-updates universe" >> /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted" >> /etc/apt/sources.list && echo "deb-src http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted" >> /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/ubuntu/ trusty-security universe" >> /etc/apt/sources.list && echo "deb-src http://mirrors.aliyun.com/ubuntu/ trusty-security universe" >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y \
aufs-tools \
automake \
btrfs-tools \
build-essential \
curl \
dpkg-sig \
git \
iptables \
libapparmor-dev \
libcap-dev \
libsqlite3-dev \
lxc=1.0* \
mercurial \
parallel \
reprepro \
ruby1.9.1 \
ruby1.9.1-dev \
s3cmd=1.1.0* \
unzip \
--no-install-recommends
RUN git clone --no-checkout https://coding.net/genedna/lvm2.git /usr/local/lvm2 && cd /usr/local/lvm2 && git checkout -q v2_02_103
RUN cd /usr/local/lvm2 && ./configure --enable-static_link && make device-mapper && make install_device-mapper
RUN curl -sSL http://docker-cn.qiniudn.com/go1.3.1.src.tar.gz | tar -v -C /usr/local -xz
ENV PATH /usr/local/go/bin:$PATH
ENV GOPATH /go:/go/src/github.com/docker/docker/vendor
ENV PATH /go/bin:$PATH
RUN cd /usr/local/go/src && ./make.bash --no-clean 2>&1
ENV DOCKER_CROSSPLATFORMS \
linux/386 linux/arm \
darwin/amd64 darwin/386 \
freebsd/amd64 freebsd/386 freebsd/arm
ENV GOARM 5
RUN cd /usr/local/go/src && bash -xc 'for platform in $DOCKER_CROSSPLATFORMS; do GOOS=${platform%/*} GOARCH=${platform##*/} ./make.bash --no-clean 2>&1; done'
RUN mkdir -p /go/src/github.com/gpmgo \
&& cd /go/src/github.com/gpmgo \
&& curl -o gopm.zip http://gopm.io/api/v1/download?pkgname=github.com/gpmgo/gopm\&revision=dev --location \
&& unzip gopm.zip \
&& mv $(ls | grep "gopm-") gopm \
&& rm gopm.zip \
&& cd gopm \
&& go install
RUN gopm bin -v code.google.com/p/go.tools/cmd/cover
RUN gem sources --remove https://rubygems.org/ \
&& gem sources -a https://ruby.taobao.org/ \
&& gem install --no-rdoc --no-ri fpm --version 1.0.2
RUN gopm bin -v -d /go/bin github.com/cpuguy83/go-md2man@tag:v1
RUN git clone -b buildroot-2014.02 https://github.com/jpetazzo/docker-busybox.git /docker-busybox
RUN /bin/echo -e '[default]\naccess_key=$AWS_ACCESS_KEY\nsecret_key=$AWS_SECRET_KEY' > /.s3cfg
RUN git config --global user.email '[email protected]'
RUN groupadd -r docker
RUN useradd --create-home --gid docker unprivilegeser
VOLUME /var/lib/docker
WORKDIR /go/src/github.com/docker/docker
ENV DOCKER_BUILDTAGS apparmor selinux
ENTRYPOINT ["hack/dind"]
COPY . /go/src/github.com/docker/docker
以上的命令把 Ubuntu 鏡像中的源替換為國內速度較快的阿里源;把 lvm2 鏡像到國內的 Git 託管服務 coding.net;從 七牛雲存儲 保存的 Golang 源碼進行獲取和編譯;使用 gopm 下載編譯所需要的 Library ;最後把其中 gem 源切換到淘寶。至此,可以在「特殊」的網路條件下快速編譯 Docker 。
E. 如何在 CentOS 7 上安裝 Docker
在編譯docker代碼之前肯定需要研究一下docker的代碼結構以及官方推薦的方式,因為docker是開源的,所以很多第三方開發者參與。那麼官方肯定會給出開發環境搭建的文檔,所以拿到代碼肯定先研究官方的編譯方法。通過文檔和代碼了解到docker官方推薦的是在docker本身的容器裡面搭建環境和編譯,官方給出的是一個基於ubuntu的dockerfile。不過正是這個dockerfile可以清楚的知道需要為了編譯准備哪些依賴環境,為我們後面自己編譯提供了環境搭建的基礎。然後就嘗試了官方的編譯方案,結果各種網路問題導致編譯通不過,當然網上也有相應的解決方案,基本上就是替換一些依賴源(國外的被牆了)。但是就算編譯通過了也只是一個基於ubuntu的二進制文件,只能在ubuntu的相應的系統上運行。我們需要的是一個可以在centos7上運行的二進制文件,關鍵要搭建一個可以持續開發和編譯測試的環境。當然也可以製作一個centos7的dockerfile文件,對照著官方的ubuntu的dockerfile也很簡單。但是這些都是還需要有一個前提,就是需要先安裝一個以前版本的docker來啟動這個環境澀,好處也是杠杠的,可以在任何一台能夠運行docker的系統上進行開發和測試,而且可以進行持續集成。不過對於我們來說能夠編譯出一個穩定運行在centos7上的二進制文件即可,所以就嘗試直接在本地進行編譯,而不是通過docker的容器進行。
經過研究docker的官方編譯腳步,發現本地編譯也很簡單,只需要在docker源碼的目錄下執行如下命令即可:
./hack/make.sh binary
上面這條命令就只會生成docker的二進制文件,不過肯定不會這么順利的,執行這個命令你就會發現錯誤。如果第一次執行報的錯誤應該是找不到相應的go依賴包。那麼現在就開始解決第一個問題,go依賴包。
解決go依賴包最直接的方法就一個一個去github或者其他地方去下載到本地,但是這樣做很麻煩,docker依賴的go語言包很多,然後依賴包可能又依賴其他包。這里有一個簡單實用的辦法,也是go語言管理項目的方便之處。通過go get命令來自動下載,例如發現報錯的是docker某一個目錄下的依賴包,那麼可以如下執行:
go get -v ./src/github.com/docker/docker/...
這條命令執行以後整個docker目錄下源文件依賴的包都會被自動下載。如果發現其他目錄下源文件也報同樣的錯誤,可以按照次方法解決。不過這里需要強調一點,這些下載都是會下載最新的包,如果編譯老的docker肯定會出問題,如果編譯最新的docker代碼肯定不會有問題,因為官方的編譯是這種方式。
上面執行的命令都是建立在go語言環境建立成功的基礎上,我安裝的go遇到是1.3.3版本的,採用源碼方式安裝。安裝在/export/servers/go下面,然後所有的go語言工程源碼目錄放在/export/servers/gopath。然後配置環境變數在用戶的根目錄下的.bashrc文件裡面如下:
export GOPATH=/export/servers/gopath
export GOROOT=/export/servers/go
export GOARCH=amd64
export GOOS=linux
然後docker的代碼目錄如下:/export/servers/gopath/src/github.com/docker/docker。這樣才能在gopath下面進行依賴包的下載。通過上面的方法把所有依賴包下載完以後就可以進行編譯了。
在繼續編譯的過程中還會遇到缺少c語言依賴包缺少的問題,主要有三個,(1)sqlite3;(2)device-mapper;(3)btrfs.
第一個sqlite3可以使用如下命令安裝依賴:yum install sqlite-devel.x86_64
第二個在官方的dockerfile文件裡面有解決方案,執行如下命令:
git clone --no-checkout https://git.fedorahosted.org/git/lvm2.git /usr/local/lvm2 && cd /usr/local/lvm2 && git checkout -q v2_02_103
cd /usr/local/lvm2 && ./configure --enable-static_link && make device-mapper && make install_device-mapper
第三個btrfs使用如下安裝依賴: yum install btrfs-progs。
這些依賴都解決了就繼續編譯,這個時候可能會出現ld連接錯誤,提示找不到庫。因為docker編譯的方式完全是static,所以所有依賴的庫必須還要有相應的靜態庫(.a),而不是動態庫(.so)。剛才通過yum install sqlite-devel.x86_64安裝了sqlite3的依賴,但是最後發現裡面沒有靜態庫,所以編譯ld的時候出錯了。我的解決辦法就是重新到sqlite3的官方網站下載了源碼包,然後編譯安裝即可。
編譯完成以後,就會在docker源碼目錄下的bundles/1.3.1/binary/目錄有如下文件:
docker docker-1.3.1 docker-1.3.1.md5 docker-1.3.1.sha256
docker-1.3.1這個文件就是我們需要的二進制文件了,docker是一個軟連接到docker-1.3.1的文件。
到此就成功完成編譯了,以後修改了代碼重新支持編譯腳步即可:
./hack/make.sh binary
F. 想使用docker來進行Android源碼編譯,對電腦配置要求怎麼樣
這個配置足夠了,還需要配置好對應的環境和編譯工具。
G. 跪求一個編譯好的dockerui,環境如圖linux。(實在不會編譯github上的dockerui項目)
https://github.com/kevana/ui-for-docker
這個往下看有如何使用說明哦哈哈
H. 如何在mips架構編譯docker之github源碼動態編譯
經過研究docker的官方編譯腳步,發現本地編譯也很簡單,只需要在docker源碼的目錄下執行如下命令即可: ./hack/make.sh binary 上面這條命令就只會生成docker的二進制文件,不過肯定不會這么順利的,執行這個命令你就會發現錯誤。如果第一次執行...
I. docker是非編譯型語言編寫的軟體嗎
Docker 是 PaaS 提供商 dotCloud 開源的一個基於 LXC 的高級容器引擎,源代碼託管在 Github 上, 基於go語言並遵從Apache2.0協議開源。
J. 如何到載百度網議
不久之前,機器之心聯合網路推出 PaddlePaddle 專欄,為想要學習這一平台的技術人員推薦相關教程與資源。在解析過PaddlePaddle框架之後,從這篇文章開始上手,安裝 PaddlePaddle。
目錄
環境
Windows 系統的安裝
在 Windows 上安裝 Docker 容器在 Windows 上安裝 Ubuntu
使用 pip 安裝
使用 Docker 安裝
從源碼編譯生成安裝包
在本地編譯生成安裝包在 Docker 編譯生成安裝包
編譯 Docker 鏡像
測試安裝環境
最後提示
項目代碼
參考資料
環境
系統:Ubuntu 16.0.4(64 位)處理器:Intel(R) Celeron(R) CPU內存:8G
Windows 系統的安裝
PaddlePaddle 目前還不支持 Windows,如果讀者直接在 Windows 上安裝 PaddlePaddlePaddle 的話,就會提示沒有找到該安裝包。如果讀者一定要在 Windows 上工作的話,筆者提供兩個建議:一、在 Windows 系統上使用 Docker 容器,在 Docker 容器上安裝帶有 PaddlePaddle 的鏡像;二、在 Windows 系統上安裝虛擬機,再在虛擬機上安裝 Ubuntu。
在 Windows 上安裝 Docker 容器
首先下載 Docker 容器的工具包 DockerToolbox,筆者使用這個安裝包不僅僅只有 Docker,它還包含了 VirtualBox 虛擬機,使用者工具包我們就不用單獨去安裝 VirtualBox 虛擬機了,DockerToolbox 的官網下載地址:https://docs.docker.com/toolbox/toolbox_install_windows/
下載之後,就可以直接安裝了,雙擊安裝包,開始安裝
選擇安裝路徑,筆者使用默認的安裝路徑
然後安裝所依賴的軟體,因為筆者之前在電腦上已經安裝了 git,所以在這里就不安裝了,其他都要勾選
這一步不用修改什麼,讓程序為我們創建一個桌面快捷鍵
最後就可以安裝了,等待一小段時間即可
到這里就安裝完成了
安裝完成之後,如果直接啟動 Docker 的話,有可能可能會卡在這里,因為還有下載一個 boot2docker.iso 鏡像,網速比較慢的話就可能一直卡在這里。所以我們還要鏡像下一步操作
Running pre-create checks...
(default) No default Boot2Docker ISO found locally, downloading the latest release...
(default) Latest release for github.com/boot2docker/boot2docker is v17.12.1-ce
(default) Downloading C:\Users\15696\.docker\machine\cache\boot2docker.iso from https://github.com/boot2docker/boot2docker/releases/download/v17.12.1-ce/boot2docker.iso...
在下載 DockerToolbox 的時候,這個工具就已經帶有 boot2docker.iso 鏡像了。並且存在 DockerToolbox 安裝的路徑上,筆者的路徑是:
C:\Program Files\Docker Toolbox\boot2docker.iso
我們把這個鏡像復制到用戶目錄\.docker\machine\cache\,如筆者的目錄如下:
C:\Users\15696\.docker\machine\cache\
復制完成之後,雙擊桌面快捷方式 Docker Quickstart Terminal,啟動 Docker,命令窗口會輸出以下信息:
Running pre-create checks...
Creating machine...
(default) Copying C:\Users\15696\.docker\machine\cache\boot2docker.iso to C:\Users\15696\.docker\machine\machines\default\boot2docker.iso...
(default) Creating VirtualBox VM...
(default) Creating SSH key...
(default) Starting the VM...
(default) Check network to re-create if needed...
(default) Windows might ask for the permission to create a network adapter. Sometimes, such confirmation window is minimized in the taskbar.
(default) Found a new host-only adapter: "VirtualBox Host-Only Ethernet Adapter #3"
(default) Windows might ask for the permission to configure a network adapter. Sometimes, such confirmation window is minimized in the taskbar.
(default) Windows might ask for the permission to configure a dhcp server. Sometimes, such confirmation window is minimized in the taskbar.
(default) Waiting for an IP...
最後看到 Docker 的 logo 就表示成功安裝 Docker 容器了
## .
## ## ## ==
## ## ## ## ## ===
/"""""""""""""""""\___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\_______/
docker is configured to use the default machine with IP 192.168.99.100
For help getting started, check out the docs at https://docs.docker.com
Start interactive shell
15696@ MINGW64 ~
$
到這就可以使用 Docker 來安裝 PaddlePaddle 了,具體請看本文章中關於 Docker 使用 PaddlePaddle 部分
在 Windows 上安裝 Ubuntu
在 Windows 上在 Ubuntu 就要先安裝虛擬機,虛擬機有很多,筆者使用的是開源的 VirtualBox 虛擬機,VirtualBox 的官網:https://www.virtualbox.org/
安裝完成 VirtualBox 虛擬機之後,進入到 VirtualBox 虛擬機中點擊新建,創建一個系統
選擇分配的內存,我這里只是分配了 2G,如果正式使用 PaddlePaddle 訓練模型,這遠遠不夠,讀者可以根據需求分配內存
創建一個虛擬硬碟
選擇默認的 VDI 硬碟文件類型
這里最好是選擇動態分配硬碟,這樣虛擬機會根據實際佔用的空間大小使用電腦本身的磁碟大小,這樣會減少電腦空間的佔用率的。如果是固定大小,那麼創建的虛擬機的虛擬硬碟一開始就是用戶設置的大小了。
這里就是選擇虛擬硬碟大小的,最後分配 20G 以上,筆者分配 30G,應該夠用。
然後選擇剛才創建的 Ubuntu 系統,點擊設置,這系統中取消勾選軟碟機,然後點擊存儲,選擇 Ubuntu 鏡像,筆者使用的是 64 位 Ubuntu 16.04 桌面版的鏡像
最後就可以啟動安裝 Ubuntu 了。選擇我們創建的 Ubuntu 系統,點擊啟動,進入到開始安裝界面,為了方便使用,筆者選擇中文版的
為了安裝之後不用在安裝和更新應用,筆者勾選了安裝 Ubuntu 時下載更新,這樣在安裝的時候就已經更新應用了
然後是選安裝的硬碟,因為我們使用的自己創建的整一個硬碟,所以我們可以直接選擇青春整個硬碟並安裝 Ubuntu,這里就不用考慮分區和掛載問題了
選擇所在的位置,這沒什麼要求的,筆者隨便選擇一個城市
然後是選擇鍵盤的布局,通常的鍵盤布局都是英語(美國)
創建 Ubuntu 的用戶名稱和密碼
最後就是安裝了,這個安裝過程可能有點久,耐心等待
安裝完成之後就可以在 Windows 系統上使用 Ubuntu 系統了,我們再使用 Ubuntu 來學習和使用 PaddlePaddle 做深度學習了。最好安裝完成之後,把在存儲中設置的 Ubuntu 鏡像移除
在本篇文章之後部分都是在 Ubuntu 上操作,我們都可以使用 Ubuntu 這虛擬機來完成。
如果讀者使用的是 Windows 10,可以使用 Windows 系統自帶的 Linux 子系統,安裝教程可以看我之前的文章 Windows10 安裝 Linux 子系統。
使用 pip 安裝
如果你還沒有在 pip 命令的話,首先要安裝 pip,要確保安裝的 pip 版本是大於 9.0.0 的,否則可能無法安裝 paddlepaddle。
安裝 pip 命令如下:
sudo apt install python-pip
安裝之後,還有看一下 pip 的的版本 pip --version,如果版本低於 9.0.0,那要先升級 pip,先要下載一個升級文件,命令如下:
wget https://bootstrap.pypa.io/get-pip.py
下載完成之後,可以使用這個文件安裝最新的 pip 了
python get-pip.py
安裝 pip 就可以動手安裝 paddlepaddle 了。如果許可權不夠,請在 root 下執行命令
pip install paddlepaddle
現在就測試看看 paddlepaddle 有沒有,在 python 的命令終端中試著導入 paddlepaddle 包:
import paddle.v2 as paddle
如果沒有報錯的話就證明 paddlepaddle 安裝成功了。
使用 Docker 安裝
為什麼要使用 Docker 安裝 paddlepaddle 呢,Docker 是完全使用沙箱機制的一個容器,在這個容器安裝的環境是不會影響到本身系統的環境的。通俗來說,它就是一個虛擬機,但是它本身的性能開銷很小。在使用 Docker 安裝 paddlepaddle 前,首先要安裝 Docker,通過下面的命令就可以安裝了:
sudo apt-get install docker
安裝完成之後,可以使用 docker --version 查看 Docker 的版本,如果有顯示,就證明安裝成功了。可以使用 docker images 查看已經安裝的鏡像。
一切都沒有問題之後,就可以用 Docker 安裝 paddlepaddle 了,命令如下:
docker pull docker.paddlepaddlehub.com/paddle
在這里不得不說的是,這個安裝過程非常久,也許是筆者的帶寬太小了。安裝完成後,可以再使用 docker images 命令查看安裝的鏡像,應該可以 看到類似這樣一個鏡像,名字和 TAG 會相同,其他信息一般不同
docker.paddlepaddlehub.com/paddle latest 2b1ae16d846e 27 hours ago 1.338 GB
從源碼編譯生成安裝包
我們的硬體環境都有很大的不同,官方給出的 pip 安裝包不一定是符合我們的需求,比如筆者的電腦是不支持 AVX 指令集的,在官方中沒找到這個的安裝包(也行現在已經有了),所以我們要根據自己的需求來打包一個自己的安裝包。
在本地編譯生成安裝包
1. 安裝依賴環境
在一切開始之前,先要安裝好依賴環境,下面表格是官方給出的依賴環境
1.1 安裝 GCC
一般現在的 Ubuntu 都是高於個版本了,可以使用 gcc --version 查看安裝的版本。比如筆者的是 4.8.4,如果你的是版本是低於 4.8.2 的就要更新一下了
sudo apt-get install gcc-4.9
1.2 安裝 CMake
先要從官網下 CMake 源碼
wget https://cmake.org/files/v3.8/cmake-3.8.0.tar.gz
解壓源碼
tar -zxvf cmake-3.8.0.tar.gz
依次執行下面的代碼
# 進入解壓後的目錄
cd cmake-3.8.0
# 執行當前目錄的 bootstrap 程序
./bootstrap
# make 一下
make
# 開始安裝
sudo make install
查看是否安裝成功,cmake --version,如果正常顯示版本,那已經安裝成功了。
1.3 安裝 pip
關於安裝 pip9.0.0 以上的版本,在上面的使用 pip 安裝部分已經講了,這里就不在熬述了
1.4 安裝 numpy
安裝 numpy 很簡單,一條命令就夠了
sudo apt-get install python-numpy
順便多說一點,matplotlib 這個包也經常用到,順便安裝一下
sudo apt-get install python-matplotlib
1.5 安裝 SWIG
執行下面代碼安裝 SWIG,安裝成功之後,使用 swig -version 檢查安裝結果
sudo apt-get install -y git curl gfortran make build-essential automake swig libboost-all-dev
1.6 安裝 Go
官方說可選擇,那看情況吧,如果像安裝安裝吧,筆者順便安裝了,就一條代碼的事情,老規則 go version
sudo apt-get install golang
到這里,依賴環境就已經安裝好了,准備安裝 paddlepaddle。
2. 首先要在 GitHub 上獲取 paddlepaddle 源碼
git clone https://github.com/PaddlePaddle/Paddle.git
3. 然後輸以下命令
# 進入剛下載的 Paddle 裡面
cd Paddle
# 創建一個 build 文件夾
mkdir build
# 進入 build 文件夾里
cd build
# 這就要選好你的需求了,比如筆者沒有使用 GPU,不支持 AVX,為了節省空間,我把測試關閉了,這樣會少很多空間。最後不要少了..
cmake .. -DWITH_GPU=OFF -DWITH_AVX=OFF -DWITH_TESTING=OFF
# 最後 make,生成你想要的安裝包,這個可能很久, 一定要有耐心
make
經過長久的 make 之後,終於生成了我們想要的安裝包,它的路徑在 Paddle/build/python/dist 下,比如筆者在該目錄下有這個安裝包 paddlepaddle-0.11.0-cp27-cp27mu-linux_x86_64.whl,你的命名可能不是這個。之後就可以安裝了,使用 pip 安裝:
# 請切入到該目錄
cd build/python/dist/
# 每個人的安裝包名字可能不一樣。如果許可權不夠,請在 root 下執行命令
pip install paddlepaddle-0.11.0-cp27-cp27mu-linux_x86_64.whl
這個我們就已經安裝了 paddlepaddle,現在就測試看看 paddlepaddle 有沒有安裝成功了,在 python 的命令終端中試著導入 paddlepaddle 包:
import paddle.v2 as paddle
如果沒有報錯的話就證明 paddlepaddle 安裝成功了。
在 Docker 編譯生成安裝包
使用 Docker 就輕松很多了,有多輕松,看一下便知 。
1. 首先要在 GitHub 上獲取 paddlepaddle 源碼
git clone https://github.com/PaddlePaddle/Paddle.git
2. 切入到項目的根目錄下
cd Paddle
3. 生成安裝包
下面一行代碼,提醒一下,這個過程非常長,一定要有耐心,順便把編譯測試關了,減少空間
docker run -it -v $PWD:/paddle -e "WITH_GPU=OFF" -e "WITH_AVX=OFF" -e "-DWITH_TESTING=OFF" docker.paddlepaddlehub.com/paddle:latest-dev bash -x /paddle/paddle/scripts/docker/build.sh
同樣會在 Paddle/build/python/dist 下生成一個安裝包,這對比在本地生成的安裝包,是不是要簡單很多,沒錯這就是 Docker 強大之處,所有的依賴環境都幫我們安裝好了,現在只要安裝這個安裝包就行了:
# 請切入到該目錄
cd build/python/dist/
# 每個人的安裝包名字可能不一樣。如果許可權不夠,請在 root 下執行命令
pip install paddlepaddle-0.11.0-cp27-cp27mu-linux_x86_64.whl
同樣我們要測試看看 paddlepaddle 有沒有安裝成功了,在 python 的命令終端中試著導入 paddlepaddle 包:
import paddle.v2 as paddle
如果沒有報錯的話就證明 paddlepaddle 安裝成功了。
編譯 Docker 鏡像
如果你比較喜歡使用 Docker 來運行你的 paddlepaddle 代碼,但是有沒有你想要的鏡像,這是就要自己來製作一個 Docker 鏡像了,比如筆者的電腦是不支持 AVX 指令集的,還只有 CPU,那麼我就要一個不用 AVX 指令集和使用 CPU 訓練的鏡像。好吧,我們開始吧
1. 我們要從 GitHub 下載源碼:
git clone https://github.com/PaddlePaddle/Paddle.git
2. 安裝開發工具到 Docker image 里
# 切入到 Paddle 目錄下
cd Paddle
# 下載依賴環境並創建鏡像,別少了最後的.
docker build -t paddle:dev .
有可能它不能夠命名為 paddle:dev,我們可以對他從重新命名,ID 要是你鏡像的 ID
# docker tag <鏡像對應的 ID> <鏡像名:TAG>
例如:docker tag 1e835127cf33 paddle:dev
3. 編譯
# 這個編譯要很久的,請耐心等待
docker run --rm -e WITH_GPU=OFF -e WITH_AVX=OFF -v $PWD:/paddle paddle:dev
安裝完成之後,使用 docker images 查看剛才安裝的鏡像。
測試安裝環境
我們就使用官方給出的一個例子,來測試我們安裝 paddlepaddle 真的安裝成功了
1. 創建一個記事本,命名為 housing.py,並輸入以下代碼:
import paddle.v2 as paddle
# Initialize PaddlePaddle.
paddle.init(use_gpu=False, trainer_count=1)
# Configure the neural network.
x = paddle.layer.data(name='x', type=paddle.data_type.dense_vector(13))
y_predict = paddle.layer.fc(input=x, size=1, act=paddle.activation.Linear())
# Infer using provided test data.
probs = paddle.infer(
output_layer=y_predict,
parameters=paddle.dataset.uci_housing.model(),
input=[item for item in paddle.dataset.uci_housing.test()()])
for i in xrange(len(probs)):
print 'Predicted price: ${:,.2f}'.format(probs[i][0] * 1000)
2. 執行一下該代碼
在本地執行代碼請輸入下面的命令
python housing.py
在 Docker 上執行代碼的請輸入下面的代碼
docker run -v $PWD:/work -w /work -p 8899:8899 docker.paddlepaddle.org/paddle python housing.py
-v 命令是把本地目錄掛載到 docker 鏡像的目錄上,-w 設置該目錄為工作目錄,-p 設置埠號,使用到的鏡像是在使用 Docker 安裝部分安裝的鏡像 docker.paddlepaddle.org/paddle
3. 終端會輸出下面類似的日誌
I0116 08:40:12.004096 1 Util.cpp:166] commandline: --use_gpu=False --trainer_count=1
Cache file /root/.cache/paddle/dataset/fit_a_line.tar/fit_a_line.tar not found, downloading https://github.com/PaddlePaddle/book/raw/develop/01.fit_a_line/fit_a_line.tar
[==================================================]
Cache file /root/.cache/paddle/dataset/uci_housing/housing.data not found, downloading https://archive.ics.uci.e/ml/machine-learning-databases/housing/housing.data
[==================================================]
Predicted price: $12,316.63
Predicted price: $13,830.34
Predicted price: $11,499.34
Predicted price: $17,395.05
Predicted price: $13,317.67
Predicted price: $16,834.08
Predicted price: $16,632.04
如果沒有成功運行該代碼,報錯信息如下,說明安裝的 paddlepaddle 版本過低,請安裝高版本的 paddlepaddle
I0116 13:53:48.957136 15297 Util.cpp:166] commandline: --use_gpu=False --trainer_count=1
Traceback (most recent call last):
File "housing.py", line 13, in <mole>
parameters=paddle.dataset.uci_housing.model(),
AttributeError: 'mole' object has no attribute 'model'
最後提示
有很多學習者會出現明明安裝完成 PaddlePaddle 了,但是在 PaddlePaddle 的時候,在初始化 PaddlePaddle 這一行代碼出錯
paddle.init(use_gpu=False, trainer_count=1)
這個多數是讀者的電腦不支持 AVX 指令集,而在 PaddlePaddle 的時候,安裝的是支持 AVX 指令集的版本,所以導致在初始化 PaddlePaddle 的時候報錯。所以在安裝或者編譯 PaddlePaddle 安裝包時,要根據讀者電腦本身的情況,選擇是否支持 AVX 指令集。查看電腦是否支持 AVX 指令集,可以在終端輸入以下命令,輸出 Yes 表示支持,輸出 No 表示不支持。
if cat /proc/cpuinfo | grep -i avx; then echo Yes; else echo No; fi
項目代碼
GitHub 地址:https://github.com/yeyupiaoling/LearnPaddle
參考資料
http://paddlepaddle.org/
https://pip.pypa.io/en/stable/
http://www.runoob.com/
http://www.linuxidc.com/Linux/2016-12/138489.htm
https://www.jianshu.com/p/c6264cd5f5c7
