什么是容器数据卷

  • docker的理念, 将应用和环境打包成一个镜像, 如果应用产生数据, 那么我们删除容器数据就会丢失.
  • 所以我们需要数据可以持久化, 比如 mysql的数据可以存储在本地! 并且容器之间可以数据共享, 这就是数据卷技术.

使用数据卷挂载目录

# 命令中 -v 就是在挂载目录 主机目录:容器内目录
docker run -it -v /home/test:/home centos /bin/bash

可以使用 docker inspect 命令 查看挂载

50425-oaf25b0xjpe.png

mysql容器实战

# 命令详解
# -d 后台运行
# -p 端口映射 宿主机端口:容器内端口
# -v 数据卷挂载
# -e 环境配置
# --name 容器名字

docker run -d -p 3333:3306 -v /home/docker/mysql/conf:/etc/mysql/conf.d -v /home/docker/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name my-mysql mysql

假设我们将容器删除, 就会发现挂载到本地的数据劵依旧没有丢失, 这就实现了容器数据化持久功能

具名挂载和匿名挂载

docker的挂载方式有三种 具名挂载和匿名挂载 指定路径挂载, 上面mysql实战中就使用了指定路径挂载

匿名挂载

# -v 直接写容器内路径

docker run -d -P --name nginx01 -v /etc/nginx nginx

# 启动容器后, 可以使用 docker volume ls 命令来查看所有卷
docker volume ls
DRIVER              VOLUME NAME
local               44bf15e29c95e85ab32f4d94c7e2766d0880d602342cf1ac00e3044c1c3415f8
local               723cc8cf114d9d4bb4ca51092b11fccf2b29d0927739414938a2cde22de4e43e

具名挂载

# -v 卷名:容器内路径
docker run -d -P --name nginx02 -v juming:/etc/nginx nginx

# 再次查看所有的卷
docker volume ls
DRIVER              VOLUME NAME
local               44bf15e29c95e85ab32f4d94c7e2766d0880d602342cf1ac00e3044c1c3415f8
local               723cc8cf114d9d4bb4ca51092b11fccf2b29d0927739414938a2cde22de4e43e
local               juming

查看匿名和具名挂载的目录

# 使用 docker volume inspect 卷名来查看挂载的目录

docker volume  inspect 44bf15e29c95e85ab32f4d94c7e2766d0880d602342cf1ac00e3044c1c3415f8

[
    {
        "CreatedAt": "2020-09-11T05:49:44Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/44bf15e29c95e85ab32f4d94c7e2766d0880d602342cf1ac00e3044c1c3415f8/_data",
        "Name": "44bf15e29c95e85ab32f4d94c7e2766d0880d602342cf1ac00e3044c1c3415f8",
        "Options": null,
        "Scope": "local"
    }
]
  • /var/lib/docker/ 目录就是docker的工作目录
  • 在其中 /var/lib/docker/volumes/ 目录就是存放了 docker 的所有挂载卷
  • 进入到目录中就可以看到挂载的目录了
    43432-ghe8velcfed.png

总结

-v 容器内路径            # 匿名挂载
-v 卷名:容器内路径        # 具名挂载
-v 宿主机路径:容器内路径   # 指定路径挂载  

镜像是什么

镜像是一种轻量级, 可执行的独立的软件包, 用来打包软件运行环境和基于运行环境开发的软件, 它包含运行某个软件所需要的内容 比如: 代码, 环境, 库, 配置文件等, 所有的应用, 直接打包docker镜像 就可以直接跑起来.

Docker镜像加载原理

UnionFS(联合文件系统)

UnionFS(联合文件系统) 是一种分层,轻量级并且高性能的文件系统, 它支持对文件系统的修改作为一次提交来一层层的叠加, 同时可以将不同目录挂载到同一个虚拟文件系统下. UnionFS文件系统是 Docker 镜像的基础. 镜像可以通过分层来进行继承, 基于基础镜像(没有父镜像, 可以制作各种具体的应用镜像).

特性: 一次同时加载多个文件系统, 但从外面看起来, 只能看到一个文件系统, 联合加载会把各层文件系统叠加起来, 这样最终的文件系统会包含所有底层的文件和目录

Docker镜像加载原理

  • docker的镜像实际上由一层一层的文件系统组成, 这种层级的文件系统UnionFS.
  • bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统, 在Docker镜像的最底层是bootfs. 这一层与我们典型的Linux/Unix系统是一样的, 包含boot加载器和内核. 当boot加载完成之后整个内核就都在内存中了, 此时内存的使用权已由bootfs转交给内核, 此时系统也会卸载bootfs.
  • rootfs(root file system), 在bootfs之上. 包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件. rootfs就是各种不同的操作系统发行版, 比如Ubuntu, Centos等等.

理解

  • 一个linux系统按启动顺序可以划分为: 引导加载, 内核, 文件系统, 应用程序.
  • 系统启动都需要引导加载也就是 bootloader和kernel, 系统运行起来之后就不需要bootfs, 也就会把它卸载掉
  • 对于Docker安装OS来说Docker使用了Linux本身的bootfs, 只需要安装自己所需的rootfs
    63513-ldoiff6h42g.png

分层理解

  • Docker安装普通镜像来说 Docker本身是分层下载镜像, 所以可以提取出公共层镜像进行复用.

90338-p4razp5s2x.png

Docker 常用命令

Docker 帮助命令

docker version # 显示docker的版本信息
docker info    # 显示docker的系统信息
docker 命令 --help  # 帮助命令

镜像命令

docker images 查看主机上所有的镜像

docker@docker-VirtualBox:~$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              bf756fb1ae65        8 months ago        13.3kB
  1. 解释
  • REPOSITORY 镜像的仓库源
  • TAG 镜像的标签
  • IMAGE ID 镜像的ID
  • CREATED 镜像的创建时间
  • SIZE 镜像的大小
  1. 可选项
 -a  --all   # 列出所有镜像
 -q  --quiet # 只显示镜像的ID  

docker search 搜索镜像

docker search mysql
NAME                              DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
mysql                             MySQL is a widely used, open-source relation…   9945                [OK]
mariadb                           MariaDB is a community-developed fork of MyS…   3638                [OK]
mysql/mysql-server                Optimized MySQL Server Docker images. Create…   725                                     [OK]
percona                           Percona Server is a fork of the MySQL relati…   508                 [OK]
  1. 可选项 -f, 过滤
docker search mysql -f STARS=3000
NAME                DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
mysql               MySQL is a widely used, open-source relation…   9945                [OK]
mariadb             MariaDB is a community-developed fork of MyS…   3638                [OK]

docker pull 拉去镜像

# 下载镜像 docker pull 镜像名称[:tag]
docker@docker-VirtualBox:~$ docker pull mysql
Using default tag: latest  # 如果不写 tag 默认就是 latest
latest: Pulling from library/mysql 
bf5952930446: Pull complete # 分层下载 docker image的核心 联合文件系统
8254623a9871: Pull complete
938e3e06dac4: Pull complete
ea28ebf28884: Pull complete
f3cef38785c2: Pull complete
894f9792565a: Pull complete
1d8a57523420: Pull complete
6c676912929f: Pull complete
3cdd8ff735c9: Pull complete
4c70cbe51682: Pull complete
e21cf0cb4dc3: Pull complete
28c36cd3abcc: Pull complete
Digest: sha256:6ded54eb1e5d048d8310321ba7b92587e9eadc83b519165b70bbe47e4046e76a # 签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest # 真实地址

# docker pull mysql 等于 docker pull  docker.io/library/mysql:latest

docker rmi 删除镜像

docker rmi 镜像名称 # 删除单个镜像
docker rmi 镜像id # 删除单个镜像
docker rmi 镜像id 镜像id 镜像id # 删除多个镜像
docker rmi -f $(docker images -ag) # 删除全部镜像

容器命令

docker run 新建容器并启动

docker run [可选参数] image

# 参数说明
--name="name" 容器名字
-d            后台方式运行
-it           使用交互方式运行, 进入容器内
-p            指定容器端口 -p 8080:8080
   -p ip:主机端口:容器端口
   -p 主机端口:容器端口 (常用)
   -P 容器端口 
-P 随机指定端口

docker ps 查看容器

# docker ps 命令
     # 列出正在运行的容器
-a   # 列出所有容器
-n=? # 列出最近创建的容器
-q   # 只显示容器编号 

docker rm 删除容器

docker rm 容器id  # 删除指定容器, 先停止容器才能删除, 强制删除 rm -f
docker rm $(docker ps -aq) # 删除所有容器

启动和停止容器

docker start 容器id   # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id    # 停止当前正在运行的容器
docker kill 容器id    # 强制停止当前容器

Docker 其他常用命令

查看日志

docker logs 容器id
 - tf 显示日志
 -- tail number 显示条数

查看容器内部的进程信息

docker top 容器id

查看镜像的元数据

docker inspect 容器id

从容器内拷贝文件到主机上

docker cp 容器id:容器内路径 主机路径

Docker的基本组成

73600-4k8lz4i4zi8.png

  • 镜像(Image): docker镜像, 就相当于是镜像模板, 比如官方镜像Ubuntu:16.04就包含了完整的一套Ubuntu16.4最小系统 可以通过镜像来创建一个或多个容器.
  • 容器(Container): 镜像和容器的关系, 就像面向对象程序设计种的类和对象一样, 镜像是静态的定义, 容器时镜像运行时的实体, 容器可以被创建 启动 停止 删除 暂停等.
  • 仓库(Repository): 仓库可看成一个代码控制中心, 用来保存镜像. 仓库分为公有仓库和私有仓库. 其中DockerHub就是docker官方的仓库地址

安装

docker官方文档 我的系统是 ubuntu 所以接下来的教程都是在 ubuntu 中安装的

  1. 卸载旧的版本
sudo apt-get remove docker docker-engine docker.io containerd runc
  1. 更新apt软件源并允许apt通过HTTPS使用仓库
sudo apt-get update

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
  1. 添加Docker的官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  1. 设置Docker稳定版软件源
# 官方源, 国内安装比较慢推荐使用阿里云的
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

# 阿里云软件源
sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
  1. 添加仓库后, 更新apt源索引 并且安装最新的 docker-ce 社区版
sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io
  1. 启动docker
sudo service docker start
  1. 使用 docker version 判断是否安装成功

36515-y5hleldy74.png

运行 hello-world

使用 docker run hello-world

45087-h5ack7tnbnw.png

  • 上图可以看到第一步运行 docker run hello-world 命令后先在本来没有在本地找到 hello-world 镜像
  • 第二步开始去远程仓库拉去 hello-world 镜像, 拉去完成之后返回一串签名信息
  • 第三步输出了 Hello from Docker! 表示已经完成了

docker run 命令详细分析

01534-qm17l6vxey.png

查看下载的镜像

docker images

01432-o3sc2ejyu9g.png

卸载 docker

  1. 卸载Docker Engine, CLI和Containerd软件包
sudo apt-get purge docker-ce docker-ce-cli containerd.io
  1. 手动删除docker的资源 比如: images, containers, volumes
sudo rm -rf /var/lib/docker

Docker底层原理

Docker是怎么工作的?

  • Docker是一个 Client - Server 结构的系统, Docker的守护进程运行在主机上, 通过 Socket从客户端访问
  • DockerServer 接收到 DockerClient的指令, 就会执行这个命令

17909-x35oynbw52i.png

Docker为什么比虚拟机快

59067-4cpj4c4zmml.png

  1. Docker有着比虚拟机更少的抽象层
  2. Docker利用的是宿主机的内核, 而 vm 需要 Guest OS.
  3. 所以说新建一个容器的时候 docker需要像虚拟机一个重新加载一个操作系统内核避免引导, 虚拟机加载GuestOS是分钟级的. 而docker是里面宿主机的操作系统, 省略了复杂的过程是秒级的.