聊聊 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

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

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和AMD642. 系统的Linux内核必须是3.8或者更新;
3. 内核必须支持cgroups和命名空间;
4. docker对disk的管理比较有限;
5. 网络管理相对简单,主要是机遇namespace隔离;
6.container随着用户进程的停止而销毁,container中的log等用户数据不方便收集。

Docker的学习资源

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

版权

部分资料参考:掘金社区Docker专栏

本作品采用《CC 协议》,转载必须注明作者和本文链接
阿德
zhangdeTalk
讨论数量: 1

标题都能抄错

4个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!