Docker
www.docker.com
Docker 是什么?
Docker 是一个开源的应用容器引擎, 基于 Go 语言并遵从 Apache 协议的开源, 让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中, 然后发布到任何流行的 Linux 或 Windows 机器上, 也可以实现虚拟化. 容器是完全使用沙箱机制, 相互之间不会有任何接口.
如果没有 Docker
环境和配置变动, 导致项目等不能简单的部署成功, 我们将需要的配置, 系统, 数据等等整体打包成我们需要的镜像, 简单启动就可以了,
Securely build and share any application, anywhere 一次构建, 处处运行.
虚拟机和容器化的区别?
虚拟机: 整套安装环境的一种解决方案, 它可以在一种操作系统里面运行另一个操作系统, 比如在 Windows 系统里面运行 Linux 系统. 应用程序对此没有感知, 因为虚拟机看上去就和真实的操作系统一模一样, 能够使应用程序, 操作系统和硬件三者之间的逻辑不变, 而对于底层系统来说, 虚拟机就是一个普通文件, 不需要了就删掉.
虚拟机占用的资源多, 步骤多, 启动是分钟级的太慢.
容器化技术: 因为如上的问题, Linux 发展出了另一种虚拟化技术, Linux 容器(Linux Containers 缩写 LXC).Linux 容器不是模拟一个完整的操作系统, 而是对程序进行隔离. 有了容器, 就可以将软件运行所需要的所有资源打包到一个隔离的容器中, 容器和虚拟机不同, 不需要捆绑一整套的操作系统, 只需要软件工作所需要的库资源和设置. 系统因此而变得高效轻量并保证部署在任何环境中的软件都能始终如一的运行.
1 Docker 架构
Docker 包括三个基本概念:
镜像(Image):Docker 镜像(Image), 就相当于是一个 root 文件系统. 比如官方镜像 Ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统.
容器 (Container): 镜像(Image) 和容器 (Container) 的关系, 就像是面向对象程序设计中的类和实例一样, 镜像是静态的定义, 容器是镜像运行时的实体. 容器可以被创建, 启动, 停止, 删除, 暂停等.
仓库(Repository): 仓库可看着一个代码控制中心, 用来保存镜像.
Docker | 面向对象 |
---|---|
镜像 | 类 |
容器 | 对象 |
概念 | 说明 |
---|---|
Docker 镜像 (Images) | Docker 镜像是用于创建 Docker 容器的模板,比如 Ubuntu 系统。 |
Docker 容器 (Container) | 容器是独立运行的一个或一组应用,是镜像运行时的实体。 |
Docker 客户端 (Client) | Docker 客户端通过命令行或者其他工具使用 Docker SDK ( https://docs.docker.com/develop/sdk/ ) 与 Docker 的守护进程通信。 |
Docker 主机 (Host) | 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。 |
Docker Registry | Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub( https://hub.docker.com/ ) 提供了庞大的镜像集合供使用。一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 < 仓库名 & gt;:< 标签 & gt; 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。 |
Docker Machine | Docker Machine 是一个简化 Docker 安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装 Docker,比如 VirtualBox、 Digital Ocean、Microsoft Azure。 |
2 Docker 安装
以 centos7 以上为例.(安装 2019.03 版本)
删除老版本
- yum -y remove docker \
- docker-client \
- docker-client-latest \
- docker-common \
- docker-latest \
- docker-latest-logrotate \
- docker-logrotate \
- docker-engine
安装需要的软件包
yum install -y yum-utils device-mapper-persistent-data lvm2
设置稳定储存库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
更新 yum 软件包索引
yum makecache fast
安装最新版本的 Docker Engine-Community 和 containerd
yum -y install docker-ce docker-ce-cli containerd.io
启动
systemctl start docker
设置开机启动
systemctl enable docker
测试
- # 版本
- docker version
配置阿里云镜像加速
访问阿里云镜像加速器网页
设置密码尽量简单如: docker123
如果觉得不方便可以使用网易云加速, 地址更改如下
- #1
- mkdir -p /etc/docker
- #2
- tee /etc/docker/daemon.JSON <<-'EOF'
- {
- "registry-mirrors": ["http://hub-mirror.c.163.com"]
- }
- EOF
- #3
- systemctl daemon-reload
- #4
- systemctl restart docker
hello-world 镜像
docker run hello-world
3 Docker 命令
3.1 帮助命令
docker help
3.2 查看本地镜像
docker images
-a: 显示所有的镜像
-q: 仅显示 id
REPOSITORY | 镜像仓库源 |
---|---|
TAG | 镜像标签 |
IMAGE ID | 镜像 ID |
CREATED | 镜像创建时间 |
SIZE | 镜像大小 |
同一个 REPOSITORY(仓库源)可以有多个 TAG, 代表这个仓库源的不同版本, 使用 REPOSITORY:TAG 来定义不同的镜像.
如果不指定一个镜像的版本标签, 例如: 使用 hello-world,docker 将默认使用 hello-world:latest 镜像
3.3 查询镜像
docker search 需要的镜像
去 https://hub.docker.com / 上去搜索需要的软件, 经常搭配 - s 参数查询点赞数比较高的镜像
3.4 下载镜像
docker pull 需要的镜像: 需要的版本 tag
3.5 删除镜像
# 删除单个
docker rmi -f 镜像 ID
# 删除多个
docker rmi -f 镜像名 1:TAG 镜像名 2:TAG
- # 删除全部
- docker rmi -f ${
- docker images -qa
- }
3.6 查看容器
docker ps
-a: 显示所有的容器
-l: 显示最近一条容器
-n: 显示最近几条容器
-q: 仅显示 id
3.7 新建启动停止容器
# 新建容器并启动, 如果没有镜像, 会先去 hubdocker 上 pull 镜像
docker run 可选参数 镜像名(或 ID)
# 重启容器
docker restart 容器名(或 ID)
# 停止容器 (普通<==> 强制)
docker stop 容器名(或 ID) <==> docker kill 容器名(或 ID)
# 启动之前创建的容器
docker start 容器名(或 ID)
# 删除之前创建的容器 <==> 批量
docker rm -f 容器 ID <==> docker ps -aq | xargs docker rm
-d: 守护式后台运行容器, 并返回容器 ID(如使用 tomcat)
-v: 数据卷, 指定主机的某个目录为容器的某个目录(如使用 tomcat-> /root/tomcat/:/usr/local/tomcat/webapps/)
-i: 交互式运行容器, 通常 - t 一起使用(如使用 Linux 中的 Linux)
-t: 为容器重新分配一个伪输入终端, 通常与 - i 一起使用(如使用 Linux 中的 Linux)
--name="新容器名字": 为容器指定一个名称
-P: 随机端口映射
-p: 指定端口映射, 有以下 4 种格式
- ip:hostPort:containerPort
- ip::containerPort
- hostPort:containerPort
- containerPort
3.7.1 守护式例子
- # 新建启动容器
- docker run --name="tomcat1" -dp 8888:8080 tomcat:8.0.52
3.7.2 互交式例子
- #1 新建启动容器, 如下图中目录变更为容器 ID
- docker run --name='centos1' -it CentOS
#2 退出容器
exit -->容器停止退出
ctrl+p+q -->容器不停止退出(注意有先后顺序)
#3 进入一个运行的容器
docker exec -it 容器名(或 ID) /bin/bash
3.8 提交容器
docker commit -a='作者' -m='修改内容' 容器名(或 ID) 容器前缀 / 容器名: TAG 号
使用上面守护式例子继续
- # 进入容器目录
- docker exec -it tomcat1 /bin/bash
- # 替换 index.jsp 内容
- cat> webapps/ROOT/index.jsp <<EOF
- Hello Tomcat
- EOF
- # 提交容器
- docker commit -a='Heaton' -m='my tomcat test' tomcat1 heaton/tomcat:0.0.1
- # 删除现有的运行容器
- docker rm -f $(docker ps -q)
- # 运行之前自己构建的镜像容器
- docker run --name="tomcat1" -dp 8888:8080 heaton/tomcat:0.0.1
3.9 上传镜像
选择阿里云或者 hub, 如下是阿里云的上传方式
- # 登录阿里云 docker 仓库, 输入密码
- dockerlogin --username=70xx@qq.com registry.cn-hangzhou.aliyuncs.com
- # 标记 tag
- docker tag b60d74c216b8 registry.cn-hangzhou.aliyuncs.com/docker-tzy/rep1:0.0.1
- # 上传
- docker push registry.cn-hangzhou.aliyuncs.com/docker-tzy/rep1:0.0.1
4 容器数据卷
Docker 容器产生的数据, 如果不通过 commit 生成新的镜像, 持久化, 那么容器删除以后, 数据就没有了.
为了能保存数据在 docker 中我们使用数据卷.
数据卷可以在容器之间共享或重用数据
卷中的更改可以直接生效
数据卷中的更改不会包含在镜像的更新中
数据卷的生命周期一直持续到没有容器使用它为止
docker inspect 容器 ID --> 返回 Docker 对象的信息(查看挂载情况)
4.1 例 1(命令 - v)
- # 创建可读可写
- docker run -it -v /my_root:/my_docker CentOS
- # 创建可读不可写(Read-only)
- #docker run -it -v /my_root:/my_docker:ro CentOS
- # 进入绑定文件夹, 主机建立新文件
- touch root.txt
- # 进入绑定文件夹, 容器修改文件
- echo "docker add"> root.txt
- # 停止容器, 主机修改文件
- echo "root add"> root.txt
- # 在重新启动容器
- docker start -i 34fe34e36ada
4.2 例 2(DockerFile)
- # 创建 Dockerfile 文件 VIM dockerFile, 写入如下内容
- # 效果为 docker run -it -v /my_root:/my_docker CentOS
- FROM CentOS
- VOLUME ["my_docker1","my_docker2"]
- CMD echo "success"
- CMD /bin/bash
- # 构建镜像
- docker build -f /Dockerfile -t mybuild/CentOS:0.0.1 .
- # 运行, 发现有 2 个容器卷
- docker run -it mybuild/CentOS:0.0.1
如例 1 进行数据卷测试, 发现数据共享
4.3 例 3(volumes-from)
容器间数据共享
- # 运行容器 1
- docker run -it --name docker1 mybuild/CentOS:0.0.1
- # 运行容器 2
- docker run -it --name docker2 --volumes-from docker1 mybuild/CentOS:0.0.1
- # 运行容器 3
- docker run -it --name docker3 --volumes-from docker2 mybuild/CentOS:0.0.1
如例 1 进行数据卷测试
5 Dockerfile
Dockerfile 是用来构建 Docker 镜像的构建文件, 是由一系列命令和参数构成的脚本.
Java | HelloWord.java | HelloWord.class |
---|---|---|
Docker | images | DockerFile |
基础注意点
每条保留字指令必须为大写字母且后面需要更至少一个参数
指令从上到下循序执行
# 为注释
每条指令都会创建一个镜像层且对镜像进行提交
执行流程
docker 从基础镜像运行一个容器
执行一条指令并对容器做出修改
执行类似 commit 操作提交一个新的镜像层
再基于刚提交的镜像运行一个新容器
继续执行 dockerfile 中的下一条指令, 循环制所有指令完成
保留字
FROM | 基础镜像, 当前镜像是基于那个镜像的。 |
---|---|
MAINTAINER | 作者 邮箱。 |
RUN | 容器构建时需要运行的命令。 |
EXPOSE | 暴露端口号 启动容器的时候还需使用 –p 指定端口。 |
WORKDIR | 指定在创建容器后, 终端默认登录后进来的工作目录, 一个落脚点, 默认根目录,通常绝对路径,CMD ENTRYPOINT 都会在这个目录下执行。 |
ENV | 构建镜像的过程中设置环境变量, 构建和运行时都有效可以使用 $ 引用。 |
ADD | 将宿主机目录下的文件拷贝到镜像且会自动处理 URL 和 解压 tar 压缩包。ADD 支持 URL 和 COPY 后解压缩包。 |
COPY | 拷贝文件和目录到镜像中,将从构建上下文目录中 & lt; 源路径 & gt; 的文件 / 复制到新的一层镜像内 & lt; 目标路径 & gt; 的位置。一般都用 ADD |
VOLUME | 容器数据卷, 数据保存和持久化。 |
USER | 指定该镜像由什么用户运行 不指定由 root 运行。 |
CMD | 指定容器启动时要运行默认的命令,Dockerfile 中可以有多个 cmd , 但只有最后一个生效。CMD 会被 docker run 之后的参数替换。 |
ENTERPOINT | 指定容器启动时要运行的命令。ENTERPOINT docker run 之后的参数会被当做参数传递给 ENTRYPOINT , 之后形成新的命令组合,追加 |
ONBUILD | 触发器, 当构建一个被继承的 dockerfile 时运行命令, 父镜像在被子继承后的父镜像的 onbuild 被触发。 |
CMD 与 ENTERPOINT 区别
CMD
如 tomcat 中, 在 Dockerfile 最后有 CMD ["catalina.sh","run"], 意思为启动容器后执行 tomcat 启动命令, 如果使用命令 docker run -it -p 8888:8080 tomcat:8.0.52 ls -l, 就会将 ls -l 这个查询指令通过参数传给 CMD, 这时容器运行就不会启动, 而是查询目录.
ENTERPOINT
如果是 CMD ["ls","-l"]指令, 我们需要在加入一个 -a 的参数, 那么 CMD 将不能完成在构建镜像后增加参数, 这个时候可以把指令改成 ENTERPOINT ["ls","-l"] , 我们就可以在后面继续追加参数而不会替换原来的参数.
5.1 例 1 拓展 CentOS
自建 CentOS
修改运行后路径
使之可以使用 VIM,ifconfig 等命令
创建 Dockerfile 文件, 加入如下内容
- # 继承自 CentOS
- FROM CentOS
- # 作者 - 邮箱
- MAINTAINER Heaton
- # 创建环境变量 mypath
- ENV mypath /usr/local/src
- # 指定创建容器后终端路径
- WORKDIR $mypath
- # 构建容器时运行命令
- RUN yum -y install VIM
- RUN yum -y install.NET-tools
- # 暴露端口号
- EXPOSE 80
- # 容器启动时要运行默认的命令
- CMD echo "success"
- CMD /bin/bash
构建镜像
docker build -f /root/Dockerfile -t heaton/CentOS:0.0.1 .
运行镜像
docker run -it heaton/CentOS:0.0.1
5.2 例 2 触发器
创建 Dockerfile1 文件, 加入如下内容
- # 继承自 CentOS
- FROM CentOS
- ONBUILD RUN echo "father onbuild----------------------------->"
构建
docker build -f /root/Dockerfile1 -t heaton/father .
创建 Dockerfile2 文件, 加入如下内容
- # 继承自 heaton/father
- FROM heaton/father
- RUN echo "son------>success"
构建
docker build -f /root/Dockerfile2 -t heaton/son .
来源: https://www.cnblogs.com/ttzzyy/p/12575742.html