Docker概述
- 概念:容器虚拟化技术,系统平滑移植,解决了运⾏环境和配置问题的软件容
器,⽅便做持续集成并有助于整体发布的容器虚拟化技术
- 意义:Docker的出现使得Docker得以打破过去程序即应⽤的观念,透过镜像将
作业系统核⼼除外,运作应⽤程序所需要的系统环境,由下⽽上打包,达到应
⽤程序跨平台间的⽆缝接轨运作
- ⽬标:Docker的主要⽬标就是通过对应⽤组件的封装、分发、部署、运⾏等⽣
命周期的管理,使⽤户的APP及其运⾏环境能够做到"⼀次镜像,处处运⾏",
只需要⼀次配置好环境,换到别的机⼦上就可以⼀键部署好,⼤⼤简化了操
作。
- ⾯试题:容器与虚拟机⽐较
a. 传统虚拟机技术
虚拟机就是带环境安装的⼀种解决⽅案,它可以在⼀种操作系统⾥⾯运⾏另⼀
种操作系统,⽐如在Window10系统⾥⾯运⾏Linux系统CentOS7。应⽤程序对此
毫⽆感知,因为虚拟机看上去跟真实系统⼀模⼀样,⽽对于底层系统来说,虚拟机
就是⼀个普通⽂件,不需要了就删除,对其他部分毫⽆影响。这类虚拟机完美的运
⾏了另⼀套系统,能够使应⽤程序、操作系统和硬件三者之间的逻辑不变。
虚拟机的缺点:1.资源占⽤多 2.冗余步骤多3.启动慢
b. 容器虚拟化技术
Linux容器是与系统其他部分隔离开的⼀系列进程,从另⼀个镜像运⾏,并由该
镜像提供⽀持进程所需的全部⽂件,容器提供的镜像包含了应⽤的所有依赖性项,
因⽽在从开发到测试再到⽣产的整个过程中,都具有可移植性和⼀致性
Linux容器不是模拟⼀个完整的操作系统⽽是对进程进⾏隔离。有了容器就可以
将软件运⾏所需的所有资源打包到⼀个隔离的容器中。容器与虚拟机不同,不需要捆绑⼀整套操作系统,只需要软件⼯作所悟的库资源和设置,系统因此⽽变得⾼效轻量并保证部署在任何环境中的软件都能始终如⼀地运⾏。
Docker容器是在操作系统层⾯上实现虚拟化,直接复⽤本地主机的操作系统,
⽽传统虚拟机则是在硬件层⾯实现虚拟化。与传统的虚拟机相⽐,Docker优势体现在启动速度快、占⽤体积⼩。
Docker安装
-
docker官⽹:http://docker.com
-
Docker Hub官⽹:https://hub.docker.com/
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo systemctl start docker
ps - ef|grep docker
- 安装步骤
a. 确定你是centOS7及以上版本
cat /etc/redhat-release
b. 卸载旧版本
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
c. yum安装gcc相关
yum -y install gcc
yum -y install gcc-c++
d. 安装需要的软件包
yum install -y yum-utils
e. 设置stable镜像仓库 – 不要⽤官⽹的镜像仓库,那个是国外的,⽤国内的镜像仓库速度⽐较快
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
f. 更新yum软件包索引
yum makecache fast
g. 安装DOCKER CE
yum -y install docker-ce docker-ce-cli containerd.io
h. 启动docker
systemctl start docker
i. 测试
yum -y install gcc
yum -y install gcc-c++
j. 卸载
systemctl stop docker
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
- 阿⾥云镜像加速
直接打开⽹址,点击控制台,选择容器镜像服务,选择镜像⼯具,获取镜像加速器地址,粘贴脚本直接执⾏。
**https://promotion.aliyun.com/ntms/act/kubernetes.html
Docker基本组成
- 三要素:镜像文件、容器实例、仓库
- 镜像文件,image文件生成的容器实例,本身也是一个文件,称为镜像文件
- 容器实例,一个容器运行一种服务,当我们需要的时候,就可以通过docker客户端创建一个对应的运行实例,也就是我们的容器
- 仓库就是放一堆镜像的地方,我们可以把镜像发布到仓库中,需要的时候再从仓库中拉下来就可以了。
- 镜像文件:Docker镜像就是一个只读的模板,Docker镜像可以用来创建Docker容器,一个镜像可以创建很多容器。Docker镜像文件类似于Java的类模板,而docker容器实例类似于java中new出来的实例对象。
- 容器实例:从面向对象的角度看,Docker利用容器独立运行的一个或一组应用,应用程序或服务运行在容器里面,容器就类似于一个虚拟化的运行环境,容器是用镜像创建的运行实例,容器是镜像运行时的实体,容器为镜像提供了一个标准的和隔离的运行环境,它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。
- 仓库:是集中存放镜像文件的场所
- Docker公司提供的官方仓库被称为Docker Hub(https://hub.docker.com/),存放各种镜像模板的地方。
Docker底层原理
- Docker有着比虚拟机更少的抽象层,由于docker不需要跟虚拟机一样实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源,因此在CPU、内存利用率上docker将会在效率上有明显优势。
- docker利用的是宿主机的内核,而不需要加载操作系统OS内核
Docker容器 | 虚拟机VM | |
---|---|---|
操作系统 | 与宿主机共享OS | 宿主机OS上运行虚拟机OS |
存储大小 | 镜像小,便于存储与传输 | 镜像庞大 |
运行性能 | 几乎无额外性能损失 | 操作系统额外的CPU、内存消耗 |
移植性 | 轻便、灵活,适用于Linux | 笨重,与虚拟化技术耦合度高 |
硬件亲和性 | 面向软件开发者 | 面向硬件运维者 |
部署速度 | 快速,秒级 | 较慢,10s以上 |
Docker常⽤命令
- 帮助启动类命令
//启动docker
systemctl start docker
//停止docker
systemctl stop docker
//重启docker
systemctl restart docker
//查看docker状态
systemctl status docker
//开机启动
systemctl enable docker
//查看docker概要信息
docker info
//查看docker总体帮助文档
docker --help
//查看docker命令帮助文档
docker 具体命令 --help
- 镜像命令
//列出本地主机上的镜像,参数说明:
//REPOSITORY表示镜像的仓库源
//TAG表示镜像的标签版本号
//IMAGE ID表示镜像ID
//CREATED表示镜像的创建时间
//SIZE表示镜像大小
//同一仓库源可以有多个TAG版本,代表这个仓库源的不同版本,我们使用REPOSITORY:TAG来定义不同的镜像
// -a:列出本地所有的镜像
// -q:只显示镜像ID
docker images
//寻找仓库中的hello-world镜像
docker search helllo-world
//后面没有加标签版本号TAG的话,默认是最新版本
docker pull hello-world
//查看镜像/容器/数据卷所占的空间
docker system df
//删除镜像文件
docker rmi 某个xxx镜像名字ID
//强制删除镜像文件
docker rmi -f 某个xxx镜像名字ID
//删除全部
docker rmi -f $(docker images -qa)
虚悬镜像:仓库名、标签都是<none>的镜像
- 容器命令
//新建+启动容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
//举例:以交互模式启动一个容器,在容器内执行/bin/bash命令
// -i:交互式操作
// -t:终端
// ububtu:ubuntu镜像
// /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式Shell,因此用的是/bin/bash
// 要退出终端,直接输入exit
docker run -it ubuntu /bin/bash
[OPTIONS]常用说明
--name="容器新名字" --> 为容器指定一个名称
-d:后台运行容器并返回容器ID,也即启动守护式容器(后台运行)
-i:以交互模式运行容器,通常与-t同时使用
-t:为容器重新分配一个伪输入终端,通常与-i同时使用
也即启动交互式容器(前台有伪终端,等待交互)
-P:随机端口映射,大写P
-p:指定端口映射,小写p
端口映射 -p 8080:80
//-a 列出当前所有正在运行的容器+历史上运行过的
//-l 显示最近创建的容器
//-n 显示最近n个创建的容器
//-q 静默模式,只显示容器编号
docker ps [options]
//run进去容器,exit退出,容器停止
1.exit
//run进去容器,ctrl+p+q退出,容器不停止
2.ctrl+p+q
docker start 容器ID或者容器名
docker restart 容器ID或者容器名
docker stop 容器ID或者容器名
docker kill 容器ID或者容器名
docker rm 容器ID
docker rm -f $(docker ps -a -q)
- 容器命令 - 重要
有镜像才能创建容器,这是根本前提!!!
在大部分场景下,我们希望docker的服务是在后台运行的,我们可以通过 -d 指定容器的后台运行模式
docker run -d 容器名
docker logs 容器ID
docker inspect 容器ID
docker top 容器ID
//启动类容器后退出,然后想重新进去,就用这个命令
docker exec -it 容器ID bashShell
//第二种方式
docker attach 容器ID
两种方式的区别:
exec是在容器中打开新的终端,并且可以启动新的进程用exit退出,不会导致容器的停止
attach直接进入容器启动命令的终端,不会启动新的进程用exit退出,会导致容器的停止
容器 -> 主机
docker cp 容器ID:容器内路径 目的主机路径
export导出容器的内容流作为一个tar归档文件[对应import命令]
import从tar包中的内容创建一个新的文件系统再导入为镜像[对应export]
docker export 容器ID > 文件名.tar
cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号
Docker镜像分层
- 镜像:是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件
- 只有通过这个镜像文件才能生成Docker容器实例(类似于Java中new出来一个对象)
- Docker分层镜像:Union文件系统是一种分层、轻量级并且高性能的文件系统,支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。 Union文件系统是Docker镜像的基础,镜像可以通过分层来进行继承,基于基础镜像,可以制作各种具体的应用镜像。
- 重点理解:Docker镜像层都是只读的,容器层是可写的,当容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常被称作容器层,容器层之下的都是镜像层
- Docker中的镜像分层,支持通过扩展现有镜像,创建新的镜像。类似于java继承于一个Base基础类,自己再按需扩展。新镜像是从base镜像一层一层叠加生成的,每安装一个软件,就在现有镜像的基础上增加一层。
Docker commit
- docker commit 提交容器副本使之称为一个新的镜像
docker commit -m = "提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
//举例
docker commit -m="安装vim镜像" -a="zyt" 容器ID 要创建的目标镜像名:1.0
- 小总结:Docker中的镜像分层,支持通过扩展现有镜像,创建新的镜像。类似java继承于一个Base基础类,自己再按需扩展,新镜像是从base镜像一层一层叠加生成的,每安装一个软件,就在现有镜像的基础上增加一层。
docker仓库
- 存放到阿里云仓库:https://cr.console.aliyun.com/repository/cn-hangzhou/zyt-private/myubuntu/details
- 存放到Docker Hub地址:https://hub.docker.com/,Docker Registry是官方提供的工具,可以用于构建私有镜像仓库
容器数据卷
- 有个坑 — 容器卷记得加入
--privileged=true
Docker挂载主机目录访问如果出现cannot open directory .: Permission denied
解决办法:在挂载目录后多加一个–privileged=true参数即可
如果是CentOS7安全模块会比之前系统版本加强,不安全的会先禁止,所以目录挂载的情况被默认为不安全的行为,在SELinux里面挂载目录被禁止掉了,如果要开启,我们一般使用–privileged=true命令,扩大容器的权限解决挂载目录没有权限的问题,也即使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限。
- 定义:使用docker容器的时候,会产生一系列的数据文件,这些数据文件在删除docker容器时是会消失的,但是其中产生的部分内容是希望能够把它保存起来另作用途的,Docker将应用与运行环境打包成容器发布,程序员希望在运行过程中产生的数据是可以持久化的,而且容器之间我们希望能够实现数据共享。一般来说,docker容器数据卷可以看成常用的U盘,它存在于一个或多个的容器中,由docker挂载到容器,但不属于联合文件系统,Docker不会在容器删除时删除其挂载的数据卷。
一句话:有点类似我们Redis里面的rdb和aof文件
- 目的:容器数据卷设计的目的就是数据的持久化,完全独立于容器的生命周期,因此Docker不会在容器删除时删除其挂载的数据卷。
docker run -it --privileged=true -v/宿主机绝对路径目录:/容器内目录 镜像名
- 特点:
-
- 数据卷可在容器之间共享或重用数据
- 卷中的更改可以直接实时生效
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷的生命周期一直持续到没有容器使用它为止
- 宿主 vs 容器之间映射添加容器卷
-
- 直接命令添加
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名
docker run -it -v /宿主机目录:/容器内目录 ubuntu /bin/bash
docker run -it --name myu3 --privileged=true -v /tmp/myHostData:/tmp/myDockerData ubuntu /bin/bash
-
- 查看数据卷是否挂载成功
docker inspect 容器ID
-
- 容器和宿主机之间数据共享
docker修改,主机同步获得
主机修改,docker同步获取
docker容器stop,主机修改,docker容器重启看数据是否同步
- 读写规则映射添加说明
读写(默认)
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:rw 镜像名
默认同上案例,默认就是rw
rw = read + write
只读:容器实例内部被限制,只能读取不能写
/容器目录:ro 镜像名 就能完成功能,此时容器自己只能读取不能写 ,ro = read only
此时如果宿主机写入内容,可以同步给容器内,容器可以读取到。
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
- 卷的继承和共享
容器1完成和宿主机的映射
docker run -it --privileged=true -v /mydocker/u:/tmp --name u1 ubuntu
容器2继承容器1的卷规则
docker run -it --privileged=true --volumes-from 父类 --name u2 ubuntu
本地镜像发布到阿⾥云流程
- 阿里云ECS Docker生态如下图所示:
- 镜像的生成(commit)方法
基于当前容器创建一个新的镜像,新功能增强
docker commit [OPTIONS] 容器ID [REPOSITORY[:TAG]]
OPTIONS说明:
-a :提交的镜像作者;
-m :提交时的说明文字;
- 创建阿里云仓库镜像
- 选择控制台,进入容器镜像服务
- 选择个人实例
- 命名空间
- 仓库名称
- 进入管理界面获得脚本
- 将镜像推送到阿里云
- 管理界面脚本
- 脚本实例
docker login --username=zzyybuy registry.cn-hangzhou.aliyuncs.com
docker tag cea1bb40441c registry.cn-hangzhou.aliyuncs.com/atguiguwh/myubuntu:1.1
docker push registry.cn-hangzhou.aliyuncs.com/atguiguwh/myubuntu:1.1
上面命令是阳哥自己本地的,你自己酌情处理,不要粘贴我的。
- 将阿里云上的镜像下载到本地
docker pull registry.cn-hangzhou.aliyuncs.com/atguiguwh/myubuntu:1.1