06-Docker

作者: 郑元吉 | 来源:发表于2019-02-21 16:13 被阅读2次

    ⼀. Docker介绍

    Docker是什么?

    Docker 是⼀个开源的应⽤容器引擎,基于Go语⾔并遵从Apache2.0协议开源。
    Docker 可以让开发者打包他们的应⽤以及依赖包到⼀个轻量级、可移植的容器中,然后发布到任何
    流⾏的Linux机器上,也可以实现虚拟化。
    容器是完全使⽤沙箱机制,相互之间不会有任何接⼝(类似 iPhone 的 app),更重要的是容器性能
    开销极低。

    容器和虚拟机

    虚拟机:
    虚拟机如VMware,VisualBox之类的需要模拟整台机器包括硬件,每台虚拟机都需要有⾃⼰的
    操作系统,虚拟机⼀旦被开启,预分配给它的资源将全部被占⽤。每⼀台虚拟机包括应⽤,必要的⼆进
    制和库,以及⼀个完整的⽤户操作系统。

    容器:
    容器技术是和我们的宿主机共享硬件资源及操作系统,可以实现资源的动态分配。容器包含应⽤
    和其所有的依赖包,但是与其他容器共享内核。容器在宿主机操作系统中,在⽤户空间以分离的进程运
    ⾏。
    Docker属于Linux容器的⼀种封装,提供简单易⽤的容器使⽤接⼝。它是⽬前最流⾏的Linux容器解
    决⽅案。

    Docker的优势
    Docker相⽐于传统虚拟化⽅式具有更多的优势:
    1. docker启动快速属于秒级别。虚拟机通常需要⼏分钟去启动.
    2. docker需要的资源更少,docker在操作系统级别进⾏虚拟化,docker容器和内核交互,⼏乎没有性能损耗,性能优于通过 Hypervisor 层与内核层的虚拟化
    3. docker 更轻量, docker 的架构可以共⽤⼀个内核与共享应⽤程序库,所占内存极⼩。同样的硬件环境, Docker 运⾏的镜像数远多于虚拟机数量,对系统的利⽤率⾮常⾼
    4. 与虚拟机相⽐,docker隔离性更弱,docker属于进程之间的隔离,虚拟机可实现系统级别隔离
    5. 安全性: docker的安全性也更弱。 Docker 的租户 root 和宿主机 root 等同,⼀旦容器内的⽤户从普通⽤户权限提升为root权限,它就直接具备了宿主机的root权限,进⽽可进⾏⽆限制的操作。虚拟机租户 root 权限和宿主机的 root 虚拟机权限是分离的,并且虚拟机利⽤如 Intel 的VT-d 和 VT-x 的 ring-1 硬件隔离技术,这种隔离技术可以防⽌虚拟机突破和彼此交互,⽽容器⾄今还没有任何形式的硬件隔离,这使得容器容易受到攻击
    6. 可管理性:docker的集中化管理⼯具还不算成熟。各种虚拟化技术都有成熟的管理⼯具,例如VMware vCenter 提供完备的虚拟机管理能⼒
    7. ⾼可⽤和可恢复性: docker 对业务的⾼可⽤⽀持是通过快速重新部署实现的。虚拟化具备负载均衡,⾼可⽤,容错,迁移和数据保护等经过⽣产实践检验的成熟保障机制, VMware 可承诺虚拟机99.999% ⾼可⽤,保证业务连续性
    8. 快速创建、删除:虚拟化创建是分钟级别的, Docker 容器创建是秒级别的, Docker 的快速迭代性,决定了⽆论是开发、测试、部署都可以节约⼤量时间
    9. 交付、部署:虚拟机可以通过镜像实现环境交付的⼀致性,但镜像分发⽆法体系化。 Docker 在Dockerfile 中记录了容器构建过程,可在集群中实现快速分发和快速部署


      比较.png
    Docker的三个基本概念

    Image(镜像)
    Container(容器)
    Repository(仓库)
    镜像是 Docker 运⾏容器的前提,仓库是存放镜像的场所,可⻅镜像更是 Docker 的核⼼。

    Image (镜像)

    Docker镜像:
    可以看作是⼀个特殊的⽂件系统,除了提供容器运⾏时所需的程序、库、资源、配置等⽂件外,还包含了⼀些为运⾏时准备的⼀些配置参数(如匿名卷、环境变量、⽤户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
    镜像是只读的,镜像中包含有需要运⾏的⽂件。镜像⽤来创建container,⼀个镜像可以运⾏多个container;镜像可以通过Dockerfile创建,也可以从Docker hub/registry上下载。

    Container (容器)

    容器 (container) 的定义和镜像 (image) ⼏乎⼀模⼀样;
    容器⼀般要由镜像来创建, ⼀个镜像可以创建任意多个相同的容器;
    容器是Docker的运⾏组件,启动⼀个镜像就是⼀个容器,容器是⼀个隔离环境,多个容器之间不会相互影响,保证容器中的程序运⾏在⼀个相对安全的环境中。

    Repository (仓库)

    Docker仓库是集中存放镜像⽂件的场所。镜像构建完成后,可以很容易的在当前宿主上运⾏,但是,如果需要在其它服务器上使⽤这个镜像,我们就需要⼀个集中的存储、分发镜像的服务,DockerRegistry (仓库注册服务器)就是这样的服务。有时候会把仓库 (Repository) 和仓库注册服务器(Registry) 混为⼀谈,并不严格区分。Docker 仓库的概念跟 Git 类似,注册服务器可以理解为GitHub 这样的托管服务。实际上,⼀个 Docker Registry 中可以包含多个仓库(Repository) ,每个仓库可以包含多个标签 (Tag),每个标签对应着⼀个镜像。所以说,镜像仓库是 Docker ⽤来集中存放镜像⽂件的地⽅类似于我们之前常⽤的代码仓库。
    通常,⼀个仓库会包含同⼀个软件不同版本的镜像,⽽标签就常⽤于对应该软件的各个版本。我们可以通过<仓库名>:<标签>的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以latest作为默认签.。
    仓库⼜可以分为两种形式:
    public(公有仓库)
    private(私有仓库)
    Docker Registry 公有仓库是开放给⽤户使⽤、允许⽤户管理镜像的 Registry 服务。⼀般这类公开服务允许⽤户免费上传、下载公开的镜像,并可能提供收费服务供⽤户管理私有镜像。
    除了使⽤公开服务外,⽤户还可以在本地搭建私有 Docker Registry 。Docker 官⽅提供了Docker Registry 镜像,可以直接使⽤做为私有 Registry 服务。当⽤户创建了⾃⼰的镜像之后就可以使⽤ push 命令将它上传到公有或者私有仓库,这样下次在另外⼀台机器上使⽤这个镜像时候,只需要从仓库上 pull 下来就可以了。
    https://hub.docker.com/

    ⼆. Docker安装

    • 由于apt官方库里的docker版本可能比较旧,所以先卸载可能存在的旧版本:
    $ sudo apt-get remove docker docker-engine docker-ce docker.io
    
    • 更新apt包索引:
    $ sudo apt-get update
    
    • 安装以下包以使apt可以通过HTTPS使用存储库(repository):
    $ sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
    
    • 添加Docker官方的GPG密钥:
    $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    
    • 使用下面的命令来设置stable存储库:
    $ sudo add-apt-repository "[deb](https://www.baidu.com/s?wd=deb&tn=24004469_oem_dg) [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
    
    • 再更新一下apt包索引:
    $ sudo apt-get update
    
    • 安装最新版本的Docker CE:
    $ sudo apt-get install -y docker-ce
    
    • 在生产系统上,可能会需要应该安装一个特定版本的Docker CE,而不是总是使用最新版本:
    $ apt-cache madison docker-ce
    
    版本.png

    选择要安装的特定版本,第二列是版本字符串,第三列是存储库名称,它指示包来自哪个存储库,以及扩展它的稳定性级别。要安装一个特定的版本,将版本字符串附加到包名中,并通过等号(=)分隔它们:

    $ sudo apt-get install docker-ce='版本号'
    
    验证docker
    • 查看docker服务是否启动:
    $ systemctl status docker
    
    • 若未启动,则启动docker服务:
    $ sudo systemctl start docker
    
    • 经典的hello world:
    $ sudo docker run hello-world
    
    hello world.png

    有以上输出则证明docker已安装成功!

    三. 镜像加速

    鉴于国内⽹络问题,后续拉取 Docker 镜像⼗分缓慢,我们可以需要配置加速器来解决,我使⽤的是⽹易的镜像地址:http://hub-mirror.c.163.com
    新版的 Docker 使⽤ /etc/docker/daemon.json(Linux) 或者%programdata%\docker\config\daemon.json(Windows) 来配置 Daemon。
    请在该配置⽂件中加⼊(没有该⽂件的话,请先建⼀个):

    $ vim /etc/docker/daemon.json
    

    {
    "registry-mirrors": ["http://hub-mirror.c.163.com"]
    }

    四. 开始使⽤Docker

    使⽤ docker run 命令来在容器内运⾏⼀个应⽤程序。

    $ sudo docker run ubuntu /bin/echo "Hello world"
    $ docker run -i -t ubuntu /bin/bash
    [docker run -it ubuntu /bin/bash]
    • -t: 在新容器内指定⼀个伪终端或终端。
    • -i: 允许你对容器内的标准输⼊ (STDIN) 进⾏交互。
    • /bin/bash: 进⼊容器
    exit: 退出容器
    

    五. Docker容器

    • 拉取镜像
    $ sudo docker pull training/webapp 
    
    • 使⽤镜像创建容器
    $ sudo docker run -d -P training/webapp python app.py
    • -d: 让容器在后台运⾏。
    • -P: 将容器内部使⽤的⽹络端⼝映射到我们使⽤的主机上。
    
    • 查看正在运⾏的容器
    $ sudo docker ps
    $ sudo docker ps -l #查询最后⼀次创建的容器
    

    通过 -p 参数来设置不⼀样的端⼝:

    $ sudo docker run -d -p 5000:5000 training/webapp python app.py
    

    也可以指定容器绑定的⽹络地址:

    $ sudo docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
    
    • 停⽌容器
    $ sudo docker stop container_id 
    
    • 重启容器
    $ sudo docker start container_id
    
    • 删除容器: 删除容器时,容器必须是停⽌状态,否则会报错误
    $ sudo docker rm container_id
    # 删除所有容器
    $ sudo docker rm `docker ps -a -q` 
    

    六. Docker镜像

    • 查看镜像列表
    $ sudo docker images
    

    REPOSITORY TAG IMAGE ID CREATED SIZE
    ubuntu 16.04 80d0abcdeaf 1 days ago 100 M
    • REPOSITORY:表示镜像的仓库源
    • TAG:镜像的标签
    • IMAGE ID:镜像ID
    • CREATED:镜像创建时间
    • SIZE:镜像⼤⼩
    • 同⼀仓库源可以有多个 TAG,代表这个仓库源的不同个版本

    $ sudo docker search ubuntu
    
    • 获取镜像
    $ sudo docker pull ubuntu
    
    • 删除镜像
    $ sudo docker rmi image_id
    # 删除所有镜像
    $ sudo docker rmi `docker images -q` 
    
    Dockerfile
    • 构建镜像: 通过创建⼀个 Dockerfile ⽂件来创建镜像
    $ sudo cat Dockerfile
    

    Dockerfile⽂件内容格式:

    FROM python:3.7
    MAINTAINER niejeff 123456@qq.com
    RUN /bin/echo "hello"
    EXPOSE 80
    CMD /usr/sbin/sshd -D
    每⼀个指令都会在镜像上创建⼀个新的层,每⼀个指令的前缀都必须是⼤写的。
    FROM: 指定基础镜像
    MAINTAINER: ⽤于指定镜像创建者和联系⽅式
    RUN: 容器内部的执⾏Linux命令
    EXPOSE: ⽤来指定对外开放的端⼝
    CMD: ⽤于启动容器时默认执⾏的命令

    写个例⼦来构建Dockerfile

    mkdir static_web
    cd static_web
    vim Dockerfile 
    

    Dockerfile内容

    FROM python:3.7
    MAINTAINER niejeff 123456@qq.com

    在Dockerfile所在⽬录执⾏:

    $ sudo docker build -t docker_demo/flask_web:v1 .
    -t 是为新镜像设置仓库和名称
    docker_demo 为仓库名
    nginx_web 为镜像名
    :v1 为标签(不添加为默认 latest )
    

    构建完成之后,再查看所有镜像

    $ sudo docker images
    

    将镜像上传到hub.docker仓库

    $ sudo docker login
    先tag, 再push
    docker tag local-image:tagname reponame:tagname
    docker push reponame:tagname
    例如
    docker tag docker_demo/flask_web:v1 niejeff/docker_demo
    • docker_demo/flask_web:v1 : 镜像REPOSITORY:TAG
    • niejeff/docker_demo : ⽤户名/仓库名
    docker push niejeff/docker_demo
    

    七. ⽤Docker部署Flask应⽤

    创建Flask应⽤

    先创建⽂件夹myflask 在myflask中创建app.py, 内容如下

    from flask import Flask
    app = Flask(__name__)
    @app.route('/')
    def hello():
     return 'hello flask'
    if __name__ == '__main__':
     app.run(debug=True)
    
    使⽤Gunicorn+Gevent运⾏Flask应⽤

    进⼊虚拟环境, 安装包

    $ pip install gunicorn gevent
    

    在myflask⽂件夹下编写gunicorn的配置⽂件gunicorn.conf.py

    workers = 8 # 进程数量
    worker_class = "gevent" # 采⽤gevent库,⽀持异步处理请求,提⾼吞吐量
    bind = "0.0.0.0:8888" # 监听IP放宽,以便于Docker之间、Docker和宿主机之间的通信

    使⽤gunicorn命令进⾏测试

    $ gunicorn app:app -c gunicorn.conf.py
    

    打开浏览器,输⼊ 127.0.0.1:8888 ,可以看到返回的⽹⻚中展示内容 hello flask。

    改⽤Docker运⾏Flask应⽤

    在myflask⽂件夹下创建⽂件requirements.txt

    flask
    gunicorn
    gevent

    创建Dockerfile来构造镜像

    FROM python:3.5
    WORKDIR /usr/src/app
    COPY requirements.txt ./
    RUN pip install --no-cache-dir -r requirements.txt
    COPY . .
    CMD ["gunicorn", "app:app", "-c", "./gunicorn.conf.py"]

    开始构造镜像

    $ sudo docker build -t 'myflask' .
    

    查看该镜像是否已经创建

    $ sudo docker images
    

    运⾏docker镜像

    $ sudo docker run -it --rm -p 8888:8888 myflask
    --rm : 容器运⾏结束时会⾃动删除该容器
    

    最后打开浏览器,输⼊ 127.0.0.1:8888 ,可以看到返回的⽹⻚中展示内容 hello flask
    如果是在云服务器端运⾏的Docker容器, 则输⼊: 公⽹IP:8888来访问

    相关文章

      网友评论

          本文标题:06-Docker

          本文链接:https://www.haomeiwen.com/subject/umnryqtx.html