源码构建docker教程(源码安装docker)
本文目录一览:
- 1、如何编译Docker源码
- 2、docker菜鸟教程是什么?
- 3、如何在Ubuntu上借助Docker管理Linux容器
- 4、怎么用虚拟机搭建docker集群
- 5、如何搭建及使用docker registry
- 6、如何使用Dockerfile构建镜像
如何编译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下面进行依赖包的下载。通过上面的方法把所有依赖包下载完以后就可以进行编译了。
docker菜鸟教程是什么?
Docker视频免费下载
链接:
提取码:1r9g
Docker视频|走进Docker|从Docker到CaaS(一)Docker集群管理介绍|从Docker到CaaS(三)Kubernetes|从Docker到CaaS(六)微服务与CaaS|从Docker到CaaS(二)Docker 容器管理工具|从 Docker 到 CaaS(五)灵雀云部署 Docker 容器|
如何在Ubuntu上借助Docker管理Linux容器
虽说标准的硬件虚拟化技术(比如KVM、Xen或Hyper-V)擅长于在一个物理主机上运行多个操作系统的完全隔离的实例,但这种虚拟化技术在性能、资源和资源配置时间等方面存在各种各样的开销。标准的机器虚拟化实际上可能没有必要,这取决于你的实际使用场合。
另外一种轻型虚拟化方法就是所谓的Linux容器(LXC),它提供了操作系统级别的虚拟化。由于不存在运行虚拟机带来的开销,LXC让用户可以在轻型容器沙盒里面运行标准Linux操作系统的多个实例。如果你搭建一个可复制的开发/测试环境,或者在安全沙盒里面部署应用程序,容器就派得上大用场。
Docker就是为了便于部署Linux容器而开发的这样一款开源工具。Docker正迅速成为容器技术方面的一项事实上的标准,已经被诸如Ubuntu和红帽之类的各大Linux发行版所采用。
我在本教程中将演示如何在Ubuntu 14.04上,借助Docker管理Linux容器。请注意:对Ubuntu的早期版本而言,操作步骤可能略有不同。
眼下,Ubuntu上可用的Docker程序包只支持64位系统。想在32位机器上运行它,你就要利用源代码构建32位版本的Docker(详见这里)。
安装Docker
借助apt-get命令,安装Docker是件轻而易举的事。
$ sudo apt-get install docker.io
为了允许非根用户也可以运行Docker,将你自己添加到docker群组。下面这个命令会允许当前用户运行Docker,无需根用户权限。
$ sudo usermod -a -G docker $USER
退出,然后重新登录,以激活群组成员的变化。
下一步,编辑Docker配置文件,以便更新Docker二进制代码的位置。
$ sudo vi /etc/default/docker.io
DOCKER="/usr/bin/docker.io"
重启Docker服务。
$ sudo service docker.io restart
管理Docker容器
如果你想启动Ubuntu操作系统的一个新的Docker容器,首先需要获取Ubuntu Docker映像文件。下面这个命令会通过网络下载Docker映像文件。
$ docker pull ubuntu
你可以以一种交互模式来开启Ubuntu Docker,如下所示。最后一个参数“/bin/bash”是一旦启动就将在容器里面执行的命令,这里是一个简单的bash外壳命令。
$ docker run -i -t ubuntu /bin/bash
上述命令会立即启动一个Ubuntu容器(这正是容器的魅力所在!),并为你提供容器里面的外壳提示符。这时候,你应该能够访问沙盒环境里面的标准的Ubuntu操作系统了。
想退出Docker容器,在容器里面的提示符处键入“exit”。
你可以启动不同形式的容器。比如,想启动Fedora容器,请执行下面这个命令:
$ docker.io run -i -t fedora /bin/bash
如果本地没有Fedora Docker映像文件,该命令就会首先自动下载映像文件,然后启动Docker。
如果你想启动采用某个发行版版本的容器,也可以这么做。比如说,想启动Ubuntu 13.04 Docker,请执行下面这个命令:
$ docker.io run -i -t ubuntu:13.04 /bin/bash
容器网络
Docker使用Linux网桥将容器彼此互联起来,并将它们连接到外部网络。安装了Docker后,你应该会看到默认情况下自动组建的docker0 Linux网桥。你创建的每个容器都将连接到docker0网桥接口。
自定义Linux网桥
如果你想,也可以使用自定义Linux网桥将诸容器互联起来。为此,你可以建立一个自定义网桥,并对它进行配置,如下所示。你可以为该网桥分配一个单独的子网,并且从子网为Docker分配IP地址。我会使用10.0.0.0/24作为Docker子网。
$ sudo apt-get install bridge-utils
$ sudo brctl addbr br0
$ sudo ifconfig br0 10.0.0.1 netmask 255.255.255.0
想让Docker使用自定义网桥,将“-b=br0”添加到/etc/default/docker.io中的DOCKER_OPTS变量,然后重启Docker服务。
$ sudo service docker.io restart
至此,任何新的容器都会连接到br0,其IP地址会自动从10.0.0.0/24来分配。
其他定制
还有另外几种方法可以定制Docker的默认网络设置,主要是通过改动/etc/default/docker.io中的DOCKER_OPTS变量来实现。
“-dns 8.8.8.8 -dns 8.8.4.4”:指定容器使用的DNS服务器。
“-icc=false”:让诸容器彼此隔离开来。
故障排查
1. 运行docker.io命令时,你会遇到下面这个错误。
dial unix /var/run/docker.sock: no such file or directory(没有此类文件或目录)
出现这个错误,可能是由于Docker守护程序没在运行。检查Docker守护程序的状态,确保先启动它。
$ sudo service docker.io status
$ sudo service docker.io start
怎么用虚拟机搭建docker集群
与安装Docker Compose相似,你可以从GitHub的release分支中获取Machine的二进制安装文件,也可以下载源代码自己编译安装或者安装Docker ToolBox,ToolBox打包了所有的Docker工具,提供UI界面的安装。
例如,在OS X 机器上,你可以在Github上获取安装文件,并存储在 /usr/local/bin/docker-machine路径下,然后赋予可执行权限,可以通过测试版本的方式测试是否安装正确。例如:
$ sudo curl -L
docker-machine-`uname -s`-`uname -m` /usr/local/bin/docker-machine
$ sudo chmod +x /usr/local/bin/docker-machine
$ docker-machine version
如何搭建及使用docker registry
registry是什么?
registry是Docker的镜像存储服务,docker hub上的registry镜像见Registry官方镜像,更多详细信息请参见源码。
搭建registry
在服务器上执行如下命令安装docker,这里选择腾讯云(Ubuntu Server 14.04.1 LTS 64位)镜像来创建服务器
curl -fsSL | sh
安装docker-compose Docker Compose是一个定义及运行多个Docker容器的工具。使用Docker Compose只需要在一个配置文件中定义多个Docker容器,然后使用一条命令将多个容器启动,Docker Compose会通过解析容器间的依赖关系,按先后顺序启动所定义的容器。详见Docker Compose
curl -L (uname -s)-$(uname -m) /usr/local/bin/docker-compose
chmod a+x /usr/local/bin/docker-compose
启动registry服务,此例中包含nginx和registry两个容器,涉及的包及配置文件请参见附件,解压后,直接执行如下命令即可创建服务。
docker-compose up -d
停止服务
docker-compose stop
重启服务
docker-compose restart
下线服务
docker-compose down
上传镜像
因为上面搭建的registry服务是http的,所以docker启动参数需要配置--insecure-registry localhost选项,修改/etc/default/docker文件
DOCKER_OPTS="--insecure-registry localhost"
重启docker
service docker restart
拉取上传镜像 docker pull;docker tag;docker push(tag默认为latest)
docker pull hello-world
docker tag hello-world localhost/library/hello-world
docker push localhost/library/hello-world
下载镜像
docker pull localhost/library/hello-world
删除镜像
docker rmi localhost/library/hello-world
获取镜像仓库列表
# curl
{"repositories":["library/hello-world"]}
未上传镜像前的输出如下:
# curl
{"repositories":[]}
获取镜像tag列表
# curl -X GET
{"name":"library/hello-world","tags":["latest"]}
获取镜像manifests信息
# curl -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X GET
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 1473,
"digest": "sha256:c54a2cc56cbb2f04003c1cd4507e118af7c0d340fe7e2720f70976c4b75237dc"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 974,
"digest": "sha256:c04b14da8d1441880ed3fe6106fb2cc6fa1c9661846ac0266b8a5ec8edf37b7c"
}
]
}
其中c54a2cc56cbb2f04003c1cd4507e118af7c0d340fe7e2720f70976c4b75237dc即为执行docker images时看到的IMAGE ID。 layers表示了镜像的层次关系,可以通过layers中的digest来拉取blob,见下面获取镜像blob
获取镜像blob
在上面获取hello-world:latest镜像的manifests信息中可以看到其只有一个layer,以此为例来看如何获取镜像blob。从拉取的结果可以看到获取的blob与文件sha256是一致的。执行docker pull实际上就是首先获取到镜像的manifests信息后,再拉取blob的。
# curl -s -X GET -o hello-world.blob
# ls -l hello-world.blob
-rw-r--r-- 1 root root 974 Nov 23 09:56 hello-world.blob
# sha256sum hello-world.blob
c04b14da8d1441880ed3fe6106fb2cc6fa1c9661846ac0266b8a5ec8edf37b7c hello-world.blob
##删除镜像(soft delete)
首先通过curl -i 参数获取到镜像的Docker-Content-Digest,registry 2.3及以后的版本必须在header中指定Accept: application/vnd.docker.distribution.manifest.v2+json,否则默认返回的是schema1的digest,其与schema2的digest不同,使用不指定上述头信息返回的digest删除时会返回404。
# curl -i -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X GET
HTTP/1.1 200 OK
Server: nginx/1.11.5
Date: Wed, 23 Nov 2016 02:17:51 GMT
Content-Type: application/vnd.docker.distribution.manifest.v2+json
Content-Length: 524
Connection: keep-alive
Docker-Content-Digest: sha256:a18ed77532f6d6781500db650194e0f9396ba5f05f8b50d4046b294ae5f83aa4
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:a18ed77532f6d6781500db650194e0f9396ba5f05f8b50d4046b294ae5f83aa4"
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 1473,
"digest": "sha256:c54a2cc56cbb2f04003c1cd4507e118af7c0d340fe7e2720f70976c4b75237dc"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 974,
"digest": "sha256:c04b14da8d1441880ed3fe6106fb2cc6fa1c9661846ac0266b8a5ec8edf37b7c"
}
]
}
根据上一步返回的Docker-Content-Digest删除,返回202表示删除成功
# curl -k -v -s -X DELETE
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 80 (#0)
DELETE /v2/library/hello-world/manifests/sha256:a18ed77532f6d6781500db650194e0f9396ba5f05f8b50d4046b294ae5f83aa4 HTTP/1.1
User-Agent: curl/7.35.0
Host: localhost
Accept: */*
**HTTP/1.1 202 Accepted**
* Server nginx/1.11.5 is not blacklisted
Server: nginx/1.11.5
Date: Wed, 23 Nov 2016 02:29:59 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Docker-Distribution-Api-Version: registry/2.0
* Connection #0 to host localhost left intact
确认结果
# curl -X GET
{"name":"library/hello-world","tags":null}
删除镜像(hard delete)
在上一步中,只是删除了镜像的manifests信息,解引用的blob还在占用磁盘空间,执行如下命令可以查看可以删除的blob
docker exec -it myregistry_registry_1 /bin/registry garbage-collect --dry-run /etc/registry/config.yml
要删除blob,释放磁盘空间,需要执行下面的命令。需要特别注意的是在执行下面的命令时registry必须是只读模式(只读模式可在registry配置文件中设置),否则可能会导致数据不一致。
docker exec -it myregistry_registry_1 /bin/registry garbage-collect /etc/registry/
如何使用Dockerfile构建镜像
你好,使用方法如下:
Dockerfile结构
dockerfile由4部分信息组成:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# This dockerfile uses the ubuntu image
# VERSION 2 - EDITION 1
# Author: docker_user
# Command format: Instruction [arguments / command] ..
# Base image to use, this must be set as the first line
FROM ubuntu
# Maintainer: docker_user docker_user at email.com (@docker_user)
MAINTAINER docker_user docker_user@email.com
# Commands to update the image
RUN echo "deb raring main universe" /etc/apt/sources.list
RUN apt-get update apt-get install -y nginx
RUN echo "\ndaemon off;" /etc/nginx/nginx.conf
# Commands when creating a new container
CMD /usr/sbin/nginx
其中#表注释,可以标注一些说明性的文字。
FROM关键字指定镜像的来源,默认为DockerHub,也可以写私有仓库的镜像,例如:localhost:5000/centos:6.7,如果本地已经存在指定的镜像名称,则会从本地缓存直接获取。MAINTAINER 指定镜像的作者,之后为镜像操作执行RUN、ADD等,最后是容器启动时发起的指令。
Dockerfile中的指令
FROM: 指定镜像名称,格式为FROM image 或FROM image:tag,例如FROM ubuntu 或 FROM ubuntu:12.04
MAINTAINER: 镜像作者 ,格式为 MAINTAINER name
RUN:格式为 RUN command 或 RUN ["executable", "param1", "param2"]。
前者将在 shell 终端中运行命令,即 /bin/sh -c;后者则使用 exec 执行。指定使用其它终端可以通过第二种方式实现,例如 RUN ["/bin/bash", "-c", "echo hello"]。
每条 RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 \ 来换行。
CMD:支持三种格式
1.CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式;
2.CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;
3.CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数;
指定启动容器时执行的命令,每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。
EXPOSE:格式为 EXPOSE port [port...]。
告诉 Docker 服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过 -P,Docker 主机会自动分配一个端口转发到指定的端口。
ENV:格式为 ENV key value。 指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持。这就对应程序语言中的变量定义,可在需要的时候引用。例如:
1
2
3
4
ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL | tar -xJC /usr/src/postgress …
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
ADD:格式为 ADD src dest。
该命令将复制指定的 src 到容器中的 dest。 其中 src 可以是Dockerfile所在目录的一个相对路径;也可以是一个 URL;还可以是一个 tar 文件(自动解压为目录)。
COPY:格式为 COPY src dest。
复制本地主机的 src(为 Dockerfile 所在目录的相对路径)到容器中的 dest。当使用本地目录为源目录时,推荐使用 COPY。
COPY和ADD的不同就是:ADD多了自动解压和支持URL路径的功能。
ENTRYPOINT:
两种格式:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2(shell中执行)。
配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。
每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效。
CMD和ENTRYPOINT比较:两个命令都是只能使用一次,并且都是在执行docker run指令时运行,如果有多个,只执行最后一条。
两者的不同在于参数的传递方式,如果在Dockerfile中定义如下指令
1
CMD echo hello
或
1
ENTRYPOINT ["echo","hello"]
那么在运行命令docker run containerId echo hello时,指定了CMD的输入结果为world,可以看出Dockerfile中指定的命令被覆盖了,而指定了ENTRYPOINT时,输出结果为hello echo world,可以看出指定的命令被作为ENTRYPOINT指定指令的参数了。
VOLUME:格式为 VOLUME ["/data"]。创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。不过此属性在Dockerfile中指定并没有什么意义,因为没有办法指定本地主机的目录。如果需要指定挂载点可以在执行docker run命令时指定:
1
docker run -it -v /home/fengzheng/ftp/:/data 859666d51c6d /bin/bash
USER:格式为 USER daemon。指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。
当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例如:RUN groupadd -r postgres useradd -r -g postgres postgres。要临时获取管理员权限可以使用 gosu,而不推荐 sudo。
WORKDIR:格式为 WORKDIR /path/to/workdir。为后续的 RUN、CMD、ENTRYPOINT 指令配置工作目录。可以使用多个 WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如
1
2
3
4
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
则最终路径为 /a/b/c。
ONBUILD:格式为 ONBUILD [INSTRUCTION]。
配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。
例如,Dockerfile 使用如下的内容创建了镜像 image-A。
1
2
3
4
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
如果基于 image-A 创建新的镜像时,新的Dockerfile中使用 FROM image-A指定基础镜像时,会自动执行ONBUILD 指令内容,等价于在后面添加了两条指令。
1
2
3
4
5
FROM image-A
#Automatically run the following
ADD . /app/src
RUN /usr/local/bin/python-build --dir /app/src
使用 ONBUILD 指令的镜像,推荐在标签中注明,例如 ruby:1.9-onbuild。
基于CentOS6.7并源码安装nginx
首先准备了nginx-1.9.9.tar.gz安装包和CentOS6-Base-163.repo(163源),将这两个文件放到同一目录下,并在此目录下创建名称为Dockerfile的文件。之后在此文件中实现源替换、nginx编译安装、及一些依赖包的安装,Dockerfile内容如下:
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
# this is a test ubuntu 12.04 image dockerfile
# Author:fengzheng
# Base image,this must be set as the first line
#localhost:5000/centos:6.7是我的私有仓库的镜像,可替换为centos:6.7(DockerHub中的镜像)
FROM localhost:5000/centos:6.7
MAINTAINER fengzheng
# Commands to update the image
RUN mkdir /usr/nginx1.9.9
ADD nginx-1.9.9.tar.gz /usr/nginx1.9.9/
#RUN yum -y install tar
#RUN tar -zxvf /usr/nginx1.9.9/nginx-1.9.9.tar.gz
RUN cd /etc/yum.repos.d/ mv CentOS-Base.repo CentOS-Base.repo.bak
ADD CentOS6-Base-163.repo /etc/yum.repos.d/
RUN cd /etc/yum.repos.d/ mv CentOS6-Base-163.repo CentOS-Base.repo \
yum clean all yum makecache \
yum -y install gcc \
yum -y install yum install -y pcre-devel \
yum -y install zlib zlib-devel \
yum -y install openssl openssl--devel \
cd /usr/nginx1.9.9/nginx-1.9.9/ ./configure make make install
#如果设置daemon off; nginx无法启动
#RUN echo "\ndaemon off;" /etc/nginx/nginx.conf
# Commands when creating a new container
# 启动nginx 需进入/usr/local/nginx/sbin 执行./configure
CMD /bin/bash
最后执行命令"docker build -t nginx-centos:6.7 ."
其中.表示在当前目录下搜索Dockerfile文件,-t参数指定镜像名称和tag。