基本介绍
Docker出现的原因
我们平时需要关注各种版本的迭代,不同版本环境的兼容问题,可能某个代码在A的系统可以运行,但是在B的系统就无法运行,因为它们的环境配置可能是不一样的,这样就会很麻烦。
:::info
Docker发展迅速的原因是因为它给出了一个标准化的解决方案------系统平滑移植,容器虚拟化技术。
不同主机的环境配置可能都不一样,如果每次换一台机器,我们都要重新配置环境,那么就会很麻烦。软件可不可以带环境安装呢?安装的时候,把原始环境一模一样的复制过来,开发人员利用Docker可以消除协作编码时"在我的机器上可正常工作"的问题
之前在服务器配置一个应用的运行环境,要安装各种软件,比如我们开发一个前后端分离项目,Java/Tomcat/MySQL/JDBC驱动包等。安装和配置这些东西有多麻烦就不说了,它还不能跨平台。假如我们是在 Windows 上安装的这些环境,到了 Linux 又得重新装。况且就算不跨操作系统,换另一台同样操作系统的服务器,要移植应用也是非常麻烦的。
:::
- Docker的出现使得Docker得以打破过去「程序即应用」的观念。透过镜像(images)将作业系统核心除外,运作应用程式程序需要的系统环境,由下而上打包,达到应用程式跨平台间的无缝接轨运作。
- 镜像(Mirroring)是一种文件存储形式,一个磁盘上的数据在另一个磁盘上存在一个完全相同的副本即为镜像。
1.2Docker认识
- · Docker是一个解决了运行环境和配置问题的软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术。
- Docker的主要目标是"Build,Ship and Run Any App,Anywhere",也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运行环境能够做到"一次镜像,处处运行"。只需要一次配置好环境,换到别的机子上就可以一键部署好,大大简化了操作。
- Linux容器技术的出现就解决了这样一个问题,而 Docker 就是在它的基础上发展过来的。将应用打成镜像,通过镜像成为运行在Docker容器上面的实例,而 Docker容器在任何操作系统上都是一致的,这就实现了跨平台、跨服务器。只需要一次配置好环境,换到别的机子上就可以一键部署好,大大简化了操作。
1.3容器和虚拟机的比较
1.3.1传统虚拟技术
虚拟机(virtual machine)就是带环境安装的一种解决方案。
**它可以在一种操作系统里面运行另一种操作系统,比如在Windows10系统里面运行Linux系统CentOS7。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。这类虚拟机完美的运行了另一套系统,能够使应用程序,操作系统和硬件三者之间的逻辑不变。 **
传统虚拟机技术基于安装在主操作系统上的虚拟机管理系统(比如VMWare,VirtualBox),创建虚拟机(虚拟出各种硬件),在虚拟机上安装从操作系统,在操作系统中安装部署各种应用。
虚拟机存在以下几个缺点
- 占用资源多(虚拟机需要启动一个完整的操作系统,这会占用较多的计算资源和存储空间。每个虚拟机需要分配一定的内存、CPU和磁盘空间,这可能导致资源的浪费和效率的降低。)
- 冗余步骤多
- 启动慢
1.3.2容器虚拟化技术
因为虚拟机存在着一些缺点,所以Linux后面发展出了另外一种虚拟技术
- Linux容器(Linux Containers,缩写为 LXC)
- Linux容器是与系统其他部分隔离开的一系列进程,从另一个镜像运行,并由该镜像提供支持进程所需的全部文件。容器提供的镜像包含了应用的所有依赖项,因而在从开发到测试再到生产的整个过程中,它都具有可移植性和一致性。
- Linux 容器不是模拟一个完整的操作系统而是对进程进行隔离。有了容器,就可以将软件运行所需的所有资源打包到一个隔离的容器中。容器与虚拟机不同,不需要捆绑一整套操作系统,只需要软件工作所需的库资源和设置。系统因此而变得高效轻量并保证部署在任何环境中的软件都能始终如一地运行。
- Docker容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统虚拟机则是在硬件层面实现虚拟化,和传统的虚拟机相比,Docker的优点体现在启动块,占用体积小
- 虚拟化,是指通过虚拟化技术将一台计算机虚拟为多台逻辑计算机。在一台计算机上同时运行多个逻辑计算机,每个逻辑计算机可运行不同的操作系统,并且应用程序都可以在相互独立的空间内运行而互不影响,从而显著提高计算机的工作效率。虚拟化使用软件的方法重新定义划分IT资源,可以实现IT资源的动态分配、灵活调度、跨域共享,提高IT资源利用率,使IT资源能够真正成为社会基础设施,服务于各行各业中灵活多变的应用需求。
1.3.3Docker和传统虚拟技术的区别
- 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;
- 容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
- ** 每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。**
1.3.4为什么Docker比虚拟机快
(1)docker有着比虚拟机更少的抽象层
- 由于docker不需要Hypervisor(虚拟机)实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。
- 比如说我们要创建一个新的虚拟机,需要有iso镜像文件,包括软件,硬件,打印机,驱动等我们需要使用的和不需要使用的 ,很齐全,但是有的是我们不需要使用的 ,这样就会导致运行很慢
(2)docker利用的是宿主机的内核,而不需要加载操作系统OS内核
当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。进而避免引寻、加载操作系统内核返回等比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载OS,返回新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了返回过程,因此新建一个docker容器只需要几秒钟。
1.4Docker能解决的问题
- 一次镜像,处处运行
- 能够更加快速的应用交付和部署
- 传统的应用开发完成后,需要提供一堆安装程序和配置说明文档,安装部署后需根据配置文档进行繁杂的配置才能正常运行。Docker化之后只需要交付少量容器镜像文件,在正式生产环境加载镜像并运行即可,应用安装配置在镜像里已经内置好,大大节省部署配置和测试验证时间。
- 更加便捷的升级和扩缩容
- 随着微服务架构和Docker的发展,大量的应用会通过微服务方式架构,应用的开发构建将变成搭乐高积木一样,每个Docker容器将变成一块"积木",应用的升级将变得非常容易。当现有的容器不足以支撑业务处理时,可通过镜像运行新的容器进行快速扩容,使应用系统的扩容从原先的天级变成分钟级甚至秒级。
- 更简单的系统运维
- ** 应用容器化运行后,生产环境运行的应用可与开发、测试环境的应用高度一致,容器会将应用程序相关的环境和状态完全封装起来,不会因为底层基础架构和操作系统的不一致性给应用带来影响,产生新的BUG。当出现程序异常时,也可以通过测试环境的相同容器进行快速定位和修复。**
- 更高效的计算资源利用
- Docker是内核级虚拟化,其不像传统的虚拟化技术一样需要额外的Hypervisor支持,所以在一台物理机上可以运行很多个容器实例,可大大提升物理服务器的CPU和内存的利用率。
Docker安装
官网: docker官网:http://www.docker.com
仓库:Docker Hub(安装Docker镜像的仓库)官网: https://hub.docker.com/
2.1安装前提
- Docker要部署在Linux内核的系统上,所以我们事先要安装Linux环境
- Docker实质上是在已经运行的Linux下制造一个隔离的文件环境
- 目前,CentOS 仅发行版本中的内核支持 Docker。Docker 运行在CentOS 7 (64-bit)上,要求系统为64位、Linux系统内核版本为 3.8以上,这里选用Centos7.x
- 我们可以通过命令来查看当前系统的相关信息
2.2Docker基本组成
镜像(image),容器,仓库是Docker的基本组成
2.2.1镜像
- Docker本身是一个容器运行载体或者称为管理引擎。我们把应用程序和配置依赖打包好形成一个可以交付的运行环境,这一个打包好的运行环境就是镜像文件。只有通过这个镜像文件才可以生成Docker容器实例。
- 镜像是一个只读的模板,可以用来创建Docker容器,一个镜像可以创建很多容器。docker镜像文件类似于Java的类模板,docker容器实例类似于Java中new出来的实例对象
- 镜像文件生成的容器实例,本身也是一个文件,称为镜像文件,同一个镜像文件,可以生成多个同时运行的容器实例。
2.2.2容器
- 容器类似于一个虚拟化的运行环境,容器是用镜像创建的运行实例。容器为镜像提供了一个标准的和隔离运行环境,它可以被启动,开始,停止,删除。每一个容器都是互相隔离的,保证平台的安全性。
- 可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
- 一个容器运行一种服务,当我们需要的时候,就可以通过docker客户端创建一个对应的运行实例,也就是我们所说的容器。
2.2.3仓库
- 仓库是集中存放镜像文件的场所,我们可以把镜像发布到仓库中,需要的时候再从仓库中拉取下来就可以了。
- docker仓库类似于maven仓库存放各种jar包的地方,github仓库,存放各种git项目的地方
- Docker公司提供的官方registry被称为是Docker Hub,存放各种镜像模板的地方
- 仓库有公开仓库和私有仓库两种形式,最大的仓库是Docker Hub(https://hub.docker.com/),存放了数量庞大的镜像来提供给用户下载。国内的公开仓库有阿里云、网易云等。
2.3Docker架构
- Client:客户端,Docker 是一个客户端-服务器(C/S)架构程序。Docker 客户端只需要向 Docker 服务器或者守护进程发出请求,服务器或者守护进程将完成所有工作并返回结果。Docker 提供了一个命令行工具 Docker 以及一整套 RESTful API。你可以在同一台宿主机上运行 Docker 守护进程和客户端,也可以从本地的 Docker 客户端连接到运行在另一台宿主机上的远程 Docker 守护进程。
- DOCKER_HOST:Docker主机
- Docker daemon:Docker守护进程
- Registry:仓库
- Docker 在运行时分为 Docker 引擎(服务端守护进程) 和 客户端工具,我们日常使用各种 docker 命令,其实就是在使用 客户端工具 与 Docker 引擎 进行交互。
- Docker是一个CS结构的系统,Docker守护进程运行在主机上,然后通过socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上容器,容器是一个运行时环境,也就是前面所说的集装箱
2.4Docker安装
官网:
Install Docker Engine on CentOS
2.4.1Centos版本需要在7及以上
2.4.2安装gcc
yum -y install gcc
yum -y install gcc-c++
在这里我们使用设置Docker的存储库来安装
2.4.3使用存储库来安装
2.4.3.1安装软件包
** yum install -y yum-utils**
2.4.3.2设置stable镜像仓库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
2.4.4更新yum软件包索引
yum makecache fast
2.4.5安装Docker引擎
yum install docker-ce docker-ce-cli containerd.io
解决docker安装依赖container-selinux_Menardღ的博客-CSDN博客_container-selinux
2.4.6启动Docker
systemctl start docker
2.4.7查看Docker版本
docker version
2.4.8通过运行映像来验证是否正确安装了 Docker 引擎。hello-world
docker run hello-world
因为本地没有hello-world这个镜像,所以会下载一个hello-world的镜像,并且在容器内运行。当最后输出如上图的那个提示以后,hello world就会停止运行,容器自动停止。
看看运行过程做了什么操作
2.4.9卸载Docker
先停止服务systemctl stop docker
卸载泊坞引擎、CLI、容器化和泊坞窗撰写包:
yum remove docker-ce docker-ce-cli containerd.io
主机上的映像、容器、卷或自定义配置文件不会自动删除。删除所有映像、容器和卷:
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
2.5阿里云镜像加速
开放云原生应用-云原生(Cloud Native)-云原生介绍 - 阿里云
然后点击控制台
mkdir -p /etc/docker
java
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://mf81xcmx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
systemctl daemon-reload
systemctl restart docker
Docker常用命令
3.1帮助启动类命令
功能 | 命令 |
---|---|
启动docker | systemctl start docker |
停止docker | systemctl stop docker |
重启docker | systemctl restart docker |
查看docker状态 | systemctl status docker |
设置主机启动的时候,开启docker | systemctl enable docker |
查看docker概要信息 | systemctl info |
查看docker总体帮助文档 | docker --help |
查看docker命令帮助文档 | docker 具体命令 --help |
3.2镜像命令
3.2.1docker images
docker images 列出本地主机上的镜像
- repository:标识镜像的仓库源
- tag:镜像的标签版本号
- image id:镜像 id
- created:镜像创建时间
- size:镜像大小
- 同一个仓库源可以有多个tag版本,我们可以使用repository:tag来定义不同的镜像,如果我们不指定一个镜像的版本标签,比如我们使用ubuntu,docker将会默认使用ubuntu:latest镜像
可选的参数options说明:
- -a:列出本地所有镜像(含历史映像层)
- -q:只显示镜像id
3.2.2 docker search [options] 镜像名字
搜索镜像
参数说明:
**NAME: **镜像仓库源的名称
**DESCRIPTION: **镜像的描述
**OFFICIAL: **是否 docker 官方发布
**stars: **类似 Github 里面的 star,表示点赞、喜欢的意思。
**AUTOMATED: **自动构建。
OPTIONS说明:
- --limit : 只列出N个镜像,默认25个
- docker search --limit 5 redis
3.2.3 docker pull 镜像名字
拉取某个镜像
- docker pull 镜像名字:tag
- docker pull 镜像名字,如果命令后面没有加上tag的话,那么默认就是拉取最新版,相当于是docker pull 镜像名字:latest
3.2.4 docker system df 查看镜像/容器/数据卷所占的空间
3.2.5 docker rmi 镜像名字id (删除某个镜像)
docker rmi -f 镜像id,可以删除单个镜像
docker rmi -f 镜像名1:tag 镜像名2:tag,可以删除多个镜像
docker rmi -f $(docker images -qa),可以删除全部镜像
3.2.6 docker虚悬镜像是什么
仓库名和标签都是none的镜像是虚悬镜像
3.3容器命令
- 镜像是模板,容器才是真正干活的实例对象,由镜像来生成一个个的容器实例。
- 有镜像才可以创建容器,这是根本前提(下载Centos或者Ubuntu镜像来进行演示)
- 本次以Ubuntu来演示,如果大家没有这个镜像,可以通过docker pull ubuntu来拉取这个镜像
3.3.1 新建+启动命令
docker run [OPTIONS] **IMAGE **[COMMAND] [ARG...]
doker是一个开源的应用容器引擎,说简单一点就是可以打包程序和运行环境,把环境和程序一起发布的容器。当你需要发布程序时,你可以使用doker将运行环境一起发布,其他人拿到你的程序后,可以直接运行,避免出现一次编译到处调试的尴尬局面。
docker为什么需要进行端口映射
docker容器在运行的时候,如果不指定端口映射参数(不配置宿主机器与虚拟机的端口映射),在容器外部是无法通过网络来访问容器内的网络应用和服务的(外部程序是无法访问虚拟机的,因为没有端口)。为了解决这个问题,就需要进行doker端口映射的设置。
docker通过端口绑定主机系统的接口,允许非本地客户端访问容器内部运行的服务。为了简便的使得容器间通信,docker提供了这种连接机制。
使用镜像ubuntu:latest以交互模式启动一个容器,在容器内执行/bin/bash命令
- ubuntu:ubuntu是镜像
- /bin/bash:放在镜像名后面的是命令,在这里我们希望有一个交互式shell,所以用的是/bin/bash。
- 如果要退出终端。直接输入exit
3.3.2 列出当前所有正在运行的容器
docker ps [OPTIONS]
关于OPTIONS说明:
-a :列出当前所有正在运行的容器+历史上运行过的
-l :显示最近创建的容器。
-n:显示最近n个创建的容器。
-q :静默模式,只显示容器编号。
3.3.3 退出容器
退出容器有两种方式
- exit 这种方式,容器会停止
- ctrl+p+q 这种方式,容器不会停止
3.3.4 重启容器
docker restart 容器id或者容器名字
3.3.5 停止容器
docker stop 容器id或者容器名字
3.3.6 强制停止容器
docker kill 容器id或者容器名字
3.3.7 删除已经停止的容器
docker rm 容器id
如果想要一次性删除多个容器实例的话,有下面两种方法
- docker rm -f $(docker ps -a -q)
- docker ps -a -q | xargs docker rm
3.4和容器命令有关的一些重要命令
3.4.1启动守护式容器(后台服务器)
一般情况下,我们都希望docker的服务是在后台运行的,我们可以通过**-d**来指定容器的后台运行模式
docker run -d 容器名
在这里,我以redis来进行演示,我们需要先下载一个redis镜像,然后才可以创建容器
接下来演示redis的前后台启动
前台交互式启动
docker run -it redis
后台守护式启动
docker run -d redis
3.4.2查看容器日志
docker logs 容器id
3.4.3查看容器内运行的进程
docker top 容器id
3.4.4查看容器内部细节
docker inspect 容器id
3.4.5进入正在运行的容器并以命令行交互
3.4.5.1命令演示
有两种方法可以重新进入到dockr容器
- docker exec -it 容器id
- docker attach 容器id
演示:
3.4.5.2docker exec 和docker attach区别
attach直接进入容器启动命令的终端,不会启动新的进程,用exit退出,会导致容器的停止
exec是在容器中打开新的终端,并且可以启动新的进程,用exit退出,不会导致容器的停止。
推荐大家使用docker exec命令,因为退出容器终端并不会导致容器的停止。
一般来说,我们用-d后台启动的程序,然后再用exec进入到容器实例中。
3.4.6从容器内拷贝文件到主机上
docker cp 容器ID:容器内路径 目的主机路径
3.4.7容器的导入导出
- export 导出容器的内容留作为一个tar归档文件[对应import命令]
- 演示:docker export 容器ID > 文件名.tar
- import 从tar包中的内容创建一个新的文件系统再导入为镜像[对应export]
- 案例演示:cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号
Docker镜像
Docker镜像分层原理-联合文件系统(UnionFS)_docker fs-CSDN博客
4.1镜像的的定义
- 镜像是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。
- 只有通过这个镜像文件才能生成Docker容器实例(类似Java中new出来一个对象)。
4.2镜像分层
以我们拉取tomcat为例子,我们可以看得出来,在下载的时候,docker的镜像好像是一层一层的在下载
那么为什么需要镜像分层呢?
以拉取镜像为例,假如没有镜像分层,拉取镜像的镜像很大,比如tomcat的镜像有680M。第一次我们拉取最新版本的tomcat,下载了完成的680M到本地,下一次我们要下载9.0.58版本的,是不是又得下载680M。尽管可能两个版本之间可能只是修改了几行配置文件。这样是非常低效的。如果能只下载有差异的部分就好了!
这个问题,也就是镜像分层要解决的问题。实际上,Docker也是这么实现的。
第一次下载tomcat时,因为之前没有下载过,所以下载了所有的层,网络慢点的话还是需要花一些时间的!
镜像分层有以下几个好处
- 拉取更快 :因为分层了,只需拉取本地不存在的层就可以了
- 存储更少:因为共同的层只需存储一份即可!
- 运行时存储更少:因为容器运行的时候可以共享同一层
- 镜像分层最大的一个好处就是共享资源,方便复制迁移,就是为了复用。
4.3UnionFS(联合文件系统)
Docker------镜像原理之联合文件系统和分层理解 - 掘金
- Union文件系统(UnionFS)是一种分层的、轻量级的、高性能 的文件系统,它是Docker镜像的基础,并且支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂在到同一个虚拟文件系统下。
- 镜像可以通过分层来进行继承,基于基础镜像(没有父镜像,类似于Java中的Object),可以制作各种具体的应用镜像。
- Union文件系统的特性:一次性同时加载多个文件系统,但是从外面来看,只能看到一个文件系统;联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有地层的文件和目录。
4.4镜像加载原理
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等等
>
平时我们在虚拟机上安装Linux操作系统都是好几个G,为什么docker才200M左右呢?对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供 rootfs 就行了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别, 因此不同的发行版可以公用bootfs。
**Docker的镜像层都是可读的,容器层是可写的。**当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作"容器层","容器层"之下的都叫"镜像层"。
4.5 Docker镜像commit操作案例(目前还有问题,还需要完善)
docker commit提交容器副本使之成为一个新的镜像
docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
案例演示ubuntu安装vim
原始的默认Ubuntu镜像是不带着vim命令的
接下来安装vim apt-get update(更新包管理工具)
然后安装我们需要的vim ** apt-get -y install vim**
然后就可以使用vim命令了
bash
root@e1b40912e5b6:/# vim a.txt
root@e1b40912e5b6:/# cat a.txt
hello docker!!!
root@e1b40912e5b6:/#
安装完成以后,commit我们的新镜像
shell
[root@pkq ~]# docker commit -m="add a vim" -a="pkq" e1b40912e5b6 pkq/myubuntu:1.1
sha256:4d6aaa1834798ad8b199e232234d0a340e1d24488f3cd8e3c558759299b4c597
本地镜像发布到阿里云
镜像的生成
参照上一小节
本地镜像推送到阿里云
本地镜像素材
阿里云开发者平台
创建仓库镜像
选择控制台进入容器镜像服务
然后点击管理控制台
选择个人实例创建命名空间
然后创建镜像仓库
进入管理界面就可以获得脚本信息
把镜像推送到阿里云
bash
docker login --username=aliyun6621649207 registry.cn-hangzhou.aliyuncs.com
docker tag 4d6aaa183479 registry.cn-hangzhou.aliyuncs.com/pkqzyh/myubuntu:1.1
docker push registry.cn-hangzhou.aliyuncs.com/pkqzyh/myubuntu:1.1
把阿里云镜像下载到本地
先删除myubuntu镜像
然后从阿里云拉取镜像
bash
$ docker pull registry.cn-hangzhou.aliyuncs.com/pkqzyh/myubuntu:[镜像版本号]
bash
$ docker pull registry.cn-hangzhou.aliyuncs.com/pkqzyh/myubuntu:1.1
本地镜像发布到私有仓库
Docker Registry
1 官方Docker Hub地址:https://hub.docker.com/,中国大陆访问太慢了且准备被阿里云取代的趋势,不太主流。
2 Dockerhub、阿里云这样的公共镜像仓库可能不太方便,涉及机密的公司不可能提供镜像给公网,所以需要创建一个本地私人仓库供给团队使用,基于公司内部项目构建镜像。
Docker Registry是官方提供的工具,可以用于构建私有镜像仓库
本地镜像推送到私有库
下载镜像Docker Registry
docker pull registry
运行私有库Registry,相当于本地有一个Docker Hub
docker run -d -p 5000:5000 -v /pkq/myregistry/:/tmp/registry --privileged=true registry
默认情况,仓库被创建在容器的/var/lib/registry目录下,建议自行用容器卷映射,方便于宿主机联调
创建一个新镜像,ubuntu安装ifconfig命令
先下载一个Ubuntu镜像
原始的Ubuntu镜像并没有ifconfig命令
docker容器内执行下面两条命令来安装ifconfig:
apt-get update
apt-get install net-tools
安装完成后提交新镜像
公式:
docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
命令:在容器外执行,记得
docker commit -m="ifconfig cmd add" -a="pkq" 9f414841a2be pkqmyubuntu:1.2
curl验证私服库存在哪些镜像
shell
[root@pkq /]# curl -XGET http://192.168.200.129:5000/v2/_catalog
{"repositories":[]}
可以看到,目前私服库没有任何镜像上传过
把新镜像修改成符合私服规范的tag
按照公式: docker tag 镜像:Tag Host:Port/Repository:Tag
使用命令 docker tag 将pkqmyubuntu:1.2 这个镜像修改为192.168.200.129:5000/pkqmyubuntu:1.2
docker tag pkqmyubuntu:1.2 192.168.200.129:5000/pkqmyubuntu:1.2
修改配置文件使其支持http
vim命令新增如下内容:vim /etc/docker/daemon.json
json
{
"registry-mirrors": ["https://mf81xcmx.mirror.aliyuncs.com"],
"insecure-registries": ["192.168.200.129:5000"]
}
上述理由:docker默认不允许http方式推送镜像,通过配置选项来取消这个限制。====> 修改完后如果不生效,建议重启docker
bash
docker run -d -p 5000:5000 -v /pkq/myregistry/:/tmp/registry --privileged=true registry
push推送到私服库
bash
docker push 192.168.200.129:5000/pkqmyubuntu:1.2
curl验证私服库存在哪些镜像
bash
curl -XGET http://192.168.200.129:5000/v2/_catalog
pull到本地运行
先删除本地镜像
bash
docker rmi -f 192.168.200.129:5000/pkqmyubuntu:1.2
bash
docker pull 192.168.200.129:5000/pkqmyubuntu:1.2
Docker容器数据卷
数据卷产生背景
Docker的镜像是由一系列的只读层组合而来,当启动一个容器时,Docker加载镜像的所有只读层,并在最上层加入一个读写层。这个设计使得Docker可以提高镜像构建、存储和分发的效率,节省了时间和存储空间,然而也存在一些问题:
- 容器中的文件在宿主机上存在形式复杂,不能在宿主机上很方便地对容器中的文件进行访问。
- 多个容器之间的数据无法共享
- 当删除容器时,容器产生的数据将丢失。
为了解决这些问题,Docker引入了数据卷(volume)机制。Volume 是存在于一个或多个容器中的特定文件或文件夹,这个目录以独立于联合文件系统的形式在宿主机中存在,并为数据的共享和持久化提供便利。
- volume 在容器创建时就会初始化,在容器运行时就可以使用其中的文件。
- volume 能在不同的容器之间共享和重用。
- 对volume中数据的操作会马上生效。
- 对volume中数据的操作不会影响镜像本身。
- volume的生存周期独立于容器的生命周期,即使删除容器,volume仍然会存在,没有任何容器使用的volume也不会被Docker删除。
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。
说白了就是将docker容器内的数据保存进宿主机内,类似于"共享文件夹"。双方都可以对其进行访问和操作。
特点:
- 数据卷可在容器之间共享或重用数据;
- 卷中的更改可以直接实时生效;
- 数据卷中的更改不会包含在镜像的更新中;
- 数据卷的生命周期一直持续到没有容器使用它为止。
运行一个带有容器卷存储功能的容器实例
bash
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名
数据卷案例
宿主机与容器之间添加映射数据卷
镜像
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名
bash
docker run -it --privileged=true -v /tmp/docker_data:/tmp/docker_data --name=u1 ubuntu
这里我的宿主机/tmp目录下是没有docker_data目录的,同样在容器Ubuntu内的/tmp下也是没有docker_data目录的,在运行此语句后会进行自动创建
查看数据卷是否挂载成功
docker inspect 容器ID
先查看镜像
bash
[root@pkq tmp]# clear
[root@pkq tmp]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
21bf8dca99bc ubuntu "bash" 4 minutes ago Up 4 minutes u1
8c289dfce3ec 3000d4e18369 "/bin/bash" 34 minutes ago Up 34 minutes nervous_newton
e2d718052046 registry "/entrypoint.sh /etc..." 43 minutes ago Up 43 minutes 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp upbeat_lehmann
[root@pkq tmp]#
bash
[root@pkq tmp]# docker inspect 21bf8dca99bc
这里显示出了挂载的目录,即挂载成功。
容器和宿主机之间的数据共享
1 docker修改,主机同步获得
2 主机修改,docker同步获得
3 docker容器stop,主机修改,docker容器重启看数据是否同步。
映射添加读写规则
读写(默认)
默认案例同上,docker容器数据卷默认为rw,操作效果同上。
只读
将容器内部的实例进行限制,只能读,不能写。
ruby
docker run -it --privileged=true -v /宿主机绝对路径目录:/tmp/容器内目录:ro 镜像名
举例:
bash
docker run -it --privileged=true -v /tmp/docker_data:/tmp/docker_data:ro ubuntu
我们前往容器内的/tmp/docker_data目录内创建文件,系统会提示这里对于容器为只读,无法进行写操作:
再前往宿主机进行文件的创建操作:
bash
touch 1.txt
echo 'adaedEWDAW' > 1.txt
前往容器内进行查看:
可以正常进行查看操作,但依旧没有写权限。
此时如果宿主机写入内容,可以同步给容器内,容器可以读取到
卷的继承和共享
容器u1完成和宿主机的映射
再来一次,这里因为需要用到两个容器,为方便区分,添加了名称:u1和u2
bash
docker run -it --privileged=true -v /tmp/docker_data:/tmp/docker_data --name u1 ubuntu
创建一个文件,随便写点什么进去。
bash
cd /tmp/docker
touch u1.txt
echo 'this is u1' > u1.txt
在宿主机中查看一下,并也随便创建点什么:
bash
touch host.txt
echo 'this is host' > host.txt
容器2继承容器1卷的规则
此时的容器u1已经和宿主机成功挂载了数据卷,完成了映射关系。
此时我们再创建一个名叫u2的Ubuntu容器
--volumes-from父类
这玩意儿其实有点类似于java中的extends,实际操作如下:
docker run -it --privileged=true --volumes-from u1 --name u2 ubuntu
在容器u2中也随便加点什么进去:
bash
touch u2.txt
echo 'this is u2' > u2.txt
然后前往u1和宿主机进行查看,u1:
宿主机:
当父级容器stop时的继承和共享
把u1给stop掉,然后在宿主机创建文件
文件创建完成后,我们再去u2查看结果(当父容器宕掉后能否继承和共享):
bash
ls
因为u2继承的只是挂载的目录,就算u1宕掉了,也不会影响他的继承和共享。
查看最近运行的两个容器:
bash
docker ps -n 2
再运行:
bash
docker start u1
bash
docker exec -it u1 /bin/bash
进入目录进行查看:
bash
cd /tmp/docker_data
ls
docker安装常用软件
安装tomcat8
docker pull billygoo/tomcat8-jdk8
docker run -it -p 8080:8080 --name mytomcat8 billygoo/tomcat8-jdk8
安装MySQL
Linux Centos7 Docker安装Mysql8.0-CSDN博客
Docker安装并使用Mysql(可用详细)_docker安装mysql-CSDN博客
写最好的Docker安装最新版MySQL8(mysql-8.0.31)教程(参考Docker Hub和MySQL官方文档)_docker mysql8-CSDN博客
拉取镜像
bash
docker pull mysql
创建挂载目录
bash
mkdir -p /docker/mysql/conf
mkdir -p /docker/mysql/data
mkdir -p /docker/mysql/logs
创建容器:将配置选项作为标志传递给mysqld,不用写xxx.cnf配置文件
bash
docker run --privileged=true --name mysql -v /docker/mysql/log:/var/log/mysql -v /docker/mysql/data:/var/lib/mysql -v /docker/mysql/conf:/etc/mysql/conf.d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql --init-connect="SET collation_connection=utf8mb4_0900_ai_ci" --init-connect="SET NAMES utf8mb4" --skip-character-set-client-handshake
bash
#参数解释
--privileged:授权
-d:后台运行容器
-p:映射容器端口号和宿主机端口号
-e:环境参数,MYSQL_ROOT_PASSWORD设置root用户的密码
-v:挂载宿主机目录和 docker容器中的目录,前面是宿主机目录,后面是容器内部目录
--name:容器名称
进入mysql容器---并登陆mysql
bash
格式:docker exec -it mysql名称 bash
进入mysql容器操作台命令:docker exec -it mysql bash
登录mysql命令:mysql -u root -p
输入密码:
开启远程访问权限
bash
命令:use mysql;
命令:select host,user from user;
命令:ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
命令:flush privileges;
把root用户的密码改成 mysql_native_password 模式,即可远程连接
#创建一个账号-pkq,用来进行远程访问;
CREATE USER 'pkq'@'%' IDENTIFIED BY '123456';
赋予所有权限给之前创建的账号:pkq
GRANT ALL ON *.* TO 'pkq'@'%';
确认使用密码{123456}登录此账号{admin}
密码尽量复杂,安全性更高。
ALTER USER 'pkq'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
刷新权限
FLUSH PRIVILEGES;