Docker 学习笔记

date
Mar 17, 2024
slug
Study-Notes-00
status
Published
tags
Docker
学习笔记
summary
一种新兴的虚拟化方式。
type
Post

为什么用Docker

一种新兴的虚拟化方式
传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而Docker容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。
Docker 对系统资源的利用率更高,不需要进行硬件虚拟以及运行完整操作系统等额外开销
Docker 容器应用直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间
Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性
Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署
Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的,可以更轻松的迁移

一些概念

  1. 镜像(Image):可以将镜像视为软件打包的模板。
    1. 功能:镜像是一个只读的文件,其中包含了运行应用程序所需的一切,包括代码、运行时环境、依赖项和配置。
  1. 容器(Container):容器是基于镜像创建的一个运行实例。
    1. 功能:可以将容器视为镜像的运行时进程,它是一个隔离的环境,其中可以运行应用程序和服务。
      特性:每个容器都具有自己的文件系统、网络和进程空间,可以独立运行应用程序。
  1. 仓库(Repository):仓库是用于存储和组织镜像的地方。Docker Registry服务器专门用来存放仓库一个 Docker Registry 中可以包含多个 仓库;每个仓库可以包含多个 标签;每个标签对应一个镜像。
    1. 通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。
      可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。
📌
镜像和容器关系的例子:
  1. 莎士比亚心中的哈姆雷特就像是一个镜像,观众在看了这个戏剧之后,在自己心中就有了一个哈姆雷特,观众心中的哈姆雷特就是容器。
  1. Python 中类和实例的关系,类是一个模板,实例是类的具体实现。

镜像操作

# 获取镜像 $ docker image pull [选项] [Docker Registry 地址[:端口号]/] 仓库名[:标签] # 旧版本的用法,也可以使用。 $ docker pull [选项] [Docker Registry 地址[:端口号]/] 仓库名[:标签] # [选项]:这是可选的参数,您可以在命令中添加一些选项来自定义拉取行为。例如,您可以指定镜像的版本、认证信息等。 # [Docker Registry 地址[:端口号]/]:这是可选的,用于指定仓库的地址和端口号。如果未提供,则默认使用 Docker 的公共仓库(Docker Hub)。 # 仓库名:这是要拉取的镜像所在的仓库的名称。仓库名可以是官方仓库中的镜像,也可以是您自己或其他人创建的仓库中的镜像。 # [:标签]:这是可选的,用于指定要拉取的镜像的标签或版本。如果未提供标签,则默认拉取最新版本的镜像。 $ docker pull hello-world # 获取 Docker Hub 的 hello-world 镜像的最新版本 # 查看镜像列表(顶层镜像) # 结果包含了仓库名、标签、镜像ID、创建时间以及所占用的空间(这里下载后解压的大小,DockerHub中显示的是压缩体积) $ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest ee301c921b8a 7 months ago 9.14kB $ docker image ls -a # 查看中间镜像(相同的层只会存一遍,而这些镜像是别的镜像的依赖,没必要删除) $ docker image ls ubuntu # 根据仓库名列出不同标签镜像 $ docker image ls ubuntu:18.04 # 指定仓库名和标签查看镜像 $ docker image ls --digests # 增加列出镜像摘要 $ docker image ls -f since=mongo:3.2 # 根据条件筛选镜像,列出 mongo:3.2 以后版本的镜像 $ docker image ls -f before=mongo:3.2 # 根据条件筛选镜像,列出 mongo:3.2 之前版本的镜像 $ docker image ls -f dangling=true # 查看虚悬镜像(由于新建和新拉取的镜像和已有的镜像同名,旧镜像名称和标签就会变为<none>成为虚悬镜像) REPOSITORY TAG IMAGE ID CREATED SIZE <none> <none> 00285df0df87 5 days ago 342 MB $ docker image prune # 删除虚悬镜像 # Docker系统的磁盘使用情况,查看镜像、容器、数据卷所占用的空间,返回类型、数量、大小、百分比等 $ docker system df TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 24 0 1.992GB 1.992GB (100%) Containers 1 0 62.82MB 62.82MB (100%) Local Volumes 9 0 652.2MB 652.2MB (100%) Build Cache 0B 0B # 删除镜像 $ docker rmi [选项] <镜像1> [<镜像2> ...] $ docker image rm [选项] <镜像1> [<镜像2> ...] # 旧版 # <镜像> 可以是 镜像短ID、镜像长ID、镜像名或者镜像摘要(ls默认列出的就是短ID) # 有些删除行为可能有Untagged:提示,说明是在取消镜像的标签; # 因为除了当前想要删除的标签,可能还有别的标签指向了这个镜像;也可能可能某个其它镜像正依赖于当前镜像的某一层;还有可能有用这个镜像启动的容器存在(即使容器没有运行) # 所以并非所有的 docker image rm 都会产生删除镜像的行为,有可能仅仅是取消了某个标签而已; $ docker image rm <镜像>@<镜像摘要> # 根据镜像摘要删除 $ docker image rm (docker image ls -q redis) # 根据条件查询删除 $ docker image rm (docker image ls -q -f before=mongo:3.2) # 根据条件查询删除 # 查看镜像历史 $ docker history nginx:v2 # 制作镜像 # 1.将已有容器的修改 commit 保存为镜像 $ docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]] $ docker commit -m "Added python setuptool pip numpy" -a "wangxiaolei" 0c28c802c5e6 mycentos:mydev # -m 是修改信息;-a 是作者信息;-a 和 -m 都可以省略;这里的仓库名其实就是镜像名 # 2.Dockerfile方式从头开始定制镜像(以 Python 项目为例) # 2.1 在 Python 项目文件夹中生成项目依赖文件 requirements.txt # 2.2 在 Python 项目文件夹中新建文本文件 Dockerfile(无后缀),并添加相关内容 # 2.3 使用【docker build -t [镜像名:标签] .】命令构建镜像 # -t : --tag 设置镜像名和标签 # . 表示指定 Dockerfile 的路径,在当前目录查找Dockerfile文件
📌
Dockerfile文件配置参考
# 基于镜像基础 #FROM python:3.6 FROM python:3.6-slim-stretch #有更小的体积 # 维护者信息 MAINTAINER name [email protected] # 复制当前代码文件到容器中 /app ADD . /app # 设置app文件夹是工作目录 /app WORKDIR /app #解决Dockers中打印日志不及时的问题 ENV PYTHONUNBUFFERED=0 # 安装所需的包,默认为使用python官方镜像源,安装 比较慢 #RUN pip install -r requirements.txt #可以修改为清华源 RUN pip install -r requirements.txt - i https://pypi.tuna.tsinghua.edu.cn/simple # Run test.py when the container launches CMD ["python", "/app/test/test.py"]

容器操作

# 使用镜像创建并启动容器 $ docker container run [选项] <镜像名> [命令] # # 旧版本的用法,也可以使用 $ docker run [选项] <镜像名> [命令] $ docker run -it --rm ubuntu:18.04 bash # -it:这是两个选项的组合。-i 表示以交互模式运行容器,即允许用户与容器进行交互。-t 表示为容器分配一个伪终端,以便于在容器中运行命令和查看输出。 # --rm:这是一个选项,表示当容器退出后自动删除容器。这意味着在容器停止运行后,相关的容器文件将被自动清理。 # ubuntu:18.04:这是要使用的镜像名称。ubuntu:18.04 是一个具体的 Ubuntu 18.04 版本的镜像。如果本地没有此镜像,Docker 将尝试从默认仓库(如 Docker Hub)中拉取该镜像。 # bash:这是在容器内运行的命令。指定在容器启动后运行 Bash shell。这将使用户能够与容器交互,并在容器中执行 Bash 命令。 # 只启动了一个终端的容器,用户通过 exit 命令或 Ctrl+d 来退出终端时,所创建的容器立刻终止。 $ docker run -dp 127.0.0.1:3000:3000 getting-started # -dp 127.0.0.1:3000:3000这是用于设置容器的运行选项的部分。 # -d 表示以后台(detached)模式运行容器, # -p 127.0.0.1:3000:3000 表示将主机的 127.0.0.1 的 3000 端口映射到容器的 3000 端口。 # getting-started:这是指定要运行的 Docker 镜像的名称。
当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:
  • 检查本地是否存在指定的镜像,不存在就从 registry 下载
  • 利用镜像创建并启动一个容器
  • 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
  • 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
  • 从地址池配置一个 ip 地址给容器
  • 执行用户指定的应用程序
  • 执行完毕后容器被终止
📌
运行镜像生成容器后,通常有两种方式来操作容器内的内容:
  • 容器开放一个访问端口,从浏览器访问
  • 在容器内打开一个 bash shll,进行命令行操作
$ docker ps # 列出当前正在运行的 Docker 容器 $ docker container ls # 列出当前正在运行的 Docker 容器 $ docker container ls -a # 查看所有状态的容器 $ docker exec [选项] <容器ID> # 进入一个运行中的容器 $ docker exec -it 69d1 bash # -i保持标准输入流(stdin)打开,-t 分配一个伟终端,bash 在容器内启动一个交互式的 Bash Shell $ docker start <容器ID> # 启动一个终止状态的容器 $ docker stop <容器ID> # 终止一个运行中的容器 $ docker restart <容器ID> # 重启一个运行中的容器 $ docker rm <容器ID> [<容器ID>2] # 重启一个运行中的容器,可批量操作 $ docker run -d ubuntu:18.04 /bin/sh -c "while true; do echo hello world; sleep 1; done" # -d 表示静默运行,-d 参数启动后会返回一个唯一的 id(CONTAINER ID)用【$ docker container ls】命令可以看到 $ docker container logs [container ID or NAMES] # 获取容器的输出信息(用上面获取的 DI 或名称)

容器的导入与导出

容器的导入(import)和导出(export)是用于在 Docker 中进行容器和镜像的迁移、备份和共享的操作。 导出容器(export)操作将容器的文件系统打包为一个单独的文件(通常是一个 tar 归档文件),其中包含容器的文件系统快照、元数据和配置信息。导出的文件可以通过文件共享、传输到其他环境或存档备份等方式进行传递和存储。导出的文件可以用于在不同的 Docker 主机上导入为一个新的镜像或容器。 导入容器(import)操作将导出的容器文件导入到 Docker 中,创建一个新的镜像。这是将容器从一个环境迁移到另一个环境的常见方法。导入的容器文件可以包含完整的文件系统、元数据和配置信息,从而可以还原出与导出时相同的容器。
# 导出容器 $ docker export 7691a814370e > ubuntu.tar # 会创建一个容器快照的归档文件(通常是一个 tar 文件)。该归档文件包含容器的文件系统内容和元数据,但不包含容器的运行状态或正在运行的进程。换句话说,导出的内容是容器当前状态的静态表示。 # 导入快照得到镜像 $ cat ubuntu.tar | docker import - test/ubuntu:v1.0 # cat ubuntu.tar:这个部分使用 cat 命令来读取名为 "ubuntu.tar" 的文件内容,并将其输出到标准输出(stdout)。 # |:这是一个管道操作符,它将 cat ubuntu.tar 的输出连接到下一个命令的输入。 # docker import - test/ubuntu:v1.0:通过管道传递的数据导入为一个 Docker 镜像。其中,"-" 表示从标准输入(stdin)读取数据,而 "test/ubuntu:v1.0" 是指定将导入的镜像的名称和标签。 $ docker image ls $ docker import http://example.com/exampleimage.tgz example/imagerepo

常用命令整理

notion imagenotion image

推荐链接

  1. 官方文档
  1. DockerHub
  1. Docker一从入门到实践
  1. 使用Docker安装配置Jupyter并配置R语言与Python环境
  1. docker desktop ubuntu镜像_基于docker的python数据挖掘环境搭建(Jupyter notebook))
 
 
对于本文内容有任何疑问, 可与我联系.