Docker 是开源的应用容器引擎,基于 go 语言,并遵从 Apache2.0 协议开源。
Docker 允许开发人员将相关应用和依赖库打包到一个轻量级的容器中
Docker 有三个基本概念:
互联网企业生产环境的部署经理了三个阶段:
物理机部署:
直接在机器上进行环境部署和应用,但多个进程都部署在同一个机器上就会导致资源抢占,导致某些异常。
虚拟机部署:
从物理机上分配好 cpu 核数、内存、磁盘等,一个虚拟机一般都只部署一个应用,实现了进程间的资源隔离,可以解决直接在物理机上部署导致的资源抢占问题,一个物理机上可以部署多个虚拟机。
虚拟机虽然可以隔离资源,但随着时间的推移和一些软件的升级,难免有没有升级或管理到的版本,容易导致软件版本和配置逐渐碎片化,当线上出现问题时,排查问题会很棘手。
容器部署:
容器不局限于 docker,但 docker 是目前最流行的,docker 的核心在于镜像文件
镜像文件就是一个进程运行时需要依赖的库的集装箱
部署时,首先拉取指定版本的镜像文件,运行镜像文件即可启动容器,由于镜像文件是一样的,所以容器中的软件和库的版本也是一样的,不会出现配置碎片化的问题。如果要升级软件版本,则修改镜像文件即可。
安装命令:
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
国内 daocloud 安装:
curl -sSL https://get.daocloud.io/docker | sh
验证 Docker 是否被正确安装:
sudo docker run hello-world
Dockerfile 是用了构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明
Dockerfile 一般包含四部分:
例如:
# This dockerfile uses the ubuntu image
# VERSION 2 - EDITION 1
# Author: docker_user
# Command format: Instruction [arguments / command] ..
# Base image to use, this must be set as the first line
FROM ubuntu # 基础镜像
# Maintainer: docker_user (@docker_user)
MAINTAINER docker_user docker_user@email.com # 镜像维护者的信息
# Commands to update the image
# RUN 指令会对镜像执行命令,每运行一条 RUN 指令,镜像添加一层
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
# Commands when creating a new container
# CMD 来指定运行容器时的操作命令
CMD /usr/sbin/nginx
指令 | 作用 |
---|---|
FROM | 第一条指令必须为 FROM,表示从哪个基础镜像的基础上来新建镜像 |
MAINTAINER | 指定维护者信息 |
RUN | 在 docker build 的时候执行,会在 shell 终端运行命令 |
RUN [“executable”, “param1”, “param2”] | 使用 exec 执行,可以指定使用其他终端,如 RUN [“/bin/bash”, “-c”, “echo hello”] |
CMD | 指定启动容器时的执行命令,在 docker run 的时候执行,每个 Dockerfile 只能有一条 CMD 命令,如果指定了多条,只有最后一条会被执行,且如果用户启动容器的时候指定了运行的命令,则会覆盖掉 CMD 指定的命令 |
EXPOSE | 告诉 Docker 服务端容器暴露的端口号,供互联系统使用,在启动容器时使用 -p ,Docker 主机会自动分配一个端口到指定的端口 |
ENV | 指定一个环境变量,会被后续的 RUN 指令使用,并在容器运行时保持 |
COPY | 复制指令,从上下文目录中复制文件或者目录到容器里指定路径 |
ADD | 类似 COPY |
使用 Dockerfile 创建一个镜像:
sudo docker build -t ImageName:TagName dir
-t
:给镜像加一个 tagImageName
:镜像的名字TagName
:镜像的 Tag 名Dir
:Dockerfile 所在目录实例:
docker build -t redis:v1.1 .
redis
:镜像名v1.1
:tag 标签.
:当前目录,即 Dockerfile 所在目录如何查看镜像:
docker image
查看 docker 系统信息:
docker info [options]
查看 docker 版本信息:
docker version [options]
一般都可以从 Docker hub 来拉取常用的镜像
也可以使用 docker search
的方式来搜索镜像:docker search yolov5
查看 images 占用磁盘空间:
docker system df
镜像拉取:
sudo docker pull NAME[:TAG]
NAME
:镜像的名称TAG
:镜像的 tag拉取所有版本的镜像:
sudo docker pull -a NAME
-a
:表示拉取名字为 NAME
的镜像的所有版本dockerhub 页面如下:
假设要拉取 yolov5 的镜像,可以直接搜索 yolov5 :
然后执行下面的命令来拉取对应的镜像即可:
docker pull ultralytics/yolov5
删除镜像:
docker rmi hello-world
docker save [options] IMAGE [IMAGE...]
docker save -o test.tar runoob/ubuntu:v3
docker load [options]
docker load < busybox.tar.gz
docker import [options] file IMAGE[:TAG]
示例:从 my_ubuntu_v3.tar 来创建镜像,命名为 runoob/ubuntu:v4
docker import my_ubuntu_v3.tar runoob/ubuntu:v4
docker images runoob/ubuntu:v4
REPOSITORY TAG IMAGE ID CREATED SIZE
runoob/ubuntu v4 63ce4a6d6bc3 20 seconds ago 142.1 MB
要上传的话要有镜像仓库的登录权限
可以将本地镜像推送到 docker 公共仓库——Dockerhub,也可以推送到私有的 docker 仓库中
这里演示如何推送到 dockerhub,要先注册并登录 dockerhub
docker push [options] NAME[:TAG]
示例:将本地镜像上传到仓库:
# 使用 docker login 登录
docker login
# 退出
docker logout
# 上传
docker push myapache:v1
查看所有的容器:
sudo docker ps -a
查看所有运行的容器:
sudo docker ps
进入已经启动的容器,使用 exec 进入容器会不受原终端运行的影响, 如果在进入容器后执行 exit 命令,容器也不会停止,只会退出该容器。
sudo docker exec -it 'test' bash
拉取到镜像之后,要使用该镜像创建一个容器,才可以使用相关的内容
语法:
docker run [options] Image [command] [arg...]
例如:
docker run -it --name 'test' IMAGE:TAG
如果要在容器中使用英伟达显卡有两种方法:
# 方法一
sudo nvidia-docker run ...
# 方法二
sudo docker run --runtime-nvidia ...
nvidia-docker 是对 docker 的包装,使得容器能够看到并使用主机的 nvidia 显卡,也就是避免需要在容器中安装 cuda 或 gpu 驱动。
参数 | 作用 |
---|---|
-a stdin | 指定标准输入输出内容类型,可以选择 STDIN/STDOUT/STDERR |
-d | 启动容器后后台运行,不会直接进入容器,界面上会返回容器的 ID,使用后台运行方式启动的容器,想要进入容器的话可以使用 docker exec,使用 exit 退出后容器依然会运行 |
-i | 以交互模式运行容器,通常和 -t 同时使用(-it) |
-P | 随机端口映射,容器内部端口随机映射到主机的端口 |
-p | 指定端口映射,格式为 主机端口:容器端口 , |
-t | 为容器重新分配一个伪输入终端 |
–name | 为启动的容器设置一个名字,方便查看 |
-m | 设定容器使用内存的最大值 |
-w | 指定工作目录 |
-v | 将主机的目录挂载到 docker 的相同目录下,docker 目录下的内容会随着主机相同目录下的内容变化而变化 |
-e | 设置容器的环境变量,-e NVIDIA_VISIBLE_DEVICES=all,表示可使用主机的所有卡,-e NVIDIA_VISIBLE_DEVICES=1,2,表示可以使用 1 和 2 卡。 |
–shm-size | 共享内存大小,docker run 运行容器的时候,最好指定一下–shm-size,单位是字节,因为默认是docker容器中默认是64M,很多软件无法正常工作,可以设置为–shm-size=59g |
–net | 指定容器的网络模式:–net=host,容器和主机共享网络,主机的所有端口都可以用于容器,可能会出现端口冲突的情况。–net=bride,是默认的模式,-p 用于指定端口映射。–net=container 当前容器和 container 容器共享 network namespace,–net=none,容器有独立的 network namespace |
–ipc | –ipc=host,容器和主机共享内存 |
–privileged | –privleged=true,使容器拥有 root 权限 |
–gpus | –gpus all,使用主机的所有 gpu,–gpus 2,使用 2 个 gpu,–gpus ‘device=1,2’,使用 1 卡和 2 卡 |
在使用 -d 的方式进入后台运行时,如果想要进入容器,可以使用下面两种方式:
docker attach 'test'
:使用 exit 退出容器会导致容器终止docker exec -it 'test' bash
:使用 exit 退出容器不会导致容器终止docker stop 'test'
docker restart 'test'
docker stop 'test'
docker rm 'test'
docker kill 'test'
kill -9 pid
容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P 或 -p 参数来指定端口映射。
主机端口:容器端口
docker history [options] IMAGE