docker学习笔记(代码片段)

zstar-_ zstar-_     2022-12-11     305

关键词:

前言

在我之前的博文中用到过两次Docker,但所涉及的内容过于碎片,因此想系统地将Docker的知识整理一下。

Docker基本概念

docker最重要的三个概念是:镜像(image),容器(container),仓库(repository)

镜像是文件与meta data的集合,可以理解为树状结构,每一个镜像都会依赖于另一个镜像,这个依赖关系是体现在docker镜像制作的dockerfile中的FROM指令中的。

容器是镜像的一个运行实例,可以不准确的把镜像当作类,容器当作对象。容器其实他的结构是与镜像相类似的,底部也是一层层的只读层,只不过在最上层会存在一个存储层,我们可以在这一层定制化我们的这个容器,还可以通过build命令,把容器打包成我们自己需要的镜像。另外镜像启动后会形成一个容器,容器在计算机中是一个进程,但这个进程对其他进程并不可见。

容器的启动过程:
检查镜像是否在本地存在,如果不存在去远程仓库下载
==>利用镜像创建一个容器
==>启动刚刚创建的容器
==>分配一个文件系统给容器,并且在镜像层外挂载一个可读可写层
==>从宿主主机的网桥接口中桥接一个给容器
==>从网桥中分一个ip地址给容器
==>执行用户指定的应用程序
==>执行完毕后容器自动终止

image负责存储和分发,container负责运行。

仓库和Github上面的仓库类似,在docker中,可以从docker hub(http://registry.hub.docker.com/)中取得的镜像。

Docker安装

我的电脑系统是Win10,因此仅记录Windows的安装方式。

首先需要到Docker官网注册账号,下载docker客户端wsl

安装好之后,根据提示重启电脑。

打开客户端如果看到左下角变绿色,说明成功运行。

如果遇到报错

可能是由于VPN和wsl2的sock端口冲突,解决方式是下载NoLsp,用管理员身份运行cmd,进入到NoLsp文件夹,输入

NoLsp.exe C:\\windows\\system32\\wsl.exe

出现success即可。

然后重启Docker Desktop,左下角变绿色,则成功运行。

启动终端后,通过命令可以检查安装后的 Docker 版本

$ docker --version
Docker version 20.10.17, build 100c701
$ docker-compose --version
docker-compose version 1.29.2, build 5becea4c

简单测试,运行一个镜像。

$ docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
d1725b59e92d: Pull complete
Digest: sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

成功输出,打开客户端,可以看到本地多了一个容器和镜像

Docker基本命令

拉取镜像

命令:

docker pull [选项] [docker镜像地址:标签]

示例:拉取最新版本的hello-world

docker pull hello-world:latest

运行镜像

直接运行:

docker run hello-world

运行镜像并进入容器:

docker run -it --rm ubuntu:18.04 bash
Unable to find image 'ubuntu:18.04' locally
18.04: Pulling from library/ubuntu
726b8a513d66: Pull complete
Digest: sha256:6fec50623d6d37b7f3c14c5b6fc36c73fd04aa8173d59d54dba00da0e7ac50ee
Status: Downloaded newer image for ubuntu:18.04
root@36f6e5581444:/# exit
exit

参数解释:

  • -i:交互式操作
  • -t:终端
  • –rm:容器退出后随之将其删除,以节省空间
  • ubuntu:18.04:指用 ubuntu:18.04 镜像为基础来启动容器
  • bash:命令,交互式Shell,进入容器后,可以在Shell下操作,执行任何所需的命令

查看本地镜像

docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
ubuntu        18.04     35b3f4f76a24   11 days ago     63.1MB
hello-world   latest    feb5d9fea6a5   11 months ago   13.3kB

IMAGE ID是镜像的唯一标识。

查看运行中的容器

docker ps
CONTAINER ID        IMAGE          COMMAND      CREATED             STATUS              PORTS               NAMES
9363b1b51118        testlog:1      "bash"       7 weeks ago         Up 7 weeks                              vigilant_bhaskara

CONTAINER ID容器唯一标识。

查看所有容器

docker ps -a
CONTAINER ID   IMAGE         COMMAND    CREATED       STATUS                   PORTS     NAMES
2193cee7642b   hello-world   "/hello"   5 hours ago   Exited (0) 5 hours ago             vigilant_aryabhata

进入运行中的容器

docker exec -it [CONTAINER ID] /bin/bash

保存修改

docker commit [CONTAINER ID] registry.cn-shanghai.aliyuncs.com/test/pytorch:myversion

注意:commit操作不仅会把有用的修改保存下来,对一些无关的修改也会保存下来,会导致镜像比较臃肿。
因此建议commit仅作为保留现场的手段,然后通过修改dockerfile构建镜像。

打TAG

docker tag registry.cn-shanghai.aliyuncs.com/test/pytorch:myversion my_tmp_version:0.1

打TAG即打标签,不会额外占用空间

推送镜像到仓库

docker push registry.cn-shanghai.aliyuncs.com/test/pytorch:myversion

使用dockerfile构建镜像

DockerFile常用指令:

FROM             # 基础镜像,一切从这里开始构建  centos
MAINTAINER        # 镜像是谁写的, 姓名+邮箱
RUN             # 镜像构建的时候需要运行的命令
ADD             # 步骤,tomcat镜像,这个tomcat压缩包!添加内容 添加同目录
WORKDIR         # 镜像的工作目录
VOLUME             # 挂载的目录
EXPOSE             # 暴露端口配置  和我们的-p一样的
CMD             # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代。
ENTRYPOINT         # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD         # 当构建一个被继承 DockerFile 这个时候就会运行ONBUILD的指令,触发指令。
COPY             # 类似ADD,将我们文件拷贝到镜像中
ENV             # 构建的时候设置环境变量

示例:

# Base Images
## 从天池基础镜像构建(from的base img 根据自己的需要更换,建议使用天池open list镜像链接:https://tianchi.aliyun.com/forum/postDetail?postId=67720)
FROM registry.cn-shanghai.aliyuncs.com/tcc-public/python:3
##安装依赖包
RUN pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple 
##或者从requirements.txt安装
##RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple 
## 把当前文件夹里的文件构建到镜像的根目录下,并设置为默认工作目录
ADD . /
WORKDIR /
## 镜像启动后统一执行 sh run.sh
CMD ["sh", "run.sh"]

构建镜像

docker build -t registry.cn-shanghai.aliyuncs.com/target:test .

注意后面有个点,默认会寻找当前路径下的DockerFile文件

如果需要指定DockerFile,可运行

docker build -f ./dockerfile -t registry.cn-shanghai.aliyuncs.com/target:test .

删除镜像

docker rmi registry.cn-shanghai.aliyuncs.com/target:test

删除容器

如果容器正在运行,首先需要停止容器

docker kill [CONTAINER ID]

然后删除容器

docker rm [CONTAINER ID]

公开基础镜像/权重

阿里云上公开的一些基础镜像以及深度模型预训练模型可参考:
https://tianchi.aliyun.com/forum/postDetail?spm=5176.21852674.0.0.6b166bdfaruCUU&postId=67720

Docker实践实例

下面来通过实例来实际使用一下Docker,阿里天池提供了一个新人练习场,可供新手练习。
地址:https://tianchi.aliyun.com/competition/entrance/531863/information

基础环境配置

首先创建一个个人版实例

进入实例中,创建命名空间


输入自己的信息,代码源选择本地仓库

本地连接:
输入

set DOCKER_REGISTRY=公网地址

公网地址在镜像管理中可以找到

然后输入

docker login --username=自己的用户名 registry.cn-hangzhou.aliyuncs.com

之后需要输入密码,密码可以在这里进行设置:

提示Login Succeeded表示登录成功。

基础案例测试

下面来测试一个简单的pytorch程序,调用机器的gpu来实现两个矩阵的相乘。

新建一个main,py文件,输入

import torch
device = torch.device("cuda")
a = torch.randn(3, 3)
b = torch.randn(3, 3)
a = a.to(device)
b = b.to(device)
c = torch.matmul(a,b)
print(c)

新建脚本文件run.sh,输入

#bin/bash
#打印GPU信息
nvidia-smi
#执行math.py
python3 math.py

新建Dockerfile文件,输入

# Base Images
## 从天池基础镜像构建(from的base img 根据自己的需要更换,建议使用天池open list镜像链接:https://tianchi.aliyun.com/forum/postDetail?postId=67720)
FROM registry.cn-shanghai.aliyuncs.com/tcc-public/pytorch:1.4-cuda10.1-py3

##安装依赖包,pip包请在requirements.txt添加
#RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

## 把当前文件夹里的文件构建到镜像的//workspace目录下,并设置为默认工作目录
ADD math.py /workspace
ADD run.sh /workspace
WORKDIR /workspace

## 镜像启动后统一执行 sh run.sh
CMD ["sh", "run.sh"]

构建镜像:
这一步由于需要从天池基础镜像拉取pytorch镜像,因此需要等待比较长的时间。

docker build -t registry.cn-hangzhou.aliyuncs.com/zstar1003/docker .

构建好之后,可以本地运行测试一下:

docker run -it --rm --name test --gpus all registry.cn-hangzhou.aliyuncs.com/zstar1003/docker:1.0

注意要在docker容器中使用电脑的GPU,需要指定--gpus all

在我电脑上,运行之后会报错:

AttributeError: partially initialized module ‘torch’ has no attribute 'device`

这是由于pytorch版本和本机的cuda版本不匹配,导致Pytorch无法调用GPU

因此进入bash环境,输入nvidia-smi查看显卡和CUDA信息

docker run -it --rm --name test --gpus all registry.cn-hangzhou.aliyuncs.com/zstar1003/docker:1.0 bash

可以看到我的CUDA版本是11.6

因此修改Dockerfile文件:

# Base Images
# FROM registry.cn-shanghai.aliyuncs.com/tcc-public/pytorch:1.6-cuda10.1-py3
# FROM pytorch/pytorch:1.12.1-cuda11.3-cudnn8-runtime
FROM registry.cn-shanghai.aliyuncs.com/tcc-public/python:3

##安装依赖包,pip包请在requirements.txt添加
RUN pip install torch==1.7.1+cu110 --extra-index-url https://download.pytorch.org/whl/cu110

## 把当前文件夹里的文件构建到镜像的//workspace目录下,并设置为默认工作目录
ADD math.py /workspace
ADD run.sh /workspace
WORKDIR /workspace

## 镜像启动后统一执行 sh run.sh
CMD ["sh", "run.sh"]

注意这里安装torch-gpu版本不能直接使用国内源,因此运行会较为缓慢。
更多链接可参考pytorch官方文档:https://pytorch.org/get-started/previous-versions/

安装好之后进行测试不报错正常输出说明测试通过。

将镜像推送到阿里云镜像仓库:

docker push registry.cn-hangzhou.aliyuncs.com/zstar1003/docker

推送完之后,可以在仓库内看到镜像地址。

最后,在练习场界面提交镜像地址以及用户名和密码即可。(目前练习场已暂停提交)

Docker环境清理

Docker对Windows系统的支持并不是很友好,很多镜像文件都是基于Linux系统,而且创建镜像文件默认会在C盘进行存储,如果C盘空间不大,需要通过下面的方式对镜像、容器进行清理,也可以手动进行删除。

docker学习笔记-安装(代码片段)

Docker学习笔记基础概念/名词解释准备工作安装启动Docker服务Docker常用命令卸载参考资料基础概念/名词解释名词说明image镜像docker封装好的一个模板,里面是一个可运行的服务,以及运行此服务所需要的依赖环境。container... 查看详情

docker学习笔记-安装(代码片段)

Docker学习笔记基础概念/名词解释准备工作安装启动Docker服务Docker常用命令卸载参考资料基础概念/名词解释名词说明image镜像docker封装好的一个模板,里面是一个可运行的服务,以及运行此服务所需要的依赖环境。container... 查看详情

docker学习笔记总结(代码片段)

文章目录1.卸载docker服务步骤(实用!!)2.docker私有库3.容器数据卷的使用4.容器卷和主机互通互联5.容器卷ro和rw读写规则6.卷的继承和共享7.docker安装tomcat8.docker安装mysql8.1运行mysql容器8.2dockermysql容器卷配置(非常重要)8.3docke... 查看详情

docker学习笔记总结(代码片段)

文章目录1.docker简介2.docker的三个组成3.docker的工作原理4.centos系统上安装docker5.阿里云镜像加速器6.dockerrun命令执行流程7.docker命令7.1帮助启动类命令7.2镜像命令7.3容器命令7.3.1dockerrun命令详解7.3.2dockerps命令详解7.3.3容器服务的一... 查看详情

docker学习笔记——docker管理容器(代码片段)

文章目录Docker管理容器1.容器&镜像&仓库&daemon&client之间的关系2.启动容器3.dockerdaemon管理4.docker命令行5.docker命令行实现容器管理搜索镜像(dockerhub)获取镜像(pull)打包传输镜像启动容器解决docker中的CtenOS8镜像无法使用yum... 查看详情

docker学习笔记——docker管理容器(代码片段)

文章目录Docker管理容器1.容器&镜像&仓库&daemon&client之间的关系2.启动容器3.dockerdaemon管理4.docker命令行5.docker命令行实现容器管理搜索镜像(dockerhub)获取镜像(pull)打包传输镜像启动容器解决docker中的CtenOS8镜像无法使用yum... 查看详情

docker学习笔记总结(代码片段)

文章目录1.dockernetwork简介2.dockernetwork网络模式3.docker底层容器ip和容器映射变化4.dockernetwork4.1bridge模式4.2host模式4.3none模式4.4container模式4.5自定义网络模式5.docker-compose容器编排简介6.compose的下载安装7.compose的几个核心概念8.compose... 查看详情

docker学习笔记(代码片段)

Docker1.安装Docker#1.yum包更新到最新yumupdate-y#2.安装需要的软件包,yum-util提供yun-config-manager功能,另外两个是devicemapper驱动依赖的yuminstall-yyum-utilsdevice-mapper-persistent-datalvm2#3.设置yum源yum-config-manager- 查看详情

docker学习笔记-仓库(代码片段)

Docker仓库是镜像存储、分发、部署的关键,制作好应用程序镜像后上传到仓库,使用Dockerdaemon从仓库拉取后运行,我们可以使用官方共有仓库dockerhub或者搭建私有仓库DockerHub包含众多镜像,无需登录就可以搜索和使用注册DockerHub... 查看详情

docker学习笔记总结(代码片段)

文章目录1.dockernetwork简介2.dockernetwork网络模式3.docker底层容器ip和容器映射变化4.dockernetwork4.1bridge模式4.2host模式4.3none模式4.4container模式4.5自定义网络模式5.docker-compose容器编排简介6.compose的下载安装7.compose的几个核心概念8.compose... 查看详情

docker学习笔记(代码片段)

前言在我之前的博文中用到过两次Docker,但所涉及的内容过于碎片,因此想系统地将Docker的知识整理一下。Docker基本概念docker最重要的三个概念是:镜像(image),容器(container),仓库(re... 查看详情

docker学习笔记(代码片段)

前言在我之前的博文中用到过两次Docker,但所涉及的内容过于碎片,因此想系统地将Docker的知识整理一下。Docker基本概念docker最重要的三个概念是:镜像(image),容器(container),仓库(re... 查看详情

docker学习笔记总结(代码片段)

文章目录1.docker搭建三主三从的redis集群2.redis集群之主从容错切换迁移(基于redis集群)3.redis集群之主从扩容(基于redis集群)4.redis集群之主从缩容(基于redis集群)5.DockerFile介绍6.DockerFile构建过程解析7.DockerFile保留字简介8.DockerFile保留... 查看详情

docker学习笔记总结(代码片段)

文章目录1.docker搭建三主三从的redis集群2.redis集群之主从容错切换迁移(基于redis集群)3.redis集群之主从扩容(基于redis集群)4.redis集群之主从缩容(基于redis集群)5.DockerFile介绍6.DockerFile构建过程解析7.DockerFile保留字简介8.DockerFile保留... 查看详情

docker基础学习笔记一:docker概述和安装(代码片段)

Docker基础学习笔记一:Docker概述和安装容器的起源什么是容器Docker是什么Docker容器为什么这么火Docker能做什么?Docker的安装(centos8中)卸载容器的起源假设你们公司正在秘密研发下一个“今日头条”APP,我们... 查看详情

docker学习笔记(代码片段)

一.Docker的概念Docker是一个开源的应用容器引擎,基于Go语言并遵从Apache2.0协议开源。Docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟... 查看详情

docker学习笔记(代码片段)

一.Docker的概念Docker是一个开源的应用容器引擎,基于Go语言并遵从Apache2.0协议开源。Docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟... 查看详情

docker入门学习笔记(代码片段)

docker基础操作入门笔记镜像操作容器操作数据卷操作(挂载)为什么要挂载如何挂载其他docker设置开机自启时间同步问题jar包的运行文章中几乎所有的写容器Id的地方,都可以使用容器名称来写命令镜像操作列出镜像... 查看详情