视频网址:https://www.bilibili.com/video/BV18b411K7q7?p=34
这个网址很有用:
https://note.youdao.com/ynoteshare1/index.html?id=8b6eb57f146d681becb2da34625a3d53&type=note
一款产品从开发到上线,从操作系统到运行环境,再到应用配置。作为开发+运维之间的协作我们需要关心很多东西,这样也是很多互联网公司都不得不去面对的问题,特别是很多版本的迭代之后,不同环境的兼容,对运维人员都是考验。
Docker
之所以发展这么迅速,也是因为他对此给出了一个标准化的解决方案。
环境配置如此麻烦,换一台机器,就要重来一次,费时费力。很多人想到,能不能从根本上解决问题,软件可以带环境安装?
也就是说,安装的时候,把原始环境一模一样的复制过来。开发人员利用Docker
可以消除协作编码时“在我的机器上可正常工作"的问题。
之前在服务器配置一个应用的运行环境,要安装各种软件,java/Tomcat/MySql/jdbc
驱动包等。安装和配置这些东西都多麻烦不用多说,它还不跨平台,假如我们在windows
环境上安装的这些环境,到了linux
又得重装,况且就算不跨操作系统,换另外一台同样操作系统的服务器,要移植应用也是非常麻烦的。
传统上认为,软件编码开发/测试结束后,所产出的成果即是程序或是能够编译执行的二进制字节码等(java为例)。而为了让这些程序可以顺利执行,开发团队也得准备完整的部署文件,让运维团队得以部署应用程序,开发需要清楚的告知运维团队,用的全文配置文件+所有软件环境。不过,即便如此,仍然常常发生部署失败的情况。
Docker
镜像的设计,使得docker
可以打破过去【程序即应用】的观念。透过镜像(images)
将作业系统核心除外,运作应用程序所需要的系统环境,由下而上的打包,达到应用程序跨平台间的无缝接轨运作。
Docker
是基于GO语言
实现的云开源项目
Docker
的主要目标是”Build,Ship and Run Any App ,AnyWhere“,也就是对应组件的封装、分发、部署、运行等生命周期的管理,使用户的APP
(可以是web
应用或者是数据库应用等等)及其运行环境能够做到”一次封装,到处运行“。
linux
容器技术的出现就解决了这个问题,而Docker
就是在它的基础上面发展过来的。将应用运行在Docker
容器上,而Docker
容器在任何一个操作系统中都是一致的,这就实现了跨平台、跨服务器
。只需要一次性配置好环境,换到别的机器上就可以一键部署好,大大的简化了操作。
一句话就是:
解决了运行环境和配置问题的软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术。
虚拟机就是带环境安装的一种解决方案。
它可以在一种操作系统里面运行另外一种操作系统,比如在windows
系统中运行Linux
系统。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一摸一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删除,对其他部分毫无影响,这类虚拟机完美的运行了另一套系统,能够使应用程序,操作系统和硬件三者之间的逻辑不变。
虚拟机的缺点:
由于之前虚拟机存在的缺点,Linux发展出了另外一种虚拟化技术:Linux容器(Linux containers)
Linux
容器不是模拟一个完整的操作系统,而是对进程进行隔离
。有了容器,就可以将软件运行的所有资源打包到一个隔离的容器中。容器与虚拟机不同,不需要捆绑一整套操作系统,只需要软件工作所需的库资源和设置,系统因此而变得高效轻量并保证部署在任何环境中的软件都能始终如一地运行。
Docker和传统虚拟化方式的不同之处
宿主的内核
,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更加轻便。也就是Docker是一个小型版,高度浓缩版的虚拟机。
一次构建,到处运行
更快速的应用交付和部署
更便捷的升级和扩缩容
更简单的系统运维
更高效的计算资源利用
安装参考地址:https://www.runoob.com/docker/centos-docker-install.html
https://www.runoob.com/docker/centos-docker-install.html
查看自己的内核
uname命令用于打印当前系统相关信息(内核版本号、硬件架构、主机名称和操作系统类型等)
[root@centos-7 ~]# uname -r
3.10.0-1062.el7.x86_64
[root@centos-7 ~]#
查看已经安装的centos版本信息
lsb_release -a
[root@centos-7 ~]# cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)
[root@centos-7 ~]#
在centos6.8上安装Docker
1.Docker使用EPEL发布,RHEL系的OS首先确保已经持有EPEL仓库,否则先检查OS的版本,然后安装相应的EPEL包。
[root@centos-7 ~]# yum install -y epel-release
Loaded plugins: fastestmirror, langpacks
Determining fastest mirrors
* base: mirror.lzu.edu.cn
* extras: mirrors.cqu.edu.cn
* updates: mirror.lzu.edu.cn
2.安装Docker
[root@centos-7 ~]# yum install -y docker-io
3.安装后的配置文件:/etc/sysconfig/docker
[root@centos-7 ~]# ls /etc/sysconfig/docker
/etc/sysconfig/docker
[root@centos-7 ~]# ls -l /etc/sysconfig/docker
-rw-r--r--. 1 root root 1094 Jan 30 19:17 /etc/sysconfig/docker
4.启动Docker后台服务:service docker start
[root@centos-7 ~]# service docker start
Redirecting to /bin/systemctl start docker.service
5.docker version验证
[root@centos-7 ~]# docker version
Client:
Version: 1.13.1
API version: 1.26
centos7上安装docker
参考网址:https://docs.docker.com/engine/install/centos/
在安装之前先安装gcc:
yum -y install gcc
yum -y install gcc-c++
gcc -v
sudo是管理员权限的切换,不一定每个人都有root管理员权限
Docker主机就是centos
docker run就是命令行终端,也就是我们敲命令的地方(就是Client),去访问安装docker的主机,但是容器中没有的话就去找镜像,镜像没有的话就去Registry上面找(这里的Registry就是dockerHub或者阿里云、网易云)
后台守护进程是daemon
镜像/容器
Person p1 = new Person();
Person p2 = new Person();
Person p3 = new Person();
p1、p2、p3是3个不同的实例,就是三个不同的容器
但是这三个均来自不同的模板,这个模板就是类就是镜像
Docker
镜像(image
)就是一个只读的模板。镜像可以用来创建Docker
容器,一个镜像可以创建多个容器。
容器与镜像的关系类似于面向对象编程中的对象与类
Docker | 面向对象 |
---|---|
容器 | 对象 |
镜像 | 类 |
Docker
利用容器(Container
)独立运行的 一个或者一组应用。容器是用镜像创建的运行实例。
它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。
可以把容器看做一个简易的linux
环境(包括 root用户权限、进程空间、用户空间和网络空间等)和运作在其中的应用程序。
容器的定义和镜像几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。
仓库(Repository
)是集中存放镜像文件的地方。
仓库(Repository
)和仓库注册服务器(Registry
)是有区别的。仓库注册服务器上往往存放着多个仓库,每个仓库中包含了多个镜像,每个镜像有不同的标签(tag
)。
仓库分为 公开仓库(Public
)和私有仓库(Private
)两种形式。
最大的公开仓库是Docker Hub(https://hub.docker.com)
存放了数量庞大的镜像供用户下载。国内的公开仓库包含 阿里云、网易云等。
需要正确理解仓库/镜像/容器这几个概念:
Docker
本身是一个容器运行载体或者称之为管理引擎。我们把 应用程序 和 配置依赖 打包好形成一个可交付的运行环境。这个打包好的运行环境就似乎image
镜像文件,只有通过这个镜像文件才能生成Docker
容器。image
文件可以看作是容器的模板。Docker
根据image
文件生成容器的实例。同一个image
文件,可以生成多个同时运行的容器实例。
image
文件生成的容器实例,本身也是一个文件,称为镜像文件。Docker
客户端创建一个对应的运行实例,也就是我们的容器。因为docker默认的是国外的镜像仓库(dockerHub)拉取镜像的时候特别慢,所以下面进行更改
阿里云镜像加速
阿里云的网址:https://dev.aliyun.com/search.html
在centos上安装好Docker以后,打开上述的网址,注册登陆(阿里云可以使用淘宝账号登陆)
点击右上角的控制台,进入按照下面的步骤
[root@centos-7 docker]# sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:f9dfddf63636d84ef479d645ab5885156ae030f611a56f3a7ac7f2fdd86d7e4e
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
docker run就是命令行终端,也就是我们敲命令的地方,去访问安装docker的主机,但是容器中没有,就去找镜像,镜像没有的话就去Registry上面找(这里的Registry就是dockerHub或者阿里云、网易云)我们已经配置成阿里云镜像加速了,拉取完就在容器中运行。
Docker
是一个Client-Server
结构的系统,Docker
守护进程运行在主机上,然后通过Socket
连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。容器,是一个运行时环境,就是我们前面说的集装箱。
Docker
有着比虚拟机更少的抽象层。由于Docker
不需要Hypervisor
实现硬件资源虚拟化,运行在Docker
容器上的程序直接使用的都是实际物理的硬件资源,因此在CPU
、内存利用率上Docker
将会在效率上有明显的优势。Docker
利用的宿主机的内核,而不需要Guest OS
。因此,当新建一个容器时,Docker
不需要和 虚拟机 一样重新加载一个操作系统内核。因而避免引寻、加载操作系统内核返个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS
,返个新建过程是分钟级别的。而Docker
由于直接利用宿主机的操作系统,则省略了返个过程,因此新建一个Docker
容器只需要几秒钟。docker version
docker info
docker --help
1、docker images 列出本地仓库的镜像
# 列出本地仓库的镜像
[root@centos-7 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 15 months ago 1.84kB
REPOSITORY
:表示镜像的仓库源TAG
:镜像的标签IMAGE ID
:镜像IDCREATED
:镜像的创建时间SIZE
:镜像大小同一个仓库可以有多个TAG,代表这个仓库源的不同版本,我们使用REPOSITORY:TAG来定义不同的镜像
如果你不指定一个镜像的版本标签,例如:你只使用了ubuntu,docker将默认使用ubuntu:latest镜像。
-a
:列出本地所有的镜像(含中间映像层)-q
:只显示镜像ID--digests
:显示镜像的摘要信息--no-trunc
:显示完整的镜像信息[root@centos-7 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 15 months ago 1.84kB
[root@centos-7 docker]# docker images -a
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 15 months ago 1.84kB
[root@centos-7 docker]# docker images -q
fce289e99eb9
[root@centos-7 docker]# docker images -qa
fce289e99eb9
[root@centos-7 docker]# docker images --digests
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
hello-world latest sha256:f9dfddf63636d84ef479d645ab5885156ae030f611a56f3a7ac7f2fdd86d7e4e fce289e99eb9 15 months ago 1.84kB
[root@centos-7 docker]# docker images --digests --no-trunc
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
hello-world latest sha256:f9dfddf63636d84ef479d645ab5885156ae030f611a56f3a7ac7f2fdd86d7e4e sha256:fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e 15 months ago 1.84kB
2、docker search —— 搜索镜像
在DockerHub
上面搜索镜像,上面配置了阿里云镜像加速,在DockerHub
上面搜索,在阿里云镜像种拉取
docker search tomcat
在DockerHub
上面查找所有的tomcat
镜像版本docker search -s 30 tomcat
: 查询出 点赞数超过30 的tomcat
镜像docker search -s 30 --no-trunc tomcat
:查询出 点赞数超过30 的tomcat
镜像的全部信息--automated
:只列出automated build
类型的镜像docker pull tomcat
等价于 docker pull tomcat:latest
最新版4、docker rmi 删除某个镜像名字ID
rmi——remove images
docker rmi -f 镜像名
docker rmi -f 镜像名:TAG 镜像名2:TAG
docker rmi -f ${docker images -qa}
有镜像才能创建容器,这是根本前提(下载一个centos镜像演示)
docker pull centos
这里说一下docker pull 和docker run的区别:
docker pull 是直接从镜像库中拉取镜像
docker run是先从本地拉取,如果本地没有的话才从镜像库上拉取
新建并启动容器 docker run -it centos
想新建并启动容器并且改名 docker run -it --name mycentos001 centos
列出当前所有正在运行的容器 docker ps
如果想退出容器的话 exit 这是直接退出
如果想后台启动的话用 ctrl + q +p
想查询上一个运行的容器 docker ps -l
想查询所有的容器(包含杀死的容器) docker ps -a
想查询前3个容器(包含杀死的容器) docker ps -n 3
想停止容器 docker stop 容器ID
想重启杀死的容器 docker restart 容器ID
想删除一个容器 docker rm -f 容器ID
一次性删除多个容器 docker rm -f ${docker ps -a -q} 或者 docker ps -a -q | xargs docker rm
启动守护式容器 后台运行容器 docker run -d 容器ID
使用镜像 centos:latest以后台模式启动一个容器
docker run -d centos
问题:然后使用docker ps -a进行查看,会发现容器已经退出
说明一点:Docker容器后台运行,就必须有一个前台进程
容器运行的命令如果不是哪些一直挂起的命令(比如运行top tail)就会自动退出
这个是Docker的机制问题,比如你的web容器,我们以nginx为例,正常情况下,我们配置启动服务只需要启动响应的service即可,例如service nginx start
但是这样做的话,nginx为后台进程模式运行,就导致docker前台没有运行的应用
这样的容器后台启动后,会立即自杀因为他觉得自己没有事可做
所以最佳的解决方案是,将你要运行的程序以前台进程的形式运行
也就是前台运行用docker run -it centos 后台启动用docker run -d centos
查看容器日志:docker logs -f -t --tail 容器ID
-t
是加入时间戳-f
跟随最新的日志打印--tail
数字显示最多多少条docker run -d centos /bin/sh -c “while true;do echo hello zzyy;sleep 2;done”
后台启动的进程,以2秒钟死循环后台打印
这里是为了演示上面的命令自己写了一个脚本
[root@centos-7 docker]# docker run -d centos /bin/sh -c "while true;do echo hello zzyy;sleep 2;done"
a56a44d230be303f7947cedc5c57873ba4478efc7ea96b8ede368024a8035958
[root@centos-7 docker]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a56a44d230be centos "/bin/sh -c 'while t…" 6 seconds ago Up 5 seconds dazzling_chaplygin
ba82cd629b27 centos "/bin/sh -c 'while t…" 4 minutes ago Up 4 minutes practical_margulis
0f6e2111305d centos "/bin/bash" 29 minutes ago Exited (0) 29 minutes ago serene_galois
# 单纯显示这个容器id的日志
[root@centos-7 docker]# docker logs ba82cd629b27
hello zzyy
hello zzyy
hello zzyy
# 显示这个容器日志的时间
[root@centos-7 docker]# docker logs -t ba82cd629b27
2020-04-10T03:48:38.848036319Z hello zzyy
2020-04-10T03:48:40.876583392Z hello zzyy
2020-04-10T03:48:42.880712689Z hello zzyy
# 显示这个容器id对应的最新的日志记录
[root@centos-7 docker]# docker logs -t -f ba82cd629b27
2020-04-10T03:48:38.848036319Z hello zzyy
2020-04-10T03:48:40.876583392Z hello zzyy
2020-04-10T03:48:42.880712689Z hello zzyy
# 显示这个容器id对应的前3行的日志信息
[root@centos-7 docker]# docker logs -t -f --tail 3 ba82cd629b27
2020-04-10T04:00:16.515217759Z hello zzyy
2020-04-10T04:00:18.519736194Z hello zzyy
2020-04-10T04:00:20.525589267Z hello zzyy
查看容器内进程
[root@centos-7 docker]# docker top 00daeb5876fd
UID PID PPID C STIME TTY TIME CMD
root 5691 5675 0 11:55 ? 00:00:02 /bin/sh -c while true;do echo hello zzyy;sleep 2;done
root 13981 5691 0 13:21 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 2
进入正在运行的容器并以命令行交互
[root@centos-7 docker]# docker ps -q
[root@centos-7 docker]# docker run -it centos
[root@b9f437b60dbe /]# ls -l
total 0
lrwxrwxrwx. 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x. 5 root root 360 Apr 10 05:48 dev
上下比较
[root@centos-7 docker]# docker attach b9f437b60dbe
[root@b9f437b60dbe /]# ls -l
total 0
lrwxrwxrwx. 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x. 5 root root 360 Apr 10 05:48 dev
docker exec -it 容器id ls -l /tmp
是在docker容器中打开新的终端,并且可以启动新的进程
[root@centos-7 docker]# docker exec -it b9f437b60dbe ls -l /tmp
total 8
-rwx------. 1 root root 671 Jan 13 21:49 ks-script-_srt3u3c
-rwx------. 1 root root 1379 Jan 13 21:49 ks-script-gpqu_kuo
[root@centos-7 docker]# docker exec -it b9f437b60dbe /bin/bash
[root@b9f437b60dbe /]#
从容器内拷贝文件到主机上
docker cp b9f437b60dbe:/tmp/yum.log /root/更改文件名(可改可不改)
这个命令的意思是把容器id为b9f437b60dbe的容器下面的/tmp/yum.log文件复制到/root目录下面并且改名
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包含代码、运行时、库、环境变量和配置文件。
Docker镜像加载原理:
Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS
bootfs(boot file system)主要包含bootloader和kernel,bootloader主要引导加载kernel,Linux刚启动会加载bootfs文件系统,在Docker镜像的底层是bootfs。这一层与我们典型的Linux/unix系统是一样的,包含boot加载器和内核。当boot加载完成之后,整个内核都就在内核中,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs.
rootfs(root,file,system),在bootfs之上,包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件,
rootfs就是各种不同的操作系统发行版,比如ubuntu,centos等等。
Docker镜像commit操作补充
Docker commit提交容器副本使之成为一个新的镜像
之前都是拉取镜像之后产生容器再运行
这里演示的是将tomcat镜像拉下来之后,修改其中文件(这里删除了/webapp下的docs文件)然后再打包成镜像的过程
- docker run -it -p 8888:8080 tomcat:8.0.52——前台启动tomcat8.0.52
然后删除最新版tomcat的docs文件,下面再对删除docs文件的tomcat容器进行打包成镜像
[root@centos-7 docker]# docker commit -a="zzyy" -m="del tomcat docs" 5260bf2770bb aiguigu/tomcat:1.2
sha256:3ff9bafa268653e17516e433f12c118aa5194d29563c70a34983a1ef27553fa3
[root@centos-7 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
aiguigu/tomcat 1.2 3ff9bafa2686 9 seconds ago 356MB
mongo latest c5e5843d9f5f 2 weeks ago 387MB
centos latest 470671670cac 2 months ago 237MB
tomcat 8.0.52 b4b762737ed4 21 months ago 356MB
[root@centos-7 docker]# docker run -it -p 7777:8080 aiguigu/tomcat:1.2
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /docker-java-home/jre
测试:
tomcat首页是可以访问的
但是点击Documentation报404
1.作用
2.先来看看Docker理念:
Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据作为镜像的一部分保存下来,那么当容器删除后,数据自然就没有了
为了能保存数据,在docker中我们使用卷
3.特点:
卷就是目录或者文件,存在于一个或者多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能都绕过Union File System提供一些用于持续存储或者共享数据的特性:
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker 不会在容器删除时删除其挂载的数据卷
特点:
一、直接用命令添加
1.直接命令添加
docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
下面目录没有,会自己创建
[root@centos-7 /]# docker run -it -v /myDataVolume:/myDataVolumeContainer centos
[root@77bf1f7a2d19 /]# ls -l
total 0
lrwxrwxrwx. 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x. 5 root root 360 Apr 10 09:08 dev
drwxr-xr-x. 1 root root 66 Apr 10 09:08 etc
这个命令执行之后,会在Linux宿主机上面和docker容器上面的centos容器上面分别产生文件夹
延申一个命令(在容器中):
echo itcase > a.txt
这句话的意思是:在当前目录下新建一个文件a.txt 里面的内容是 itcase
2.查看数据卷是否挂载成功
docker inspect
3.容器和宿主机之间数据共享
这里说明的是容器和主机之间数据的共享
怎么体现呢?
这里是这样的,当你按照上面分别在宿主机和centos容器上面新建的目录之后,分别在宿主机或者centos容器上的任何一个新建一个文件,对应的宿主机或者centos上面就有响应的文件。
4.容器停止退出后,主机修改后数据是否同步
是同步的
场景:
exit退出centos容器,在宿主机上面新建一个文件或者修改文件,当重新启动centos对应容器时,数据会同步这个centos容器上面
5.命令带权限
docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
ro —— readonly
这里想说明一个问题:
当你在宿主机上面新建一个文件夹里面新建一个文件之后,centos容器上面这个文件是有的,而容器centos里面是不能新建或者修改文件
[root@centos-7 /]# docker run -it -v /myDataVolume:/myDataVolumeContainer:ro centos
[root@67ec1cb80799 /]#
docker run -it --name=c3 -v /volume centos:7 /bin/bash
2.创建启动c1,c2容器,使用–volume-from c3 centos:7 /bin/bash
docker run -it --name=c1 --volume-from c3 centos:7 /bin/bash
docker run -it --name=c2 --volume-from c3 centos:7 /bin/bash
二、 DockerFile添加容器数据卷
1.根目录下新建mydocker文件夹并进入
[root@centos-7 /]# mkdir mydocker
[root@centos-7 /]# cd mydocker/
[root@centos-7 mydocker]#
2.可在DockerFile中使用volume指令来给镜像添加一个或多个数据卷
VOLUME[“/dataVolumeContainer”,“/dataVolumeContainer2”,“/dataVolumeContainer3”]
说明:
出于可移植和分享的考虑,用-v主机目录:容器目录这种方法不能直接在DockerFile中实现。
由于宿主机目录是依赖于特定宿主机的,并不能够在所有的宿主机上都存在这样的特定目录。
3.DockerFile的构建
[root@centos-7 mydocker]# pwd
/mydocker
[root@centos-7 mydocker]# touch DockerFile
[root@centos-7 mydocker]# ll
total 0
-rw-r--r--. 1 root root 0 Apr 11 13:06 Dockerfile
[root@centos-7 mydocker]# vim DockerFile
[root@centos-7 mydocker]#
Dockerfile里面的内容:
#volume test
FROM centos
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
CMD echo "finished,-------success1"
CMD /bin/bash
其中DockerFile里面的内容用上面的命令形式相当于
docker run -it -v /host1:/dataVolumeContainer1 -v /host2:/dataVolumeContainer2 centos /bin/bash
4.build后生成镜像
[root@centos-7 mydocker]# docker build -f /mydocker/Dockerfile -t zzyy/centos .
docker run -it zzyy/centos /bin/bash
根据上面的步骤,可以发现在centos容器里面可以看到有两个容器卷:dataVolumeContainer1,dataVolumeContainer2
在任意一个里面新建一个文件:containt01.txt
[root@22f1cafbb05e /]# cd dataVolumeContainer1
[root@22f1cafbb05e dataVolumeContainer1]# touch containt01.txt
[root@22f1cafbb05e dataVolumeContainer1]# ls -l
total 0
-rw-r--r--. 1 root root 0 Apr 11 07:32 containt01.txt
然后执行docker inspent 容器id ,找到其中在宿主机下的文件地址:
然后在宿主机下面根据上述的地址可以找到在centos下新建的文件;
[root@centos-7 _data]# cd /var/lib/docker/volumes/9a838cd81b0229e5b0635f6986d201aef36886d442e71f0de9c913608c500425/_data
[root@centos-7 _data]# ll
total 0
-rw-r--r--. 1 root root 0 Apr 11 15:32 containt01.txt
[root@centos-7 _data]#
然后在宿主机上面新建一个host.txt文件
[root@centos-7 _data]# touch host.txt
[root@centos-7 _data]# ll
total 0
-rw-r--r--. 1 root root 0 Apr 11 15:32 containt01.txt
-rw-r--r--. 1 root root 0 Apr 11 15:56 host.txt
在centos容器上会同步有host.txt文件
[root@22f1cafbb05e dataVolumeContainer1]# ls -l
total 0
-rw-r--r--. 1 root root 0 Apr 11 07:32 containt01.txt
-rw-r--r--. 1 root root 0 Apr 11 07:56 host.txt
命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,成为数据卷容器。
1.以上一步新建的zzyy/centos为模板并运行容器 dc01/dc02/ddc03
他们已经有了容器卷
2.容器间传递共享(–volumes-from)
docker run -it --name dc01 zzyy/centos
[root@centos-7 docker]# docker run -it --name dc01 zzyy/centos
[root@3d2997c24b48 /]# ls -l
total 0
lrwxrwxrwx. 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x. 2 root root 6 Apr 11 08:30 dataVolumeContainer1
drwxr-xr-x. 2 root root 6 Apr 11 08:30 dataVolumeContainer2
[root@3d2997c24b48 /]# cd dataVolumeContainer2
[root@3d2997c24b48 dataVolumeContainer2]# touch dc01_add.txt
[root@3d2997c24b48 dataVolumeContainer2]# ls -l
total 0
-rw-r--r--. 1 root root 0 Apr 11 08:32 dc01_add.txt
[root@3d2997c24b48 dataVolumeContainer2]# touch dc01_add.txt[root@centos-7 docker]#
[root@centos-7 docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3d2997c24b48 zzyy/centos "/bin/sh -c /bin/bash" 2 minutes ago Up 2 minutes dc01
docker run -it --name dc02 --volumes-from dc01 zzyy/centos
docker run -it --name dc03 --volumes-from dc01 zzyy/centos
[root@centos-7 docker]# docker run -it --name dc02 --volumes-from dc01 zzyy/centos
[root@ce4c2ee486f3 /]# cd dataVolumeContainer2
[root@ce4c2ee486f3 dataVolumeContainer2]# ls -l
total 0
-rw-r--r--. 1 root root 0 Apr 11 08:32 dc01_add.txt
[root@ce4c2ee486f3 dataVolumeContainer2]# touch dc02_add.txt
[root@ce4c2ee486f3 dataVolumeContainer2]# ls -l
total 0
-rw-r--r--. 1 root root 0 Apr 11 08:32 dc01_add.txt
-rw-r--r--. 1 root root 0 Apr 11 08:38 dc02_add.tx
[root@centos-7 docker]# docker run -it --name dc03 --volumes-from dc01 zzyy/centos
[root@1f1e54cd67d1 /]# cd dataVolumeContainer2
[root@1f1e54cd67d1 dataVolumeContainer2]# ls -l
total 0
-rw-r--r--. 1 root root 0 Apr 11 08:32 dc01_add.txt
-rw-r--r--. 1 root root 0 Apr 11 08:38 dc02_add.txt
[root@1f1e54cd67d1 dataVolumeContainer2]# touch dc03_add.txt
[root@1f1e54cd67d1 dataVolumeContainer2]# ls -l
total 0
-rw-r--r--. 1 root root 0 Apr 11 08:32 dc01_add.txt
-rw-r--r--. 1 root root 0 Apr 11 08:38 dc02_add.txt
-rw-r--r--. 1 root root 0 Apr 11 08:42 dc03_add.txt
[root@centos-7 docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1f1e54cd67d1 zzyy/centos "/bin/sh -c /bin/bash" About a minute ago Up About a minute dc03
ce4c2ee486f3 zzyy/centos "/bin/sh -c /bin/bash" 4 minutes ago Up 4 minutes dc02
3d2997c24b48 zzyy/centos "/bin/sh -c /bin/bash" 12 minutes ago Up 12 minutes dc01
这样在三个容器里面的dataVolumeContainer2数据卷里面都有了dc01_add.txt,dc02_add.txt,dc03_add.txt这三个文件
1.手动编写一个dockerfile文件,当然,必须要符合file的规范
2.有了这个文件以后,直接docker build命令执行,获得一个自定义的镜像
3.run
1.Dockerfile是什么?
Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。
2.Dockerfile的构建三步骤
3.Dockerfile的构建过程解析
Dockerfile内容基础知识
1.每条保留字指令都必须为大写字母且后面要跟随至少一个参数
2.指令按照从上到下。顺序执行
3.#表示注释
4.每条指令都会创建一个新的镜像层,并对镜像进行提交
4.Docker执行Dockerfile的大致流程
1.Docker从基础镜像运行一个容器
2.执行一条指令并对容器进行修改
3.执行类似Docker commit的操作提交一个新的镜像层
4.Docker基于刚提交的镜像运行一个新的容器
5.执行Dockerfile中的下一条指令直到所有指令都执行完成
5.小总结
从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段。
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。
6.DockerFile保留字指令
ENV MY_PATH /usr/mytest
这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样
也可以在其他指令中直接使用这些环境变量
比如:WORKDIR $MY_PATH
COPY src dest——这是Linux命令shell脚本的形式
COPY [“src”,“dest”]——这个类似json串的形式
VOLUME——容器数据卷,用于数据保存和持久化工作
CMD——指定一个容器启动时要运行的命令
Dockerfile中可以有多个CMD指令,但是只有最后一个生效,CMD会被docker run之后的参数替换
CMD容器启动命令
cmd指令的格式和RUN相似,也是两种格式:
- shell 格式:CMD<命令>
- exec 格式:CMD [“可执行文件”,“参数1”,“参数2”,…]
- 参数列表格式:CMD [“参数1”,“参数2”,…],在指定了ENTRYPOINT指令后,用CMD指定具体的参数
ENTRYPOINT——指定一个容器启动时要运行的命令
- ENTRYPOINT的目标和CMD一样,都是在指定容器启动程序参数
ONBUILD——当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发
7.Base镜像(scratch)
Docker Hub中99%的镜像都是通过base镜像中安装和配置需要的软件构建出来的
1.编写
Hub默认Centos镜像是什么情况
场景:
自定义mycentos目的使我们自己的镜像具备如下:
FROM centos
MAINTAINER zzyy<zzyy167@126.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "success-----------ok"
CMD /bin/bash
编写完dockerfile以后,然后build镜像,再run容器,可以看到
根目录变了,成了dockerfile里面的路径了/usr/local 可以编写vim文件了 可以用ifconfig查看网络
[root@centos-7 mydocker]# docker build -f /mydocker/Dockerfile2 -t mycentos:1.3 .
[root@centos-7 mydocker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 1.3 56597bf6f192 28 seconds ago 327MB
[root@centos-7 mydocker]# docker run -it mycentos:1.3
[root@a9f79cdf07eb local]# pwd
/usr/local
[root@a9f79cdf07eb local]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 8 bytes 656 (656.0 B)
列出镜像的变更历史
docker history 镜像名
[root@a9f79cdf07eb local]# [root@centos-7 mydocker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 1.3 56597bf6f192 11 minutes ago 327MB
zzyy/centos latest cef2c37dde04 24 hours ago 237MB
aiguigu/tomcat 1.2 3ff9bafa2686 46 hours ago 356MB
mongo latest c5e5843d9f5f 2 weeks ago 387MB
centos latest 470671670cac 2 months ago 237MB
tomcat 8.0.52 b4b762737ed4 21 months ago 356MB
[root@centos-7 mydocker]# docker history 56597bf6f192
IMAGE CREATED CREATED BY SIZE COMMENT
56597bf6f192 11 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B
b07330cb0c0e 11 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
a4d410fbab24 11 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
29bcfa9e0f48 11 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B
d46bdf059248 11 minutes ago /bin/sh -c yum -y install net-tools 26.7MB
71c4af8a1f5d 12 minutes ago /bin/sh -c yum -y install vim 63.5MB
db4b72980b1d 13 minutes ago /bin/sh -c #(nop) WORKDIR /usr/local 0B
ccf4bb35fc75 13 minutes ago /bin/sh -c #(nop) ENV MYPATH=/usr/local 0B
89b073d320c5 13 minutes ago /bin/sh -c #(nop) MAINTAINER zzyy<zzyy167@1… 0B
470671670cac 2 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 2 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 2 months ago /bin/sh -c #(nop) ADD file:aa54047c80ba30064… 237MB
可以看到Dockerfile文件执行的时候是从上往下执行的
用docker history的时候是需要从下往上看的
都是指定一个容器启动时要运行的命令
1.CMD指令
Dockerfile中可以有多个CMD指令,但是只有最后一个生效,CMD会被docker run之后的参数替换
举例对这句话的解释:CMD会被docker run之后的参数替换
可以先去tomcat中的Dockerfile文件看看,最底层CMD [“catalina.sh”,“run”]
当你执行docker run -it -p 7777:8080 tomcat的时候时是可以启动的,
但是当你执行docker run -it -p 7777:8080 tomcat ls -l时是不会启动的
因为CMD会被docker run之后的ls -l替换了直接进入tomcat的目录下面了
[root@centos-7 mydocker]# docker run -it -p 7777:8080 tomcat:8.0.52 ls -l
total 92
-rw-r--r--. 1 root root 57011 Apr 28 2018 LICENSE
-rw-r--r--. 1 root root 1444 Apr 28 2018 NOTICE
-rw-r--r--. 1 root root 6792 Apr 28 2018 RELEASE-NOTES
-rw-r--r--. 1 root root 16242 Apr 28 2018 RUNNING.txt
drwxr-xr-x. 2 root root 4096 Jun 27 2018 bin
drwxr-xr-x. 2 root root 182 Apr 28 2018 conf
drwxr-sr-x. 3 root staff 19 Jun 27 2018 include
drwxr-xr-x. 2 root root 4096 Jun 27 2018 lib
drwxr-xr-x. 2 root root 6 Apr 28 2018 logs
drwxr-sr-x. 3 root staff 151 Jun 27 2018 native-jni-lib
drwxr-xr-x. 2 root root 30 Jun 27 2018 temp
drwxr-xr-x. 7 root root 81 Apr 28 2018 webapps
drwxr-xr-x. 2 root root 6 Apr 28 2018 work
2.ENTRYPOINT指令
docker run之后的参数会被当作参数传递给ENTRYPOINT,之后形成新的命令组合
Case
3.ONBUILD命令
当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发
1.mkdir -p /zzyyuse/mydockerfile/tomcat9
2.在上述的目录下面touch c.txt
3.将jdk和tomcat安装的压缩包拷贝进上一目录
apache-tomcat-9.0.8.tar.gz
jdk-8u171-linux-x64.tar.gz
4.在/zzyyuse/mydockerfile/tomcat9目录下新建Dockerfile文件
FROM centos
MAINTAINER zzyy<zzyybs@126.com>
#把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下
COPY c.txt /usr/local/cincontainer.txt
#把java与tomcat添加到容器中
ADD jdk-8u51-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-7.0.55.tar.gz /usr/local/
#安装vim编辑器
RUN yum -y install vim
#设置工作访问时候的VORKDIR路径,登录落脚点
ENV MYPATH /usr/local
WORKDIR $MYPATH
#配置java与tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_51
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-7.0.55
ENV CATALINA_BASE /usr/local/apache-tomcat-7.0.55
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/lib
#容器运行时监听的端口号
EXPOSE 8080
#启动时运行tomcat
#ENTRYPOINT ["/usr/local/apache-tomcat-7.0.55/bin/startup.sh"]
#CMD ["/usr/local/apache-tomcat-7.0.55/bin/catalina.sh","run"]
CMD /usr/local/apache-tomcat-7.0.55/bin/startup.sh && tail-F /usr/local/apache-tomcat-7.0.55/bin/logs/catalina.out
[root@centos-7 tomcat9]# docker run -d -p 9080:8080 --name myt9 -v /zzyyuse/mydockerfile/tomcat9/test:/usr/local/apache-tomcat-7.0.55/webapps/test -v /zzyyuse/mydockerfile/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-7.0.55/logs --privileged=true zzyy/tomcat9
594ea0948dcf56e43d1d1d1c67f79ba3a6cae98868c798cfba756de0a9643514
总体步骤
1.搜索镜像
2.拉取镜像
3. 查看镜像
4.启动镜像
5.停止容器
6.移除镜像
1.从DockerHub上面查找mysql镜像
docker search mysql
2.从docker hub上(阿里云加速器)拉取mysql镜像到本地标签为5.6
docker pull mysql:5.6
3.使用mysql5.6镜像创建容器(也叫运行镜像)
[root@centos-7 docker]# docker run -p 12345:3306 --name mysql
-v /zzyyuse/mysql/conf:/etc/mysql/conf.d
-v/zzyyuse/mysql/logs:/logs
-v /zzyyuse/mysql/data:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=123456
-d mysql:5.6
通过docker 来操作docker上面的mysql数据库来进行数据的备份
docker exec a5a9483c4d9c sh -c 'exec mysqldump--all-databases -uroot -p"123456"'> /zzyyuse/all-databases.sql
对上面的解释:
对这个mysql容器的数据按照用户名和密码的形式备份到 /zzyyuse/all-databases.sql的目录下
docker pull redis:3.2
docker run -p 6379:6379 -v /zzyyuse/myredis/data:/data -v /zzyyuse/myredis/config/redis.conf:/usr/local/etc/redis/redis.conf -d redis:3.2 redis-server /usr/local/etc/redis/redis.conf --appendonly yes
在主机//zzyyuse/myredis/conf/redis.conf 目录下新建redis.conf文件
vim /zzyyuse/myredis/conf/redis.conf/redis.conf
新建了上面的文件以后,需要复制redis.conf的内容并且再其中可以修改一些配置内容
docker ps以后可以看到redis-server的服务端已经启动
下来要客户端连接服务端
docker exec -it d36231a90b90 redis-cli
进入了客户端
# 1、拉取mongodb镜像
[root@localhost run]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 14 months ago 13.3kB
[root@localhost run]# docker pull mongo:latest
latest: Pulling from library/mongo
...
37200fef7cf6: Pull complete
Digest: sha256:8bed0be3e86595283d67836e8d4f3f08916184ea6f2aac7440bda496083ab0c8
Status: Downloaded newer image for mongo:latest
docker.io/library/mongo:latest
# 2、创建和启动容器
[root@localhost run]# docker run -d --restart=always -p 27017:27017 --name mymongo -v /data/db:/data/db -d mongo
dbd35c554e1b5eb8e503407154486c45b0791aac0fb457864501324e19404e7b
# 3、进入容器
[root@localhost run]# docker exec -it mymongo /bin/bash
[root@localhost run]# docker exec -it mymongo /bin/bash
root@dbd35c554e1b:/#
# 4、使用MongoDB客户端进行操作
# mongo命令在mongodb 6.0已经不适用了。
# 改成使用mongosh 命令就可以
root@dbd35c554e1b:/# mongosh
Current Mongosh Log ID: 6384bb0b35cdd61f4f83c2a3
Connecting to: mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+1.6.0
Using MongoDB: 6.0.3
Using Mongosh: 1.6.0
...
# 查询所有的数据库
test> show dbs
admin 40.00 KiB
config 12.00 KiB
local 40.00 KiB
1.把本地idea代码打成jar包
2.然后把这个jar包上传到docker容器中(放在Dockerfile的目录下面)
3.编辑Dockerfile文件
FROM java:8
MAINTAINER itheima <itheima@itcase.cn>
ADD springboot-hello-0.0.1-SNAPSHOT.jar app.jar
CMD java -jar app.jar
docker commit -a zzyy -m "new mycentos:1.4 with vim and ifconfig" 18156bccb7fb mycentos:1.4
将本地镜像推送到阿里云
1.本地镜像素材原型
2.阿里云开发者平台
https://dev.aliyun.com/search.html
3.创建仓库镜像
$ sudo docker login --username=镜像云 registry.cn-qingdao.aliyuncs.com
$ sudo docker tag [ImageId] registry.cn-qingdao.aliyuncs.com/zzyybulx/mycentos1.4:[镜像版本号]
$ sudo docker push registry.cn-qingdao.aliyuncs.com/zzyybulx/mycentos1.4:[镜像版本号]
5.公有云可以查询到
6.在阿里云上可以查看
1.服务编排:
微服务架构的应用系统中一般包括若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,维护的工作量会很大。
3.Docker Compose
Docker Compose是一个编排多容器分布式部署的工具,提供命令集管理容器化应用的完整开发周期,包括服务构建,启动和停止
使用步骤:
1.Dockerfile定义运行环境镜像
2.使用docker-compose.yml定义组成命令的各服务
3.运行docker compose up启动应用
4.docker compose安装使用
curl -L https://github.com/docker/compose/releases/download/1.25.4/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
进入 /usr/local/bin 目录,会发现多了个 docker-compose,但没有x 这个权限
[root@bogon docker]# cd /usr/local/bin
[root@bogon bin]# ll
total 16776
-rw-r--r--. 1 root root 17176256 Mar 19 22:01 docker-compose
设置权限
chmod +x /usr/local/bin/docker-compose
现在就有了
[root@bogon bin]# ll
total 16776
-rwxr-xr-x. 1 root root 17176256 Mar 19 22:01 docker-compose
验证是否安装成功
[root@bogon bin]# docker-compose version
docker-compose version 1.25.4, build 8d51620a
docker-py version: 4.1.0
CPython version: 3.7.5
OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019
5.卸载docker compose
rm /usr/local/bin/dokcer-compose
1.创建docker compose目录
mkdir ~/docker-compose
cd ~/docker-compose
vim docker-compose.yml
2.编写docker-compose.yml文件
version: '3'
service:
nginx:
images: nginx
ports:
- 80:80
links:
- app
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
app:
image: app
expose:
- "8080"
3.创建./nginx/conf.d目录
mkdir -p ./nginx/conf.d
4.在/nginx/conf.d目录下编写itheima.conf文件
server {
listen: 80;
access_log off;
location / {
proxy_pass http://app:8080;
}
}
5.在~/docker-compose目录下 使用docker-compose启动容器
docker-compose up
6.测试访问
http://ip/hello
一、私有仓库的搭建
#1.拉取私有仓库镜像
docker pull registry
#2.启动私有仓库容器
docker run -id --name=registry -p 5000:5000 registry
#3.打开浏览器 输入地址http://私有仓库服务器ip:5000/v2/_catalog,看到{"repositories":[]}表示私有仓库搭建成功
#4.修改daemon.json
vim /etc/docker/daemon.json
#在上述文件中添加一个key,保存退出。此步用于让docker信任私有仓库地址,注意将私有仓库服务器ip修改为自己私有仓库真实ip
{"insecure-registries": [私有仓库服务器ip:5000]}
#5.重启docker服务
systemct1 restart docker
docker start registry
二、将镜像上传至私有仓库
#1.标记镜像为私有仓库的镜像
docker tag centos:7 私有仓库服务器ip:5000/centos:7
#2.上传标记的镜像
docker push 私有仓库服务器ip:5000/centos:7
三、从私有仓库拉取镜像
#1.拉取镜像
docker pull 私有仓库服务器ip:5000/centos:7
建议以后看这个视频:
https://www.bilibili.com/video/BV167411g7Lg?p=27