学习笔记:Linux下Docker的使用

目录

一、介绍

二、使用镜像

三、使用容器

四、数据管理

一、介绍

Docder属于操作系统层面的虚拟化技术。传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。

1. 基本概念:镜像(Image)、容器(Container)、仓库(Repository)

1) 镜像

操作系统分为内核和用户空间,内核启动后会挂在root文件系统为其提供用户空间支持,镜像就相当于一个root文件系统,提供了容器运行时所需的程序、库、资源、配置等文件,以及一些为运行时准备的配置参数(如匿名卷、环境变量、用户等)。

镜像被设计为分层存储架构,由多层文件系统联合组成,不包含任何动态数据。镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。

2) 容器

镜像是静态的定义,容器是镜像运行时的实体(像是类和实例一样),容器的实质是进程,但运行与属于自己的独立的命名空间。

容器也使用分层存储。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的容器存储层。

容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用数据卷(Volume)或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。

3) 仓库

镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样的服务。最常使用的 Registry 公开服务是官方的 Docker Hub,这也是默认的 Registry,并拥有大量的高质量的官方镜像。

一个 Docker Registry 中可以包含多个仓库;每个仓库可以包含多个标签;每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。

二、使用镜像

# 获取
官方镜像library/centos仓库中标签最新的镜像
# docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
$ docker pull ufoym/deepo:tensorflow-py36

# 列出已经下载下来的镜像
$ docker image ls

# 保存&加载:可以回滚到之前的层
# 持久化镜像
$ docker save [IMAGE NAME] > /root/save.tar
# 导入save的文件
$ docker load < /root.save.tar
# 回滚
$ docker iamges --tree
$ docker tag <LAYER ID> <IMAGE NAME>

# 查看镜像、容器、数据卷所占用的空间
$ docker system df

# 取消镜像的某个标签(删除镜像)
# 因为一个镜像可以对应多个标签,因此当我们删除了所指定的标签后,可能还有别的标签指向了这个镜像
# 如果是这种情况,那么 Delete 行为就不会发生
$ docker image rm [镜像标签]

# 查看当前系统版本
$ cat /etc/os-release

# 层回滚
$ docker tag [LAYER ID] [IMAGE NAME]

三、使用容器

# 查看已有的容器
$ docker container ls -a

# 新建并启动
# 以centos镜像为基础以bash终端启动并运行一个容器,允许用户进行交互
# -it 创建一个交互式的容器
# -d 容器会在后台运行并不会把输出的结果 (STDOUT) 打印到宿主机上面
# -p 选择宿主机具体的9999端口映射到容器内部的8888端口上
# -v 挂载目录 /root/software是本地目录,/software是容器自己创建的目录
# -c "while true; do echo hello world; sleep 1; done" 指令 容器是否会长久运行,是和docker run指定的命令有关
# --name 容器名称
# --privileged=true 关闭安全权限,否则你容器操作文件夹没有权限
# --runtime=nvidia 在容器中使用NVIDIA的GPU,需要安装nvidia-docker
# --ipc=host 增加共享内存大小
# --rm 结束则删除容器
$ docker run --runtime=nvidia --rm ufoym/deepo:tensorflow-py36 nvidia-smi
$ docker run --runtime=nvidia --ipc=host -it -p 8888:8888 -v /root/myDocker:/share --privileged=true --name my_tensorflow ufoym/deepo:tensorflow-py36 /bin/bash
$ docker run --runtime=nvidia --ipc=host -it -p 8888:8888 ufoym/deepo:all-py36-jupyter jupyter notebook --no-browser --ip=0.0.0.0 --allow-root --NotebookApp.token= --notebook-dir='/root'

# 终止容器
$ docker container stop [container ID]

# 启动已终止的容器
$ docker container start [container ID]

# 重启容器
$ docker container restart [container ID]

# 进入容器
$ docker exec -it [CONTAINER ID] bash

# 退出容器
$ exit

# 提交容器成为新的镜像
$ docker commit [container id] [your name]/[image name]:[tag]

# 导出&导入:会丢失所有历史
# 持久化容器
$ docker export [CONTAINER ID] > export.tar
# 导入export的文件
$ cat centos.tar | docker import - test/centos:v1.0

# 指定URL或者某个目录来导入
$ docker import http://example.com/exampleimage.tgz example/imagerepo

# 删除容器
$ docker container rm [CONTAINER NAMES]

# 查看输出结果
$ docker container logs [container ID or NAMES]

# 查看容器绑定和映射的端口
$ docker port [container NAMES]

# 查看容器信息
$ docker inspect [container NAMES]

# 查看已经存在的容器的挂载目录
$ docker inspect [container NAMES] | grep Mounts -A 10

# 清理所有处于终止状态的容器
$ docker container prune

注:docker save/load和 docker export/import 的区别

  1. docker save保存的是镜像(image)可以层回滚,docker export保存的是容器(container);
  2. docker load用来载入镜像包,docker import用来载入容器包,但两者都会恢复为镜像;
  3. docker load不能对载入的镜像重命名,而docker import可以为镜像指定新名称。

四、数据管理

容器中数据管理主要有两种方式:数据卷(Volumes)和挂载主机目录(Bind mounts)

1)数据卷:可以在容器之间共享和重用;对数据卷的修改会立刻生效;对数据卷的更新不会影响镜像;即使容器被删除数据卷也会默认会一直存在

# 创建数据卷
$ docker volume create my-vol

# 查看所有的数据卷
$ docker volume ls

# 查看指定数据卷的信息
$ docker volume inspect my-vol

# 启动一个挂载数据卷的容器,在一次docker run中可以挂载多个数据卷
# 创建一个名为web的容器,并加载一个数据卷到容器的 /webapp 目录
$ docker run -d -P \
    --name web \
    # -v my-vol:/wepapp \
    --mount source=my-vol,target=/webapp \
    training/webapp \
    python app.py

# 删除数据卷
$ docker volume rm my-vol

# 在删除容器的同时移除数据卷
$ docker rm -v my-vol

2) 挂载一个主机目录作为数据卷

# 加载主机的 /src/webapp 目录到容器的 /opt/webapp目录
$ docker run -d -P \
    --name web \
    # -v /src/webapp:/opt/webapp \
    --mount type=bind,source=/src/webapp,target=/opt/webapp \
    training/webapp \
    python app.py

# 从主机挂载单个文件到容器中
# 记录在容器输入过的命令
$ docker run --rm -it \
   # -v $HOME/.bash_history:/root/.bash_history \
   --mount type=bind,source=$HOME/.bash_history,target=/root/.bash_history \
   ubuntu:17.10 \
   bash

参考:

https://yeasy.gitbooks.io/docker_practice/content/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章