Docker
2021-05-13 19:29:29 4 举报
AI智能生成
docker基础
作者其他创作
大纲/内容
资料
学习目标
能够说出docker容器和虚拟机的主要区别能够说出docker用到的内核技术
能够安装docker
掌握镜像的常见操作
掌握镜像仓库的搭建与使用
掌握常见的容器操作命令
能够查找docker存储驱动
能够说出写时复制技术的特点
能够说出overlay2联合文件系统的特点能够使用docker跑httpd等基础应用
能够使用dockerfile构建容器镜像
能够通过link连接容器
能够说出docker本地网络的4种类型
能够通过flannel网络实现容器互联
能够安装docker
掌握镜像的常见操作
掌握镜像仓库的搭建与使用
掌握常见的容器操作命令
能够查找docker存储驱动
能够说出写时复制技术的特点
能够说出overlay2联合文件系统的特点能够使用docker跑httpd等基础应用
能够使用dockerfile构建容器镜像
能够通过link连接容器
能够说出docker本地网络的4种类型
能够通过flannel网络实现容器互联
一、认识容器技术
linux容器技术是一种轻量级的虚拟化技术。主要特点有:
1. 轻量:只打包了需要的bins/libs(也就是命令和库文件)。与宿主机共享操作系统,直接使用宿主机的内核.
2. 部署快: 容器的镜像相对虚拟机的镜像小。部署速度非常快,秒级部署
3. 移植性好: Build once,Run anywhere(一次构建,随处部署运行)。 build,ship,run
4. 资源利用率更高: 相对于虚拟机,不需要安装操作系统,所以几乎没有额外的CPU,内存消耗
二、docker介绍
Docker简介
docker就是目前最火热的能实现容器技术的软件,使用go(golang)语言开发。
参考:https://www.docker.com/
Docker版本
2017之前版本
1.7 ,1.8,1.9,1.10,1.11,1.12, 1.13
2017年的3月1号之后,Docker的版本命名开始发生变化,同时将CE版本
和EE版本进行分开。
Docker社区版(CE):为了开发人员或小团队创建基于容器的应用,与团队
成员分享和自动化的开发管道。docker-ce提供了简单的安装和快速的安
装,以便可以立即开始开发。docker-ce集成和优化,基础设施。
17-03-ce
17-06-ce
18-03-ce
18-06-ce
18-09-ce
Docker企业版(EE):专为企业的发展和IT团队建立。docker-ee为企业
提供最安全的容器平台,以应用为中心的平台。
docker用到的内核技术
Docker通过namespace实现了资源隔离
通过cgroups实现了资源限制
NameSpace
Linux内核实现namespace的一个主要目的就是实现轻量级虚拟化(容器)服务。
在同一个namespace下的进程可以感知彼此的变化,而对外界的进程一无所知。
Linux 在很早的版本中就实现了部分的 namespace,比如内核 2.4 就实现了mount namespace。
大多数的namespace支持是在内核 2.6 中完成的,比如 IPC、Network、 PID、和 UTS。
还有个别的namespace 比较特殊,比如User,从内核 2.6 就开始实现了,但在内核 3.8 中才宣布完成。
随着 Linux 自身的发展以及容器技术持续发展带来的需求,也会有新的 namespace 被支持,比如在内核 4.6 中就添加了Cgroup namespace。
inux内核提拱了6种namespace隔离的系统调用
UTS CLONE_NEWUTS 主机名或域名,每个NameSpace都拥有独立的主机名或域名,可以把每个NameSpace认为一个独立主机。
IPC CLONE_NEWIPC 信号量、消息队列和共享内存,每个容器依旧使用linux内核中进程交互的方法,实现进程间通信。
PID CLONE_NEWPID 进程编号,每个容器都拥有独立的进程树,而容器是物理机中的一个进程,所以容器中的进程是物理机的线程
net CLONE_NEWNET 网络设备接口,IP路由表、防火墙规则等,每个容器的网络是隔离
mount CLONE_NEWNS 挂载点(文件系统),每个容器的文件系统是独立的
user CLONE_NEWUSER 用户和用户组,每个容器的用户和组ID是隔离,每个容器都拥有root用户
IPC CLONE_NEWIPC 信号量、消息队列和共享内存,每个容器依旧使用linux内核中进程交互的方法,实现进程间通信。
PID CLONE_NEWPID 进程编号,每个容器都拥有独立的进程树,而容器是物理机中的一个进程,所以容器中的进程是物理机的线程
net CLONE_NEWNET 网络设备接口,IP路由表、防火墙规则等,每个容器的网络是隔离
mount CLONE_NEWNS 挂载点(文件系统),每个容器的文件系统是独立的
user CLONE_NEWUSER 用户和用户组,每个容器的用户和组ID是隔离,每个容器都拥有root用户
UTS:
小结: 应用程序运行在一个隔离的空间(namespace)内, 每个隔离的空间都
拥有独立的UTS,IPC,PID,Net,Mount,User.
Control Group
控制组(CGroup)是Linux内核的一个特性,
主要用来对共享资源进行隔
离、限制、审计等。
它可以提供对容器的内存,cpu,磁盘IO等资源
进行限制
计费管理
只有能控制分配到容器的资源,才能避免多个容器同时运行时对宿主机系统的资源竞争。
LXC与docker区别
LXC提供轻量级的容器化技术
Docker在LXC的基础上发展
三、docker环境准备
不能直接在windows上跑docker(因为namespace,cgroup是linux内核的特性,windows没有,所以需要在windows跑linux虚拟机,再跑docker)
1. 要求能访问公网
2. 关闭防火墙,selinux
docker软件安装
docker-ce的yum源下载(任选其一)
下载docker官方ce版
[root@daniel ~]# wget https://download.docker.com/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
或者使用aliyun的docker-ce源
root@daniel ~]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
PS: 注意要安装docker-ce版,不要安装docker(否则可能安装1.13老版本)
彻底卸载清除docker
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
rm -rf /etc/systemd/system/docker.service.d
rm -rf /var/lib/docker
rm -rf /var/run/docker
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
rm -rf /etc/systemd/system/docker.service.d
rm -rf /var/lib/docker
rm -rf /var/run/docker
启动服务
[root@daniel ~]# systemctl start docker
[root@daniel ~]# systemctl enable docker
[root@daniel ~]# systemctl status docker
查看版本信息
[root@daniel ~]# docker -v
Docker version 18.09.7, build 2d0083d
[root@daniel ~]# docker info
[root@daniel ~]# docker version
Client:
Version: 18.09.7
API version: 1.39
Go version: go1.10.8
Git commit: 2d0083d
Built: Thu Jun 27 17:56:06 2019
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.7
API version: 1.39 (minimum version 1.12)
Go version: go1.10.8
Git commit: 2d0083d
Built: Thu Jun 27 17:26:28 2019
OS/Arch: linux/amd64
Experimental: false
docker daemon管理
可以将client与Server进行分离,实现远程docker连接。实现远程操作docker
远程客户端主机# docker -H 容器宿主机IP version
Client:
Version: 18.09.7
API version: 1.39
Go version: go1.10.8
Git commit: 2d0083d
Built: Thu Jun 27 17:56:06 2019
OS/Arch: linux/amd64
Experimental: false
Cannot connect to the Docker daemon at
tcp://10.1.1.11:2375. Is the docker daemon running?
这个权限很大,危险
特别注意: 远程客户端主机远程操作的权限非常大,请测试完后还原
对docker daemon进行相应的配置。
1, 修改docker配置文件前,请先关闭docker守护进程
[root@daniel ~]# systemctl stop docker
2, 通过/etc/docker/daemon.json文件对docker守护进程文件进行配置
[root@daniel ~]# vim /etc/docker/daemon.json
{
"hosts":
["tcp://0.0.0.0:2375","unix:///var/run/docker.sock"]
}
[root@daniel ~]# netstat -ntlup | grep :2375
[root@daniel ~]# ls /var/run/docker.sock
{
"hosts":
["tcp://0.0.0.0:2375","unix:///var/run/docker.sock"]
}
[root@daniel ~]# netstat -ntlup | grep :2375
[root@daniel ~]# ls /var/run/docker.sock
3, 添加/etc/docker/daemon.json后会导致docker daemon无法启动, 请先
修改如下文件内容:
修改前:
[root@daniel ~]# vim
/usr/lib/systemd/system/docker.service
[Service]
Type=notify
# the default is not to use systemd for cgroups because
the delegate issues still
# exists and systemd currently does not support the cgroup
feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H fd:// --
containerd=/run/containerd/containerd.sock
[root@daniel ~]# vim
/usr/lib/systemd/system/docker.service
[Service]
Type=notify
# the default is not to use systemd for cgroups because
the delegate issues still
# exists and systemd currently does not support the cgroup
feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H fd:// --
containerd=/run/containerd/containerd.sock
修改后:
[root@daniel ~]# vim
/usr/lib/systemd/system/docker.service
[Service]
Type=notify
# the default is not to use systemd for cgroups because
the delegate issues still
# exists and systemd currently does not support the cgroup
feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd
4, 修改完成后,一定要加载此配置文件
[root@daniel ~]# systemctl daemon-reload
5, 重新开启docker守护进程
[root@daniel ~]# systemctl start docker
[root@daniel ~]# netstat -ntlup | grep :2375
tcp6 0 0 :::2375 :::*
LISTEN 3318/dockerd
6, 实例远程连接方法
远程客户端主机# docker -H 容器宿主机IP version
注意: 客户端远程连接不需要加端口号
7.测试完后还原
按照上述,删除其操作的痕迹
systemctl daemon-reload
四、镜像,容器,仓库
镜像(image): 镜像就是打包好的环境与应用。
容器(contanier): 容器就是运行镜像的实例. 镜像看作是静态的,容器是动态的。
仓库(repository): 存放多个镜像的一个仓库。
五、镜像常见操作
镜像主要分为两类:
1. 操作系统类(如centos,ubuntu)
2. 应用程序类
命令
查看镜像列表
通过docker images命令查看当前镜像列表; 使用man docker-images得到参数说明
[root@daniel ~]# docker images
搜索镜像
通过docker search查找官方镜像; 使用man docker-search得到参数说明
[root@daniel ~]# docker search centos
拉取镜像
通过docker pull拉取(下载)镜像; 使用man docker-pull得到参数说明
[root@daniel ~]# docker pull
[root@daniel ~]# docker pull centos
或
[root@daniel ~]# docker pull docker.io/centos 名字为
search查找时得到的全名
如果网速慢,可以试试阿里,腾讯,百度,网易等国内的镜像仓库,比如:
[root@daniel ~]# docker pull
hub.c.163.com/library/centos:latest
删除镜像
通过docker rmi删除镜像; man docker-rmi查看参数帮助
[root@daniel ~]# docker rmi
hub.c.163.com/library/centos:latest
问题:如果镜像pull非常慢,怎么解决?
镜像加速器
国内的几个互联网巨头都有自己的容器服务。
阿里云容器镜像服务地址:https://cr.console.aliyun.com/cn-hangzhou/ne
w 申请一个阿里账号登录
修改daemon.json配置文件
[root@daniel ~]# vim /etc/docker/daemon.json
{
"registry-mirrors":
["https://42h8kzrh.mirror.aliyuncs.com"]
}
[root@daniel ~]# systemctl daemon-reload
[root@daniel ~]# systemctl restart docker
镜像导出
使用docker save保存(导出)镜像为一个tar文件
[root@daniel ~]# docker save centos -o
/root/dockerimage_centos.latest
镜像导入
使用docker load导入
测试时可以将导出的文件scp传输到另一台宿主机测试。或者先删除本地的
镜像再导入测试
[root@daniel ~]# docker load <
/root/dockerimage_centos.latest
修改镜像名
可以使用docker tag 命令改名称
六、镜像仓库
官方自建镜像仓库
docker hub为最大的公开仓库,也就是官方仓库: https://hub.docker.com/
1, 没有账号的先上网申请账号
2, 回到宿主机登录账号与密码
# docker login
Login with your Docker ID to push and pull images from
Docker Hub. If you don't have a Docker ID, head over to
https://hub.docker.com to create one.
Username: linuxdaniel
Password:
Login Succeeded
3, tag你的镜像
我们从dockerhub上下载的公开镜像是不能直接上传的,要先tag(打标签,
类似于重新指定路径并命名)
[root@daniel ~]# docker push centos:latest
Error response from daemon: You cannot push a "root"
repository. Please rename your repository to
docker.io/<user>/<repo> (ex: docker.io/<user>/centos)
[root@daniel ~]# docker tag centos:latest
linuxdaniel/daniel_docker_repo:V1
[root@daniel ~]# docker push
linuxdaniel/daniel_docker_repo:V1
Error response from daemon: You cannot push a "root"
repository. Please rename your repository to
docker.io/<user>/<repo> (ex: docker.io/<user>/centos)
[root@daniel ~]# docker tag centos:latest
linuxdaniel/daniel_docker_repo:V1
[root@daniel ~]# docker push
linuxdaniel/daniel_docker_repo:V1
4, push镜像到仓库
[root@daniel ~]# docker push
linuxdaniel/daniel_docker_repo:V1
5, 验证
6, 登出账号
[root@daniel ~]# docker logout
Removing login credentials for https://index.docker.io/v1/
阿里云镜像仓库
1. 登录阿里云Docker Registry
$ sudo docker login --username=王wang91 registry.cn-hangzhou.aliyuncs.com
用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。
2. 从Registry中拉取镜像
$ sudo docker pull registry.cn-hangzhou.aliyuncs.com/wangx-ali/tesi1:[镜像版本号]
3. 将镜像推送到Registry
$ sudo docker login --username=王wang91 registry.cn-hangzhou.aliyuncs.com
$ sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/wangx-ali/tesi1:[镜像版本号]
$ sudo docker push registry.cn-hangzhou.aliyuncs.com/wangx-ali/tesi1:[镜像版本号]
4. 选择合适的镜像仓库地址
从ECS推送镜像时,可以选择使用镜像仓库内网地址。推送速度将得到提升并且将不会损耗您的公网流量。
如果您使用的机器位于VPC网络,请使用 registry-vpc.cn-hangzhou.aliyuncs.com 作为Registry的域名登录。
如果您使用的机器位于VPC网络,请使用 registry-vpc.cn-hangzhou.aliyuncs.com 作为Registry的域名登录。
5. 示例
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
registry.aliyuncs.com/acs/agent 0.7-dfb6816 37bb9c63c8b2 7 days ago 37.89 MB
$ sudo docker tag 37bb9c63c8b2 registry-vpc.cn-hangzhou.aliyuncs.com/acs/agent:0.7-dfb6816
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
registry.aliyuncs.com/acs/agent 0.7-dfb6816 37bb9c63c8b2 7 days ago 37.89 MB
$ sudo docker tag 37bb9c63c8b2 registry-vpc.cn-hangzhou.aliyuncs.com/acs/agent:0.7-dfb6816
harbor私有镜像仓库
Harbor是VMware公司开源了企业级Registry项目, 可以帮助用户快速搭建一个企业级的Docker registry
harbor由python语言开发, 需要使用docker-compose工具进行启动
需要的工具
使用epel源安装pip
使用pip安装dockers-compose
环境准备
再准备一台新的虚拟机(192.168.122.18)做harbor服务器
安装过程
1, 安装docker-compose
安装方法1:
因为centos7上默认安装了python2.7,我们这里安装python2-pip,然后通过pip安装docker-compose模块
[root@harbor ~]# yum install epel-release -y
[root@harbor ~]# yum install python2-pip -y
[root@harbor ~]# pip install -i https://pypi.tuna.tsinghua.edu.cn/simple docker-compose指定清华源安装速度较快
[root@harbor ~]# yum install python2-pip -y
[root@harbor ~]# pip install -i https://pypi.tuna.tsinghua.edu.cn/simple docker-compose指定清华源安装速度较快
[root@harbor ~]# docker-compose -v
docker-compose version 1.24.1, build 4667896b
安装方法2:
[root@harbor ~]# curl -L
https://get.daocloud.io/docker/compose/releases/download/1 .24.1/docker-compose-`uname -s`-`uname -m` >
/usr/local/bin/docker-compose
[root@harbor ~]# chmod +x /usr/local/bin/docker-compose
https://get.daocloud.io/docker/compose/releases/download/1 .24.1/docker-compose-`uname -s`-`uname -m` >
/usr/local/bin/docker-compose
[root@harbor ~]# chmod +x /usr/local/bin/docker-compose
安装方法3:
[root@harbor ~]# yum install epel-release
[root@harbor ~]# yum install docker-compose
注意:此安装方法安装的版本较低,如果harbor版本太新,可能会不兼容
2, 在harbor服务器上安装docker-ce并启动docker服务
root@harbor ~]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
[root@harbor ~]# yum install docker-ce
[root@harbor ~]# systemctl start docker
[root@harbor ~]# systemctl enable docker
3, 安装harbor
harbor分为离线包和在线包两种。在线包较小,但需要连网下载。
下载地址: https://github.com/goharbor/harbor/releases
也可以使用harbor-offline-installer-v1.8.2.tgz
4,浏览器访问 http://192.168.122.18,登录进行配置
镜像上传下载操作
5, 在docker宿主机配置非https连接
配置"insecure-registries": ["harbor服务器IP"]来使用http通讯
[root@daniel ~]# vim /etc/docker/daemon.json
{
"registry-mirrors":
["https://42h8kzrh.mirror.aliyuncs.com"], 这里有一个逗号
"insecure-registries": ["192.168.122.18"]
}
[root@daniel ~]# systemctl restart docker
6, 在docker宿主机登下载一个测试镜像,并tag成 harborIP/项目名/镜像
名:TAG
[root@daniel ~]# docker pull hello-world
[root@daniel ~]# docker tag hello-world
192.168.122.18/test/hello-world:v1
[root@daniel ~]# docker tag hello-world
192.168.122.18/test/hello-world:v1
7, 登陆服务器,并push上传镜像
[root@daniel ~]# docker login 192.168.122.18
Username: admin
Password: 密码为前面修改好的123
Login Succeeded
[root@daniel ~]# docker push 192.168.122.18/test/helloworld:
v1
不用了可以logout
[root@daniel ~]# docker logout 192.168.122.18
Username: admin
Password: 密码为前面修改好的123
Login Succeeded
[root@daniel ~]# docker push 192.168.122.18/test/helloworld:
v1
不用了可以logout
[root@daniel ~]# docker logout 192.168.122.18
8, 浏览器界面验证
9, docker宿主机想要pull上传的镜像,可以这样做
删除镜像再重新从harbor仓库上下载
[root@daniel ~]# docker rmi 192.168.122.18/test/hello-world:v1
私有项目里的镜像需要先登录,再pull(公共项目里的镜像不用登录就可以直接pull,请自行测试)
[root@daniel ~]# docker login 192.168.122.18
Username: admin
Password: 密码为前面设置的123
Login Succeeded
[root@daniel ~]# docker pull 192.168.122.18/test/hello-world:v1
七、容器常见操作
查看容器列表
列表所有状态的容器,现在为空列表
使用man docker-ps得到参数说明
[root@daniel ~]# docker ps -a
运行第一个容器
通过hello-world这个镜像,运行一个容器(没有定义容器名称,则为随机名称)
当前docker-host(容器宿主机)如果有hello-world这个镜像,则直接使用
如果没有相关镜像,则会从docker hub去下载(配置了镜像加速器的优先找加速器)
使用man docker-run得到参数说明
[root@daniel ~]# docker run hello-world
问题: 为什么容器运行完hello-world后就退出了,而不是继续运行?
我们前面把容器比喻为轻量级虚拟机,但是容器实际上只是进程。进行运行
完了当然就退出了, 除非是类似服务那样的守护进程。
容器运行命令或脚本
指定使用docker.io/centos镜像运行"echo haha"命令
latest是默认的TAG标签,可以省略;如果是其它TAG就不能省略,否则会默认
为latest
[root@daniel ~]# docker run centos:latest echo haha
haha
docker运行一个不间断的脚本, -d表示后台运行(后台运行表示不输出结果
到屏幕)
[root@daniel ~]# docker run -d centos /bin/bash -c "while
true; do echo haha;sleep 3;done"
查看刚才运行的容器
只有不间断运行脚本的容器还在UP状态,其它都为Exited状态
[root@daniel ~]# docker ps -a |awk -F"[ ]{2}*" '{print
$1"\t\t"$3"\t\t"$5"\t"$NF}'
CONTAINER ID COMMAND STATUS
NAMES
21086dab3efa "/bin/bash -c 'whi..." Up 1 minutes
sleepy_ride
495310e96d9f "echo haha" Exited (0) 3 minutes
ago unruffled_jepsen
6e3f991b9e8a "/hello" Exited (0) 15 minutes
ago silly_lovelace
查看容器运行结果
后面接容器ID,也可以接容器名称
[root@daniel ~]# docker logs 21086dab3efa
停止容器
[root@daniel ~]# docker stop 21086dab3efa
启动容器
[root@daniel ~]# docker start 21086dab3efa
查看容器的相关信息
root@daniel ~]# docker inspect 21086dab3efa
复制文件到容器中
docker cp [源文件] [容器中的目标文件]
Copy files/folders between a container and the local filesystem
运行容器并交互式操作
使用下面命令启动容器;-i指交互;-t指tty终端;--name是用来指定容器名称
[root@daniel ~]# docker run -i -t --name=c1 centos:latest
/bin/bash
[root@f736fe36002c /]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core) 可
以看到我们下载的centos是7.6版本
[root@f736fe36002c /]# uname -r
3.10.0-862.el7.x86_64 查看的内核却与宿主机
centos7.5一样,说明是共享宿主机的内核
在容器内操作(我这里创建一个文件,然后退出)
[root@f736fe36002c /]# touch /root/daniel
[root@f736fe36002c /]# exit
exit
实验: 交互式操作退出后如何再查看或修改先前在容器里创建的文件?
不要再使用下面的命令了,因为名称冲突,会报错(换一个名称会启动一个新的
容器)
[root@daniel ~]# docker run -i -t --name=c1 centos:latest
/bin/bash
1,使用下面命令查看到c1容器已经为Exited状态;-l表示列表最近的容器
2,启动容器
[root@daniel ~]# docker start c1
3,然后使用attach指令连接UP状态的容器(Exited状态的容器无法
attach)
[root@daniel ~]# docker attach c1
4,验证文件,可以按需求修改
[root@f736fe36002c /]# ls /root/daniel -l
-rw-r--r-- 1 root root 0 Dec 19 12:30 /root/daniel
[root@f736fe36002c /]# exit
exit
5, commit提交成一个新的镜像;c63d63bff173为容器ID;test_image为新的
镜像名称
[root@daniel ~]# docker commit c63d63bff173 test_image
sha256:bfb4e268cc6b683e1fc19346daf446ddd85dc7d75bcaa5cfd80
978ac271a913f
6,验证新的镜像
[root@daniel ~]# docker images |grep test_image
test_image latest bfb4e268cc6b
47 seconds ago 202 MB
容器外指定容器运行命令
可以在宿主机通过exec指令传命令到容器中执行,但要求容器为UP状态
[root@daniel ~]# docker start c1
在container1容器里创建文件并验证;man docker-exec查看帮助
[root@daniel ~]# docker exec c1 touch /root/123
[root@daniel ~]# docker exec c1 ls -l /root/123
或者用下面的命令连接上去交互式操作
[root@daniel ~]# docker exec -it c1 /bin/bash
删除容器
UP状态的容器要先停止才能删除
[root@daniel ~]# docker stop 21086dab3efa
[root@daniel ~]# docker rm 21086dab3efa
批量删除所有容器
加-q参数只查看所有容器的ID
[root@daniel ~]# docker ps -aq
f736fe36002c
21086dab3efa
495310e96d9f
6e3f991b9e8a
停止所有容器
[root@daniel ~]# docker stop $(docker ps -aq)
删除所有容器
[root@daniel ~]# docker rm $(docker ps -aq)
容器与镜像迁移
注:
用户既可以使用 docker load 来导入镜像存储文件到本地镜像库,也可以使用 docker import 来导入一个容器快照到本地镜像库。这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。此外,从容器快照文件导入时可以重新指定标签等元数据信息。
export与import命令:
export:
导出容器会丢失历史记录和元数据,类似与快照。
命令格式:
docker export [容器ID|Name] > xxx.tar
或
docker export -o xxx.tar [容器ID|Name]
或
docker export -o xxx.tar [容器ID|Name]
docker export --output="latest.tar" red_panda
应用场景:
主要用来制作基础镜像
import:
导入容器快照到本地镜像库。
命令格式:
docker import xxx.tar newname:tag
例子
1.创建容器web并新增数据
[root@localhost ~]# docker run -itd --name web nginx
9a17f7c9f00a3711018581a1523ecd7a06c40d1408ae5678e034be1a1e4e0cd8
[root@localhost ~]# docker exec -it web touch /mnt/test.txt
[root@localhost ~]# docker exec -it web ls /mnt/
test.txt
9a17f7c9f00a3711018581a1523ecd7a06c40d1408ae5678e034be1a1e4e0cd8
[root@localhost ~]# docker exec -it web touch /mnt/test.txt
[root@localhost ~]# docker exec -it web ls /mnt/
test.txt
2.导出容器快照
[root@localhost ~]# docker export web > web.tar
[root@localhost ~]# ll -h web.tar
-rw-r--r-- 1 root root 123M 5月 13 04:34 web.tar
[root@localhost ~]# ll -h web.tar
-rw-r--r-- 1 root root 123M 5月 13 04:34 web.tar
3.导入容器快照到本机镜像库
[root@localhost ~]# docker import web.tar web:v1
sha256:134f9251e15e56060d564c23cec4be0048434fb90b19188ea64bf77af77b85ff
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
web v1 134f9251e15e 10 minutes ago 125MB
sha256:134f9251e15e56060d564c23cec4be0048434fb90b19188ea64bf77af77b85ff
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
web v1 134f9251e15e 10 minutes ago 125MB
4.启动使用import导入镜像库的web:v1镜像,并查看数据
[root@localhost ~]# docker run -itd --name web2 web:v1 /bin/bash
ef07135bcda92c8660392ce29e24c7c8de82f3369fb024ae772c34cd74b9258d
[root@localhost ~]# docker exec -it web2 ls /mnt/
test.txt
ef07135bcda92c8660392ce29e24c7c8de82f3369fb024ae772c34cd74b9258d
[root@localhost ~]# docker exec -it web2 ls /mnt/
test.txt
注意:
启动export与import命令导出导入的镜像必须加/bin/bash或者其他/bin/sh,否则会报错。
docker: Error response from daemon: No command specified.
docker: Error response from daemon: No command specified.
总结:
通过export命令也可以将容器里的数据保存,并可以迁移到别的docker主机。
1.会丢弃历史记录和元数据。
导出容器会丢失历史记录和元数据,类似与快照。
2.启动export与import命令导出导入的镜像必须加/bin/bash或者其他/bin/sh,否则会报错。
docker: Error response from daemon: No command specified.
docker: Error response from daemon: No command specified.
commit命令:
将已存在容器中的镜像和修改内容提交为一个新的镜像,通过这个方式同样能保存读写层内容。
命令格式:
docker commit [容器名称|ID] 生成新的镜像名字
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Options
选项说明:
-a:提交的镜像作者
-c:使用dockerfile指令来创建镜像
-m:提交时的说明文字
-p:在commit的时候,将正在运行的容器暂停
-c:使用dockerfile指令来创建镜像
-m:提交时的说明文字
-p:在commit的时候,将正在运行的容器暂停
应用场景:
主要作用是将配置好的一些容器生成新的镜像,可以得到复用(再次使用不需要再配置)。
例子
1.启动一个nginx容器,并且在容器的/mnt目录下创建一个文件
[root@localhost ~]# docker run -itd --name nginxweb -p 80:80 nginx
fda3ca1b33ba4c9dc6a1ca27c7242bbbdc2a08f4e6e7642d3ec5de62e1e8f78c
[root@localhost ~]# docker exec -it nginxweb touch /mnt/test.txt
[root@localhost ~]# docker exec -it nginxweb ls /mnt/
test.txt
fda3ca1b33ba4c9dc6a1ca27c7242bbbdc2a08f4e6e7642d3ec5de62e1e8f78c
[root@localhost ~]# docker exec -it nginxweb touch /mnt/test.txt
[root@localhost ~]# docker exec -it nginxweb ls /mnt/
test.txt
2.将nginxweb容器commit成一个新的镜像
[root@localhost ~]# docker commit nginxweb nginx_test:v1
sha256:a06b16b343036bcbf424c499022ca635bf90740aa7d76acbe0c271a731aba2ef
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx_test v1 a06b16b34303 4 seconds ago 127MB
sha256:a06b16b343036bcbf424c499022ca635bf90740aa7d76acbe0c271a731aba2ef
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx_test v1 a06b16b34303 4 seconds ago 127MB
3.使用nginxweb生成的新镜像nginx_test启动一个nginx_v1容器,并查看新容器中的数据
[root@localhost ~]# docker stop nginxweb //为了方便先停止nginxweb容器,因为80端口已被占用
nginxweb
[root@localhost ~]# docker run -itd --name nginx_v1 -p 80:80 nginx_test:v1
df074341d7a39b072966672ef9bb8769142b67395488e30e81711d0c75f2a821
[root@localhost ~]# docker exec -it nginx_v1 ls /mnt/
test.txt ---》可以看到新容器nginx_v1中有之前nginxweb的数据
nginxweb
[root@localhost ~]# docker run -itd --name nginx_v1 -p 80:80 nginx_test:v1
df074341d7a39b072966672ef9bb8769142b67395488e30e81711d0c75f2a821
[root@localhost ~]# docker exec -it nginx_v1 ls /mnt/
test.txt ---》可以看到新容器nginx_v1中有之前nginxweb的数据
注意:
commit 命令虽然能实现保存读写层数据,但不适于做数据持久化。
save与load命令:
save:
将指定镜像保存成tar文件。
命令格式:
docker save 镜像名 > xxx.tar
或
docker save -o xxx.tar 镜像名
或
docker save -o xxx.tar 镜像名
docker save [OPTIONS] IMAGE [IMAGE...]
应用场景:
如果你的应用是使用docker-compose.yml编排的多个镜像组合,但你要部署的客户服务器并不能连外网。这时,你可以使用docker save将用到的镜像打个包,然后拷贝到客户服务器上使用docker load载入(一般用于镜像迁移到别处)。
load:
导入使用docker save命令导出的镜像。
命令格式:
docker load -i xxx.tar
或
docker load < xxx.tar
或
docker load < xxx.tar
docker load [OPTIONS]
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
$ docker load < busybox.tar.gz
Loaded image: busybox:latest
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 769b9341d937 7 weeks ago 2.489 MB
$ docker load --input fedora.tar
Loaded image: fedora:rawhide
Loaded image: fedora:20
REPOSITORY TAG IMAGE ID CREATED SIZE
$ docker load < busybox.tar.gz
Loaded image: busybox:latest
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 769b9341d937 7 weeks ago 2.489 MB
$ docker load --input fedora.tar
Loaded image: fedora:rawhide
Loaded image: fedora:20
注意:
1.不会丢弃历史记录和元数据,并可以回滚版本。
2.启动不用加/bin/bash。
2.启动不用加/bin/bash。
注意
docker save和docker export的区别
docker save保存的是镜像(image),docker export保存的是容器(container);
docker load用来载入镜像包,docker import用来载入容器包,但两者都会恢复为镜像;
docker load不能对载入的镜像重命名,而docker import可以为镜像指定新名称。
docker export的包会比save的包要小,原因是save的是一个分层的文件系统,export导出的只是一个linux系统的文件目录。
docker load用来载入镜像包,docker import用来载入容器包,但两者都会恢复为镜像;
docker load不能对载入的镜像重命名,而docker import可以为镜像指定新名称。
docker export的包会比save的包要小,原因是save的是一个分层的文件系统,export导出的只是一个linux系统的文件目录。
相关资料
案例
运行一段时间后的容器,其中包含了新的数据,如果想把这些内容数据一并迁移到新的主机上,可以按照以下步骤进行:
1.提交容器生成新的镜像
[root@localhost ~]# docker ps //查看正在运行的容器web
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9a17f7c9f00a nginx "nginx -g 'daemon of…" 19 hours ago Up 19 hours 80/tcp web
[root@localhost ~]# docker commit -p web webdata:v1 //-p暂停web容器并提交为新镜像webdata:v1
sha256:b25ea02c5f1f4efe4c35d6503a277d968d5dfdf0cfd69092b3e99202dd687723
[root@localhost ~]# docker images //查看提交的新镜像webdata
REPOSITORY TAG IMAGE ID CREATED SIZE
webdata v1 b25ea02c5f1f 3 seconds ago 127MB
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9a17f7c9f00a nginx "nginx -g 'daemon of…" 19 hours ago Up 19 hours 80/tcp web
[root@localhost ~]# docker commit -p web webdata:v1 //-p暂停web容器并提交为新镜像webdata:v1
sha256:b25ea02c5f1f4efe4c35d6503a277d968d5dfdf0cfd69092b3e99202dd687723
[root@localhost ~]# docker images //查看提交的新镜像webdata
REPOSITORY TAG IMAGE ID CREATED SIZE
webdata v1 b25ea02c5f1f 3 seconds ago 127MB
2.将镜像保存成一个tar压缩包
[root@localhost ~]# docker save webdata:v1 > webdata.tar
[root@localhost ~]# ll -h webdata.tar
-rw-r--r-- 1 root root 125M 5月 13 23:47 webdata.tar
[root@localhost ~]# ll -h webdata.tar
-rw-r--r-- 1 root root 125M 5月 13 23:47 webdata.tar
3.将tar压缩包复制到另一台主机
[root@localhost ~]# scp webdata.tar root@192.168.2.128:/root/test
4.在另一台主机上加载镜像的tar压缩包
[root@localhost ~]# cd test/
[root@localhost test]# ll
总用量 127572
-rw-r--r-- 1 root root 130631168 5月 13 23:49 webdata.tar
[root@localhost test]# docker load -i webdata.tar
d9d778e6751c: Loading layer [==================================================>] 10.24kB/10.24kB
Loaded image: webdata:v1
[root@localhost test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
webdata v1 b25ea02c5f1f 12 minutes ago 127MB
[root@localhost test]# ll
总用量 127572
-rw-r--r-- 1 root root 130631168 5月 13 23:49 webdata.tar
[root@localhost test]# docker load -i webdata.tar
d9d778e6751c: Loading layer [==================================================>] 10.24kB/10.24kB
Loaded image: webdata:v1
[root@localhost test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
webdata v1 b25ea02c5f1f 12 minutes ago 127MB
5.使用这个加载的镜像运行容器
[root@localhost test]# docker run -itd --name web webdata:v1
51d9ed10961b9620ea6456f5bd75dbd43168b73c7bd184dcccdd25fcf956d9e5
[root@localhost test]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
51d9ed10961b webdata:v1 "nginx -g 'daemon of…" 35 seconds ago Up 33 seconds 80/tcp web
[root@localhost test]# docker exec -it web ls /mnt/
test.txt
51d9ed10961b9620ea6456f5bd75dbd43168b73c7bd184dcccdd25fcf956d9e5
[root@localhost test]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
51d9ed10961b webdata:v1 "nginx -g 'daemon of…" 35 seconds ago Up 33 seconds 80/tcp web
[root@localhost test]# docker exec -it web ls /mnt/
test.txt
八、docker存储驱动
写时复制与用时分配
一个镜像可以跑多个容器,如果每个容器都去复制一份镜像内的文件系统,那么将会占用大量的存储空间。
docker使用了写时复制cow(copy-on-write)和用时分配(allocate-on-demand)技术来提高存储的利用率。
可以提高效率和节省资源
写时复制:
写时复制技术可以让多个容器共享同一个镜像的文件系统, 所有数据都从镜像中读取
只有当要对文件进行写操作时,才从镜像里把要写的文件复制到自己的文件系统进行修改。所以无论有多少个容器共享同一个镜像,所做的写操作都是对从镜像中复制到自己的文件系统中的复本上进行,并不会修改镜像的源文件
多个容器操作同一个文件,会在每个容器的文件系统里生成一个复本,每个容器修改的都是自己的复本,相互隔离,相互不影响
用时分配:
启动一个容器,并不会为这个容器预分配一些磁盘空间,而是当有新文件写入时,才按需分配新空间
联合文件系统
联合文件系统(UnionFS)就是把不同物理位置的目录合并mount到同一个目录中.
思考: 把光盘看作是docker里的image,而硬盘目录看作是container,你再想想看?
docker就支持aufs和overlay两种联合文件系统。
aufs
aufs(Another UnionFS),后来叫Alternative UnionFS,后来可能觉得不够霸气,叫成Advance UnionFS.
Docker最开始采用AUFS作为文件系统,也得益于AUFS分层的概念,实现了多个Container可以共享同一个image。
除了最上面的一层为读写层之外,下面的其他的层都是只读的镜像层.
分层结构不适合文件频繁变化的工具,例如数据库
可以把经常改动的文件放在容器外边,不经常改动的放在容器内部。
overlay
由于AUFS未并入Linux内核,且只支持Ubuntu,考虑到兼容性问题,在Docker 0.7版本中引入了存储驱动。
目前,Docker支持AUFS,OverlayFS,Btrfs,Device mapper,ZFS五种存储驱动.
查看docker的文件系统
# docker info |grep "Storage Driver"
Storage Driver: overlay2
Storage Driver: overlay2
# lsmod |egrep 'aufs|overlay'
overlay 71964 7
描述
Overlay是Linux内核3.18后支持的
如果upperdir和lowerdir有同名文件时会用upperdir的文件
读文件的时候,文件不在upperdir则从lowerdir读
如果写的文件不在uppderdir在lowerdir,则从lowerdir里面copy到upperdir。
不管文件多大,copy完再写,删除镜像层的文件只是在容器层生成
OverlayFS只有两层:
一个upper文件系统
代表Docker的容器层
高层目录upperdir
一个lower文件系统
代表镜像层.
底层目录lowerdir
aufs,overlay,overlay2对比
aufs: 使用多层分层
overlay: 使用2层分层, 共享数据方式是通过硬连接,只挂载一层,其他层通过最高层通过硬连接形式共享(增加了磁盘inode的负担)
overlay2: 使用2层分层, 驱动原生地支持多层lower overlay镜像(最多128层),与overlay驱动对比,消耗更少的inode
Docker不同阶段的存储状况
docker第1次启动前
在刚安装docker-ce第1次启动服务之前,/var/lib/下并没有docker这个目录
docker启动后
第1次systemctl start docker 启动后,则会产生/var/lib/docker 目录
[root@vm2 ~]# systemctl start docker
[root@vm2 ~]# ls -l /var/lib/docker
total 0
drwx------ 2 root root 24 Jun 23 15:30 builder
drwx------ 4 root root 92 Jun 23 15:30 buildkit
drwx------ 2 root root 6 Jun 23 15:30 containers
drwx------ 3 root root 22 Jun 23 15:30 image
drwxr-x--- 3 root root 19 Jun 23 15:30 network
drwx------ 3 root root 40 Jun 23 15:39 overlay2
drwx------ 4 root root 32 Jun 23 15:30 plugins
drwx------ 2 root root 6 Jun 23 15:39 runtimes
drwx------ 2 root root 6 Jun 23 15:30 swarm
drwx------ 2 root root 6 Jun 23 15:41 tmp
drwx------ 2 root root 6 Jun 23 15:30 trust
drwx------ 2 root root 25 Jun 23 15:30 volumes
[root@vm2 ~]# ls -l /var/lib/docker
total 0
drwx------ 2 root root 24 Jun 23 15:30 builder
drwx------ 4 root root 92 Jun 23 15:30 buildkit
drwx------ 2 root root 6 Jun 23 15:30 containers
drwx------ 3 root root 22 Jun 23 15:30 image
drwxr-x--- 3 root root 19 Jun 23 15:30 network
drwx------ 3 root root 40 Jun 23 15:39 overlay2
drwx------ 4 root root 32 Jun 23 15:30 plugins
drwx------ 2 root root 6 Jun 23 15:39 runtimes
drwx------ 2 root root 6 Jun 23 15:30 swarm
drwx------ 2 root root 6 Jun 23 15:41 tmp
drwx------ 2 root root 6 Jun 23 15:30 trust
drwx------ 2 root root 25 Jun 23 15:30 volumes
[root@vm2 ~]# cd /var/lib/docker/overlay2/
[root@vm2 overlay2]# ls
total 0
brw------- 1 root root 8, 3 Jul 26 14:10 backingFsBlockDev
drwx------ 2 root root 6 Jul 26 14:10 l
下载镜像后
[root@vm2 overlay2]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
8ba884070f61: Pull complete
Digest:
sha256:a799dd8a2ded4a83484bbae769d97655392b3f86533ceb7dd96
bbac929809f3c
Status: Downloaded newer image for centos:latest
Using default tag: latest
latest: Pulling from library/centos
8ba884070f61: Pull complete
Digest:
sha256:a799dd8a2ded4a83484bbae769d97655392b3f86533ceb7dd96
bbac929809f3c
Status: Downloaded newer image for centos:latest
[root@vm2 overlay2]# pwd
/var/lib/docker/overlay2
[root@vm2 overlay2]# ls
23664d7a4167e74ee04838d87cd3568cc82be49f781bba2212b9bff942
bb8fa4 backingFsBlockDev l
[root@vm2 overlay2]# ls
23664d7a4167e74ee04838d87cd3568cc82be49f781bba2212b9bff942
bb8fa4/
diff link
[root@vm2 overlay2]# ls
23664d7a4167e74ee04838d87cd3568cc82be49f781bba2212b9bff942
bb8fa4/diff/
anaconda-post.log bin dev etc home lib lib64 media
mnt opt proc root run sbin srv sys tmp usr var
[root@vm2 overlay2]# cat
23664d7a4167e74ee04838d87cd3568cc82be49f781bba2212b9bff942
bb8fa4/link
5D7D6BY2V3FKMZHUU6VHK7ILWL
[root@vm2 overlay2]# ll l
total 0
lrwxrwxrwx 1 root root 72 Jul 26 14:16
5D7D6BY2V3FKMZHUU6VHK7ILWL ->
../23664d7a4167e74ee04838d87cd3568cc82be49f781bba2212b9bff
942bb8fa4/diff
/var/lib/docker/overlay2
[root@vm2 overlay2]# ls
23664d7a4167e74ee04838d87cd3568cc82be49f781bba2212b9bff942
bb8fa4 backingFsBlockDev l
[root@vm2 overlay2]# ls
23664d7a4167e74ee04838d87cd3568cc82be49f781bba2212b9bff942
bb8fa4/
diff link
[root@vm2 overlay2]# ls
23664d7a4167e74ee04838d87cd3568cc82be49f781bba2212b9bff942
bb8fa4/diff/
anaconda-post.log bin dev etc home lib lib64 media
mnt opt proc root run sbin srv sys tmp usr var
[root@vm2 overlay2]# cat
23664d7a4167e74ee04838d87cd3568cc82be49f781bba2212b9bff942
bb8fa4/link
5D7D6BY2V3FKMZHUU6VHK7ILWL
[root@vm2 overlay2]# ll l
total 0
lrwxrwxrwx 1 root root 72 Jul 26 14:16
5D7D6BY2V3FKMZHUU6VHK7ILWL ->
../23664d7a4167e74ee04838d87cd3568cc82be49f781bba2212b9bff
942bb8fa4/diff
下载完镜像,overlay2目录里多了一个23664....这样的目录,只有1层
此目录内部的diff子目录记录每一层自己的数据link记录该层链接目录(和overlay目录下l子目录里记录的链接是一致的)
子目录l中包含了很多软链接,使用短名称指向了其他层,短名称用于避免mount参数时达到页面大小的限制
运行容器后
[root@vm2 overlay2]# docker run -i -t --name=c1
centos:latest /bin/bash
[root@9169c38e6424 /]
同时按ctrl+p+q三键退出,保持容器为UP状态
centos:latest /bin/bash
[root@9169c38e6424 /]
同时按ctrl+p+q三键退出,保持容器为UP状态
[root@vm2 overlay2]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES
9169c38e6424 centos:latest "/bin/bash" 12 seconds ago
Up 10 seconds c1
CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES
9169c38e6424 centos:latest "/bin/bash" 12 seconds ago
Up 10 seconds c1
容器运行后,再次查看overlay2目录下的情况
[root@vm2 overlay2]# ll
3652e67b65ebe7eaed7cc879f8470983181fc19fee2f3d72173e67666e
28ec74/
total 8
drwxr-xr-x 2 root root 6 Jul 26 14:30 diff
-rw-r--r-- 1 root root 26 Jul 26 14:30 link
-rw-r--r-- 1 root root 57 Jul 26 14:30 lower
drwxr-xr-x 1 root root 6 Jul 26 14:30 merged
drwx------ 3 root root 18 Jul 26 14:30 work
3652e67b65ebe7eaed7cc879f8470983181fc19fee2f3d72173e67666e
28ec74/
total 8
drwxr-xr-x 2 root root 6 Jul 26 14:30 diff
-rw-r--r-- 1 root root 26 Jul 26 14:30 link
-rw-r--r-- 1 root root 57 Jul 26 14:30 lower
drwxr-xr-x 1 root root 6 Jul 26 14:30 merged
drwx------ 3 root root 18 Jul 26 14:30 work
lower指定了下层
work用来完成如copy-on_write的操作。
[root@vm2 overlay2]# cat
3652e67b65ebe7eaed7cc879f8470983181fc19fee2f3d72173e67666e
28ec74/lower
l/UQF6DWQE64JXS3TEBUFOBSD3TY:l/5D7D6BY2V3FKMZHUU6VHK7ILWL
3652e67b65ebe7eaed7cc879f8470983181fc19fee2f3d72173e67666e
28ec74/lower
l/UQF6DWQE64JXS3TEBUFOBSD3TY:l/5D7D6BY2V3FKMZHUU6VHK7ILWL
[root@vm2 overlay2]# ls -l l/
total 0
lrwxrwxrwx 1 root root 72 Jul 26 14:16 5D7D6BY2V3FKMZHUU6VHK7ILWL ->
../23664d7a4167e74ee04838d87cd3568cc82be49f781bba2212b9bff 942bb8fa4/diff
lrwxrwxrwx 1 root root 72 Jul 26 14:30 KBKN2UECH7JGUJBUGIVHYV4ERX ->
../3652e67b65ebe7eaed7cc879f8470983181fc19fee2f3d72173e676 66e28ec74/diff
lrwxrwxrwx 1 root root 77 Jul 26 14:30 UQF6DWQE64JXS3TEBUFOBSD3TY ->
../3652e67b65ebe7eaed7cc879f8470983181fc19fee2f3d72173e676 66e28ec74-init/diff
total 0
lrwxrwxrwx 1 root root 72 Jul 26 14:16 5D7D6BY2V3FKMZHUU6VHK7ILWL ->
../23664d7a4167e74ee04838d87cd3568cc82be49f781bba2212b9bff 942bb8fa4/diff
lrwxrwxrwx 1 root root 72 Jul 26 14:30 KBKN2UECH7JGUJBUGIVHYV4ERX ->
../3652e67b65ebe7eaed7cc879f8470983181fc19fee2f3d72173e676 66e28ec74/diff
lrwxrwxrwx 1 root root 77 Jul 26 14:30 UQF6DWQE64JXS3TEBUFOBSD3TY ->
../3652e67b65ebe7eaed7cc879f8470983181fc19fee2f3d72173e676 66e28ec74-init/diff
通过上面的测试总结:
用户看到的文件系统层为:
/var/lib/docker/overlay2/3652e67b65ebe7eaed7cc879f84709831 81fc19fee2f3d72173e67666e28ec74/merged
由两部分挂载而来
/var/lib/docker/overlay2/3652e67b65ebe7eaed7cc879f84709831 81fc19fee2f3d72173e67666e28ec74-init/diff/
和
/var/lib/docker/overlay2/23664d7a4167e74ee04838d87cd3568cc 82be49f781bba2212b9bff942bb8fa4/diff/
用于copy-on-write操作
/var/lib/docker/overlay2/3652e67b65ebe7eaed7cc879f84709831 81fc19fee2f3d72173e67666e28ec74/work
容器内创建文件的话,它会存放在
/var/lib/docker/overlay2/3652e67b65ebe7eaed7cc879f84709831 81fc19fee2f3d72173e67666e28ec74/diff
九、容器里启动应用
前提要打开路由转发
[root@daniel ~]# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
[root@daniel ~]# sysctl -p
net.ipv4.ip_forward = 1
[root@daniel ~]# sysctl -p
镜像分为
系统镜像
应用镜像
例子
系统镜像来跑httpd
案例1: 端口映射
利用官方centos镜像运行容器跑httpd服务,因为官方centos镜像里默认并没有安装httpd服务,所以需要我们自定义安装
将docker内部的httpd启动80端口与docker_host(宿主机)进行端口映射
1, 运行容器httpd1; -p 8000:80的意思是把容器里的80端口映射为docker_host(宿主机)的8000端口
docker run -p 8000:80指定端口映射
[root@daniel ~]# docker run -it -p 8000:80 --name=httpd1 centos:latest /bin/bash
在容器内部安装httpd服务
[root@b0a9623d3920 /]# yum install httpd httpd-devel -y Failed to get D-Bus connection: Operation not permitted
启动服务.这里用systemctl start httpd启动服务会报错,所以直接使用命令启动
启动服务.这里用systemctl start httpd启动服务会报错,所以直接使用命令启动
使用标准的方式启动httpd协议
[root@b0a9623d3920 /]# httpd -k start
[root@b0a9623d3920 /]# ss -an |grep :80
tcp LISTEN 0 0 :::80
:::*
[root@b0a9623d3920 /]# ss -an |grep :80
tcp LISTEN 0 0 :::80
:::*
2, 这里如果exit退出的话,启动的服务也会关闭。
同时按下ctrl+q+p三键,可以实现退出容器并保持容器后台运行
同时按下ctrl+q+p三键,可以实现退出容器并保持容器后台运行
可以查看到容器仍然是UP状态
[root@daniel ~]# docker ps -l
CONTAINER ID IMAGE COMMAND
CREATED STATUS PORTS
NAMES
b0a9623d3920 centos:latest "/bin/bash"
1 minutes ago Up 1 minutes 0.0.0.0:8000-
>80/tcp httpd1
[root@daniel ~]# docker ps -l
CONTAINER ID IMAGE COMMAND
CREATED STATUS PORTS
NAMES
b0a9623d3920 centos:latest "/bin/bash"
1 minutes ago Up 1 minutes 0.0.0.0:8000-
>80/tcp httpd1
3, 使用另一台机器浏览器访问 http://宿主机IP:8000测试
案例2: 自定义httpd并提交为镜像
将自定义的容器提交为新的镜像
1, 运行容器httpd2,安装httpd相关软件并自定义配置
[root@daniel ~]# docker run -it --name=httpd2
centos:latest /bin/bash
[root@82b985aea72c /]# yum install httpd httpd-devel -y
[root@82b985aea72c /]# mkdir /www
[root@82b985aea72c /]# echo "main page" > /www/index.html
修改119行和131行的家目录为/www
[root@82b985aea72c /]# vi /etc/httpd/conf/httpd.conf
[root@82b985aea72c /]# exit
exit
2, exit退出后此容器就变为了Exited状态
3, 将搭建好的环境commit成新的镜像(此镜像相当于是自定义的,生产环境中可以按需求push到镜像仓库)
[root@daniel ~]# docker commit httpd2 httpd_image
4, 将commit提交的镜像启动一个新的容器,并将端口80映射到宿主机的8001
启动一个守护持续性的服务
“-D FOREGROUND”apach的容器后台运行参数
“-D FOREGROUND”apach的容器后台运行参数
-d 是指后边命令的输出为后台,并不是容器后台运行
5, 使用另一台机器浏览器访问 http://宿主机IP:8001测试
问题: /usr/sbin/httpd -D FOREGROUND 能否做成自动传参?
答案: 可以,在dockerfile构建镜像章节会讨论。
案例3: docker数据卷挂载
挂载的产生需求?
数据的持久化
如果手动进入容器添加文件时,当容器删除时,里面的相关改变的数据也会删除,也就是说数据不能持久化保存。
将服务的配置文件,数据目录,日志目录等与宿主机的目录映射,把数据保持到宿主机上实现数据持久化.
文件更改
容器内配置文件需要修改?
容器内数据(如: 如httpd家目录内的数据)需要保存?
容器内数据(如: 如httpd家目录内的数据)需要保存?
数据共享
不同容器间数据需要共享(如: 两个httpd容器家目录数据共享)?
宿主机的目录也可以共享给多个容器使用。
将宿主机的目录(数据卷)挂载到容器中(配置文件也可以挂载)
docker数据卷挂载命令
docker -v 宿主机目录:容器目录
可以挂载多个 -v -v -v
容器共享卷(挂载点)
--volumes-from
docker run --name test1 -it myimage /bin/bash
上面命令中的 myimage是用前面的dockerfile文件构建的镜像。 这样容器test1就有了 /data1 和 /data2两个挂载点。
下面我们创建另一个容器可以和test1共享 /data1 和 /data2卷 ,这是在 docker run中使用 --volumes-from标记,如:
可以是来源不同镜像,如:
docker run --name test2 -it --volumes-from test1 ubuntu /bin/bash
也可以是同一镜像,如:
docker run --name test3 -it --volumes-from test1 myimage /bin/bash
上面的三个容器 test1 , test2 , test3 均有 /data1 和 /data2 两个目录,且目录中内容是共享的,任何一个容器修改了内容,别的容器都能获取到。
上面命令中的 myimage是用前面的dockerfile文件构建的镜像。 这样容器test1就有了 /data1 和 /data2两个挂载点。
下面我们创建另一个容器可以和test1共享 /data1 和 /data2卷 ,这是在 docker run中使用 --volumes-from标记,如:
可以是来源不同镜像,如:
docker run --name test2 -it --volumes-from test1 ubuntu /bin/bash
也可以是同一镜像,如:
docker run --name test3 -it --volumes-from test1 myimage /bin/bash
上面的三个容器 test1 , test2 , test3 均有 /data1 和 /data2 两个目录,且目录中内容是共享的,任何一个容器修改了内容,别的容器都能获取到。
最佳实践:数据容器
--volumes-from
如果多个容器需要共享数据(如持久化数据库、配置文件或者数据文件等),可以考虑创建一个特定的数据容器,该容器有1个或多个卷。
其它容器通过--volumes-from 来共享这个数据容器的卷。
因为容器的卷本质上对应主机上的目录,所以这个数据容器也不需要启动。
如: docker run --name dbdata myimage echo "data container"
其它容器通过--volumes-from 来共享这个数据容器的卷。
因为容器的卷本质上对应主机上的目录,所以这个数据容器也不需要启动。
如: docker run --name dbdata myimage echo "data container"
说明:有个卷,容器之间的数据共享比较方便,但也有很多问题需要解决,如权限控制、数据的备份、卷的删除等。这些内容后续文章介绍。
过程
1,先在宿主机创建一个目录,并建立一个内容不同的主页
[root@daniel ~]# mkdir /docker_www
[root@daniel ~]# echo daniel > /docker_www/index.html
[root@daniel ~]# echo daniel > /docker_www/index.html
2,运行容器httpd4, 将宿主机的/docker_www/目录挂载到容器中的/www/目录
[root@daniel ~]# docker run -d -p 8002:80 -v /docker_www/:/www --name=httpd4 httpd_image /usr/sbin/httpd -D FOREGROUND
[root@daniel ~]# docker ps -l
CONTAINER ID IMAGE COMMAND
CREATED STATUS PORTS
NAMES
484d7432d7ef httpd_image "/usr/sbin/httpd
-..." 21 seconds ago Up 20 seconds
0.0.0.0:8002->80/tcp httpd4
3, 使用另一台机器浏览器访问 http://宿主机IP:8002测试
(注意: 如果访问不到主页,请检查是否关闭了selinux)
4, 尝试修改宿主机/docker_www/index.html的内容, 访问的结果也会随着修改而改变
拓展:
解决镜像和宿主机中的时差问题,可以使用docker挂载配置文件
# docker run -it -v /etc/localtime:/etc/localtime --name c2 centos /bin/bash
说明:
因为我们是从docker官方pull下来的centos:latest镜像,它默认为UTC时区
我们需要改成自己的时区,可以在启动容器时用-v
/etc/localtime:/etc/localtime挂载映射
如果你觉得每次都要挂载时区文件很麻烦,可以自定义把时区文件改好,保持为新的镜像再使用
-v的标记只设置了容器的挂载点,并没有指定关联的主机目录。这时docker会自动绑定主机上的一个目录。通过docker inspect 命令可以查看到。
# docker run -d --name httpd1 -p 8000:80 \
> -v /httpd_www:/www -v
/test/httpd.conf:/etc/httpd/conf/httpd.conf \
> httpd_image /usr/sbin/httpd -DFOREGROUND
> -v /httpd_www:/www -v
/test/httpd.conf:/etc/httpd/conf/httpd.conf \
> httpd_image /usr/sbin/httpd -DFOREGROUND
说明:
/httpd_www/目录可以不用提前创建,它会自动帮我们创建
/test/httpd.conf此文件需要提前准备(配置文件里的家目录要改
为/www)
挂载后,通过修改宿主机的数据来达到修改容器内部数据的目地
/test/httpd.conf此文件需要提前准备(配置文件里的家目录要改
为/www)
挂载后,通过修改宿主机的数据来达到修改容器内部数据的目地
案例4: 官方httpd镜像运行容器
参考: https://hub.docker.com/_/httpd
1, pull官方httpd镜像
[root@daniel ~]# docker search httpd
[root@daniel ~]# docker pull httpd
2, 运行容器
/data/www目录可以提前创建,也可以不用创建(它会帮我们自动创建)
[root@daniel ~]# docker run -d -p 8003:80 --name=httpd4 -v
/data/www/:/usr/local/apache2/htdocs/ httpd:latest
[root@daniel ~]# echo "new page" > /data/www/index.html
3, 使用另一台机器浏览器访问 http://宿主机IP:8003测试
容器中运行mysql或mariadb应用
案例1:官方mysql镜像运行容器
1, 先拉取mysql镜像
[root@daniel ~]# docker pull mysql:5.6
2, 运行容器
更多参数和详细说明请参考: https://hub.docker.com/_/mysql
--restart=always表示重启docker服务后会自动重启
-e MYSQL_ROOT_PASSWORD=123 指定mysql的root用户密码
-e MYSQL_ROOT_PASSWORD=123 指定mysql的root用户密码
[root@daniel ~]# docker run -d -p 3306:3306 --name=mysql1
-v /data/mysql:/var/lib/mysql --restart=always -e
MYSQL_ROOT_PASSWORD=123 mysql:5.6
启动后查看宿主机的/data/mysql/目录,发现已经初始化数据了
[root@daniel ~]# ls /data/mysql/
auto.cnf ibdata1 ib_logfile0 ib_logfile1 mysql
performance_schema
3, 连接上去,按需求自由使用
[root@daniel ~]# mysql -h 127.0.0.1 -u root -p123
案例2:centos镜像自定义mariadb环境
1,安装mariadb
[root@daniel ~]# docker run -it -d -p 3307:3306 -v
/data/mysql2:/var/lib/mysql --restart=always --
name=mariadb2 centos:latest /bin/bash
[root@daniel ~]# docker attach mariadb2
[root@7dccf1c72315 /]# yum install mariadb-server -y
[root@7dccf1c72315 /]# mysql_install_db --
datadir=/var/lib/mysql/ --user=mysql
[root@7dccf1c72315 /]# mysqld_safe --defaultsfile=/
etc/my.cnf &
[root@7dccf1c72315 /]# mysql
MariaDB [(none)]> grant all on *.* to 'abc'@'%' identified
by '123';
MariaDB [(none)]> flush privileges;
MariaDB [(none)]> quit
[root@7dccf1c72315 /]#
最后按ctrl+p+q退出并保持容器后台运行
/data/mysql2:/var/lib/mysql --restart=always --
name=mariadb2 centos:latest /bin/bash
[root@daniel ~]# docker attach mariadb2
[root@7dccf1c72315 /]# yum install mariadb-server -y
[root@7dccf1c72315 /]# mysql_install_db --
datadir=/var/lib/mysql/ --user=mysql
[root@7dccf1c72315 /]# mysqld_safe --defaultsfile=/
etc/my.cnf &
[root@7dccf1c72315 /]# mysql
MariaDB [(none)]> grant all on *.* to 'abc'@'%' identified
by '123';
MariaDB [(none)]> flush privileges;
MariaDB [(none)]> quit
[root@7dccf1c72315 /]#
最后按ctrl+p+q退出并保持容器后台运行
2, 找另一台远程连接测试OK
# mysql -h docker宿主机IP -u abc -p123 -P 3307
容器中运行nginx应用
参考: https://hub.docker.com/_/nginx
案例1: 官方nginx镜像运行容器
1, pull拉取镜像
[root@daniel ~]# docker pull nginx
2, 准备一个nginx.conf配置文件
[root@daniel ~]# mkdir /data/nginx/etc -p
准备下面的配置文件(自己写一个,或者拷贝一个都可以)
[root@daniel ~]# ls /data/nginx/etc/nginx.conf
3, 运行容器,并准备一个主页文件
[root@daniel ~]# docker run -d -p 8004:80 --restart=always
--name=nginx1 -v /data/nginx/html:/usr/share/nginx/html -v
/data/nginx/etc/nginx.conf:/etc/nginx/nginx.conf -v
/data/nginx/log:/var/log/nginx nginx:latest
[root@daniel ~]# echo "nginx main page" >
/data/nginx/html/index.html
4, 使用另一台机器浏览器访问 http://宿主机IP:8003测试
按需求先修改配置文件
[root@daniel ~]# vim /data/nginx/etc/nginx.conf
再重启容器
[root@daniel ~]# docker stop nginx1
[root@daniel ~]# docker start nginx1
5,如果想要修改nginx配置文件,可以按下面步骤来实现
容器中运行tomcat应用
参考: https://hub.docker.com/_/tomcat
十、Dockerfile(docker build)构建镜像
通过man dockerfile 可以查看到详细的说明
什么是Dockerfile?
Dockerfile把构建镜像的步骤都写出来,然后按顺序执行实现自动构建镜像。就类似于脚本文件,ansible的playbook,saltstack的sls文件等。
常用指令
1, FROM
FROM指令用于指定其后构建新镜像所使用的基础镜像。
FROM指令必是Dockerfile文件中的首条命令。
FROM指令指定的基础image可以是官方远程仓库中的,也可以位于本地仓库,优先本地仓库。
格式:FROM <image>:<tag>
例:FROM centos:latest
例:FROM centos:latest
2, RUN
RUN指令用于在构建镜像中执行命令,有以下两种格式:
shell格式
格式:RUN 指令1 [&& 指令2]
例:RUN echo daniel > /var/www/html/index.html
RUN mkdir -p /usr/lsy && echo 'this is lsy file' > /usr/lsy/lsy.html
例:RUN echo daniel > /var/www/html/index.html
RUN mkdir -p /usr/lsy && echo 'this is lsy file' > /usr/lsy/lsy.html
exec格式
格式:RUN ["可执行文件", "参数1", "参数2"]
例:RUN ["/bin/bash", "-c", "echo daniel > /var/www/html/index.html"]
例:RUN ["/bin/bash", "-c", "echo daniel > /var/www/html/index.html"]
注意:
按优化的角度来讲:当有多条要执行的命令,不要使用多条RUN,尽量使用&&符号与\符号连接成一行。因为多条RUN命令会让镜像建立多层(总之就是会变得臃肿了😃)。
这个建议是针对AUFS 的联合文件系统
对于overlay并无特别要求
RUN yum install httpd httpd-devel -y
RUN echo daniel > /var/www/html/index.html
可以改成
RUN yum install httpd httpd-devel -y && echo daniel >
/var/www/html/index.html
或者改成
RUN yum install httpd httpd-devel -y \
&& echo daniel > /var/www/html/index.html
3, CMD
CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
格式有三种:
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2
CMD ["param1","param2"]
CMD command param1 param2
每个Dockerfile只能有一条CMD命令。如果指定了多条命令,只有最后一条会被执行。
如果用户启动容器时候指定了运行的命令,则会覆盖掉CMD指定的命令。
什么是启动容器时指定运行的命令?
# docker run -d -p 80:80 镜像名 运行的命令
# docker run -d -p 80:80 镜像名 运行的命令
4, EXPOSE
EXPOSE指令用于指定容器在运行时监听暴露的端口
格式:EXPOSE <port> [<port>...]
例:EXPOSE 80 3306 8080
例:EXPOSE 80 3306 8080
上述运行的端口还需要使用docker run运行容器时通过-p参数映射到宿主机的端口.
5, ENV
ENV指令用于指定一个环境变量.
格式:ENV <key> <value> 或者 ENV <key>=<value>
例:ENV JAVA_HOME /usr/local/jdkxxxx/
例:ENV JAVA_HOME /usr/local/jdkxxxx/
6, ADD
ADD指令用于把宿主机上的文件拷贝到镜像中
格式:ADD <src> <dest>
<src>可以是一个本地文件或本地压缩文件,还可以是一个url,
如果把<src>写成一个url,那么ADD就类似于wget命令
<dest>路径的填写可以是容器内的绝对路径,也可以是相对于工作目录的相对路径
当源文件是.tar.gz等压缩文件,会自动解压到目标目录
<src>可以是一个本地文件或本地压缩文件,还可以是一个url,
如果把<src>写成一个url,那么ADD就类似于wget命令
<dest>路径的填写可以是容器内的绝对路径,也可以是相对于工作目录的相对路径
当源文件是.tar.gz等压缩文件,会自动解压到目标目录
例如:ADD ./test.html /usr/lsy
ADD https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe /temp/python-3.5.1.exe
ADD https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe /temp/python-3.5.1.exe
7, COPY
COPY指令与ADD指令类似,但COPY的源文件只能是本地文件
格式:COPY <src> <dest>
8, ENTRYPOINT
ENTRYPOINT与CMD非常类似
相同点:
一个Dockerfile只写一条,如果写了多条,那么只有最后一条生效都是容器启动时才运行
不同点:
如果用户启动容器时候指定了运行的命令,ENTRYPOINT不会被运行的命令覆盖,而CMD则会被覆盖
格式有两种:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
ENTRYPOINT command param1 param2
9, VOLUME
VOLUME指令用于把宿主机里的目录与容器里的目录映射. 只指定挂载点,docker宿主机映射的目录为自动生成的。
通过docker inspect 查看通过该dockerfile创建的镜像生成的容器
"Mounts": [
{
"Name": "d411f6b8f17f4418629d4e5a1ab69679dee369b39e13bb68bed77aa4a0d12d21",
"Source": "/var/lib/docker/volumes/d411f6b8f17f4418629d4e5a1ab69679dee369b39e13bb68bed77aa4a0d12d21/_data",
"Destination": "/data1",
"Driver": "local",
"Mode": "",
"RW": true
},
{
"Name": "6d3badcf47c4ac5955deda6f6ae56f4aaf1037a871275f46220c14ebd762fc36",
"Source": "/var/lib/docker/volumes/6d3badcf47c4ac5955deda6f6ae56f4aaf1037a871275f46220c14ebd762fc36/_data",
"Destination": "/data2",
"Driver": "local",
"Mode": "",
"RW": true
}
],
{
"Name": "d411f6b8f17f4418629d4e5a1ab69679dee369b39e13bb68bed77aa4a0d12d21",
"Source": "/var/lib/docker/volumes/d411f6b8f17f4418629d4e5a1ab69679dee369b39e13bb68bed77aa4a0d12d21/_data",
"Destination": "/data1",
"Driver": "local",
"Mode": "",
"RW": true
},
{
"Name": "6d3badcf47c4ac5955deda6f6ae56f4aaf1037a871275f46220c14ebd762fc36",
"Source": "/var/lib/docker/volumes/6d3badcf47c4ac5955deda6f6ae56f4aaf1037a871275f46220c14ebd762fc36/_data",
"Destination": "/data2",
"Driver": "local",
"Mode": "",
"RW": true
}
],
格式:VOLUME ["<mountpoint>"]
10, USER
USER指令设置启动容器的用户(像hadoop需要hadoop用户操作,oracle需要oracle用户操作),可以是用户名或UID
USER daemon
USER 1001
USER 1001
注意:如果设置了容器以daemon用户去运行,那么RUN,CMD和ENTRYPOINT都会以这个用户去运行
镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户
镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户
指定用户
11, WORKDIR
WORKDIR指令设置工作目录,类似于cd命令。不建议使用RUN cd /root ,建议使用WORKDIR
WORKDIR /root
12. LABEL
为镜像指定标签,会继承基础镜像的LABLE,如果key相同,则覆盖。可替代MAINTANIER使用。
格式:LABLE key1=value1 key2=value2
例如:LABLE author=lsy
格式:LABLE key1=value1 key2=value2
例如:LABLE author=lsy
LABEL 指令会添加元数据到镜像。LABEL是以键值对形式出现的。
为了在LABEL的值里面可以包含空格,你可以在命令行解析中使用引号和反斜杠。一些使用方法如下:
为了在LABEL的值里面可以包含空格,你可以在命令行解析中使用引号和反斜杠。一些使用方法如下:
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
组合多个labels在一个LABEL里来指定多重labels。
LABEL multi.label1="value1" multi.label2="value2" other="value3"
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
Labels 包含在基镜像或者父母镜像(在FROM行的镜像)继承到你的镜像。如果label本身已经存在但是值不一样,最后的赋值将会覆盖前面的复制。
13. ONBUILD
ONBUILD:当构建一个被继承Dockerfile时运行的命令,父镜像在被子镜像继承后,父镜像的ONBUILD会被触发调用。其实有点像Java的里父类super方法。
ONBUILD定义的指令,只在子镜像构建的时候,进行运行。
例子
定义父类Dockerfile,内容如下
FROM docker.io/centos
MAINTAINER michard michar@qq.com
CMD echo "this is cmd instrunction"
ONBUILD RUN echo "father onbuild instruction"
FROM docker.io/centos
MAINTAINER michard michar@qq.com
CMD echo "this is cmd instrunction"
ONBUILD RUN echo "father onbuild instruction"
构建Dockerfile,docker build -f df7 -t centos_onbuild:1.9 .
定义子镜像Dockerfile文件
FROM centos_onbuild:1.9
MAINTAINER michard michar@qq.com
CMD ["echo","echo 99"]
构建子镜像Dockerfile,docker build -f df8 -t child_centos:2.0 .
14. ARG
构建参数,作用于ENV相同,不同的是ARG的参数只在构建镜像的时候起作用,也就是docker build的时候。
格式:ARG k=v
格式:ARG k=v
15. MAINTAINER
用于让Dockerfile制作者提供本人的详细信息,此指令位置不限,但推荐放置FROM之后。
格式:MAINTAINER 作者信息
例如:MAINTAINER "lsy"
格式:MAINTAINER 作者信息
例如:MAINTAINER "lsy"
docker build
镜像构建上下文(Context)
镜像构建上下文(Context)
docker build 命令最后有一个 “.”。
. 表示当前目录
引入了上下文的概念。当构建的时候,用户会指定构建镜像上下文的路径,docker build 命令得知这个路径后,会将路径下的所有内容打包,然后上传给 Docker 引擎。这样 Docker 引擎收到这个上下文包后,展开就会获得构建镜像所需的一切文件。
例如
COPY ./package.json /app/
这并不是要复制执行 docker build 命令所在的目录下的 package.json,也不是复制 Dockerfile所在目录下的 package.json,而是复制 上下文(context) 目录下的 package.json。
因此,COPY 这类指令中的源文件的路径都是相对路径。这也是初学者经常会问的为什么 COPY ../package.json /app 或者 COPY /opt/xxxx /app 无法工作的原因,因为这些路径已经超出了上下文的范围,Docker 引擎无法获得这些位置的文件。如果真的需要那些文件,应该将它们复制到上下文目录中去。
观察 docker build 输出,我们其实已经看到了这个发送上下文的过程:
$ docker build -t nginx:v3 .
Sending build context to Docker daemon 2.048 kB
...
为什么会有人误以为 . 是指定 Dockerfile 所在目录呢?这是因为在默认情况下,
如果不额外指定 Dockerfile 的话,会将上下文目录下的名为 Dockerfile 的文件作为 Dockerfile。
如果不额外指定 Dockerfile 的话,会将上下文目录下的名为 Dockerfile 的文件作为 Dockerfile。
Dockerfile 的文件名并不要求必须为 Dockerfile,而且并不要求必须位于上下文目录中,
比如可以用 -f ../Dockerfile.php 参数指定某个文件作为 Dockerfile。
比如可以用 -f ../Dockerfile.php 参数指定某个文件作为 Dockerfile。
其它 docker build 的用法
直接用 Git repo 进行构建
docker build 还支持从 URL 构建,比如可以直接从 Git repo 中构建:
$ docker build https://github.com/twang2218/gitlab-ce-zh.git#:8.14
docker build https://github.com/twang2218/gitlab-ce-zh.git\#:8.14
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM gitlab/gitlab-ce:8.14.0-ce.0
8.14.0-ce.0: Pulling from gitlab/gitlab-ce
aed15891ba52: Already exists
773ae8583d14: Already exists
...
docker build https://github.com/twang2218/gitlab-ce-zh.git\#:8.14
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM gitlab/gitlab-ce:8.14.0-ce.0
8.14.0-ce.0: Pulling from gitlab/gitlab-ce
aed15891ba52: Already exists
773ae8583d14: Already exists
...
这行命令指定了构建所需的 Git repo,并且指定默认的 master 分支,构建目录为 /8.14/,然后 Docker 就会自己去 git clone 这个项目、切换到指定分支、并进入到指定目录后开始构建。
用给定的 tar 压缩包构建
$ docker build http://server/context.tar.gz
如果所给出的 URL 不是个 Git repo,而是个 tar 压缩包,那么 Docker 引擎会下载这个包,
并自动解压缩,以其作为上下文,开始构建。从标准输入中读取 Dockerfile 进行构建
并自动解压缩,以其作为上下文,开始构建。从标准输入中读取 Dockerfile 进行构建
docker build - < Dockerfile
cat Dockerfile | docker build -
从标准输入中读取上下文压缩包进行构建
$ docker build - < context.tar.gz
如果发现标准输入的文件格式是 gzip、bzip2 以及 xz 的话,将会使其为上下文压缩包,直接将其展开,将里面视为上下文,并开始构建。
案例
案例1:Dockerfile构建httpd镜像v1
案例2:Dockerfile构建httpd镜像v2
案例3: Dockerfile构建tomcat镜像v1
案例4: Dockerfile构建tomcat镜像v2
十一、单宿主机容器互联方式
需求
有些时候我们希望容器与容器之间也要能通迅,而实现服务的连接(如nginx连远程mysql等)。
互联方法
同一台宿主机,相同网段
同一宿主机的相同网段,容器默认使用docker0网络,互联
通过link连接
使用link方式可以实现两个容器的连接,但是方向是单向的。
实验
在相同的docker——host主机上准备两台终端,其中一台link另外一台
终端一
[root@daniel ~]# docker run -it --name c1 centos /bin/bash [root@551b2985d420 /]# ip a |grep inet
inet 127.0.0.1/8 scope host lo
inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0
可以看到c1容器的IP为172.17.0.4/16
终端二
使用--link c1:alias1来连接c1容器;haha为c1容器的别名
[root@daniel ~]# docker run -it --link c1:haha --name c2 centos /bin/bash
[root@1e8cd36da3af /]# tail -1 /etc/hosts
172.17.0.4 haha d64d657b4e1f c1
可以看到c2容器把c1容器的IP与别名haha进行了绑定
[root@1e8cd36da3af /]# ping haha
PING haha (172.17.0.4) 56(84) bytes of data.
64 bytes from haha (172.17.0.4): icmp_seq=1 ttl=64 time=0.280 ms
64 bytes from haha (172.17.0.4): icmp_seq=2 ttl=64 time=0.137 ms
64 bytes from haha (172.17.0.4): icmp_seq=3 ttl=64 time=0.130 ms
通过网络连接
默认创建的容器都在同一个网络上,宿主机的docker0网卡也连接在此网络。
终端三
查看容器c1和c2的IP地址,发现这两个容器默认就在一个网络,所以直接用这两
个IP就可以直接互相通迅了
[root@daniel ~]# docker inspect c1 |grep IPAddress |tail
-1
"IPAddress": "172.17.0.4",
[root@daniel ~]# docker inspect c2 |grep IPAddress |tail
-1
"IPAddress": "172.17.0.5",
[root@daniel ~]# ifconfig docker0 |head -2
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu
1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast
0.0.0.0
十二、docker网络
本地网络
docker本地有4种类型的网络:
1. bridge
此为默认网络类型,运行容器时不指定网络时,就使用bridge
与虚拟机上的NAT网络相似
2. host 和宿主机共享网络。
和宿主机共享网络。
类似于虚拟机的仅主机模式
使用宿主机的物理网卡
3. none
连接此网络的容器没有IP地址等信息,只有lo本地回环网卡。无法连接公网网络。
4. container
container 多个容器连接到此网络,那么容器间可以互相通讯,不和宿主机共享。
查看docker网络以及网络信息
docker network ls
docker network ls
[root@daniel ~]# docker network ls
NETWORK ID NAME DRIVER
SCOPE
6f92ca98b6e7 bridge bridge
local
658477d11b2c host host
local
411dc19aef37 none null
local
NETWORK ID NAME DRIVER
SCOPE
6f92ca98b6e7 bridge bridge
local
658477d11b2c host host
local
411dc19aef37 none null
local
[root@daniel ~]# docker inspect bridge
查看bridge网络相关的信息
man docker-network
docker network --help
docker network create
bridge模式
案例
1, 创建一个名为bridge0的bridge类型的网络,指定网段为10.3.3.0/24(此网段不能和宿主机已有的网段冲突),网关为10.3.3.1
[root@daniel ~]# docker network create -d bridge --subnet "10.3.3.0/24" --gateway "10.3.3.1" bridge0
查看网络
[root@daniel ~]# docker network ls
NETWORK ID NAME DRIVER
SCOPE
6f92ca98b6e7 bridge bridge
local
39fe88f034d6 bridge0 bridge
local
658477d11b2c host host
local
411dc19aef37 none null
local
删除网络
docker network rm bridge0
2, 运行容器,指定使用刚创建的网络
[root@daniel ~]# docker run -it -d --name c4 --network bridge0 centos:latest
--network {网络名称} 可以指定网络
3, 验证并测试此容器的网络
[root@daniel ~]# docker inspect c4 |grep IPAddress |tail
-1
"IPAddress": "10.3.3.2",
-1
"IPAddress": "10.3.3.2",
可以ping通网关
[root@daniel ~]# docker exec c4 ping -c1 10.3.3.1
PING 10.3.3.1 (10.3.3.1) 56(84) bytes of data.
64 bytes from 10.3.3.1: icmp_seq=1 ttl=64 time=0.319 ms
可以上网
[root@daniel ~]# docker exec c4 ping -c1 www.baidu.cn
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=55 time=7.51 ms
[root@daniel ~]# docker exec c4 ping -c1 10.3.3.1
PING 10.3.3.1 (10.3.3.1) 56(84) bytes of data.
64 bytes from 10.3.3.1: icmp_seq=1 ttl=64 time=0.319 ms
可以上网
[root@daniel ~]# docker exec c4 ping -c1 www.baidu.cn
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=55 time=7.51 ms
4, 宿主机上会产生一个网卡名为br-xxxxx, IP地址为设置的网关10.3.3.1
[root@daniel ~]# ifconfig |head -2
br-39fe88f034d6:
flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.3.3.1 netmask 255.255.255.0 broadcast
0.0.0.0
br-39fe88f034d6:
flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.3.3.1 netmask 255.255.255.0 broadcast
0.0.0.0
如果想改名的话,可按下面步骤来做
[root@daniel ~]# ifconfig br-39fe88f034d6 down
[root@daniel ~]# ip link set dev br-39fe88f034d6 name
docker1
[root@daniel ~]# ifconfig docker1 up
[root@daniel ~]# ifconfig docker1 |head -2
docker1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu
1500
inet 10.3.3.1 netmask 255.255.255.0 broadcast
0.0.0.0
[root@daniel ~]# systemctl restart docker
[root@daniel ~]# ip link set dev br-39fe88f034d6 name
docker1
[root@daniel ~]# ifconfig docker1 up
[root@daniel ~]# ifconfig docker1 |head -2
docker1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu
1500
inet 10.3.3.1 netmask 255.255.255.0 broadcast
0.0.0.0
[root@daniel ~]# systemctl restart docker
host模式
1, 宿主机只能拥有一个host模式网络(和docker-host共享网络类似于VM仅主机模式),再创建会报错
2,运行容器, 指定使用host网络
[root@daniel ~]# docker run -it -d --name c5 --network host centos:latest
3, 验证并测试此容器的网络
可以上公网
[root@daniel ~]# docker exec c5 ping -c1 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=55 time=7.51 ms
[root@daniel ~]# docker exec c5 yum install net-tools -y
容器里ifconfig得到的信息和宿主机上ifconfig得到的信息一致
[root@daniel ~]# docker exec c5 ifconfig
none模式
不能与外网通讯,只有lo本地通迅
[root@daniel ~]# docker run -itd --name c7 --network=none centos:latest /bin/bash
container模式
container 多个容器连接到此网络,那么容器间可以互相通讯,不和宿主机共享。
[root@daniel ~]# docker run -itd --name c8 --network=container:c1 centos:latest /bin/bash
说明:
c8容器与c1容器的网络一致(包括IP)
跨docker_host(主机)网络
不同的宿主机上的容器通过映射端口,然后通过两台宿主机的IP和映射的端口来通迅。但这样做是利用了宿主机的网络,在某些场景并不方便。
能不能建立跨宿主机之间的网络,让容器使用自己的IP就可以通迅呢? 答案
是肯定的,而且方案也有很多种: 有docker原生的overlay、macvlan和第
三方方案flannel、weave、calico 等.
这里我们重点介绍flannel[ˈflænəl],参考:https://coreos.com/blog/introdu
cing-rudder.html
cing-rudder.html
flannel介绍
flannel是kubernetes[kubə’netis]默认提供网络插件,由CoreOS团队设计
flannel实质上是一种“覆盖网络(overlay network)”, 也就是将TCP数据包装
在另一种网络包里面进行路由转发和通信,目前已经支持UDP、VxLAN、
AWS VPC和GCE路由等数据转发方式。
默认的节点间数据通信方式是UDP转发,在Flannel的GitHub页面有如下
的一张原理图:
fannel可使用etcd存储,分配,维护子网信息,最终实现一个大网络内的不同子网可以互通
flannel实验测试
实验准备
准备两台新虚拟机来做实验
安装docker etcd flannel
1, IP静态
2, 主机名绑定
10.1.1.13 vm3.cluster.com
10.1.1.14 vm4.cluster.com
3, 时间同步
4, 关闭防火墙和selinux
5, yum源(使用centos安装完系统后的默认yum源再加上下面的docker-ce源)
# wget https://mirrors.aliyun.com/dockerce/
linux/centos/docker-ce.repo -O /etc/yum.repos.d/dockerce.repo
linux/centos/docker-ce.repo -O /etc/yum.repos.d/dockerce.repo
实验过程:
第1步: 在docker宿主机1上(主机名vm3)安装etcd,flannel,docker
[root@vm3 ~]# yum install etcd flannel docker-ce -y
第2步: 在docker宿主机1上配置etcd服务并启动
[root@vm3 ~]# vim /etc/etcd/etcd.conf
6 ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" 这里要监听
0.0.0.0,这样flanneld服务才能连接
[root@vm3 ~]# systemctl start etcd
[root@vm3 ~]# systemctl enable etcd
6 ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" 这里要监听
0.0.0.0,这样flanneld服务才能连接
[root@vm3 ~]# systemctl start etcd
[root@vm3 ~]# systemctl enable etcd
第3步: 在docker宿主机1上配置flanneld服务,创建网络,并启动服务
[root@vm3 ~]# vim /etc/sysconfig/flanneld
4 FLANNEL_ETCD_ENDPOINTS="http://10.1.1.13:2379" 注
意:这里IP改为etcd服务IP
4 FLANNEL_ETCD_ENDPOINTS="http://10.1.1.13:2379" 注
意:这里IP改为etcd服务IP
创建一个虚拟网络(我这里创建172.18.0.0/16)
[root@vm3 ~]# etcdctl mk //atomic.io/network/config
'{"Network":"172.18.0.0/16"}'
{"Network":"172.18.0.0/16"}
[root@vm3 ~]# etcdctl mk //atomic.io/network/config
'{"Network":"172.18.0.0/16"}'
{"Network":"172.18.0.0/16"}
[root@vm3 ~]# systemctl start flanneld
[root@vm3 ~]# systemctl enable flanneld
[root@vm3 ~]# systemctl enable flanneld
验证分配的网络(在172.18.0.0/16里随机的)
[root@vm3 ~]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=172.18.0.0/16
FLANNEL_SUBNET=172.18.86.1/24
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false
[root@vm3 ~]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=172.18.0.0/16
FLANNEL_SUBNET=172.18.86.1/24
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false
第4步: 在docker宿主机1上关联docker0网络与flannel0网络,启动docker服务,并验证网络
[root@vm3 ~]# systemctl start docker # 先启动
docker才会产生/etc/docker/目录
[root@vm3 ~]# vim /etc/docker/daemon.json
{
"bip": "172.18.86.1/24",
"mtu": 1472
}
docker才会产生/etc/docker/目录
[root@vm3 ~]# vim /etc/docker/daemon.json
{
"bip": "172.18.86.1/24",
"mtu": 1472
}
说明
bip 边界IP,和/run/flannel/subnet.env 配置文件里的对应
mtu 网络最大传输单元,也和/run/flannel/subnet.env 配置文件里的对应
第5步: 在docker宿主机2上(主机名vm4)安装flannel,docker
[root@vm4 ~]# yum install flannel docker-ce -y
第6步: 在docker宿主机2上配置flanneld服务,并启动服务
[root@vm4 ~]# vim /etc/sysconfig/flanneld
4 FLANNEL_ETCD_ENDPOINTS="http://10.1.1.13:2379" 注
意:这里IP改为etcd服务IP
4 FLANNEL_ETCD_ENDPOINTS="http://10.1.1.13:2379" 注
意:这里IP改为etcd服务IP
[root@vm4 ~]# systemctl start flanneld
[root@vm4 ~]# systemctl enable flanneld
[root@vm4 ~]# systemctl enable flanneld
验证分配的网络
[root@vm4 ~]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=172.18.0.0/16
FLANNEL_SUBNET=172.18.42.1/24
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false
[root@vm4 ~]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=172.18.0.0/16
FLANNEL_SUBNET=172.18.42.1/24
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false
第7步: 在docker宿主机2上启动docker服务,并验证网络
[root@vm4 ~]# systemctl start docker # 先启动
docker才会产生/etc/docker/目录
[root@vm4 ~]# vim /etc/docker/daemon.json
{
"bip": "172.18.42.1/24",
"mtu": 1472
}
docker才会产生/etc/docker/目录
[root@vm4 ~]# vim /etc/docker/daemon.json
{
"bip": "172.18.42.1/24",
"mtu": 1472
}
第8步: 在两台docker宿主机上分别运行容器
两台都下载busybox镜像(此镜像包含了ifconfig命令,镜像也小,下载快)
[root@vm3 ~]# docker pull busybox
[root@vm4 ~]# docker pull busybox
[root@vm3 ~]# docker pull busybox
[root@vm4 ~]# docker pull busybox
[root@vm3 ~]# docker run -itd --name=c1 busybox /bin/sh
5b4fa3e8e71e53229f75a94ea993f4486f80ac0706678d1f1a214dea44
d69b7f
[root@vm3 ~]# docker exec c1 ifconfig |head -2
eth0 Link encap:Ethernet HWaddr 02:42:AC:12:56:02
inet addr:172.18.86.2 Bcast:0.0.0.0
Mask:255.255.255.0
5b4fa3e8e71e53229f75a94ea993f4486f80ac0706678d1f1a214dea44
d69b7f
[root@vm3 ~]# docker exec c1 ifconfig |head -2
eth0 Link encap:Ethernet HWaddr 02:42:AC:12:56:02
inet addr:172.18.86.2 Bcast:0.0.0.0
Mask:255.255.255.0
[root@vm4 ~]# docker run -itd --name=c1 busybox /bin/sh
79e5f60ef310721901ac870f88a1475aaef7a8ab45575c02e947dcbee3
2b4d5a
[root@vm4 ~]# docker exec c1 ifconfig |head -2
eth0 Link encap:Ethernet HWaddr 02:42:AC:12:2A:02
inet addr:172.18.42.2 Bcast:0.0.0.0
Mask:255.255.255.0
79e5f60ef310721901ac870f88a1475aaef7a8ab45575c02e947dcbee3
2b4d5a
[root@vm4 ~]# docker exec c1 ifconfig |head -2
eth0 Link encap:Ethernet HWaddr 02:42:AC:12:2A:02
inet addr:172.18.42.2 Bcast:0.0.0.0
Mask:255.255.255.0
第9步: 在两台docker宿主机上进行容器连通测试
vm3上的c1容器ping测试vm4上的c1容器,不通
[root@vm3 ~]# docker exec c1 ping -c 2 172.18.42.2
[root@vm3 ~]# docker exec c1 ping -c 2 172.18.42.2
这里是被防火墙给限制了(启动docker服务,会产生iptables的规则),清除规
则(注意FORWARD链默认规则要改)
[root@vm3 ~]# iptables -F
[root@vm3 ~]# iptables -P FORWARD ACCEPT
[root@vm4 ~]# iptables -F
[root@vm4 ~]# iptables -P FORWARD ACCEPT
则(注意FORWARD链默认规则要改)
[root@vm3 ~]# iptables -F
[root@vm3 ~]# iptables -P FORWARD ACCEPT
[root@vm4 ~]# iptables -F
[root@vm4 ~]# iptables -P FORWARD ACCEPT
[root@vm3 ~]# docker exec c1 ping -c 2 172.18.42.2
PING 172.18.42.2 (172.18.42.2): 56 data bytes
64 bytes from 172.18.42.2: seq=0 ttl=60 time=1.652 ms
64 bytes from 172.18.42.2: seq=1 ttl=60 time=2.491 ms
[root@vm4 ~]# docker exec c1 ping -c2 172.18.86.2
PING 172.18.86.2 (172.18.86.2): 56 data bytes
64 bytes from 172.18.86.2: seq=0 ttl=60 time=1.804 ms
64 bytes from 172.18.86.2: seq=1 ttl=60 time=1.981 ms
PING 172.18.42.2 (172.18.42.2): 56 data bytes
64 bytes from 172.18.42.2: seq=0 ttl=60 time=1.652 ms
64 bytes from 172.18.42.2: seq=1 ttl=60 time=2.491 ms
[root@vm4 ~]# docker exec c1 ping -c2 172.18.86.2
PING 172.18.86.2 (172.18.86.2): 56 data bytes
64 bytes from 172.18.86.2: seq=0 ttl=60 time=1.804 ms
64 bytes from 172.18.86.2: seq=1 ttl=60 time=1.981 ms
总结
小结1
容器属于typeIII虚拟化,属于Paas
容器是一种轻量级,进程级的虚拟机
相比于虚拟机的优势
不需要安装OS,和宿主机共享
镜像存储空间小
启动速度快(容器为秒级,虚拟机一般需要10秒左右)移植性更好,更轻便
性能更好
docker是一个实现容器的软件,底层使用LXC
docker主要使用namespace命名空间技术实现资源隔离,使用cgroup实现资源限制
小结: 远程仓库
官方仓库 缺点:网络问题
国内云运营商提供的镜像仓库 优点:网速较好 缺点: 安全性考虑
自建仓库 优点: 网速好,安全性也好 缺点: 自己维护,需要服务器和存储成本
小结:
docker ps -a : 列出本地的所有容器信息
docker run 参数选项 --name 容器名 镜像名:TAG 传给容器内部执行的
命令
docker logs 容器名或容器ID: 输出容器内执行命令的结果
docker stop 容器名或容器ID: 停止容器
docker start 容器名或容器ID: 启动容器
docker attach 容器名或容器ID: 连接一个UP状态的容器,可以进去交互
(有bash环境的才可以)
docker exec 容器名或容器ID 命令: 不用连接容器,可以外部传命令给
容器内部操作
docker exec -it 容器名或容器ID /bin/bash 连接容器交互
docker inspect 容器名或容器ID: 查看容器的属性
docker rm 容器名或容器ID: 删除容器
docker commit 容器名或容器ID 新的镜像名:TAG 将容器提交为
一个镜像
docker run 参数选项 --name 容器名 镜像名:TAG 传给容器内部执行的
命令
docker logs 容器名或容器ID: 输出容器内执行命令的结果
docker stop 容器名或容器ID: 停止容器
docker start 容器名或容器ID: 启动容器
docker attach 容器名或容器ID: 连接一个UP状态的容器,可以进去交互
(有bash环境的才可以)
docker exec 容器名或容器ID 命令: 不用连接容器,可以外部传命令给
容器内部操作
docker exec -it 容器名或容器ID /bin/bash 连接容器交互
docker inspect 容器名或容器ID: 查看容器的属性
docker rm 容器名或容器ID: 删除容器
docker commit 容器名或容器ID 新的镜像名:TAG 将容器提交为
一个镜像
需要记忆的核心命令:
docker ps -a
docker run (重难点)
docker start ; docker stop;
docker commit
docker exec; docker exec -it 容器名或容器ID /bin/bash
docker rm
小结
docker在centos7目前使用的存储驱动为overlay2 docker通过写时复制(cow)和用时分配来提高存储的效率aufs和ovelay属于联合文件系统
aufs是多层分层
overlay主要为2两层: lowerdir和upperdir
overlay2相比于overlay节省innode
aufs是多层分层
overlay主要为2两层: lowerdir和upperdir
overlay2相比于overlay节省innode
练习: 请使用centos镜像自定义nginx环境
小结:
c2容器使用--link c1:haha创建,其实就是在c2容器内的/etc/hosts文件里增加了c1的主机名别名绑定
link实现单向通讯
link实现单向通讯
0 条评论
下一页