【Docker】 3、Docker 超详细介绍、docker build


一、概述

Docker 是开源的应用容器引擎,基于 go 语言,并遵从 Apache2.0 协议开源。

Docker 允许开发人员将相关应用和依赖库打包到一个轻量级的容器中

Docker 有三个基本概念:

  • 镜像(Image):镜像就相当于一个文件系统,比如官方镜像 ubuntu:16.04 就包含了一整套的 Ubuntu16.04 最小系统的 root 文件系统
  • 容器(Container):镜像是静态的定义,容器是镜像运行起来的实体
  • 仓库(Reposityor):仓库可以用于保存镜像

1.1 优势

互联网企业生产环境的部署经理了三个阶段:

  • 物理机部署:

    直接在机器上进行环境部署和应用,但多个进程都部署在同一个机器上就会导致资源抢占,导致某些异常。

  • 虚拟机部署:

    从物理机上分配好 cpu 核数、内存、磁盘等,一个虚拟机一般都只部署一个应用,实现了进程间的资源隔离,可以解决直接在物理机上部署导致的资源抢占问题,一个物理机上可以部署多个虚拟机。

    虚拟机虽然可以隔离资源,但随着时间的推移和一些软件的升级,难免有没有升级或管理到的版本,容易导致软件版本和配置逐渐碎片化,当线上出现问题时,排查问题会很棘手。

  • 容器部署:

    容器不局限于 docker,但 docker 是目前最流行的,docker 的核心在于镜像文件

    镜像文件就是一个进程运行时需要依赖的库的集装箱

    部署时,首先拉取指定版本的镜像文件,运行镜像文件即可启动容器,由于镜像文件是一样的,所以容器中的软件和库的版本也是一样的,不会出现配置碎片化的问题。如果要升级软件版本,则修改镜像文件即可。

1.2 Ubuntu 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

二、docker 配置

2.1 数据路径

默认 docker 会放在 /var/lib/docker 下,但通常系统盘都空间有限,所以可更改 docker 配置:

vim /etc/docker/daemon.json
{
  "data-root": "/www/docker"
}


docker info | grep 'Docker Root Dir' 可看到数据路径

三、Dockerfile

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 at email.com> (@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:给镜像加一个 tag
  • ImageName:镜像的名字
  • 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]
  • 示例:

Dockerfile 如下:

From alpine:latest
RUN apk add squashfs-tools

然后 build 并 push 并 run

运行 docker build -t dockerhub.my.com/abc:latest .
docker push dockerhub.my.com/abc:latest
docker run -it -v path1/path2:/path3:path4 dockerhub.my.com/abc:latest sh

五、镜像

  • 一般都可以从 Docker hub 来拉取常用的镜像

  • 也可以使用 docker search 的方式来搜索镜像:docker search yolov5

查看 images 占用磁盘空间:

docker system df

5.1 镜像拉取

镜像拉取:

sudo docker pull NAME[:TAG]
  • NAME:镜像的名称
  • TAG:镜像的 tag

拉取所有版本的镜像:

sudo docker pull -a NAME
  • -a:表示拉取名字为 NAME 的镜像的所有版本

dockerhub 页面如下:

在这里插入图片描述
假设要拉取 yolov5 的镜像,可以直接搜索 yolov5 :

在这里插入图片描述

然后执行下面的命令来拉取对应的镜像即可:

docker pull ultralytics/yolov5

5.2 镜像删除

删除镜像:

docker rmi hello-world

5.3 使用 docker save 将镜像保存成 tar 归档文件

docker save [options] IMAGE [IMAGE...]
  • -o:输出到的文件
docker save -o test.tar runoob/ubuntu:v3

5.4 导入使用 docker save 导出的镜像

docker load [options]
--input, -i:指定导入的文件
--quiet,-q:精简输出信息
docker load < busybox.tar.gz
# Save、Load
docker system df 查看images占用磁盘空间
docker run -e 可以覆盖Dockerfile中的 "ENV设置"
Dockerfile的ONBUIILD比较好用, 用于做基础镜像
$ docker save alpine -o filename 可以把镜像存储为文件, 对文件后缀无要求
docker load -i filename 可以从文件存储为镜像

5.5 使用 docker import 从归档文件中创建镜像

docker import [options] file IMAGE[:TAG]
  • -c:使用 docker 指令创建镜像
  • -m:提交时的文字说明

示例:从 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

5.6 将本地镜像上传到镜像仓库

要上传的话要有镜像仓库的登录权限

可以将本地镜像推送到 docker 公共仓库——Dockerhub,也可以推送到私有的 docker 仓库中

这里演示如何推送到 dockerhub,要先注册并登录 dockerhub

docker push [options] NAME[:TAG]

示例:将本地镜像上传到仓库:

# 使用 docker login 登录
docker login
# 退出
docker logout
# 上传
docker push myapache:v1

5.7 常见镜像

5.7.1 Alpine

文档

Alpine 是一种更轻型的 Linux 发行版(即和ubuntu、CentOS等是并列的),其因为用了 musl libcbusybox 技术从而使得镜像体积非常小,下表时官方镜像的大小比较:

REPOSITORY          TAG           IMAGE ID          VIRTUAL SIZE
alpine              latest        4e38e38c8ce0      4.799 MB
debian              latest        4d6ce913b130      84.98 MB
ubuntu              latest        b39b81afc8ca      188.3 MB
centos              latest        8efe422e6104      210 MB

ubuntu 里的包管理工具是 apt-get update xxx,alpine 里的包管理工具是 apk add xxx

应用场景:如果我们有一个alpine的镜像,希望在其中安装一个包,可以先在 alpine的apk包仓库 中寻找,其界面如下图所示:

在这里插入图片描述

六、容器的一般操作

6.1 查看容器

docker ps -a # 查看所有的容器
docker ps    # 查看所有运行的容器
docker ps --no-trunc # 不折行, 使结果都能可视化
sudo docker exec -it 'test' bash # 进入已经启动的容器,使用 exec 进入容器会不受原终端运行的影响, 如果在进入容器后执行 exit 命令,容器也不会停止,只会退出该容器

6.2 启动容器

拉取到镜像之后,要使用该镜像创建一个容器,才可以使用相关的内容

语法:

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 卡

6.3 进入容器

在使用 -d 的方式进入后台运行时,如果想要进入容器,可以使用下面两种方式:

  • docker attach 'test':使用 exit 退出容器会导致容器终止
  • docker exec -it 'test' bash :使用 exit 退出容器不会导致容器终止

6.4 停止容器

docker stop 'test'

6.5 重启容器

docker restart 'test'

6.6 删除容器

docker stop 'test'
docker rm 'test'

6.7 杀死容器中正在运行的程序

docker kill 'test'

6.8 在 docker 中杀死正在运行的进程

kill -9 pid

6.9 容器的连接

容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P 或 -p 参数来指定端口映射。

  • -P :是容器内部端口随机映射到主机的高端口。
  • -p : 是容器内部端口绑定到指定的主机端口,-p 主机端口:容器端口

6.10 查看 docker 的创建历史

docker history [options] IMAGE
  • -H:以可读格式打印镜像大小和日期
  • –no-trunc:显示完整的提交记录
  • -q:仅列出提交记录 id

6.11 设置容器的参数

通常普通用户没有 sudo 权限,但希望改 docker container 的 shm 参数,该怎么办呢? 可以按如下操作

# 停止当前正在运行的容器
docker stop container_id_or_name

# 从停止状态的容器创建一个新镜像
docker commit container_id_or_name new_image_name

# 使用新创建镜像启动一个新容器,并设置/dev/shm大小
docker run --shm-size=1g -d new_image_name

6.12 docker build

6.12.1 docker build --build-arg

首先有一个 Dockerfile

FROM ubuntu:latest # 基础镜像

ARG path # 通过 docker build --build-arg path=a 传入
ARG name # 通过 docker build --build-arg name=b 传入

WORKDIR /$name #  设置 container 的工作路径(即在哪个路径执行命令)

COPY $path /$name/ # docker build 时从 开发机的 $path 拷贝到 container 内的 /$name/
# 例如 从开发机的 mycli/dist 拷贝到 container 内的 /mycli 路径

ENTRYPOINT ["./mycli"] # 设置 container 启动时执行的命令

然后在 Makefile 可以通过 docker build --build-arg path=mycli/dist --build-arg name=mycli --tag=1.2.3 执行 docker build

最终 docker exec mycli:1.2.3 – sh

会进到 container 里的 WORKDIR 并执行 ENTRYPOINT 命令(即 cd /mycli && ./mycli)

七、docker-compose

docker-compose 相比 k8s 很轻量,可以方便调度和编排各 docker:

version: "3.8"
services:
  nginx:
    image: 'nginx:1.17.3'
    container_name: 'my-nginx'
    restart: always
    network_mode: host
    volumes:
      - '/etc/localtime:/etc/localtime:ro'
      - '/home/dir1:/home/dir2'
      - '/var/www:/var/www'
      - '/etc/nginx/nginx.conf:/etc/nginx/nginx.conf'
      - '/etc/nginx/conf.d:/etc/nginx/conf.d'
    logging:
      driver: json-file
      options:
        max-file: '5'
        max-size: 50m

八、升级 runc 版本

升级runc,搜 CVE-xxxxx 的 bug 号,看官方的 bug 描述(不要看别人的 bug 描述),然后下载 fixed 的版本,更新 runc 的二进制(一般在 /bin/runc, 可以用 which runc 搜到),然后 systemctl stop

docker && systemctl start docker && docker version 看 runc 的版本 && runc —version 看版本
# 下载
wget https://github.com/opencontainers/runc/releases/download/v1.1.12/runc.amd64

# 停止docker
systemctl stop docker

# 复制
which runc
cp /usr/bin/runc /usr/bin/runc.bak
cp runc.amd64 /usr/bin/runc
chmod +x /usr/bin/runc

# 启动
systemctl start docker
docker ps
docker version
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呆呆的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值