zoukankan      html  css  js  c++  java
  • docker基础(原理)

    docker基础概念

    docker基础作用

    1.简化配置

    2.整合服务器

    3.代码流水线管理

    4.调试能力

    5.提高开发效率

    6.多租户

    7.隔离应用

    8.快速隔离

    docker对于虚拟化如kvm等不足

    Docker并不是全能的,设计之初也不是KVM之类虚拟化手段的替代品,简单总结几点:
    1. Docker是基于Linux 64bit的,无法在32bit的linux/Windows/unix环境下使用
    2. LXC是基于cgroup等linux kernel功能的,因此container的guest系统只能是linux base的
    3. 隔离性相比KVM之类的虚拟化方案还是有些欠缺,所有container公用一部分的运行库
    4. 网络管理相对简单,主要是基于namespace隔离
    5. cgroup的cpu和cpuset提供的cpu功能相比KVM的等虚拟化方案相比难以度量(所以dotcloud主要是按内存收费)
    6. Docker对disk的管理比较有限
    7. container随着用户进程的停止而销毁,container中的log等用户数据不便收集

     docker实现devops流程

     docker对比传统服务优势

    1.扩展性更好(应用扩展更轻量更快速)

    2.部署更加简洁,快速部署(部署方法简洁,能快速实现扩展应用)

    3.资源浪费(资源利用率太低,传统服务器资源保持在百分之75以下)

    4.成本高(需要先部署服务器)

    5.迁移难(服务器多,迁移复杂)

    docker实现原理

    Docker采用 C/S架构 Docker daemon 作为服务端接受来自客户的请求,并处理这些请求(创建、运行、分发容器)。 客户端和服务端既可以运行在一个机器上,也可通过 socket 或者RESTful API 来进行通信。
    Docker daemon 一般在宿主主机后台运行,等待接收来自客户端的消息。 Docker 客户端则为用户提供一系列可执行命令,用户用这些命令实现跟 Docker daemon 交互
    原理
    Docker核心解决的问题是利用LXC来实现类似VM的功能,从而利用更加节省的硬件资源提供给用户更多的计算资源。同VM的方式不同, LXC 其并不是一套硬件虚拟化方法 - 无法归属到全虚拟化、部分虚拟化和半虚拟化中的任意一个,而是一个操作系统级虚拟化方法, 理解起来可能并不像VM那样直观。所以我们从虚拟化到docker要解决的问题出发,看看他是怎么满足用户虚拟化需求的。
    用户需要考虑虚拟化方法,尤其是硬件虚拟化方法,需要借助其解决的主要是以下4个问题:
    • 隔离性 - 每个用户实例之间相互隔离, 互不影响。 硬件虚拟化方法给出的方法是VM, LXC给出的方法是container,更细一点是kernel namespace
    • 可配额/可度量 - 每个用户实例可以按需提供其计算资源,所使用的资源可以被计量。硬件虚拟化方法因为虚拟了CPU, memory可以方便实现, LXC则主要是利用cgroups来控制资源
    • 移动性 - 用户的实例可以很方便地复制、移动和重建。硬件虚拟化方法提供snapshot和image来实现,docker(主要)利用AUFS实现
    • 安全性 - 这个话题比较大,这里强调是host主机的角度尽量保护container。硬件虚拟化的方法因为虚拟化的水平比较高,用户进程都是在KVM等虚拟机容器中翻译运行的, 然而对于LXC, 用户的进程是lxc-start进程的子进程, 只是在Kernel的namespace中隔离的, 因此需要一些kernel的patch来保证用户的运行环境不会受到来自host主机的恶意入侵, dotcloud(主要是)利用kernel grsec patch解决的.
    Linux Namespace
    LXC所实现的隔离性主要是来自kernel的namespace, 其中pid, net, ipc, mnt, uts 等namespace将container的进程, 网络, 消息, 文件系统和hostname 隔离开。
    pid namespace
    之前提到用户的进程是lxc-start进程的子进程, 不同用户的进程就是通过pidnamespace隔离开的,且不同 namespace 中可以有相同PID。具有以下特征:
    1. 每个namespace中的pid是有自己的pid=1的进程(类似/sbin/init进程)
    2. 每个namespace中的进程只能影响自己的同一个namespace或子namespace中的进程
    3. 因为/proc包含正在运行的进程,因此在container中的pseudo-filesystem的/proc目录只能看到自己namespace中的进程
    4. 因为namespace允许嵌套,父namespace可以影响子namespace的进程,所以子namespace的进程可以在父namespace中看到,但是具有不同的pid
    正是因为以上的特征,所有的LXC进程在docker中的父进程为docker进程,每个lxc进程具有不同的namespace。同时由于允许嵌套,因此可以很方便的实现 LXC in LXC
    net namespace
    有了 pid namespace, 每个namespace中的pid能够相互隔离,但是网络端口还是共享host的端口。网络隔离是通过netnamespace实现的,
    每个net namespace有独立的 network devices, IP addresses, IP routing tables, /proc/net 目录。这样每个container的网络就能隔离开来。
    LXC在此基础上有5种网络类型,docker默认采用veth的方式将container中的虚拟网卡同host上的一个docker bridge连接在一起。
    ipc namespace
    container中进程交互还是采用linux常见的进程间交互方法(interprocess communication - IPC), 包括常见的信号量、消息队列和共享内存。然而同VM不同,container 的进程间交互实际上还是host上具有相同pid namespace中的进程间交互,因此需要在IPC资源申请时加入namespace信息 - 每个IPC资源有一个的 32bit ID。
    mnt namespace
    类似chroot,将一个进程放到一个特定的目录执行。mnt namespace允许不同namespace的进程看到的文件结构不同,这样每个 namespace 中的进程所看到的文件目录就被隔离开了。同chroot不同,每个namespace中的container在/proc/mounts的信息只包含所在namespace的mount point。
    uts namespace
    UTS(“UNIX Time-sharing System”) namespace允许每个container拥有独立的hostname和domain name,
    使其在网络上可以被视作一个独立的节点而非Host上的一个进程。
    user namespace
    每个container可以有不同的 user 和 group id, 也就是说可以以container内部的用户在container内部执行程序而非Host上的用户。
    有了以上6种namespace从进程、网络、IPC、文件系统、UTS和用户角度的隔离,一个container就可以对外展现出一个独立计算机的能力,并且不同container从OS层面实现了隔离。
    然而不同namespace之间资源还是相互竞争的,仍然需要类似ulimit来管理每个container所能使用的资源 - LXC 采用的是cgroup。 [6] 
    Control Groups
    cgroups 实现了对资源的配额和度量。 cgroups 的使用非常简单,提供类似文件的接口,在 /cgroup目录下新建一个文件夹即可新建一个group,在此文件夹中新建task文件,并将pid写入该文件,即可实现对该进程的资源控制。具体的资源配置选项可以在该文件夹中新建子 subsystem ,{子系统前缀}.{资源项} 是典型的配置方法,
    如memory.usage_in_bytes 就定义了该group 在subsystem memory中的一个内存限制选项。
    另外,cgroups中的 subsystem可以随意组合,一个subsystem可以在不同的group中,也可以一个group包含多个subsystem - 也就是说一个 subsystem。
    关于术语定义
    A *cgroup* associates a set of tasks with a set of parameters for one
    or more subsystems.
    A *subsystem* is a module that makes use of the task grouping
    facilities provided by cgroups to treat groups of tasks in
    particular ways. A subsystem is typically a "resource controller" that
    schedules a resource or applies per-cgroup limits, but it may be
    anything that wants to act on a group of processes, e.g. a
    virtualization subsystem.
    我们主要关心cgroups可以限制哪些资源,即有哪些subsystem是我们关心。
    cpu : 在cgroup中,并不能像硬件虚拟化方案一样能够定义CPU能力,但是能够定义CPU轮转的优先级,因此具有较高CPU优先级的进程会更可能得到CPU运算。
    通过将参数写入cpu.shares,即可定义改cgroup的CPU优先级 - 这里是一个相对权重,而非绝对值。当然在cpu这个subsystem中还有其他可配置项,手册中有详细说明。
    cpusets : cpusets 定义了有几个CPU可以被这个group使用,或者哪几个CPU可以供这个group使用。在某些场景下,单CPU绑定可以防止多核间缓存切换,从而提高效率
    memory : 内存相关的限制
    blkio : block IO相关的统计和限制,byte/operation统计和限制(IOPS等),读写速度限制等,但是这里主要统计的都是同步IO
    net_cls, cpuacct , devices , freezer 等其他可管理项

     

    虚拟化原理及优点:

     物理资源充足可以使用虚拟机进行资源分配,实现资源充足利用,避免浪费。

    虚拟化优点:

    1.资源池——一个物理资源分配到不同的虚拟机中。

    2.很容易扩展——可以将更多的物理机or虚拟机加入资源池中。

    3.很容易云化——很容易将虚拟机进行云化如阿里云 AWS 等

    虚拟机局限性:

    1.每一个虚拟机都是一个完整的操作系统,要给其分配资源,当虚拟机增多时,操作系统本身消耗的资源也大。

    容器解决问题:

    1.解决开发和运维之间矛盾

    2.在开发和运维之间搭建桥梁,是实现devops最佳解决方案。

     
     
  • 相关阅读:
    说下vue工程中代理配置proxy
    说一下登陆页面的实现逻辑
    $router和router区别
    iframe中涉及父子页面跨域问题
    浅析闭包
    用户注册之短信验证
    vue.js(三)
    vue.js(二)
    vue.js(一)
    批量更改会员权限
  • 原文地址:https://www.cnblogs.com/dahuige/p/14700202.html
Copyright © 2011-2022 走看看