• docker基本管理


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

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

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

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

    通过镜像启动一个容器,一个镜像是一个可执行的包,其中包括运行应用程序所需要的所有内容包含代码,运行时间,库
    、环境变量、和配置文件。 ▁
    Docker镜像也是一个压缩包,只是这个压缩包不只是可执行文件,环境部署脚本,它还包含了完整的操作系统。因为大
    分的镜像都是基于某个操作系统来构建,所以很轻松的就可以构建本地和远端一样的环境,这也是Docker镜像的精髓。
    容器
    Docker的容器是从镜像创建的运行实例,它可以被启动、停止和删除。所创建的每一个容器都是相互隔离、互不可见,以
    保证平台的安全性。A然日
    可以把容器看做是一个简易版的1inux环境(包括root用户权限、镜像空间、用户空间和网络空间等)和运行在其中的应
    用程序。
    仓库
    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
    systemctl start docker.service
    systemctl enable docker.service
    安装好的Docker系统有两个程序,Docker服务端和Docker客户端。其中Docker服务端是一个服务进程,负责管理所有容器

    Docker客户端则扮演着Docker服务端的远程控制器,可以用来控制Docker的服务端进程。大部分情况下Docker服务端和客户端运行在一台机器上。

    #查看 docker版本信息
    docker version
    #docker信息查看
    docker info

    Server:

    Containers: 0 #容器数量
    Running: 0
    Paused: 0
    Stopped: O

    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

    -Docker镜像操作–
    #搜索镜像
    格式:docker search关键字
    docker search nginx
    #获取镜像
    格式:docker pull仓库名称[:标签]
    #如果下载镜像时不指定标签,则默认会下载仓库中最新版本的镜像,即选择标签为1atest标签。
    docker pull nginx
    #镜像加速下载
    浏览器访问 https://cr.console.alfyun.com/cn-hangzhou/instances/mirrors获取镜像加速器配置

    sudo mkdir -p /etc/docker
    sudo tee /etc/docker/daemon.json <<-‘EOF’
    {
    “registry-mirrors”: [“https://awxum5le.mirror.aliyuncs.com”]
    }
    EOF
    sudo systemctl daemon-reload
    sudo systemctl restart docker

    #查看镜像信息
    镜像下载后存放在/var/lib/docker。
    Docker相关的本地资源存放在/var/lib/docker/目录下,其中 containers目录存放容器信息,image
    目录存放镜像信息,overlay2目录下存放具体的镜像底层文件。
    #查看下载的镜像文件信息
    cat /var/lib/docker/image/overlay2/rppositories.json
    #查看下载到本地的所有镜像
    docker images

    REPOSITORY:镜像属于的仓库;
    TAG:镜像的标签信息,标记同一个仓库中的不同镜像;
    IMAGEID.锫像的唯一TD号,唯一标识一个镜像:
    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 命令进行上传。

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

    –Docker容器操作----

    #======容器创建,就是将镜像加载到容器的过程。
    新创建的容器默认处于停止状态,不运行任何程序,需要在其中发起一个进程来启动容器。
    格式:docker create[选项]镜像
    常用选项:
    -i:让容器升启标准输入
    -t:让 Docker 分配一个伪终端tty
    -it:合起来实现和容器交互的作用,运行一个交互式会话shell
    docker create -it nginx:latest /bin/bash
    #查看容器的运行状态
    #-a选项可以显示所有的容器
    docker ps -a

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

    #启动容器
    格式: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容器中必须有一个前台进程,否则认为容器已经挂掉。
    当利用 dockerrun来创建容器时,Docker在后台的标准运行过程是:
    (1)检查本地是否存在指定的镜像。当镜像不存在时,会从公有仓库下载;
    (2)利用镜像创建并启动一个容器;
    (3)分配一个文件系统给容器,在只读的镜像层外面挂载一层可读写层;
    (4)从宿主主机配置的网桥接口中桥接一个虚拟机接口到容器中;
    (5)分配一个地址池中的IP地址给容器;
    (6)执行用户指定的应用程序,执行完毕后容器被终止运行。

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

    #在后台持续运行 docker run 创建的容器
    需要在dockerrun命令之后添加-d选项让Docker容器以守护形式在后台运行。并且容器所运行的程序不能结束。
    docker run -d centos:7 /usr/bin/bash -c “while true;do echo hello;done”
    #可以看出容器始终处于UP,运行状态
    docker ps -a

    docker run -itd --name test1 centos:7 /bin/bash
    #创建容器并持续运行容器
    #=======终止容器运行
    格式:docker stop容器的ID/名称
    docker stop 2592d3fad0fb
    docker ps -a

    #====容器的进入
    需要进入容器进行命令操作时,可以使用 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
    #不加-d选项会创建容器后直接进入容器,但是退出容器,容器也会停止
    docker run -it centos:7 bash

    怎么把宿主机的文件传入到容器内部
    1、linux怎么复制
    Cp原文件路径目标文件路径
    docker cp /opt /abc容器id:/opt/abc
    #======复制到容器中
    echo abcl23 > ~/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 I 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
    #删除none镜像
    docker images | grep none | awk ‘{print $3)’ | xargs docker rmi
    #批量清理后台停止的容器
    docker rm $ (docker ps -a -q)

    当日志占满之后如何处理

    ###设置docker日志文件数量及每个日志大小
    vim /etc/docker/daemon.json
    {
    “registry-mirrors”: [“https://awxum5le.mirror.aliyuncs.com”],
    “log-driver”: “json-file”,
    “log-opts”: { “max-size” : “500m”, “max-file” : “3”}
    }

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

    #Docker网络实现原埋
    Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
    Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法直接通过 Container-IP访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即dockerrun创建容器时候通过-p或-P参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器。
    docker run -d --name test1 -P nginx:01 #随机映射端口(从32768开始)
    docker run -d --name test2 -p 43000:80 nginx #指定映射端口
    docker ps -a

    浏览器访问: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表配置与宿主机诵信
    • 自定义网络
      安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络)、none、host

    docker network ls 或 docker network list #查看docker网络列表

    NETWORK ID NAME DRIVER SCOPE
    b11da96da3be bridge bridge local
    503c91fdcfa1 host host local
    9c128aa82df4 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和端口。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KMK9GjZT-1663330661908)(C:/Users/weiguang/AppData/Roaming/Typora/typora-user-images/image-20220906141120047.png)]

    2.container模式
    在理解了host模式后,这个模式也就好理解了。这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。
    #–name选项可以给容器创建一个自定义名称
    docker run -itd --name test4 centos:7 /bin/bash
    docker ps -a
    docker inspect -f ‘{{.State.Pid}}’ 6553e3a2e5fc #查看容器进程号
    3441
    ls -l /proc/3441/ns #查看容器的进程、网络、文件系统等命名空间编号

    总用量 0
    lrwxrwxrwx 1 root root 0 9月 6 17:40 ipc -> ipc:[4026532518]
    lrwxrwxrwx 1 root root 0 9月 6 17:40 mnt -> mnt:[4026532516]
    lrwxrwxrwx 1 root root 0 9月 6 17:38 net -> net:[4026532521]
    lrwxrwxrwx 1 root root 0 9月 6 17:40 pid -> pid:[4026532519]
    lrwxrwxrwx 1 root root 0 9月 6 17:40 user -> user:[4026531837]
    lrwxrwxrwx 1 root root 0 9月 6 17:40 uts -> uts:[4026532517]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bxmZnsm7-1663330661909)(C:/Users/weiguang/AppData/Roaming/Typora/typora-user-images/image-20220906142618910.png)]

    docker run -itd --name test5 --net=container:6553e3a2e5fc centos:7 /bin/bash
    docker ps -a

    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    d37682318305 centos:7 “/bin/bash” 3 seconds ago Up 2 seconds test5
    6553e3a2e5fc centos:7 “/bin/bash” 49 minutes ago Up 49 minutes test4

    docker inspect -f ‘{{.State.Pid}}’ d37682318305
    4276
    ls -l /proc/4276/ns #查看可以发现两个容器的 net namespace 编号相同

    总用量 0
    lrwxrwxrwx 1 root root 0 9月 6 18:29 ipc -> ipc:[4026532614]
    lrwxrwxrwx 1 root root 0 9月 6 18:29 mnt -> mnt:[4026532612]
    lrwxrwxrwx 1 root root 0 9月 6 18:29 net -> net:[4026532521]
    lrwxrwxrwx 1 root root 0 9月 6 18:29 pid -> pid:[4026532615]
    lrwxrwxrwx 1 root root 0 9月 6 18:29 user -> user:[4026531837]
    lrwxrwxrwx 1 root root 0 9月 6 18:29 uts -> uts:[4026532613]

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

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N9ue1pAA-1663330661910)(C:/Users/weiguang/AppData/Roaming/Typora/typora-user-images/image-20220906144940393.png)]

    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
    #docker为执行ifconfig-a命令时,显示的网卡名,如果不使用–opt参数指定此名称,那你在使用ifconfig
    -a命令查看网络信息时,看到的是类似br-110eb56a0b22这样的名字,这显然不怎么好记。
    #mynetwork 为执行 docker network list 命令时,显示的bridge网络模式名称。

    NETWORK ID NAME DRIVER SCOPE
    b11da96da3be bridge bridge local
    503c91fdcfa1 host host local
    ef18ab196e8e mynetwork bridge local
    9c128aa82df4 none null local

    docker run -itd --name test4 --net mynetwork --ip 172.18.0.10 centos:7 /bin/bash

    docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    cac300bade32 centos:7 “/bin/bash” 3 seconds ago Up 2 seconds test7
    d37682318305 centos:7 “/bin/bash” 58 minutes ago Up 58 minutes test5
    6553e3a2e5fc centos:7 “/bin/bash” 2 hours ago Up 2 hours test4

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

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

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

    使用–cpu-period即可设置调度周期,使用–cpu-quota即可设置在每个周期内容器能使用的CPU时间。两者可以配合使用。
    CFS周期的有效范围是1ms1s,对应的–cpu-period的数值范围是10001000000。
    而容器的CPU配额必须不小于1ms,即–cpu-quota的值必须>=1000。
    docker run -itd --name test5 centos:7 /bin/bash

    docker ps -a

    cd /sys/fs/cgroup/cpu/docker/c7d60146c7cd22e8d2aaee0c43213f0ff0cb2c9066ac6900b62d580f06fce2a8/
    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 c7d60146c7cd /bin/bash
    vi /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 test9 --cpu-quota 50000 centos:7 /bin/bash
    docker ps -a

    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    ecf5ea2bb6b7 centos:7 “/bin/bash” About a minute ago Up About a minute test9
    c7d60146c7cd centos:7 “/bin/bash” 13 minutes ago Up 13 minutes test8
    cac300bade32 centos:7 “/bin/bash” 35 minutes ago Up 35 minutes test7

    cd /sys/fs/cgroup/cpu/docker/ecf5ea2bb6b7a266765e9d70794cbc25b154b73cad5369efa1df34a4634180d0/

    cat cpu.cfs_quota_us
    50000

    #可以重新创建一个容器并设置限额
    或者
    cd /sys/fs/cgroup/cpu/docker/c7d60146c7cd22e8d2aaee0c43213f0ff0cb2c9066ac6900b62d580f06fce2a8/
    echo 50000 > cpu.cfs_quota_us
    docker exec -it c7d60146c7cd22e8d2aaee0c43213f0ff0cb2c9066ac6900b62d580f06fce2a8 /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 stressstress -c 4
    #产生四个进程,每个进程都反复不停的计算随机数的平方根

    #查看容器运行状态(动态更新)
    docker stats

    (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 -ystress -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。
    所以-m300m–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、mbM)或者gb。
    例: docker run -itd --name test9–device-read-bps /dev/sda:1Mcentos:7 /bin/bash

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

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

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

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

    #通过dd来验证写速度
    dd if=/dev/zero bf=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 的数据管理---------------------
    管理 Docker 容器中数据主要有两种方式:数据卷(Data Volumes)和数据卷容器(DataVolumes Containers)。
    1.数据卷
    数据卷是一个供容器使用的特殊目录,位于容器中。可将宿主机的目录挂载到数据卷上,对数据卷的修改操作立刻可见,并且更新数据不会影响镜像,从而实现数据在宿主机与容器之间的迁移。数据卷的使用类似于 Linux 下对目录进行的 mount 操作。

    docker pull centos:7

    #宿主机目录/var/www 挂载到容器中的/data1。
    注意:宿主机本地目录的路径必须是使用绝对路径。如果路径不存在,Docker会自动创建相应的路径。
    docker run -v /var/www:/data1 --name web1 -it centos:7 /bin/bash #-v 选项可以在容器内创建数据卷
    ls
    echo “this is web1” > /data1/abc.txt
    exit

    #返回宿主机进行查看
    cat /var/www/abc.txt

    2.数据卷容器
    如果需要在容器之间共享一些数据,最简单的方法就是使用数据卷容器。数据卷容器是一个普通的容器,专门提供数据卷给其他容器挂载使用。
    #创建一个容器作为数据卷容器
    docker run --name web2 -v /data1 -v /data2 -it centos:7 /bin/bash
    echo “this is web2” > /data1/abc.txt
    echo “THIS IS WEB2” > /data2/ABC.txt

    #使用 --volumes-from 来挂载 web2 容器中的数据卷到新的容器
    docker run -it --volumes-from web2 --name web3 centos:7 /bin/bash
    cat /data1/abc.txt
    cat /data2/ABC.txt

    -----------------端口映射-----------------------------------
    在启动容器的时候,如果不指定对应的端口,在容器外是无法通过网络来访问容器内的服务。端口映射机制将容器内的服务提供给外部网络访问,实质上就是将宿主机的端口映射到容器中,使得外部网络访问宿主机的端口便可访问容器内的服务。
    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

    ------------------容器互联(使用centos镜像)---------------------------------
    容器互联是通过容器的名称在容器间建立一条专门的网络通信隧道。简单点说,就是会在源容器和接收容器之间建立一条隧道,接收容器可以看到源容器指定的信息。
    #创建并运行源容器取名web1
    docker run -itd -P --name web1 centos:7 /bin/bash

    #创建并运行接收容器取名web2,使用–link选项指定连接容器以实现容器互联
    docker run -itd -P --name web2 --link web1:web1 centos:7 /bin/bash #–link 容器名:连接的别名

    #进web2 容器, ping web1
    docker exec -it web2 bash
    ping web1

    ------------------Docker 镜像的创建---------------------------------
    创建镜像有三种方法,分别为基于已有镜像创建、基于本地模板创建以及基于Dockerfile创建。
    1.基于现有镜像创建
    (1)首先启动一个镜像,在容器里做修改
    docker create -it centos:7 /bin/bash

    docker ps -a
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    000550eb36da centos:7 “/bin/bash” 3 seconds ago Created gracious_bassi

    (2)然后将修改后的容器提交为新的镜像,需要使用该容器的 ID 号创建新镜像
    docker commit -m “new” -a “centos” 000550eb36da centos:test
    #常用选项:
    -m 说明信息;
    -a 作者信息;
    -p 生成过程中停止容器的运行。

    docker images

    2.基于本地模板创建
    通过导入操作系统模板文件可以生成镜像,模板可以从 OPENVZ 开源项目下载,下载地址为http://openvz.org/Download/template/precreated

    wget http://download.openvz.org/template/precreated/debian-7.0-x86-minimal.tar.gz

    #导入为镜像
    cat debian-7.0-x86-minimal.tar.gz | docker import - debian:test

    3.基于Dockerfile 创建

    //联合文件系统(UnionFS)
    UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。AUFS、OverlayFS 及 Devicemapper 都是一种 UnionFS。

    Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

    特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

    我们下载的时候看到的一层层的就是联合文件系统。

    //镜像加载原理
    Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是UnionFS。

    bootfs主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统。

    在Docker镜像的最底层是bootfs,这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。

    rootfs,在bootfs之上。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。

    我们可以理解成一开始内核里什么都没有,操作一个命令下载debian,这时就会在内核上面加了一层基础镜像;再安装一个emacs,会在基础镜像上叠加一层image;接着再安装一个apache,又会在images上面再叠加一层image。最后它们看起来就像一个文件系统即容器的rootfs。在Docker的体系里把这些rootfs叫做Docker的镜像。但是,此时的每一层rootfs都是read-only的,我们此时还不能对其进行操作。当我们创建一个容器,也就是将Docker镜像进行实例化,系统会在一层或是多层read-only的rootfs之上分配一层空的read-write的rootfs。

    //为什么Docker里的centos的大小才200M?
    因为对于精简的OS,rootfs可以很小,只需要包含最基本的命令、工具和程序库就可以了,因为底层直接用宿主机的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。

    //Dockerfile
    Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

    镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。

    Dockerfile是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。有了Dockerfile,当我们需要定制自己额外的需求时,只需在Dockerfile上添加或者修改指令,重新生成 image 即可, 省去了敲命令的麻烦。

    除了手动生成Docker镜像之外,可以使用Dockerfile自动生成镜像。Dockerfile是由多条的指令组成的文件,其中每条指令对应 Linux 中的一条命令,Docker 程序将读取Dockerfile 中的指令生成指定镜像。

    Dockerfile结构大致分为四个部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。Dockerfile每行支持一条指令,每条指令可携带多个参数,支持使用以“#“号开头的注释。

    #Docker 镜像结构的分层
    镜像不是一个单一的文件,而是有多层构成。容器其实是在镜像的最上面加了一层读写层,在运行容器里做的任何文件改动,都会写到这个读写层。如果删除了容器,也就删除了其最上面的读写层,文件改动也就丢失了。Docker使用存储驱动管理镜像每层内容及可读写层的容器层。

    (1)Dockerfile 中的每个指令都会创建一个新的镜像层;
    (2)镜像层将被缓存和复用;
    (3)当Dockerfile 的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了,对应的镜像层缓存就会失效;
    (4)某一层的镜像缓存失效,它之后的镜像层缓存都会失效;
    (5)镜像层是不可变的,如果在某一层中添加一个文件,然后在下一层中删除它,则镜像中依然会包含该文件,只是这个文件在 Docker 容器中不可见了。

    #Dockerfile 操作常用的指令:
    (1)FROM 镜像
    指定新镜像所基于的基础镜像,第一条指令必须为FROM 指令,每创建一个镜像就需要一条 FROM 指令

    (2)MAINTAINER 名字
    说明新镜像的维护人信息

    (3)RUN 命令
    在所基于的镜像上执行命令,并提交到新的镜像中

    (4)ENTRYPOINT [“要运行的程序”, “参数 1”, “参数 2”]
    设定容器启动时第一个运行的命令及其参数。
    可以通过使用命令docker run --entrypoint 来覆盖镜像中的ENTRYPOINT指令的内容。

    (5)CMD [“要运行的程序”, “参数1”, “参数2”]
    上面的是exec形式,shell形式:CMD 命令 参数1 参数2
    启动容器时默认执行的命令或者脚本,Dockerfile只能有一条CMD命令。如果指定多条命令,只执行最后一条命令。
    如果在docker run时指定了命令或者镜像中有ENTRYPOINT,那么CMD就会被覆盖。
    CMD 可以为 ENTRYPOINT 指令提供默认参数。

    (6)EXPOSE 端口号
    指定新镜像加载到 Docker 时要开启的端口

    (7)ENV 环境变量 变量值
    设置一个环境变量的值,会被后面的 RUN 使用

    (8)ADD 源文件/目录 目标文件/目录
    将源文件复制到镜像中,源文件要与 Dockerfile 位于相同目录中,或者是一个 URL
    有如下注意事项:
    1、如果源路径是个文件,且目标路径是以 / 结尾, 则docker会把目标路径当作一个目录,会把源文件拷贝到该目录下。
    如果目标路径不存在,则会自动创建目标路径。

    2、如果源路径是个文件,且目标路径是不以 / 结尾,则docker会把目标路径当作一个文件。
    如果目标路径不存在,会以目标路径为名创建一个文件,内容同源文件;
    如果目标文件是个存在的文件,会用源文件覆盖它,当然只是内容覆盖,文件名还是目标文件名。
    如果目标文件实际是个存在的目录,则会源文件拷贝到该目录下。 注意,这种情况下,最好显示的以 / 结尾,以避免混淆。

    3、如果源路径是个目录,且目标路径不存在,则docker会自动以目标路径创建一个目录,把源路径目录下的文件拷贝进来。
    如果目标路径是个已经存在的目录,则docker会把源路径目录下的文件拷贝到该目录下。

    4、如果源文件是个归档文件(压缩文件),则docker会自动帮解压。
    URL下载和解压特性不能一起使用。任何压缩文件通过URL拷贝,都不会自动解压。

    (9)COPY 源文件/目录 目标文件/目录
    只复制本地主机上的文件/目录复制到目标地点,源文件/目录要与Dockerfile 在相同的目录中

    (10)VOLUME [“目录”]
    在容器中创建一个挂载点

    (11)USER 用户名/UID
    指定运行容器时的用户

    (12)WORKDIR 路径
    为后续的 RUN、CMD、ENTRYPOINT 指定工作目录

    (13)ONBUILD 命令
    指定所生成的镜像作为一个基础镜像时所要运行的命令。
    当在一个Dockerfile文件中加上ONBUILD指令,该指令对利用该Dockerfile构建镜像(比如为A镜像)不会产生实质性影响。
    但是当编写一个新的Dockerfile文件来基于A镜像构建一个镜像(比如为B镜像)时,这时构造A镜像的Dockerfile文件中的ONBUILD指令就生效了,在构建B镜像的过程中,首先会执行ONBUILD指令指定的指令,然后才会执行其它指令。

    (14)HEALTHCHECK
    健康检查

    在编写 Dockerfile 时,有严格的格式需要遵循:
    ●第一行必须使用 FROM 指令指明所基于的镜像名称;
    ●之后使用 MAINTAINER 指令说明维护该镜像的用户信息;
    ●然后是镜像操作相关指令,如 RUN 指令。每运行一条指令,都会给基础镜像添加新的一层。
    ●最后使用 CMD 指令指定启动容器时要运行的命令操作。

    --------Dockerfile 案例--------
    #建立工作目录
    mkdir /opt/apache
    cd /opt/apache

    vim Dockerfile
    #基于的基础镜像
    FROM centos:7
    #维护镜像的用户信息
    MAINTAINER this is apache image
    #镜像操作指令安装apache软件
    RUN yum -y update
    RUN yum -y install httpd
    #开启 80 端口
    EXPOSE 80
    #复制网站首页文件
    ADD index.html /var/www/html/index.html
    //方法一:
    #将执行脚本复制到镜像中
    ADD run.sh /run.sh
    RUN chmod 755 /run.sh
    #启动容器时执行脚本
    CMD [“/run.sh”]
    //方法二:
    ENTRYPOINT [ “/usr/sbin/apachectl” ]
    CMD [“-D”, “FOREGROUND”]

    //准备执行脚本
    vim run.sh
    #!/bin/bash
    rm -rf /run/httpd/* #清理httpd的缓存
    /usr/sbin/apachectl -D FOREGROUND #指定为前台运行
    #因为Docker容器仅在它的1号进程(PID为1)运行时,会保持运行。如果1号进程退出了,Docker容器也就退出了。

    //准备网站页面
    echo “this is test web” > index.html

    //生成镜像
    docker build -t tomcat:centos . #注意别忘了末尾有"."

    //新镜像运行容器
    docker run -d -p 1234:8080 tomcat:centos

    //测试
    http://192.168.80.10:1216/

    ########如果有网络报错提示########
    [Warning] IPv4 forwarding is disabled. Networking will not work.

    解决方法:
    vim /etc/sysctl.conf
    net.ipv4.ip_forward=1

    sysctl -p
    systemctl restart network
    systemctl restart docker

    gitlab-rails console -e production

    user = User.where(id: 1).first

    user.password = ‘123456’

    user.password_confirmation = ‘123456’

    user.save!
    exit
    法二:
    ENTRYPOINT [ “/usr/sbin/apachectl” ]
    CMD [“-D”, “FOREGROUND”]

    //准备执行脚本
    vim run.sh
    #!/bin/bash
    rm -rf /run/httpd/* #清理httpd的缓存
    /usr/sbin/apachectl -D FOREGROUND #指定为前台运行
    #因为Docker容器仅在它的1号进程(PID为1)运行时,会保持运行。如果1号进程退出了,Docker容器也就退出了。

    //准备网站页面
    echo “this is test web” > index.html

    //生成镜像
    docker build -t tomcat:centos . #注意别忘了末尾有"."

    //新镜像运行容器
    docker run -d -p 1234:8080 tomcat:centos

    //测试
    http://192.168.80.10:1216/

    ########如果有网络报错提示########
    [Warning] IPv4 forwarding is disabled. Networking will not work.

    解决方法:
    vim /etc/sysctl.conf
    net.ipv4.ip_forward=1

    sysctl -p
    systemctl restart network
    systemctl restart docker

    gitlab-rails console -e production

    user = User.where(id: 1).first

    user.password = ‘123456’

    user.password_confirmation = ‘123456’

    user.save!
    exit

  • 相关阅读:
    element table穿梭框+分页
    整理笔记——MOS管、三极管、IGBT
    JavaWeb-使用session机制和cookie机制改造JavaWeb基础项目
    同花顺_代码解析_技术指标_B
    国产PHY YT8521S UTP/FIBER 模式的一次调试
    内存空间扩充之进程覆盖技术,交换技术
    Elasticsearch(十五)搜索---搜索匹配功能⑥--基于地理位置查询
    对观察者模式的理解
    线性表顺序表综合应用题P18
    Flink之Watermark源码解析
  • 原文地址:https://blog.csdn.net/qq_38713675/article/details/126897058