# 虚拟化技术

Virtualization 是一种资源管理技术,将计算机各种实体资源(服务器,内存,网络)予以抽象,打破实体结构间不可切割的障碍,使用户可以更好的方式利用资源。从而实现在同一主机上运行多个系统或应用。

软件虚拟化技术是利用软件技术,在现有的物理平台上实现对物理平台访问的截获和模拟。有些软件虚拟化技术需要依赖硬件支持,比如:VMware,KVM。

Docker 就是软件虚拟化,软件虚拟化分为好几类,Docker 实际是操作系统层虚拟化。操作系统级虚拟化也被称为容器化,它允许多个相互隔离的用户空间实例存在,这些用户空间实例也被容器

普通的进程可以看到计算机所有资源而容器只能看到分配给该容器的资源

实现操作系统虚拟化需要用到 Namespace cgroups 技术。

因为不是主要讲解虚拟化技术的底层实现,所以详细可以看这篇文章:操作系统级虚拟化概述

# Docker 虚拟化

Docker 是一个开源的应用容器引擎,它让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到安装了任何 Linux 发行版本的机器上。Docker 是直接运行在宿主操作系统之上的一个容器(操作系统级别的虚拟化),所有容器用的都是宿主操作系统的内核

Docker 能快速搭建开发环境,并且每个容器相互隔离:我们只需要将这些环境打包成镜像,到需要在服务器上部署时,可以直接下载镜像实现一键部署。

# Docker 与虚拟机区别

虚拟机

  • 基础设施(Infrastructure):个人电脑,服务器,云主机。
  • 主操作系统(Host Operating System):基础设施上运行的 MacOS,Windows 或者某个 Linux 发行版。
  • 虚拟机管理系统(Hypervisor):利用 Hypervisor,可以在主操作系统之上运行多个不同的从操作系统。类型 1 的 Hypervisor 有支持 MacOS 的 HyperKit,支持 Windows 的 Hyper-V 以及支持 Linux 的 KVM。类型 2 的 Hypervisor 有 VirtualBox 和 VMWare。
  • 操作系统(Guest Operating System):假设你需要运行 3 个相互隔离的应用,则需要使用 Hypervisor 启动 3 个从操作系统,也就是 3 个虚拟机。这些虚拟机都非常大,也许有 700MB,这就意味着它们将占用 2.1GB 的磁盘空间。更糟糕的是,它们还会消耗很多 CPU 和内存。
  • 各种依赖:每一个从操作系统都需要安装许多依赖。如果你的的应用需要连接 PostgreSQL 的话,则需要安装 libpq-dev;如果你使用 Ruby 的话,应该需要安装 gems;如果使用其他编程语言,比如 Python 或者 Node.js,都会需要安装对应的依赖库。

Docker 容器

  • 主操作系统(Host Operating System):所有主流的 Linux 发行版都可以运行 Docker。对于 MacOS 和 Windows,也有一些办法 "运行"Docker。
  • Docker 守护进程(Docker Daemon):Docker 守护进程取代了 Hypervisor,它是运行在操作系统之上的后台进程,负责管理 Docker 容器
  • 各种依赖。对于 Docker,应用的所有依赖都打包在 Docker 镜像中,Docker 容器是基于 Docker 镜像创建的
  • 应用。应用的源代码与它的依赖都打包在 Docker 镜像中,不同的应用需要不同的 Docker 镜像。不同的应用运行在不同的 Docker 容器中,它们是相互隔离的。

Docker 守护进程可以直接与主操作系统进行通信,为各个 Docker 容器分配资源;它还可以将容器与主操作系统隔离,并将各个容器互相隔离。

# Docker 架构

Docker 是 C/S 架构,通过远程 API 来管理和创建容器。

客户端:客户端通过命令行或者其他工具使用 Docker SDK 和 Docker 守护进程通信。

主机:物理或虚拟机器,用于执行 Docker 守护进程和容器。

其他的基本概念:

  • 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。

  • 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

  • 仓库(Repository):仓库可看着一个代码控制中心,用来保存镜像。

# Docker 安装

我使用的系统是 Ubuntu 20.04.3 版本

先安装一些工具

sudo apt-get install ca-certificates curl gnupg lsb-release

再安装官方的 GPG key:

sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

将 Docker 的库添加到 apt 资源列表中:

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

更新 apt:

sudo apt update

安装 Docker CE 版本

sudo apt install docker-ce

等待安装后,查看 Docker 版本

sudo docker --version

但是我们使用了 sudo 命令(因为当前用户使用权限可能不足),所以需要将当前用户加入到 Docker 组里面

sudo usermod -aG docker <用户名>

退出 ssh 终端,重新连接即可生效。

我们可以先看一下 Docker 这个组

# 这里把提示符部分也写出来是为了展示一下我的用户名
cyan@cyan-virtual-machine:~$ cat /etc/group
# 最后一排:docker:x:998:cyan
# 我已经执行过 usermod 命令了,所以 docker 组有 cyan 这个用户

关于详细的 Linux 组的知识,你可以参考这篇文章:Linux 文件权限

如果加入组后权限依然不够,执行: newgrp docker 。newgrp 命令是登入群组。

前文提到 Docker 架构(C/S),现在部署 Nginx 服务器

sudo docker run -d -p 80:80 nginx

会从镜像仓库里面下载对应的镜像,下载完成后就在后台运行了

在浏览器的 url 中输入虚拟机 IP,就能看到 Nginx 启动了

该命令流程:

  1. Docker 客户端将操作发送给服务端,告诉服务端我们要运行 nginx 这个镜像。
  2. Docker 服务端先看看本地有没有这个镜像,发现没有。
  3. 接着只能从公共仓库 Docker Hub 去查找下载镜像了。
  4. 下载完成,镜像成功保存到本地。
  5. Docker 服务端加载 Nginx 镜像,启动容器开始正常运行。

# 参考

https://pdai.tech/md/devops/docker/docker-01-docker-vm.html

https://www.yuque.com/qingkongxiaguang/zwhkpi/kq6rlg

https://my.oschina.net/kelvinxupt/blog/1602990

https://www.cnblogs.com/jie-fang/p/10279629.html