2023年3月7日08:34:23 公司没有任务安排,闲着也没事做,就学学docker吧…
docker诞生是解决什么问题?
docker的诞生是为了防止开发人员与运维人员之间吵架。在没有docker之前,开发人员开发完一套项目,然后就打裸包【只打项目包,不打测试环境】,发给运维人员。结果呢?运维人员一部署,发现压根跑不起来。遵循程序猿法则:自己的一定没问题,肯定是他们的错。然后,就去找开发人员理论。开发人员在本地环境一测试,能跑。运维人员就咽不下这口气。就说:“劳资不给你们配置环境了,你们直接连同环境一起打包给我”。然后,连夜开发了一套软件给开发人员用。最后说:“用这套软件,把运行环境和项目发我就OK”。这个软件就是docker.其实也不能怪运维人员。开发环境涉及很多版本问题。比如,【mysql 5.0 与 mysql 8.0 、redis补丁、开发该项目语言的源码版本、各种依赖版本…】。鬼知道你用的是什么啊?开发人员一听,也觉得是这么个理。就说行吧,以后将环境和项目一起打包给你放docker容器里。
docker在哪里出现呢?
从本质上来讲,docker是虚拟机。还记得当时配置CentOS的时候,下载了一个.ios的文件。这个CentOS 7 .ios 实则是CentOS操作系统打包后的产物。被称为镜像文件。虚拟机上跑的实际上是这个镜像文件,装的也是镜像文件。同样的,开发人员也把开发的项目+开发环境 一起打包成镜像文件,产生 project.ios 【镜像文件】。然后这个project.ios 放进docker中去运行。
镜像文件是什么啊?
光看这个名字也差不多知道意思了。你可以理解CentOS 7.ios 是Cent OS操作系统的一个压缩版复制。除了不能去修改内在文件外,其他功能几乎与Cent OS一致。不要太纠结这个镜像文件。就是个打压缩包,只不过这个压缩包不解压也可以运行而已。
一次镜像,处处运行
虚拟机就是一个很大的docker!虚拟机占用的资源太多,启动很慢,冗余步骤太多。如果把虚拟机比作为大货车,那么docker就是自行车。所以,docker是比较轻巧的。虚拟机是进行硬件虚拟了的。而docker是直接运行与Linux内核。不依赖操作系统。并且没有进行硬件虚拟。
总结:
docker官网,请点击…
docker Hub仓库,请点击…
docker官网是下载docker容器的,而docker Hub 是下载镜像文件【.ios】的。切记,Docker必须部署在Linux内核上。
对虚拟机也有配置要求:
uname -r
可以查看当前虚拟机的版本信息
从docker官网上下载了一个docker模板【这个模板不是镜像】,根据这个模板可以实例化一个个的相互隔离的docker。镜像文件是去远程仓库拉取到本地仓库的。容器内部署的也是一个个镜像实例。
安装步骤:
安装CentOS 7 的docker,请参考该官方文档…
yum -y install gcc
GCC 是GNU的编译器,必用。
sudo yum install -y yum-utils
安装工具包
根据官方文档,在执行了
yum install -y yum-utils
后,是不是就该执行sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
这条命令了?先说明一下这个命令吧。这是docker最大的镜像仓库。理论上来说,去这个仓库拿是最好的。但是呢?这个仓库是在国外的。网速很慢,所有,只能去连接中国境内的仓库了。
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
这是我们国内的阿里云的镜像仓库,联通镜像仓库
yum makecache fast
重建yum索引,以后,安装新的软件快些
上诉都是准备工作,接下来就是安装docker引擎了
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
安装docker引擎,安装有点慢,正常。
docker引擎一旦安装了,就会被Systemctl 控制。
启动docker:
sudo systemctl status docker
查看docker引擎的状态,【下图表示禁止状态】
sudo systemctl start docker
启动docker引擎
docker version
sudo docker run hello-world
直观的说,就是方便以后从阿里云镜像仓库拉取镜像文件的时候,能快一些。这个是免费的,每个阿里云账户都有一个专属于自己的地址。
阿里云官网
sudo mkdir -p ./etc/docker
systemctl daemon-reload
重新加载daemon文件【注意,在执行这条命令之前,一定要让docker关机】
systemctl restart docker
在执行这一步命令时,我报错了。
上面的报错,实际上是官方给的命令,输入到daemo.json文件的内容格式不对!必须改成下面的效果。
最后重新加载、启动 docker
docker run hello-world分析
为什么Docker会比VM虚拟机快?
这是在工作中常用的docker命令,记住会用就OK。
启动类命令:
systemctl status docker
查看docker状态systemctl start docker
启动systemctl stop docker
停止systemctl enable docker
开机自启动docker --help
帮助docker info
查看docker概要信息上述命令没什么好介绍的,会用就行。
镜像命令:
docker [-a -q] images
列出本机上的镜像文件【-a 表示列出本机上的所有镜像,包括历史镜像层 | -q 表示只显示镜像ID】
docker search [--limit] {images}
搜索指定的镜像【–limit 表示只列出N个镜像结果,默认是25个】
docker pull {image}[:TAG]
拉取指定的镜像【:TAG 表示拉取指定版本的镜像。默认是拉取最新版本】 拉取镜像一般很慢。
df -h
查看虚拟机文件的内存大小
docker system df
·查看镜像/容器/数据卷所占的空间
docker rmi {images_id or images_name}
删除镜像仓库中的镜像文件【- f 表示强制删除】。最好是根据id删除,因为镜像多了,就可能有同名的。
上诉命令都是在docker容器实例内去操作镜像文件的。
容器命令:
先在本机上拉取一个Ubuntu的镜像。
docker run [--name | -d | -it |-P |-p] {images:TAG}
运行一个镜像实例【–name 表示自定义该实例名 | -d 表示在后台运行该容器实例,并返回一个id | -it 表示运行了该实例后,进入其内部终端,让你操作它 | -P 这是大写的P,表示随机分配端口映射 | -p 这是小写的p,表示指定端口映射】
注意,在
exit
命令执行后,Ubuntu自动停止运行。在run进去后,按ctrl +p +q
退出,该容器实例不会停止。
docker ps [-a -l -n -q]
列出当前所有正在运行的容器.【-a :列出当前所有正在运行的容器+历史上运行过的 | -l :显示最近创建的容器 |-n:显示最近n个创建的容器|-q :静默模式,只显示容器编号】。
docker start {images.id or images.name}
·启动已停止运行的容器
docker restart {images.id or images.name}
·重新启动容器实例
docker stop {images.id or images.name}
··停止容器实例
docker kill {images.id or images.name}
强制停止容器实例
docker rm [-f] {images.id or images.name}
删除容器实例【-f 表示强制删除】
问题:如果我想再次进入镜像实例呢?难道还要 docker run {??}
接下来的命令,很重要!首先,拉取一个redis v6.0.8的镜像文件。
可以看出,上诉docker容器中没有实例,在仓库内有两个镜像【ubuntu、redis6.0.8】。接下来,介绍实例的两种模式:
docker run -d --name=back ubuntu
】直白的说,就是一旦运行了,就放在后台。此时,这个实例的状态是停止的。因为docker有个机制:“没有用的实例,通通给爷睡着!爷这不养闲人!”所以,你刚才run了个ubuntu实例出来,但是被docker视作没用的废物,就给停止了。如果说,我非要让这个redis实例运行呢?这就引出了下一种模式。docker run -it --name=float ubuntu
】就是打开终端那个。之前Ubuntu用的那种模式。只要你一直跟实例交互,那它就是有用的。如果你exitctrl +c
了,那它也就挂了。当然,你用ctrl +p+q
去退回,它不会挂。有些镜像带-d 而run出来的实例,不会挂。比如,redis 6.0.8.因为redis一直有进程与它交互。redis可以一直保持运行。Ubuntu就不行了。除了你跟Ubuntu实例交互,就没有其他进程与它交互了。
docker logs {images.id or images.name}
查看容器实例日志
docker top {images.id or images.name}
查看指定容器实例内运行的进程
docker inspect {images.id}
查看容器的内部信息.【所有信息都会显示】
怎么重新进入容器实例?
我在这里说明一下,有些容器实例,比如redis 、mysql .它们可以一直与进程交互。可以通过
docker top {images}
去查看具体实例的进程信息。所以,有些实例无论你是用exit
还是ctrl +c
还是ctrl +p+q
去退出。它们都不会停止,会在后台默默运行。但这些容器只是很少一部分。下面演示重新进入容器实例,或退出。我以Ubuntu为列。
docker ps
查看正在运行的实例
docker images
查看本地仓库镜像
docker run --name=myubuntu -it ubuntu
创建并运行一个Ubuntu实例,且进入其终端
ls
列出Ubuntu列表
exit
退出
docker ps -a
此时,Ubuntu实例停止运行
docker start myubuntu
开启运行,【类似于强制开启,不会自动停止】
docker ps
查看该容器实例是否正在运行中【必须是UP的】
docker exec -it {images.id} bashShell
重新进入该实例终端界面
可以看出,用
docker exec -it {images} bashShell
进入容器实例后,再按exit
退出,不会导致停用。
docker ps
docker attach {images}
exit
docker ps -a
可以看出,用
docker attach {images}
进入实例终端,在exit
后会自动停止,但是用ctrl +p+q
退出时,不会停止。所以,一般在部署中,还是使用docker exec -it {images}
去再次进入终端。
在镜像实例中的文件复制到虚拟机上进行保护和备份:
docker cp {images}:{镜像实例内部的文件路径} {虚拟机上的备份文件的路径}
问题:假如说我的Ubuntu实例内部有很多个文件,难道我要全部备份吗?这显然是不科学的.
下述的命令,是以整个镜像实例【myubuntu】来进行备份。
docker export {images} > 新目录下的新文件.tar
如何将myubuntucopy.tar文件导入到docker中?
myubuntucopy.tar文件导入到docker中,生成的不是一个myubuntu实例。而是一个镜像文件!它被放在本机仓库中。然后可以以它为模板,
docker run
出一个个跟myubuntu的实例来,每一个克隆出的实例内部都有一个hang.txt文件。
cat 宿主机上的文件.tar | docker import - 镜像用户/镜像名:镜像版本号
上述命令,可以理解为:自定义了一个镜像文件
通过这个镜像文件,生成实例,去看看有没有hang.txt
以上的命令,必须要上手搞一把。光看是记不住的。
镜像是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。
镜像是分层的:
实现这个分层的下载布局是因为UnionFS:Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像
为什么要采用分层下载呢?
实现局部资源共享!有这么一个现象:在你本机仓库内有了Ubuntu镜像后,你再去下载centos。这是你就会发现centos的分层很少,并且下载很快!为什么呢?因为Ubuntu和centos可以共用最基本的Linux内核!你本机仓库原本就有了Ubuntu,下载了那部分Linux内核。centos拉取过来的时候,一看,这不有现成的嘛,直接用。
自定义一个Ubuntu镜像出来,让它具备vim编辑器:
docker run --name=hangUbuntu -it ubuntu
new出一个原始Ubuntu实例,并进入其交互终端
apt-get update
更新包管理工具
apt-get -y install vim
安装Vin编辑器
验证vim是否安装
提交实例副本,使其成为一个新的镜像
docker commit -m="描述信息" -a="作者名" {实例ID} {该镜像包名/镜像名:版本}
以后,用hangubuntuwithvim镜像run出来的实例都带有vim编辑器和hang.txt文件
登录到阿里云官网,定位到之前镜像加速器模块。开通个人版的实例列表。
创建成功后,点击管理
跟着阿里云的操作指南来执行命令就行。
容器卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性:
容器卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。
直白的说,容器卷就是共享文件夹。是宿主机与镜像实例的共享文件夹。就是之前的备份操作。只不过容器卷可以持久的,自动的同步数据。数据同步是双向的!可以说,只要宿主机的某个目录与容器实例内的某个目录建立了映射关系【容器卷】,那么这两个目录永远存的是一样的数据。
docker run -it --privileged=true -v /宿主机【你的虚拟机】备份空间的绝对路径 : /容器实例内的目录 镜像名
docker ps -a
docker images
docker run -it --name=juan --privileged=true -v //home/hang/Disktop/ubuntu_data:/home/hang ubuntu /bin/bash
在容器内部的 //home/hang/hang.txt 下新建文件hang.txt。去查看宿主机是否同步数据。
同样,在ubuntu_data目录下新建文件,查看在容器映射目录下是否同步数据。自行测试。结果是可以同步的。甚至在容器实例停止运行后,在宿主机中新增数据。当容器实例再次启动后,数据也是同步的。
所以说,容器卷就是共享文件夹。也不知道是谁翻译成容器卷这个词,以后直接说共享文件夹多好。
当然。,也可以限制容器实例【只读、只写、读写】权限
docker run -it --name=juan --privileged=true -v //home/hang/Disktop/ubuntu_data:/home/hang:ro ubuntu /bin/bash
只允许实例读取宿主机映射目录下的数据。ro 【read only】docker run -it --name=juan --privileged=true -v //home/hang/Disktop/ubuntu_data:/home/hang:ro ubuntu /bin/bash
只允许实例写入数据到宿主机映射目录下。wo 【write only】不写就是读写都允许【即:数据同步】。只能限制容器实例,宿主机是不可能被限制的【就好比,凡人怎么能限制上帝呢?对吧。不要去纠结】
容器之间的继承映射目录:
有这么一个场景:宿主机【虚拟机】的同一个指定的目录想跟多个容器实例建立映射关系。难道是每run一个容器实例的时候都要写一遍映射目录规则?甚至有的时候,目录又长又臭!所以,有人就想了。当第一个容器实例与宿主机建立映射目录规则时,我下次run的时候,能不能找第一个实例要这个规则?答案是可行的。
docker run -it --name={自定义第二个实例名} --privileged=true --volums-from {第一个实例} ubuntu /bin/bash
这样第二个实例就有了同样的映射目录规则。即使第一个实例挂了,对第二个实例也没有影响。
tomcat:
docker images
docker search --limit 5 tomcat
docker pull tomcat
docker run -it -p 8080:8080 tomcat
-p【主机端口:docker容器端口】
接下来,查看webapps、webapps.dist是否有内容.
删除webapps目录,再把webapps.dist目录改变成webapps
最后在虚拟机上访问tomcat
其实不光虚拟机能访问,你的Windows也能访问
只有最新版的tomcat有这个要求;只要是10.0.14版本以下的没有变。首页资源还是放在wenapps目录下的。可以直接访问。
mysql:
docker images
docker pull mysql:5.7
docker run -p 3306:3306 --name=hangismysql -e MYSQL_ROOT_PASSWORD={设置你mysql的密码} -d mysql:5.7
在执行这条命令之前,先检测你虚拟机上的3306端口是否被占用
ps -ef | grep mysql
对于常用的镜像实例,比如:mysql 端口在3306 附近;Tomcat 端口在8080附近。
docker exec -it hangismysql /bin/bash
mysql -uroot -p
执行该命令,输入之前创建实例时的密码,进入mysql。同样你也可以在Windows的mysql图形界面去连接docker的mysql5.7
mysql的中文乱码问题:
mysql在实战部署中的应用:
docker run -d -p 3306:3306 --privileged=true -v //home/hang/mysql_data/mysql_5.7/logs:/var/log/mysql -v //home/hang/mysql_data/mysql_5.7/data:/var/lib/mysql -v //home/hang/mysql_data/mysqls_config:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=root --name=hangmysql mysql:5.7
上述命令配置了数据库的日志、数据、配置文件的映射关系。所以,可以在虚拟机上直接写配置信息。容器卷会自动同步到docker上的mysql实例中去
更改数据库配置信息:
在虚拟机配置的文件,会自动同步到数据库的配置文件目录中去。【重启mysql容器】
再次在mysql终端查询字符编码,就会全部变为utf8格式。
redis
跟mysql操作是一样的。使用容器卷,映射配置文件、数据存储。
在虚拟机上创建目录,使redis的数据和配置信息备份和同步。
目录结构如上,接下来就是自定义redis的配置文件了。在redis_config目录下新建一个redis.conf文件。
#必须注释掉 bind 127.0.0.1 这行,不然redis就不允许外地连接
#bind 127.0.0.1
#关闭保护模式,不然外界可能访问不了
protected-mode no
#端口号固定为 6379
port 6379
#将daemonize yes注释起来 、因为该配置和docker run中-d参数冲突,会导致容器一直启动失败
daemonize no
目录环境准备好了,接下来就是run实例了,并使用数据卷去映射指定的存储目录
docker run -p 6379:6379 --name=hangredis --privileged=true -v //home/hang/redis_data/redis_6.0.8/data:/data -v //home/hang/redis_data/redis_config/redis.conf:/etc/redis/redis.conf -d redis:6.0.8 redis-server /etc/redis/redis.conf
启动容器实例。使用redis-cli 进入redis。如果遇到一直无法启动的问题。原因是 redis的配置文件与redis的版本冲突!
redis各版本的配置文件,请点击…