Docker 概念、原理、安装部署

Docker 概念、原理、安装部署

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口

docker是一种技术,能使得应用在任何环境都能用的打包技术。打包出的东西叫镜像。镜像运行时(有对外提供服务能力)叫容器
在这里插入图片描述

DevOps(开发即运维)

应用更快速的交付和部署

更便捷的升级和扩容

更简单的系统运维

更高效的计算资源利用

镜像(image)

容器(container)

仓库(repository)

一. 安装docker:

环境查看:

[hadoop@centos101 ~]$ cat /etc/os-release 
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

卸载旧版本

sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

下载依赖包

sudo yum install -y yum-utils

设置仓库(设置)

# 默认
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 阿里云镜像
sudo yum-config-manager --add-repo  http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

更新yum软件包索引

yum makecache fast

安装Docker引擎 ce:社区办 ee:企业版

 sudo yum install docker-ce docker-ce-cli containerd.io

启动docker

sudo systemctl start docker

docker version 查看安装是否成功

通过运行hello-world 映像来验证是否正确安装了Docker Engine 。

sudo docker run hello-world

查看docker镜像

[hadoop@centos101 ~]$ sudo docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    d1165f221234   2 months ago   13.3kB

卸载docker

 sudo yum remove docker-ce docker-ce-cli containerd.io
 sudo rm -rf /var/lib/docker
 sudo rm -rf /var/lib/containerd

阿里云镜像加速

  1. 登录阿里云
  2. 找到镜像加速器
  3. 配置镜像加速

二. Docker底层原理

Docker是一个Client-Server结构的系统,Docker守护进程(Docker daemon)运行在主机上, 然后通过Socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。
在这里插入图片描述

1. Linux的namespace和cgroup
1.1 namespace

Namespace是对全局系统资源的一种封装隔离,使得处于不同namespace的进程拥有独立的全局系统资源,改变一个namespace中的系统资源只会影响当前namespace里的进程,对其他namespace中的进程没有影响。有6个namespace(ipc、mount、net、pid、user、uts)。查看进程所属的namespaces

[hadoop@centos101 ~]$ ls -l /proc/$$/ns 
total 0
lrwxrwxrwx. 1 hadoop hadoop 0 May 25 14:12 ipc -> ipc:[4026531839]
lrwxrwxrwx. 1 hadoop hadoop 0 May 25 14:12 mnt -> mnt:[4026531840]
lrwxrwxrwx. 1 hadoop hadoop 0 May 25 14:12 net -> net:[4026531956]
lrwxrwxrwx. 1 hadoop hadoop 0 May 25 14:12 pid -> pid:[4026531836]
lrwxrwxrwx. 1 hadoop hadoop 0 May 25 14:12 user -> user:[4026531837]
lrwxrwxrwx. 1 hadoop hadoop 0 May 25 14:12 uts -> uts:[4026531838]
  1. IPC namespace

    IPC namespace用来隔离System V IPC objects和POSIX message queues。其中System V IPC objects包含Message queues、Semaphore sets和Shared memory segments.

  2. mount namespace

    Mount namespace用来隔离文件系统的挂载点, 使得不同的mount namespace拥有自己独立的挂载点信息,不同的namespace之间不会相互影响,这对于构建用户或者容器自己的文件系统目录非常有用。

    当前进程所在mount namespace里的所有挂载信息可以在/proc/[pid]/mounts、/proc/[pid]/mountinfo和/proc/[pid]/mountstats里面找到。

    Mount namespaces是第一个被加入Linux的namespace,由于当时没想到还会引入其它的namespace,所以取名为CLONE_NEWNS,而没有叫CLONE_NEWMOUNT。

    每个mount namespace都拥有一份自己的挂载点列表,当用clone或者unshare函数创建新的mount namespace时,新创建的namespace将拷贝一份老namespace里的挂载点列表,但从这之后,他们就没有关系了,通过mount和umount增加和删除各自namespace里面的挂载点都不会相互影响

  3. network namespace

    network namespace用来隔离网络设备, IP地址, 端口等. 每个namespace将会有自己独立的网络栈,路由表,防火墙规则,socket等

  4. PID namespace

    PID namespaces用来隔离进程的ID空间,使得不同pid namespace里的进程ID可以重复且相互之间不影响。

    PID namespace可以嵌套,也就是说有父子关系,在当前namespace里面创建的所有新的namespace都是当前namespace的子namespace。父namespace里面可以看到所有子孙后代namespace里的进程信息,而子namespace里看不到祖先或者兄弟namespace里的进程信息。

    目前PID namespace最多可以嵌套32层,由内核中的宏MAX_PID_NS_LEVEL来定义

    Linux下的每个进程都有一个对应的/proc/PID目录,该目录包含了大量的有关当前进程的信息。 对一个PID namespace而言,/proc目录只包含当前namespace和它所有子孙后代namespace里的进程的信息。

    在Linux系统中,进程ID从1开始往后不断增加,并且不能重复(当然进程退出后,ID会被回收再利用),进程ID为1的进程是内核启动的第一个应用层进程,一般是init进程(现在采用systemd的系统第一个进程是systemd),具有特殊意义,当系统中一个进程的父进程退出时,内核会指定init进程成为这个进程的新父进程,而当init进程退出时,系统也将退出。

    除了在init进程里指定了handler的信号外,内核会帮init进程屏蔽掉其他任何信号,这样可以防止其他进程不小心kill掉init进程导致系统挂掉。不过有了PID namespace后,可以通过在父namespace中发送SIGKILL或者SIGSTOP信号来终止子namespace中的ID为1的进程。

    由于ID为1的进程的特殊性,所以每个PID namespace的第一个进程的ID都是1。当这个进程运行停止后,内核将会给这个namespace里的所有其他进程发送SIGKILL信号,致使其他所有进程都停止,于是namespace被销毁掉

  5. user namespace

    User namespace用来隔离user权限相关的Linux资源,包括user IDs and group IDs,keys , 和capabilities

  6. UTS namespace

    UTS namespace用来隔离系统的hostname以及NIS domain name

2.cgroup

Docker 容器使用 linux namespace 来隔离其运行环境,使得容器中的进程看起来就像一个独立环境中运行一样。但是,光有运行环境隔离还不够,因为这些进程还是可以不受限制地使用系统资源,比如网络、磁盘、CPU以及内存 等。关于其目的,一方面,是为了防止它占用了太多的资源而影响到其它进程;另一方面,在系统资源耗尽的时候,linux 内核会触发 OOM,这会让一些被杀掉的进程成了无辜的替死鬼。因此,为了让容器中的进程更加可控,Docker 使用 Linux cgroups 来限制容器中的进程允许使用的系统资源。cgroup提供以下功能:

Resource limitation: 限制资源使用,比如内存使用上限以及文件系统的缓存限制。

Prioritization: 优先级控制,比如:CPU利用和磁盘IO吞吐。

Accounting: 一些审计或一些统计,主要目的是为了计费。

Controll: 挂起进程,恢复执行进程。

从实现角度来看,cgroups实现了一个通用的进程分组框架,不同资源的具体管理工作由各cgroup子系统来实现,当需要多个限制策略比如同时针对cpu和内存进行限制,则同时关联多个cgroup子系统即可。

cgroups子系统

cgroups为每种资源定义了一个子系统,典型的子系统如下:

  • cpu 子系统,主要限制进程的 cpu 使用率。
  • cpuacct 子系统,可以统计 cgroups 中的进程的 cpu 使用报告。
  • cpuset 子系统,可以为 cgroups 中的进程分配单独的 cpu 节点或者内存节点。
  • memory 子系统,可以限制进程的 memory 使用量。
  • blkio 子系统,可以限制进程的块设备 io。
  • devices 子系统,可以控制进程能够访问某些设备。
  • net_cls 子系统,可以标记 cgroups 中进程的网络数据包,然后可以使用 tc 模块(traffic control)对数据包进行控制。
  • freezer 子系统,可以挂起或者恢复 cgroups 中的进程。
  • ns 子系统,可以使不同 cgroups 下面的进程使用不同的 namespace。

每个子系统都是定义了一套限制策略,它们需要与内核的其他模块配合来完成资源限制功能,比如对 cpu 资源的限制是通过进程调度模块根据 cpu 子系统的配置来完成的;对内存资源的限制则是内存模块根据 memory 子系统的配置来完成的,而对网络数据包的控制则需要 Traffic Control 子系统来配合完成。

2.docker与虚拟机的区别
2.1 虚拟机结构介绍

在这里插入图片描述

  • 基础设施(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,都会需要安装对应的依赖库。
  • 应用。安装依赖之后,就可以在各个从操作系统分别运行应用了,这样各个应用就是相互隔离的。
2.2 Docker结构介绍

在这里插入图片描述

基础设施(Infrastructure)。

主操作系统(Host Operating System)。所有主流的Linux发行版都可以运行Docker。对于MacOS和Windows,也有一些办法”运行”Docker。

Docker守护进程(Docker Daemon)。Docker守护进程取代了Hypervisor,它是运行在操作系统之上的后台进程,负责管理Docker容器。

各种依赖。对于Docker,应用的所有依赖都打包在Docker镜像中,Docker容器是基于Docker镜像创建的。

应用。应用的源代码与它的依赖都打包在Docker镜像中,不同的应用需要不同的Docker镜像。不同的应用运行在不同的Docker容器中,它们是相互隔离的。

3.为什么Docker比较比VM快?
  1. docker有着比虚拟机更少的抽象层。docker不需要Hypervisor实现硬件资源虚拟化,Docker守护进程取代了Hypervisor,它是运行在操作系统之上的后台进程,运行在docker上的程序直接使用的就是实际物理机的资源。
  2. docker利用的是宿主机的内核,而不需要Guest OS。因此,当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。仍而避免引寻、加载操作系统内核返个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了返个过程,因此新建一个docker容器只需要几秒钟
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值