一、Docker 架构
http://blog.csdn.net/u012562943/article/category/6048991/1
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和建立Docker容器。
Docker 容器经过 Docker 镜像来建立。
容器与镜像的关系相似于面向对象编程中的对象与类。
Docker 面向对象
容器 对象
镜像 类html

Docker 镜像(Images) Docker 镜像是用于建立 Docker 容器的模板。
Docker 容器(Container) 容器是独立运行的一个或一组应用。
Docker 客户端(Client) Docker 客户端经过命令行或者其余工具使用 Docker API (https://docs.docker.com/reference/api/docker_remote_api) 与 Docker 的守护进程通讯。
Docker 主机(Host) 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。
Docker 仓库(Registry) Docker 仓库用来保存镜像,能够理解为代码控制中的代码仓库。Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。
Docker Machine Docker Machine是一个简化Docker安装的命令行工具,经过一个简单的命令行便可在相应的平台上安装Docker,好比VirtualBox、 Digital Ocean、Microsoft Azure。
Docker项目的目标是实现轻量级的操做系统虚拟化解决方案。Docker的基础是linux容器(LXC)等技术。
二、Docker的概念,安装及镜像管理
2.一、docker的概念:
镜像:是一个只读的模板,相似于安装系统用到的那个iso文件,咱们经过镜像来完成各类应用的部署。镜像能够用来建立Docker容器
容器:镜像相似于操做系统,而容器相似于虚拟机自己。它能够被启动、开始、中止、删除等操做,每一个容器都是相互隔离的。能够把容器看作是一个简易版的linux环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
仓库:存放镜像的一个场所,仓库分为公开仓库和私有仓库。 最大的公开仓库是Docker hub(hub.docker.com),国内公开仓库(dockerpool.com)
2.二、docker安装启动:
yum install -y epel-release
yum instal -y docker
systemctl enable docker.service
systemctl start docker
2.三、镜像管理
2.3.一、获取镜像
语法:docker pull NAME[:TAG]
其中,NAME是镜像仓库的名称(用来区分镜像),TAG是镜像的标签(用来表示版本信息)
docker pull centos:从docker.com获取centos镜像
2.3.二、查看镜像
语法:docker images
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/nginx latest b175e7467d66 2 days ago 109 MB

docker tag centos long:为centos镜像设置标签为long,再使用docker images查看会多出来一行,打了标签的image id和centos的同样
[root@localhost ~]# docker tag nginx nginx_1.12.2
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/nginx latest b175e7467d66 2 days ago 109 MB
nginx_1.12.2 latest b175e7467d66 2 days ago 109 MB
docker inspect {IMAGE_ID | IMAGE_NAME}:获取镜像详细信息
[root@localhost ~]# docker inspect nginx
返回的是一个JSON格式的消息,若是咱们只要其中一项内容时,可使用参数-f来指定,例如,获取镜像的Architecture
[root@localhost ~]# docker inspect -f {{".Architecture"}} nginx
amd64
2.3.三、搜索镜像
docker search [image-name]:从docker仓库搜索docker镜像,后面是关键词
[root@localhost ~]# docker search nginx
2.3.四、删除镜像
docker rmi centos:用来删除指定镜像, 其中后面的参数能够是tag,若是是tag时,其实是删除该tag,只要该镜像还有其余tag,就不会删除该镜像。当后面的参数为镜像ID时,则会完全删除整个镜像,连通全部标签一同删除
[root@localhost ~]# docker rmi nginx_1111
Untagged: nginx_1111:latest
Untagged: docker.io/nginx@sha256:37350fbb4afbb1c01b6e542fe1537dd701e4430983d6d9c673cbb5eccdbec357
docker rmi -f centos:强制删除,通常不建议使用,会致使某些问题
[root@localhost ~]# docker rmi -f nginx_1111
Untagged: nginx_1111:latest
2.3.五、建立镜像
建立镜像的方法有如下3种方式:
(1)基于已有镜像的容器建立
(2)基于本地模板导入
(3)基于Dockerfile建立python
(1)基于已有镜像的容器建立
命令格式:docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] 主要选项: -a:做者信息 -m:提交消息 -p:提交时暂停容器运行 运行docker run后,进入到该容器中,咱们作一些变动,好比安装一些东西,而后针对这个容器进行建立新的镜像
[root@localhost ~]# docker ps -a //查看全部的容器
[root@localhost ~]# docker start 67d //启动ID为67d的容器,ID可简写为前3位
[root@localhost ~]# docker exec -it 67d /bin/bash //进入67d容器
[root@67dde53e0651 /]# yum install -y net-tools wget
[root@67dde53e0651 /]# exit
[root@localhost ~]# docker commit -m "centos_with_nettools_wget" -a "long" 67d centos_with_net //建立新的镜像
sha256:90f2a945a44d466c8a8d46dcdd4ab80f9f2aab79761482a1b5839d9ea2cf7904
tips:这个命令有点像svn的提交,-m 加一些改动信息,-a 指定做者相关信息 67d这一串为容器id,再后面为新镜像的名字
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos_with_net latest 90f2a945a44d 32 seconds ago 300.6MB
docker.io/centos latest 328edcd84f1b 11 days ago 192.5MB
long long 328edcd84f1b 11 days ago 192.5MB
(2)基于本地模板导入 模块获取,能够直接在网上下载一个模块
[root@izwz920g719hydx1spem46z ~]# wget https://download.openvz.org/template/precreated/contrib/centos-7-x86_64-minimal-20170709.tar.xz
http://openvz.org/Download/templates/precreated 惋惜速度并不快,若咱们下载了一个centos的模板 centos-7-x86_64-minimal-20170709.tar.xz那么导入该镜像的命令为:
cat centos-7-x86_64-minimal-20170709.tar.xz |docker import - centos-5-x86
2.3.六、存出和载入镜像以及上传镜像
docker save -o ***.tar IMAGE:TAG
docker load --input ***.tar 或 dokcer load < ***.tar
docker push IMAGE_NAME
把现有镜像,导出为一个文件,能够做为备份:
docker save -o long.tar long:long
咱们还能够用该文件恢复本地镜像:
docker load --input long.tar 或者
docker load < long.tar
docker push image_name //能够把本身的镜像传到dockerhub官方网站上去,但前提是须要先注册一个用户,后续若是有需求再研究吧
三、操做Docker容器
3.一、建立容器
当使用docker run来建立并启动容器时,Docker在后台运行的标准操做:
(1)检查本地是否存在指定的镜像centos,不存在就从公有仓库下载
(2)利用镜像建立并启动一个容器
(3)分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
(4)从宿主主机配置的桥接网络接口中桥接一个虚拟接口到容器中去
(5)从地址池配置一个IP地址给容器
(6)执行用户指定的应用程序
(7)执行完毕后,容器被终止mysql
语法:
建立容器:docker create -it {image_name}
docker create命令新建的容器处于中止状态,可使用docker start命令来启动它。
启动容器:docker start {container_id}
新建并启动容器:docker run -t -i centos /bin/bash
用下载到的镜像开启容器,-i表示让容器的标准输入打开,-t表示分配一个伪终端,要把-i -t 放到镜像名字前面
[root@localhost ~]# docker run -t -i nginx /bin/bash
root@c1eff06c8501:/#
守护态运行容器:docker run -itd centos /bin/bash
3.二、终止容器
可使用docker stop来终止一个运行中的容器,改命令的格式为docker stoop [container]
首先向容器发送SIGTERM信号,等待一段超时时间(默认为10s)后,再发送SIGKILL信号来终止容器
docker kill
命令会直接发送SIGKILL信号来强行终止容器linux
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
402e1bd8ff16 centos "/bin/bash" 16 hours ago Up 16 hours mynginx
[root@localhost ~]# docker stop mynginx
mynginx
3.三、进入容器
进入容器有如下3种方法:
(1)attach命令
(2)exec命令(推荐方式)
(3)nsenter工具nginx
(1)attach命令
[root@localhost ~]# docker attach mynginx
[root@402e1bd8ff16 /]#
注意:使用attach命令有时候并不方便,当多个窗口同时使用attach命令连接到同一个容器的时候,全部窗口都会同步显示。当某个窗口因命令阻塞时,其余窗口也没法进行操做。
(2)exec命令(推荐方式)
[root@localhost ~]# docker exec -it mynginx /bin/bash
[root@402e1bd8ff16 /]#
(3)nsenter工具
[root@localhost ~]# yum install -y util-linux #安装nsenter工具
为了使nsenter连接到容器,还须要找到容器进程的PID,能够经过如下命令获取
PID=$(docker inspect --format "{{.State.Pid}}" <container>)
经过这个pid就能够链接到这个容器
nsenter -t $PID -u -i -n -p
通常状况下,将这个工具写成一个脚本更方便:
[root@localhost ~]# cat ns.sh
#!/bin/bash
PID=`docker inspect --format "{{.State.Pid}}" $1`
nsenter -t $PID -u -i -n -p
[root@localhost ~]# ./ns.sh mynginx
[root@402e1bd8ff16 ~]#
3.四、删除容器
可使用docker rm 命令来删除处于终止或退出状态的容器,命令格式为docker rm <container>
默认状况下,docker rm 只能删除处于终止或退出状态的容器,并不能删除还处于运行状态的容器。若是须要直接删除一个运行中的容器,能够添加-f参数。Docker会先发送SIGKILL信号给容器,终止其中的应用,以后强行删除。
选项:
-f:
强行终止并删除在运行的一个容器
-l:
删除容器的连接,但保留容器
-v:
删除容器挂载的数据卷git
1
2
|
[root@localhost ~]
nginx2
|
3.五、导入和导出容器
导出容器是指导出一个已经建立的容器到一个文件,无论此时这个容器是否处于运行状态,可使用docker export命令
格式为:docker export CONTAINER_ID
docker export container_id > file.tar // 导出容器,能够迁移到其余机器上,须要导入
举例:
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c40ae00fd190 centos_1 "bash" 14 hours ago Up 14 hours 0.0.0.0:82->80/tcp mad_yonath
84acb55af1f9 nginx "bash" 14 hours ago Up 14 hours 0.0.0.0:81->80/tcp prickly_montalcini
[root@localhost ~]# docker export 84acb55af1f9 > file.tar
导出的文件file.tar又可使用docker import 命令导入,成为镜像
格式:cat ***.tar |docker import - IMAGENAME:TAG
[root@localhost ~]# cat /tmp/mynginx.tar |docker import - test/nginx:v1
sha256:f133989eba3b11f0b81e6976421f9510a94d8692cceb7505c4d98029870cd110
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test/nginx v1 f133989eba3b 3 seconds ago 199 MB
3.六、docker的基础命令
[root@localhost ~]# docker -h
Flag shorthand -h has been deprecated, please use --help
Usage: docker COMMAND
A self-sufficient runtime for containers
Options:
--config string Location of client config files (default "/root/.docker") #客户端配置文件的位置
-D, --debug Enable debug mode #启用Debug调试模式
--help Print usage #查看帮助信息
-H, --host list Daemon socket(s) to connect to (default []) #守护进程的套接字(Socket)链接
-l, --log-level string Set the logging level ("debug", "info", "warn", "error", "fatal") (default "info") #设置日志级别
-v, --version Print version information and quit #打印版本信息并退出
Commands:
attach Attach to a running container #进入一个正在运行的容器
build Build an image from a Dockerfile #经过Dockerfile建立镜像
commit Create a new image from a container's changes #提交当前容器为一个新的镜像
cp Copy files/folders between a container and the local filesystem #从容器中拷贝指定文件或者目录到宿主机中
create Create a new container #建立一个新的容器
diff Inspect changes on a container's filesystem #查看docker容器变化
events Get real time events from the server #从docker服务获取容器实时事件
exec Run a command in a running container #在一个已经运行的容器中运行一条命令
export Export a container's filesystem as a tar archive #导出容器的内容流做为一个tar归档文件
history Show the history of an image #展现一个镜像造成历史
images List images #列出系统当前镜像
import Import the contents from a tarball to create a filesystem image #导入一个镜像
info Display system-wide information #显示系统信息
inspect Return low-level information on Docker objects #查看容器详细信息
kill Kill one or more running containers #kill指定docker容器
load Load an image from a tar archive or STDIN #从一个tar包中加载一个镜像(对应save)
login Log in to a Docker registry #注册或者登录一个docker源服务器
logout Log out from a Docker registry #从当前Docker registry退出
logs Fetch the logs of a container #输出当前容器日志信息
pause Pause all processes within one or more containers #暂停容器
port List port mappings or a specific mapping for the container #查看映射端口对应的容器内部源端口
ps List containers #列出容器列表
pull Pull an image or a repository from a registry #从docker镜像源服务器拉取指定镜像或者库镜像
push Push an image or a repository to a registry #推送指定镜像或者库镜像至docker源服务器
rename Rename a container #重命名容器
restart Restart one or more containers #重启运行的容器
rm Remove one or more containers #移除一个或者多个容器
rmi Remove one or more images #移除一个或者多个镜像
run Run a command in a new container #建立一个新的容器并运行一个命令
save Save one or more images to a tar archive (streamed to STDOUT by default) 保存一个镜像为一个tar包(对应load)
search Search the Docker Hub for images #在docker hub中搜索镜像
start Start one or more stopped containers #启动容器
stats Display a live stream of container(s) resource usage statistics #统计容器使用资源
stop Stop one or more running containers #中止容器
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE #给源中镜像打标签
top Display the running processes of a container #查看容器中运行的进程信息
unpause Unpause all processes within one or more containers #取消暂停容器
update Update configuration of one or more containers #更新一个或多个容器的配置信息
version Show the Docker version information #查看容器版本号
wait Block until one or more containers stop, then print their exit codes #截取容器中止时的退出状态值
Run 'docker COMMAND --help' for more information on a command. #运行docker命令在帮助能够获取更多信息
四、访问Docker仓库
4.一、解析Docker 仓库
仓库(Repository)是集中存放镜像的地方。
一个容易混淆的的概念是注册服务器(Registry
)。实际上注册服务器是存放仓库的具体服务器,每一个服务器上都有不少个仓库,而每一个仓库下面都有多个镜像。从这方面来讲,仓库能够认为是一个具体的项目或目录。例如对于仓库地址dl.dockerpool.com/centos
来讲,dl.dockerpool.com
是注册服务器地址,centos
是仓库名。
仓库又分为公有仓库(public)和私有仓库(private)github
4.二、建立和使用私有仓库
使用registry镜像来建立私有仓库:docker pull registry
//以registry镜像启动容器,-p会把容器的端口映射到宿主机上,:左边为宿主机监听端口,:右边为容器监听端口web
[root@localhost ~]# docker run -d -p 5000:5000 registry #这里将自动下载registry镜像并启动容器,建立本地私有仓库。
Unable to find image 'registry:latest' locally
Trying to pull repository docker.io/library/registry ...
latest: Pulling from docker.io/library/registry
49388a8c9c86: Pull complete
e4d43608dd22: Pull complete
3a41740f900c: Pull complete
e16ef4b76684: Pull complete
65f212f7c778: Pull complete
Digest: sha256:d837de65fd9bdb81d74055f1dc9cc9154ad5d8d5328f42f57f273000c402c76d
c9bba59aa7ce072b888ca8214a76211bf03cf9d3bcb55d2183183b876683f33f
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c9bba59aa7ce registry "/entrypoint.sh /etc/" About a minute ago Up About a minute 0.0.0.0:5000->5000/tcp sick_wozniak
默认的状况下,会将仓库建立在容器的/tmp/registry
目录下,能够经过-v参数来将镜像文件存放在本地的指定路径上。redis
[root@localhost ~]# mkdir -p /opt/data/registry
[root@localhost ~]# docker run -d -p 5000:5000 -v /opt/data/registry:/tmp/registry registry
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test/nginx 1.10.1 def358072817 3 hours ago 106.7 MB
[root@localhost ~]# docker tag test/nginx:1.10.1 192.168.0.134:5000/test2 //标记一下tag,必须带有私有仓库的ip:port
[root@localhost ~]# docker push 192.168.0.134:5000/test2
Get https://192.168.0.165:5000/v2/: http: server gave HTTP response to HTTPS client
tips:因为客户端采用https,docker registry未采用https服务所致。<br/>处理方法:更改配置文件:/etc/docker/daemon.json
[root@localhost ~]# vim /etc/docker/daemon.json
{"insecure-registries":["192.168.0.134:5000"]}
修改完配置文件须要进行重启docker
[root@localhost ~]# systemctl restart docker
docker重启后,原先运行的容器会中止掉,须要从新开启容器
[root@localhost ~]# docker run -d -p 5000:5000 -v /opt/data/registry:/tmp/registry registry
[root@localhost ~]# docker push 192.168.0.134:5000/test2
The push refers to a repository [192.168.0.134:5000/test2]
c4c704007df5: Pushed
latest: digest: sha256:2fa255d11989458a1f9d3173e36a911c5f40c0ba1d74b16608a27ba52fa9237a size: 528
[root@localhost ~]# curl http://192.168.0.134:5000/v2/_catalog
{"repositories":["test2"]}
在第二台机器(192.168.0.136)上进行验证私有仓库是否可用
[root@backup ~]# yum install -y docker
[root@backup ~]# systemctl start docker
[root@backup ~]# curl http://192.168.0.134:5000/v2/_catalog
{"repositories":["test2"]}
[root@backup ~]# docker pull 192.168.0.134:5000/test2
Using default tag: latest
Trying to pull repository 192.168.0.134:5000/test2 ...
Get https://192.168.0.165:5000/v1/_ping: http: server gave HTTP response to HTTPS client
出如今docker私有仓库同样的错误,因而一样修改配置文件
[root@backup ~]# vim /etc/docker/daemon.json
{"insecure-registries":["192.168.0.134:5000"]}
[root@backup ~]# systemctl restart docker
[root@backup ~]# docker pull 192.168.0.134:5000/test2
Using default tag: latest
Trying to pull repository 192.168.0.134:5000/test2 ...
latest: Pulling from 192.168.0.134:5000/test2
9ff86f02c57e: Pull complete
Digest: sha256:2fa255d11989458a1f9d3173e36a911c5f40c0ba1d74b16608a27ba52fa9237a
[root@backup ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.0.165:5000/test2 latest def358072817 Less than a second ago 106.7 MB
小结:
仓库概念的引入,为Docker镜像文件的分发和管理提供了便捷的途径,在企业生产环境中,则每每须要使用私有仓库来维护内部镜像。
五、Docker数据管理
用户在使用Docker的过程当中,每每须要能查看容器内应用产生的数据,或者须要把容器内的数据进行备份,甚至多个容器之间进行数据共享,这必然涉及到容器的数据管理操做。
容器中管理数据主要有两种方式:
(1)数据卷(Data Volumes
)
(2)数据卷容器(Data Volumes Dontainers
)sql
5.一、数据卷
数据卷能够是一个可供容器使用的特殊目录。
a.
数据卷能够在容器中共享和重用
b.
对数据卷修改会立马生效
c.
对数据卷更新,不会影响镜像
d.
卷会一直存在,直到没有容器使用
数据卷的使用,相似于Linux下对目录或文件进行mount操做
在容器内建立一个数据卷
在使用docker run
命令的时候,使用-v
标记能够在容器内建立一个数据卷,屡次使用-v
标记,能够建立多个数据卷。使用-v标记也能够指定本地的已有的目录到容器中做为数据卷。也就是映射宿主机目录到容器中去。这个功能在测试的时候十分方便,好比用户能够放置一些程序或数据到本地目录,而后再容器中运行和使用。另外,本地目录的路径必须是绝对路径,若是目录不存在,Docker会自行建立。
Docker挂载数据卷的默认权限是rw
,用户也能够经过指定权限,ro
指定可读:
docker run -itd -P --name web2 -v /data:/data:ro centos_nginx:1.10 bash
同时,也能够挂载本地主机的一个文件做为数据卷
docker run -it --rm -P --name web2 -v ~/.bash_history:/.bash_history centos_nginx:1.10 bash
5.二、挂载本地的目录到容器里
(1)查看本地镜像
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos_nginx 1.10 3cdab9e3fdbb 19 hours ago 361.6 MB
centos_nginx latest 3cdab9e3fdbb 19 hours ago 361.6 MB
(2)建立容器,并将本地/data目录映射到容器中
[root@localhost ~]# docker run -itd -P --name web2 -v /data:/data centos_nginx:1.10 bash
52babe20009cb2366ebe0a9e3633140bcaa2d92e2057c56e47b8377960f43d62
//-v 用来指定挂载目录,:前面的/data/为宿主机本地目录,:后面的/data/为容器里的目录,会在容器中自动建立
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
52babe20009c centos_nginx:1.10 "bash" 3 seconds ago Up 3 seconds 0.0.0.0:32771->80/tcp web2
(3)在数据卷目录中建立目录123
[root@localhost ~]# docker exec -it 52babe20009c bash
[root@52babe20009c /]# mkdir /data/123
[root@52babe20009c /]# ll /data/
total 24
drwxr-xr-x 2 root root 4096 Nov 12 07:06 123
drwxr-xr-x 5 1003 1003 4096 Sep 30 03:17 logs
drwxr-xr-x 8 1003 1003 4096 Oct 19 04:16 mysql
drwxr-xr-x 3 1003 1003 4096 Sep 30 03:18 nginx
drwxr-xr-x 2 1003 1003 4096 Oct 1 13:01 oldboy
drwxr-xr-x 2 1003 1003 4096 Sep 30 03:17 web
(4)宿主机查看目录变化
[root@localhost ~]# ll /data/
total 24
drwxr-xr-x 2 root root 4096 Nov 12 02:06 123
drwxr-xr-x 5 mysql mysql 4096 Sep 29 23:17 logs
drwxr-xr-x 8 mysql mysql 4096 Oct 19 00:16 mysql
drwxr-xr-x 3 mysql mysql 4096 Sep 29 23:18 nginx
drwxr-xr-x 2 mysql mysql 4096 Oct 1 09:01 oldboy
drwxr-xr-x 2 mysql mysql 4096 Sep 29 23:17 web
5.三、数据卷容器
若是用户须要在容器之间共享一些持续更新的数据,最简单的方式是试用数据卷容器。数据卷容器其实就是一个普通的容器,专门用它来提供数据卷供其余容器挂载使用。
(1)首先建立一个数据卷容器dbdata
,并在其中建立一个数据卷挂载到/dbdata
[root@localhost ~]# docker run -it -v /dbdata --name dbdata centos
tips:这里的/dbdata是容器里的/dbdata目录,并不是宿主机本地的目录
(2)查看/dbdata
目录,并建立文件
[root@8ee4460dccae /]# ls
anaconda-post.log bin dbdata dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@8ee4460dccae /]# touch /dbdata/long.txt
[root@8ee4460dccae /]# ll /dbdata/
total 0
-rw-r--r-- 1 root root 0 Nov 12 07:12 long.txt
[root@8ee4460dccae /]# exit
(3)经过--volumes-from
来挂载dbdata
容器中的数据卷,例如建立一个db1
容器,并从dbdata
容器挂载数据卷
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8ee4460dccae centos "/bin/bash" 2 minutes ago Exited (0) About a minute ago dbdata
[root@localhost ~]# docker run -it --volumes-from dbdata --name db1 centos bash
(4)查看db1容器是否存在/dbdata
目录,并在该目录下建立long2.txt
文件
[root@ee0f12d8023b /]# ll /dbdata/
total 0
-rw-r--r-- 1 root root 0 Nov 12 07:12 long.txt
[root@ee0f12d8023b /]# touch /dbdata/long2.txt
[root@ee0f12d8023b /]# exit
(5)进入dbdata
容器查看是否有long2.txt
[root@localhost ~]# docker exec -it 8ee4460dccae bash
[root@8ee4460dccae /]# ll /dbdata/
total 0
-rw-r--r-- 1 root root 0 Nov 12 07:12 long.txt
-rw-r--r-- 1 root root 0 Nov 12 07:15 long2.txt
(6)屡次使用--volumes-from
参数来从多个容器挂载多个数据卷
[root@localhost ~]# docker run -itd --name db5 --volumes-from db1 --volumes-from db4 centos bash
9513d4c30a85601b8d0939e4b58e24697df6417fb0b82a5eb5dfc42ed729cc7b
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9513d4c30a85 centos "bash" 5 seconds ago Up 3 seconds db5
72ae1898a04d centos "bash" 56 seconds ago Up 55 seconds db4
ee0f12d8023b centos "/bin/bash" 51 minutes ago Up 50 minutes db1
[root@localhost ~]# docker exec -it db5 bash
[root@9513d4c30a85 /]# ls
anaconda-post.log bin dbdata dbdata4 dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
(7)还能够从其余已经挂载了容器卷的容器来挂载容器卷:
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ee0f12d8023b centos "/bin/bash" 47 minutes ago Up 46 minutes db1
8ee4460dccae centos "/bin/bash" 49 minutes ago Up 45 minutes dbdata
[root@localhost ~]# docker run -it --name db2 --volumes-from db1 centos bash
[root@701a34da1cde /]# ll /dbdata/
total 0
-rw-r--r-- 1 root root 0 Nov 12 07:12 long.txt
-rw-r--r-- 1 root root 0 Nov 12 07:15 long2.txt
tips:使用--volumes-from参数所挂载数据卷的容器自身并不须要保持在运行状态,若是删除了挂载的容器(包括dbdata,db1,db2),数据卷并不会被自动删除,
若是要删除一个数据卷,必须在删除最后一个还挂载着它的容器时显示使用docker rm -v 命令来指定删除关联的容器
(1)中止db4
容器并删除
[root@localhost ~]# docker stop db4
db4
[root@localhost ~]# docker rm db4
db4
(2)进入db5
容器查看数据卷dbdata4
是否存在
[root@localhost ~]# docker exec -it db5 bash
[root@9513d4c30a85 /]# ls
anaconda-post.log bin dbdata dbdata4 dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
5.四、利用数据卷容器迁移数据
能够利用数据卷容器对其中的数据卷进行备份,恢复,以实现数据的迁移。
(1)备份
[root@localhost ~]# docker run --volumes-from dbdata -v /backup:/backup --name work centos tar cvf /backup/backup.tar /dbdata
tar: Removing leading `/' from member names
/dbdata/
/dbdata/long.txt
/dbdata/long2.txt
[root@localhost ~]# ll /backup/
-rw-r--r-- 1 root root 10240 Nov 12 03:30 backup.tar
说明:首先利用centos镜像建立了一个容器work,使用--volumes-from dbdata参数来让容器挂载dbdata容器的数据卷(即dbdata数据卷);
-v /backup:/backup参数来将本地的备份目录(/backup)挂载到work容器的/backup目录。work容器启动后,使用了tar cvf /backup/backup.tar /dbdata命令来将/dbdata下的内容备份为容器内的/backup/backup.tar,
即宿主机/backup目录下的/backup/backup.tar
(2)恢复
[root@localhost ~]# docker run -itd -v /dbdata --name db6 centos bash
bb0357aba6fcee546eda5903f40cf61b3fd46a4ad9e0962e55550caaea10e06c
[root@localhost ~]# docker run --volumes-from db6 -v /backup:/backup --name db7 centos tar xvf /backup/backup.tar
dbdata/
dbdata/long.txt
dbdata/long2.txt
[root@localhost ~]# docker exec -it db6 bash
[root@bb0357aba6fc /]# ll /dbdata/
total 0
-rw-r--r-- 1 root root 0 Nov 12 07:12 long.txt
-rw-r--r-- 1 root root 0 Nov 12 07:15 long2.txt
说明:首先利用centos镜像新建一个db6的容器,而后经过--volumes-from参数挂载db6容器的数据卷(/dbdata)新建容器,
并将本地的/backup目录映射到db7容器中。然后对/backup/backup.tar进行解压到/dbdata目录下,从而实现db6恢复/dbdata数据
小结:
在生产环境中,在使用数据卷或者数据卷容器以外,按期将宿主机的本地数据进行备份,或者使用支持容错的存储系统,包括RAID或分布式文件系统。
六、端口映射和容器互联
6.一、端口映射,实现外部访问
在启动容器的时候,若是不指定对应的参数,在容器外部是没法经过网络进行访问容器内的应用和服务的。当容器中运行一些网络应用,要让外部访问这些应用,能够经过-P
或-p
参数来指定端口映射。当使用-P标记时,Docker会随机映射一个49000~49900
的端口至容器内部开放的网络端口。
端口映射的方式:
(1)映射全部接口地址
使用hostPort:containerPort格式,将本地的5000端口映射到容器的5000端口,能够执行如下命令:
docker run -d -p 5000:5000 centos_nginx bash
此时默认会绑定本地全部接口上的全部地址。屡次使用-p标记能够绑定多个端口。例如:
docker run -d -p 5000:5000 -p 8082:80 centos_nginx bash
(2)映射到指定地址的指定端口
可使用ip:hostPort:containerPort格式指定映射一个特定的地址,例如localhost的地址127.0.0.1
docker run -d -p 127.0.0.1:5000:5000 centos_nginx bash
(3)映射到指定地址的任意端口
使用ip::containerPort绑定localhost的任意端口到容器的5000端口,本地主机会任意分配一个端口
docker run -d -p 127.0.1.1::5000 centos_nginx bash
(4)查看端口映射状况
docker port container_name/container_id
演示:
(1)以centos_nginx镜像启动一个容器(web_nginx),并将宿主机8081端口进行映射
[root@localhost ~]# docker run -itd --name web_nginx -p 8081:80 centos_nginx bash
c558c2a986929f280e7b1db2c46c5951fa95670dfa54de1df83f8b0335241c3c
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c558c2a98692 centos_nginx "bash" 6 seconds ago Up 4 seconds 0.0.0.0:8081->80/tcp web_nginx
(2)进入容器,启动nginx,发现Operation not permitted报错
[root@localhost ~]# docker exec -it web_nginx bash
[root@c558c2a98692 /]# ps -ef |grep nginx
root 26 13 0 05:59 ? 00:00:00 grep --color=auto nginx
[root@c558c2a98692 /]# systemctl start nginx
Failed to get D-Bus connection: Operation not permitted
解决:
•新建的容器,启动nginx或者httpd服务的时候会报错
•Failed to get D-Bus connection: Operation not permitted
• 这是由于dbus-daemon没有启动,解决该问题能够这样作
• 启动容器时,要加上--privileged -e "container=docker",而且最后面的命令改成/usr/sbin/init
docker run -itd --privileged -e "container=docker" centos_with_nginx /usr/sbin/init
可是若是直接使用nginx命令直接启动,nginx也是能够的。
(3)删除容器,使用参数--privileged -e "container=docker",bash改成/usr/sbin/init从新启动一个容器,并查看端口映射
[root@localhost ~]# docker rm -f web_nginx
web_nginx
[root@localhost ~]# docker run -itd --privileged -e "container=docker" --name web_nginx -p 8081:80 centos_nginx /usr/sbin/init
c57f0ef025b8b61ced5b39d6cf088f6258b536eecbe05868cb8adadf3610db44
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c57f0ef025b8 centos_nginx "/usr/sbin/init" 7 seconds ago Up 6 seconds 0.0.0.0:8081->80/tcp web_nginx
(4)启动nginx,并写入网页内容,查看是否实现端口映射
[root@localhost ~]# docker exec -it web_nginx bash
[root@c57f0ef025b8 /]# ps -ef |grep nginx
root 75 63 0 06:03 ? 00:00:00 grep --color=auto nginx
[root@c57f0ef025b8 /]# systemctl start nginx
[root@c57f0ef025b8 /]# ps -ef |grep nginx
root 82 1 0 06:03 ? 00:00:00 nginx: master process /usr/sbin/nginx
nginx 83 82 0 06:03 ? 00:00:00 nginx: worker process
root 85 63 0 06:03 ? 00:00:00 grep --color=auto nginx
[root@c57f0ef025b8 /]# cp /usr/share/nginx/html/index.html{,.bak}
[root@c57f0ef025b8 /]# echo "<h1> www.deng.com </h1>" > /usr/share/nginx/html/index.html
七、使用Dokcerfile建立镜像
7.一、Dockerfile基本结构
Dockerfile
是为了快速构建镜像
Dockerfile
由一行行命令语句组成,而且支持以#开头的注释行。
通常而言,Dockerfile
分为4个部分:
基础镜像信息<br/>维护者信息<br/>镜像操做指令<br/>容器启动时执行指令
示例:
#This dockerfile uses the centos image
#VERSION 1
#Author:docker_user
#Command format:Instruction [arguments / command] ..
#第一行必须制定基于的基础镜像
FROM centos
#维护者信息
MAINTAINER docker_user docker_user@email.com
#镜像的操做指令
RUN echo "hello world"
RUN yum update && yum install -y net-tools
RUN yum install -y nginx
#容器启动时执行指令
CMD /usr/sbin/nginx
其中,一开始必须指明所基于的镜像名称,接下来通常会说明维护者信息。
后面则是镜像操做指令,例如RUN
指令,RUN
指令将对镜像执行跟随的命令。每运行一条RUN
指令,镜像添加新的一层,并提交。最后是CMD
指令,来指定运行容器时操做的命令。
7.二、Dockerfile指令
指令的通常格式为INSTRUCTION arguments
(1)FROM
指定所建立镜像的基础镜像,若是本地不存在,则默认会去Docker Hub下载指定镜像。
格式:FROM <image>或 FROM <image>:<tag>
任何Dockerfile中的第一条指令必须为FROM指令。而且在同一个Dockerfile中建立多个镜像时,可使用多个FROM指令(每一个镜像一次)
(2)MAINTAINER
格式:MAINTAINER <name>,指定维护者信息
该信息会写入生成镜像的Author属性域中
(3)RUN
运行指定命令。
格式:RUN <command>或RUN ["executable","param1","param2"]。注意,后一个指令会被解析为Json数组,所以必须用双引号。
前者默认将在shell终端运行命令,即/bin/sh -c;后者则使用exec执行,不会启动shell环境。
好比:RUN yum install httpd
RUN ["/bin/bash","-c","echo hello"]
每条RUN指令将在当前镜像基础上执行指定命令,并提交为新镜像。当命令过长时,可使用\来换行。
(4)CMD
CMD指令用来指定启动容器时默认执行的命令。
支持3种格式:
•CMD ["executable", "param1", "param2"]<br/>•CMD command param1 param2<br/>•CMD ["param1", "param2"]
RUN和CMD看起来很像,可是CMD用来指定容器启动时用到的命令,只能有一条。若是指定了多条命令,只有最后一条会被执行。若是用户启动容器时,指定了运行命令,则会覆盖掉CMD指定的命令。
好比:CMD ["/bin/bash", "/usr/local/nginx/sbin/nginx", "-c", "/usr/local/nginx/conf/nginx.conf"]
(5)EXPOSE
声明镜像内服务所监听的端口
格式:EXPOSE <port> [<port>...]
好比:EXPOSE 22 80 443
告诉Docker服务端容器暴露的端口号,供互联系统使用。在启动容器时须要经过-P,Docker主机会自动分配一个端口转发到指定端口;使用-p,则能够具体指定哪一个本地端口映射过来。
(6)ENV
格式:ENV <key> <value>或ENV <key>=<value>,指定一个环境变量,会被后续RUN指令使用,在镜像启动的容器中也会存在。
好比:ENV PATH /usr/local/mysql/bin:$PATH
(7)ADD
格式:ADD <src> <dest>
将本地的一个文件或目录拷贝到容器的某个目录里。其中<src>为Dockerfile所在目录的相对路径,它也能够是一个URL;若是为tar文件,会自动解压到<dest>路径下。<dest>能够是镜像内的绝对路径,或者相对于工做目录(WORKDIR)的相对路径。
• ADD <conf/vhosts> </usr/local/nginx/conf>
(8)COPY
格式:COPY <src> <dest>
复制本地主机的<src>(为Dockerfile所在目录的相对路径,文件或目录)为容器中的<dest>。目录路径不存在时,会自动建立。当使用本地目录为源目录时,推荐使用COPY。
(9)ENTRYPOINT
指定镜像的默认入口命令,该入口命令在启动容器时做为根命令执行,全部传入值做为该命令的参数
两种格式:
ENTRYPOINT ["executable", "param1", "param2"] (exec调用执行)<br/>ENTRYPOINT command param1 param2 (shell中执行)
此时,CMD指令指定值将做为根命令的参数
配置容器启动后执行的命令,而且不可被docker run 提供的参数覆盖,每一个Dockerfile中只能有一个ENTRYPOINT,当指定多个ENTRYPOINT时,只有最后一个生效。
在运行时,能够被--entrypoint参数覆盖掉,如docker run --entrypoint
•咱们在Dockerfile中指定以下CMD:
• CMD ["/bin/echo", "test"]
• 启动容器的命令是 docker run aming这样会输出test
• 假如启动容器的命令是 docker run -it aming /bin/bash 什么都不会输出
• ENTRYPOINT不会被覆盖,并且会比CMD或者docker run指定的命令要靠前执行
• ENTRYPOINT ["echo", "test"]
• docker run -it aming 123
• 则会输出 test 123,这至关于要执行命令 echo test 123
(10)VOLUME
建立一个数据卷挂载点
格式:VOLUME ["/data"]
建立一个能够从本地主机或其余容器挂载的挂载点,通常用于存放数据库和须要保持的数据等。
(11)USER
格式:USER daemon
指定运行容器时的用户名或UID,后续的RUN也会指定用户。
当服务不须要管理员权限时,能够经过该指令指定运行的用户。而且能够在以前建立所须要的用户。例如:
RUN groupadd -r postgres && useradd -r -g postgres postgres。要临时获取管理员权限可使用gosu,而不推荐sudo
(12)WORKDIR
格式:WORKDIR /path/to/workdir
为后续的RUN,CMD,ENTRYPOINT指令配置工做目录。可使用多个WORKDIR指令,后续命令若是参数是相对路径,则会基于以前命令指定的路径。例如:
WORKDIR /a<br/>WORKDIR b<br/>WORKDIR c<br/>RUN pwd
则最终路径为:/a/b/c
(13)ARG
指定一些镜像内使用的参数(例如版本号信息等),这些参数在执行docker build命令时,才以--build-arg<varname>=<value>格式传入
格式:ARG<name>[=<default value>]
则能够用docker build --build-arg<name>=<value>.来指定参数值
(14)ONBUILD
配置当所建立的镜像做为其余镜像的基础镜像时,所执行的建立操做指令。
格式:ONBUILD [INSTRUCTION]
例如,Dockerfile使用以下的内容建立了镜像image-A:
[...]<br/>ONBUILD ADD . /app/src<br/>ONBUILD RUN /usr/local/bin/python-build --dir /app/src<br/>[...]
若是基于image-A建立新的镜像时,新的Dockerfile中使用FROM image-A指定基础镜像,会自动执行ONBUILD指令的内容
(15)STOPSIGNAL
指定所建立镜像启动的容器接收退出的信号值。例如:
STOPSIGNAL signal
(16)HEALTHCHECK
配置所启动容器如何进行健康检查(如何判断健康与否),自docker 1.12开始支持
格式有两种:
HEALTHCHECK [OPTIONS] CMD command:根据所执行命令返回值是否为0来判断;
HEALTHCHECK NONE:禁止基础镜像中的健康检查。
OPTION支持:
①--interval=DURATION(默认为:30s):过多久检查一次;
②--timeout=DURATION(默认为:30s):每次检查等待结果的超时;
③--retries=N(默认为:3):若是失败了,重试几回才最终肯定失败。
(17)SHELL
指定其余命令使用shell时的默认shell类型
SHELL ["executable","parameters"]
默认值为["/bin/sh","-c"]
7.三、建立镜像
编写完Dockerfile以后,能够经过docker build命令来建立镜像。
格式:docker build [选项] 内容路径
该命令将读取指定路径下(包括子目录)的Dockerfile,并将该路径下的全部内容发送给Docker服务端,有服务端来建立镜像。所以除非生成镜像须要,不然通常建议放置Dockerfile的目录为空目录,可使用-f选项来指定其路径。
①若是使用非内容路径下的Dockerfile,能够经过-f选项来指定其路径
②要指定生成镜像的标签信息,可使用-t选项
例如:指定的Dockerfile所在路径为/tmp/docker_builder/,而且但愿生成的镜像标签为build_repo/frist_image,可使用:
docker build -t build_repo/first_image /tmp/docker_builder/
7.四、Dockerfile建立镜像示例(nginx)
(1)编辑Dockerfile文件
[root@localhost ~]# vim Dockerfile
FROM centos
MAINTAINER long 442305405@qq.com
RUN yum install -y pcre-devel wget net-tools gcc zlib zlib-devel make openssl-devel
ADD http://nginx.org/download/nginx-1.12.2.tar.gz .
RUN tar zxvf nginx-1.12.2.tar.gz
RUN mkdir -p /usr/local/nginx
RUN cd nginx-1.12.2 && ./configure --prefix=/usr/local/nginx && make && make install
RUN rm -fv /usr/local/nginx/conf/nginx.conf
ADD http://www.apelearn.com/study_v2/.nginx_conf /usr/local/nginx/conf/nginx.conf
ADD index.html /usr/local/nginx/html/index.html
RUN echo "daemon off;" >> /usr/local/nginx/conf/nginx.conf
EXPOSE 80
ENTRYPOINT /usr/local/nginx/sbin/nginx
(2)建立镜像
[root@localhost ~]# docker build -t centos_nginx:1.12.2 .
Sending build context to Docker daemon 212.7 MB
Step 1 : FROM centos
---> d123f4e55e12
Step 2 : MAINTAINER long 442305405@qq.com
---> Using cache
---> 42a2766d5cce
Step 3 : RUN yum install -y pcre-devel wget net-tools gcc zlib zlib-devel make openssl-devel
---> Running in ebd2bc43b045
Loaded plugins: fastestmirror, ovl
......
Step 8 : RUN rm -fv /usr/local/nginx/conf/nginx.conf
---> Running in eb41c1c7b39d
removed '/usr/local/nginx/conf/nginx.conf'
---> d6b0d765ca2e
Removing intermediate container eb41c1c7b39d
Step 9 : ADD http://www.apelearn.com/study_v2/.nginx_conf /usr/local/nginx/conf/nginx.conf
Downloading [==================================================>] 1.678 kB/1.678 kB
---> efffda0c218d
Removing intermediate container af06898e74f4
Step 10 : EXPOSE 80
---> Running in fb3905caf714
---> 6efacb9d8a12
Removing intermediate container fb3905caf714
Step 11 : ENTRYPOINT /usr/local/nginx/sbin/nginx && tail -f /etc/passwd
---> Running in 61b617e30d2b
---> 02447e813325
Removing intermediate container 61b617e30d2b
Successfully built 02447e813325
(3)查看建立的镜像,并经过建立的镜像建立容器
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos_nginx 1.12.2 02447e813325 About a minute ago 350 MB
[root@localhost ~]# docker run -itd centos_nginx:1.12.2 bash
10fa28dc417e0023004f857f72537e232a63b2977fda3228a77688d33b0d7803
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
10fa28dc417e centos_nginx:1.12.2 "/bin/sh -c '/usr/loc" 3 seconds ago Up 3 seconds 80/tcp gigantic_agnesi
(4)进入容器查看nginx运行情况
[root@localhost ~]# docker exec -it gigantic_agnesi bash
[root@10fa28dc417e /]# ps -ef |grep nginx
root 1 0 0 06:37 ? 00:00:00 /bin/sh -c /usr/local/nginx/sbin/nginx
root 6 1 0 06:37 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nobody 7 6 0 06:37 ? 00:00:00 nginx: worker process
nobody 8 6 0 06:37 ? 00:00:00 nginx: worker process
root 24 10 0 06:38 ? 00:00:00 grep --color=auto nginx
7.5.遇到的问题
因为以前使用过pipework进行配置桥接网络,须要更改网络,并开启IPv4转发
[root@localhost ~]# docker run -itd --name test centos_nginx bash
WARNING IPv4 forwarding is disabled. Networking will not work
a93d14f536d31b3edfd847f12c8e1115bb75bc2b202fb44f761c2e14c2018a6b
解决:
# vi /etc/sysctl.conf
或者
# vi /usr/lib/sysctl.d/00-system.conf
添加以下代码:
net.ipv4.ip_forward=1
重启network服务
# systemctl restart network
查看是否修改为功
# sysctl net.ipv4.ip_forward
#################################################################################
Docker 安装时会自动在host
上建立三个网络,咱们可用 docker network ls
命令查看:
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
0164da7ee66a bridge bridge local
a4a5d0b84564 host host local
df2c5c066a6a none null local
一、host模式
host模式,使用docker run
时,使用--net=host
指定docker
使用的网络实际上和宿主机同样,启动容器的时候使用host
模式,那么这个容器将不会得到一个独立的Network Namespace
,而是和宿主机共用一个Network Namespace
。容器将不会虚拟出本身的网卡,配置本身的IP
等,而是使用宿主机的IP
和端口。可是,容器的其余方面,如文件系统、进程列表等仍是和宿主机隔离的。
演示:
[root@localhost ~]# docker run -it --rm --net=host --name net1 centos_1 bash
[root@localhost /]# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:5aff:fe52:25a9 prefixlen 64 scopeid 0x20<link>
ether 02:42:5a:52:25:a9 txqueuelen 0 (Ethernet)
RX packets 32541 bytes 45836190 (43.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 45025 bytes 305790826 (291.6 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.165 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::71bd:4770:36ed:a5df prefixlen 64 scopeid 0x20<link>
ether 08:00:27:06:15:d8 txqueuelen 1000 (Ethernet)
RX packets 690783 bytes 269935255 (257.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 164584 bytes 86989110 (82.9 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 5206 bytes 265735 (259.5 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 5206 bytes 265735 (259.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

二、container模式
container
模式,使用--net=container:container_id/container_name
多个容器使用共同的网络,这个模式指定新建立的容器和已经存在的一个容器共享一个 Network Namespace
,而不是和宿主机共享。新建立的容器不会建立本身的网卡,配置本身的IP
,而是和一个指定的容器共享 IP
、端口范围等。一样,两个容器除了网络方面,其余的如文件系统、进程列表等仍是隔离的。两个容器的进程能够经过lo
网卡设备通讯。
演示:
①建立一个net2的容器,并查看ip为172.17.0.2
[root@localhost ~]# docker run -itd --name net2 centos_1 bash
b8a14e5e8a670d5680aae830f79267257143397c124d011fbf09b71c59b37e5d
[root@localhost ~]# docker exec -it net2 bash
[root@b8a14e5e8a67 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:acff:fe11:2 prefixlen 64 scopeid 0x20<link>
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 8 bytes 648 (648.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
②建立容器net3,并指定使用container网络模式,查看net3容器的ip为:172.17.0.2
[root@localhost ~]# docker run -it --net=container:net2 --name net3 centos_1 bash
[root@b8a14e5e8a67 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:acff:fe11:2 prefixlen 64 scopeid 0x20<link>
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 8 bytes 648 (648.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
③查看运行的net2,net3容器,二者id并不相同,但使用container网络模式,进入到net3时,net3容器id会和net2相同
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a795f6825e1e centos_1 "bash" 6 minutes ago Up 3 seconds net3
b8a14e5e8a67 centos_1 "bash" 8 minutes ago Up 8 minutes net2
[root@localhost ~]# docker exec -it net3 bash
[root@b8a14e5e8a67 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:acff:fe11:2 prefixlen 64 scopeid 0x20<link>
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 8 bytes 648 (648.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

三、none模式
non
e模式,使用--net=none
指定这种模式下,不会配置任何网络。使用none
模式,Docker
容器拥有本身的Network Namespace
,可是,并不为Docker
容器进行任何网络配置。也就是说,这个Docker
容器没有网卡、IP、路由
等信息。须要咱们本身为Docker
容器添加网卡、配置IP等。
演示:
[root@localhost ~]# docker run -it --net=none --name net4 centos_1 bash
[root@b12e7ad03af2 /]# ifconfig
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
四、bridge模式
bridge
模式,使用--net=bridge
指定默认模式,当Docker
进程启动时,会在主机上建立一个名为docker0
的虚拟网桥,此主机上启动的Docker
容器会链接到这个虚拟网桥上。虚拟网桥的工做方式和物理交换机相似,这样主机上的全部容器就经过交换机连在了一个二层网络中。
从docker0
子网中分配一个IP
给容器使用,并设置docker0
的IP地址为容器的默认网关。在主机上建立一对虚拟网卡veth pair
设备,Docker
将veth pair
设备的一端放在新建立的容器中,并命名为eth0
(容器的网卡),另外一端放在主机中,以vethxxx
这样相似的名字命名,并将这个网络设备加入到docker0
网桥中。能够经过brctl show
命令查看。
bridge
模式是docker的默认网络模式,不写--net
参数,就是bridge
模式。使用docker run -p
时,docker
实际是在iptables
作了DNAT规则,实现端口转发功能。可使用iptables -t nat -vnL
查看。
演示:
①查看宿主机docker0的虚拟网桥ip为:172.17.0.1
[root@localhost ~]# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:5aff:fe52:25a9 prefixlen 64 scopeid 0x20<link>
ether 02:42:5a:52:25:a9 txqueuelen 0 (Ethernet)
RX packets 32557 bytes 45837262 (43.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 45025 bytes 305790826 (291.6 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.165 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::71bd:4770:36ed:a5df prefixlen 64 scopeid 0x20<link>
ether 08:00:27:06:15:d8 txqueuelen 1000 (Ethernet)
RX packets 702882 bytes 271309720 (258.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 166364 bytes 87203641 (83.1 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
②建立net5容器,并使用bridge网络模式。查看ip和网关
[root@localhost ~]# docker run -it --name net5 --net=bridge centos_1 bash
[root@a3a6416d08c0 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.3 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:acff:fe11:3 prefixlen 64 scopeid 0x20<link>
ether 02:42:ac:11:00:03 txqueuelen 0 (Ethernet)
RX packets 6 bytes 508 (508.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 6 bytes 508 (508.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@a3a6416d08c0 /]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.17.0.1 0.0.0.0 UG 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0

五、如何自定义docker网络?
咱们可经过bridge
驱动建立相似前面默认的bridge
网络,例如:
[root@localhost ~]# docker network create --driver bridge my_net #建立桥接网络my_net
afb854fd239b26f95265002190f9df88f8b7f66c204085bfd16c6a2b4932f5d9
[root@localhost ~]# brctl show 查看一下当前 host 的网络结构变化
bridge name bridge id STP enabled interfaces
br-afb854fd239b 8000.02422702f1bc no
docker0 8000.0242646f882f no veth211fb49
veth709c331
veth8069764
vethfa120d8
增了一个网桥 br-afb854fd239b,这里 br-afb854fd239b 正好新建 bridge 网络 my_net 的短 id。执行 docker network inspect 查看一下 my_net 的配置信息:
[root@localhost ~]# docker network inspect my_net
[
{
"Name": "my_net",
"Id": "afb854fd239b26f95265002190f9df88f8b7f66c204085bfd16c6a2b4932f5d9",
"Created": "2018-04-21T14:14:15.479906429+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16", #这里 172.18.0.0/16 是 Docker 自动分配的 IP 网段。
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
指定 --subnet
和--gateway
参数自定义ip
网段:
[root@localhost ~]# docker network create --driver bridge --subnet 192.168.100.0/24 --gateway 192.168.100.1 my_net2
889ba4ceb97290e440db559e104db2bf9273854fd789322aaea30b3c76937af6
[root@localhost ~]# docker network inspect my_net2
[
{
"Name": "my_net2",
"Id": "889ba4ceb97290e440db559e104db2bf9273854fd789322aaea30b3c76937af6",
"Created": "2018-04-21T14:19:15.730480499+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.100.0/24",
"Gateway": "192.168.100.1"
}
]
},
"Internal": false,
"Attachable": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
建立了新的 bridge 网络 my_net2,网段为 192.168.100.0/24,网关为 192.168.100.1。与前面同样,网关在 my_net2 对应的网桥 br-889ba4ceb972 上:
[root@localhost ~]# brctl show
bridge name bridge id STP enabled interfaces
br-889ba4ceb972 8000.02424b2256df no
br-afb854fd239b 8000.02422702f1bc no
docker0 8000.0242646f882f no veth211fb49
veth709c331
veth8069764
vethfa120d8
[root@localhost ~]# ifconfig br-889ba4ceb972
br-889ba4ceb972: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 192.168.100.1 netmask 255.255.255.0 broadcast 0.0.0.0
ether 02:42:4b:22:56:df txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
容器要使用新的网络,须要在启动时经过 --network
指定,而且还可使用--ip
参数直接指定一个静态ip
:
[root@localhost ~]# docker run -it --network=my_net2 busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
116: eth0@if117: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:c0:a8:64:02 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.2/24 scope global eth0 ##容器被分配的ip为192.168.100.2
valid_lft forever preferred_lft forever
inet6 fe80::42:c0ff:fea8:6402/64 scope link
valid_lft forever preferred_lft forever
[root@localhost ~]# docker run -it --network=my_net2 --ip 192.168.100.100 busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
118: eth0@if119: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:c0:a8:64:64 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.100/24 scope global eth0 ##容器被分配的ip为192.168.100.100
valid_lft forever preferred_lft forever
inet6 fe80::42:c0ff:fea8:6464/64 scope link
valid_lft forever preferred_lft forever
注:只有使用 --subnet 建立的网络才能指定静态 IP。
my_net 建立时没有指定 --subnet,若是指定静态 IP 报错以下:
[root@localhost ~]# docker run -it --rm --network=my_net --ip 172.18.0.100 busybox
/usr/bin/docker-current: Error response from daemon: User specified IP address is supported only when connecting to networks with user configured subnets.
六、Docker使用pipework配置容器与宿主机在同一网段
为了使本地网络中的机器和Docker
容器更方便的通讯,咱们常常会有将Docker
容器配置到和主机同一网段的需求。这个需求其实很容易实现,咱们只要将Docker
容器和宿主机的网卡桥接起来,再给Docker
容器配上IP
就能够了。
(1)新建桥接网卡br0,并进行修改宿主机网卡enp0s3以及br0
[root@localhost network-scripts]# cp ifcfg-enp0s3 ifcfg-br0
[root@localhost network-scripts]# vim ifcfg-br0
注:修改TYPE=Bridge,DEVICE=br0,NAME=br0
TYPE=Bridge
BOOTPROTO=static
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=br0
#UUID=faa61166-b507-4992-b055-2c6284de3981
DEVICE=br0
ONBOOT=yes
IPADDR=192.168.0.165
GATEWAY=192.168.0.1
NATMASK=255.255.255.0
DNS1=8.8.8.8
#NM_CONTROLLED=no
[root@localhost network-scripts]# vim ifcfg-enp0s3
注:增长BRIDGE=br0,删除IPADDR,GATEWAY,NETMASK,DNS
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=enp0s3
#UUID=faa61166-b507-4992-b055-2c6284de3981
DEVICE=enp0s3
ONBOOT=yes
#IPADDR=192.168.0.165
#GATEWAY=192.168.0.1
#NATMASK=255.255.255.0
#DNS1=8.8.8.8
#NM_CONTROLLED=no
BRIDGE=br0
(2)重启网络,查看br0的ip地址,以及enp0s3是否未分配ip地址,表示成功
[root@localhost network-scripts]# systemctl restart network
[root@localhost network-scripts]# ifconfig
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.165 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::ca01:a411:fb77:c348 prefixlen 64 scopeid 0x20<link>
ether 08:00:27:06:15:d8 txqueuelen 1000 (Ethernet)
RX packets 36 bytes 3485 (3.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 25 bytes 2318 (2.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
ether 02:42:7e:ec:e1:e6 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 08:00:27:06:15:d8 txqueuelen 1000 (Ethernet)
RX packets 2831 bytes 321711 (314.1 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1070 bytes 182494 (178.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 96 bytes 7888 (7.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 96 bytes 7888 (7.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
(3)下载pipework
[root@localhost ~]# git clone https://github.com/jpetazzo/pipework
Cloning into 'pipework'...
remote: Counting objects: 501, done.
remote: Total 501 (delta 0), reused 0 (delta 0), pack-reused 501
Receiving objects: 100% (501/501), 172.97 KiB | 4.00 KiB/s, done.
Resolving deltas: 100% (264/264), done.
(4)拷贝pipework二进制文件到/usr/local/bin下,运行一个容器并使用none网络模式
[root@localhost ~]# cp pipework/pipework /usr/local/bin/
[root@localhost ~]# docker run -itd --net=none --name pipework centos_nginx bash
ab88e2159ce32408154a776c1c62cf1af170fa8ce4d01908da6175f01b6c787d
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ab88e2159ce3 centos_nginx "bash" 4 seconds ago Up 4 seconds pipework
[root@localhost ~]# docker exec -it pipework bash
[root@ab88e2159ce3 /]# ifconfig
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@ab88e2159ce3 /]# exit
exit
(5)使用pipework进行配置容器pipework的ip地址,166为容器的ip地址,@后面的ip为容器网关,配置完毕进入容器进行查看
[root@localhost ~]# pipework br0 pipework 192.168.0.166/24@192.168.0.1
[root@localhost ~]# docker exec -it pipework bash
[root@ab88e2159ce3 /]# ifconfig
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.166 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::340c:ebff:fe50:1ba3 prefixlen 64 scopeid 0x20<link>
ether 36:0c:eb:50:1b:a3 txqueuelen 1000 (Ethernet)
RX packets 62 bytes 10518 (10.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 10 bytes 732 (732.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
(6)windows和linux下验证容器pipework的网络连通性
[root@ab88e2159ce3 /]# ping www.baidu.com
PING www.a.shifen.com (14.215.177.39) 56(84) bytes of data.
64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=1 ttl=54 time=8.29 ms
64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=2 ttl=54 time=8.09 ms
64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=3 ttl=54 time=8.43 ms
64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=4 ttl=54 time=8.12 ms
64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=5 ttl=54 time=8.80 ms
64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=6 ttl=54 time=8.51 ms
^C
--- www.a.shifen.com ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5007ms
rtt min/avg/max/mdev = 8.094/8.378/8.805/0.249 ms
(7)经过pipework配置网络,配置web服务
[root@localhost ~]# docker run -itd --privileged -e "container=docker" --name pipework --net=none centos_nginx /usr/sbin/init
aa85a59dc347633fcd9a2b5206eaed619451c52f299d2505c32df2b6d1ce7521
[root@localhost ~]# pipework br0 pipework 192.168.0.166/24@192.168.0.1
[root@localhost ~]# docker exec -it pipework bash
[root@aa85a59dc347 /]# ifconfig
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.166 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::a00d:aff:fec2:a59d prefixlen 64 scopeid 0x20<link>
ether a2:0d:0a:c2:a5:9d txqueuelen 1000 (Ethernet)
RX packets 192 bytes 21152 (20.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 11 bytes 774 (774.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@aa85a59dc347 /]# systemctl start nginx
[root@aa85a59dc347 /]# netstat -tulnp |grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 86/nginx: master pr
tcp6 0 0 :::80 :::* LISTEN 86/nginx: master pr
[root@aa85a59dc347 /]# ps -ef |grep nginx
root 86 1 0 07:54 ? 00:00:00 nginx: master process /usr/sbin/nginx
nginx 87 86 0 07:54 ? 00:00:00 nginx: worker process
root 98 68 0 07:54 ? 00:00:00 grep --color=auto nginx
一、docker-compose的简介
docker-compose
做为dokcer
的官方编排工具,它可让用户经过编写一个简单的模板文件,快速地建立和管理基于docker
容器的应用集群。实现对docker
容器集群的快速编排。咱们知道Dockerfile
模板文件,可让用户很方便地定义一个单独的应用容器。然而在平常工做中,常常会遇到须要多个容器相互配合来完成某项任务的状况。例如要实现一个web项目,除了web
服务器容器自己,每每还须要加上后端的数据库服务容器,甚至还包括负载均衡容器等。
而Compose正好能够知足这样的需求,它容许用户经过一个单独的docker-compose.yml
模板文件(YAML格式
)来定义一组相关联的应用容器做为一个项目(project
)
Compose中有2个重要的概念:
(1)服务(service):一个应用的容器,实际上能够包含若干运行相同镜像的容器实例。
(2)项目(project):由一组关联的应用容器组成的一个完成业务单元,在docker-compose.yml文件中定义。
二、docker-compose安装
Compose
项目是用Python
语言编写的,因此compose
能够经过python
的pip
工具进行安装。安装过程以下:
[root@localhost ~]# yum install -y python-pip
[root@localhost ~]# pip install -U docker-compose
[root@localhost ~]# docker-compose version
docker-compose version 1.21.0, build 5920eb0
docker-py version: 3.2.1
CPython version: 2.7.5
OpenSSL version: OpenSSL 1.0.1e-fips 11 Feb 2013
三、Compose命令
对于Compose
来讲,大部分命令的对象既能够是项目自己,也能够指定为项目中的服务或容器。若是没有特别说明,命令对象将是项目,这意味着项目中全部的服务都会受到命令的影响。docker-compose
命令的基本使用格式以下:
Usage:
docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
docker-compose -h|--help
Options:
-f, --file FILE 指定使用的Compose模板文件,默认为docker-compose.yml,可屡次指定;
-p, --project-name NAME 指定项目名称,默认将使用所在目录名称做为项目名 ;
--verbose 输出更多调试信息;
-v, --version 打印版本信息;
Commands:
build 构建项目中的服务容器
help 得到一个命令的帮助
images 列出全部镜像
kill 经过发送SIGKILL信号来强制中止服务容器
logs 查看服务器容器的输出
pause 暂停一个服务容器
port 打印某个容器的端口所映射的公共端口
ps 列出项目中目前的全部容器
pull 拉取服务依赖的镜像
push 推送服务依赖的镜像
restart 重启项目中的服务
rm 删除全部的服务器容器(中止状态中的)
run 在指定服务上执行一个命令
scale 设置指定服务运行的容器个数
start 启动已经存在的服务容器
stop 中止已经处于运行状态的容器,但不删除它
top 展现运行的进程
unpause 恢复处于暂停状态中的服务
up 自动完成包括构建镜像、建立服务、启动服务并关联服务相关容器的一系列操做
version 打印docker-compose的版本信息
四、Compose模板文件
模板文件是使用Compose
的核心,设计的指令关键字也有不少,默认的模板文件名称为docker-compose.yml
,格式为YAML
格式。举例:
version: "2"
service:
webapp:
image: examplses/web
ports:
- "80:80"
volumes:
- "/data"
注意,每一个服务都必须经过image
指定镜像或build
命令(须要Dockerfile
)等来自动构建生成镜像。若是使用build
指令,在Dockerfile
中设置的选项(例如:CMD、EXPOSE、VOLUME、ENV
等)将会自动被获取,无需在docker-compose.yml
中再次设置。如下为模板的主要指令和功能:
(1)build指令
指定Dockerfile
所在文件夹的路径(能够是绝对路劲,或相对docker-compose.yml
文件的路径。)Compose
将会利用它自动构建这个镜像,而后使用这个镜像:
build: /path/to/build/dir
(2)cap_add,cap_drop
指定容器的内核能力(capacity
)分配。例如,让容器拥有全部能力能够指定为:
去掉NET_ADMIN
能力能够指定为:
(3)command
覆盖容器启动后默认执行的命令:
command: echo "hello world"
(4)cgroup_parent
指定父cgroup组,意味着将继承该组的资源限制,例如,建立了一个cgroup
组为cgroups_1
:
(5)container_name
指定容器名称。默认将会使用“项目名称_服务名称_序号”这样的格式。例如:
container_name: docker-web-container
指定容器名称后,该服务将没法进行扩展,由于Docker不容许多个容器具备相同的名称。
(6)devices
指定设备映射关系,例如:
devices:
- "/dev/ttyUSB1:/dev/ttyUSB0"
(7)dns
自定义DNS服务器。能够是一个值,也能够是一个列表,例如:
dns: 8.8.8.8
dns:
- 8.8.8.8
- 114.114.114.114
(8)dns_search
配置DNS搜索域。能够是一个值,也能够是一个列表,例如:
dns_search: example.com
dns_search:
- domain1.example.com
- domain2.example.com
(9)dockerfile
若是须要,指定额外的编译镜像的Dockerfile文件,能够经过该指令来指定,例如:
该指令不能和image一块儿使用,不然Compose不知道根据哪一个指令来生成最终的服务镜像。
dockerfile: Dockerfile-alternate
(10)env_file
从文件中获取环境变量,能够为单独的文件路径或列表。
若是经过docker-compose -f FILE的方式来指定Compose模板文件,则env_file中变量的路径会基于模板文件路径,若是有变量名称和environment指令冲突,则按照惯例,之后者为准:
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- ./opt/secrets.env
环境变量文件中每一行都必须符合格式,支持#开头的注释行:
(11)environment
设置环境变量,可使用数组或字典两种格式。只给定名称的变量会自动获取运行Compose主机上对应变量的值,能够用来防止泄露没必要要的数据。例如:
environment:
RACK_ENV: development
SESSION_SECRET
或者:
environment:
- RACK_ENV=development
- SESSION_SECRET
(12)expose
暴露端口,但不映射到宿主机,只容许能被连接的服务访问。仅能够指定内部端口为参数,以下所示:
expose:
- "3000"
- "8000"
(13)extends
基于其余模板文件进行扩展。例如咱们已经有了一个webapp服务,定义一个基础模板文件为common.yml,以下所示:
# common.yml
webapp:
build: ./webapp
environment:
- DEBUG=false
- SEND_EMAILS=false
再编写一个新的development.yml文件,使用common.yml中的webapp服务进行扩展:
#development.yml
web:
extends:
file: common.yml
service: webapp
ports:
- "8000:8000"
links:
- db
environment:
- DEBUG=true
db:
image: postgres
development.yml会自动继承common.yml中的webapp服务及环境变量定义。使用extends须要注意如下几点:
1.避免出现循环依赖,如A依赖B,B依赖C,C依赖A
2.extends不会继承links和volume_from中定义的容器和数据卷资源。
通常状况下,推荐在基础模板中只定义一些能够共享的镜像和环境变量,在扩展模板中具体指定应用变量、连接、数据卷等信息。
(14)external_links
连接到docker-compose.yml外部的容器,甚至能够是非Compose管理的外部容器。参数格式和links相似
external_links:
- redis_1
- project_db_1:mysql
- project_db_1:postgresql
相似于Docker中的–add-host参数,指定额外的host名称映射信息,例如:
extra_hosts:
- "googledns:8.8.8.8"
- "dockerhub:52.1.157.61"
会在启动后的服务容器中/etc/hosts文件中添加如下2个条目:
8.8.8.8 googledns
52.1.157.61 dockerhub
(16)image
指定为镜像名称或镜像ID,若是镜像在本地不存在,Compose将会尝试拉取这个镜像。
image: centos
image: nginx
(17)labels
为容器添加Docker元数据(metadata)信息。例如,能够为容器添加辅助说明信息:
labels:
com.startupteam.description: "webapp for a startup team"
com.startupteam.department: "devops department"
com,startupteam.release: "rc3 for v1.0"
(18)links
连接到其余服务中的容器。使用服务名称(同时做为别名),或者”服务名称:服务别名”(如SERVICE:ALIAS),这样的格式均可以,例如:
links:
- db
- db:database
- redis
使用的别名会将自动在服务容器中的/etc/hosts里建立。例如:
172.17.2.186 db
172.17.2.186 database
172.17.2.187 redis
所链接容器中相应的环境变量也将建立
(19)log_driver
相似于Docker中的–log-driver参数,指定日志驱动类型。目前支持三种日志驱动类型:
log_driver: "json-file"
log_driver: "syslog"
log_driver: "none"
(20)log_opt
日志驱动的相关参数。例如:
log_driver: "syslog"
log_opt:
syslog-address: "tcp://192.168.0.42:123"
(21)net
设置网络模式。参数相似于docker client的–net参数
net: "bridge"
net: "none"
net: "container:[name or id]"
net: "host"
(22)pid
跟主机系统共享进程命名空间。打开该选项的容器之间,以及容器和宿主机系统之间能够经过进程ID来相互访问和操做:
(23)ports
暴露端口信息。使用”宿主:容器“的格式,或者仅仅指定容器的端口(宿主机会随机选择端口):
ports:
- "3000"
- "8000:8000"
- "49100:22"
- "127.0.0.1:8081:8081"
当使用"HOST:CONTAINER"格式来映射端口时,若是你使用的容器端口小于60而且没有放到引号里,可能会获得错误结果,由于YAML会自动解析xx:yy这种数字格式为60进制。为了不这种问题的出现,建议数字串都用引号包括起来的字符串格式。
(24)security_opt
指定容器模板标签(label)机制的默认属性(用户、角色、类型、级别等)。例如,配置标签的用户名和角色名:
security_opt:
- label:user:USER
- label:role:ROLE
(25)ulimits
指定容器的ulimits限制值,例如,指定最大进程数为65535,指定文件句柄数位20000(软限制,应用能够随时修改,不能超过硬限制,只能root用户提升)。
ulimits:
nproc:65535
nofile:
soft:20000
hard:40000
(26)volumes
数据卷所挂载的路径设置。能够设置宿主机路径(HOST:CONTAINER)或加上访问模式(HOST:CONTAINER:ro)。该指令中路径支持相对路径。例如:
volumes:
- /var/lib/mysql
- cache/:/tmp/cache
- ~/configs:/etc/configs/:ro
(27)volumes_driver
较新版本的Docker支持数据卷的插件驱动。用户能够先使用第三方驱动建立一个数据卷,而后使用名称来访问它。此时,能够经过volumes_driver来指定驱动:
(28)volumes_from
从另外一个服务或容器挂载它的数据卷:
volumes_from:
- service_name
- container_name
Docker-compose部署gitlab
一、安装Docker
安装必要工具
[root@vm_10_14_centos ~]# yum -y install yum-utils device-mapper-persistent-data lvm2
添加Docker-ce镜像源并安装
[root@vm_10_14_centos ~]# yum-config-manager --add-repo
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
[root@vm_10_14_centos ~]# yum makecache fast
[root@vm_10_14_centos ~]# yum -y install docker-ce[root@gitlab ~]# yum makecache fast
[root@vm_10_14_centos ~]# yum -y install docker-ce
[root@vm_10_14_centos ~]# systemctl start docker
[root@vm_10_14_centos ~]# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
添加Docker镜像加速
[root@vm_10_14_centos ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://9w1hl6qt.mirror.aliyuncs.com"]
}
[root@vm_10_14_centos ~]# systemctl daemon-reload
[root@vm_10_14_centos ~]# systemctl restart docker
[root@vm_10_14_centos ~]# rpm -qa docker
[root@vm_10_14_centos ~]# rpm -qa docker-ce
docker-ce-18.09.0-3.el7.x86_64
[root@vm_10_14_centos ~]# docker --version
Docker version 18.09.0, build 4d60db4
[root@vm_10_14_centos ~]# docker version
Client:
Version: 18.09.0
API version: 1.39
Go version: go1.10.4
Git commit: 4d60db4
Built: Wed Nov 7 00:48:22 2018
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.0
API version: 1.39 (minimum version 1.12)
Go version: go1.10.4
Git commit: 4d60db4
Built: Wed Nov 7 00:19:08 2018
OS/Arch: linux/amd64
Experimental: false
二、安装Docker-compose
下载Docker-compose二进制文件并添加执行权限
[root@vm_10_14_centos ~]# curl -L https://github.com/docker/compose/releases/download/1.23.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 617 0 617 0 0 959 0 --:--:-- --:--:-- --:--:-- 958
100 11.2M 100 11.2M 0 0 1824k 0 0:00:06 0:00:06 --:--:-- 2422k
[root@vm_10_14_centos ~]# chmod +x /usr/local/bin/docker-compose
[root@vm_10_14_centos ~]# docker-compose --version
docker-compose version 1.23.2, build 1110ad01
三、安装Gitlab
(1)编辑docker-compose的yml文件
[root@vm_10_14_centos ~]# mkdir gitlab
[root@vm_10_14_centos ~]# cd gitlab/
[root@vm_10_14_centos gitlab]# vim docker-compose.yml
version: '2'
services:
gitlab:
image: 'twang2218/gitlab-ce-zh:11.1.4'
container_name: "gitlab"
restart: unless-stopped
privileged: true
hostname: 'gitlab'
environment:
TZ: 'Asia/Shanghai'
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://129.204.133.242'
gitlab_rails['time_zone'] = 'Asia/Shanghai'
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.aliyun.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "kimasd102419@aliyun.com" #用本身的aliyun邮箱
gitlab_rails['smtp_password'] = "axbc1kof"
gitlab_rails['smtp_domain'] = "aliyun.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['gitlab_email_from'] = 'kimasd102419@aliyun.com'
gitlab_rails['gitlab_shell_ssh_port'] = 22
ports:
- '80:80'
- '443:443'
- '22:22'
volumes:
- /opt/gitlab/config:/etc/gitlab
- /opt/gitlab/data:/var/opt/gitlab
- /opt/gitlab/logs:/var/log/gitlab
(2)建立相关目录
[root@vm_10_14_centos gitlab]# mkdir /opt/gitlab/{config,data,logs} -p
[root@vm_10_14_centos gitlab]# ls -l /opt/gitlab/
total 12
drwxr-xr-x 2 root root 4096 Dec 8 11:35 config
drwxr-xr-x 2 root root 4096 Dec 8 11:35 data
drwxr-xr-x 2 root root 4096 Dec 8 11:35 logs
(3)拉取gitlab中文版镜像
[root@vm_10_14_centos gitlab]# docker pull twang2218/gitlab-ce-zh:11.1.4
11.1.4: Pulling from twang2218/gitlab-ce-zh
8ee29e426c26: Pull complete
6e83b260b73b: Pull complete
e26b65fd1143: Pull complete
40dca07f8222: Pull complete
b420ae9e10b3: Pull complete
a218309dd589: Pull complete
5c60fd7ba0ce: Pull complete
659c2144b5a3: Pull complete
8289bbac0d0e: Pull complete
31bbd150e8a7: Pull complete
9114e78243fa: Pull complete
0b97fa2153bc: Pull complete
308c7e15be6a: Pull complete
b7f31b8e487d: Pull complete
cbbb6dec5000: Pull complete
0241c9ad6a16: Pull complete
7fa6f0b53edd: Pull complete
1c2861e152b2: Pull complete
0536f3466f66: Pull complete
Digest: sha256:3c2372e3285e6d6933ddebb5ee3ae0c4bbf7cb235084e54d33d7f0ddf4813c4a
Status: Downloaded newer image for twang2218/gitlab-ce-zh:11.1.4
[root@vm_10_14_centos gitlab]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
twang2218/gitlab-ce-zh 11.1.4 1935cc9f8798 4 months ago 1.61GB
(4)启动gitlab的容器
[root@vm_10_14_centos gitlab]# docker-compose up -d
Creating network "gitlab_default" with the default driver
Creating gitlab ... error
ERROR: for gitlab Cannot start service gitlab: b'driver failed programming external connectivity on endpoint gitlab (9308ca74b8491c556263eac9fb9b0abcb25258d9e2df5733fc4d9143d6b18dcc): Error starting userland proxy: listen tcp 0.0.0.0:22: bind: address already in use'
ERROR: for gitlab Cannot start service gitlab: b'driver failed programming external connectivity on endpoint gitlab (9308ca74b8491c556263eac9fb9b0abcb25258d9e2df5733fc4d9143d6b18dcc): Error starting userland proxy: listen tcp 0.0.0.0:22: bind: address already in use'
ERROR: Encountered errors while bringing up the project.
[root@vm_10_14_centos gitlab]# vim /etc/ssh/sshd_config
[root@vm_10_14_centos gitlab]# systemctl restart sshd
[root@vm_10_14_centos gitlab]# netstat -tulnp |grep 22
tcp 0 0 0.0.0.0:60022 0.0.0.0:* LISTEN 4044/sshd
这里须要注意的是,因为gitlab容器须要用到22端口,不能与宿主机冲突,这里须要修改宿主机的sshd服务的监听端口
[root@vm_10_14_centos gitlab]# docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------
------------------------
gitlab /assets/wrapper Up (healthy) 0.0.0.0:22->22/tcp, 0.0.0.0:443-
>443/tcp, 0.0.0.0:80->80/tcp
(5)gitlab设置开机启动
[root@vm_10_14_centos gitlab]# chmod +x /etc/rc.local
[root@vm_10_14_centos gitlab]# ls -l /etc/rc.local
lrwxrwxrwx. 1 root root 13 Jul 7 16:43 /etc/rc.local -> rc.d/rc.local
[root@vm_10_14_centos gitlab]# echo "cd /root/gitlab && docker-compose up -d" >>
/etc/rc.local
[root@gitlab gitlab]# tail -1 /etc/rc.local
cd /root/gitlab && docker-compose up -d
(6)gitlab管理界面
地址:http://129.204.133.242
帐号:root
密码:首次登录设置


