##docker容器安装和配置###

#docker的git-hub网站:https://github.com/login

#docker官网hub仓库:https://hub.docker.com

#docker官网文档和镜像:https://docs.docker.com/samples/centos/

#docker官网的容器网络配置:https://docs.docker.com/engine/userguide/networking/#bridge-networks

#docker入门实战笔记(首选参考书):http://www.cnblogs.com/garfieldcgf/p/5462963.html

docker官方安装手册:https://docs.docker.com/engine/installation/linux/docker-ce/centos/#install-using-the-repository

docker官方yum源:https://download.docker.com/linux/centos/docker-ce.repo

docker资料大全:http://sofar.blog.51cto.com/353572/1598249

docker从入门到实践:https://yeasy.gitbooks.io/docker_practice/

注意:此文档最后讲解了如何配置docker自定义桥接网络。

##docker简介

    docker容器:Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,

然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

    说明:1、docker容器是以docker镜像来启动自己的环境。比KVM和VMware相比,占用的内存资源更少。

          2、在docker中可以有自己独立的网络配置,可以跟物理机用NAT网络模式通信。

          3、运行的docker容器中可以像虚拟机那样安装独立的服务软件。

 4、支持在源镜像中安装新软件,并将修改用commit保存成一个新镜像。然后移值到其他物理机中使用。

##docker的3个基本概念

镜像(Image)

容器(Container)

仓库(Repository)

理解了这三个概念,就理解了Docker的整个生命周期。

docker基本工作过程:

从仓库--->下载镜像--->运行在容器中

dokcer重新封装完整镜像过程:

基本镜像包--->运行在容器中--->安装所需软件和启动脚本--->停止容器--->commit生成新镜像--->测试在容器中运行新镜像。

用Dockerfile创建nginx新镜像的过程:

###docker镜像Image:就是一个只读模板。

例如:一个镜像可以包含一个完整的Centos操作系统环境,里面仅安装了Apache或用户需要的其它应用程序。镜像可以用来创建Docker容器。

Docker提供了一个很简单的机制来创建或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。

###docker容器Container:利用窗口来运行应用。

容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。

可以把容器看做是一个简易版的Linux环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的程序。

注:镜像是只读的,容器在启动的时候创建一层可写层作为最上层。

###Docker仓库Repository:是集中存放镜像文件的场所。

有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。

仓库分为公开仓库(public)和私有仓库(private)两种形式。

当然,用户可以在本地网络内创建一个私有仓库。

当用户创建了自己的镜像之后就可以使用push命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时,只需要从仓库上pull下来就可以了。

注:docker仓库的跟Git,注册服务器可以理解为Github这样的托管服务器。

#centos7安装和配置docker

#安装、启动docker

说明:centos7自带的网络yum源中包含docker的安装包。

yum  install  -y  docker-io  docker

rpm  -q  docker

service  docker  restart

chkconfig  docker  on

#实验:用docker快速部署nginx服务器:

源贴:

第1步:安装docker,启动服务,查看信息。

yum  install  -y  docker

service  docker  restart

chkconfig  docker  on

docker  info

第2步:查找nginx镜像,并抓取镜像(下载镜像),查看镜像。

docker  search  nginx   //查找

docker  pull  nginx     //下载

docker  p_w_picpaths   //查看所有镜像

docker  save  nginx  > nginx.tar   //导出nginx镜像

第3步:指定镜像创建容器并启动服务。访问nginx的测试网站。

docker  run  -d  -p  8088:80  --name  cn1  nginx

curl  127.0.0.1:8088    //ip是容器默认的ip,用ifconfig查看

参数说明:-d  放在后台执行(daemon)

-p  主机端口:容器端口   将容器的端口映射到主机上,目的是可以直接对外提供访问。

--name  指定容器名称

第5步:容器的管理。

docker  ps  -a //查看所有容器

docker  kill  cn1   //结束cn1这个容器

docker  start  cn1   //启动cn1容器

docker  rm   cn1   //删除cn1容器

实用命令:

以交互式方式进入容器:docker  exec  -it  容器名   bash

退出docker容器交互模式:exit  或  ctrl+p+q

创建docker桥接网卡:docker -d -b br1

-------------------

###docker常用命令汇总:

查看docker帮助:docker

查看docker的start命令帮助:docker  start  --help

查看docker信息:docker  info

查找nginx镜像:docker  search  nginx

设置docker镜像下载的仓库:

查看本地镜像:docker   p_w_picpaths

查看docker容器进程:docker   ps  -a

docker下载的镜像保存的路径:ls /var/lib/docker/

下载镜像:docker  pull  镜像名:tag号

镜像centos6下载实例(有yum源和网络):docker  pull  centos:6 

镜像centos7下载实例(无yum源和网络):docker  pull  centos:7 

例:docker  run  --name  webserver0  -p  8081:80 -d  -it   nginx   sh

说明:--name是指定容器名称,-p 8081:80是做端口映射,映射外部8081端口到容器的80端口,

      -d是daemon后台运行。-i是以交互式方式运行,-t是分配一个tty(伪终端)。

运行docker容器:docker  run  --name  实例名称 -d   镜像名

运行docker容器实例:docker run  --name  cto7  -d centos:7

交互的方式进入已经运行的容器中:docker exec -it centos:6 /bin/bash

查看docker容器日志(操作日志):docker  logs   id或Name

查看差异(容器和镜像对比):docker  diff   id或name

说明:CONTAINER_ID(是容器ID号)或Name(是容器名称)

停止docker容器:docker  stop   CONTAINER_ID或Name

启动docker容器:docker  restart   CONTAINER_ID或Name

删除docker窗口:docker  rm  CONTAINER_ID或Name

发布docker镜像:docker push new_p_w_picpath_name 

(不用做)登录registry server(login)

#登陆registry server; -e, --email="" Email; -p, --password="" Password; -u, --username="" Username 

#登录:docker login 

返回正常系统:ctrl+p+q(正常返回后台运行)   (或exit退出并停止运行)

进入docker实例环境:docker  attach  CONTAINER_ID或Name

docker其他命令:

#启动sshd服务:/sbin/sshd  -D

#退出,但不停止容器:Ctrl+P+Q 

#回到Docker下面,停止容器: docker stop <容器名或ID>

#启动容器: docker start <容器名或ID>

#提交当前容器到镜像:docker commit <容器ID> <NAME/VERSION>  新镜像名

#启动新容器,并且进行端口映射:

docker run -itd -p 50001:22 <刚才提交的镜像ID> /bin/bash 

查看容器日志:

docker logs Name/ID

# 显示一个运行的容器里面的进程信息:docker top Name/ID  

# 从容器里面拷贝文件/目录到本地一个路径:

docker cp Name:/container_path to_path

docker cp ID:/container_path to_path 

#启动sshd服务:/usr/sbin/sshd -D 

-------------

保存和加载镜像(save、load) 

当需要把一台机器上的镜像迁移到另一台机器的时候,需要保存镜像与加载镜像。

#保存镜像到一个tar包; -o, --output="" Write to an file 

方法一:docker save p_w_picpath_name -o file_path 

方法二:docker save p_w_picpath_name > file_path

# 加载一个tar包格式的镜像; -i, --input="" Read from a tar archive file 

方法一:docker load -i file_path  

方法二:docker load  < file_path

# 机器a导出镜像: docker save p_w_picpath_name > /home/save.tar

# 使用scp将save.tar拷到机器b上。

#机器b导入镜像: $docker load < /home/save.tar 

-------------

利用 commit 理解镜像构成

用commit创建镜像的思路:下载镜像--->运行容器--->在容器中修改文件--->commit生成新镜像--->查镜像列表--->测试新镜像。

实例:下载nginx镜像,在容器中运行nginx镜像,在容器中修改文件,生成新镜像并测试。

具体实施:

第1步:下载nginx镜像。

docker  pull  nginx

第2步:在容器中运行镜像。

docker run --name webserver -d -p 801:80  nginx

curl  127.0.0.1:801

第3步:进入docker容器,在容器中修改文件。

docker  exec  -it  webserver  bash

echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

exit  或  ctrl+p+q

curl  127.0.0.1:801

第4步:查看差异,并commit生成新镜像。

docker commit 的语法格式为:

docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]

查看差异:docker  diff  webserver

生成新镜像:

方法一:docker  commit   webserver   nginx:v2

方法二:docker commit \

    --author "flyer <2559721591@qq.com>" \

    --message "修改了默认网页" \

    webserver \

    nginx:v2

说明:--author声明作者信息,--message声明所做的修改。

第5步:查看镜像列表,在容器中运行新镜像。测试访问。

docker p_w_picpaths

docker history nginx:v2

docker run --name web2 -d -p 802:80 nginx:v2

curl  127.0.0.1:802

附加任务:将生成的nginx:v2镜像导出成nginx_v2.tar文件,复制到另一台linux主机上,导入nginx_v2.tar到docker仓库中。

1、导出nginx:v2镜像。

方法一:docker  save  nginx:v2  >  nginx_v2.tar

方法二:docker  save  nginx:v2  -o  nginx_v2.tar

2、导入nginx:v2.tar镜像。

方法一:docker  load  < nginx_v2.tar

方法二:docker  load  -i nginx_v2.tar

注意:慎用commit生成新镜像。

    因为commit生成的新镜像是属于完整镜像包,会导致镜像包太大。

生成的镜像也被称为黑箱镜像,换句话说,就是除了制作镜像的人知道执行过

什么命令、怎么生成的镜像,别人根本无从得知。

    docker commit 命令除了学习之外,还有一些特殊的应用场合,比如被***后保存现场等。

 但是,不要使用 docker commit 定制镜像,定制行为应该使用 Dockerfile 来完成。

 下面的章节我们就来讲述一下如何使用 Dockerfile 定制镜像。

-------------

使用Dockerfile创建nginx的新镜像:

使用 Dockerfile 定制镜像

    从刚才的 docker commit 的学习中,我们可以了解到,镜像的定制实际上就是定制每一层所添加的配置、文件。

如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,

那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。

Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

用Dockerfile创建镜像的思路:

准备目录,创建Dockerfile文件--->docker  build生成镜像--->查镜像列表--->测试新镜像。

还以之前定制 nginx 镜像为例,这次我们使用 Dockerfile 来定制。

第1步:在一个空白目录中,建立一个文本文件,并命名为 Dockerfile:

mkdir mynginx

cd mynginx

touch Dockerfile

其内容为:cat  Dockerfile

FROM nginx

EXPOSE  80

RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

这个 Dockerfile 很简单,一共就两行。涉及到了两条指令,FROM 和 RUN。

Dockerfile内容解释:

FROM 指定基础镜像

   所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制。就像我们之前运行了一个 nginx 镜像的容器,

再进行修改一样,基础镜像是必须指定的。而 FROM 就是指定基础镜像,因此一个 Dockerfile 中 FROM 是必备的指令,

并且必须是第一条指令。

第2步:用Dockerfile生成镜像nginx:v3:

docker  build -t nginx:v3  .

docker  p_w_picpaths

第3步:启动新容器cn5运行镜像nginx:v3:

docker run -d -p 803:80 --name web3 nginx:v3

docker  ps

第4步:测试访问:

curl  127.0.0.1:803  或 firefox  127.0.0.1:803 看到网页内容如下

Hello, Docker!

-------------

实例:用Dockerfile以centos6的docker镜像为基础,创建新镜像mysql:v2。并在容器中运行新镜像,进行测试。

第1步:准备目录,创建Dockerfile文件。

mkdir  mysqltest

cd  mysqltest

vi  Dockerfile  全文内容如下

#指定参考镜像,run运行命令。

FROM centos:6

RUN yum  install  -y  mysql-server  mysql 

#修改my.cnf配置文件。

RUN sed -i '1a\character_set_server=utf8'  /etc/my.cnf

RUN sed -i '2a\default-storage-engine=innodb'  /etc/my.cnf

RUN sed -i '3a\log-bin=mysql-bin'  /etc/my.cnf

RUN sed -i '4a\max_connections=100'  /etc/my.cnf

RUN sed -i '5a\#server-id=2'  /etc/my.cnf

RUN sed -i '6a\skip-name-resolve'  /etc/my.cnf

RUN sed -i '$a\[mysql]'  /etc/my.cnf

RUN sed -i '$a\default-character-set=utf8'  /etc/my.cnf

RUN sed -i '$a\prompt="(\\u@\\h) [\\d]> " '  /etc/my.cnf

#启动服务,创建一个新的管理员账号。

RUN  /etc/init.d/mysqld restart &&\

    chkconfig  mysqld  on &&\

    mysql -e  "grant  all on *.* to admin@'%' identified by 'admin' with grant option;flush privileges;" &&\

    mysql -e  "grant  all on *.* to admin@'localhost' identified by 'admin' with grant option;flush privileges;" &&\

    mysql -e  "grant  replication  slave  on *.* to rep@'%' identified by 'rep';flush privileges;" &&\

    echo  'install ok.'

EXPOSE 3306

CMD ["/usr/bin/mysqld_safe"]

第2步:在mysqltest目录用Dockerfile生成mysql:v2镜像。

docker build -t mysql:v2  .

第3步:查看镜像列表,在容器中运行mysql:v2,查看docker所有的容器进程。

docker  p_w_picpaths

docker  run  --name  m2  -d  mysql:v2

docker  ps  -a

第4步:进入m2名称的容器的交互操作。执行命令,并退出容器。

docker  exec  -it  m2   m2   bash

mysql  -uadmin  -padmin  -e  "select  user,host,password  from  mysql.user;"

exit  或  ctrl+p+q  退出容器

docker  ps  -a

-------------

Dockerfile 指令详解

我们已经介绍了 FROM,RUN,还提及了 COPY, ADD,其实 Dockerfile 功能很强大,它提供了十多个指令。这里我们继续讲解剩下的指令。

资料网址:https://yeasy.gitbooks.io/docker_practice/p_w_picpath/dockerfile/

Dockerfile 指令详解:

COPY 复制文件

ADD 更高级的复制文件

CMD 容器启动命令

ENTRYPOINT 入口点

ENV 设置环境变量

ARG 构建参数

VOLUME 定义匿名卷

EXPOSE 暴露端口

WORKDIR 指定工作目录

USER 指定当前用户

HEALTHCHECK 健康检查

ONBUILD 为他人作嫁衣裳

-------------

Docker创建MySQL容器的p_w_picpath镜像:

目标:本文目的是创建一个MySQL的p_w_picpath,并且在新创建出来的容器里自动启动mysql服务接受外部连接

参考步骤(已验证OK):

必须的准备:保证创建Docker镜像的机器能够正常上网。因为创建新镜像时会自动从网络上下载文件。

第1步. 首先创建一个目录/ak,并在/ak目录下创建一个Dockerfile,文件内容如下

#以centos:centos6镜像作为基础镜像来创建新的镜像。

FROM centos:centos6

#作者信息

MAINTAINER Flyer "2559721591@qq.com"

#安装软件,修改my.cnf配置文件

RUN yum install -y mysql-server mysql

##以下RUN是一条完整的命令,其中&&是逻辑与,\命令换行符。

RUN /etc/init.d/mysqld start &&\

    mysql -e "grant all on *.* to 'admin'@'%' identified by 'admin';"&&\

    mysql -e "grant all on *.* to 'admin'@'localhost' identified by 'admin';"&&\

    mysql -e "grant all on *.* to 'admin'@'127.0.0.1' identified by 'admin';"&&\

    mysql -e "grant replication slave on *.* to 'rep'@'%' identified by 'rep';"&&\

    mysql -e "grant all privileges on *.* to 'root'@'%' identified by 'admin';"&&\

    mysql -e "grant all privileges on *.* to 'root'@'localhost' identified by 'admin';"&&\

    mysql -u root -padmin -e "show databases;"

##内部端口号

EXPOSE 3306

##容器启动时要执行的命令

CMD ["/usr/bin/mysqld_safe"]

第2步. 在Dockerfile所在目录下运行build命令来生成p_w_picpath文件,这里使用mysql_server作为p_w_picpath文件名

docker build -t mysql_server  ./    

说明:可能第1次会失败,因为要同步网络数据,请再执行一遍上面的命令。

运行完build命令后,可以使用“Docker p_w_picpaths”来查看。

第3步. 启动容器

3.1 首先使用下面的命令来启动容器

docker run --name=mysqlserver -dit -P  mysql_server

说明:启动容器,名称为mysqlserver,以后台方式运行,映射随机端口,容器的镜像为mysql_server。

交互的方式进入已经运行的容器中:docker exec -it  mysqlserver  bash

启动完容器后,可以使用“docker ps”来查看,此时可以看PORTS列内容为“0.0.0.0:49153->3306/tcp”,容器的3306端口会被映射到宿主机器的49153端口,这样我们就可以通过宿主机器的49153端口来连接了,比如:

mysql -h <宿主机器> -u root -padmin -P 49153  

3.2 另外在运行容器的时候也可以通过下面的命令

docker run --name=mysqlserver -d -p 3306:3306 mysql_server  

此时容器的3306端口会被映射到宿主机器的3306端口,这样我们就可以通过宿主机器的3306端口访问mysql了

mysql -h <宿主机器> -u root -padmin  

3.3 还有一种情况就是为了安全考虑,我只希望当前的宿主机器可以访问mysql服务,此时我们可以

docker run --name=mysqlserver -d -p 127.0.0.1:3306:3306 mysql_server  

4.1 导出mysql_server镜像。

方法一:docker  save  mysql_server  >  mysql_server.tar

方法二:docker  save  mysql_server  -o  mysql_server.tar

4.2 导入mysql_server.tar镜像。

方法一:docker  load  < mysql_server.tar

方法二:docker  load  -i mysql_server.tar

-------------

实例:在centos:7这个docker镜像中安装mysql-server和mysql,并将mysqld服务设置成启动docker容器时自动启动,将修改后的镜像生成一个新镜像mysqld。

第1步:下载centos:7这个docker镜像。

docker  pull  centos:7

docker  p_w_picpaths

第2步:用centos:7镜像开启一个docker容器,安装mysql-server、mysql软件

docker  run  --name  mysqld_1   -it  centos:7   sh

yum  install  -y  mysql-server   mysql

service  mysqld  restart

chkconfig  mysqld  on

第3步:创建随docker容器同步启动的mysqld的启动脚本。

vi  /home/mysqld_auto.sh

#!/bin/sh

/etc/init.d/mysqld  restart

/bin/bash

:wq保存并退出vi

添加x执行权限:chmod  -v  +x  /home/mysqld_auto.sh

第4步:退出docker容器,将修改保存成一个新镜像。

ctrl+p+q

docker  ps  -a

docker  stop  mysqld_1

docker  commit  mysqld_1  mysqld

docker  p_w_picpaths

第5步:运行测试新镜像:

docker  run  --name  m1  -it  mysqld  /home/mysqld_auto.sh

service  mysqld  status

mysql  -e  "show  databases;"

ctrl+p+q

docker  ps  -a

-------------

搭建私有仓库

系统环境: CentOS 7.2 

192.168.0.179:Docker仓库 

192.168.0.60:客户端

安装并启动docker

yum -y install docker

service docker  start

chkconfig  docker  on

搭建私有仓库

179上下载registry镜像

docker pull registry 

防火墙添加运行5000端口

iptables -I INPUT 1 -p tcp --dport 5000 -j ACCEPT 

下载完之后我们通过该镜像启动一个容器

复制代码 代码如下:

docker run -d -p 5000:5000 --privileged=true -v /opt/registry:/tmp/registry registry 

参数说明:

1.-v /opt/registry:/tmp/registry :默认情况下,会将仓库存放于容器内的/tmp/registry目录下,指定本地目录挂载到容器

2.–privileged=true :CentOS7中的安全模块selinux把权限禁掉了,参数给容器加特权,不加上传镜像会报权限错误(OSError:[Errno 13] Permission denied: ‘/tmp/registry/repositories/liibrary')或者(Received unexpected HTTP status: 500 Internal Server Error)错误

客户端上传镜像

修改/etc/sysconfig/docker(Ubuntu下配置文件地址为:/etc/init/docker.conf),增加启动选项(已有参数的在后面追加),之后重启docker,不添加报错,https证书问题。

OPTIONS='--insecure-registry 192.168.0.179:5000' #CentOS 7系统 other_args='--insecure-registry 192.168.0.179:5000' #CentOS 6系统 

因为Docker从1.3.X之后,与docker registry交互默认使用的是https,而此处搭建的私有仓库只提供http服务在docker公共仓库下载一个镜像

docker pull docker.io/centos 

来修改一下该镜像的tag

docker tag centos 192.168.0.179:5000/centos 

把打了tag的镜像上传到私有仓库

docker push 192.168.0.179:5000/centos 

客户端添加私有仓库地址

# 添加这一行 ADD_REGISTRY='--add-registry 192.168.0.179:5000' 

加上后,search镜像,私有仓库和docker hub上都会显示; 

不加搜索私有仓库,需要命令中指定私有仓库ip

使用仓库中的镜像

查询私有仓库中的所有镜像,使用docker search命令:

curl -u myuser https://registry_ip:5000/v1/searchcurl registry_ip:5000/v1/search 

docker search registry_ip:5000/  #centos 7 docker search registry_ip:5000/library #centos 6 

查询仓库中指定账户下的镜像,则使用如下命令:

docker search registry_ip:5000/account/ 

-------------

###Centos7 下建立 Docker 桥接网络

centos7宿主机上建立Docker桥接物理网络过程

宿主机网卡信息:

name:eth0

IP:192.168.100.99

GATEWAY:192.168.100.2

DNS:192.168.100.2

1. 停止Docker服务

~#:service docker stop

2.删除docker0网卡

~#:ip link set dev docker0 down

~#:brctl delbr docker0

3.新建桥接物理网络虚拟网卡br0

~#:brctl addbr br0

~#:ip link set dev br0 up

~#:ip addr add 192.168.100.100/24 dev br0 #为br0分配物理网络中的ip地址

~#:ip addr del 192.168.100.99/24 dev eth0 #将宿主机网卡的IP清空

~#:brctl addif br0 eth0 #将宿主机网卡挂到br0上

~#:ip route del default #删除原路由

~#:ip route add default via 192.168.100.2 dev br0 #为br0设置路由

4.设置docker服务启动参数

这里要注意的是,不同的Linux操作系统docker的配置文件所在不同

centos 在/etc/sysconfig/docker

其他操作系统请前往下面的网址

https://docs.docker.com/installation/#installation

~#:vim /etc/sysconfig/docker #在OPTIONS='--selinux-enabled'这行中修改为OPTIONS='--selinux-enabled -b=br0'即让docker服务启动时使用br0网卡进行桥接

5.启动docker服务

~#:service docker start

6.安装pipework

~#:git clone https://github.com/jpetazzo/pipework

~#:cp ~/pipework/pipework /usr/local/bin/

7.启动一个手动设置网络的容器

这里最好不要让docker自动获取ip,下次启动会有变化而且自动获取的ip可能会和物理网段中的ip冲突

~#:docker run -itd --net=none --name=test centos7 /bin/bash

9.为test容器设置一个与桥接物理网络同地址段的ip@网关

~#:pipework br0 test 192.168.100.11/24@192.168.100.2

10.进入容器查看ip

~#:docker attach test

-------------

Docker创建httpd容器的p_w_picpath镜像:

目标:本文目的是创建一个MySQL的p_w_picpath,并且在新创建出来的容器里自动启动mysql服务接受外部连接

参考步骤(未验证):

1. 首先创建一个目录并在目录下创建一个Dockerfile,文件内容如下

##第1步:在当前目录创建Dockerfile文件,内容如下:

##以#号开头的为注释内容,只是测试代码(可以不写)。

#FROM是指定新镜像是以centos:centos6这个镜像作为基础镜像来创建的。

FROM centos:centos6 

#镜像的创建者信息。

MAINTAINER Flyer <2559721591@qq.com> 

#RUN代码用于指定要执行的命令。通常用于安装软件。

#RUN yum -y update; yum clean all 

#RUN yum -y install httpd && yum clean all 

RUN yum -y install httpd

RUN touch  /var/www/html/index.html 

RUN echo "apachetest web site!!!! --Flyer " > /var/www/html/index.html 

#container容器内部服务开启的端口。主机上要用还得在启动container时,做host-container的端口映射:

EXPOSE 80 

#例如:运行容器时映射端口:docker run -d -p 127.0.0.1:33301:22 centos6-ssh

#Simple startup script to avoid some issues observed with container restart 

#注意脚本目录,将脚本添加到docker容器的/根目录中。

ADD run-httpd.sh  /run-httpd.sh

#赋予脚本执行权限

RUN chmod -v +x  /run-httpd.sh  

#Container容器启动时执行的命令,但是一个Dockerfile中只能有一条CMD命令,多条则只执行最后一条CMD。

CMD ["/run-httpd.sh"]   

##第2步####

在Dockerfile文件所在的目录创建run-httpd.sh脚本,内容如下:

cat > run-httpd.sh <<EOK 

#!/bin/bash 

#Make sure we are not confused by old, incompletely-shutdown httpd 

#context after restarting the container.  httpd won't start correctly 

#if it thinks it is already running. 

rm -rf /run/httpd/* 

exec /usr/sbin/apachectl -D FOREGROUND

EOK

注意:Dockerfile需借助脚本来重启httpd服务,并且最好放置于同一目录

##第3步:在Dockerfile文件的目录生成镜像文件fly/httpd:centos6。

docker  build  -t   fly/httpd:centos6  ./ 

docker  p_w_picpaths  //查看所有的镜像

此时通过Dockerfile创建的镜像已经创建成功,并无报错。

#第4步:运行容器

方法一:启动容器并映射到随机端口,容器名称为httpdk:

以后台方式运行:docker run --name=httpdk -d -P  fly/httpd:centos6 

查看docker容器进程:docker  ps  -a

进入已运行的容器:docker  exec  -it  httpdk  /bin/bash

退出交互模式:ctrl+p+q   [退出后容器仍然运行中]

以交互式方式运行:

docker run  --name=httpda -it -p 801:80 fly/httpd:centos6   /bin/bash

方法二:启动并指定映射端口:

说明:将容器的80端口映射到物理机801端口

docker run --name=web802 -d -p 802:80 fly/httpd:centos6  

curl  http://localhost:802    显示结果如下

apachetest web site!!!! --Flyer  //curl测试成功 

4.1 导出mysql_server镜像。

方法一:docker  save  fly/httpd:centos6  >  httpd_centos6.tar

方法二:docker  save  fly/httpd:centos6  -o  httpd_centos6.tar

4.2 导入mysql_server.tar镜像。

方法一:docker  load  <  httpd_centos6.tar

方法二:docker  load  -i  httpd_centos6.tar

-------------

Docker Dockerfile详解

原贴:http://blog.csdn.net/wsscy2004/article/details/25878223

要点一:如何使用Dockerfile

Dockerfile用来创建一个自定义的p_w_picpath,包含了用户指定的软件依赖等。

例:当前目录下包含Dockerfile,使用命令build来创建新的p_w_picpath,并命名为edwardsbean/centos6-jdk1.7:

docker  build -t edwardsbean/centos6-jdk1.7  /.

要点一:Dockerfile关键字

问题1:如何编写一个Dockerfile,格式如下:

# CommentINSTRUCTION arguments

FROM 基于哪个镜像

RUN  安装软件用

MAINTAINER  镜像创建者

CMD  命令

说明:Container启动时执行的命令,但是一个Dockerfile中只能有一条CMD命令,多条则只执行最后一条CMD.

CMD主要用于container时启动指定的服务,当Docker run command的命令匹配到CMD command时,会替换CMD执行的命令。如:

Dockerfile:

CMD echo hello world

运行一下试试:

docker run centos-cmd  运行的结果如下:

hello world

一旦命令匹配:

docker run centos-cmd echo hello edwardsbean    运行的结果如下:

hello edwardsbean

ENTRYPOINT

说明:container容器启动时执行的命令,但是一个Dockerfile中只能有一条ENTRYPOINT命令,如果多条,则只执行最后一条

ENTRYPOINT没有CMD的可替换特性

USER

使用哪个用户跑container

如:

ENTRYPOINT ["memcached"]

USER daemon

EXPOSE  端口号

说明:container容器内部服务开启的端口。主机上要用还得在启动container时,做host-container的端口映射:

docker run -d -p 127.0.0.1:33301:22 centos6-ssh

解释:container ssh服务的22端口被映射到主机的33301端口

ENV  环境变量

功能:用来设置环境变量,比如:

ENV LANG en_US.UTF-8

ENV LC_ALL en_US.UTF-8

ADD  源文件   /目标文件

功能:将文件<src>拷贝到container的文件系统对应的路径<dest>

说明:1、所有拷贝到container中的文件和文件夹权限为0755,uid和gid为0

2、如果文件是可识别的压缩格式,则docker会帮忙解压缩

3、如果要ADD本地文件,则本地文件必须在 docker build <PATH>,指定的<PATH>目录下

4、如果要ADD远程文件,则远程文件必须在 docker build <PATH>,指定的<PATH>目录下。比如:

例如:

docker build github.com/creack/docker-firefox

说明:docker-firefox目录下必须有Dockerfile和要ADD的文件

注意:使用docker build - < somefile方式进行build,是不能直接将本地文件ADD到container中。只能ADD url file.

ADD只有在build镜像的时候运行一次,后面运行container的时候不会再重新加载了。

VOLUME

可以将本地文件夹或者其他container的文件夹挂载到container中。

WORKDIR

说明:切换目录用,可以多次切换(相当于cd命令),对RUN,CMD,ENTRYPOINT生效

ONBUILD

说明:ONBUILD 指定的命令在构建镜像时并不执行,而是在它的子镜像中执行

详见here

=========================

Docker:添加自定义网桥

    

    Docker服务进程在启动的时候会生成一个名为docker0的网桥,容器默认都会挂载到该网桥下,

但是我们可以通过添加docker启动参数-b Birdge 或更改docker配置文件来选择使用哪个网桥。

操作系统:centos7

删除docker0网桥:

service docker stop //关闭docker服务  

ip link set dev docker0 down //关闭docker0网桥   

ip link del dev docker0       //删除docker0网桥  

自定义网桥设置(/etc/sysconfig/network-scripts/ifcfg-br0文件)

DEVICE="br0"  

ONBOOT="yes"  

TYPE="Bridge"  

BOOTPROTO="static"  

IPADDR="10.10.10.20"  

NETMASK="255.255.255.0"  

GATEWAY="10.10.10.20"  

DEFROUTE="yes"  

NM_CONTROLLED="no"  

重启网络服务

service network restart  

查看网桥

[black@test opt]$ yum install -y bridge-utils

[black@test opt]$ brctl show  

bridge name     bridge id               STP enabled     interfaces  

br0             8000.32e7297502be       no                

virbr0          8000.000000000000       yes  

接下来我们需要重新启动docker,可以在启动docker服务进程时使用以下两种方式:

第一种:-b 参数指定网桥

[root@test opt]# docker -d -b br0  

INFO[0000] Listening for HTTP on unix (/var/run/docker.sock)   

INFO[0000] [graphdriver] using prior storage driver "devicemapper"   

WARN[0000] Running modprobe bridge nf_nat failed with message: , error: exit status 1   

INFO[0000] Loading containers: start.                     

......  

INFO[0000] Loading containers: done.                      

INFO[0000] Daemon has completed initialization            

INFO[0000] Docker daemon      commit=786b29d execdriver=native-0.2 graphdriver=devicemapper version=1.7.1  

不知道为什么这样启动docker 服务进程会阻塞当前终端(︶︿︶),只好重新开一个终端,然后运行一个容器

[root@test shell]# docker run -ti --rm centos:latest  

[root@3c6874559411 /]# ifconfig  

eth0      Link encap:Ethernet  HWaddr 02:42:0A:0A:0A:01    

          inet addr:10.10.10.1  Bcast:0.0.0.0  Mask:255.255.255.0  

          inet6 addr: fe80::42:aff:fe0a:a01/64 Scope:Link  

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1  

          RX packets:5 errors:0 dropped:0 overruns:0 frame:0  

          TX packets:6 errors:0 dropped:0 overruns:0 carrier:0  

          collisions:0 txqueuelen:0   

          RX bytes:418 (418.0 b)  TX bytes:508 (508.0 b)  

容器成功使用br0网桥。

第二种:修改/etc/sysconfig/docker文件

我在进行这种操作的时候遇到了一点问题,我修改了/etc/sysconfig/docker文件

[root@test opt]# vi /etc/sysconfig/docker   

# /etc/sysconfig/docker  

# Other arguments to pass to the docker daemon process  

# These will be parsed by the sysv initscript and appended  

# to the arguments list passed to docker -d  

other_args="-b br0"  

接着使用service docker start启动docker服务,但是other_args并不生效,在centos7下servicer docker start仍然会采用systemctl start docker.service命令来运行,于是我就打开/usr/lib/systemd/system/docker.service查看

[root@test opt]# vi /lib/systemd/system/docker.service   

[Unit]  

Description=Docker Application Container Engine  

Documentation=https://docs.docker.com  

After=network.target docker.socket  

Requires=docker.socket  

[Service]  

ExecStart=/usr/bin/docker -d  -H fd://  

MountFlags=slave  

LimitNOFILE=1048576  

LimitNPROC=1048576  

LimitCORE=infinity  

  

[Install]  

WantedBy=multi-user.target  

发现ExecStart一项并没有运行参数,于是将ExecStart改为/usr/bin/docker -d -b br0 -H fd://,运行docker服务,启动一个容器发现能够成功使用br0网桥。

-------------------------------------------

在网上看到了一种更好的方法,将docker.service改为如下

[black@test ~]$ vi /usr/lib/systemd/system/docker.service   

[Unit]  

Description=Docker Application Container Engine  

Documentation=https://docs.docker.com  

After=network.target docker.socket  

Requires=docker.socket  

[Service]  

EnvironmentFile=-/etc/sysconfig/docker  

ExecStart=/usr/bin/docker -d $other_args  -H fd://  

MountFlags=slave  

LimitNOFILE=1048576  

LimitNPROC=1048576  

LimitCORE=infinity  

  

[Install]  

WantedBy=multi-user.target  

这个时候在other_args中添加的参数就有效了。