Docker生产环境实战从0-1学习基础指南——快速掌握

Docker是什么?

Docker 是一个开源平台,用于开发、打包、分发和运行容器化应用程序。

  • 关键点:
    • 容器化应用:把应用程序及其所有依赖(代码、库、环境变量、配置文件)打包在一起。
    • 轻量隔离:每个容器是独立的,但共享宿主机操作系统内核。
    • 跨平台一致性:同一个容器在开发环境、测试环境、生产环境都能一样运行。

容器和 Docker 的关系

概念 描述
容器 (Container) 一种轻量级、可移植的运行环境,隔离应用和系统依赖
Docker 管理和运行容器的工具/平台,提供打包、分发和运行能力

Docker 是容器的"管理和操作平台",容器是 Docker 的"载体"。

Docker 的核心组成

Docker Engine

  • Docker 的核心组件
  • 负责创建、运行和管理容器

Docker 镜像(Image)

  • 应用及其依赖的静态模板
  • 可以版本化、共享

Docker 容器(Container)

  • 镜像的运行实例
  • 是应用真正运行的环境

Docker Hub

  • 官方镜像仓库
  • 可以下载已有镜像,也可以上传自己制作的镜像

Docker的技术原理

docker利用了linux内核的两大原生功能实现容器化技术。Cgroups用来限制和隔离进程的使用资源,可以为每个容器设置CPU、内存、网络带宽等资源使用,确保一个容器的资源消耗,不会影响到宿主机。NameSpaces用来隔离进程的资源视图,NameSpaces使得容器只能看到自己内部的进程ID而看不到宿主机的。所以容器本质上还是一个特殊的进程。想要在windows系统下查看一个容器内部的进程,可以使用docker top命令。因为容器内部进行了资源视图的隔离,所以说容器内部无法看到附主机的一个进程情况。

Docker 产生的背景

软件部署复杂化 :传统的开发环境和生产环境常常不一致,开发者在自己的电脑上能跑,部署到服务器上可能就报错:"在我电脑上没问题啊!"

不同操作系统版本、不同依赖库版本、不同配置导致"环境不一致"问题非常普遍。
虚拟机的局限 :在 Docker 出现之前,解决环境问题的一个方法是使用 虚拟机(VM)。

虚拟机可以隔离环境,但虚拟机很重:每个虚拟机都有自己的操作系统,需要占用大量 CPU 和内存。启动慢,管理复杂。

对于大规模微服务或者需要快速启动的开发环境,虚拟机显得不够灵活。
微服务兴起 :互联网应用越来越倾向 微服务架构:把一个大应用拆成许多小服务。每个服务可能依赖不同的语言环境、不同的数据库版本、不同的库。管理和部署这些服务,需要一种轻量、高效、可重复的方式来保证环境一致性。

Docker 的出现

核心理念: "一次打包,到处运行"。

技术基础: 利用 Linux 的 容器(Container)技术(cgroups + namespace)来实现轻量级隔离。

虚拟机 Docker 容器
重量级,需要完整操作系统 轻量级,共享宿主机内核
启动慢(分钟级) 启动快(秒级)
占用大 占用小
管理复杂 易于版本化、移植和部署

Docker解决的问题

环境一致性
  • 开发环境、测试环境、生产环境完全一致。
  • 解决了"在我电脑能跑,但上线就报错"的经典问题。
快速部署与扩展
  • 容器启动快,像启动一个进程一样简单。
  • 很适合云端和微服务环境,方便水平扩展。
资源隔离
  • 容器之间互相隔离,防止软件冲突。
  • 可以限制容器的 CPU、内存使用量。
便于持续集成/持续部署(CI/CD)
  • Docker 镜像可以版本化,代码 + 依赖打包在一起。
  • 自动化构建、测试、部署都可以用相同镜像,保证一致性。
轻量化替代虚拟机
  • 更节省硬件资源。
  • 能在同一台服务器上跑更多实例。

Docker重要命令

docker pull

docker pull 命令用于从官方镜像仓库下载镜像。以下面这个示例命令进行讲解:

bash 复制代码
docker pull docker.io/library/nginx:latest

首先,这条命令有4部分:

  • docker.io。一般叫registry(仓库地址),是docker仓库的注册表地址,docker.io表示,这是Docker Hub的官方仓库地址。如果你使用官方仓库的地址拉取镜像的话,其实是可以省略的。 即命令可以变为后面这一条:
bash 复制代码
docker pull library/nginx:latest
  • library。library是命名空间。因为docker hub是公共仓库,每个人都可以上传自己的一个镜像。为了防止许多人上传同一个镜像而导致混乱,所以要求对所有上传的定像都得进行一个命名。即library也是命名空间的意思,用来命名作者自己的名字。library是docker官方仓库的命名空间的名字,只要带上这个命名空间下载的镜像,都是从官方公共维护的仓库里面获取的。一般来说,如果是官方的命名空间------即library的话,那么实际上也可以省略这一个词。命令就进一步简化为如下:
bash 复制代码
docker pull nginx:latest
  • nginx。是你要下载的镜像的一个名字,用来下载对应的镜像的名称。输入什么镜像的名字,就代表你要下载什么样的镜像。

  • :latest。这部分是docker镜像的一个标签名(版本号)。一个软件它都有对应的一个版本号的。如果我们需要特定的版本号,我们可以在冒号后面添加对应的一个数字信息。如果没有的话,希望是最新的一个镜下,那么就直接加上latest就行了。**当然,如果你是想要获取关于这个镜像最新的版本,那么这个冒号latest就可以省略不写,它会默认拉取的是最新的一个版本。**这样终端命令就进一步简化为了这一句:

bash 复制代码
docker pull nginx

上面四部分讲完之后还要讲一下一部分合起来的叫法:

repository:镜像库(存放一个镜像的不同版本)。 下面这一串整合起来就是一个镜像图。具体形式是:

bash 复制代码
docker.io/library/nginx

比如说,docker hub一整个网站就是一个镜像库。然后对应的一个nginx是repository,存储了同一个镜像的不同版本。

docker images

这个命令就是用来查看docker下载过的一个镜像。

docker rmi

dockerI的意思就是用docker删除对应的一个镜像。后面跟上镜像的名字或者ID,就可以删除对应的一个镜像。

docker run

docker run是指使用镜像创建并运行容器的一条指令。run后面可以贴一个镜像的名字,或者是对应镜像的ID表示它要运行哪一个镜像创建一个容器。当这条指令完成之后,创建出来的一个容器,它就会运行起来。如果想要查看运行状态,可以使用docker ps进行查看。一般来说,如果要创建并运行容器的话,会附加一个参数-d,表示让容器在后台静默的运行,不阻塞当前的一个窗口。事实上,我们只需要运行docker run命令,就可以将对应的镜像给启动起来。即使这个镜像没有通过doker pull拉取也是可以的。

docker run还有一个重要的参数:-p。表示用来端口映射即宿主机和容器的端口要怎样映射的关系。每个docker容器都运行在独立的一个虚拟机环境当中。容器的网络与宿主机是隔离的。默认情况下,并不能从宿主机对应的端口访问到容器内部对应的端口。这时候就需要-p参数进行一个一一的一个端口映射。比如 -p 80:80。冒号前面是竖级的端口,冒号后面是容器内的端口。这样子的指令表示了宿主机与容器内的端口映射,即可以通过数主机的这个端口号访问到容器内部这个对应映射的端口号。

还有一个重要参数叫做-v。挂载卷。由于docker是无状态的,所以说我们需要一个数据挂载卷来做一个数据持久化的操作。-v相当于把宿主机和容器的文件目录进行绑定,容器内对这个文件夹的修改会影响宿主机的文件夹。而在宿主机对文件夹的修改,也会影响到容器里面的数据。宿主机和容器通过这个目录进行数据共享以及视久化。这种目录称为挂载卷。这种挂载方式称为(绑定挂载)。

还有一种数据持久化操作是:创建一个存储空间(命名卷)

-V 卷的名字:容器内目录(这种叫做命名卷挂载)

docker run 其他参数

比如说-e参数可以用来往容器里面传递环境变量。如果不清楚容器的环境变量有哪些,可以去docker hub寻找。还有一个--name,用来给镜像的容器取名,这个取名必须在整个数主机上都是唯一的。还有-it。可以让我的控制台进入容器进行交互。--rm指的是当容器停止之后,会自动把删除。

一般-it和--rm连起来用的。用来暂时性的调试一个容器。--restart always。用来配置容器在停止时的重启策略。(包含容器因为内部错误崩溃而导致的停止它也会重启,或者宿主机断电)。还有一个是--restart unless-stopped。(这跟always的区别是手动停止的容器unless-stopped不会再重启)。docker会自动重启,因为意外原因而停止了容器。但是手动就不会。

docker run内核理解

doper run首先它会根据镜像,然后创建出一个新的容器,要是每次都运行docker run来启动镜像的话,它会创建很多个容器如果我们只想对原有的一个容器进行开始和结束。那么我们可以使用以下命令:docker start 和 docker stop

Docker Hub

docker hub是docker的一个官方的一个镜像仓库。如果我们有需要的镜像的话,可以来这边进行一个搜索。具体的windows的一个桌面版的一个docker操作界面如下:

或者直接去搜索这个网址:https://hub.docker.com/

DockerFile

如果把镜像比作模具,那么容器就是通过模具做成的东西。那么dockerfile就是制作模具的图纸。详细说明了镜像如何制作。这里以一个最简单的代码文件作为实战。以下需要两个文件:

当我们能够再网页中搜索8000端口然后返回hello world就说明成功了。

首先,想要启动好当前的这两个文件,核心步骤是三步:

  • 一给这个项目安装Python环境
  • 二是下载对应的依赖
  • 三是运行main.py文件

可以先在当前目入文件夹下创建一个dockerfile文件。

dockerfile文件的第一行一定是from。选择一个基础镜像,也就是我们的这个镜像是从哪个镜像的基础上构建过来的,我们希望基础镜像它自带python环境,那么就要from python。可以从docker hub上查找对应所需要的基础镜像。dockerfile文件准备好之后如下:

构建镜像打包并上传到自己的docker hub仓库中

之后开始再终端构建镜像。运行这条命令:

bash 复制代码
docker build -t docker_test .

docker build。使用 Dockerfile 构建镜像

-t。参数表示标签名,后面是自定义的名称。标签名后面如果跟上:<版本号>的话就是对应的镜像版本。没有的话默认latest

最后的一个.表示当前目录。Docker 会把这个目录里的文件打包给构建过程使用。对应你的dockerfile里面的COPY . .

构建完毕之后终端输出情况如下:

构建完这个镜像之后,我们可以从docker run来运行这个镜像,让它创建一个容器实例。运行命令:docker run -d -p 8000:8000 docker_test。

然后通过docker ps能够查看当前正在运行的一个容器。

如果想把自己已经构建好的这个镜像推送到自己的一个仓库里面的话,首先需要在终端先登录一下docker。由于我本地已经登录过docker了,所以说我话没有出现什么英文验证码的情况。

登录进来之后,就把这一个镜像推送到自己的一个仓库下。然后在推送自己想要推送的镜像之前,必须得在命名空间那边署名自己的一个docker名字。下面这条指令中的namespace是我自己docker账号的用户名,推送自己的一定是要用自己的用户名的。

构建完新的一个镜像,带有自己署名的镜像之后就可以进行推送了。推送用的指令是docker push

推送完成的终端输出效果如下:

这时候可以在docker hub上,根据我的命名空间以及镜像名称,就可以搜索到我刚才推送的那个镜像了,如下图所示:

Docker网络

docker网络默认是bridge,也就是桥接连接。所有容器都默认连接到这个网络。每个容器内部都默认分配1个IP地址,一般是172.17开头。在这个内部子网里面,容器可以通过这个内部IP地址进行互相访问。但是容器网络与宿主机的网络是隔离的。可以使用以下命令创建出子网:docker network create network1。默认情况下创建出来的子网也是属于桥接模式的一种。然后可以指定容器加入不同的一个子网。同一个子网的容器可以互相通信。但是跨子网则不可以通信。创建子网还有一个好处:同一个子网的容器,可以使用容器的名字互相访问,而不必使用内部IP地址。

还有一种docker网络的模式是host模式。docker容器直接共享宿主机的网络。容器直接使用宿主机的IP地址。不需要-p参数进行端口映射。host模式可以解决一些棘手的网络问题。

最后一种docker网络模式是none模式。如果想要查看docker网络有几种模式,可以输入一下命令。

bash 复制代码
docker network list

不要的子网可以通过docker network rm <网络ID>

DockerCompose

有时候一个完整的应用是有很多部分组成的。比如说前端、后端、数据库等。这时候如果想用docker对他们进行一个容器化操作。一般会想到将这些都打包在一起,做成一个巨大的一个容器,但实际上这样子的话,如果一个地方出现问题,整个容器都将变得无法可用。而且这样子打包完的容器,它可伸缩性差。如果你后期想要扩容的话,那么就又要重新再构建一个容器。做不到精准细扩容。多应用的最佳实践是把每一个模块都打包成一个独立的容器。 不过使用多容器的话,会增加一个使用的一个成本。因为如果你想创建多个容器,就必须多次执行docker run命令。还得把容器的网络配置好,尝试管理容器的时候,很多地方可能会出问题。这时候就需要运用到容器编排技术:Docker Compose 。Docker Compose 使用 YML 文件管理多个容器。YAML 文件里面列出了容器之间是如何协作工作和管理的。可以先简单的把 Docker Compose 文件理解成一个或多个的 run 命令。按照特定的格式列到了一个文件里面。

这边我们以左边自己手动输入的一个命令,以及右边 Docker Compose.yaml 文件对比进行举例。左右两边唯一的区别就是左边有运行一条创建子网的命令,而右边没有。这是因为 Docker会为每一个 Docker Compose 文件自动创建一个子网,同一个 Compose 文件里面定义的容器都会自动加入在同一个子网当中。Docker Compose 文件还有一个额外的功能,就是可以自定义容器的一个启动顺序。通过 VMIM编辑好了 docker compose.yaml 文件之后,我们就可以运行一串指令来启动这一个 docker compose 文件。

bash 复制代码
docker compose up -d

执行上面这串命令之后,出现的容器会加一些前缀或者编号,用来更方便的管理。

与启动相反的命令就是将 UP 改为 DOWN。这个 down 命令会停止并且删除对应的一个容器实例。如果只想停止,不想删除容器的话,可以将这个 down 改为 stop。如果想要把通过 stop 停止的容器实例再启动起来的话,可以用 start。

如果你编写的 Docker Compose .yaml 文件不是标准的命名方式的话,你可以加上 -F 参数,指定对应路径下或对应位置的一个 YAML 文件进行启动。比如假设你有一个 test.yaml 文件,这个文件它其实里面写的是 Docker 相关的配置内容,那么你就可以运行下面这串命令来运行这一个 YAML 文件。

bash 复制代码
docker compose -f test.yaml up -d

Docker Compose 是一个轻量级的容器编排技术,对于个人的单机运行测试是有用的。对于企业级的服务器集群需求,大规模的容器编排需求的话,需要用到 K8s。

基础演示部分(Windows)

下面我们来演示通过docker拉取使用nginx,并且成功在数主机中访问到容器内的nginx服务。

之前说过,如果本地没有对应的这个nginx镜像,只要你通过docker run命令,它就会自动的去解决你这个问题,从而拉取到nginx镜像,并且成功运行。

比如直接运行,docker run -p 80:80 nginx

之后可以看到当前这个nginx正在运行,由于我们没有加上-d参数因此它直接阻塞了当前这个窗口

这时候我们可以到本地宿主机的网址上去搜索这个网址,看看能否进入到nginx的一个欢迎页。可以看到如下所示:

下面演示一部分关于加入数据卷的操作。首先要把刚才启动的nginx删除了。然后重新输入指令,带上数据卷。

首先我们需要创建一个挂载卷。命令如下:

bash 复制代码
docker volume create nginx_html

之后可以运行如下指令:

bash 复制代码
docker run -d -p 80:80 -v nginx_html:/usr/share/nginx/html nginx

之后会得到一串nginx的ID容器号。当我们想要查看这个挂载卷的位置在哪里的时候,我们可以运行如下指令:

bash 复制代码
docker volume inspect <挂载卷的名字>

首先如果你想修改这一个文件的话,那么你需要先进入到WSL中,然后切换成root用户才可以。因为实际上查出来的inpect路径,它是linux这个系统里面的路径,不是windows硬盘的一个路径。

这个命令显示的是docker内部看到的路径。实际上在WSL中,如果去转到这个目录下,可能会是找不到的。因此,这边在windows系统下使用中转容器是最方便的。

首先查看一下当前电脑的WSL中有多少个实例。

然后使用Ubuntu来充当中转容器。

之后再按照图中如下的指令输路,就能够成功的去编辑docker里面的这个文件。

这边为了测试,直接输入这句命令:

linux 复制代码
echo "<h1>Hello Docker! I changed this file.</h1>" > /target_data/index.html

接下来直接访问这一个nginx网页,看看有没有覆盖的这一句话。

效果如下:

以上是 Docker 的一些基础的实用命令。如果还要了解更详细的话,可以去 Docker 官网查看。

相关推荐
郑寿昌1 小时前
K8s中GPU智能体扩缩容的显存碎片优化
云原生·容器·kubernetes
KuaCpp1 小时前
Docker从0到1学习
学习·docker·容器
ting94520001 小时前
动手学深度学习(PyTorch版)深度详解(1)(含实操+避坑)
pytorch·深度学习·学习
nervermore9901 小时前
3. 人工智能学习-PyTorch框架学习
人工智能·pytorch·学习
handler012 小时前
进程状态流转的本质:Linux 内核队列与底层数据结构解密
linux·运维·c语言·数据结构·c++·笔记·学习
Shan12052 小时前
大学计算机初学者之学习课程推荐
学习
Nice_Fold2 小时前
Kubernetes探针机制与Deployment控制器(自用笔记)
笔记·容器·kubernetes
memoryjs2 小时前
鸿蒙系统进一步学习(二):ArkUI底层原理揭秘
学习·华为·harmonyos
燐妤2 小时前
前端HTML编程2:深入学习表单与表格
前端·学习·html5