zoukankan      html  css  js  c++  java
  • Docker

    Docker是一个能够把开发的应用程序自动部署到container的开源container engine(容器引擎)。
    Docker官网对它的定义是:Simplify modern application development and delivery by bundling distributed services into a single Docker application
    Docker背后的想法是创建软件程序可移植的轻量容器,让其可以在任何安装了Docker的机器上运行,而不用关心底层操作系统。
     
    Docker版本选择
    Docker有社区版(Community Edition)、企业版(Enterprise Edition)两种。企业版主要是在安全方面进行了加强。
    从2017年初的1.13版本以后,Docker使用了新的<年>.<月>形式的版本号规则。
    目前发布通道分为Stable、Test、Nightly三种。
    如今,Docker运行容器已经不是简单的通过Docker Daemon来启动,Docker Daemon被分成了多个模块以适应OCI标准。
     
    Docker CE这个产品,是由Moby组织下的Moby项目以及其他项目构建和编译出来的。因此,并不会存在一个开源项目叫Docker CE。因为Docker CE是一个产品,只能从Docker公司官网上来下载使用。
     
    64位Centos下Docker-CE部署
    首先清除当前docker
    $ sudo yum remove docker 
                      docker-client 
                      docker-client-latest 
                      docker-common 
                      docker-latest 
                      docker-latest-logrotate 
                      docker-logrotate 
                      docker-engine
    docker默认存储目录是/var/lib/docker/,包括 images、containers、volumes、networks等,是一个被保护的目录。
    1、设置Docker's repositories并从中安装
    (1)安装需要的包
    $ sudo yum install -y yum-utils
    yum-utils提供了yum-config-manager
    device-mapper-persistent-data和lvm2是deviceapper存储驱动所必须的
    (2)使用如下命令设置stable仓库
    $ sudo yum-config-manager 
        --add-repo 
        https://download.docker.com/linux/centos/docker-ce.repo
    (3)可选:启用/禁用edge和test仓库
    $ sudo yum-config-manager --enable/disable docker-ce-nightly
    $ sudo yum-config-manager --enable/disable docker-ce-test
    这些仓库被包括在docker.repo文件中但默认是disable的
    (4)更新yum软件包目录
    $ sudo yum makecache fast
    (5)安装最新版Docker CE
    $ sudo yum install docker-ce docker-ce-cli containerd.io
    或者搜索选择版本
    $ yum list docker-ce --showduplicates | sort -r
    docker-ce.x86_64  3:18.09.1-3.el7                     docker-ce-stable
    docker-ce.x86_64  3:18.09.0-3.el7                     docker-ce-stable
    docker-ce.x86_64  18.06.1.ce-3.el7                    docker-ce-stable
    docker-ce.x86_64  18.06.0.ce-3.el7                    docker-ce-stable
    选择需要安装的版本
    $ sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
    (6)启动Docker CE
    $ sudo systemctl start docker
    2、安装RPM包并手工安装、手工升级
    (1)前往这两个网页下载rpm文件:
    (2)安装Docker CE,把下面的路径改为下载包的路径
    $ sudo yum install /path/to/package.rpm
    (3)启动Docker CE
    $ sudo systemctl start docker
    (4)更新Docker CE
    下载新的包文件重复安装过程
    $ sudo yum -y update /path/to/package.rpm
     
    检查版本和基本信息
    docker -v
    docker info
     
    运行Container
    开启运行一个Container:
    docker run <image>
    相当于:
    docker create <image>
    docker start <container>
    image参数就是指定在这个Container里运行哪个镜像。如果未指定具体标签,将默认选择tag为latest的镜像。
    一个image可以同时开启并运行多个Container,同时运行的多个Container也可以同时运行同一个image。
     
    命令示例:
    docker run -i -t ubuntu /bin/echo 'Hello world'
    -p 8080:80   将容器的80端口和主机的8080映射。一个主机端口只能绑定一个容器端口。如果要映射的端口比较多,冒号前后的端口号可以是一个范围
    -i                   打开容器的标准输入
    -t                  为容器打开一个命令行终端
    -d                 表示该容器为后台容器,
    --name         为容器指定名
    --rm              一旦运行的进程退出就删除容器
    -e k="v"       创建环境变量 
    注意点:
    (1)运行在后台的容器,创建成功后就与当前终端无关了。要停止容器只能调用docter stop或者docker kill等命令
    (2)使用-d参数启动的容器,启动命令不能是bash,否则执行后会直接退出。可以搭配-i和-t参数为容器提供一个伪tty n
    (3)-i和-t参数一般搭配使用,使容器运行在前台,有指定的交互控制台。可以给容器输入和输出。但只要从所在终端exit了,容器就会变成停止状态。 
     
    此命令使用Ubuntu镜像创建并启动一个容器 ,在容器里执行 /bin/echo 'Hello world’命令。本地不存在此镜像时会自动从配置的镜像仓库拉取。
    容器的文件系统是在只读的镜像文件上加一层可读写的文件层,这样可以保证镜像不变只记录改变的数据。
    接着会配置容器的网络,docker会为容器分配一个虚拟网络接口,并通过桥接的方式将该网络接口桥接到宿主主机上去,然后为该虚拟网络接口分配一个ip地址。
    最后,docker在新容器中运行指定的命令。启动的运行程序称为initial进程。这个initial进程启动的时候,容器也会随之启动。
    容器内不一定只有一个进程,initial进程本身也可以产生其他的子进程,或者通过docker exec等运维操作产生子进程。
    当initial进程退出的时候,容器中的所有子进程也会随之退出(防止资源的泄漏)。因此,可以认为容器的生命周期和initial进程的生命周期是一致的。
     
    交互式进入容器中
    docker attch <container name | id>
    docker exec -it <container name | id> /bin/bash
    docker attch可以使本机的输入直接输到容器中,容器的输出会直接显示在本机的屏幕上。因此,可以attach到一个已经运行的容器的stdin,然后进行命令执行的动作。 但是需要注意的是,如果从这个stdin中exit,会导致容器的停止。
     
    查看Container和image
    查看容器列表:
    docker ps
    加上-a参数以包含非运行中的容器
    查看镜像列表:
    docker images
    此命令只会显示顶层镜像,加上-a参数可以显示隐藏的中间层镜像
    查看镜像和容器的元数据,包括制作者、适应架构、各层的数字摘要等:
    docker inspect <image name | id>
    docker inspect <container name | id>
    例如查看一个容器的挂载信息:
    docker inspect <container name | id> | grep Mounts -A 9
     
    停止/重启/一个 Container
    docker stop <container name | id>
    docker restart <container name | id>
    docker kill <container name | id>
    stop容器时会向容器中PID为1的initial进程(主进程)发送SIGTERM信号,默认在10秒后才会发送SIGKILL信号;kill容器时会直接向initial进程发送SIGKILL信号
    使用参数-t指定等待的时间
    如果容器启动命令是/bin/sh(主进程是shell),则不会将信号转发给用户进程
     
    例如停止所有容器:
    docker stop $(docker ps -a -q)
    删除一个 image/Container
    docker rmi <image name>
    docker rm <container name | id>
    已经创建容器的镜像无法删除,必须先删除容器
    -f  强制删除
     
    Container与主机间数据拷贝
    docker cp CONTAINER:SRC_PATH DEST_PATH
    docker cp SRC_PATH|- CONTAINER:DEST_PATH
     
    docker system-全新的命令集合
    查看docker整体磁盘使用率的概况,包括镜像、容器和(本地)volume:
    docker system df
    查看docker系统实时事件,不包括容器内的(等同于docker events命令):
    docker system events
    查看整个docker系统的信息(等同于docker info命令):
    docker system info
    清理资源,包括stop的容器、未使用的数据卷、未使用的网络、dangling的镜像(无名称悬停镜像):
    docker system prune
    -a 强制清理,包括所有未使用的镜像
     
    开启Remote API 访问 2375端口
    在docker的启动参数中加上-H tcp://0.0.0.0:2375
    就可以用如下命令访问远程主机的docker
    docker -H tcp://ip:2375 version
    此时任何人都可以不经过认证远程访问此docker,因此需要加上授权的方式,在启动参数中加上:
    --tlsverify
    --tlscacert=/data/hps/certificate/ca.pem
    --tlscert=/data/hps/certificate/server-cert.pem
    --tlskey=/data/hps/certificate/server-key.pem
     
    刚刚的命令就变成了:
    docker --tlsverify --tlscacert=/data/hps/certificate/ip/ca.pem --tlscert=/data/hps/certificate/ip/client-cert.pem --tlskey=/data/hps/certificate/ip/client-key.pem -H ip:2375 info
    容器日志
    查看某个容器的日志
    docker logs <container name | id>
    -f:跟踪日志输出
    --since="xxxx-xx-xx":显示某个开始时间的日志 
    --tail=10:显示最后10条日志
    -t:显示时间戳
     
    docker支持的日志引擎如下:
    • none
    关闭docker的回显日志,无法查看任何容器输出的日志,docker logs看不到任何输出。
    • syslog
    把所有容器的回显日志打到系统的syslog中。
    • journald
    把所有容器的回显日志打到系统的journald服务中。
    • fluentd
    把所有容器的回显日志打到fluentd服务中
    • gelf
    把所有容器的回显日志打到支持Graylog Extended Log Format格式的服务(比如Graylog或Logstash)中
    • json-file
    把每个容器的回显日志打到每个容器的内部,形式为json文件。
    在实际使用中,有些容器在启动后有大量的回显日志,尤其在程序内部报错时打出的日志信息尤其巨大,因此要配置存储目录、存储上限:
      "log-driver": "json-file",
      "log-level": "warn",
      "log-opts": {
        "max-size": "100m",
        "max-file": "3"    # 意味着一个容器有三个日志,分别是id+.json、id+1.json、id+2.json
        }
      "date-root": "xxx"   # 存储目录
    数据卷
    默认情况下,当用户退出容器而容器中又没有非守护进程在运行时,容器会进入关闭状态,数据的修改会保留在层级的可写文件系统内。当用户需要重新开启一个容器时,是无法访问原来所做的修改的,而是恢复到镜像的初始化状态。
    为了解决数据持久化的问题,Docker提供了卷(Volume)机制。就是将宿主机中的某个目录,mount到容器中
    这样,在容器中此目录下的修改,即便容器关闭,数据也会保留下来,供宿主机和其他容器访问。
    卷是受控存储,是由Docker引擎进行管理维护的。因此使用卷,不必处理 uid、SELinux 等各种权限问题,Docker引擎在建立卷时会自动添加安全规则,以及根据挂载点调整权限。并且可以统一列表、添加、删除。
    • 在运行容器的时候,在Docker中创建一个匿名数据卷
    docker run -dti -v /data centos
    在docker容器中会有/data目录,这个目录不归属于层级文件系统
    创建命名数据卷:
    docker volume create --name xxx
    由于数据卷有名字,下次挂载的时候还可以用
    数据卷默认可能会保存于/var/lib/docker/volumes,不过一般不需要、也不应该访问这个位置
    • 将宿主机的一个目录,挂在到容器里
    docker run -tdi -v /var/data:/data:ro centos
    冒号前为宿主机目录,必须为绝对路径,冒号后为镜像内挂载的路径在冒号后指定权限
    直接挂载目录,可能会遇到Permission Denied问题
    • 挂载单个文件到容器中
    docker run -tdi ~/dbback.tar.gz:/dbback.tar.gz centos
    • 数据卷容器
    数据卷其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载共同使用的。其它容器启动可以直接挂载数据卷容器中定义的挂载信息。
    创建一个包含数据卷的容器供其他容器使用,这个容器并不需要一直开启
    docker run -tdi -v /data --name data_s centos
    如果需要将数据同步到宿主机的目录中,则创建数据卷容器的时候,选择挂载宿主机的目录,如:
    docker run -tdi -v /data:/data --name data_s centos
    创建两个容器,使用这个数据卷容器
    docker run -ti --volumes-from data_s  --name web1 centos
    docker run -ti --volumes-from data_s  --name web2 centos
    此时这两个容器,都可以共同读写/data目录了
    其实就是挂载了匿名卷的容器,早就过时了。
     
    监控
    docker自带的docker stats命令,可以显示容器使用的系统资源。数据主要来自cgroup。
     
    例如,/cgroup/memory/docker/xxxx/目录下,cgroup中的memory子系统为hierarchy提供了大量文件,与docker监控相关的主要有:
        memory.usage_in_bytes:已使用的内存量(包含cache和buffer)字节数,相当于linux的used_mem
        memory.limit_in_bytes:限制的内存字节数,相当于linux的total_mem
        memory.failcnt:申请内存失败次数计数
        memory.memsw.usage_in_bytes:已使用的内存和swap字节数
        memory.memsw.limit_in_bytes:限制的内存和swap字节数
        memory.memsw.failcnt:申请内存和swap失败次数计数
        memory.stat:内存相关状态
     
    docker stats命令会将容器的内存监控分为cache、usage、swap usage、kernel usage、kernel tcp usage。
    其中cache是从memory.stat中的cache中获取;usage是使用memory.usage_in_bytes和memory.limit_in_bytes进行相除。
    这一方式有一个弊端,就是不够细化,没有区分出cache部分,不能真正反映内存使用率。因为一般来说cache是可以复用的内存部分,因此一般将其计入到可使用的部分。
     
    在统计内存使用量时可以考虑将cache计算排除出去。类似于linux中计算real_used时将buffer和cache排除。
    但计算cache并不能直接应用memory.stat中的cache,因为其中包括了tmpfs,而tmpfs(即share memory)算是实际使用的内存部分。
    因为在memory.stat中存在:active_file + inactive_file = cache - size of tmpfs
    因此可以计算实际使用的内存量为:real_used = memory.usage_in_bytes - (rss + active_file + inactive_file)
     

     
    Docker是client-server架构,docker daemon(dockerd)监听API请求,负责管理容器、镜像、容器网络、卷等;用户使用CLI通过API接口来控制dockerd。
    Docker服务启动之后,可以看见系统上启动了dockerd进程,其子进程为containerd,containerd的子进程为若干个containerd-shim进程,每个containerd-shim进程有1个子进程,就是容器内的主进程,该进程启动命令就是容器的启动命令
     
    moby daemon是实际管理容器的engine。
     
    containerd是容器运行时管理引擎
        向上为moby daemon提供容器、镜像的相关管理的gRPC接口,使得moby daemon屏蔽下面的结构变化,确保原有接口向下兼容。
        向下通过containerd-shim结合runC,使得引擎可以独立升级,避免之前Docker升级会导致所有容器不可用的问题。
    上图从左右两部分看,可以认为containerd提供了两大功能:对容器生命周期(runtime)的管理;对镜像拉取、存储的管理。
    按照水平层次来看:
        第一层是GRPC,containerd通过GRPC的形式来对上层提供服务的。Metrics主要是提供cgroup Metrics的一些内容。
        第二层的左边是容器镜像的存储;中间images、containers对应的Matadata是通过bootfs存储在磁盘上的;右边的Tasks是管理容器的容器结构,容器的一些操作会有Event向上层发出,上层订阅Event以知道容器状态发生什么变化。
        第三层是Runtimes层。
     
    shim类似于containerd底层的守护进程模块,这样设计的原因有几点:
    1、containerd需要管理容器生命周期,而容器可能是由不同的容器运行时所创建出来的,因此需要提供一个灵活的插件化管理。而 shim就是针对于不同的容器运行时所开发的,这样就能够从 containerd中脱离出来,通过插件的形式进行管理。
    2、因为shim插件化的实现,使其能够被containerd动态接管。如果不具备这样的能力,当moby daemon或者containerd daemon意外退出的时候,容器就没人管理了,那么它也会随之消失、退出,这样就会影响到应用的运行。
    3、因为随时可能会对moby或者containerd进行升级,如果不提供shim机制,那么就无法做到原地升级,也无法做到不影响业务的升级,因此containerd shim非常重要,它实现了动态接管的能力。
     
    runC是Docker开发的容器runtime,符合oci规范,也是现在docker的默认runtime。
    它提供了一个命令行小工具,没有镜像管理功能,只能根据准备好的文件系统创建容器。具体底层实现基于libcontainer库。
    启动Docker Daemon时增加--add-runtime参数可以选择其他的runtime实现
  • 相关阅读:
    vector
    vector-back
    vector-back
    vector-begin
    vector-begin
    vector-at
    vector-at
    Vector-assign
    Vector-assign
    Vector-Constructors
  • 原文地址:https://www.cnblogs.com/yangyuliufeng/p/14183609.html
Copyright © 2011-2022 走看看