欢迎光临散文网 会员登陆 & 注册

尚硅谷Docker实战教程(docker教程天花板)

2023-06-08 17:56 作者:无双小骏  | 我要投稿

docker存在的意义

在开发完成后将src源码提交给运维进行部署,而如果开发环境和运维生产环境不同则会出现问题:

  1. 运维与开发之间的mysql版本、redis补丁、java版本不一致,
  2. 有可能是因为安装啰嗦,因此运维需要让开发提供一条list清单,而开发所提交的list清单环境有时候会用多台集群,对于运维的痛苦在于如果多台集群当中有一台部署错误都跑不起来。
  3. 最后一种可能是扩容、缩容的问题,例如开发的redis是六主六从,而运维当前只有三主三从,这就是一个很费时费力的问题。

而我们引入了新的技术docker后,例如说当开发把所有的源代码和配置环境还有版本都是ok的情况下,把这些都打包成一个镜像文件,将这个镜像文件跑在docker里,此时所模拟出来的环境就会让开发时所愚弄的环境原封不动地运行。

好比说我们搬家时,我们的家居需要搬走并在新家重新部署,难以避免地出现损失(损耗),那么docker的出现好比于将整栋楼搬到了新的地址,原本我们住在哪里现在还住在哪里,只不过是地址不一样了,内部的东西都是一样的,docker保证了迁移的过程中不走样。

在装双系统时,由于每个人的电脑品牌不同,所安装的linxu时会出现很多不同的问题,为此我们需要安装一个软件——WMware,如果我们每个人都安装了这个软件,在同一个软件上运行同一个iso文件,这样就保证了换证迁移的一致,这就是我们的理念初心。

而docker更加强大,例如在做一个项目时需要安装很多软件,redis、mysql、mq等等,尽管是同桌只要互换环境去跑相同的代码都容易因为环境出现不同的问题,因此我们可以通过docker将源码、运行环境和配置文件还有特殊引导第三方组件等用docker打包成一个gmall镜像文件,这样就不会出现很多复杂的问题。

总结:我们的vmware就是docker,而centos7.iso就是最后所打包的镜像文件,这就是docker带给我们的方便和灵活。

docker是基于Go语言实现的云开源项目。

docker主要目标是“Build”,也就是通过对应组件的封装、分发、部署、运行等生命周期的管理,使用户的APP及运行环境能够做到“一次镜像,处处运行”。

docker的出现解决了运行环境和配置问题的软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术。

容器和虚拟机有什么不同?

docker是一个容器虚拟化技术。

虚拟机是带环境安装的一种解决方案,而docker是相较之下更简介的一个安装方案,就好比我们在win10的系统里运行linux系统centos7,通过虚拟机软件VMware安装ISO镜像文件来模拟虚拟机管理类系统、创建虚拟机,在虚拟机上安装操作系统,在操作系统中部署安装各种应用。

缺点:

  1. 资源占用多
  2. 冗余步骤多
  3. 启动慢

对此Linux想出了一个解决方式,俗称Linux容器(缩写为LXC)。Linux容器是系统与系统其他部分分隔离开的一系列进程,从另一个镜像运行,并由该镜像提供支持进程所需的全部文件。容器提供的镜像包含了应用的所有依赖项,因而在从开发到测试再到生产的整个过程中,它都具有可移植性和一致性。

docker容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统虚拟机则是在硬件层面实现虚拟化。与传统的虚拟机相比,docker优势体现为启动速度快,占用体积小。

docker出来会后对于技术支撑有着很大的变化,例如说第一种coder就是码农,只是一个写代码的,可以做一些基础的软件工作,那么接下来就是programmer程序员,对于部分模块有自己的心得,可以写一些东西了,再进阶就是software engineer软件工程师。而随着docker的出现,有了DevOps engineer运维开发混合型工程师,将传统的开发与运维合并在一起成为了新一代开发工程师。

Docker的好处:

  1. 更快速的应用交付和部署(传统的应用开发完成后,需要提供一堆安装程序和配置说明文档,安装部署后需要根据配置文档进行繁杂的配置才能正常运行。Docker化之后只需要交付少量容器镜像文件,在正式生产环境加载镜像并运行即可,应用安装配置在镜像里已经内置好,大大节省部署配置和测试验证时间。)
  2. 更便捷的升级和扩缩容(随着微服务架构和Docker的发展,大量的应用会通过微服务方式架构,应用的开发构建将变成搭乐高积木一样,每个Docker容器将变成一块“积木”,应用的升级将变得非常容易。当现有的容器不足以支撑业务处理时,可通过镜像运行新的容器快速扩容,使应用程序的扩容从原先的天级变成分钟级甚至秒级。)
  3. 更简单的系统运维(应用容器化运行后,生产环境运行的应用与开发、测试环境的应用高度一致,容器会将应用程序相关的环境和状态完全封装起来,不会因为底层基础架构和操作系统的不一致性给应用带来影响,产生新的BUG。当出现程序异常时,也可以通过测试环境的相同容器进行快速定位和修复。)
  4. 更高效的计算资源利用(docker是内核级虚拟化,并不像传统的虚拟化技术一样需要额外的Hypervisor支持,所以在一台物理机上可以运行很多个容器实例,可大大提升物理服务器的CPU和内存的利用率

新浪、美团、蘑菇街等企业都在用.

下载方式:

  1. docker官网:http://www.docker.com
  2. docker Hub官网:https://hub.docker.com/

Docker的组成:

  1. 镜像(image:就是一个只读的模板。镜像可以用来创建docker容器,一个镜像可以创建很多容器,它也相当于是一个root文件系统。比如官方镜像centos:7,最小系统的root文件系统。相当于容器的“源代码”,docker镜像文件类似于java的类模板,而docker容器实例类似于java中new出来的实例对象。
  2. 容器(container:从面向对象角度来看,docker利用容器独立运行在容器里面,容器就类似于一个虚拟化的运行环境,容器是用镜像创建的运行实例。就像是JAVA中的类和实例对象一样,镜像是静态的定义,容器是镜像运行时的实体。容器为镜像提供了一个标准和隔离运行环境,它可以被启动、开始、停止、删除。每个容器都是相互隔离的,保证安全的平台。而从镜像容器角度来看,可以把容器看做是一个简易版的linxu环境和运行在其中的应用程序 。 )
  3. 仓库(repository:是集中存放镜像文件的场所。类似于maven仓库,存放各种jar包的地方;github仓库,存放各种git项目的地方;docker公司提供的官方registry被称为docker Hub,存放各种镜像模板的地方。仓库分为公开仓库和私有仓库两种形式。最大的公开仓库是Docker Hub,存放了数量庞大的镜像供用户下载。国内的公开仓库包括阿里云、网易云等。)


09_docker平台入门图解 P9 - 00:54


Docker是一个Client-Server结构的系统,Docker守护进程运行在主机上,然后通过Socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。容器是一个运行时环境,就是我们前面所说到的集装箱。可以对比mysql演示对比讲解:


09_docker平台入门图解 P9 - 04:15


我们在装完mysql后,本地服务(后台)上会启动一个mysql服务,如果想让mysql干活,就需要第三方工具(小海豚或者是Navicat等)软件连接上mysql让其进行干活。docker与mysql几乎雷同,区别是mysql用的是mysql脚本来生成sql语句,docker是用镜像文件生成了一个又一个的容器实例。通过这种方式来实现只要版本对应的情况下,在不同机子上都能跑的目的。

docker的三大特色:构建、分享以及运行。

安装docker的步骤:

  1. 确定使用的版本是centos7(虚拟机上查看)
  2. 卸载旧版本(如果之前装过docker:yum remove docker)
  3. yum安装gcc相关(首先保证能连接上外网,然后安装gcc和gcc-c++:yum -y install gcc和yum -y install gcc-c++)
  4. 安装需要的软件包(根据官网要求执行命令:yum install -y yum-utils)
  5. 设置stable镜像仓库(由于国内按照官网设置速度很慢会报错,因此我们采取国内下载方式:yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo)
  6. 更新yum软件包索引(yum makecache fast)
  7. 安装DOCKER CE(yum install docker -ce docker-ce-cli containerd.io)
  8. 启动docker(systemctl start docker)
  9. 测试(docker version来查看docker的版本并尝试运行hello world:docker run hello-world,根据我们前面学到的理论,docker如果要run这个镜像,会报错说本地炸不到这个镜像,因为如果本地有就直接转化成容器实例运行,如果没有就从远程仓库里去找拉到本地。这个消息如果能够在界面上出现代表工作正常。)

卸载docker的步骤:

  1. systemctl stop docker(停止正在运行的docker)
  2. yum remove docker -ce docker-ce-cli containerd.io(停止docker后台服务)
  3. rm -rf /var/lib/docker(删掉docker的配置文件)
  4. rm -rf /var/lib/containerd(删掉docker的第三方库包)


12_镜像加速器配置 P12 - 05:44

启动Docker后台容器(测试运行hello-world):docker run hello-world

底层原理:为什么docker会比VM虚拟机快?

  1. docker有着比虚拟机更少的抽象层(由于docker不需要Hypervisor【虚拟机】实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此利用率上docker将会在效率上有明显优势)
  2. docker利用的是宿主机的内核,而不需要加载操作系统OS内核(当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。进而避免引寻、加载操作系统内核返回等比较费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载OS,返回新建过程时分钟级别的。而docker时直接利用宿主机的操作系统,则省略了返回过程,因此新建一个docker容器只需要几秒钟)


14_为什么Docker会比VM虚拟机快 P14 - 03:16


Docker常用命令有帮助启动类命令、镜像命令和容器命令。

帮助启动类命令:

镜像命令:

docker images:列出本地主机上的镜像

  1. -a:列出本地所有的镜像(含历史)
  2. -q:只显示镜像ID

docker search [OPTIONS]镜像名字

  1. --limit:只列出N个镜像,默认25个

eg:docker search --limit 5 redis

docker pull 镜像名字[:TAG]:下载镜像

eg:docker pull redis:6.0.8

没有TAG的话默认是下载最新版本

docker system df :查看镜像/容器/数据卷所占的空间

docker rmi 仓库名字/imageID

eg:docker rmi -f feb5d9fea6a5(如果不加f的话会可能会报错)

docker rmi -f $(docker images -qa)【删除全部仓库】


16_镜像命令 P16 - 20:30


容器命令

新建+启动容器:docker run [OPTIONS] images

如果没有设立--name那么系统就会随机分配一个给我们

如果我们想更深一步地学习或了解run,可以使用docker run --help来查看更多的命令参数。我们现在已经得知,--name是指定名称,-it是启动交互容器,

列出所有正在运行的容器实例:docker ps [OPTIONS]

  1. -a:罗列出所有正在运行的容器+历史上运行过的
  2. -l:显示最近创建的容器
  3. -n:显示最近n个创建的容器
  4. -q:静默模式,只显示容器编号

退出容器

  1. exit:run进去容器,exit退出,容器停止
  2. ctrl+p+q:run进去容器,ctrl+p+q退出,容器不停止

重启容器:docker restart容器ID或者容器名

停止容器:docker stop容器ID或者容器名

强制停止容器:docker kill容器ID或容器名

删除已停止的容器:docker rm 容器ID

一次性删除多个容器实例:

  1. docker rm -f $(docker ps -a -q)【docker -ps -a -q列出所有正在运行的和已停止的容器用$包起来执行rm -f强制删除命令】
  2. docker ps -a -q | xargs docker rm

【在Docker中,docker ps命令用于列出当前正在运行的容器。-a选项允许列出所有的容器,而不仅仅是正在运行的容器,并且使用-q选项将输出限制为容器的ID。这意味着运行docker ps -a -q会返回所有容器的ID,无论它们目前是否正在运行。

管道符|将命令的输出从前一个命令传递到下一个命令。在这种情况下,它将docker ps -a -q的输出传递给xargs命令。

xargs命令用于将输入从标准输入转换为参数。在这里,它将docker ps -a -q的输出作为输入,并以容器ID的形式将它们传递给docker rm命令。因此,整个命令docker ps -a -q | xargs docker rm的含义是,删除所有容器,包括正在运行的和已停止的,但不包括运行中的容器。】

启动守护式容器(后台服务器)

在大部分场景下,我们希望docker的服务是在后台运行的,我们可以通过-d指定容器的后台运行模式。

docker run -d 容器名


21_容器命令D P21 - 05:59


查看容器日志:docker logs 容器ID或名称

查看容器内运行的进程:docker top 容器ID或名称

查看容器内部细节:docker inspect 容器ID

docker exec -it 容器ID bashShell

如果在使用Docker创建一个容器,并且希望进入该容器的命令行界面交互,你可以使用"docker exec -it container_name /bin/bash"命令来实现。这将启动一个新的shell会话,让你可以在容器中执行命令。

一旦你完成了容器中的操作并想要退出容器,你可以在容器中运行"exit"命令来退出容器的shell环境。这个命令不需要任何数字参数,它将在容器中退出命令行界面,并返回到宿主机的shell环境。你可以在宿主机上继续执行其他命令或操作。

需要注意的是,如果你是在容器启动时使用"docker run -it container_name"命令来启动容器并进入交互模式,则可以使用"exit"命令来退出该容器,并关闭容器。在这种情况下,"exit"命令不需要任何数字参数。

docker exec和docker run命令都可以用于进入Docker容器,但二者的区别主要有:

功能不同:docker run命令是用于启动一个新的Docker容器并在其中运行指定的命令,也可以进行进入容器的操作。而docker exec命令则是在已经运行的Docker容器中需要启动一个新的命令或进程。因此,在容器还未启动的情况下只能使用docker run命令进入容器。

进入容器的方式不同:docker run命令进入容器默认是交互式Shell会话,需要输入exit或按Ctrl+D退出容器。而docker exec命令默认是在已经运行的容器内执行指定的命令,进入容器后并不会自动启动交互式Shell会话,如果需要可以使用-it选项来进入交互式Shell会话。

容器的生命周期不同:docker run命令启动的容器一旦退出,就会被删除,所有在容器内所保存的数据也会随之丢失。而docker exec命令在已经运行的容器中启动新的命令或进程,与容器的生命周期无关。

总的来说,docker run命令主要用于启动新的容器,docker exec命令主要用于操作或调试已经在运行的容器。

重新进入docker attch 容器ID

二者的区别:

  1. attach直接进入容器启动命令的终端,不会启动新的进程,用exit退出会导致容器的停止
  2. exec是在容器中打开新的终端,并且可以启动新的进程用exit退出,不会导致容器的停止

我们用docker run 进入ubuntu,然后ctrl+p+q退出之后,再次用run进入后用exit退出之后发现还是up状态存活,意思就是说,我们用exec所打开的心终端用exit退出不会停止容器,方便别人使用。而attach进入后用exit退出会发现up状态取消了,所以工作室建议用exec命令,退出容器终端不会导致容器停止。

从容器内拷贝文件到主机上(容器—>主机)

导入和导出容器

export导出容器的内容流作为一个tar归档文件[对应import命令]

import从tar包中的内容创建一个新的文件系统再导入为镜像[对应export]


22_容器命令E P22 - 04:07


镜像:是一种轻量级、可执行的独立软件包。它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。

只有通过这个镜像文件才能生成Docker的容器实例(类似于Java中new出来一个对象)。

Unions(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一虚拟文件系统下(unite several directories into a single virtual filesystem)。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于镜像(没有父镜像),可以制作各种具体的应用镜像。镜像分层最大的一个好处就是共享资源,方便复制迁移,就是为了复用。

对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令,工具和程序就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就行了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。

Docker镜像层都是只读的,容器层是可写的。

当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称为“容器层”,“容器层”之下的都叫“镜像层”。

docker之所以能够做到体积如此之小,就是因为它只包含了linux内核(最核心的部分),所以我们docker run -it Ubuntu /bin/bash运行一个镜像想要使用vim命令是用不了的(command not found),这个容器实例上没有vim这个命令。因此我们就需要使用commit命令。

docker commit提交容器副本使之成为一个新的镜像。

docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]。

更新完之后安装一下vim命令就可以用了(外网联通的情况下)

后续ps会发现有原生的Ubuntu,还多出了一个新的container ID是我们刚才加了vim的ID,可以看到原生的Ubuntu只有73mb,加了vim后又一百多mv,以前的base是原生的镜像,而增加了其它的功能,就是在原生镜像的基础上增加的,类似于一个花卷一样一层一层地堆叠增加。


25_commit命令下集 P25 - 03:20


在 Docker 中,Commit 和 Export 都可以创建一个 Docker 镜像的备份,但是它们有着不同的作用和区别。

Commit:Commit 命令能够将一个正在运行的容器转换为一个新的镜像。当你在容器中新增一个文件或修改了某些配置的时候,如果这些修改比较重要,需要创建一个新的镜像,可以使用 commit 命令来进行。它会将当前容器的状态保存在一个镜像中,可以用于其他容器的启动。

使用 commit 命令的优势是可以快速创建镜像,在调试期间非常有用,例如你在容器中进行了多次修改,可以在每次修改后执行一次 commit 命令,实现版本控制,以便在后续需要时回滚到某个状态。

Export:Export 将 Docker 容器作为一个 .tar 文件导出到本地磁盘中。与 commit 不同,export 导出的是容器的文件系统和元数据,不包括容器的状态。你可以使用导出的文件在其他 Docker 环境中,或者通过 Dockerfile 构建一个新的镜像。

对于需要迁移 Docker 容器或备份 Docker 容器的场景,export 命令非常有用。它可以将容器的文件系统和数据导出到一个备份文件中,从而可以在其他 Docker 环境中重新构建容器。

总的来说,Commit 是为了版本控制和快速创建新镜像时使用的,Export 则是为了备份和迁移容器使用的。需要根据具体场景选择不同的命令。

本地镜像发布到阿里云

我们之前在docker原生(eg:docker1.0)的base上通过commit进行了升级,升级之后的功能更加强大,我们希望将升级后的形成一个新的docker标签(eg:docker1.1)发布到阿里云上实现共享,使用push推送到阿里云上去,然后再pull拉回到本地,就可以复用我们的劳动成果,阿里云毕竟是公网,为了保险起见,我们也可以建立私有库,但总而言之,任何一个容器实例,我们加强后构建成一个新的镜像后可以推送到公网或私网再回到本地进行使用,详情如下图所示:


26_本地镜像发布到阿里云 P26 - 04:22


注意事项:

  1. 输入密码时虽然光标不变但实际会输入密码。
  2. 输入的密码为阿里云容器仓库访问凭证的密码。
  3. 别用crt等工具,一定要用阿里云原生的链接工具执行命令。


26_本地镜像发布到阿里云 P26 - 11:14


  1. 官方Docker Hub地址:https://hub.docker.com/,中国大陆访问太慢了且准备被阿里云取代的趋势,不太主流。
  2. 我们推到阿里云上后是个人版,如果想要公用的话就需要企业版(充钱)。
  3. Dockerhub、阿里云这样的公共镜像仓库可能不太方便,涉及机密的公司不可能提供镜像给公网,所以需要创建一个本地私人仓库供给团队使用,基于公司内部项目构建镜像。Docker Registry是官方提供的工具,用于构建私有的个人经先不管仓库。
  4. 下载registry方式:docker pull registry。运行方式如下图所示:


28_新镜像推送私服库案例 P28 - 05:25


在新的镜像创建完成后,输入docker run -it 62e7fed04e2c /bin/bash进入我们的新升级后的镜像再输入ifconfig测试是否升级完成,接下来我们就可以将它放进私服。

首先先curl验证私服上有什么镜像

由于我们没有推送任何镜像到私服库,所以当前为空。然后将新镜像zzyyUbuntu:1.2修改符合私服规范的Tag。

然后我们要改一下docker下的daemon.json文件内容(因为docker默认不允许http方式推送镜像,通过配置选项来取消这个限制):输入vim /etc/docker/deamon.json进入编辑内容界面,在registry-mirror的下面加上一行“insecure-registries”:["192.168.111.162:5000"]

(修改后如果不生效就重新启动一下docker,注意红字部分前面要加一个逗号)

重启(systemctl restart docker)之后将docker的registry私服库再次运行一遍(这一次run可能会报错,可以尝试使用start试试)。

接下来使用push将镜像推送到私服库:docker push ip+端口+名称

第一次验证时发现是空的,第二次我们验证看一下结果,会发现从空变成了我们的名称。


28_新镜像推送私服库案例 P28 - 16:07


“privileged=true”是指在Docker中的容器中运行一个特权进程,以便获得与主机操作系统相同的特权级别。在Docker中,默认情况下,容器中的进程是以非特权模式运行的,因此它们不能访问一些主机系统的特权操作、设备文件等。

将“privileged=true”标志设置为容器表示启用了容器中的进程的特权模式,这样它们可以像主机系统一样执行某些任务,并且可以执行特殊的内核级别操作,例如打开主机设备草稿并编译设备驱动程序等。

但是,需要注意的是,使用特权模式可能会带来一些潜在的安全风险,因为容器中的任何攻击者都具有与主机相同的访问级别。因此,在使用特权模式时,需要非常小心,并且只应该在必要的情况下使用。

所以,老师提到的坑是指必须小心地使用“privileged=true”来确保不会引入安全风险,而不是随意地使用特权模式来访问主机上的特权操作。

我们在笔记本电脑上存储重要数据的时候会外置活动硬盘或将数据上环到阿里云盘等操作来保护数据,到了docker容器上我们以数据卷的方式,完成数据的持久化,将数据映射目录以后,完成重要数据的备份和持久化到本地主机目录上。

卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统(不属于容器内的),因此能够绕过Union File System提供一些用于持续存储或共享数据的特征:卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。(有点类似于我们Redis里的rab和aof文件),能够解决将docker容器内的数据保存进宿主机的此版当中的问题。

运行一个带有容器卷存储功能的容器实例:docker run -it --privilege=true -v /宿主机绝对路径目录:/容器内目录 镜像名

相比于我们之前学习的cp或export复制与导出,容器卷能够实时跟进我们的进程,要更加方便强大。


31_容器卷和主机互通互联 P31 - 00:11


docker inspect 容器ID可以查询到容器与哪个挂载(Mounts),这个v可以挂载多个。


32_容器卷ro和rw读写规则 P32 - 00:34



33_容器卷之间的继承 P33 - 00:20


安装Tomcat

  1. 在docker hub上查看tomcat镜像:docker search tomcat(我这里使用链接进行的下载:使用以下链接中的其中一个代替您的下载链接:wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.53/bin/apache-tomcat-9.0.53.tar.gz)我们可以通过docker search tomcat来检查是否安装成功。
  2. 从docker hub上拉取tomcat镜像到本地:docker pull tomcat
  3. 查看是否拉取到了tomcat:docker images tomcat

使用tomcat镜像创建容器实例:docker run -it -p 8080:8080 tomcat(-p小写:指定端口。-P大写:随机端口。-i:交互。-t:终端。-d:后台)【使用-it选项可能会导致容器启动时图形用户界面无法加载。因此,建议使用-itd选项,该选项表示以交互式、终端和守护进程模式运行容器。这样做后,容器将在后台运行,并且可以使用docker attach <container-name>命令重新进入容器】

连接数据卷容器

容器连接

  1. 连接数据卷容器是使用docker run时加入参数-volumes-form CONTAINER,即可将数据卷容器中的数据卷挂载到新的容器中。
  2. 可以多次使用-volumes-form参数来瓜子啊多个数据卷容器。

容器连接

  1. 数据卷容器中的数据卷时集成的,例如容器B通过-volumes-from挂在了容器A中的/data数据卷,容器C通过-volumes-from挂载了容器A中的/data数据卷,容器C通过-volumes-from挂载了容器B,则容器C中也挂载了/data数据卷。
  2. 数据卷容器本身不需要启动,挂载它的容器中也能挂载到所需的数据卷。

Docker常规安装简介

  1. 搜索镜像
  2. 拉取镜像
  3. 查看镜像
  4. 启动镜像——-p服务端口映射
  5. 停止容器
  6. 移除容器

Dockerfile简介

官网:https://docs.docker.com/engine/reference/builder

dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本,让镜像一次成型。

我们的电脑上装了docker实例,而dockerfile是独立在外面的,假设我们run了一个Ubuntu实例,我们用commit来不断地升级这个images,而dockerfile可以自己编写写好这个文件,构建成一个新的镜像,最终形成一个新的images。

构建三步骤:

  1. 编写dockerfile文件
  2. docker build命令构建镜像
  3. docker run依镜像运行容器实例

dockerfile内容基础知识:

  1. 每条保留字指令都必须大写字母且后面要跟随至少一个参数
  2. 指令按照从上到下按顺序执行。
  3. #表示注释
  4. 每条指令都会创建一个新的镜像层并对镜像进行提交

docker执行dockerfile的大致流程:

  1. docker从基础镜像运行一个容器(我们镜像的源代码就是我们的模板)
  2. 执行一条指令并对容器作出修改(在dockerfile里进行编排,就是将以前一个命令所做出的操作汇总成了一个文件,多个命令都汇聚到这个容器当中)
  3. 执行类似docker commit的操作提交一个新的镜像层
  4. docker再基于刚提交的镜像运行一个新容器(层层叠层层)
  5. 执行dockerfile中的吓一条指令直到所有指令都执行完成
  1. Dockerfile,需要定义一个Dockerfle,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等。
  2. Dockerfile镜像,再用Dockerfile定义了一个文件之后,docker bulid时会产生一个Docker镜像,当运行Docker镜像时会真正开始提供服务。
  3. Docker容器,容器是直接提供服务的。

环境变量

  1. 环境变量的作用:
  2. 环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息。
  3. RUN,CMD,ENTRYPOINT等命令都可以使用环境变量。
  4. ENV命令用于定义环境变量的值,该值也可以引用已定义的环境变量。
  5. 操作系统内部已经定义好的环境变量可以在Dockerfile中直接使用
  6. 更灵活的环境变量设置
  7. 更灵活的环境变量配置:
  8. 如果一些环境变量的值容易发生改变,我们可能不希望总是修改Dockerfile,那么可以将这些环境变量的值的语句放在.bashrc和.profile等文件里,使用以下语句,在构建时更新环境变量
  9. 如在.bashrc里加入export SERVER_IP=10.10.0.1;
  10. Dockerfile里写入:
  11. COPY .bashrc ~/.bashrc
  12. RUN source ~/.bashrc && curl -sL http://$SERVER_IP/readme.txt
  13. 根据命令结果设置环境变量并永久保存:有一种需求是这样的,在构建镜像时下载软件,需要将软件的版本号设置为环境变量,容器启动时的程序需要调用到这个环境变量。因为构建镜像时软件版本可能更新,此版本号不是固定值,需要使用命令解析。假如说命令curl -v --silent a.com/repos/files 2>& 1 | cut –c 15-能够获得版本号,则在Dockerfile如下写法可以实现需求:RUN bash -l -c 'echo export VERSION="$(curl -v --silent a.com/repos/files 2>& 1 |    cut –c 15-)" >> /etc/.profile';

虚悬镜像

虚悬镜像是指没有明确标记或没有被任何容器使用的Docker镜像。这些镜像占用着系统的存储空间,同时也可能会引起镜像命名冲突和漏洞等问题。本文将介绍如何了解并管理虚悬镜像的过程。

查看虚悬镜像

要查看系统中是否存在虚悬镜像,可以使用以下命令:

docker images -f dangling=true

这个命令会罗列出所有没有使用任何标签或者没有被任何容器所引用的镜像,即虚悬镜像。

删除虚悬镜像

为了释放系统的存储空间和提高整个系统的安全性,需及时删除虚悬镜像。可用以下命令删除所有虚悬镜像:

docker rmi $(docker images -f "dangling=true" -q)

此命令自动删除所有未被引用的镜像,释放存储空间。

防止产生虚悬镜像

及时清理不再需要的镜像,避免占用空间和引起别名冲突。

镜像优化

镜像优化原则:

  1. 如不加以注意并且优化,镜像的体积会越来越大
  2. 镜像的优化有以下原则:
  3. 尺寸尽量小
  4. 构建速度尽量快
  5. 网络访问尽量快

精简镜像尺寸:

  1. 选择体积最小的基础镜像可有效降低镜像体积
  2. 构建镜像的过程中,当dockerfile的指令执行完成后,删除镜像不需要用的的文件。
  3. 在使用dockerfile构建镜像时,dockerfile中的每一条指令都会生成一个层,因此可以尽量合并dockerfile中可合并的指令,减少最终生成镜像的层数。

精简镜像尺寸之多阶段构建:

在一个Dockerfile里使用多次FROM命令可以达成多阶段构建的效果

多阶段构建的使用场景是将编译环境和运行环境分离,比如,之前我们需要构建一个Go语言程序,那么就需要用到go命令等编译环境,但运行时并不需要这些编译环境,只需要运行环境,则可以分两个阶段构建,第一阶段编译,第二阶段构建运行镜像,最后生成的镜像将不包含编译环境:

# 编译阶段 命名为 builder 

FROM golang:1.10.3 as builder # ... 省略编译步骤 

# 运行阶段 

FROM scratch 

# 从编译阶段的中拷贝编译结果到当前镜像中 

COPY --from=builder /build/server /

提高网络访问速度:

  1. 使用国内的源下载软件包。
  2. 所有可下载的网站上,找访问速度最快的。
  3. 如必须访问国内的网站,寻找速度最快的代理服务器。

其他优化事项:

  1. 精简镜像用途,避免构造大而复杂、多功能的镜像;
  2. 在Dockerfile中提供注释和维护者信息;
  3. 正确使用版本号,镜像中使用到的软件应给出明确的版本号;
  4. Dockerfile中下载软件时应指明持久的下载地址,并带有明确的版本号。 

Dockerfile保留字简介:

Dockerfile是一种定义Docker镜像的文本格式,并包含了一组Docker容器运行的指令。Dockerfile保留字是在Dockerfile中定义的关键字或指令。在Dockerfile中使用这些指令,可以配置和构建Docker镜像。

以下是Dockerfile中的一些常见保留字:

  1. FROM:该指令从指定的基础镜像中创建一个新的镜像。
  2. RUN:该指令在Docker容器内部执行指定的命令,并且记录下镜像的更改历史。RUN指令可以包含shell脚本、shell命令、python代码等。
  3. RUN命令可用于在镜像中执行任意合法shell命令并提交结果。
  4. RUN命令是创建Docker镜像的步骤,RUN命令对Docker容器造成的改变是会被反映到创建的Docker镜像上的。
  5. 一个Dockerfile中可以有许多个RUN命令,每一个RUN命令将生成一个新的镜像。
  6. 根据命令结果设置环境变量并永久保存
  7. COPY:该指令将主机上的文件或目录复制到容器内部的指定目录。
  8. WORKDIR:该指令设置容器的工作目录,所有后续的指令都在该目录下执行。
  9. WORKDIR <path>
  10. WORKDIR指令为Dockerfile中的任何 RUN、CMD、ENTRYPOINT、COPY 和 ADD指令设置工作目录。
  11. 如果WORKDIR不存在,即使在后续的Dockerfile指令中不使用它,也会创建它。
  12. WORKDIR指令可以在Dockerfile中多次使用。
  13. 如WORKDIR指定的是一个相对路径,它将相对于前面的WORKDIR指令的路径。
  14. EXPOSE:该指令声明容器将在运行时使用的端口。
  15. EXPOSE <端口1> [<端口2>...]。
  16. EXPOSE 指令的作用是声明运行时容器提供服务端口。这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。
  17. 运行容器时使用命令docker run -P时,会自动将容器上EXPOSE 声明的端口映射到宿主机上随机的端口。
  18. 若需指定将容器的端口映射到宿主机指定端口,请在运行容器时使用命令docker run –p <宿主机端口>:<容器端口>
  19. ENV:该指令在容器内设置环境变量。
  20. ENV <环境变量名>=<变量值>
  21. ENV指令用于定义镜像的环境变量,被定义的环境变量在后续层次的镜像中和启动的容器中能够被以“$环境变量名”的方式使用
  22. 变量值中可以引用已经定义的环境变量。以下环境变量可以直接引用:
  23. HOME,用户主目录
  24. HOSTNAME,默认容器的主机名
  25. PATH,可执行文件查找路径列表
  26. TERM,默认xterm
  27. ARG:该指令用于在构建(build)镜像时设置变量。
  28. ARG <name>[=<default value>]
  29. ARG指令用来定义构建时需要的参数,这些参数在docker build命令中以--build-arg <name>=<value>形式赋值
  30. 如下参数可以直接使用:
  31. HTTP_PROXY 和 http_proxy
  32. HTTPS_PROXY 和 https_proxy
  33. FTP_PROXY 和 ftp_proxy
  34. NO_PROXY 和 no_proxy
  35. VOLUME:该指令声明容器卷,并为容器卷分配位置。
  36. USER:该指令在容器中设置运行容器进程的用户名或UID。
  37. USER <user>[:<group>]
  38. USER <UID>[:<GID>]
  39. USER指令设置用户名(或UID)以及可选的用户组(或GID),以便在运行映像时以及Dockerfile中跟随它的任何RUN,CMD和ENTRYPOINT指令时使用。
  40. 在docker run 中可以通过 -u 选项来覆盖USER指令的设置。
  41. 不指定USER时,默认用户为root;USER不指定group时,默认组为root。
  42. 使用root以外用户或组时,请先用RUN命令创建。
  43. CMD:该指令提供了容器的默认命令。它可以在Dockerfile中指定或者在启动容器时通过docker run命令进行覆盖。

这些保留字并不是Dockerfile中的全部指令,但它们是使用最为广泛的指令之一,每个Dockerfile都应该包含其中的一些。使用这些Dockerfile保留字,Docker用户可根据自己的需要和应用程序的特点,定义和配置自己的Docker镜像。


61_centos之dockerfile案例演示 P61 - 00:25


原生网络

docker安装时会自动在host上创建三种网络(bridge、host、none),可以用docker network ls命令查看,除此之外还有container网络模式,及自定义网络。

  1. none网络:none网络就是什么都没有的网络。挂在这个网络下的容器除了lo,没有其他任何网卡,创建容器时,可以通过--network=none指定使用none网络。
  2. none网络的应用:
  3. 一些安全性要求高并且不需要联网的应用可以使用none网络。
  4. 比如某个容器的唯一用途是生成随机密码,就可以放到none网络中避免密码被窃取。
  5. 使用none网络的容器只能够通过数据卷和外界交互。
  6. host网络:连接host网络的容器共享主机的网卡,容器的网络配置与宿主机完全一样。可以通过--network=host指定host网络。
  7. host网络的应用:
  8. host网络最大的好处就是性能,如果容器对网络传输有较高要求,则可以选择host网络。当然不便之处就是牺牲一些灵活性,比如要考虑端口冲突,宿主机上已经使用的端口不能再用了。
  9. host网络的另一个用途是让容器可以直接配置host网络。比如某些跨主机的网络解决方案,各主机上的应用以容器方式运行的时候。
  10. bridge网络:bridge网络又名桥接网络,在该网络模式中,宿主机上提供一个网关,其他同一网络的容器连接到网关,共同组织一个局域网。docker安装时会创建一个命名为docker0的缺省网关。启动容器时不指定network的容器将会以docker0为网关。安装bridge-utils后使用brctl show命令可查看所有网关。
  11. bridge网络可以让容器之间互相组建局域网,拥有自己的虚拟网卡,但只是有一个虚拟网关因此适合比较小型的容器网络。
  12. 自定义网络(实例)
  13. docker提供三种用户自定义网络驱动:bridge、overlay和macvian。
  14. bridge网络与自带的bridge网络类似,只是用户可以自己创建网关。
  15. overlay和mavaian用于创建跨主机的网络。
  16. 具体实例如下:我们可以通过bridge驱动创建类似前面默认的bridge网络:

这是创建 Docker 网络的命令,其中 sudo 表示以超级管理员身份运行命令,docker 是 Docker 的 CLI 工具,network create 是创建网络的命令,--driver bridge 指定了网络驱动类型为 bridge(Docker 默认使用的网络驱动),mini 是网络名,可以根据需要自行指定。

使用这个命令创建网络后,可以让在同一网络下的 Docker 容器互相通信,实现更灵活高效的应用程序部署和管理。例如,可以在同一网络下运行不同的容器,它们可以通过指定容器名称来相互访问和通信,实现协同工作和数据共享等功能。

可以用brctl show查看新创建的网关

这是在 Docker 中运行 BusyBox 容器的命令,并将容器连接到名为 mini2 的网络中。其中 sudo 表示以超级管理员身份运行命令,docker 是 Docker 的 CLI 工具,run 指启动一个新的容器, -it 则启用交互式 shell, --network=mini2 指定了网络,便让新容器加入到这个网络下。

启动容器后,会进入 BusyBox 的 shell 环境,可以在这个环境下运行各种命令,例如 ls、ping 等,进行测试或调试操作。同时,通过网络连接,这个容器也可以与其他网络中的容器和主机进行通信,实现更复杂的应用程序部署和管理。

如需要配置容器的静态IP,如果创建网关时指定了--subent参数,即可通过在启动容器时指定参数--ip来设定静态IP。

container网络:新建的容器和已存在的一个容器共享一个网络ip配置而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。(俩嘴共用一个习惯喝同一杯奶茶:容器A借用容器B的网络实现功能)

Alpine Linux 是一款独立的、非商业的通用 Linux 发行版,专为追求安全性、简单性和资源效率的用户而设计。 可能很多人没听说过这Linux 发行版本,但是经常用 Docker 的朋友可能都用过,因为他小,简单,安全而著称,所以作为基础镜像是非常好的一个选择,麻雀虽小五脏俱全,镜像非常小巧,不到6M的大小,所以特别适合容器打包。


74_docker network之container P74 - 04:52


自定义网络(docker容器内部的ip是可以发生改变的):

曾经用的是docker link,但这个功能在不久将会被移除,因此就不被用了。那么两个问题:

  1. 没用前是怎样的效果:
    
    75_docker network之自定义网络上集 P75 - 02:26
    
    网段按照服务名是ping不通的
  2. 用了后是怎样的效果:
  3. 自定义桥接网络(默认使用的桥接网络是bridge)
  4. 新建自定义网络(docker network network_name)
  5. 新建容器加入上一步新建的自定义网络:
    
    77_docker network之自定义网络下集 P77 - 01:27
    
  6. 互相ping测试:自定义网络就维护好了主机名和ip的对应关系(ip和域名都能通)

Docker轻量级可视化工具——portainer

portainer是一款轻量级的应用,它提供了图形化界面,用于方便地管理Docker环境,包括单击环境和集群(更建议用k8s)环境。

安装方式:

  1. 官网
  2. https://www.portainer.io/
  3. https://docs.portainer.io/v/ce-2.9/start/install/server/docker/linux
  4. 步骤

docker run除了可以挂多个v容器数据卷,也可以搞多个p端口映射。--restart=always代表如果整个docker重启了,这个容器也可以重启,保证实时在线,实时监控。如下图所示:我们加了--restart=always之后的容器实例没有像u1一样因为重启而挂掉。

  1. docker命令安装
  2. 的第一次登录需创建admin,访问地址:xxx.xxx.xxx.xxx:9000(xxx是主机ip地址,用户名就用默认的admin即可)
  3. 设置admin用户和密码后首次登录
  4. 选择local选项卡后本地docker详细信息展示,

Dashboard(仪表盘)盘点我们的家底,有多少镜像、容器等。图像化显示了有多少个容器(containers)、多少个镜像(images)、多少个容器卷(volumes)、多少个网络(network),而第一个Stack意思是有几组编排的容器。左边的events是事件的意思,日志操作。host是主机的基本情况。

以上的图形化命令我们可以通过命令:docker system df查看。


88_Portainer常规操作 P88 - 01:26


CIG(容器重量级监控系统)是一款由百度开发的开源容器监控和分析工具。它可以帮助用户监控Docker容器的性能、资源使用情况和应用程序的运行情况。CIG提供了图形化的仪表盘和报告,使得用户可以随时了解应用程序和容器的状态,并对其进行分析和优化。

CIG的主要组件包括cAdvisor、Prometheus、Grafana和Alertmanager。其中,cAdvisor是由Google开发的轻量级容器监控工具,用于收集Docker容器的性能指标和资源使用情况;Prometheus是一种开源的引擎,用于处理和存储时间序列数据,也是CIG的核心组件之一;Grafana是一种开源的灵活的仪表盘和监控平台,使用户可以创建和共享实时数据可视化,并且提供了多种插件和数据源扩展;Alertmanager是一种开源的警报管理工具,负责接收警报并将其转发到用户定义的接收端。


93_CIG添加panel P93 - 00:19


CIG是一种非常流行的Docker容器监控系统,它可以帮助用户监控容器的性能和资源使用情况,同时也提供了其他有用的特性。在使用Docker Compose搭建CIG监控平台的过程中,需要注意对Prometheus和Alertmanager进行适当的配置以便让它们能够正常工作。Grafana是CIG的核心。


92_CIG三平台登陆验证通过 P92 - 00:02


CIG配置监控业务规则

在学习CIG配置监控业务规则的过程中,需要注意以下几个关键环节:

定义需求:在设置业务规则之前,需要明确业务规则的目的和需要检查的内容。例如,需要检查某个服务是否正常运行或特定设备的状态是否正常等。

确定规则类型:CIG支持多种类型的业务规则,包括简单规则、复合规则、计算规则和自定义规则等。根据需求选择适合的规则类型。

编写规则脚本:根据需求和规则类型编写规则脚本。规则脚本中应包括规则名称、检查条件、动作以及其他必要的元素。脚本应该经过验证和测试,确保其能够正确地检查和报警。

设置规则匹配条件:定义规则的匹配条件,以确保规则只适用于特定的服务器或设备,避免出现误报和漏报等情况。

测试规则:在应用规则之前,需要对规则进行测试和验证,确保规则的准确性和有效性。可以通过模拟特定的故障或问题进行测试并检查CIG是否能够正确地检测到和报告这些问题。

应用规则:当规则已经通过测试和验证后,将规则应用于监控系统。在应用规则之后,需要进行定期维护和更新,以确保规则的持续有效性。



尚硅谷Docker实战教程(docker教程天花板)的评论 (共 条)

分享到微博请遵守国家法律