精华内容
下载资源
问答
  • linux云计算虚拟化-搭建 Kubernetes 容器集群管理系统 1. kubernetes简介 Kubernetes 是Google开源的容器集群管理系统,基于 Docker 构建一个容器的调度服务,提供资源调度、均衡容灾、服务注册、动态扩缩容等功能...

    Linux云计算虚拟化-Kubernetes 容器集群管理系统基础概念讲述

    1. kubernetes简介

    Kubernetes 是Google开源的容器集群管理系统,基于 Docker 构建一个容器的调度服务,提供资源调度、均衡容灾、服务注册、动态扩缩容等功能套件。

    Kubernetes 是基于docker容器的云平台,简写为:k8s
    OpenStack 是基于kvm虚拟机云平台。

    k8s官网https://kubernetes.io/

    在这里插入图片描述

    2. k8s常见组件介绍

    ①Master:提供k8s集群的管理控制中心,可以在集群中任何节点上运行。通常在一台VM/机器上启动所有Master组件,并且不会在此VM/机器上运行用户容器。

    ②Api Server:提供接口服务,用户通过apiserver来管理整个容器集群平台。API Server负责和etcd交互(其他组件不会直接操作etcd,只有API Server这么做),整个kubernetes 集群的所有的交互都是以API Server为核心的。

    • 任何的资源请求/调用操作都是通过apiserver提供的接口进行。
    • 所有模块之间并不会互相调用,而是通过和API Server交互完成自己的那部分工作。
    • API Server 提供的验证和授权保证了整个集群的安全。

    ③Scheduler:k8s的调度服务,监视新创建没有分配到Node的Pod,为Pod选择一个Node。

    ④Replication Controllers:Kubernetes 系统中最有用的功能,实现复制多个 Pod 副本,往往一个应用需要多个 Pod 来支撑,并且可以保证其复制的副本数,即使副本所调度分配的宿主机出现异常,通过 Replication Controller 可以保证在其它宿主机启用同等数量的 Pod。Replication Controller 可以通过 repcon 模板来创建多个 Pod 副本,同样也可以直接复制已存在 Pod,需要通过 Label selector 来关联。

    ⑤minion:真正用来运行容器container的物理机,在k8s中需要多个minion机器来提供运算。

    ⑥container:容器,用来运行服务和程序。【豌豆】

    ⑦pod:在k8s系统中,调度的最小颗粒不是容器,而是一个pod,pod是一个可以被创建、销毁、调度、管理的最小的部署单元,pod可以包括一个或一组容器。【一群鲸鱼(docker容器)或豌豆荚】

    ⑧kube_proxy:端口转发,相当于lvs-nat模式中的负载调度器。proxy解决了同一宿主机,相同服务端口冲突的问题,提供了对外服务的能力,proxy的后端使用了随机、轮询负载均衡算法。实现 Kubernetes 网络相关内容。

    ⑨etcd:是kubernetes提供的默认存储系统。存储 kubernetes 集群的所有数据, 可以理解为是 k8s 的数据库,存储着 k8s 容器云平台中所有节点、pods、网络等信息。使用时需要为etcd数据提供备份计划。

    ⑩controller manager:控制器管理器,是集群中处理常规任务的后台线程。逻辑上,每个控制器是一个单独的进程,但为了降低复杂性,它们都被编译成单个二进制文件,并在单个进程中运行。

    • 节点(Node)控制器
    • 副本(Replication)控制器:负责维护系统中每个副本中的pod。
    • 端点(Endpoints)控制器:填充Endpoints对象(即连接Services和Pods)。
    • Service Account和Token控制器:为新的Namespace创建默认账户访问API Token

    其他概念:
    ①service:Services 是 Kubernetes 最外围的单元,通过虚拟一个访问 IP 及服务端口,可以访问我们定义好的 Pod 资源,目前的版本是通过 iptables 的 nat 转发来实现,转发的目标端口为Kube_proxy 生成的随机端口。

    ②lables:用于区分 Pod、Service、Replication Controller 的 key/value 键值对,仅使用在Pod、Service、 Replication Controller 之间的关系识别,但对这些单元本身进行操作时得使用 name标签。

    ③deployment:用于更新 Pod 和 Replica Set(下一代的 Replication Controller)。可以在 Deployment 对象中只描述你所期望的理想状态(预期的运行状态),Deployment 控
    制器会将现在的实际状态转换成期望的状态。

    ④kubelet命令:管理 Pod、Pod 中容器及容器的镜像和卷等信息。
    Kubelet 和 Kube-proxy 都运行在 minion 节点上。

    ⑤cloud-controller-manager:云控制器管理器,负责与底层云提供商的平台交互。在1.6版本引入。

    各组件的关系:

    Kubernetes 的架构由一个master和多个minion组成,master通过 api提供服务,接受kubectl的请求来调度管理整个集群。

    Replication controller定义了需要运行的多个pod 或者容器,如果当前集群中运行的 pod或容器达不到配置的数量,replication controller 会调度容器在多个 minion 上运行,保证集群中的pod数量。

    service 则定义真实对外提供的服务,一个 service 会对应后端运行的多个 container

    Kubernetes 是个管理平台,minion上的kube-proxy拥有提供真实服务公网 IP。客户端访问kubernetes中提供的服务,是直接访问到kube-proxy上的。

    ⑤在 Kubernetespod是一个基本单元,一个pod 可以是提供相同功能的多个 container,这些容器会被部署在同一个 minion上。minion是运行Kubelet中容器的物理机。minion接受master的指令创建pod 或者容器。

    3. k8s原理持续更新…

    展开全文
  • 各个服务组件中的各个模块则采用虚拟化容器Docker进行资源隔离,提高了资源利用率,同时也保证了安全性。在基于容器的分布式资源管理平台之上,可以构建类似于视频流服务、深度学习计算框架等服务,形成媒体智能处理...

    前言

     大多数底层平台必须支撑上层的多种服务,如媒体流服务、深度学习计算框架等,如果采用传统的基于MapReduce分布式计算框架必将带来扩展性差、资源利用率低、无法支持多种框架的问题。上层的每个服务组件的实现均是一个分布式子系统,如果单独实现,必然造成各组件之间完全孤立维护与管理。

    设计思路

     为了解决这个问题,解决方案则是考虑将各个服务组件的资源管理与作业控制进行分离,并且加入基于Docker容器的资源管理方案。
     将资源管理整合成一个资源管理与调度平台,而作业控制则放到应用程序框架中从而解决扩展性差的问题。各个服务组件中的各个模块则采用虚拟化容器Docker进行资源隔离,提高了资源利用率,同时也保证了安全性。在基于容器的分布式资源管理平台之上,可以构建类似于视频流服务、深度学习计算框架等服务,形成媒体智能处理层。
     基于多种面向有向无环图(DAG)任务的调度方式,将业务平台与资源管理平台进行解耦,达到资源的高效利用。

    架构设计方案

     采用Master/Slave架构,分别对应RC(Resource Control)、NC(Node Control)和SAS。RC负责整个集群的资源管理和调度,NC负责单个节点的资源管理,SAS负责保存框架实例的服务访问入口

    具体架构示意图如下:
    在这里插入图片描述
    各个功能模块如下:

    • Framework(FW):应用程序框架,包含该应用程序的所有模块,如应用程序框架内的master、slave等。
    • RC:资源控制节点,是一个全局的资源管理器,负责整个系统的资源管理与分配。
    • NC:节点控制,NC是每个节点上的资源和作业管理器。
    • Docker Container:虚拟化的应用容器,用于资源隔离。在每台机器上,一个Docker Container对应一个Framework实例,因此Framework实例内部的资源可以共享,Framework实例间的资源不能共享。
    • FW Master:框架实例内部的Master模块。
    • FW Slave:框架实例内部的Slave模块。
      注:FW Master和FW Slave这里是相对的,如A启动B,B启动C。对于A来说,B是FW Slave,但对于C来说,B是FW Master。
    • Portal/Client:Portal和Client提供给用户不同的操作接口,拥有相同的协议。用户可以提交制作好的框架的Image(镜像),启动关闭框架,以及查询平台的资源情况和框架的资源使用情况,同时提供框架业务数据查询的重定向功能。
    • Docker仓库:存放所有Framework Image的仓库。
    • LS:日志服务器,负责记录操作日志等。
    • SAS:保存框架实例的服务访问入口。
    展开全文
  • 搭建Jmeter容器集群平台

    万次阅读 热门讨论 2018-05-03 11:11:49
    基于大量虚拟机的Jmeter集群有个缺点,就是不方便管理,比如需要重启Jmeter服务,还需要一个个的连接到虚拟机上进行操作,而且安装部署不方便(无法一键部署),也不方便将集群封装成整体应用对外提供服务。...

    基于大量虚拟机的Jmeter集群有个缺点,就是不方便管理,比如需要重启Jmeter服务,还需要一个个的连接到虚拟机上进行操作,而且安装部署不方便(无法一键部署),也不方便将集群封装成整体应用对外提供服务。这些缺点通过Rancher部署的容器云平台就能够解决。

    一、给各个节点的虚拟机安装Docker

    可以让创建虚拟机时就自动带上统一版本的Docker,就可以省掉这一步操作,网上还推荐使用DaoCloud进行Docker安装和镜像加速,我们是为了做实现,就原始的方式安装吧:

    1、对于CantOS安装Docker最好是CentOS7,这样可以保证内核至少是3.10(通过uname -r 命令查看),低于这个版本的内核无法安装Docker。

    2、使用 root 权限登录 Centos。确保 yum 包更新到最新(sudo yum update),我是没有更新。

    3、卸载旧版本(如果安装过旧版本的话)

    sudo yum remove docker  docker-common docker-selinux docker-engine

    4、安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的

    sudo yum install -y yum-utils device-mapper-persistent-data lvm2

    5、设置yum源

    sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

    6、直接安装最新版的docker(记住版本宁可最新,也不要低于Rancher所要求的版本)

    sudo yum install docker-ce

    7、启动并加入开机启动

    $ sudo systemctl start docker
    $ sudo systemctl enable docker

    二、Rancher安装和配置

    可以选择一台机独立安装,也可以和Jmeter的Master节点部署在一台机上。Rancher是一个开源的容器管理平台(支持华人的产品),帮助构建企业私有容器服务,相当于KVM里的Openstack。

    1、直接调用Docker安装

    sudo docker run -d --restart=unless-stopped -p 8080:8080 rancher/server

    2、登录Rancher

    装完后,(等启动完后)通过http://IP:8080登录,可以选择语言为中文版显示,进行Rancher认证配置(我也不配了,直接忽略)

    3、Rancher主机添加

    Rancher提供了很多machine drivers批量添加主机,我们也简单一点,直接选择Custom手动添加吧

    以上的两标签可先不加,留后面再加也行,主要是为了标识这是主节点,host.ip为指定IP(对于Slave节点不需要加标签io.rancher.host.name=master),第4步的IP也可以不用配置,除非是某个节点主机与Rancher部署在一台机器上(我就是)。最后奔向第5步,复制那一串代码,到需要添加的主机上运行就可以(前提也是主机装好了Docker,并且可以访问Rancher,避免访问失败连防火墙也可以先关了)。

    添加完一个主机后,继续添加其他Slave节点的主机,我是添加了一台master(与Rancher共用)、两台slave(这三台机的IP最好都是同网段的,不要用相邻网段的,比如网段为172.16的虚拟机创建Docker后,其网桥的默认网段就变成172.17,这就导致和172.17网段的虚拟机会网络冲突,碰到冲突临时的解决方式就是手动修改网桥docker0的网段并重启机器

    逐台主机登录输入命令添加Custom也挺头疼,可以使用expect编写一个脚本来减轻部分工作量(我就添加三台,用不上):

    #!/usr/bin/expect
    set timeout -1
    set ip [lindex $argv 0]
    spawn ssh root@$ip
    expect {
        "*Are you sure you want to continue connecting (yes/no)?*" { send "yes\r" }
        "*password*" { send "123456\r" }
    }
    expect {
        "*password*" { send "123456\r" }
    }
    expect {
        "]# " { send "sudo docker run --rm --privileged -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/rancher:/var/lib/rancher rancher/agent:v1.2.2 http://172.16.1.37:8080/v1/scripts/EE431DCFC650693D335A:1483142400000:3FSEGIHT9rsY68RViGJGV8sBiBk\r" }
    }
    send "exit\r"
    expect eof
    exit

    添加完三台主机后的效果:

    4、添加Jmeter应用

    添加应用(Add Stack)就是填写docker-compose.yml和rancher-compose.yml。由于slave集群在压测过程中往往由于压力过大出现各种rmi异常导致崩溃,我们把主从分别建两个应用(Stack)。

    jmeter-master的docker-compose.yml配置如下(调用的是Docker Hub镜像库里的镜像):

    version: '2'
    services:
      master:
        image: malfurionpd/jmeter-master
        stdin_open: true
        network_mode: host
        tty: true
        ports:
        - 60000:60000/tcp
        labels:
          io.rancher.scheduler.affinity:host_label: io.rancher.host.name=master
          io.rancher.container.pull_image: always

    jmeter-master的rancher-compose.yml配置如下:

    version: '2'
    services:
      master:
        scale: 1
        start_on_create: true

    jmeter-slaves的docker-compose.yml配置如下(包含多节点):

    version: '2'
    services:
      slave01:
        image: malfurionpd/jmeter-slave-ip
        environment:
          HOST_IP: 172.16.1.37
        stdin_open: true
        tty: true
        ports:
        - 1099:1099/tcp
        - 50000:50000/tcp
        labels:
          io.rancher.container.pull_image: always
          io.rancher.scheduler.affinity:host_label: host.ip=172.16.1.37
      slave02:
        image: malfurionpd/jmeter-slave-ip
        environment:
          HOST_IP: 172.16.1.140
        stdin_open: true
        tty: true
        ports:
        - 1099:1099/tcp
        - 50000:50000/tcp
        labels:
          io.rancher.container.pull_image: always
          io.rancher.scheduler.affinity:host_label: host.ip=172.16.1.140

    jmeter-slaves的rancher-compose.yml配置如下:

    version: '2'
    services:
      slave01:
        scale: 1
        start_on_create: true
      slave02:
        scale: 1
        start_on_create: true

    添加应用时导入以上配置文件,点击创建,顺间就能创建jmeter集群(几秒钟的事情)。

    创建好的集群各个节点,就可以方便的进行管理(升级、重启、停止服务、查看日志、执行命令行等操作),无需连接Linux,就可直接进行各节点的命令操作:

    通过以上ps查看,就能发现jmeter的从节点自动启动了jmeter-server,无需人为操作jmeter-server的启动。

    登录到master主机,也能看到jmeter-master容器和rancher服务

    说明:以上的镜像是用jmeter 3.2构建的,如果觉得版本不满足要求,可以自己构建镜像:参考构建代码:

    https://github.com/malfurionpd/docker-files

    三、Jmeter集群应用

    到这一步就可以验证上面的成果了,直接到一个脚本newTest.jmx进行测试:

    jmeter -n -t /jmeter/apache-jmeter-3.2/bin/newTest.jmx -Djava.rmi.server.hostname=172.16.1.30 -Dclient.rmi.localport=60000 -R 172.16.1.140,172.16.1.37 -l /jmeter/apache-jmeter-3.2/DashReport/log-222.csv -e -o /jmeter/apache-jmeter-3.2/DashReport/htmlReport-222

    将输出的报告从容器中拷出用html查看,一切OK

    四、扩展应用

    以上已经实现了一套Jmeter的容器云平台,但是为了让脚本和报告集中管理,我们需要构建一个文件服务器,通过nginx或是SVN都行。在文件目录下建立jmx,jtl,report三个子目录。

    将本机编辑和测试通过的脚本,直接上传到文件服务器上(需要配置SSH免密登录

    scp newTest.jmx root@x.x.x.x:/data/jmetertest/jmx/

    通master节点的jmeter可以直接连接文件服务器调用脚本,并将生成的报告保存到文件服务器上。以下是jmeter的示例脚本:

    #!/bin/bash
    
    if [ ! -n "$1" ] ;then
            echo 'give me a parameter, ok?'
    else
            now=`date --date='0 days ago' "+%Y%m%d%H%M%S"`
            echo "=====Start JMeter Test $1 on $now"
            echo "=====Step1 wget"
            cmd1="wget -P /jmeter/apache-jmeter-3.2/bin/ https://xxx.xxx.xxx/jmetertest/jmx/$1"
            eval ${cmd1}
    
            echo "=====Step2 makedir in local"
            #jmeter-jtl
            if [ ! -d "/jmeter-jtl" ]; then
                    mkdir /jmeter-jtl
            fi
            #jmeter-jtl/xxx.jmx
            if [ ! -d "/jmeter-jtl/$1" ]; then
                    mkdir "/jmeter-jtl/$1"
            fi
            #jmeter-report
            if [ ! -d "/jmeter-report" ]; then
                    mkdir /jmeter-report
            fi
            #jmeter-report/xxx.jmx
            if [ ! -d "/jmeter-report/$1" ]; then
                    mkdir "/jmeter-report/$1"
            fi
    
            echo "=====Step3 jmeter"
            cmd2="/jmeter/apache-jmeter-3.2/bin/jmeter -n -t /jmeter/apache-jmeter-3.2/bin/$1 -l /jmeter-jtl/$1/$now.jtl -e -o /jmeter-report/$1/$now -Djava.rmi.server.hostname=172.16.1.30 -Dclient.rmi.localport=60000 -R 172.16.1.37,172.16.1.140"
            eval ${cmd2}
    
            tip="10.135.147.74"
            echo "=====Step4 scp"
    
            #scp jtl
            tjtl="/data/jmetertest/jmetertest/jtl"
            cmd3="ssh root@${tip} \"[ -d ${tjtl}/$1 ] && echo ok || mkdir -p ${tjtl}/$1\""
            eval ${cmd3}
    
            cmd4="scp /jmeter-jtl/$1/$now.jtl root@${tip}:${tjtl}/$1/"
            eval ${cmd4}
    
            #scp report
            treport="/data/jmetertest/report"
            cmd5="ssh root@${tip} \"[ -d ${treport}/$1 ] && echo ok || mkdir -p ${treport}/$1\""
            eval ${cmd5}
            cmd6="ssh root@${tip} \"[ -d ${treport}/$1/$now ] && echo ok || mkdir -p ${treport}/$1/$now\""
            eval ${cmd6}
    
            cmd7="scp -r /jmeter-report/$1/$now root@${tip}:${treport}/$1/"
            eval ${cmd7}
    
            echo "=====End JMeter Test $1 on $now"
    fi

    备注说明:上面所用到的jmeter镜像都是从DockerHub调用的,为了方便镜像的分布式下发和运行,调用DockerHub的镜像是个简便的方式,我们也可以自己生成jmeter镜像,申请个Docker Hub账号后上传到镜像库里。

    由于以上的jmeter镜像太老,jmeter 3.2,我们可以自己定义Dockerfile,以构建新的镜像(如 jmeter 5.1.1):

    Jmeter-master Dockerfile:

    # Use JDK-8 on alpine.
    From openjdk:8-alpine
    MAINTAINER smooth00 <smooth.blog.csdn.net>
    
    ENV JMETER_VERSION 5.1.1
    
    # Install Pre-requisite Packages like wget
    RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
        apk update && apk add wget unzip vim
    
    # Installing jmeter
    RUN mkdir /jmeter \
            && cd /jmeter/ \
            && wget https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-$JMETER_VERSION.tgz \
            && tar -xzf apache-jmeter-$JMETER_VERSION.tgz \ 
    	&& rm apache-jmeter-$JMETER_VERSION.tgz \
    	&& wget -P /jmeter/apache-jmeter-$JMETER_VERSION/lib/ext https://repo.maven.apache.org/maven2/kg/apc/jmeter-plugins-extras-libs/1.4.0/jmeter-plugins-extras-libs-1.4.0.jar \
    	&& wget -P /jmeter/apache-jmeter-$JMETER_VERSION/lib/ext https://repo.maven.apache.org/maven2/kg/apc/jmeter-plugins-standard/1.4.0/jmeter-plugins-standard-1.4.0.jar
    
    # Settingt Jmeter Home
    ENV JMETER_HOME /jmeter/apache-jmeter-$JMETER_VERSION/
    
    # Finally Adding Jmeter to the Path
    ENV PATH $JMETER_HOME/bin:$PATH
    
    # Ports to be exposed from the container for JMeter Master
    EXPOSE 60000

    Jmeter-slave Dockerfile:

    # Use JDK-8 on alpine.
    From openjdk:8-alpine
    MAINTAINER smooth00 <smooth.blog.csdn.net>
    
    ENV JMETER_VERSION 5.1.1
    
    # Install Pre-requisite Packages like wget
    RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
        apk update && apk add wget unzip vim
    
    # Installing jmeter
    RUN mkdir /jmeter \
            && cd /jmeter/ \
            && wget https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-$JMETER_VERSION.tgz \
            && tar -xzf apache-jmeter-$JMETER_VERSION.tgz \ 
    	&& rm apache-jmeter-$JMETER_VERSION.tgz \
    	&& wget -P /jmeter/apache-jmeter-$JMETER_VERSION/lib/ext https://repo.maven.apache.org/maven2/kg/apc/jmeter-plugins-extras-libs/1.4.0/jmeter-plugins-extras-libs-1.4.0.jar \
    	&& wget -P /jmeter/apache-jmeter-$JMETER_VERSION/lib/ext https://repo.maven.apache.org/maven2/kg/apc/jmeter-plugins-standard/1.4.0/jmeter-plugins-standard-1.4.0.jar
    
    # Settingt Jmeter Home
    ENV JMETER_HOME /jmeter/apache-jmeter-$JMETER_VERSION/
    
    # Finally Adding Jmeter to the Path
    ENV PATH $JMETER_HOME/bin:$PATH
    
    # Ports to be exposed from the container for JMeter Slaves/Server
    EXPOSE 1099 50000
    ENV SSL_DISABLED true
    
    # Application to run on starting the container
    ENTRYPOINT $JMETER_HOME/bin/jmeter-server \
                            -Dserver.rmi.localport=50000 \
                            -Dserver_port=1099 \
                            -Jserver.rmi.ssl.disable=${SSL_DISABLED} \
                            -Djava.rmi.server.hostname=${HOST_IP}

     关于Jmeter的Docker可以参考官网的说明:http://www.testautomationguru.com/jmeter-distributed-load-testing-using-docker/

    最主要是记住下面这段话,我们需要配置好主从节点的端口(因为docker环境和防火墙环境下是一样的,端口没配置明白,就压测不了了):

    We need to open 2 ports for each Slave/Server.
    
    Server_port=1099
    server.rmi.localport=50000
    
    Open a port in client machine for slaves to sends the results to master.
    
    client.rmi.localport=60000

    参考:https://cloud.tencent.com/developer/article/1601081

    由于Rancher还有很多其他功能,也可以做一些其他方面的集成,后续再做研究!

    展开全文
  • 摘要:无论公有云还是私有云厂商,都认识到了将虚拟化的隔离性和容器的高效运维特性相结合,是云原生平台发展的必然趋势。 容器是如何解决隔离问题的 众所周知,容器技术的出现有两个关键原因: 1.软件运行过程中...

    摘要:无论公有云还是私有云厂商,都认识到了将虚拟化的隔离性和容器的高效运维特性相结合,是云原生平台发展的必然趋势。

    容器是如何解决隔离问题的

    众所周知,容器技术的出现有两个关键原因:

    1.  软件运行过程中的资源和环境的隔离。

    2.  软件因为运行环境多样带来的打包和配置的复杂性。

    而对于软件运行环境的隔离需求,从计算机出现之初就已经开始了,多任务分时操作系统和虚拟地址的引入,都是为了解决多个任务在同一主机上运行,并且让任务本身认为自己独占机器。当然这样的隔离是远远不够的,当今软件,根据不同的层级,可以将隔离技术分为以下三类:

    1.  进程级别的隔离

    2.  操作系统级别的隔离

    3.  虚拟化级别的隔离

    操作系统以进程作为程序运行过程的抽象,进程拥有独立的地址空间,进程的执行依靠操作系统的调度。但是进程共享了文件系统,函数库等资源,程序之间出现互相干扰的可能性很大。这个层级的隔离适合在相同主机上运行单个用户的不同程序,由用户自己保证程序之间的资源分配。

    上世纪70年代出现了chroot,进行文件系统的隔离,21世纪初开始,随着计算硬件的性能提升,软件隔离的需求更加强烈,这时候开始出现如jail,cgroup,namespace等各种不同资源的隔离技术。我们将这些技术统一划分到操作系统的隔离技术,这类隔离技术可以实现软件在诸如硬件资源、文件系统、网络、进程号等方面的隔离,但是不同的应用依然是运行在相同的操作系统内核上,对于恶意的利用漏洞攻击的场景,这种隔离技术依然会捉襟见肘。但是这种级别的隔离带来的额外资源消耗较小,适合相同的组织内不同用户的应用在相同主机上运行。

    虚拟化技术的出现,让相同的物理机上也能运行多个不同的操作系统。操作系统对硬件的接口,由虚拟机管理程序(VMM)负责模拟。运行在不同系统中的程序,内核也是隔离的。硬件资源则通过各种硬件辅助手段进行划分,虚拟机上的程序很难突破虚拟化层加上的资源限制。并且因为内核的隔离,资源的可见性也做到了很强的隔离性。即使是恶意的用户,也很难突破这层虚拟化的限制,已达到攻击物理机,或者相同主机上其他虚拟机的目的。

    以上三种隔离是按照层级一步一步加强的,同时带来的理论损耗也是逐步递进的。虚拟化由于需要模拟各种设备,带来的资源损耗比其他两种隔离方式要大很多。

     

    什么是“安全容器”

    容器概念出来的时候,最初大家做隔离的思路,几乎都是操作系统级的隔离,也就是基于内核提供的namespace、cgroup、seccomp等机制,实现容器内的资源、文件、系统调用等限制和隔离。这种隔离方式更加高效,损耗更小。但是随着容器的大规模使用,尤其是各种容器编排系统,如k8s的深入使用,人们逐渐发现这样的隔离级别往往不能满足要求。在公有云场景下,相同主机如果需要运行不同租户的应用,因为这种隔离级别依然采用了共内核的机制,存在这广泛的攻击面,容器的隔离级别完全不能满足要求。所以最初的公有云上的容器服务,都是配合虚拟机的使用来完成的,首先是用户需要创建一批虚拟机作为运行容器的节点,形成一个私有的集群,然后才能在其上创建容器应用。虚拟化级别的隔离已经被各种公有云的实践证明,是一种安全的隔离技术。

    自从云计算的概念提出开始,虚拟机一直是云平台的基础,无论是平台本身服务还是用户的使用,都是从IaaS平台创建通用虚拟机开始的。一般都是创建相应的规格的虚拟机,使用一个完成操作系统镜像启动一个完整的操作系统,随后在其安装,配置,运行软件和服务。包括我们上节提到的公有云容器服务的提供形式也是如此。

    虚拟化本身带来的隔离能力是受到普遍认可的,不过IaaS层希望提供的是一个和应用完全无关的基础设施层,它几乎完全不感知应用的任何信息。于是从基础设施到应用运维,中间巨大的鸿沟则是由PaaS和用户自己来填平,这中间依然需要耗费无数的人力和成本。通用的虚拟机服务诚然有它的好处,比如完整的操作系统很适合程序调试,或者作为工作办公环境等等。但是对于多数运行于云平台的软件,它需要的是它独有的运行环境,它的运行环境由它的镜像已经完全定义好了。如果在此之外,又启动一个完整的操作系统,既浪费资源,也增加了运维的成本。为什么不能直接将虚拟化级别的隔离引入到容器技术中呢?结合虚拟化的安全性和容器在软件生命周期管理方面的优势,是不是可以给软件开发运维带来巨大的便利呢?

    也就是在这个时间,docker和coreos等一起成立了OCI组织,其目的是将容器的运行时和镜像管理等流程标准化。OCI标准定义了一套容器运行时的命令行接口和文件规范,docker将其RunC捐给OCI作为运行时标准的一个参考实现。2015年Hyper.sh开源了RunV,则是一种基于虚拟化的容器运行时接口的实现,它很好地结合了虚拟化的安全性和容器的便利性。后来RunV和ClearContainer合并成立了kata项目,kata提供了更加完整的基于虚拟化的容器实现。我们把这种基于虚拟化的容器实现称作安全容器。

    除kata之外,还相继出现了多个安全容器的实现方式,比如google的gVisor、AWS的firecracker-containerd、IBM的Nabla、VMware的CRX等等,其原理不尽相同,但共同反应了一个趋势,就是将容器的便利和虚拟化的安全隔离结合起来,让虚拟化直接和应用运维结合,成为云原生技术的大势所趋。下面对这些“安全容器”的实现技术进行简要的介绍和对比。

    Google gVisor

    相比于其他几种实现,gVisor的显著不同之处在于,它通过拦截容器中应用的系统调用,模拟了一个操作系统内核,因此gVisor实际上没有虚拟化,而是在用户态实现了一个操作系统。这种方式可以降低因为虚拟化带来的模拟设备内存损耗。gVisor提供的runsc符合OCI标准,可以直接对接docker、containerd等容器平台,同时它也完全兼容docker的镜像格式。但是由于不是一个标准linux内核,因为应用的兼容性有较大问题。另外拦截系统调用带来的巨大的性能损耗也是阻止其广泛使用的一个阻碍。

     

    图片来自https://gvisor.dev/docs/

     

    IBM nabla

    nabla是继承于unikernel的隔离方式,应用采用rumprun打包成一个unikernel镜像,直接运行在一个专为运行unikernel定制虚拟机(ukvm)中。应用直接打包首先可以降低很多内核态和用户态转换的开销,另外通过ukvm暴露非常有限的主机上的syscall(只剩7个),可以大大缩小主机的攻击面。它是这些安全容器实现中,最安全的。不过由于它要求应用打包成unikernel镜像,因此和当前docker的镜像标准是不兼容的。另外,unikernel应用在诸如支持创建子进程等一些常规操作上都有很难解决的问题。

     

    图片来自https://unit42.paloaltonetworks.com/making-containers-more-isolated-an-overview-of-sandboxed-container-technologies/

     

     AWS Firecracker

    最初firecracker是为AWS的Lambda打造的高密度轻量级虚拟化组件。由于它是从头开始构建虚拟化,带着轻量化的目的,因此他抛掉了qemu这种通用虚拟化组件的大部分功能,只留下运行容器和Function必要的一些模拟设备。因此它的内存开销非常小(小于5M),启动速度非常快(小于125ms),一秒钟可以在一个节点上运行150个轻量级虚拟机。

    为了让firecracker-microvm更好的运行容器,AWS启动了firecracker-containerd项目,firecracker-containerd是containerd-shim-v2的一个实现,不符合OCI标准,但是可以直接对接containerd启动容器,也就很容易通过containerd对接k8s的CRI接口。containerd-shim-v2是containerd定义的新的runtime接口,它是对最初shim-v1的一个简化,可以大大精简runtime的组件和内存使用。containerd是一个全插件化的代码框架,扩展性非常好。firecracker-containerd在该框架下,实现了一个snapshotter作为镜像插件,负责块设备镜像的生成;实现了一个shim-v2的runtime,负责容器的生命周期管理。另外还有个fc-control-plugin作为虚拟机的管理插件,提供grpc接口供runtime调用。在轻量级虚拟机内部,有一个agent负责监听runtime传进来的vsock,接收runtime的指令进行虚机内部真正的容器生命周期管理操作,它是直接调用runc来管理容器的。

     

    图片来自https://github.com/firecracker-microvm/firecracker-containerd/blob/master/docs/architecture.md

     

    VMware CRX

    VMware发布的vSphere 7与kubernetes进行了融合,它利用k8s的CRD将其集群的虚拟机、容器、函数等运行实体管理的所有功能都集成到了k8s中。VMware是一个做虚拟化起家的公司,因此虚拟化作为它的老本行,这块的积累是很深厚的。它将虚拟化融合到它的容器runtime CRX中,因此和firecracker-containerd和kata类似,也是一个基于轻量级虚拟化的容器runtime的实现。通过对其虚拟化组件和guest内核的精简,CRX 容器同样做到了很低的内存损耗(20MB)、快速(100ms)的启动以及高密度部署(单个节点大于1000个pod)。

     

    图片来自https://cormachogan.com/2019/11/22/project-pacific-vmworld-2019-deep-dive-updates/

    vSphere对node上的kubelet组件改造比较大,节点上的Spherelet部分功能和kubelet重合,负责pod的生命周期管理(他们称之为Native Pod),运行在虚拟机中的SphereletAgent则集成了符合OCI接口规范的libcontainer,实现容器的生命周期管理,以及容器的监控日志采集、容器的shell登录(kubectl exec)。Spherelet和虚机中的SphereletAgent交互实现类似于kubelet使用CRI接口管理pod的效果。

     

    kata containers

    相比于以上几种,kata containers 最大的特点是它专注于实现一个开放的符合OCI标准的安全容器runtime实现,对于对接什么样的虚拟化方案,它抽象了一套hypervisor接口,如今已经对接了多种虚拟化实现,比如qemu、nemu、firecracker、cloud-hypervisor等等。

     

    图片来自https://katacontainers.io/

     

    通过containerd-shim-v2和vsock技术,kata精简了大量的组件,配合轻量级hypervisor和精简内核,kata可以做到将额外内存消耗降低到10MB以下。容器启动时间降低到100ms以下。后续还会通过rust语言重写等方式,提供更低内存额外消耗。

    图片来自https://github.com/kata-containers/documentation/blob/master/design/architecture.md

     现有安全容器技术对比

     

    实现方式

    安全隔离

    性能/轻量化

    兼容性

    Google gVisor

    用户态内核

    拦截系统调用

    IO、网络性能差

    OS兼容性差

    IBM nabla

    Unikernel

    裁剪系统调用+虚拟化

    暂无数据

    和现有镜像不兼容

    AWS Firecracker

    轻量级虚拟化

    虚拟化

    仅对接firecracker-microvm虚拟化

    VMware CRX

    轻量级虚拟化

    虚拟化

    仅对接VMware的ESXi

    kata-containers

    轻量级虚拟化

    虚拟化

    适配多种轻量级虚拟化技术

     

    安全容器技术发展趋势

    随着Serverless等技术的兴起,应用部署和运维工作已经下沉到云平台上,人们需要一个更加高效的云原生技术平台。从这几年涌现的安全容器实现技术可以观察到,无论公有云还是私有云厂商,都认识到了将虚拟化的隔离性和容器的高效运维特性相结合,是云原生平台发展的必然趋势。结合当前安全容器实现中遇到的一些问题,我们可以预见到,未来这项技术发展的几个走向:

    1. 需要一个为安全容器而生的轻量级hypervisor,当前qemu+kvm是主流的虚拟化技术,但因为qemu是为通用的虚拟机而设计的,其体量过于庞大,而对于安全容器而言,一个模块化可定制的虚拟化实现尤为重要。如果结合gVisor和nabla的实现来看,内核的可定制性也是安全容器场景的必然要求。rust-vmm即是这样一种模块化的虚拟化组件库。linux内核本身的模块化特性可以部分满足容器场景下的内核定制需求,不过也许像gVisor那样实现一个专为容器而生的内核也许是未来的趋势。

    2. 容器的启动时间是衡量一个云原生平台效率的重要指标,尤其是在Serverless场景下,程序运行时间本身可能很短,这时候启动时间可能占用了其绝大部分,那么这种低效就显得尤为明显。安全容器通过极致的轻量化,可以将容器启动时间降低到100ms以下,但是容器镜像拉取时间过长仍是当前容器部署过程中的一个短板。由于当前容器镜像格式和镜像挂载方式等方面的限制,需要在启动容器之前将容器镜像拉取到本地以后,才能启动容器。而容器启动本身需要的数据只占镜像的6%左右。因此我们亟需一个高效的镜像挂载方式,当前已经有一些免下载和懒加载(Lazy-Loading)的技术原型,后续需要尽快推出一个可商用的镜像下载加速方案。

    3. 当前公有云的网络普遍采用原IaaS的网络管理模式,在地址分配,网络配置效率等方面完全赶不上容器快速启停的需求,docker容器采用的veth方式在性能等方面也很难满足高效转发的要求。因此需要一个专为云原生设计的网络管理方案

    4. 我们看到云平台对应用的管理逐步深入,从只管理基础设施的IaaS层,发展到管理应用整体部署和运维的PaaS,再到如今服务网格(Service Mesh)技术将平台管理能力深入到应用内部的微服务级别。同时我们也看到,以K8s容器、Istio服务网格为代表的云原生技术已经和下层的计算/网络虚拟化等技术逐步整合到了一起,比如安全容器即是容器与计算虚拟化的结合,而Istio服务网格也会与虚拟化网络进行深度整合以提供更高的性能与更精细的QoS控制

    5. 当前硬件加速技术在AI和大数据等领域大行其道,安全容器需要与各种计算加速硬件技术进行结合使得AI、大数据、科学计算等批量计算领域的用户可以利用云平台直接投递其海量的计算任务,可大大降低他们在底层技术上的心智负担。通过硬件加速也是提升云平台本身效率、降低云平台运行成本的有效手段。比如华为云擎天架构在硬件加速方面拥有的技术优势在“安全容器”领域已得到充分的证明,CCE Turbo裸金属容器已经实现了安全容器的部分硬件卸载能力

    总结

    未来必然是云原生技术大行其道的时代,我们已经看到很多传统行业也逐渐认识到云原生技术可以给传统企业的IT软件,工业自动化,线上运维和数据管理等带来明显的效率提升。我们将看到通过对底层硬件和上层服务的全栈整合,打造出一个高效智能的云计算技术平台,而这中间,容器将是串联整个技术栈的关键所在。

     

    点击这里,了解更多精彩内容

    展开全文
  • 容器和微服务是当前最热话题,不久之前,笔者(据说因为现在都不用笔了,“笔者”的称谓已经不合适了,因为输入用键盘,叫“键人”更为合适)参加QCon...Swarm是Docker公司在2014年12月初新发布的容器集群管理工具。
  • 容器虚拟化之网络概述

    千次阅读 2018-10-26 15:48:23
    网络虚拟化 前言 网络虚拟化相对计算、存储虚拟化来说是比较抽象的,以我们在学校书本上学的那点网络知识来理解网络虚拟化可能是不够的。 在我们的印象中,网络就是由各种网络设备(如交换机、路由器)相连组成的...
  • 为了支持容器和虚拟机共存的应用,有些企业不得不在vSphere集群外搭建一套新的容器集群,这种做法引入了新的孤岛,并且多个集群的运维管理工具和方法是完全不同的,应用治理的策略也无法同步到两种类型的集群中。...
  • 本文来自网易云社区作者:孙婷婷背景在前文《测试环境docker—基于ndp部署模式的docker基础镜像制作》中已经详述了docker镜像制作及模块部署的过程,按照上述做法已可以搭建测试环境。但是在实践过程中发现存在很...
  • 作者简介:吴恒,BoCloud博云主任架构师,中科院软件所博士,虚拟化容器化10多年经验,docker、libcloud开源项目社区贡献者,并带领团队为swarm、swarmkit、kubernets开源社区贡献内容。 本文节选自《程序员》,...
  • Linux虚拟化容器

    千次阅读 2017-09-04 13:39:44
    为了充分发挥硬件潜力,提高服务器性能,虚拟化技术由此诞生。 所谓虚拟化技术,是指将计算元件和硬件隔离开来,隐藏底层的硬件物理特性,为用户提供抽象、统一的模拟计算环境,从而可以适应庞大的硬件资源而不至于...
  • 虚拟化容器Docker

    万次阅读 2019-10-24 17:29:03
    容器技术是实现操作系统虚拟化的一种途径,可以让您在资源受到隔离的进程中运行应用程序及其依赖关系。通过使用容器,我们可以轻松打包应用程序的代码、配置和依赖关系,将其变成容易使用的构建块,从而实现环境...
  • 云计算、虚拟化容器化杂谈

    千次阅读 2017-11-20 18:56:52
    虚拟机技术已经发展了很多年,虚拟机和虚拟化层间的接口、虚拟机镜像格式等都已经标准化了,相应的管理工具、分布式集群管理工具都有比较完善的解决方案,而容器最近几年才兴起,配套技术和标准还在完善中;...
  • 虚拟机、集群、数据中心虚拟化

    千次阅读 2018-06-09 23:13:38
    1、虚拟机的实现层次虚拟化技术通过在同一个硬件主机上多路复用虚拟机的方式来共享昂贵的硬件资源,虚拟化的基本思想是分离软硬件以产生更好的系统性能 VMM代表虚拟机监视器1、1虚拟化实现层次1、1、1指令集体系...
  • 虚拟化容器技术的理解总结

    千次阅读 2020-06-09 17:19:58
    因为项目需求,最近在学习虚拟化容器技术,在网上看到了很多关于这方面的知识,所以在这里写一篇博客简单总结一下这段时间学习的收获。 虚拟化 虚拟化技术其实是一种将计算机物理资源进行抽象、转换为虚拟的...
  • 容器集群技术-Kubernetes简介

    千次阅读 2018-11-16 13:56:41
    随着Docker技术的发展和广泛流行,云原生应用和容器调度管理系统也成为IT领域大热的词汇。事实上,云原生应用的思想,在Docker技术火爆之前,已经由云计算技术的领导者和分布式系统架构的推广者广泛传播,例如云原生...
  • 作为架构师不得不了解的技术领域-虚拟化技术与容器Docker
  • 我们为什么使用容器? 我们为什么使用虚拟机(云主机)? 为什么使用物理机? 这一系列的问题并没有一个统一的标准答案。因为以上几类技术栈都有自身最适用的场景,在最佳实践之下,它们分别都是不可替代的。 原本...
  • 1. 虚拟化容器Docker入门

    千次阅读 2020-10-19 08:56:58
    文章目录一、Docker简介1.1 什么是Docker1.2 Docker中包括三个基本的概念1.3 Docker组件1.4 安装Docker二、Docker常用命令三、应用部署3.1 mysql部署3.2 安装Redis3.3 安装Elasticsearch3.4 安装...我们用的传统虚拟
  • 从0诞生2013年初,京东商城研发布局虚拟化技术方向。那时的我们从0起步。从几人小团队开始起航。 在物理机时代,应用上线等待分配物理机时间平均在一周。应用混部要看脸看颜值的,没有隔离的应用混部如履薄冰,所以...
  • 虚拟化&云原生基本概念及原理解析 本章主题 1.认识kubernetes(k8s)在企业中实际的应用场景 — 为什么要学习k8s? 2.云技术 — 虚拟化及虚拟机基本理念和原理 3.云技术 — 容器技术及容器基本原理 4.云原生 — ...
  • 大规模的容器技术运用从来不是一项独立工程,而是一个汇集虚拟化技术、容器编排、任务调度、操作系统、容器仓库、跨节点网络、分布式存储、动态扩缩、负载均衡、日志监控、故障自恢复等系统性难题的复杂有机体。...
  • 容器与管理程序虚拟化(hypervisor virtualization,HV)有所不同,管理程序虚拟化通过中间层将一台或者多台独立的机器虚拟运行与物理硬件之上,而容器则是直接运行在操作系统内核之上的用户空间。因此,容器虚拟化...
  • 虚拟化技术是云计算的重要技术,主要用于物理资源的池化,从而可以弹性地分配给用户。物理资源包括服务器、网络和存储。但是计算资源的池化不一定要用虚拟化技术,金属裸机也能池化,比如 IBM 的 Softlayer 就是直接...
  • 文章目录Linux云计算虚拟化-使用Rancher搭建k8s集群并发布电商网站1. Rancher介绍2. 使用Rancher搭建k8s集群2.1 实验环境介绍2.2 在master节点上部署rancher平台 Linux云计算虚拟化-使用Rancher搭建k8s集群并发布...
  • Kubernetes将于7月21日发布1.0版本,对容器生态圈具有重大意义。topic将介绍kubernetes的轻量、模块、弹性伸缩等特征,以及在服务发现、虚拟网络等方面的优势。
  • 一、服务器虚拟化技术:(是下面集群服务器、云服务的技术基石) 将服务器的物理资源抽象成逻辑资源,让一台服务器变成几台甚至上百台(很少见啊)相互隔离的虚拟服务器,我们不再受限于物理上的界限,而是让CPU、...
  • Swarm是Docker公司在2014年12月初发布的一套较为简单的工具,用来管理Docker集群,它将一群Docker宿主机变成一个单一的,虚拟的主机。Swarm使用标准的Docker API接口作为其前端访问入口,换言之,各种形式的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 37,073
精华内容 14,829
关键字:

容器集群虚拟化