/www/wwwroot/www.liudu.love/usr/plugins/AMP/templates/MIPpage.php on line 31
">

Docker系列课程之一:基础篇

2026-07-22T13:26:00

一、什么是Docker及其体系架构

1、什么是Docker?体系架构
    (*)Docker是一个容器的引擎(虚拟机)
    (*)让开发人员可以打包自己的应用程序(依赖:包、资源)
    (*)虚拟化
    (*)组成:
        (1)Docker Client客户端:Docker命令
        (2)Docker Daemon守护进程
        (3)Docker Image镜像模板:分层结构
        (4)Docker Container容器

2、安装和配置Docker实验环境:Centos
    (*)关闭防火墙
            systemctl stop firewalld.service
            systemctl disable firewalld.service  永久关闭防火墙

    (*)使用在线安装的方式
            yum install docker
            启动Docker服务
            systemctl start docker
            systemctl enable docker 开机自启
            查看Docker版本
            docker version

二、Docker的镜像:image(模板---->创建容器)

什么是Docker镜像?
(1)镜像是一个模板
(2)镜像采用分层的文件系统
(3)镜像是容器运行的基石
(4)可以从镜像仓库中进行拉取(公有、私有harbor)
    

1、使用和访问官方的Docker的镜像仓库(hub)  https://hub.docker.com
    docker search **** 搜索镜像模板
    docker pull *** 拉取镜像(下载本地)
    docker run 命令创建容器
    
    举例1:拉取MySQL的镜像,创建一个容器
        docker search mysql
        docker pull mysql  ----> 默认:latest版本
        docker images  ----> 查看本地下载的镜像
        docker run --name my_mysql_demo -p 3306:3306 -e MYSQL_ROOT_PASSWORD=Welcome_1 -d mysql
        说明: --name 指定容器的名称
               -p     指定宿主机和容器之间的端口映射
               -e     设置环境变量
               -d     启动容器进程(后台,返回container id)
               mysql  镜像的名称
        进入容器:
        docker exec -it CONTAINER_ID /bin/bash
        docker exec -it eadee3a87f29 /bin/bash
        
    举例2:拉取Tomcat的镜像,创建一个容器
        docker search tomcat
        docker pull tomcat
        docker images
        docker run --name my_tomcat_demo -d -p 8080:8080 tomcat


2、配置和使用阿里云提供的Docker镜像加速器
    mkdir -p /etc/docker
    tee /etc/docker/daemon.json <<-'EOF'
    {
      "registry-mirrors": ["https://giwrd70q.mirror.aliyuncs.com"]
    }
    EOF
    systemctl daemon-reload
    systemctl restart docker    
    
    地址
    Registry Mirrors:
     https://giwrd70q.mirror.aliyuncs.com
    

3、管理镜像(Docker命令)
    docker search [NAME] 在镜像仓库中搜索镜像
    docker pull [NAME] 拉取镜像(latest)
    docker push [NAME] 上传到镜像仓库中
    docker images 列出本地的所有镜像(基本信息)
    docker images m*  支持通配符
    docker inspect [NAME]/[CONTAINER_ID] 列出镜像(容器)的详细信息
    docker rmi [NAME] 删除镜像
                      参数:-f 强制删除
                      如果有多个镜像,采用空格进行分隔
    docker run 使用镜像创建容器


4、构建Docker镜像(上传到docker hub)
    (1)使用docker commit
        举例:1、使用Docker部署一个Tomcat的容器
                    docker pull tomcat
                    docker run -d --name tomcat_web_app -p 8080:8080 tomcat
        
              2、在Tomcat容器中部署一个简单的Web应用(修改容器)
                    docker exec -it 6490798df72b /bin/bash
                    
                    cd webapps
                    mkdir mydemo
                    cd mydemo
                    echo '<h1>Hello Tomcat</h1>' > a.html
              
              3、将容器保存docker commit -----> 本地
                    docker commit 6490798df72b tomcat_web_app_local
              
                 将容器保存docker commit -----> 镜像仓库中
                    登录 docker login
                    docker commit 6490798df72b collenzhao/tomcat_web_app_remote
              
              4、使用docker push命令上传的镜像
                    docker push collenzhao/tomcat_web_app_remote
    
    (2)使用Dockerfile(命令:docker build)
        (1)创建一个Dockerfile(-f参数指定文件名称)
                基于Nginx镜像,部署一个简单的Web App应用
                
                FROM nginx
                RUN echo '<h1>This is a Demo WebApp</h1>' > /usr/share/nginx/html/index.html
                
        (2)使用docker build命令,生成镜像
                docker build -t nginx:mylatest .
    
        (3)创建一个容器
               docker run -d -p 7788:80 nginx:mylatest
    
5、Dockerfile使用(综合例子)
    (1)Docker镜像、Docker容器、Dockerfile三者的关系
            参考PPT

    (2)Dockerfile的基本概念
        (*)Docker镜像是一个特殊的文件系统
        (*)Dockerfile基于文本的配置文件,包含一条条的指令。每一条指令构建分层文件系统中的一层
        (*)docker build构建image镜像
        
    (3)Dockerfile文件格式:4部分
        (*)基础镜像信息
        (*)维护者的信息
        (*)镜像操作命令
        (*)容器启动执行的命令
        
    (4)综合的例子:    
        (*)从一个基本的centos基础镜像开始
        (*)安装JDK和Tomcat
        (*)在tomcat中部署一个Web App应用
        (*)启动容器,访问Web App的应用
        创建Dockerfile
        
        FROM centos
        MAINTAINER zhaoqiang zhaoqiang@example.com
        RUN mkdir /root/training
        RUN mkdir /root/tools
        COPY jdk-8u144-linux-x64.tar.gz /root/tools
        RUN tar zxvf /root/tools/jdk-8u144-linux-x64.tar.gz -C /root/training/
        ENV JAVA_HOME /root/training/jdk1.8.0_144
        ENV PATH $JAVA_HOME/bin:$PATH
        ADD http://mirror.bit.edu.cn/apache/tomcat/tomcat-8/v8.5.35/bin/apache-tomcat-8.5.35.tar.gz /root/tools
        RUN tar zxvf /root/tools/apache-tomcat-8.5.35.tar.gz -C /root/training/
        COPY MyDemoWeb.war /root/training/apache-tomcat-8.5.35/webapps
        ENTRYPOINT ["/root/training/apache-tomcat-8.5.35/bin/catalina.sh","run"]    

        命令:FROM 指定基础镜像
              MAINTAINER 维护者的信息
              RUN 执行一条命令
              COPY 从宿主机上拷贝一个文件到镜像模板中
              ENV 设置环境变量
              ADD 添加一个URL的地址(下载文件)
              ENTRYPOINT 启动容器的时候,执行命令
              
        编译的命令:docker build -t mywebapp .
        启动容器:  docker run -d -p 8080:8080 mywebapp

三、Docker的容器(container)

1、容器的基本操作:创建容器、停止容器、进入容器、删除容器
                   导入和导出容器(迁移)、查看容器等等
                   
    (1)创建容器
            命令:run、create、start
            区别:run = create + start
    
            例子:docker create --name mycontainer1 centos
                无法通过docker ps命令来查看容器,因为容器没有运行
                  docker start [container id]
    (2)停止容器 docker stop
    (3)进入容器 docker exec -it 47ceba4e6e66 /bin/bash
                    参数  -i 保持标准输入打开
                          -t 分配一个伪终端
                          
    (4)删除容器: docker rm 47ceba4e6e66
    (5)导入和导出容器(迁移)
        注意:不管容器处于什么状态,都可以使用export导出操作
            docker export 
                docker export -o mywebapp.tar 47ceba4e6e66
                
            docker import 把导入的tar包变成一个镜像
                docker import mywebapp.tar mywebapp_imported


2、容器的日志
    (1)Docker引擎的日志:一般来说,由操作系统来维护
            Centos 7:journalctl -u docker
    
    (2)容器的日志:命令 docker logs [CONTAINER_ID]
            命令:docker logs -f -t --since="2018-12-01" --tail=20 47ceba4e6e66
                -f 查看实时日志,类似 tail -f
                -t 查看日志产生的日期
                --since 指定了输入日志的开始期(只输出指定日期后产生的日志)
                --tail   查看最后的20条日志

    
3、管理容器的资源
    (1)基础知识:Linux Control Groups
        (*)什么是Linux Control Groups?
                简单来说:以一组进程为目标进行系统资源的分配和控制。
                
        (*)功能
                限制资源的使用
                优先级的控制
                审计
                控制功能:挂起进程、恢复执行进程
                
        (*)查看Linux的内核中,是否启用了cgroup的功能
                uname -r
                cat /boot/config-3.10.0-693.el7.x86_64 |grep CGROUP
                
        (*)Demo1:限制进程(应用程序)对CPU的使用率
            开发一个c程序:死循环
            int main(void){
                int i=0;
                for(;;) i++;
                return 0;
            }
            
            使用gcc进行编译: yum install gcc
            gcc -o hello hello.c
            
            对应用程序的CPU的使用率进行限制:20%
            cd /sys/fs/cgroup/cpu
            mkdir my001
            cd my001
            
            查看cat cpu.cfs_quota_us
            -1  表示:没有任何的限制
            
            echo 20000 > cpu.cfs_quota_us
            把hello的进程号 ---> tasks中
            echo 6565 > tasks
            
            再启动一个hello程序
            两个hello程序总的CPU的使用:20%
        
        (*)Demo2:限制进程(应用程序)对内存的使用
            cd /sys/fs/cgroup/memory/my001 如果没有这个目录,创建这个目录
            查看cat memory.limit_in_bytes
            9223372036854771712  可以没有任何限制
            
            规定hello的应用程序最多只能使用64K的内存
            echo 64k > memory.limit_in_bytes
            
            把hello的进程号写到tasks
            echo 6633 > tasks
            
            如果6633(hello的应用程序)的内存使用超过64K,自动被kill
        
        (*)Demo3:限制进程(应用程序)对I/O使用
                安装工具:iotop 类似top命令 监视磁盘的IO的情况
                
            命令:dd if=/dev/sda of=/dev/null 不断访问磁盘
            使用iotop监视磁盘的IO的情况
            
            cd /sys/fs/cgroup/blkio/my001  如果没有这个目录,创建这个目录
            显示对磁盘的IO的访问:10M之内
            
            echo '8:0 10485760' > blkio.throttle.read_bps_device
            把进程号输出到tasks中(生效)
            echo 6671 > tasks
            
    (2)Docker对容器使用CPU的使用率:是相对权重
            准备实验的环境 Dockerfile
                FROM centos:latest
                RUN yum install -y epel-release && yum install -y stress
                ENTRYPOINT ["stress"]
            docker build -t centos001 .
            
            启动两个容器,分配CPU使用率的不同权重(相对)
            docker run -it centos001 --cpu 4     ----> 默认CPU使用率的权重:1024
            docker run -it -c 512 centos001 --cpu 4  ----->CPU使用率的权重:512
            
            通过命令:docker stats
                CONTAINER           CPU %              
                ecd45c19e72d        32.50%             
                3562d2c5a40f        66.21%             
    
    (3)Docker对容器使用的内存管理和限制
         默认:一个容器可以使用宿主机上所有的内存
         使用命令:docker run -m开关:使用内存的大小
         
         docker run -it -m 128m centos001 --cpu 4
         -m 指定容器的使用内存的上限
         
         通过docker stats查看
        CONTAINER           CPU %               MEM USAGE / LIMIT  
        1cb50eaff3f4        97.36%              192 KiB / 128 MiB  
            
    (4)Docker对容器使用I/O的管理和限制
            很多参数:参考PPT
            
        Demo1: --blkio-weight 参数(测试的时候,效果不是很理想)
                docker run -it --blkio-weight 100 centos /bin/bash
                docker run -it --blkio-weight 1000 centos /bin/bash
                
                在两个容器中,同时执行dd命令
                dd if=/dev/zero of=test.out bs=1M count=3000
                
        Demo2:--device-read-bps和--device-write-bps
                限制容器读入和写出的速率:1M(每秒)
                
                写入速率的上限:1M
                docker run -it --device-write-bps /dev/sda:1mb centos /bin/bash
                
                在容器内部:dd if=/dev/zero of=test.out bs=1M count=20 oflag=direct
                            oflag=direct表示:读写数据采用直接IO

                读取数据速率的上限:1M
                docker run -it --device-read-bps /dev/sda:1mb centos /bin/bash
                
        Demo3: --device-write-iops和--device-read-iops
                以写数据为例:容器write iops 是5/秒(次数)
                
                docker run -it --device-write-iops /dev/sda:5 centos /bin/bash
                
                在容器内部执行: dd if=/dev/zero of=test.out bs=1M count=200 oflag=direct
                
                使用命令观察: iostat 1 (安装:yum install sysstat)
                
                也能针对读,进行限制
                docker run -it --device-read-iops /dev/sda:5 centos /bin/bash
                
    
    

四、Docker网络和容器的通信

1、Docker网络通信的基本原理
    (1)Docker的网络接口是虚拟的接口
    (2)虚拟的网络接口的转发的效率高
    (3)宿主机的信息
        docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
                inet 172.17.0.1  netmask 255.255.0.0  broadcast 0.0.0.0
                inet6 fe80::42:52ff:fe4b:4e4c  prefixlen 64  scopeid 0x20<link>
                ether 02:42:52:4b:4e:4c  txqueuelen 0  (Ethernet)
                RX packets 8  bytes 536 (536.0 B)
                RX errors 0  dropped 0  overruns 0  frame 0
                TX packets 8  bytes 648 (648.0 B)
                TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        
    
        vethd1b406d: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
                inet6 fe80::78da:cfff:feef:44b5  prefixlen 64  scopeid 0x20<link>
                ether 7a:da:cf:ef:44:b5  txqueuelen 0  (Ethernet)
                RX packets 8  bytes 648 (648.0 B)
                RX errors 0  dropped 0  overruns 0  frame 0
                TX packets 16  bytes 1296 (1.2 KiB)
                TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
                
    (4)到容器内部查看网卡的信息
        eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
                inet 172.17.0.2  netmask 255.255.0.0  broadcast 0.0.0.0
                inet6 fe80::42:acff:fe11:2  prefixlen 64  scopeid 0x20<link>
                ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
                RX packets 1819  bytes 8445579 (8.0 MiB)
                RX errors 0  dropped 0  overruns 0  frame 0
                TX packets 1687  bytes 95886 (93.6 KiB)
                TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    (5)Docker创建容器的时候,会执行下面的操作
        (*)创建一对的虚拟的网络接口,一个放在本地的主机和新容器的各自的命名空间中
        (*)本地主机一端的虚拟的接口连接到默认的docker0的网桥上,取名:veth****
        (*)容器一端:把虚拟的网络接口放到新容器中,改名:eth0
        (*)从网桥(docker0)获取一个空闲的IP地址,分配给容器的eth0的网卡

2、Docker的网络模式:
    四种不同的网络模式:host、container、bridge(默认)、none
    命令:docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    845b88ede2ca        bridge              bridge              local
    74a262ef9181        host                host                local
    6bcd1c1ff2ea        none                null                local
    
    镜像:busybox集成了一百多个Linux的工具箱
    
    (*)host:容器不会虚拟出自己的网卡,直接使用宿主机的IP和端口
            docker run -it --network=host busybox /bin/sh
            信息:
            docker0   Link encap:Ethernet  HWaddr 02:42:52:4B:4E:4C  
                      inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
                      inet6 addr: fe80::42:52ff:fe4b:4e4c/64 Scope:Link
                      UP BROADCAST MULTICAST  MTU:1500  Metric:1
                      RX packets:1692 errors:0 dropped:0 overruns:0 frame:0
                      TX packets:1812 errors:0 dropped:0 overruns:0 carrier:0
                      collisions:0 txqueuelen:0 
                      RX bytes:72456 (70.7 KiB)  TX bytes:8444973 (8.0 MiB)                
    
    (*)container:容器不会虚拟出自己的网卡,和一个指定的容器共享IP和端口
            启动两个容器:第一个 docker run -it busybox /bin/sh   ---> 使用bridge的模式
                                 信息
                                eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
                                          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
                          
                          第二个 docker run -it --network=container:d8c0a1aa2673 busybox /bin/sh
                                 其中:d8c0a1aa2673是另一个容器的ID
                                eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
                                          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
    
    (*)bridge:默认的模式,会为每一个新创建的容器分配网络配置(IP等等)
    
    (*)none:关闭了容器的网络功能
                docker run -it --network=none busybox /bin/sh
                
                通过ifconfig,无法查看到eth0的信息


    自定义bridge的模式
        (1)创建自己的网络:bridge
             docker network create -d bridge --ip-range=192.168.78.0/24 --gateway=192.168.78.1 --subnet=192.168.78.0/24 bridge2
             
             查看网络模式的详情:docker network inspect 3e7b5641cbeb
             
        (2)创建自己的容器,使用自定义的网络模式(bridge2)
            docker run -it --network=bridge2 --ip=192.168.78.3 busybox
            docker run -it --network=bridge2 --ip=192.168.78.4 busybox

3、容器间的通信
    (1)IP通信
            docker run -it --network=bridge2 --ip=192.168.78.3 busybox
            docker run -it --network=bridge2 --ip=192.168.78.4 busybox    

            缺点:不够灵活
    
    (2)Docker DNS Server
        (*)版本:1.10以后
        (*)参数:--name
            docker run -it --network=bridge2 --name box1 busybox
            docker run -it --network=bridge2 --name box2 busybox
    
    (3)Joined容器:本质就是container网络模式
        (*)基于httpd的镜像创建容器
            docker run -it --name box3 httpd
            
        (*)使用Joined容器创建一个新的容器
            docker run -it --network=container:box3 busybox
            
        (*)测试:在第二个容器中执行wget 127.0.0.1

4、容器访问控制
    (1)容器访问外部网络
        (*)需要宿主机的转发
             docker run -it centos
             sysctl net.ipv4.ip_forward ---> 是1,开启了转发功能
                                          是0,没有开启转发
                                          
             通过下面方式开启
             sysctl -w net.ipv4.ip_forward=1
             
             更简单:启动docker服务的时候指定:  --ip-forward=true
    
    
    (2)外部访问容器网络:通过指定-p参数进行端口映射
            docker run -it -p 80:80 centos bash
            在宿主机上:iptables -nL查看

五、Docker的数据管理:数据的共享

1、Docker的数据卷(共享目录)
    (*)相当于mount操作
    (*)是一个可供容器使用的特殊的目录
    (*)实现主机操作系统与容器之间进行目录的映射
    (*)特性
        (1)数据卷可以在容器之间实现数据的共享和重用
        (2)对数据卷内数据的修改会立即生效
        (3)对数据卷的更新不会影响镜像
        (4)数据卷会一直存在,直到没有容器使用
        
    (*)Demo演示:在主机和容器之间创建数据卷,实现数据共享(共享目录)
            docker run -it -v /root/mydatavolume:/root/container/mydatavolume centos /bin/bash
            
            -v 指定数据卷的目录
            
        默认:挂载的数据卷默认权限是读写(RW),也可以通过指定ro参数标识为只读
            docker run -it -v /root/mydatavolume:/root/container/mydatavolume:ro centos /bin/bash
            
    (*)新版本的docker:使用命令: docker volume 命令管理数据卷
        docker volume create ----> 也可以创建数据卷
        
    (*)问题:Permission denied
          原因:Centos 7的安全模块selinux把权限给禁掉了
          (1)--privileged=true 加入到docker run中
          (2)临时关闭SeLinux: setenforce 0
    

2、Docker的数据卷容器
    (*)数据卷容器也是一个容器,目的:专门用来提供数据卷供其他的容器挂载
    (*)实现在多个容器之间数据数据的共享
    (*)Demo演示:创建数据卷容器
        (1)创建一个数据卷容器dbdatacontainer,在这个容器中创建一个数据卷挂载: /dbdata
                docker run -it -v /dbdata --name dbdatacontainer centos
    
        (2)可以在其他的容器中使用 --volumes-from来挂载dbdatacontainer容器中的数据卷
                docker run -it --volumes-from dbdatacontainer --name db1 centos
                docker run -it --volumes-from dbdatacontainer --name db2 centos
        

3、利用数据卷容器来实现数据的迁移:数据的备份和恢复
    (*)备份:使用下面的命令备份dbdatacontainer数据卷容器内的数据卷(tar包)
        docker run --volumes-from dbdatacontainer -v $(pwd):/backup --name myworker centos tar cvf /backup/backup.tar /dbdata
        
    (*)恢复:如果要将数据恢复到一个容器中
        (1)创建一个带有数据卷的容器
                docker run -it -v /dbdata --name dbdatacontainer2 centos
                
        (2)docker run -it --volumes-from dbdatacontainer2 -v $(pwd):/backup --name worker2 centos /bin/bash

六、Docker应用实战篇

1、Docker与数据库: MySQL
    (*)演示:在Docker容器中运行MySQL
        docker search mysql
        docker pull mysql
        docker run --name my_mysql_demo1 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=Welcome_1 -d mysql
    
    (*)数据库不适合运行在Docker容器中,为什么?
        (1)数据不安全
        (2)运行数据库的时候需要一些硬件环境的支持
        (3)网络的问题
        (4)Docker中打包的应用是无状态的应用

    
2、Docker与nginx
    (*)基于Ubuntu的系统,安装nginx,然后部署一个简单的web app
    (*)创建Dockerfile
    FROM ubuntu:14.04
    RUN apt-get update
    RUN apt-get install -y nginx
    RUN echo '<h1>Hello World and Nginx</h1>' > /usr/share/nginx/html/index.html
    EXPOSE 80
    ENTRYPOINT tail -f /dev/null
    
    使用docker build进行编译
    docker build -f file1 -t mynginx1 .
    
    启动容器:docker run -d -p 80:80 mynginx1
    手动启动nginx服务,进入容器,执行:/usr/sbin/nginx
    访问网页
    
3、Docker与PHP
    (*)需求:基于Centos,部署PHP的环境 ----> docker commit ---> 镜像
    (*)步骤:
        (1)注意:由于Centos 7存在一个bug,建议使用Centos 6
        (2)拉取Centos6
             docker pull centos:6
             
        (3)启动容器
             docker run -it -p 1234:80 0cbf37812bff /bin/bash

        (4)安装Apache(在容器中执行)
            yum install httpd
            chkconfig httpd on
            service httpd start
            
        (5)在容器中安装PHP
            yum install php
            yum install php-mysql php-gd php-imap php-ldap php-odbc php-pear php-xml php-xmlrpc
        
        (6)写一个简单的php    
            <?php
               phpinfo();                
            ?>
            注意:打开一些开关 (php.ini)
                ; short_open_tag
                ;   Default Value: On
                ;   Development Value: Off
                ;   Production Value: Off

            重启apache

        (7)docker commit ---> 镜像
                docker commit 7b4c8a58438f mycentos_php

4、Docker与Python
    (*)基于Centos
    (*)通过两种不同的方式
        (1)docker commit安装Python3的镜像
        (2)通过dockerfile安装Python3的运行环境
        
    参考提供的文档
    
5、Docker与Jupyter NootBook
    参考提供的文档

6、Docker与TensorFlow
    参考提供的文档
    from __future__ import print_function

    import tensorflow as tf

    with tf.Session():
        input1 = tf.constant([1.0, 2.0, 3.0, 4.0])
        input2 = tf.constant([2.0, 3.0, 4.0, 5.0])
        output = tf.add(input1, input2)
        result = output.eval()
        print("result: ", result)    

7、Docker与OpenStack的关系

(后续)Docker与大数据:Hadoop、Spark等等
    

七、搭建Harbor私有镜像仓库

1、什么是Harbor?
2、安装和配置Harbor
3、访问私有的镜像仓库Harbor

当前页面是本站的「Baidu MIP」版。发表评论请点击:完整版 »