虚拟化技术Docker学习
学习就是脚踏实地不断地重复、反思、总结的过程
文章目录
1. Docker介绍
是什么?
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有接口。
优点:(举例)
- 更高效的利用系统资源
- 应用执行速度、内存损耗或者文件存储速度都要比传统虚拟机技术更高效。一个docker上面可以跑多个应用。避免的重复开多台虚拟机,这就有效的利用了资源
- 更快速的启动时间
- docker容器应用,由于直接运行在Linux内核中,无需启动完整的操作系统,docker应用的启动是秒级的,大大的节约了开发测试,部署的时间。
- 一致的运行环境
- 企业,开发人员、测试人员、运维人员的生产环境不一致,导致有些Bug因为版本的问题而花费大量的时间。而docker由于小,可以打包镜像,确保了环境的一致性。从而不会出现“这段代码在我机器上没问题”这类问题
- 持续支付和部署
- 对于开发和运维人员来说,希望一次创建和部署,可以在任意的地方运行。使用dockerfile使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像
- 更轻松地迁移
- 由于docker保证了运行环境的一致性。使得应用的迁移变得更加的容易
- 更轻松的维护和拓展
- docker使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,应用的维护更新更加简单,基于基础镜像进一步扩展变得十分简单。将自己的需求更改后上传到阿里云仓库,需要时可以直接下载。
网络上选取的几张图可以帮助我们更好的理解docker的作用
为什么是Docker?
- 更轻量:基于容器的虚拟化,仅包含业务运行所需的runtime环境,CentOS/Ubuntu基础镜像仅170M;宿主机可以部署100~1000个容器
- 更高效:无操作系统虚拟化开销
- 计算:轻量,无额外开销
- 存储:系统盘aufs/dm/overlayfs;数据盘volume
- 网络:宿主机网络,NS隔离
- 更便捷、更灵活:
- 分层的存储和包管理,devops理念
- 支持多种网络配置
安装
参考菜鸟文档:https://www.runoob.com/docker/centos-docker-install.html
2. Docker三大特性:仓库、镜像、容器
镜像(Image):
就是一个可读的模板。镜像可以用来创建Docker容器,一个镜像可以创建很多容器。
镜像/容器
容器于镜像的关系类似于面向对象编程中的对象与类
docker | 面向对象 |
---|---|
容器 | 对象 |
镜像 | 类 |
容器(Container):
容器是用镜像创建的运行实例,Docker利用容器(Container)独立运行的一个或一组应用。它可以被启动、开始、停止、删除。每个容器环境(集装箱)都是相互隔离的、保证安全的平台。
也可以把容器看作是一个简易版的Linux环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
补充:由于虚拟机存在着大量的缺点,Linux发展出了另一种虚拟化技术:Linux容器(Linux Containers,缩写为LXC)
Linux容器不是模拟一个完整的操作系统,而是对进程进行隔离。有了容器,就可以将软件运行所需的所有资源打包到一个隔离的容器中。容器与虚拟机不同,不需要捆绑一整套操作系统,只需要软件工作所需的库资源和设置。系统因此而变得高效、轻量,并保证部署在任何环境中的软件都能始终如一地运行。
仓库(Repository):
集中存放镜像文件的场所。
仓库(Repository)和仓库注册服务器(Registry)是有区别的。仓库注册服务器上往往存放着多个仓库,每个仓库又包含了多个镜像,每个镜像有不同的标签(tag).
仓库分为**公开仓库(Public)和私有仓库(Private)**两种形式。
最大的公开仓库是Docker Hub(https://hub.docker.com/),存放了数量庞大的镜像供用户下载。
国内的公开仓库包括阿里云、网易云等。
安装好了之后docker pull hello-world
先拉镜像看一下
docker pull hello-world
docker images
docker run hello-world
使用这条命令来查看是否镜像加速ps -ef | grep docker
3. docker底层原理
- Dockers是怎么工作的?
Docker是一个C/S(Client-Server)结构的系统 ,Docker守护进程运行在主机上,然后通过Socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。容器,是一个运行环境,就是我们前面所说的集装箱。
可以把各个应用放在集装箱上,然后通过客户端来操作这些东西。
- 为什么Docker比VM虚拟机快?
- docker有着比虚拟机更少的抽象层。由于Docker不需要Hypervisor实现硬件资源虚拟化,运行在Docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上Docker将在效率上有明显的效率。
- docker利用的是宿主机的内核,而不需要Guest OS。因此,当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。仍而避免引寻、加载操作系统内核这份比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,这个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了这个过程,因此新建一个docker容器只需要几秒钟。
/ | Docker容器 | 虚拟机(VM) |
---|---|---|
操作系统 | 与宿主机共享OS | 宿主机OS上运行虚拟机OS |
存储大小 | 镜像小,便于存储与传输 | 镜像庞大(vmdk、vdi等) |
运行性能 | 几乎无额外性能损失 | 操作系统额外的CPU、内存消耗 |
移植性 | 轻便、灵活、适应于Linux | 笨重,与虚拟化技术耦合度高 |
硬件亲和性 | 面向软件开发者 | 面向硬件运维者 |
4. docker常用命令
帮助命令
docker version ##查看版本
docker info ##查看更加详细的说明
docker --help #帮助手册,文档(习惯去看英文)
镜像命令
鲸鱼背上有集装箱在蓝色的大海里
蓝色的大海=宿主机Window10 鲸鱼=docker 集装箱=容器实例 from来自我们的镜像模板
docker images ##列出本地主机上的的镜像
-a ##(all)列出本地所有的镜像(含中间映像层。镜像是一个千层饼)
-q ##只显示镜像的ID。 可以-aq显示所有镜像的ID
--digests ##显示镜像的摘要信息(类似于备注)
--no-trunc ##显示完整的镜像信息
docker search 某个XXX镜像的名字
官方网站查找https://hub.docker.com
命令:docker search [OPTIONS]镜像名字
OPTIONS说明:
--no-trunc:显示完整的镜像描述
-f stars=60:列出收藏数不小于指定值(60)的镜像
--automated:只列出automated build类型的镜像;
eg:docker search tomcat
docker search -f 30 tomcat
docker search -f 30 --no-trunc tomcat
docker pull 某个XXX镜像名字 **拉取镜像**
默认的话,拉取的是最新版的
eg: docker pull nginx
:latest
docker rmi 某个XXX镜像名字ID/镜像名
:删除镜像
:删除单个--docker rmi -f(force强制) 镜像ID
:删除多个--docker rmi -f 镜像名1:TAG镜像名2:TAG
:删除全部--docker rmi -f $(docker images -q/-qa)
容器命令:
新建并启动容器docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
OPTIONS说明(常用):有些是一个减号,有些事两个减号
--name="容器名字":为容器指定一个名称;
-d:后台运行容器,并返回容器ID,也即启动守护式容器;
## -i:以交互模式运行容器,通常与-t同时使用;
## -t:为容器重新分配一个伪输入终端,通常与-i同时使用;
-P:随机端口映射;
-p:指定端口映射,有以下四种格式
ip:hostPort:containerPort
ip::containerPort
** hostPort:containerPort
containerPort
列出当前所有正在运行的容器docker ps [OPTIONS]
-a:列出当前所有正在运行的容器+历史上运行过的
-l:显示最近创建的容器
-n:显示最近n个创建的容器。
-q:静默模式,只显示容器编号。
--no-trunc:不截断输出。
退出容器--两种退出方式:exit 容器停止并退出
ctrl+P+Q 容器不停止退出
重启容器 docker restart 容器ID或者容器名
停止容器 docker stop 容器ID或者容器名
强制停止容器 docker kill 容器ID或者容器名
删除已停止的容器 docker rm (-f强制) 容器ID或者容器名
一次性删除多个容器 docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm
容器重要命令
启动守护式容器docker run -d 容器名或者容器ID
查看容器日志 docker logs -f -t --tail 容器ID
* -t是加入时间戳
* -f跟随最新的日志打印
* --tail数字显示最后多少条
查看容器内运行的进程 docker top 容器ID
查看容器内部细节 docker inspect 容器ID
进入正在运行的容器并以命令行交互 docker exec -it 容器ID /bin/bash (bash shell)
重新进入docker attach 容器ID
上述两个区别: attach直接进入容器启动命令的终端,不会启动新的进程
exec是在容器中打开新的终端,并且可以启动新的进程
##docker -exec -it 容器ID /bin/bash可以进入容器中的应用。比如centos
##docker -exec -it 容器ID ls -l /tmp 不会进入容器中就可以返回结果
从容器内拷贝文件到主机上 docker cp 容器ID:容器内路径 目的主机路径
eg:
[root@localhost ~]# docker cp 93c6ab4c9297:/tmp/ks-script-eusq_sc5 /root
[root@localhost ~]# ls
1.py anaconda-ks.cfg echo.sh ks-script-eusq_sc5
当你在后台启动一个程序时,这时你通过docker ps
来查看,就会发现容器已经退出,当前没有任何启动?这是为什么呢?难道没有启动?
答:Docker 容器后台运行,就必须有一个前台进程。容器运行的命令如果不是那些一直挂起的命令,就会自动退出的。
docker的机制问题,比方说后台启动一个Nginx,这样做,Nginx为后台进程模式运行,就导致
docker前台没有运行的应用,这样的容器后台启动后,会立即自杀,因为他觉得他没事可做了。
所以,最佳方案是,将你要运行的程序以前台进程的形式运行
5. Dockers镜像
docker镜像是什么?
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
UnionFS(联合文件系统):
Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual file system),Union文件系统是docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:==一次同时加载多个文件系统,==但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。就跟花卷一样
docker镜像加载原理?
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
平时我们安装虚拟机的Centos都是好几个G,为什么Docker这里才200M??
对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的Kernel,自己只需要提供rootfs就行了。由此可见对于不同的Linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs
为什么docker镜像要采用这种分层结构呢?
最大的一个好处就是–共享资源
比如:有多个镜像都从相同的base镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,同时内存中也只需加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。
特点:
docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
docker commit操作补充
- docker commit提交容器副本使之变成一个新的镜像。(容器再次变成镜像,用于下次满足自己需求)
- docker commit -m=“提交的描述信息” -a=“作者” 容器ID要创建的目标镜像名:[标签名]
- 案例演示
- 从Hub上下载tomcat镜像到本地并成功运行
docker run -it -p 8088:8080 tomcat
-p 主机端口:docker容器端口
-P 随机分配端口
-i 交互
-t 新的伪终端
docker run -it P tomcat ##随机分配一个端口
- 故意删除上一步镜像生产tomcat容器的文档
进入到tomcat中,删除webpons中的docs
- 也即当前的tomcat运行实例是一个没有文档内容的容器,以它为模板commit一个没有docs的tomcat新镜像atguigu/tomcat02
docker commit -a="zzyy" -m="del tomcat docs" 容器ID atguigu.tomcat:02标签(tag)
eg:docker commit -a='zzyy' -m="tomcat without docs" 容器ID atguigu/mytomcat:1.2
- 启动我们的新镜像并于原来的对比
启动atguigu/tomcat02,他没有docs
新启动原来的tomcat,它有docs
后台访问tomcat,前台不显示日志
docker run -d -p 6666:8080 tomcat
6.Docker容器数据卷(移动硬盘)
是什么?
Docker的理念:
- 将运用与运行的环境打包形成容器运行,运行可以伴随着容器,但是我们对数据的要求希望是持久化的
- 容器之间希望有可能共享数据
Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据作为镜像的一部分保存下来,那么当容器删除后,数据也就没有了。、
为了能保存数据在docker中我们使用卷
一句话,有点类似我们Redis里面的rdb和aof文件
干什么?
- 容器的持久化
- 容器间继承+共享数据
卷就是目录或者文件,卷的设计目的就是==数据的持久化,==完全独立于容器的生存周期。
特点:
- 数据卷可在容器之间共享或重用数据
- 卷中的更改可以直接生效
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷的生命周期一直持续到没有容器使用它为止
数据卷(在容器内添加)
直接命令添加(容器和宿主机之间数据可以进行共享)
docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
##eg:-v在这里有创建的意思
docker run -it -v /myDataVolumeContainer:/dataVolumeContainer 镜像名
查看数据卷是否挂在成功 docker inspect 容器ID
容器和宿主机之间数据共享
容器停止退出后,主机修改后数据是否同步,---再次同步,登录该容器,内容实现同步
命令(带权限) docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
## 上条命令代表着只能主机创建修改文件,容器只有看的权限,而没有修改或者新建文件的权限
DockerFile添加
- 根目录下新建mydocker文件夹并进入
cd /
mkdir mydocker
cd /mydocker
- 可在dockerfile中使用VOLUME指令来给镜像添加一个或多个数据卷
VOLUME["/dataVolumeContainer1","/dataVolumeContainer2","/dataVolumeContainer3"]
说明:
-
出于可移植和分享的考虑,用-v主机目录:容器目录这种方法不能够直接在Dockerfile中实现。
-
由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有的宿主机上都存在这样的特定目录
- File构建
- build后生成镜像—获得一个新镜像zzyy/centos
docker build -f /mydocker/docker.file -t zzyy/centos . ##一定要有顿号
新建好了镜像
[root@localhost mydocker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
zzyy/centos latest bd54ca6c896d About a minute ago 209MB
此时运行这个zzyy/centos镜像就会产生上述的两个/dataVolumeContainer1,"/dataVolumeContainer2"这两个卷
- run容器
[root@localhost mydocker]# docker run -it zzyy/centos
[root@7939b35b9c37 /]# ls
bin dev lib media proc sbin tmp
dataVolumeContainer1 etc lib64 mnt root srv usr
dataVolumeContainer2 home lost+found opt run sys var
- 通过上述步骤,容器内的卷目录地址已经知道
- 对应的主机目录地址在哪?
- 主机对应默认地址
假如没有给定宿主机的绝对目录,docker默认目录
docker inspect 镜像ID
主机再次cd进去可以发现共享的目录
[root@localhost _data]# cd /var/lib/docker/volumes/feb47845229701f739516f6d0dd15a976c02b734a9effc1b513675fd4a1220a7/_data
[root@localhost _data]# ls
containt01.txt
注意
假如新建容器卷之后,发现自己不能写,出现了报错
比如:
7. 数据卷容器
是什么?
命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器。
通俗点:活动硬盘上面挂活动硬盘,实现数据的传输依赖
容器之间传递共享
先启动一个父容器dc01——在dataVolumeContainer2新增内容
481 docker run -it --name dc01 zzyy/centos
484 docker run --name=dc02 --volume-from dc01 zzyy/centos
dc02/dc03继承自dc01
–volumes-from
命令——dc02/dc03分别在dataVolumeContainer2各自新增内容
486 docker run -it --name=dc02 --volumes-from dc01 zzyy/centos
487 docker ps
488 docker run -it --name=dc03 --volumes-from dc01 zzyy/centos
回到dc01可以看到02/03各自添加的都能共享了
[root@localhost ~]# docker attach dc01
[root@132bf3814a05 dataVolumeContainer2]# ls
dc01_add.txt dc02_add.txt dc03_add.txt
删除dc01,dc02修改后dc03可否访问
[root@localhost ~]# docker rm -f dc01
[root@localhost ~]# docker attach dc02
[root@5f1fa8b5692f dataVolumeContainer2]# ls
dc01_add.txt dc02_add.txt dc03_add.txt
[root@5f1fa8b5692f dataVolumeContainer2]# touch dc02_update.txt
[root@5f1fa8b5692f dataVolumeContainer2]# ls
dc01_add.txt dc02_add.txt dc02_update.txt dc03_add.txt
## 以访问,虽然删除了父卷,但没有受到影响
删除dc02后dc03可否访 问
[root@localhost /]# docker attach dc03
[root@9922565eefd9 dataVolumeContainer2]# ls
dc01_add.txt dc02_add.txt dc02_update.txt dc03_add.txt
[root@9922565eefd9 dataVolumeContainer2]# touch dc03_update.txt
[root@9922565eefd9 dataVolumeContainer2]# ls
dc01_add.txt dc02_add.txt dc02_update.txt dc03_add.txt dc03_update.txt
新建dc04继承dc03后再删除dc03
[root@localhost ~]# docker run -it --name=dc04 --volumes-from dc03 zzyy/centos
[root@3bfa66034811 /]# cd /dataVolumeContainer2
[root@3bfa66034811 dataVolumeContainer2]# ls
dc01_add.txt dc02_add.txt dc02_update.txt dc03_add.txt dc03_update.txt
[root@3bfa66034811 dataVolumeContainer2]# touch dc04_add.txt
[root@3bfa66034811 dataVolumeContainer2]# ls
dc01_add.txt dc02_update.txt dc03_update.txt
dc02_add.txt dc03_add.txt dc04_add.txt
[root@localhost ~]# docker rm -f dc03
dc03
[root@localhost ~]# docker attach dc04
[root@3bfa66034811 dataVolumeContainer2]# ls
dc01_add.txt dc02_update.txt dc03_update.txt
dc02_add.txt dc03_add.txt dc04_add.txt
## 父进程不会影响紫禁城的操做和读取
结论:容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止
8. DockerFile解析
是什么?
Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本
构建三步骤:
- 编写Dockerfile文件
- docker build
- docker run
文件什么样? ()
编写要求:
- 手动编写一个dockerfile文件,当然,必须要符合file的规范有这个文件后,
- 有这个文件后,直接docker build命令执行,获得一个自定义的镜像run
- run
以centos为例,dockerfile
FROM scratch
ADD centos-7-x86_64-docker.tar.xz /
LABEL \
org.label-schema.schema-version="1.0" \
org.label-schema.name="CentOS Base Image" \
org.label-schema.vendor="CentOS" \
org.label-schema.license="GPLv2" \
org.label-schema.build-date="20201113" \
org.opencontainers.image.title="CentOS Base Image" \
org.opencontainers.image.vendor="CentOS" \
org.opencontainers.image.licenses="GPL-2.0-only" \
org.opencontainers.image.created="2020-11-13 00:00:00+00:00"
CMD ["/bin/bash"]
Dockerfile构建过程解析
Dockerfile内容基础知识
- 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
- 指令按照从上到下,顺序执行
- 表示注释 #
- 每条指令都会创建一个新的镜像层,并对镜像进行提交
Docker执行Dockerfile的大致流程
- docker从基础镜像运行一个容器
- 执行一条指令并对容器作出修改
- 执行类似docker commit的操作提交一个新的镜像层
- docker再基于刚提交的镜像运行一个新容器
- 执行dockerfile中的下一条指令直到所有指令都执行完成
- Dockerfile 需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;
- Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行Docker镜像时,会真正开始提供服务;
- Dockers容器,容器是直接提供服务的。
DockerFile体系结构(保留字指令)
- FROM 基础镜像,当前新镜像是基于哪个镜像的
- MAINTAINER 镜像维护者的姓名和邮箱地址
- RUN 容器构建时需要运行的命令
- EXPOSE 当前容器对外暴露出的端口
- WORKDIR 指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点
- ENV 用来在构建镜像过程中设置环境变量
- ADD 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
- COPY 类似ADD,拷贝文件和目录到镜像中。
将从构建上下文目录中<源路径>文件/目录复制到新的一层的镜像内的<目标路径>位置
- VOLUME 容器数据卷,用于数据保存和持久化工作
- CMD 指定一个容器启动时要运行的命令
Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run 之后的参数替换
-
ENTRYPOINT 指定一个容器启动时要运行的命令
ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及参数
-
ONBUILD 当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后 父镜像的onbuild被触发
案例
Base镜像(scratch)
Docker Hub中99%的镜像都是通过在base镜像中安装和配置需要的软件构建出来的
自定义镜像mycentos
-
编写:
- Hub默认CentOS镜像什么情况
因为是mini版的Centos,所以只有kernel
- 默认编写DockerFile文件
- mycentos内容Dockerfile2
vi Dockerfile2
FROM centos MAINTAINER zzyy<zzyy167@126.com> ##作者的信息 ENV MYPATH /usr/local ##设置环境变量 WORKDIR $MYPATH ##默认进来的地址是/usr/local RUN yum -y install vim RUN yum -y install net-tools EXPOSE 80 ##当前容器对外暴露出的端口 CMD echo $MYPATH CMD echo "success----------ok" CMD /bin/bash
-
构建: docker build -t 新镜像名字:TAG .
docker build -f /mydocker/Dockerfile2 -t mycentos:1.3 .
-
运行
docker run -it 新镜像名字:TAG
-
列出镜像的变更历史
docker history 镜像名
CMD/ENTRYPOINT镜像案例
- 都是指定一个容器启动时要运行的命令(相同点)
不同点
- CMD
- Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run 之后的参数替换
- Case tomcat的讲解演示 docker run -it -p 8888:8080 tomcat ls -l
现在docker images发现tomcat根本就没有启动起来,但是ls -l 显示出了tomcat的文件夹,即CMD 最后的一条指令会覆盖前面的指令
- ENTRYPOINT
- docker run 之后的参数会被当作参数传递给ENTRYPOINT,之后形成新的命令组合
- Case
- 制作CMD版可以查询IP信息的容器,
curl命令解释:curl是将下载文件输出到stdout
- 问题,如果我们希望显示HTTP头信息,就需要加上-i参数
- WHY
- 制作ENTRYPOINT版查询IP信息的容器
- 制作CMD版可以查询IP信息的容器,
[root@localhost mydocker]# docker run myip -i
第一个这样会出现报错,因为CMD会覆盖
相当于在后面有执行了CMD -i
覆盖掉原先的
跟在镜像名后面的command,运行时会替换 CMD的默认值
[root@localhost mydocker]# docker run myip2 -i
相当于
ENTRYPOINT [ "curl", "-s". "http://ip.cn" ]变成了
ENTRYPOINT [ "curl", "-s".i "http://ip.cn" ]
ONBUILD案例讲解
vi Dockerfile4
docker build -f /mydocker/Dockerfile4 -t myip_father .
vi Dockerfile5
docker build -f /mydocker/Dockerfile5 -t myip_son .
## 会触发myip_father(onbuild)
自定义镜像Tomcat9
mkdir -p /zzyyuse.mydockerfile/tomcat9
- 在上述目录下
touch c.txt
- 将jdk和tomcat安装的压缩包拷贝进上一步目录
- apache-tomcat-9.0.8.tar.gz
- jdk-8u171-linux-x64.tar.gz
- 在/zzyyuse/mydockerfile/tomcat9目录下新建Dockerfile文件
- 构建
- run
docker run -d -p 9080:8080 myt9 -v /zzyyuse/mydockerfile/tomcat9/test:/usr/local/apache-tomcat-9.0.46/webapps/test -v /zzyyuse/mydockerfile/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0.46/logs --privileged=true zzyytomcat9
- 结合前述的容器卷将测试的web服务test发布
9. Docker 常用安装
总体步骤
- 搜索镜像
- 拉取镜像
- 查看镜像
- 启动镜像
- 停止容器
- 移除容器
安装tomcat
- docker hub上面查找tomcat镜像
- 从docker hub上拉去tomcat镜像到本地
- docker images查看是否有拉取到的tomcat
- 使用tomcat镜像创建容器(也叫运行镜像)
docker search tomcat
docker pull tomcat
docker images
docker run -it -p 8080:8080 tomcat
-p 主机端口:docker容器端口
-P 随机分配端口
-i:交互
-t:终端
安装mysql
753 docker search mysql
754 docker pull mysql:5.6
755 docker images
756 docker ps
757 docker images mysql
758 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
759 docker ps
760 docker exec -it 279d5f55a1c4 /bin/bash
把容器里面的数据导出来,形成在/zzyyuse下的all-databases.sql的一个文件。相当于把数据库彻彻底底的备份出来了
docker exec 容器ID -c 'exec mysqldump --all-databases -uroot -p "123456"' > /zzyyuse/all-databases.sql
安装redis
764 docker search redis
765 docker pull redis:3.2
766 docker images
767 docker run -p 6379:6379 -v /zzyyuse/myredis/data:/data -v /zzyyuse/myredis/conf/redis.conf:/usr/local/etc/redis/redis.conf -d redis:3.2 redis-server /usr/local/etc/redis/redis.conf --appendonly yes
docker exec -it 容器ID redis-cli
10.本地镜像发布到阿里云(push)
本地镜像发布到阿里云流程
镜像的生成方法
- 前面的DockerFile
- 从容器创建一个新的镜像
docker commit [OPTIONS] 容器ID [REPOSITORY[:TAG]]
将本地镜像推送到阿里云
- 本地镜像素材原型(默认1.4=1.44哈)
[root@localhost ~]# docker images mycentos:1.44
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 1.44 3076b0f7a679 6 minutes ago 291MB
- 阿里云开发者平台—https://dev.aliyun.com/search.html
- 创建仓库镜像
- 命名空间
- 仓库名称
- 将镜像推送到registry
管理里面点进去有详细的说明
-
公有云可以查询到
-
查看详情
将阿里云上的镜像下载到本地
docker pull registry.cn-hangzhou.aliyuncs.com/tkk-personal-pace/kk_personal:1.441
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.cn-hangzhou.aliyuncs.com/tkk-personal-pace/kk_personal 1.441 3076b0f7a679 4 hours ago 291MB