1.1 什么是 Docker?
Docker 最初是 dotCloud 公司创始人在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于 2013 年 3 月以 Apache 2.0 授权协议开 源,主要项目代码在 GitHub 上进行维护。 在 2013 年底,dotCloud 公司决定改名为 Docker。Docker 最初是在 Ubuntu 12.04 上开 发实现的;Red Hat 则从 RHEL 6.5 开始对 Docker 进行支持。 Docker 使用 Google 公司推出的 Go 语言进行开发实现,基于操作系统内核中的 Cgroup (资源控制)、Namespace(资源隔离)与 OverlayFS(数据存储)等技术,实现基于操作 系统层面的(应用)虚拟化技术。 最初实现是基于 LXC 技术,从 0.7 版本以后开始去除 LXC,转而使用自行开发的 libcontainer(容器管理技术)。 Docker 运行层次图解: 前提条件: 操作系统需要支持运行 Docker 每个操作系统中运行一个 Docker 进程
1.2 docker 发行版本
Docker 发行版本 Docker 从 1.13.x 版本开始,版本分为企业版 EE 和社区版 CE,版本号也改为按照时间线来 发布,比如 17.03 就是 2017 年 3 月,有点类似于 ubuntu 的版本发布方式。 Docker EE(企业版),Docker CE(社区版) 在 CentOS 系统中可以使用 docker version 查看版本信息 [root@master ~]# docker version Client: Docker Engine - Community Version: API version: 19.03.5 1.40
1.3Docker 基本实现原理
通过三个方面实现容器化技术的前置:
1) 操作系统的 NameSpace 隔离系统资源技术,通过隔离网络、PID 进程、系统信号
量、文件系统挂载、主机名与域名, 来实现在同一宿主机系统中,运行不同的容
器,而每个容器之间相互隔离,运行互不干扰。
2) 使用系统的 Cgroups 系统资源配额功能, 限制资源包括: CPU、Memory、Blkio(块设
备)、Network。
3) 通过 OverlayFS 数据存储技术, 实现容器镜像的物理存储与新建容器存储。
1.3.0 讲解容器基本实现原理
1.3.1 Linux NameSpace
当一台物理主机(宿主机)运行容器的时候, 为了避免容器所需系统资源之间相互干扰
与。所以 Docker 利用操作系统的隔离技术-NameSpace, 来实现在同一个操作系统
中,不同容器之间的资源独立运行。
Linux Namespace 是 Linux 系统提供的一种资源隔离机制,可实现系统资源隔离的列
表如下:
1.3.1.1 查看系统资源隔离
1.3.2Cgroups (资源控制)
在操作系统解决了资源相互隔离的问题以后,还需要解决资源限制的问题,也就是避
免在同一个操作系统中,防止有些资源消耗较大的容器,将整个物理机器(宿主机)的
硬件资源(CPU, Memory) 占满。
在 Linux 系统中能够控制的资源列表如下:
1.3.2 查看系统实现的限制资源
[root@node212 ~]# cat /proc/cgroups #subsys_name hierarchy num_cgroups enabled cpuset 7 6 1 cpu 6 83 1 cpuacct 6 83 1 memory 10 83 1 devices 4 83 1 freezer 8 6 1 net_cls 2 6 1 blkio 5 83 1 perf_event 11 6 1 hugetlb 3 6 1 pids 9 83 1 net_prio 2 6 1
1.3.3 OverlayFS
OverlayFS 是一种堆叠文件系统,它依赖并建立在其它的文件系统之上(例如 ext4fs 和 xfs 等),
并不直接参与磁盘空间结构的划分,仅仅将原来系统文件中的文件或者目录进行"合并一起",
最后向用户展示"合并"的文件是在同一级的目录, 这就是联合挂载技术, 相对于 AUFS
(<1.12 早期使用的存储技术), OverlayFS 速度更快,实现更简单。
Linux 内核为 Docker 提供的 OverlayFS 驱动有两种:Overlay 和 Overlay2。而 Overlay2 是相
对于 Overlay 的一种改进,在 Inode 利用率方面比 Overlay 更有效。但是 Overlay 有环境需
求:Docker 版本 17.06.02+,宿主机文件系统需要是 EXT4 或 XFS 格式。
1.3.4 OverlayFS 实现方式
OverlayFS 通过三个目录:lower 目录、upper 目录、以及 work 目录实现,其中 lower 目录可
以是多个, upper 目录为可以进行读写操作的目录, work 目录为工作基础目录,挂载后内容会
被清空,且在使用过程中其内容用户不可见,最后联合挂载完成给用户呈现的统一视图称为
merged 目录。
1.3.5 Overlay2 命令行挂载操作
1.创建文件 [root@master ~]# mkdir /lower{1..3} [root@master ~]# mkdir /upper /work /merged 2.挂载文件系统 [root@master ~]# mount -t overlay overlay -o lowerdir=/lower1:/lower2:/lower3,upperdir=/upper,workdir=/work /merged 3.查看挂载 [root@master ~]# mount | grep merged 4.在/upper 目录中写入文件,在 merged 中可以显示 [root@master /]# touch /upper/upper.txt [root@master /]# ll /merged/ total 0 -rw-r--r-- 1 root root 0 Mar 14 02:17 upper.txt 5. 在 merged 中写入文件, 实际存储到了/uppper [root@master /]# touch /merged/d.txt [root@master /]# ll /upper/ total 0 -rw-r--r-- 1 root root 0 Mar 14 02:19 d.txt 注:如果没有 upperdir, merged 是只读的 [root@node-2 overlay2]# umount /merged [root@node-2 overlay2]# mount -t overlay overlay -o lowerdir=/lower1:/lower2 /merged [root@master /]# touch /merged/c.txt touch: cannot touch ‘/merged/c.txt’: Read-only file system
1.3.6 NameSpace、Cgroup 与 OverlayFS 关系
在操作系统中, 可以根据宿主机的资源情况,创建不同应用与数量不同的容器。每个容器 的 CPU、Memory、Network 由系统的内核 NameSpace 进行隔离, 相互之间不影响。
为了防止某个正在运行的容器大量占用宿主机的系统资源(CPU、Memory、Network), 那么将由操作系统的 Cgroups 功能进行资源限制(防止独占)。
容器运行的基础是需要镜像,并且新容器的运行也是需要存储支持的。在 Docker 中使用 OverlayFS 解决这一问题。
1.4 Docker 优势与局限性
优势
1)Docker 让软件开发者与维护人员可以非常方便的启动应用程序以及将程序的依赖, 包到一个容器中,然后启动 Docker 应用到支持 Docker 的系统平台中,就可以实现应用 虚拟化。
2)Docker 镜像中包含了应用运行环境和配置文件,所以 Docker 可以简化部署多种应用 的工作。比如说 Web 应用、后台应用(Java/C++)、数据库应用、Hadoop 集群、消息 队列等等都可以打包成一个个独立的 Docker 应用镜像来部署。 3)提升宿主机(物理服务器/云虚拟机), 系统资源的利用率。
局限性
1) 基本的 Docker 网络管理模式比较简单,主要是基于系统使用 Namespace 隔离。
2) 与其他系统的网络连通性,使用自定义的地址网段,需要借助其他插件实现与其他网 段的互通, 提高了网络的整体复杂度。
3) 容器中应用程序日志不方便查看与收集。
4) 容器中无法运行 Windows
1.5 容器与虚拟机区别
比较 Docker 和传统虚拟化方式的不同之处,可见容器是在操作系统层面上实现虚拟化,直接复用宿主机的操作系统,而传统虚拟化(KVM/XEN/VMware)方式则是在硬件层面实现,并且完全虚拟一个操作系统,这是两者最大的不同之处。
1.5.1 详细对比说明
1) Docker 容器的启动可以在秒级实现,相比传统的虚拟机方式要快很多(分钟级)。 其次,容器对系统资源的利用率很高,一台主机上可以同时运行数百个 Docker 应用。
2) 容器基本不消耗额外的系统资源,使系统的开销尽量小。传统虚拟机方式运行应用与虚拟机的数量 1:1 (应用级别)
3) 虚拟机技术依赖物理 CPU 和内存,属于硬件级别的(特别是桌面虚拟化);而 Docker 构
建在操作系统上,利用操作系统的系统隔离技术运行,甚至Docker 可以在虚拟机中运行。
4)无需要硬件是否支持,在大多数主流的 Linux/Unix 与 Windows 系统上都支持。
1.6 Dokcer 架构与术语
1.6.1 Docker C/S 架构逻辑图
1.6.1 Docker C/S 架构逻辑图
1) Docker 分为客户端与服务端, 客户端可以管理本地的服务端(默认), 也可以管理远程 的服务端。
2) Docker 服务端在启动容器时需要从仓库获取启动镜像。
3)运行镜像分为两个部分:
a.默认的公共仓库。b.自建与第三方的私有仓库。 4)私有仓库有两种实现方式:
a. 使用 Docker Registry 部署。b. Vmware Harbor
1.6.2 Docker 基本术语
1.7 Docker 基本安装
1.7.1 操作系统版本要求
CentOS 7 要求系统为 64 位、系统内核版本为 3.10 以上。
CentOS-6.5 或更高的版本的 CentOS 上,要求系统为 64 位、系统内核版本为 2.6.32-431 或者更高版本。
1.7.2 查看系统内核版本
[root@docker ~]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core)
1.7.3 关闭系统防火墙与 Selinux
[root@docker ~]# service firewalld stop [root@docker ~]# service firewalld status [root@docker ~]# getenforce [root@docker ~]# setenforce 0 [root@docker ~]# reboot
1.7.3.1 安装 Docker 的准备
[root@docker ~]# yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
[root@docker ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
1.7.4 下载 Docker CE Yum 源 (社区版)
[root@docker ~]# yum-config-manager \ --add-repo https://download.docker.com/linux/centos/docker-ce.repo
1.7.5 安装开源版
[root@master ~]# yum install wget net-tools vim -y [root@docker ~]# yum search docker-ce #可省略 [root@docker ~]# yum install docker-ce-19.03.6 docker-ce-cli-19.03.6 containerd.io [root@docker ~]# servie docker start [root@docker ~]# chkconfig docker on #开机启动
1.7.6docker 信息查询
Docker 是传统的 CS 架构分为 Docker Client 和 Docker Server
[root@docker ~]# docker version Client: #客户端 Version: 18.09.0 API version: 1.39 Go version: go1.10.4 Git commit: 4d60db4 Built: Wed Nov 7 00:48:22 2018 OS/Arch: linux/amd64 Experimental: false Server: Docker Engine - Community #服务端 Engine: Version: 18.09.0 API version: 1.39 (minimum version 1.12) Go version: go1.10.4 Git commit: 4d60db4 Built: Wed Nov 7 00:19:08 2018 OS/Arch: linux/amd64 Experimental: false
1.7.7 docker 开机自启动
[root@docker ~]# systemctl enable docker
1.7.8 #查看 ip 地址
Docker 启动后,会自动创建一个 docker 0 的网桥
[root@docker ~]# ip a docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0 ether 02:42:e1:99:6c:ef txqueuelen 0 (Ethernet)
1.7.9.1 Docker 状态信息查看
[root@docker01 ~]# docker info Docker Root Dir: /var/lib/docker #容量 Labels: Experimental: false Insecure Registries: 127.0.0.0/8 Registry Mirrors: https://registry.docker-cn.com/ Live Restore Enabled: false Product License: Community Engine #社区版本
1.7.9.2 修改 Docker 存储数据存储目录
root@docker01 ~]# vi /usr/lib/systemd/system/docker.service [Service] ExecStart=/usr/bin/dockerd --graph=/data/docker -H fd:// --containerd=/run/containerd/containerd.sock [root@docker ~]# systemctl restart docker #重启服务 [root@docker ~]# docker info #查看是否修改成功
1.7.9.2.1 添加阿里云镜像加速器
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://plqjafsr.mirror.aliyuncs.com"] } EOF [root@master ~]# systemctl daemon-reload [root@master ~]# systemctl restart docker
1.7.9.3 运行第一个 Docker 应用
检验 Docker 是否可以正常运行
[root@docker ~]# docker run hello-world Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal.
1.8 Docker C/S 模式
Docker 客户端和服务端是使用 Socket 方式连接,主要有以下几种方式:
- 本地的 socket 文件 unix:///var/run/docker/sock (默认)
- tcp://host:prot (演示)
- fd://socketfd
1.8.1 Docker 默认连接方式
#未启动的状态, 说明 Docker 在默认情况下使用本地的 var/run/docker.sock 连接
[root@master ~]# service docker stop [root@ master ~]# docker info Client: Debug Mode: false Server: ERROR: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? errors pretty printing info
1.8.2 设置 Docker 远程使用 TCP 的连接方式
#打开 sock 与 tcp 连接方式
[root@ master ~]# vim /usr/lib/systemd/system/docker.service ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock #修改为: ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock -H fd:// --containerd=/run/containerd/containerd.sock
1.8.3 重启 Docker 服务
[root@master ~]# systemctl daemon-reload [root@master ~]# service docker restart
1.8.4 查看 Docker 运行状态
[root@master-1 ~]# service docker status Redirecting to /bin/systemctl status docker.service ● docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled) Main PID: 2218 (dockerd) Tasks: 12 Memory: 42.0M CGroup: /system.slice/docker.service └─2218 /usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock -H fd:// -- containerd=/run/containerd/containerd.sock
1.8.5 查看地址端口监听
[root@master ~]# netstat -nltup |grep 2375 tcp6 0 0 :::2375 :::* LISTEN 2218/dockerd
1.8.6 远程连接 Docker TCP 查看 Docker 信息
在另外一台安装 Docker 的宿主机连接(从 192.168.91.9 客户端远程到 192.168.91.8 服务端) 192.168.91.9 需要安装 Docker 客户端
[root@node-1 ~]# docker -H 192.168.91.8:2375 info Containers: 12 Running: 0 Paused: 0 Stopped: 12 Images: 1 Server Version: 19.03.4 Storage Driver: overlay2 Backing Filesystem: extfs Supports d_type: true Native Overlay Diff: true Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: bridge host ipvlan macvlan null overlay Swarm: inactive Kernel Version: 3.10.0-862.el7.x86_64 Operating System: CentOS Linux 7 (Core) OSType: linux Architecture: x86_64 Number of Docker Hooks: 3 CPUs: 1 Total Memory: 3.685 GiB Name: master-1 Docker Root Dir: /var/lib/docker Registry: https://index.docker.io/v1/
1.8.7 远程连接查看 Docker Images
[root@node-1 ~]# docker -H 192.168.91.8:2375 images REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest fce289e99eb9 14 months ago #远程启动容器 [root@node-1 ~]# docker -H 192.168.91.8:2375 ps --all [root@node-1 ~]# docker -H 192.168.91.8:2375 start 8a9ec62bea66
1.9 Docker 应用程序运行条件
姓名]
1) 计算机硬件: CPU、内存、磁盘、显卡、网卡(物理机/虚拟机)。2) 支持运行 Docker 的操作系统 (NS、Cgroups、OverlayFS)。3) 安装 Docker 服务,并且能够正常运行。4)需要可以运行在 Docker 里面的镜像, 镜像来自本地、docker hub、远程私有仓库。 5) 在镜像加载需要运行的程序(最终目的)。