聊聊 Docker

Docker 是什么?

定义

Docker 是一款 开源的应用容器引擎。

简单来说,就是 以容器虚拟化技术为基础的软件。可以把应用程序和所依赖的包一起打包到一个可移植的镜像中,发布到 Linux 或者 Windows 上运行。(代码 + 运行环境)

虚拟机与容器技术对比

虚拟机

虚拟机 可以高效使用计算机资源(比如可以解决同一种服务端口冲突、程序依赖版本库不同、进程受限制等问题) ,常见的虚拟机有: vmware、virtualbox

虚拟机的 底层原理 是基于 hypervisor(硬件抽象层) ,也叫 虚拟机监视器(VMM)

容器技术

是一种沙盒技术,相互之间不会有任何接口。将应用运行在容器中,容器之间隔离的。

容器技术更 关注应用本身,应用和所依赖环境的共享和复用。

Linux Container (简称 LXC),是一种内核轻量级的操作系统层虚拟化技术,容器化技术就是基于 LXC 实现的。

四个维度对比

由此可见,为什么容器技术会出现,为什么容器技术会那么流行,是因为虚拟机有痛点的,容器技术就是为了解决这些痛点而生的。而 Docker 就是容器化技术的代表。

Docker 的应用场景

Docker 的实现原理与优势

Docker 的技术架构

Docker 是由 dotCloud 公司于 2013 年推出的产品,用 GO 语言编写的。

Docker 有两种发行版本 ,分别是 CE (Community Edition,社区版)和 EE (Enterprise Edition,企业版)。

Docker 是 C/S 架构。客户端(docker cli,执行程序),通过命令行和 API 形式与守护进程(docker daemon,提供 Docker 服务)进行通讯。

举个具体的例子,在常见的虚拟机实现中,我们要搭建一套 LNMP 结构的服务,我们通常会建立一个虚拟机,在虚拟机中安装上 Linux 系统,之后分别安装 Nginx、MySQL 和 PHP。

而在 Docker 里,最佳的实践是分别基于 Nginx、MySQL 和 PHP 的镜像建立三个容器,分别运行 Nginx、MySQL 和 PHP ,而它们所在的虚拟操作系统也直接共享于宿主机的操作系统。

Docker 的实现原理

Linux 三大技术

Docker 的实现,主要归结于 Linux 的三大技术:命名空间(Namespaces)、控制组(Control Groups)和联合文件系统(Union FIle System)。

命名空间(Namespaces)

在编程语言中,命名空间的主要目的就是为了集合相同模块的类,区分不同模块间的同名类。
Linux 内核的命名空间,就是 能够将计算机资源进行切割划分,形成各自独立的空间。
如 User Namespace、Net Namespace、PID Namespace、Mount Namespace 等等。

利用 PID Namespace,Docker 就实现了容器中隔离程序运行中进程隔离这一目标。

控制组(Control Groups)

资源控制组的作用就是 控制计算机资源 。CGroups 主要做的是硬件资源的隔离。 除了资源的隔离,还有资源分配这个关键性的作用。

通过 CGroups,我们 可以指定任意一个隔离环境对任意资源的占用值或占用率 ,这对于很多分布式使用场景来说是非常有用的功能。

联合文件系统(Union FIle System)

一种能够 同时挂载不同实际文件或文件夹到同一目录,形成一种联合文件结构的文件系统。

Docker 用它解决虚拟环境对文件系统占用过量,实现虚拟环境快速启停等问题。

Docker 大幅减少了虚拟文件系统对物理存储空间的占用。(例子:Git,Git 中每进行一次提交,Git 并不是将我们所有的内容打包成一个版本,而只是将修改的部分进行记录,这样即使我们提交很多次后,代码库的空间占用也不会倍数增加)

Docker 的优势

  1. 应用的安全性、可移植性和节约成本;
  2. 让自动化部署更简单(持续集成CI和持续部署CD,快速交付);
  3. 加速应用架构现代化进程(如微服务架构);
  4. 充分利用服务器资源;
  5. 跨平台部署和动态伸缩(如使用K8s编排工具管理)。

Docker 的安装

macos 安装

安装教程:https://www.runoob.com/docker/macos-docker-install.html

windows 安装

安装教程:https://www.runoob.com/docker/windows-docker-install.html 或者
https://blog.58heshihu.com/index.php/archives/286/

Linux 安装

centos:https://www.runoob.com/docker/centos-docker-install.html
ubuntu:https://www.runoob.com/docker/ubuntu-docker-install.html

Docker 的四大核心组成

镜像(Image)

可以理解为 一个只读的文件包,其中包含了虚拟环境运行最原始文件系统的内容。

查看镜像列表:docker images

镜像命名格式:开发者 / 镜像名字:版本号

拉取: docker pull 镜像名称

搜索: docker search 镜像名称 //从docker hub搜索

镜像详细信息: docker inspect 镜像名称/ID

删除镜像: docker rmi 镜像名称/ID

容器(Container)

简介

在容器技术中, 容器就是用来隔离虚拟环境的基础设施,而在 docker 里,它也被引申为隔离出来的虚拟环境。

容器包括

  • 一个 Docker 镜像
  • 一个程序运行环境
  • 一个指令集合

容器的生命周期

  • Created:容器已经被创建,容器所需的相关资源已经准备就绪,但容器中的程序还未处于运行状态
  • Running:容器正在运行,也就是容器中的应用正在运行
  • Paused:容器已暂停,表示容器中的所有程序都处于暂停 ( 不是停止 ) 状态
  • Stopped:容器处于停止状态,占用的资源和沙盒环境都依然存在,只是容器中的应用程序均已停止
  • Deleted:容器已删除,相关占用的资源及存储在 Docker 中的管理信息也都已释放和移除

常用命令

查看正在运行的容器列表:docker ps
所有容器:docker ps -a
创建启动容器:docker run –name redis -d redis:5.0.15
停止容器:docker stop 容器名字/ID
启动/重启容器:docker start/restart 容器名字/ID
删除容器:docker rm [-f] //-f强制,可以删除正在运行的容器
进入容器:docker exec -it redis bash //容器内部是虚拟出来的一个Linux
查看容器报错信息:docker logs 容器ID

网络(Network)

容器网络 实质上也是由 Docker 为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作系统的网络环境中独立出来,形成容器自有的网络设备、IP 协议栈、端口套接字、IP 路由表、防火墙等等与网络相关的模块。

  • 沙盒(Sandbox)提供了容器的虚拟网络栈,也就是之前所提到的端口套接字、IP 路由表、防火墙等的内容。其实现隔离了容器网络与宿主机网络,形成了完全独立的容器网络环境

  • 网络(Network)可以理解为 Docker 内部的虚拟子网,网络内的参与者相互可见并能够进行通讯。Docker 的这种虚拟网络也是于宿主机网络存在隔离关系的,其目的主要是形成容器间的安全通讯环境

  • 端点(Endpoint)是位于容器或网络隔离墙之上的洞,其主要目的是形成一个可以控制的突破封闭的网络环境的出入口。当容器的端点与网络的端点形成配对后,就如同在这两者之间搭建了桥梁,便能够进行数据传输了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KuxNurAy-1692625431644)(http://flt-pan.58heshihu.com/blog/typecho/llkx21og.png)]

Docker 容器网络一共有 5 种网络驱动 ,网络驱动,分别是: Bridge Driver(网桥 默认)、Host Driver、Overlay Driver(集群)、MacLan Driver、None Driver。

容器之间以及宿主机与容器之间可以通过端口来进行访问。

常用命令

查看网络列表:docker network ls
容器加入网络:

docker run -d –name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes –network network_name mysql:5.7
docker run -d –name php –link mysql –network network_name php:latest

端口映射:

docker run -d –name nginx -p 8080:80 nginx:1.12 //80为容器的端口,8080可为宿主机或别的容器的端口

数据卷(Volume)

在 Docker 中,通过 bind mount、volume、tmpfs mount 这几种方式进行数据共享或持久化的文件或目录,我们都称为数据卷 (Volume)。

Docker 的数据卷一共 有 3 中挂载方式 ,分别是: Bind Mount、Volume、Tmpfs Mount

  • Bind Mount 能够直接将宿主操作系统中的目录和文件挂载到容器内的文件系统中,通过指定容器外的路径和容器内的路径,就可以形成挂载映射关系,在容器内外对文件的读写,都是相互可见的

  • Volume 也是从宿主操作系统中挂载目录到容器内,只不过这个挂载的目录由 Docker 进行管理,我们只需要指定容器内的目录,不需要关心具体挂载到了宿主操作系统中的哪里

  • Tmpfs Mount 支持挂载系统内存中的一部分到容器的文件系统里,不过由于内存和容器的特征,它的存储并不是持久的,其中的内容会随着容器的停止而消失

bind mount方式:

docker run -d –name nginx_test -v /nginx/html:/usr/share/nginx/html nginx

查看容器挂在文件:

docker exec nginx_test ls /usr/share/nginx/html

利器 docker-compose

docker-compose 是用于定义和运行多容器 Docker 应用程序的工具(集成部署),使用 docker-compose 可以高效管理容器。

使用步骤:

1、Dockerfile 定义应用程序的环境(定制自己的镜像源)
2、docker-compose.yml 定义构成应用程序的服务,多个容器一起执行
3、docker-compose up 启动并运行整个应用程序
备注:Linux需单独安装docker-compose,macos和windows已经集成

实战案例 – 搭建 LNMP 环境

源码下载: https://github.com/zhangdejian/docker_lnmp.git

请参考我的另外一篇博客: https://learnku.com/articles/39417 (Dockerfile 方式定制 lnmp 环境)

Docker 的不足

  1. 必须在64位机器上运行,目前仅支持x86_64和AMD64;
  2. 系统的Linux内核必须是3.8或者更新;
  3. 内核必须支持cgroups和命名空间;
  4. docker对disk的管理比较有限;
  5. 网络管理相对简单,主要是机遇namespace隔离;
    6.container随着用户进程的停止而销毁,container中的log等用户数据不方便收集。

Docker 的学习资源

官网: https://docs.docker.com/engine/reference/run/
中文手册: https://docker_practice.gitee.io/zh-cn/basic_concept/image.html
菜鸟教程: https://www.runoob.com/docker/docker-tutorial.html
掘金社区: https://juejin.cn/tag/Docker
开源中国: https://www.oschina.net/question/tag/docker
SegmentFault: https://segmentfault.com/t/docker
推荐入门书籍: 《Docker 技术入门与实战》 、 《Docker 进阶与实战》华为团队
看云:《Docker — 从入门到实践》
优秀文章:
CentOS 安装 docker
Dockerfile 方式定制 lnmp 环境
Docker 搭建 Jenkins 实现自动部署
Docker+LNMP+Jenkins+ 码云实现 PHP 代码自动化部署
Docker 操作命令大全