• 9月22日上课内容 Docker


    Docker 基本管理

    docker 发展历史 https://www.cnblogs.com/rongba/articles/14782624.html

    Docker 概述

    Docker是一个开源的应用容器引擎,基于go语言开发并遵循了apache2.0协议开源。
    Docker是在Linux容器里运行应用的开源工具,是一种轻量级的“虚拟机”。
    Docker 的容器技术可以在一台主机上轻松为任何应用创建一个轻量级的、可移植的、自给自足的容器。

    Docker的Logo设计为蓝色鲸鱼,拖着许多集装箱。
    鲸鱼可看作为宿主机,集装箱可理解为相互隔离的容器,每个集装箱中都包含自己的应用程序。

    Docker的设计宗旨:Build,Ship and Run Any App,Anywhere,
    即通过对应用组件的封装、发布、部署、运行等生命周期的管理,达到应用组件级别的“一次封装,到处运行”的目的。这里的组件,既可以是一个应用,也可以是一套服务,甚至是一个完整的操作系统。

    容器化越来越受欢迎,因为容器是:

    ●灵活:即使是最复杂的应用也可以集装箱化。
    ●轻量级:容器利用并共享主机内核。
    ●可互换:可以即时部署更新和升级。
    ●便携式:可以在本地构建,部署到云,并在任何地方运行。
    ●可扩展:可以增加并自动分发容器副本。
    ●可堆叠:可以垂直和即时堆叠服务。


    容器是在linux上本机运行,并与其他容器共享主机的内核,它运行的是一个独立的进程,不占用其他任何可执行文件的内存,非常轻量。
    虚拟机运行的是一个完整的操作系统,通过虚拟机管理程序对主机资源进行虚拟访问,相比之下需要的资源更多。

    Docker与虚拟机的区别:

    特性                        Docker容器                    虚拟机
    启动速度                    秒级                        分钟级
    计算能力损耗                 几乎无                         损耗 50%左右
    性能                        接近原生                    弱于
    系统支持量(单机)            上千个                        几十个
    隔离性                        资源隔离/限制                完全隔离

    容器在内核中支持2种重要技术:
    docker本质就是宿主机的一个进程,docker是通过namespace实现资源隔离,通过cgroup实现资源限制,通过写时复制技术(copy-on-write)实现了高效的文件操作(类似虚拟机的磁盘比如分配500g并不是实际占用物理磁盘500g)。


    ====namespace的六项隔离============================================
    namespace     系统调用参数       隔离内容
    UTS            CLONE_NEWUTS     主机名与域名
    IPC            CLONE_NEWWIPC    信号量、消息队列和共享内存
    PID            CLONE_NEWPID     进程编号                                    重点
    NETWORK        CLONE_NEWNET     网络设备、网络栈、端口等                    重点
    MOUNT          CLONE_NEWNS      挂载点(文件系统)                           
    USER           CLONE_NEWUSER    用户和用户组(3.8以后的内核才支持〉


    Docker核心概念

    ●镜像   image

    Docker的镜像是创建容器的基础,类似虚拟机的快照,可以理解为一个面向 Docker 容器引擎的只读模板。
    通过镜像启动一个容器,一个镜像是一个可执行的包,其中包括运行应用程序所需要的所有内容包含代码,运行时间,库、环境变量、和配置文件。
    Docker镜像也是一个压缩包,只是这个压缩包不只是可执行文件,环境部署脚本,它还包含了完整的操作系统。因为大部分的镜像都是基于某个操作系统来构建,所以很轻松的就可以构建本地和远端一样的环境,这也是Docker镜像的精髓。

    ●容器  container

    Docker的容器是从镜像创建的运行实例,它可以被启动、停止和删除。所创建的每一个容器都是相互隔离、互不可见,以保证平台的安全性。
    可以把容器看做是一个简易版的linux环境(包括root用户权限、镜像空间、用户空间和网络空间等)和运行在其中的应用程序。

    ●仓库 repoistory                      

    Docker仓库是用来集中保存镜像的地方,当创建了自己的镜像之后,可以使用push命令将它上传到公有仓库(Public)或者私有仓库(Private)。当下次要在另外一台机器上使用这个镜像时,只需从仓库获取。

    Docker 的镜像、容器、日志等内容全部都默认存储在 /var/lib/docker 


    安装 Docker

    目前 Docker 只能支持 64 位系统。

    systemctl stop firewalld.service
    setenforce 0

    安装依赖包

    yum install -y yum-utils device-mapper-persistent-data lvm2 
    --------------------------------------------------------------------------------------------
    yum-utils:提供了 yum-config-manager 工具。
    device mapper: 是Linux内核中支持逻辑卷管理的通用设备映射机制,它为实现用于存储资源管理的块设备驱动提供了一个高度模块化的内核架构。
    device mapper存储驱动程序需要 device-mapper-persistent-data 和 lvm2。
    --------------------------------------------------------------------------------------------

    设置阿里云镜像源

    yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 

    #安装 Docker-CE并设置为开机自动启动
    yum install -y docker-ce docker-ce-cli containerd.io
    docker-ce-20.10.18

    systemctl start docker.service
    systemctl enable docker.service 
    --------------------------------------------------------------------------------------------
    安装好的Docker系统有两个程序,Docker服务端和Docker客户端。其中Docker服务端是一个服务进程,负责管理所有容器。 Docker客户端则扮演着Docker服务端的远程控制器,可以用来控制Docker的服务端进程。大部分情况下Docker服务端和客户端运行在一台机器上。
    --------------------------------------------------------------------------------------------

    查看 docker 版本信息

    docker version

    docker 信息查看

    docker info  
    Client:
     Context:    default
     Debug Mode: false
     Plugins:
      app: Docker App (Docker Inc., v0.9.1-beta3)
      buildx: Build with BuildKit (Docker Inc., v0.5.1-docker)

    Server:
     Containers: 0                        # 容器数量
      Running: 0
      Paused: 0
      Stopped: 0
     Images: 1                            # 镜像数量
     Server Version: 20.10.3            # server 版本
     Storage Driver: overlay2            # docker 使用的是 overlay2 文件驱动
      Backing Filesystem: xfs            # 宿主机上的底层文件系统
      Supports d_type: true
      Native Overlay Diff: true
     Logging Driver: json-file
     Cgroup Driver: cgroupfs            # Cgroups 驱动
     Cgroup Version: 1
     Plugins:
      Volume: local
      Network: bridge host ipvlan macvlan null overlay
      Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
     Swarm: inactive
     Runtimes: io.containerd.runtime.v1.linux runc io.containerd.runc.v2
     Default Runtime: runc
     Init Binary: docker-init
     containerd version: 269548fa27e0089a8b8278fc4fc781d7f65a939b
     runc version: ff819c7e9184c13b7c2607fe6c30ae19403a7aff
     init version: de40ad0
     Security Options:
      seccomp
       Profile: default
     Kernel Version: 3.10.0-693.el7.x86_64        # 宿主机的相关信息
     Operating System: CentOS Linux 7 (Core)
     OSType: linux
     Architecture: x86_64
     CPUs: 1
     Total Memory: 976.3MiB
     Name: localhost.localdomain
     ID: Y4ES:FTH2:ZJL7:MRVE:RJVB:WJIB:S7BV:C5IZ:LMBR:E4G5:QWSM:SNDT
     Docker Root Dir: /var/lib/docker            # docker 数据存储目录
     Debug Mode: false
     Registry: https://index.docker.io/v1/        # registry 地址
     Labels:
     Experimental: false
     Insecure Registries:
      127.0.0.0/8
     Registry Mirrors:                            # 加速站点
      https://6ijb8ubo.mirror.aliyuncs.com/
     Live Restore Enabled: false

    Docker 镜像操作

    搜索镜像

    格式:docker search 关键字
    docker search nginx

    获取镜像

    格式:docker pull 仓库名称[:标签]
    #如果下载镜像时不指定标签,则默认会下载仓库中最新版本的镜像,即选择标签为 latest 标签。
    docker pull nginx

    镜像加速下载设置

    浏览器访问 https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors 获取镜像加速器配置

    mkdir -p /etc/docker
    tee /etc/docker/daemon.json <<-'EOF'
    {
      "registry-mirrors": ["https://ae3f5qei.mirror.aliyuncs.com"]
    }
    EOF
    systemctl daemon-reload
    systemctl restart docker

    查看镜像信息

    镜像下载后存放在 /var/lib/docker 。
    Docker 相关的本地资源存放在 /var/lib/docker/ 目录下,其中 containers 目录存放容器信息,image 目录存放镜像信息,overlay2 目录下存放具体的镜像底层文件。

    查看下载的镜像文件信息

    cat /var/lib/docker/image/overlay2/repositories.json

    查看下载到本地的所有镜像

    docker images

    REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
    nginx        latest    ae2feff98a0c   9 days ago   133MB
    --------------------------------------------------------------------------------------------
    REPOSITORY:镜像属于的仓库;
    TAG:镜像的标签信息,标记同一个仓库中的不同镜像;
    IMAGE ID:镜像的唯一ID 号,唯一标识一个镜像;
    CREATED:镜像创建时间;
    VIRTUAL SIZE:镜像大小;
    --------------------------------------------------------------------------------------------

    根据镜像的唯一标识 ID 号,获取镜像详细信息

    格式:docker inspect 镜像ID号
    docker inspect ae2feff98a0c

    为本地的镜像添加新的标签

    格式:docker tag 名称:[标签] 新名称:[新标签]
    docker tag nginx:latest nginx:web

    docker images | grep nginx

    删除镜像

    格式:
    docker rmi 仓库名称:标签                #当一个镜像有多个标签时,只是删除其中指定的标签
    或者
    docker rmi 镜像ID号                        #会彻底删除该镜像

    注意:如果该镜像已经被容器使用,正确的做法是先删除依赖该镜像的所有容器,再去删除镜像。

    docker rmi nginx:web

    存出镜像====:将镜像保存成为本地文件

    格式:docker save -o 存储文件名 存储的镜像
    docker save -o nginx nginx:latest            #存出镜像命名为nginx存在当前目录下
    ls -lh

    #载入镜像====:将镜像文件导入到镜像库中

    格式:
    docker load < 存出的文件
    或者
    docker load -i 存出的文件

    docker load < nginx

    #====上传镜像

    默认上传到 docker Hub 官方公共仓库,需要注册使用公共仓库的账号。https://hub.docker.com
    可以使用 docker login 命令来输入用户名、密码和邮箱来完成注册和登录。
    在上传镜像之前,还需要先对本地镜像添加新的标签,然后再使用 docker push 命令进行上传。

    docker tag nginx:latest soscscs/nginx:web        #添加新的标签时必须在前面加上自己的dockerhub的username
    docker login                                #登录公共仓库
    Username:soscscs
    password:abc123456
    docker push soscscs/nginx:web                    #上传镜像

    Docker 容器操作

    容器创建:就是将镜像加载到容器的过程。

    新创建的容器默认处于停止状态,不运行任何程序,需要在其中发起一个进程来启动容器。

    格式:docker create [选项] 镜像
    常用选项:
    -i:让容器开启标准输入
    -t:让 Docker 分配一个伪终端 tty
    -it :合起来实现和容器交互的作用,运行一个交互式会话 shell 

    docker create -it nginx:latest /bin/bash

    查看容器的运行状态

    docker ps -a            #-a 选项可以显示所有的容器
    CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS    PORTS     NAMES
    8b0a7be0ff58   nginx:latest   "/docker-entrypoint.…"   57 seconds ago   Created             inspiring_swanson

    容器的ID号       加载的镜像     运行的程序               创建时间       当前的状态  端口映射  名称

    注:用docker ps 查看只能查看到启动的容器


    启动容器

    格式:docker start 容器的ID/名称
    docker start 8b0a7be0ff58
    docker ps -a

    创建并启动容器

    可以直接执行 docker run 命令, 等同于先执行 docker create 命令,再执行 docker start 命令。
    注意:容器是一个与其中运行的 shell 命令共存亡的终端,命令运行容器运行, 命令结束容器退出。

    docker 容器默认会把容器内部第一个进程,也就是 pid=1 的程序作为docker容器是否正在运行的依据,如果docker容器中 pid = 1 的进程挂了,那么docker容器便会直接退出,也就是说Docker容器中必须有一个前台进程,否则认为容器已经挂掉。

    /var/lib/docker

    当利用 docker run 来创建容器时, Docker 在后台的标准运行过程是:

    (1)检查本地是否存在指定的镜像。当镜像不存在时,会从公有仓库下载;
    (2)利用镜像创建并启动一个容器;
    (3)分配一个文件系统给容器,在只读的镜像层外面挂载一层可读写层;
    (4)从宿主主机配置的网桥接口中桥接一个虚拟机接口到容器中;
    (5)分配一个地址池中的 IP 地址给容器;
    (6)执行用户指定的应用程序,执行完毕后容器被终止运行。

    docker run centos:7 /usr/bin/bash -c ls /
    docker ps -a                    #会发现创建了一个新容器并启动执行一条 shell 命令,之后就停止了

    查看详细信息也可以看到

    后台持续运行 docker run 创建的容器

    需要在 docker run 命令之后添加 -d 选项让 Docker 容器以守护形式在后台运行。并且容器所运行的程序不能结束。

    docker run -d centos:7 /usr/bin/bash -c "while true;do echo hello;done"

    docker ps -a                    #可以看出容器始终处于 UP,运行状态
    CONTAINER ID   IMAGE      COMMAND                  CREATED          STATUS         PORTS     NAMES
    2592d3fad0fb   centos:7   "/usr/bin/bash -c 'w…"   2 seconds ago    Up 2 seconds             peaceful_chatelet

    docker run -itd --name test1 centos:7 /bin/bash   #创建容器并持续运行容器

    创建了两个容器,ifconfig就能查看到两个veth了

    创建容器并持续运行容器

    终止容器运行

    由于前面使用whell循环一直运行(死循环了),导致CPU进程太高,资源一直使用,因此需要终止运行,释放资源

    格式:docker stop 容器的ID/名称
    docker stop 2592d3fad0fb

    docker ps -a

    再次启动

    停止

    由此表明

    up:开启状态

    Exit:停止状态

    容器的进入

    需要进入容器进行命令操作时,可以使用 docker exec 命令进入运行着的容器。

    格式:docker exec -it 容器ID/名称 /bin/bash
    -i 选项表示让容器的输入保持打开;
    -t 选项表示让 Docker 分配一个伪终端。

    docker start 2592d3fad0fb                    #进入容器前,确保容器正在运行
    docker exec -it 2592d3fad0fb /bin/bash
    ls
    exit                #退出容器后,容器仍在运行
    docker ps -a

    docker run -it centos:7 bash      #不加 -d 选项会创建容器后直接进入容器,但是退出容器,容器也会停止

    不加 -d 选项会创建容器后直接进入容器,但是退出容器,容器也会停止

    #面试题

    怎么把宿主机的文件传入(复制)到容器内部(重点)

    1、linux 怎么复制
    cp 原文件路径目标文件路径
    docker cp l opt / abc容器id: /opt/abc


    复制到容器中

    echo abc123 > ~/test.txt
    docker cp ~/test.txt 2592d3fad0fb:/opt/

    从容器复制文件到主机

    docker cp 2592d3fad0fb:/opt/test.txt ~/abc123.txt


    容器的导出与导入

    用户可以将任何一个 Docker 容器从一台机器迁移到另一台机器。在迁移过程中,可以使用docker export 命令将已经创建好的容器导出为文件,无论这个容器是处于运行状态还是停止状态均可导出。可将导出文件传输到其他机器,通过相应的导入命令实现容器的迁移。

    #导出格式:docker export 容器ID/名称 > 文件名

    docker export 2592d3fad0fb > centos7.tar

    #导入格式:cat 文件名 | docker import – 镜像名称:标签

    cat centos7.tar | docker import - centos7:test            #导入后会生成镜像,但不会创建容器

    删除容器

    格式:docker rm [-f] 容器ID/名称
    docker stop 2592d3fad0fb
    docker rm 2592d3fad0fb                #删除已经终止状态的容器

    docker rm -f 2592d3fad0fb            #强制删除正在运行的容器

    docker ps -a | awk 'NR>=2{print "docker stop "$1}' | bash            #批量停止容器
    docker ps -a | awk 'NR>=2{print $1}'| xargs docker stop

    docker ps -a | awk 'NR>=2{print "docker rm "$1}' | bash                #批量删除所有容器
    docker ps -a | awk 'NR>=2{print $1}'| xargs docker rm

    docker images | awk 'NR>=2{print "docker rmi "$3}' | bash            #批量删除镜像
    docker images | grep none | awk '{print $3}' | xargs docker rmi        #删除none镜像

    docker rm $(docker ps -a -q)        #批量清理后台停止的容器

    小结

    Vmware workstation         个人版 PCG
    VMware Sphere /ESXI     企业版
    openstack KVM linux       环境虚拟机        私有云环境

    容器: 提供在多台主机上运行的应用程序相同的运行环境

    docker 是开源的容器 引警

    GO语言开发的,是容器里面运用的工具,他是一个轻量级的虚拟机,可以利用docker在多台主机上轻松的创建和运行容器

    docker容器可以看做运行在宿主机上的一个进程,容器共享宿主机的内核

    容器之间是通过namespace (命名空间、名称空间) 隔离资源,通过Cgroup (资源配额) 去限制资源

    核心概念

    镜像

    运行容器的基础,包含运行程序所需的所有内容(压缩包,环境部署脚本,操作系统等

    容器

    是从镜像创建的运行实例(可以被启动、停止和删除,容器之间相互隔离、互不可见

    仓库

    集中保存镜像的地方 (公有仓库docker hub ,私有仓库 harbor)

    docker search 仓库名/镜像名                #搜索镜像
                pull      仓库名/镜像名:标签        #下载镜像/拉取镜像
                images                                      #查看镜像
                tag       原仓库名/原镜像名:原标签    新原仓库名/新原镜像名:新原标签       #创建镜像标签
                push    登录公共仓库:标签用户名 密码                #上传镜像到公用仓库/私有仓库(后面会学)
                rmi       删除镜像
                save -o    导出镜像
                login    登录公用仓库/私有仓库         -u 仓库用户名         -p 密码
                inspect  镜像ID/容器ID 详细信息
                rm        删除容器        -f 强制制删除容器
                cp        复制本地机器目录的文件 拷贝到容器中容器文件拷贝到本地机器
                create  创建容器(创建之后,然后可以启动)
                start     启动容器
                exec -it        切换到容器内部
                stop     关闭容器
                run      创建并启动容器
                ps -a   显示所有容器
                load    导入镜像
                info     显示信息
                export 导出容器实例为镜像 (数据迁移)
                import 导入镜像

                kill 删除

    -------------------------------------------------------------------------------------------------------------------------------

    docker 网络模式

    ① host:使用host模式容器使用宿主机的网络直接公开服务,这意味着你在容器运行一个web服务,那么它直接绑定主机的网络接口上,而不是通过docker进行任何网络转发

    总结一句话:与宿主机共享网络命名空间/网络协议栈

    ② container:使用这种模式允许容器共享另一个容器的网络命名空间,意味着两个容器可以有相同的网络接口和IP地址,如果他们共享的是同一个网络命名空间

    总结一句话:多个容器直接共享一个networkspace

    ③ node:这是最简单的网络模式,此网络模式表示容器拥有自己的网络命名空间,但不会进行任何网络配置,这实际上给用户完全自主权来配置容器的网络

    总结:自闭空间

    ④ bridge:这是docker默认网络模式,每个新创建的容器都将从该网络中分配一个IP地址,此网络模式允许所有docker容器之间既docker宿主机之间进行相互通信

    总结:通过veth对接容器与docker网桥  网桥分配给容器IP,同时docker0作为“局域网”内容器的网关,最后和宿主机网卡进行通信

    外加

    自定义:docker运行用户创建自己定义的网络,用户可以定义网络范围 子网 路由等参数 这种类型的网络使得我们的用户可以更好的对容器网络进行控制和隔离

    面试题

    容器状态有哪些?

    docker 主要有7个状态

    ① created 已创建,还未运行的容器

    ② running  正在运行中的容器

    ③ restartin 容器正在启动中

    ④ removing 容器正在迁移中

    ⑤ paused 已暂停状态的容器        命令挂起指定容器中的所有进程

    ⑥ exited 停止状态的容器

    ⑦ dead    死亡 主要是操作系统出现异常或者断电关机等有可能引发dead状态   不是很常见

    一个核 1s=1000ms 周期 分片

    #Docker 网络实现原理
    Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的 Container-IP 直接通信。

    Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法直接通过 Container-IP 访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即 docker run 创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器。

    docker run -d --name test1 -P nginx                    #随机映射端口(从32768开始)

    docker run -d --name test2 -p 43000:80 nginx        #指定映射端口

    docker ps -a
    CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                   NAMES
    9d3c04f57a68   nginx     "/docker-entrypoint.…"   4 seconds ago    Up 3 seconds    0.0.0.0:43000->80/tcp   test2
    b04895f870e5   nginx     "/docker-entrypoint.…"   17 seconds ago   Up 15 seconds   0.0.0.0:49170->80/tcp   test1

    浏览器访问:http://192.168.80.10:43000    、http://192.168.80.10:49170

    #查看容器的输出和日志信息
    docker logs 容器的ID/名称

    #Docker 的网络模式:
    ●Host:容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
    ●Container:创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围。
    ●None:该模式关闭了容器的网络功能。
    ●Bridge:默认为该模式,此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及iptables nat 表配置与宿主机通信。
    ●自定义网络  

    kgc0   172.18.0.0/24  172.18.0.20

    安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络)、 none 、host

    docker network ls     或  docker network list            #查看docker网络列表
    NETWORK ID     NAME      DRIVER    SCOPE
    2b4359d229c6   bridge    bridge    local
    0fa580365d39   host      host      local
    cc13aa84a223   none      null      local

    #使用docker run创建Docker容器时,可以用 --net 或 --network 选项指定容器的网络模式
    ●host模式:使用 --net=host 指定。
    ●none模式:使用 --net=none 指定。
    ●container模式:使用 --net=container:NAME_or_ID 指定。
    ●bridge模式:使用 --net=bridge 指定,默认设置,可省略。

    #网络模式详解:
    1.host模式
    相当于Vmware中的桥接模式,与宿主机在同一个网络中,但没有独立IP地址。
    Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。
    一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、iptable规则等都与其他的Network Namespace隔离。 一个Docker容器一般会分配一个独立的Network Namespace。 但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace, 而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡、配置自己的IP等,而是使用宿主机的IP和端口。

    2.container模式
    在理解了host模式后,这个模式也就好理解了。这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。

    docker run -itd --name test1 centos:7 /bin/bash            #--name 选项可以给容器创建一个自定义名称

    docker ps -a
    CONTAINER ID   IMAGE      COMMAND       CREATED      STATUS       PORTS     NAMES
    3ed82355f811   centos:7   "/bin/bash"   5 days ago   Up 6 hours             test1

    docker inspect -f '{{.State.Pid}}' 3ed82355f811            #查看容器进程号
    25945

    ls -l /proc/25495/ns                    #查看容器的进程、网络、文件系统等命名空间编号
    lrwxrwxrwx 1 root root 0 1月   7 11:29 ipc -> ipc:[4026532572]
    lrwxrwxrwx 1 root root 0 1月   7 11:29 mnt -> mnt:[4026532569]
    lrwxrwxrwx 1 root root 0 1月   7 11:27 net -> net:[4026532575]
    lrwxrwxrwx 1 root root 0 1月   7 11:29 pid -> pid:[4026532573]
    lrwxrwxrwx 1 root root 0 1月   7 12:22 user -> user:[4026531837]
    lrwxrwxrwx 1 root root 0 1月   7 11:29 uts -> uts:[4026532570]

    docker run -itd --name test2 --net=container:3ed82355f811 centos:7 /bin/bash
    docker ps -a
    CONTAINER ID   IMAGE      COMMAND       CREATED          STATUS          PORTS     NAMES
    ff96bc43dd27   centos:7   "/bin/bash"   48 seconds ago   Up 46 seconds             test2
    3ed82355f811   centos:7   "/bin/bash"   58 minutes ago   Up 58 minutes             test1

    docker inspect -f '{{.State.Pid}}' ff96bc43dd27
    27123

    ls -l /proc/27123/ns            #查看可以发现两个容器的 net namespace 编号相同
    lrwxrwxrwx 1 root root 0 1月   7 12:27 ipc -> ipc:[4026532692]
    lrwxrwxrwx 1 root root 0 1月   7 12:27 mnt -> mnt:[4026532690]
    lrwxrwxrwx 1 root root 0 1月   7 12:27 net -> net:[4026532575]
    lrwxrwxrwx 1 root root 0 1月   7 12:27 pid -> pid:[4026532693]
    lrwxrwxrwx 1 root root 0 1月   7 12:27 user -> user:[4026531837]
    lrwxrwxrwx 1 root root 0 1月   7 12:27 uts -> uts:[4026532691]


    3.none模式
    使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。 也就是说,这个Docker容器没有网卡、IP、路由等信息。这种网络模式下容器只有lo回环网络,没有其他网卡。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。

    4.bridge模式
    bridge模式是docker的默认网络模式,不用--net参数,就是bridge模式。

    相当于Vmware中的 nat 模式,容器使用独立network Namespace,并连接到docker0虚拟网卡。通过docker0网桥以及iptables nat表配置与宿主机通信,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的 Docker 容器连接到一个虚拟网桥上。    

    (1)当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。

    (2)从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。

    (3)Docker将 veth pair 设备的一端放在新创建的容器中,并命名为 eth0(容器的网卡),另一端放在主机中, 以 * 这样类似的名字命名,并将这个网络设备加入到 docker0 网桥中。可以通过 brctl show 命令查看。veth

    (4)使用 docker run -p 时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL 查看。


    5.自定义网络
    #直接使用bridge模式,是无法支持指定IP运行docker的,例如执行以下命令就会报错
    docker run -itd --name test3 --network bridge --ip 172.17.0.10 centos:7 /bin/bash

    //创建自定义网络
    #可以先自定义网络,再使用指定IP运行docker
    docker network create --subnet=172.18.0.0/16 --opt "com.docker.network.bridge.name"="docker1"  mynetwork
    ----------------------------------------------------------------------------------------------------------
    #docker1 为执行 ifconfig -a 命令时,显示的网卡名,如果不使用 --opt 参数指定此名称,那你在使用 ifconfig -a 命令查看网络信息时,看到的是类似 br-110eb56a0b22 这样的名字,这显然不怎么好记。
    #mynetwork 为执行 docker network list 命令时,显示的bridge网络模式名称。
    ----------------------------------------------------------------------------------------------------------
    docker run -itd --name test4 --net mynetwork --ip 172.18.0.10 centos:7 /bin/bash

    --------------------------------资源控制---------------------------------------------------
    1.CPU 资源控制
    cgroups,是一个非常强大的linux内核工具,他不仅可以限制被 namespace 隔离起来的资源, 还可以为资源设置权重、计算使用量、操控进程启停等等。 所以 cgroups(Control groups)实现了对资源的配额和度量。

    cgroups有四大功能:
    ●资源限制:可以对任务使用的资源总额进行限制
    ●优先级分配:通过分配的cpu时间片数量以及磁盘IO带宽大小,实际上相当于控制了任务运行优先级
    ●资源统计:可以统计系统的资源使用量,如cpu时长,内存用量等
    ●任务控制:cgroup可以对任务执行挂起、恢复等操作

    100000   1   50000  0.5

    (1)设置CPU使用率上限
    Linux通过CFS(Completely Fair Scheduler,完全公平调度器)来调度各个进程对CPU的使用。CFS默认的调度周期是100ms。
    我们可以设置每个容器进程的调度周期,以及在这个周期内各个容器最多能使用多少 CPU 时间。

    使用 --cpu-period 即可设置调度周期,使用 --cpu-quota 即可设置在每个周期内容器能使用的CPU时间。两者可以配合使用。
    CFS 周期的有效范围是 1ms~1s,对应的 --cpu-period 的数值范围是 1000~1000000。 周期100毫秒 
    而容器的 CPU 配额必须不小于 1ms,即 --cpu-quota 的值必须 >= 1000。

    docker run -itd --name test5 centos:7 /bin/bash

    docker ps -a
    CONTAINER ID   IMAGE      COMMAND       CREATED      STATUS       PORTS     NAMES
    3ed82355f811   centos:7   "/bin/bash"   5 days ago   Up 6 hours             test5

    cd /sys/fs/cgroup/cpu/docker/3ed82355f81151c4568aaa6e7bc60ba6984201c119125360924bf7dfd6eaa42b/
    cat cpu.cfs_quota_us 
    -1

    cat cpu.cfs_period_us 
    100000
    ---------------------------------------------------------------------------------------------------------
    #cpu.cfs_period_us:cpu分配的周期(微秒,所以文件名中用 us 表示),默认为100000。
    #cpu.cfs_quota_us:表示该cgroups限制占用的时间(微秒),默认为-1,表示不限制。 如果设为50000,表示占用50000/100000=50%的CPU。
    ---------------------------------------------------------------------------------------------------------

    #进行CPU压力测试
    docker exec -it 3ed82355f811 /bin/bash
    vim /cpu.sh
    #!/bin/bash
    i=0
    while true
    do
    let i++
    done

    chmod +x /cpu.sh
    ./cpu.sh

    top                    #可以看到这个脚本占了很多的cpu资源

    #设置50%的比例分配CPU使用时间上限
    docker run -itd --name test6 --cpu-quota 50000 centos:7 /bin/bash    #可以重新创建一个容器并设置限额
    或者
    cd /sys/fs/cgroup/cpu/docker/3ed82355f81151c4568aaa6e7bc60ba6984201c119125360924bf7dfd6eaa42b/
    echo 50000 > cpu.cfs_quota_us
    docker exec -it 3ed82355f811 /bin/bash
    ./cpu.sh

    top                    #可以看到cpu占用率接近50%,cgroups对cpu的控制起了效果


    (2)设置CPU资源占用比(设置多个容器时才有效)
    Docker 通过 --cpu-shares 指定 CPU 份额,默认值为1024,值为1024的倍数。
    #创建两个容器为 c1 和 c2,若只有这两个容器,设置容器的权重,使得c1和c2的CPU资源占比为1/3和2/3。
    docker run -itd --name c1 --cpu-shares 512 centos:7    
    docker run -itd --name c2 --cpu-shares 1024 centos:7

    #分别进入容器,进行压力测试
    yum install -y epel-release
    yum install -y stress
    stress -c 4                #产生四个进程,每个进程都反复不停的计算随机数的平方根

    #查看容器运行状态(动态更新)
    docker stats
    CONTAINER ID   NAME             CPU %     MEM USAGE / LIMIT     MEM %     NET I/O          BLOCK I/O         PIDS
    c3ee18e65852   c2               66.50%    5.5MiB / 976.3MiB     0.56%     20.4MB / 265kB   115MB / 14.2MB    4
    bb02d3b345d8   c1               32.68%    2.625MiB / 976.3MiB   0.27%     20.4MB / 325kB   191MB / 12.7MB    4

    (3)设置容器绑定指定的CPU
    #先分配虚拟机4个CPU核数
    docker run -itd --name test7 --cpuset-cpus 1,3 centos:7 /bin/bash

    #进入容器,进行压力测试
    yum install -y epel-release
    yum install stress -y
    stress -c 4

    #退出容器,执行 top 命令再按 1 查看CPU使用情况。


    2.对内存使用的限制
    //-m(--memory=) 选项用于限制容器可以使用的最大内存
    docker run -itd --name test8 -m 512m centos:7 /bin/bash

    docker stats

    //限制可用的 swap 大小, --memory-swap
    强调一下,--memory-swap 是必须要与 --memory 一起使用的。

    正常情况下,--memory-swap 的值包含容器可用内存和可用 swap。
    所以 -m 300m --memory-swap=1g 的含义为:容器可以使用 300M 的物理内存,并且可以使用 700M(1G - 300)的 swap。

    如果 --memory-swap 设置为 0 或者 不设置,则容器可以使用的 swap 大小为 -m 值的两倍。
    如果 --memory-swap 的值和 -m 值相同,则容器不能使用 swap。
    如果 --memory-swap 值为 -1,它表示容器程序使用的内存受限,而可以使用的 swap 空间使用不受限制(宿主机有多少 swap 容器就可以使用多少)。


    3.对磁盘IO配额控制(blkio)的限制
    --device-read-bps:限制某个设备上的读速度bps(数据量),单位可以是kb、mb(M)或者gb。
    例:docker run -itd --name test9 --device-read-bps /dev/sda:1M  centos:7 /bin/bash

    --device-write-bps : 限制某个设备上的写速度bps(数据量),单位可以是kb、mb(M)或者gb。
    例:docker run -itd --name test10 --device-write-bps /dev/sda:1mb centos:7 /bin/bash

    --device-read-iops :限制读某个设备的iops(次数)
     
    --device-write-iops :限制写入某个设备的iops(次数)

    #创建容器,并限制写速度
    docker run -it --name test10 --device-write-bps /dev/sda:1MB centos:7 /bin/bash

    #通过dd来验证写速度
    dd if=/dev/zero of=test.out bs=1M count=10 oflag=direct                #添加oflag参数以规避掉文件系统cache
    10+0 records in
    10+0 records out
    10485760 bytes (10 MB) copied, 10.0025 s, 1.0 MB/s


    #清理docker占用的磁盘空间
    docker system prune -a            #可以用于清理磁盘,删除关闭的容器、无用的数据卷和网络

    生产扩展
    故障:由于docker容器故障导致大量日志集满,会造成磁盘空间满
    解决方案
    1、清楚日志

    #!/bin/bash
    logs=$ (find /var/lib/docker/containers/ -name *-json.log*)
    for log in $logs
    do
    cat /dev/null > $log
    done

    2、当日志占满之后如何处理
    ###设置docker日志文件数量及每个日志大小
     vim /etc/docker/daemon.json
    {
    "registry-mirrors": ["http://f613ce8f.m.daocloud.io"],
    "log-driver": "json-file",   #我的一日志格式
    "log-opts": { "max-size" : "500m", "max-file" : "3"}   日志的参数最大500M   我最大容器中有三个日志文件 每个日志文件大小是500M
    }

    修改完需要重新加载  systemctl daemon-reload
     

  • 相关阅读:
    ROS 多机器人导航RVIZ环境的配置
    在 MacOS 应用程序(和 iOS 应用程序)中嵌入 Python 解释器,并成功发布到 App Store。
    Maven最新版的下载与安装教程(详细教程)
    SQL数据分析之窗口排序函数rank、dense_rank、raw_number与lag、lead窗口偏移函数【用法整理】
    Python测试框架Pytest的基础入门
    Python的函数简介
    STM32F4 外部中断的时钟SYSCFG
    js 面试题学习笔记一
    [附源码]计算机毕业设计JAVA高校知识产权管理系统论文2022
    121. 买卖股票的最佳时机 --力扣 --JAVA
  • 原文地址:https://blog.csdn.net/m0_70766460/article/details/133265855