zoukankan      html  css  js  c++  java
  • Docker基础学习

    Docker基础学习

    一、介绍

    • 简介

      • Docker出现前的现况

        • 开发-上线
          • 问题:两套环境(应用环境、应用配置)
        • 开发-运维
          • 版本更新导致服务不可用
          • 换台电脑就不可以运行了
        • 传统解决方式
          • 环境配置等由运维来做
      • 什么是Doceker?

        • 针对上述问题,Docker技术应运而生,实现了开发部署上线,一套流程搞定;

        • Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或[Windows 机器上,也可以实现虚拟化;

        • Docker容器是完全使用沙箱机制,相互之间不会有任何接口;

        • 一个完整的Docker有以下几个部分组成:

          • DockerClient客户端;
          • Docker Daemon守护进程;
          • Docker Image镜像;
          • DockerContainer容器;
        • img

          Docker发展史
    • 原理

      • Docker是如何工作的?

        • Docker是一个Client-Server结构的系统;
        • DockerClient的守护进程运行在主机上,通过socket从客户端访问;
        • DockersServer接收到DockerClient的指令,就会执行这个指令;
        • img
      • Docker比虚拟机快的原因

        • Docker比虚拟机抽象层少;

        • Docker利用的是宿主机的内核;

        • 新建一个容器,docker不需要像虚拟机一样重新加载一个操作系统内核,虚拟机加载的是Guest OS,分钟级别;Docker是利用宿主机的OS,秒级

        • img

        • img

          对比图
      • Docker指令结构图

        img

    • 相关网站

    二、安装

    • 卸载

      • # 停止运行
        systemctl stop docker
        
        # 卸载依赖
        yum -y remove docker-ce docker-ce-cli containerd.io
        
        # 删除资源
        rm -rf /var/lib/docker
        
    • 安装

      • # 安装所需的安装包
        sudo yum install -y yum-utils
        
        # 设置镜像的仓库(默认为国外,修改为阿里云的)
        sudo yum-config-manager 
            --add-repo 
            http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
            
        # 更新索引
        yum makecache fast
        
        #安装最新版本的Docker Engine和容器(ce社区,ee企业)
        sudo yum install docker-ce docker-ce-cli containerd.io
        
        # 启动Docker
        sudo systemctl start docker
        
        #通过运行hello-world 映像来验证是否正确安装了Docker Engine
        sudo docker run hello-world
        
        #查看docker版本
        docker version
        
      • docker的大部分默认工作路径

        • /var/lib/docker
    • 配置镜像加速

      • 登陆阿里云控制台首页,单击容器镜像服务

        image-20200910145657257

      • 执行一下命令image-20200910145919457

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

    三、基本命令

    • 帮助命令

      • # 显示docker版本信息
        docker version
        # 显示docker的系统信息(镜像和容器数量)
        docker info
        # 查看docker所有命令
        docker --help
        # 查看命令详情
        docker 命令 --help
        
      • 官网指令大全

    • 镜像命令

      • # 运行镜像
        sudo docker run imageName
        

        image-20200910145012360

        image-20200910161025703

        镜像运行流程
      • # 查看镜像
        docker images
        
        # 详细用法
        Usage:	docker images [OPTIONS] [REPOSITORY[:TAG]]
        
        List images
        
        Options:
          -a, --all             Show all images (default hides intermediate images)
              --digests         Show digests
          -f, --filter filter   Filter output based on conditions provided
              --format string   Pretty-print images using a Go template
              --no-trunc        Don't truncate output
          -q, --quiet           Only show numeric IDs
        

        image-20200910145128265

      • # 搜索镜像
        docker search searchContent
        
        # 详细用法
        Usage:	docker search [OPTIONS] TERM
        
        Search the Docker Hub for images
        
        Options:
          -f, --filter filter   Filter output based on conditions provided
              --format string   Pretty-print search using a Go template
              --limit int       Max number of search results (default 25)
              --no-trunc        Don't truncate output
        
      • # 下载镜像(若不写TAG版本号,默认latest)
        docker pull imageName
        
        # 详细用法
        Usage:	docker pull [OPTIONS] NAME[:TAG|@DIGEST]
        
        Pull an image or a repository from a registry
        
        Options:
          -a, --all-tags                Download all tagged images in the repository
              --disable-content-trust   Skip image verification (default true)
              --platform string         Set platform if server is multi-platform capable
          -q, --quiet                   Suppress verbose output
          
        # 实例测试
        [root@lazyr ~]# docker pull mysql
        Using default tag: latest #不写tag,默认latest
        latest: Pulling from library/mysql
        d121f8d1c412: Pull complete #分层下载(若不同版本有重复的文件,就不下载了)
        f3cebc0b4691: Pull complete 
        1862755a0b37: Pull complete 
        489b44f3dbb4: Pull complete 
        690874f836db: Pull complete 
        baa8be383ffb: Pull complete 
        55356608b4ac: Pull complete 
        dd35ceccb6eb: Pull complete 
        429b35712b19: Pull complete 
        162d8291095c: Pull complete 
        5e500ef7181b: Pull complete 
        af7528e958b6: Pull complete 
        Digest: sha256:e1bfe11693ed2052cb3b4e5fa356c65381129e87e38551c6cd6ec532ebe0e808 #签名
        Status: Downloaded newer image for mysql:latest
        docker.io/library/mysql:latest #真实地址
        
        # docker pull mysql =等价于= docker pull .io/library/mysql:latest
        

        版本号可以在docker官网里查询后填写

        image-20200910160443936

      • # 删除镜像
        docker rmi -f 镜像ID
        # 删除全部镜像
        docker rmi -f $(docker images -aq)
        
        
        # 详细用法
        Usage:	docker rmi [OPTIONS] IMAGE [IMAGE...]
        
        Remove one or more images
        
        Options:
          -f, --force      Force removal of the image
              --no-prune   Do not delete untagged parents
        
    • 容器命令

      • # 新建容器并启动
        docker run [opt] imageName/imageId
        
        # opt
         --name="containerName"	容器名字,用来区分容器
         -d						后台方式运行
         -it					使用交互方式运行,可以进入容器内查看内容
         -p						指定容器端口号
         	-p ip:主机端口:容器端口		指定ip地址,和容器端口对应主机端口的映射
         	-p 主机端口:容器端口		指定容器端口对应主机端口的映射
         	-p 容器端口
         -P						随机指定端口号
        
        # 实例测试
        # 启动并进入容器
        [root@lazyr ~]# docker run -it centos /bin/bash
        # @635911d7e995:容器id
        [root@635911d7e995 /]# ls
        bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
        # 关闭并退出容器
        [root@635911d7e995 /]# exit
        exit
        
      • # 查看容器
        docker ps [opt]
        # opt
        空		   列出正在运行的容器
        -a		 	列出所有容器	
        -n=num	 	列出最近创建的num个容器
        -q			只列出容器id
        
      • # 退出容器
        # 关闭且退出容器
        exit
        # 不关闭,只退出容器
        ctrl+P+Q
        
      • # 删除容器
        # 删除指定容器(无法删除正在运行的容器)
        docker rm 容器id
        # 强制删除指定容器(可以删除正在运行的容器)
        docker rm -f $(docker ps -aq)
        # 删除所有容器
        docker rm -f $(docker ps -aq)
        docker ps -a -q|xargs docker rm
        
      • # 启动容器
        docker start 容器ID
        
      • # 重启容器
        docker restart 容器ID
        
      • # 停止正在运行的容器
        docker stop 容器ID
        
      • # 强制停止正在运行的容器
        docker kill 容器ID
        
    • 常见命令

      • # 查看日志
        docker logs -f -t --details 容器id
        
        # 详细用法
        Usage:	docker logs [OPTIONS] CONTAINER
        
        Fetch the logs of a container
        
        Options:
              --details        Show extra details provided to logs
          -f, --follow         Follow log output
              --since string   Show logs since timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
              --tail string    Number of lines to show from the end of the logs (default "all")
          -t, --timestamps     Show timestamps
              --until string   Show logs before a timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
        
      • # 查看容器中进程信息
        docker top 容器id
        
      • # 查看镜像的元数据
        docker inspect
        
        # 详细用法
        Usage:	docker inspect [OPTIONS] NAME|ID [NAME|ID...]
        
        Return low-level information on Docker objects
        
        Options:
          -f, --format string   Format the output using the given Go template
          -s, --size            Display total file sizes if the type is container
              --type string     Return JSON for specified type
              
        # 实例测试
        # 查看centos容器信息
        [root@lazyr ~]# docker inspect c5500d0e92cd
        [
            {
         		# 容器id为该id的前缀缩写
                "Id": "c5500d0e92cddb3e6eb65a9ba1777e020eb29f6902ceeb8c2f039e7abba07518",
                "Created": "2020-09-10T08:49:05.484098663Z",
                "Path": "/bin/bash",
                "Args": [],
                "State": {
                    "Status": "exited",
                    "Running": false,
                    "Paused": false,
                    "Restarting": false,
                    "OOMKilled": false,
                    "Dead": false,
                    "Pid": 0,
                    "ExitCode": 0,
                    "Error": "",
                    "StartedAt": "2020-09-10T08:49:05.859357989Z",
                    "FinishedAt": "2020-09-10T08:49:05.857222556Z"
                },
        		# 忽略了其余部分.....
            }
        ]
        
      • # 进入正在运行的容器
        # 进入容器后,开启一个新的终端
        docker exec -it 容器id /bin/bash
        # 进入容器正在执行的终端
        docker attach 容器id
        
      • # 从容器内拷贝文件到主机上
        docker cp 容器id:容器内路径 目的主机路径
        
    • 部署Nginx(练习)

      • 搜索镜像信息

        image-20200910182330960

      • 下载镜像

        [root@lazyr ~]# docker pull nginx
        Using default tag: latest
        latest: Pulling from library/nginx
        bf5952930446: Pull complete 
        cb9a6de05e5a: Pull complete 
        9513ea0afb93: Pull complete 
        b49ea07d2e93: Pull complete 
        a5e4a503d449: Pull complete 
        Digest: sha256:2850bbf7ed1bcb88e50c08c424c13fec71cf0a0bf0d496b5481601c69f905534
        Status: Downloaded newer image for nginx:latest
        docker.io/library/nginx:latest
        
      • 查看镜像

        [root@lazyr ~]# docker images
        REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
        mysql               latest              e1d7dc9731da        4 hours ago         544MB
        nginx               latest              4bb46517cac3        3 weeks ago         133MB
        centos              latest              0d120b6ccaa8        4 weeks ago         215MB
        hello-world         latest              bf756fb1ae65        8 months ago        13.3kB
        
      • 新建并运行Nginx容器

        [root@lazyr ~]# docker run -d --name nginxTest -p 3344:80 nginx
        c2d8256def4228b4781b5e9ba3fda2887264d0d14ee92b2c7a5788c8957f7c77
        
      • 查看容器运行状态

        [root@lazyr ~]# docker ps
        CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
        c2d8256def42        nginx               "/docker-entrypoint.…"   42 seconds ago      Up 41 seconds       0.0.0.0:3344->80/tcp   nginxTest
        
      • 测试连接

        [root@lazyr ~]# curl localhost:33344
        <!DOCTYPE html>
        <html>
        <head>
        <title>Welcome to nginx!</title>
        <style>
            body {
                 35em;
                margin: 0 auto;
                font-family: Tahoma, Verdana, Arial, sans-serif;
            }
        </style>
        </head>
        <body>
        <h1>Welcome to nginx!</h1>
        <p>If you see this page, the nginx web server is successfully installed and
        working. Further configuration is required.</p>
        
        <p>For online documentation and support please refer to
        <a href="http://nginx.org/">nginx.org</a>.<br/>
        Commercial support is available at
        <a href="http://nginx.com/">nginx.com</a>.</p>
        
        <p><em>Thank you for using nginx.</em></p>
        </body>
        </html>
        
      • 网站访问

        image-20200910184247391

      • 访问流程原理

        image-20200910184027332

      • 问题

        • 我们现在若想修改nginx配置文件,必须进入容器内部,而容器内部有很多指令等因素不方便修改,怎么解决?
        • 采用数据卷技术解决上述问题
    • 部署Tomcat(练习)

      • 搜索镜像信息

        image-20200910185035540

      • 下载tomcat

        [root@lazyr ~]# docker pull tomcat:9.0
        9.0: Pulling from library/tomcat
        d6ff36c9ec48: Pull complete 
        c958d65b3090: Pull complete 
        edaf0a6b092f: Pull complete 
        80931cf68816: Pull complete 
        bf04b6bbed0c: Pull complete 
        8bf847804f9e: Pull complete 
        6bf89641a7f2: Pull complete 
        3e97fae54404: Pull complete 
        10dee6830d45: Pull complete 
        680b26b7a444: Pull complete 
        Digest: sha256:cbdcddc4ca9b47e42c7d0c2db78cbc0f7a8b4bbe1fa395f4a53c5a236db29146
        Status: Downloaded newer image for tomcat:9.0
        docker.io/library/tomcat:9.0
        
      • 新建并运行Tomcat容器

        [root@lazyr ~]# docker run -d --name tomcatTest -p 3355:8080 tomcat:9.0
        1318076a80396de946f1a39af203aa09ad6a6ad96931bcc54e976ee7f1a07262
        
      • 查看容器运行状态

        [root@lazyr ~]# docker ps
        CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
        1318076a8039        tomcat:9.0          "catalina.sh run"   59 seconds ago      Up 58 seconds       0.0.0.0:3355->8080/tcp   tomcatTest
        
      • 测试连接

        [root@lazyr ~]# curl localhost:3355
        <!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 404 – Not Found</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p><hr class="line" /><h3>Apache Tomcat/9.0.37</h3></body></html>
        
      • 网站访问(404是因为官方的Tomcat是不完整的)

        image-20200910185827502

      • 进入容器内查看

        [root@lazyr ~]# docker exec -it tomcatTest /bin/bash
        root@1318076a8039:/usr/local/tomcat# ls
        BUILDING.txt  CONTRIBUTING.md  LICENSE	NOTICE	README.md  RELEASE-NOTES  RUNNING.txt  bin  conf  lib  logs  native-jni-lib  temp  webapps  webapps.dist  work
        root@1318076a8039:/usr/local/tomcat# cd /usr/local/tomcat/webapps
        root@1318076a8039:/usr/local/tomcat/webapps# ls
        # webapps文件夹内为空,所以访问时显示404
        root@1318076a8039:/usr/local/tomcat/webapps# 
        
    • 常用问题

      • 后台启动程序问题

        • 描述:使用docker run -d centos新建并启动容器之后,使用docker ps命令发现并没有在运行

          image-20200910165259571

        • 原因:docker容器使用后台运行时,必须要有一个前台进程,若docker发现没有前台应用,就会自动停止(nginx容器启动后,发现自己没有提供服务,就会立刻停止)

    四、Portainer

    • 介绍

      • 什么式Portainer?
        • Docker图形化界面管理工具,提供了一个后台面板供我们操作
    • 使用

      • docker run -d -p 8088:9000 
        --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
        
      • 访问http://119.23.231.254:8088/

        image-20200910191044271

    五、Docker镜像

    • 加载原理

      • UnionFS(联合文件系统)

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

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

        • img

          UnionFS结构图
      • BootFS

        • boots(boot file system)主要包含 bootloader和 Kernel, bootloader主要是引导加 kernel;
        • Linux刚启动时会加bootfs文件系统,在 Docker镜像的最底层是 boots;
        • 这一层与我们典型的Linux/Unix系统是一样的,包含boot加載器和内核;
        • 当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs转交给内核,此时系统也会卸载bootfs。
      • RootFS

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

    六、提交镜像

    • 命令

      • # 提交容器为一个新的镜像
        docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]
        
    • 提交自定义Tomcat镜像(练习)

      • 新建运行Tomcat容器,并进入该容器内

        [root@lazyr ~]# docker run -d --name mytomcat -p 3366:8080 tomcat:9.0
        954b95fcfcab595b30bbb341e2530ead0a6b6d1964e77a9c77012324565d0fa0
        [root@lazyr ~]# docker ps
        CONTAINER ID        IMAGE                 COMMAND             CREATED              STATUS              PORTS                    NAMES
        954b95fcfcab        tomcat:9.0            "catalina.sh run"   About a minute ago   Up About a minute   0.0.0.0:3366->8080/tcp   mytomcat
        224761104e96        portainer/portainer   "/portainer"        47 minutes ago       Up 47 minutes       0.0.0.0:8088->9000/tcp   determined_mahavira
        [root@lazyr ~]# docker exec -it 954b95fcfcab /bin/bash
        root@954b95fcfcab:/usr/local/tomcat# 
        
      • 往webapps内移入初始文件

        root@954b95fcfcab:/usr/local/tomcat# cp -r webapps.dist/* webapps
        root@954b95fcfcab:/usr/local/tomcat# cd webapps
        root@954b95fcfcab:/usr/local/tomcat/webapps# ls
        ROOT  docs  examples  host-manager  manager
        
      • 访问网站(显示正常)

        image-20200910200000171

      • ctrl+P+Q退出后,将容器提交为镜像

        [root@lazyr ~]# docker commit -a="Lazyr" -m="add some files to the folder named webapps" 954b95fcfcab mytomcat:1.0
        sha256:8ea04e5e29cf0cbce633355cbf1fc8766f40b0f762a604bad949b4406acb3c67
        [root@lazyr ~]# docker images
        REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
        mytomcat              1.0                 8ea04e5e29cf        13 seconds ago      652MB
        mysql                 latest              e1d7dc9731da        5 hours ago         544MB
        tomcat                9.0                 d5eef28cf41d        8 days ago          647MB
        tomcat                latest              d5eef28cf41d        8 days ago          647MB
        nginx                 latest              4bb46517cac3        3 weeks ago         133MB
        centos                latest              0d120b6ccaa8        4 weeks ago         215MB
        portainer/portainer   latest              62771b0b9b09        7 weeks ago         79.1MB
        hello-world           latest              bf756fb1ae65        8 months ago        13.3kB
        
        

    八、容器数据卷

    • 介绍

      • 什么是容器数据卷?

        • 我们将应用和环境打包成一个镜像,镜像运行时生成的数据应该存放在什么位置?

        • 若放在容器内,容器一被删除,数据就全丢失了,并且每次修改数据都得进入容器内部才可以修改,若可以容器中产生的数据可以自动同步到本地就好了;

        • 容器数据卷就是完成了将容器内的目录,挂载到Linux上面,实现本地和容器内数据同步

          image-20200912141215553
    • 使用

      • 指定位置挂载

        # -v 主机目录(绝对路径):容器内目录
        docker run -it -v 主机目录:容器内目录 镜像名/镜像id /bin/bash
        # 挂载多个目录
        docker run -it -v 主机目录:容器内目录 -v 主机目录:容器内目录 镜像名/镜像id /bin/bash
        
        # 实例测试
        # 挂载前本机home目录结构
        [root@lazyr home]# ls
        lazyr  wjr  www
        # 挂载
        [root@lazyr home]# docker run -it -v /home/test:/home centos /bin/bash
        # 挂载后本机home目录结构
        [root@lazyr home]# ls
        lazyr  test  wjr  www
        # 在本机修改test目录内容
        [root@lazyr home]# cd test/
        [root@lazyr test]# vim hello.txt
        [root@lazyr test]# ls
        hello.txt
        # 进入容器内查看/home目录
        [root@lazyr test]# docker exec -it bd1de60a2007 /bin/bash
        [root@bd1de60a2007 /]# ls
        bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
        [root@bd1de60a2007 /]# cd home
        [root@bd1de60a2007 home]# ls
        hello.txt
        
        # ctrl+P+Q退出容器,查看容器信息
        [root@lazyr test]# docker inspect bd1de60a2007
        [
           	# 忽略...
                "Mounts": [
                    {
                        "Type": "bind",
                        # Linux挂载的目录
                        "Source": "/home/test",
                        # 容器内挂载的目录 
                        "Destination": "/home",
                        "Mode": "",
                        "RW": true,
                        "Propagation": "rprivate"
                    }
                ]
        	# 忽略....
            
        ]
        
        # 删除容器后查看本地挂载的文件夹
        [root@lazyr test]# docker rm bd1de60a2007
        bd1de60a2007
        [root@lazyr test]# ls
        hello.txt                                                                     
        
      • 匿名挂载(在默认位置随机创建挂载目录)

        # -v 容器内目录
        # 本地挂载目录(/var/lib/docker/volumes)
        docker run -d -v 卷名:容器内目录 镜像名/镜像id
        
        # 实例测试
        [root@lazyr data]# docker run -d -v /home centos
        02f09ab52e02e14bc79a5407e670d2163496cade21a9fd708e6c2ae628ad8dc2
        # 查看卷名
        [root@lazyr data]# docker volume ls
        DRIVER              VOLUME NAME
        local               5e0ebc9242c84b8f0ad985721bd8d8c5dddf3e1692f77682dcb302049f984eb6
        local               f4ec2f78f12864e3b6a560c9e20d563604375ed4ee8f092ca3ab42e0c6a07038
        # 进入本地匿名挂载目录
        [root@lazyr data]# cd /var/lib/docker
        [root@lazyr docker]# ls
        builder  buildkit  containers  image  network  overlay2  plugins  runtimes  swarm  tmp  trust  volumes
        [root@lazyr docker]# cd volumes/
        [root@lazyr volumes]# ls
        5e0ebc9242c84b8f0ad985721bd8d8c5dddf3e1692f77682dcb302049f984eb6  f4ec2f78f12864e3b6a560c9e20d563604375ed4ee8f092ca3ab42e0c6a07038  metadata.db
        
      • 具名挂载(在默认位置创建指定名的挂载目录)

        # -v 卷名:容器内目录
        # 本地挂载目录(/var/lib/docker/volumes)
        docker run -it -v 卷名:容器内目录 镜像名/镜像id /bin/bash
        
        # 实例测试
        [root@lazyr volumes]# docker run -d -v centosVolume:/home centos
        a8144eaaf2d0363945a046fb5581629b4ff1e414f39950c915dc2c1433d33975
        # 查看卷名
        [root@lazyr volumes]# docker volume ls
        DRIVER              VOLUME NAME
        local               5e0ebc9242c84b8f0ad985721bd8d8c5dddf3e1692f77682dcb302049f984eb6
        local               centosVolume
        local               f4ec2f78f12864e3b6a560c9e20d563604375ed4ee8f092ca3ab42e0c6a07038
        # 进入本地匿名挂载目录
        [root@lazyr volumes]# cd /var/lib/docker/volumes/
        [root@lazyr volumes]# ls
        5e0ebc9242c84b8f0ad985721bd8d8c5dddf3e1692f77682dcb302049f984eb6  centosVolume  f4ec2f78f12864e3b6a560c9e20d563604375ed4ee8f092ca3ab42e0c6a07038  metadata.db
        
      • 添加权限

        # -v 卷名:容器内路径:ro/rw
        # ro : readOnly,只读,只能通过宿主机写入,容器内部无法写入 
        # rw : readWrite,读写
        # 匿名挂载使用会报错
        
        # 实例测试
        [root@lazyr volumes]# docker run -d -v centosRO:/home:ro centos
        8fc4c5d9fdfd1c798a19a52c29b6f645994031a174140114cee74cc98eca6481
        
    • 相关指令

      • # 查看所有的卷
        docker volume ls
        
        # 详细用法
        Usage:	docker volume COMMAND
        
        Manage volumes
        
        Commands:
          create      Create a volume
          inspect     Display detailed information on one or more volumes
          ls          List volumes
          prune       Remove all unused local volumes
          rm          Remove one or more volumes
          
        # 实例测试
        [root@lazyr data]# docker volume ls
        DRIVER              VOLUME NAME
        local               f4ec2f78f12864e3b6a560c9e20d563604375ed4ee8f092ca3ab42e0c6a07038
        
        
    • Mysql同步本地数据

      • 下载Mysql数据库

        [root@lazyr ~]# docker pull mysql:5.7
        5.7: Pulling from library/mysql
        d121f8d1c412: Already exists 
        f3cebc0b4691: Already exists 
        1862755a0b37: Already exists 
        489b44f3dbb4: Already exists 
        690874f836db: Already exists 
        baa8be383ffb: Already exists 
        55356608b4ac: Already exists 
        277d8f888368: Pull complete 
        21f2da6feb67: Pull complete 
        2c98f818bcb9: Pull complete 
        031b0a770162: Pull complete 
        Digest: sha256:14fd47ec8724954b63d1a236d2299b8da25c9bbb8eacc739bb88038d82da4919
        Status: Downloaded newer image for mysql:5.7
        docker.io/library/mysql:5.7
        
      • 新建并运行容器,同时挂载目录到本机(运行语句在官网里找)

        [root@lazyr ~]# docker run -d -p 3310:3306 -v /var/mysql/conf:/etc/mysql/conf.d -v /var/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=wjr135792468 mysql:5.7
        201fa4875eecbdf26c3be3ce5af25a6076160a43ea2c5fba9f3d2751508db7dc
        
        image-20200911143548615
      • 本地数据库连接

        image-20200911144020243 image-20200911144020243
      • 在本地创建新数据库

        image-20200911144339490
      • 查看Linux服务器挂载的目录

        image-20200911144731499

    九、数据卷容器

    • 介绍

      • 什么是数据卷容器?
        • 容器数据卷解决了容器和主机间数据同步的问题,那不同容器之间数据如何同步呢?
        • 数据卷容器解决了不同容器间的数据同步问题,且只有若多个容器数据都同时删除,容器内的数据才会删除(没挂载到本地时;挂载到本地时,所有容器都删除,本地数据也在)
        • image-20200912142229688
    • 指令

      • # --volumes-from
        docker run -d --volumes-from fahterContainerName/fahterContainerId imageName/imageID
        
    • 使用

      • 只有父容器挂载了文件,子容器才可以同步数据

      • 创建父容器(父容器必须挂载目录)

        image-20200912154206610

      • 创建子容器

        image-20200912154519298

      • 查看父容器的数据变化

        image-20200912154617909

    十、Dockerfile

    • 介绍

      • 什么是Dockerfile?
        • Dockerfile就是用来构建docker镜像的文件,命令脚本;
        • 通过Dockerfile这个脚本可以生成镜像。
    • 初体验

      • 创建dockerfile文件(文件名建议dockerfile

        [root@lazyr test]# pwd
        /home/test
        [root@lazyr test]# vim dockerfile1
        
      • dockerfile文件内容(指令大写

        FROM centos
        
        VOLUME ["mountedVolume01","mountedVolume02"]
        
        CMD echo "----end-----"
        CMD /bin/bash
        
      • 通过dockerfile构建镜像

        [root@lazyr test]# docker build -f dockerfile1 -t lazyrcentos:1.0 .
        Sending build context to Docker daemon  3.072kB
        # 分步执行dockerfile中的命令
        # 从哪个基础镜像生成
        Step 1/4 : FROM centos
         ---> 0d120b6ccaa8
        # 挂载的目录
        Step 2/4 : VOLUME ["mountedVolume01","mountedVolume02"]
         ---> Running in 8eea57e19489
        Removing intermediate container 8eea57e19489
         ---> dc69ae084b62
        Step 3/4 : CMD echo "----end-----"
         ---> Running in 689ffb5e4afd
        Removing intermediate container 689ffb5e4afd
         ---> 4da7979ae660
        # 进入容器内
        Step 4/4 : CMD /bin/bash
         ---> Running in 1a9a8cd42f7c
        Removing intermediate container 1a9a8cd42f7c
         ---> d88c4fb5e551
        Successfully built d88c4fb5e551
        Successfully tagged lazyrcentos:1.0
        
      • 查看构建的镜像

        [root@lazyr test]# docker images
        REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
        lazyrcentos           1.0                 d88c4fb5e551        36 seconds ago      215MB
        mytomcat              1.0                 8ea04e5e29cf        20 hours ago        652MB
        mysql                 5.7                 ef08065b0a30        25 hours ago        448MB
        
      • 运行构建的镜像

        image-20200911160428226
      • 查看容器详细信息

        [root@lazyr test]# docker inspect 76d75a193882
        [
        		# 忽略...
                "Mounts": [
                    {
                        "Type": "volume",
                        "Name": "df4413202054c82534c30d2e871077a572d50a9a50c89216767104c4ddef43b7",
                        # 容器外的目录
                        "Source": "/var/lib/docker/volumes/df4413202054c82534c30d2e871077a572d50a9a50c89216767104c4ddef43b7/_data",
                        # 容器内的目录
                        "Destination": "mountedVolume01",
                        "Driver": "local",
                        "Mode": "",
                        "RW": true,
                        "Propagation": ""
                    },
                    {
                        "Type": "volume",
                        "Name": "80d66cead979064cce5cf55d974f1e6a30fa222aacdc9b6520eddc3c9dfa32bd",
                        # 容器外的目录
                        "Source": "/var/lib/docker/volumes/80d66cead979064cce5cf55d974f1e6a30fa222aacdc9b6520eddc3c9dfa32bd/_data",
                        # 容器内的目录
                        "Destination": "mountedVolume02",
                        "Driver": "local",
                        "Mode": "",
                        "RW": true,
                        "Propagation": ""
                    }
                ],
                # 忽略...
        ]
        
    • 语法

      • 基础知识

        • 每个保留关键字(指令)都必须大写;
        • 执行按从上到下顺序执行;
        • 表示注释;

        • 每一个指令都会创建提交一个新的镜像层
        • dockerfile是面向开发的,我们以后要发布项目,做镜像,需要编写dockerfile文件;
        • dockerfile文件名最好统一为Dockerfile,这样构建时就不需要-f指定文件,系统会默认使用名为Dockerfile的文件;
        • image-20200516131756997
      • 指令 作用
        FROM 设置镜像使用的基础镜像
        MAINTAINER 设置镜像的作者(姓名<邮箱>)
        RUN 编译镜像时运行的脚本
        LABEL 设置镜像的标签
        EXPOESE 设置镜像暴露的端口
        ENV 设置容器的环境变量
        ADD 编译镜像时复制文件到镜像中,会自动解压
        COPY 编译镜像时复制文件到镜像中,不会解压,单纯的复制
        CMD 指定容器启动的时候要运行的命令,替换指令
        ENTRYPOINT 指定容器启动的时候要运行的命令,追加参数
        VOLUME 设置容器的挂载卷
        USER 设置运行RUN CMD ENTRYPOINT的用户名
        WORKDIR 设置RUN CMD ENTRYPOINT COPY ADD指令的工作目录
        ARG 设置编译镜像时加入的参数
        ONBUILD 当构建一个被继承的DockerFile,这时候就会运行ONBUILD指令
        STOPSIGNAL 设置容器的退出信号量
    • 指令

      • # 构建镜像
        # 最后的.表示指定dockerfile路径为当前目录
        docker build -f dockerfilePath -t imageName:TAG .
        
      • # 查看镜像构造历史
        docker history imageName/imageId
        
        # 实例测试
        [root@lazyr test]# docker history lazyrcentos:1.0
        IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
        d88c4fb5e551        25 hours ago        /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "/bin…   0B                  
        4da7979ae660        25 hours ago        /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B                  
        dc69ae084b62        25 hours ago        /bin/sh -c #(nop)  VOLUME [mountedVolume01 m…   0B                  
        0d120b6ccaa8        4 weeks ago         /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B                  
        <missing>           4 weeks ago         /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B                  
        <missing>           4 weeks ago         /bin/sh -c #(nop) ADD file:538afc0c5c964ce0d…   215MB  
        
    • 进阶实战

      • 编写dockerfile文件

        FROM centos
        MAINTAINER lazyr<2296339656@qq.com>
        
        # 环境变量
        ENV MYPATH /usr/local
        WORKDIR $MYPATH
        
        
        # 开启端口
        EXPOSE 80
        
        
        CMD echo $MYPATH
        CMD echo "---end---"
        CMD /bin/bash
        
      • 通过dockerfile构建镜像

        [root@lazyr test]# docker build -f dockerfile -t wjrcentos:1.0 .
        
    • CMD与ENTRYPOINT


      • 测试CMD

      • 创建dockerfile文件

        FROM centos
        CMD ["ls","-a"]
        
      • 构建镜像

        [root@lazyr test]# docker build -f dockerfile -t cmd-test .
        Sending build context to Docker daemon  3.072kB
        Step 1/2 : FROM centos
         ---> 0d120b6ccaa8
        Step 2/2 : CMD ["ls","-a"]
         ---> Running in 3e76b0572d98
        Removing intermediate container 3e76b0572d98
         ---> b5717f92ff23
        Successfully built b5717f92ff23
        Successfully tagged cmd-test:latest
        
      • 运行镜像

        [root@lazyr test]# docker run cmd-test
        # 自动执行ls -a
        .
        ..
        .dockerenv
        bin
        dev
        etc
        home
        lib
        # ...
        
      • 运行镜像并追加参数

        [root@lazyr test]# docker run cmd-test -l
        # 此时执行的指令的并不是ls -al,而是-l。-l替换了之前ls -a指令
        docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: "-l": executable file not found in $PATH": unknown.
        

      • 测试ENTRYPOINT

      • 创建dockerfile文件

        FROM centos
        ENTRYPOINT ["ls","-a"]
        
      • 构建镜像

        [root@lazyr test]# docker build -f dockerfile -t entrypoint-test .
        Sending build context to Docker daemon  3.072kB
        Step 1/2 : FROM centos
         ---> 0d120b6ccaa8
        Step 2/2 : ENTRYPOINT ["ls","-a"]
         ---> Running in 66b4da10fcb3
        Removing intermediate container 66b4da10fcb3
         ---> a59c0931215c
        Successfully built a59c0931215c
        Successfully tagged entrypoint-test:latest
        
      • 运行镜像

        [root@lazyr test]# docker run entrypoint-test 
        # 自动执行ls -a
        .
        ..
        .dockerenv
        bin
        dev
        etc
        home
        lib
        # ...
        
      • 运行镜像并追加参数

        [root@lazyr test]# docker run entrypoint-test -l
        # 相当于执行ls -al,自动在ls -a后追加参数
        total 56
        drwxr-xr-x   1 root root 4096 Sep 12 09:07 .
        drwxr-xr-x   1 root root 4096 Sep 12 09:07 ..
        -rwxr-xr-x   1 root root    0 Sep 12 09:07 .dockerenv
        lrwxrwxrwx   1 root root    7 May 11  2019 bin -> usr/bin
        drwxr-xr-x   5 root root  340 Sep 12 09:07 dev
        drwxr-xr-x   1 root root 4096 Sep 12 09:07 etc
        drwxr-xr-x   2 root root 4096 May 11  2019 home
        lrwxrwxrwx   1 root root    7 May 11  2019 lib -> usr/lib
        # ....
        
    • 构建Tomcat镜像

      • 准备初始文件

        [root@lazyr myTomcat]# pwd
        /home/wjr/myTomcat
        [root@lazyr myTomcat]# ls
        # 准备tomcat、jdk压缩包和readMe.txt
        apache-tomcat-9.0.36.tar.gz  jdk-8u251-linux-x64.tar.gz  readMe.txt
        
      • 编写dockrfile文件

        FROM centos
        MAINTAINER lazyr<2296339656@qq.com>
        # 复制readMe.txt文件到镜像内,这里使用相对路径(也可以使用绝对路径)
        COPY readMe.txt /usr/local/readMe.txt
        
        # ADD命令会自动解压,将jdk、tomcat添加到镜像内,这里使用相对路径(也可以使用绝对路径)
        ADD jdk-8u251-linux-x64.tar.gz /usr/local/
        ADD apache-tomcat-9.0.36.tar.gz /usr/local/
        
        # 安装vim
        RUN yum -y install vim
        
        # 设置进入容器内时的默认路径
        ENV MYPATH /usr/local
        WORKDIR $MYPATH
        
        # 配置环境变量
        ENV JAVA_HOME /usr/local/jdk1.8.0_251
        ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
        ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.36
        ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.36
        ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
        
        EXPOSE 8080
        
        # 命令可通过&&追加
        CMD /usr/local/apache-tomcat-9.0.36/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.36/bin/logs/catalina.out
        
      • 构建镜像

        # 不写-f,系统会自动在当前目录下寻找名为Dockerfile的文件
        [root@lazyr myTomcat]# docker build -t mytomcat:1.0 .
        Sending build context to Docker daemon  206.3MB
        Step 1/15 : FROM centos
         ---> 0d120b6ccaa8
        Step 2/15 : MAINTAINER lazyr<2296339656@qq.com>
         ---> Running in 89805720d237
        Removing intermediate container 89805720d237
         ---> bae5bf13892d
        Step 3/15 : COPY readMe.txt /usr/local/readMe.txt
         ---> 6e7aadcff317
        Step 4/15 : ADD jdk-8u251-linux-x64.tar.gz /usr/local/
         ---> 95647b2a70fa
        Step 5/15 : ADD apache-tomcat-9.0.36.tar.gz /usr/local/
         ---> 69dbc30d7d7d
        Step 6/15 : RUN yum -y install vim
         ---> Running in 48de8ec2599f
        CentOS-8 - AppStream                            1.0 MB/s | 5.8 MB     00:05    
        CentOS-8 - Base                                 1.1 MB/s | 2.2 MB     00:01    
        CentOS-8 - Extras                               2.7 kB/s | 7.9 kB     00:02    
        Dependencies resolved.
        ================================================================================
         Package             Arch        Version                   Repository      Size
        ================================================================================
        Installing:
         vim-enhanced        x86_64      2:8.0.1763-13.el8         AppStream      1.4 M
        Installing dependencies:
         gpm-libs            x86_64      1.20.7-15.el8             AppStream       39 k
         vim-common          x86_64      2:8.0.1763-13.el8         AppStream      6.3 M
         vim-filesystem      noarch      2:8.0.1763-13.el8         AppStream       48 k
         which               x86_64      2.21-12.el8               BaseOS          49 k
        
        Transaction Summary
        ================================================================================
        Install  5 Packages
        
        Total download size: 7.8 M
        Installed size: 31 M
        Downloading Packages:
        (1/5): gpm-libs-1.20.7-15.el8.x86_64.rpm        246 kB/s |  39 kB     00:00    
        (2/5): vim-filesystem-8.0.1763-13.el8.noarch.rp 624 kB/s |  48 kB     00:00    
        (3/5): which-2.21-12.el8.x86_64.rpm             183 kB/s |  49 kB     00:00    
        (4/5): vim-enhanced-8.0.1763-13.el8.x86_64.rpm  1.5 MB/s | 1.4 MB     00:00    
        (5/5): vim-common-8.0.1763-13.el8.x86_64.rpm    1.6 MB/s | 6.3 MB     00:03    
        --------------------------------------------------------------------------------
        Total                                           1.1 MB/s | 7.8 MB     00:07     
        warning: /var/cache/dnf/AppStream-02e86d1c976ab532/packages/gpm-libs-1.20.7-15.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
        CentOS-8 - AppStream                            164 kB/s | 1.6 kB     00:00    
        Importing GPG key 0x8483C65D:
         Userid     : "CentOS (CentOS Official Signing Key) <security@centos.org>"
         Fingerprint: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65D
         From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
        Key imported successfully
        Running transaction check
        Transaction check succeeded.
        Running transaction test
        Transaction test succeeded.
        Running transaction
          Preparing        :                                                        1/1 
          Installing       : which-2.21-12.el8.x86_64                               1/5 
          Installing       : vim-filesystem-2:8.0.1763-13.el8.noarch                2/5 
          Installing       : vim-common-2:8.0.1763-13.el8.x86_64                    3/5 
          Installing       : gpm-libs-1.20.7-15.el8.x86_64                          4/5 
          Running scriptlet: gpm-libs-1.20.7-15.el8.x86_64                          4/5 
          Installing       : vim-enhanced-2:8.0.1763-13.el8.x86_64                  5/5 
          Running scriptlet: vim-enhanced-2:8.0.1763-13.el8.x86_64                  5/5 
          Running scriptlet: vim-common-2:8.0.1763-13.el8.x86_64                    5/5 
          Verifying        : gpm-libs-1.20.7-15.el8.x86_64                          1/5 
          Verifying        : vim-common-2:8.0.1763-13.el8.x86_64                    2/5 
          Verifying        : vim-enhanced-2:8.0.1763-13.el8.x86_64                  3/5 
          Verifying        : vim-filesystem-2:8.0.1763-13.el8.noarch                4/5 
          Verifying        : which-2.21-12.el8.x86_64                               5/5 
        
        Installed:
          gpm-libs-1.20.7-15.el8.x86_64         vim-common-2:8.0.1763-13.el8.x86_64    
          vim-enhanced-2:8.0.1763-13.el8.x86_64 vim-filesystem-2:8.0.1763-13.el8.noarch
          which-2.21-12.el8.x86_64             
        
        Complete!
        Removing intermediate container 48de8ec2599f
         ---> 67e8a0acea34
        Step 7/15 : ENV MYPATH /usr/local
         ---> Running in 7f9f7b16c0c7
        Removing intermediate container 7f9f7b16c0c7
         ---> b2bb634a8eaf
        Step 8/15 : WORKDIR $MYPATH
         ---> Running in ecabfcbb7b63
        Removing intermediate container ecabfcbb7b63
         ---> 890ebfa171ef
        Step 9/15 : ENV JAVA_HOME /usr/local/jdk1.8.0_251
         ---> Running in 4a850f2244be
        Removing intermediate container 4a850f2244be
         ---> 0ea38511996b
        Step 10/15 : ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
         ---> Running in 90b15750b921
        Removing intermediate container 90b15750b921
         ---> 78a3bde77d24
        Step 11/15 : ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.36
         ---> Running in dc22ec6b85ba
        Removing intermediate container dc22ec6b85ba
         ---> cd983a9c11c4
        Step 12/15 : ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.36
         ---> Running in 576517e09b20
        Removing intermediate container 576517e09b20
         ---> 37090bb413f6
        Step 13/15 : ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
         ---> Running in c9722175c830
        Removing intermediate container c9722175c830
         ---> dd856f0441ba
        Step 14/15 : EXPOSE 8080
         ---> Running in afee5049c7e2
        Removing intermediate container afee5049c7e2
         ---> b90129ca6890
        Step 15/15 : CMD /usr/local/apache-tomcat-9.0.36/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.36/bin/logs/catalina.out
         ---> Running in 398823b49d9f
        Removing intermediate container 398823b49d9f
         ---> a0596a8007d9
        Successfully built a0596a8007d9
        Successfully tagged mytomcat:1.0
        
      • 运行镜像

        [root@lazyr myTomcat]# docker images
        REPOSITORY            TAG                 IMAGE ID            CREATED              SIZE
        mytomcat              1.0                 a0596a8007d9        About a minute ago   694MB
        [root@lazyr myTomcat]# docker run -d -p 3456:8080 --name myTomcat -v /home/wjr/myTomcat/myWeb:/usr/local/apache-tomcat-9.0.36/webapps/myWeb -v /home/wjr/myTomcat/myLogs:/usr/local/apache-tomcat-9.0.36/logs mytomcat:1.0
        795a1adeac2afc995d3c9a0cd3a3e18150762e570ca2553d663155e9b4b8fb1e
        
        
      • 网站访问:http://119.23.231.254:3456/

        image-20200912181828805
      • 发布项目

        # 往myWeb文件夹里上传自己的网站代码
        [root@lazyr myWeb]# pwd
        /home/wjr/myTomcat/myWeb
        [root@lazyr myWeb]# ls
        index.jsp  WEB-INF
        
      • 访问网站:http://119.23.231.254:3456/myWeb/

        image-20200912182436188

    十一、发布镜像

    • DockerHub

      • 什么是DockerHub?
        • DockerHub 是一个由 Docker 公司运行和管理的基于云的存储库。
        • 它是一个在线存储库,Docker 镜像可以由其他用户发布和使用。
        • 有两种库:公共存储库和私有存储库。如果你是一家公司,你可以在你自己的组织内拥有一个私有存储库,而公共镜像可以被任何人使用。
      • 网址
    • 指令

      • # 登陆dockerhub
        docker login -u username
        
        # 详细用法
        Usage:	docker login [OPTIONS] [SERVER]
        
        Log in to a Docker registry.
        If no server is specified, the default is defined by the daemon.
        
        Options:
          -p, --password string   Password
              --password-stdin    Take the password from stdin
          -u, --username string   Username
          
        # 实例测试
        [root@lazyr myLogs]# docker login -u lazyr
        Password: 
        WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
        Configure a credential helper to remove this warning. See
        https://docs.docker.com/engine/reference/commandline/login/#credentials-store
        
        Login Succeeded
        
      • # 创建TAG
        docker tag 镜像名/镜像Id 新镜像名:TAG
        
        # 详细用法
        Usage:	docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
        
        # 实例测试
        [root@lazyr myLogs]# docker images
        REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
        mytomcat              1.0                 a0596a8007d9        49 minutes ago      694MB
        [root@lazyr myLogs]# clear
        [root@lazyr myLogs]# docker tag mytomcat:1.0 lazyr/mytomcat:1.0
        [root@lazyr myLogs]# docker images
        REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
        lazyr/mytomcat        1.0                 a0596a8007d9        53 minutes ago      694MB
        mytomcat              1.0                 a0596a8007d9        53 minutes ago      694M
        
      • # 提交镜像(提交前先登陆)
        docker push imageName:TAG
        
        # 详细用法
        [root@lazyr myLogs]# docker push --help
        
        Usage:	docker push [OPTIONS] NAME[:TAG]
        
        Push an image or a repository to a registry
        
        Options:
              --disable-content-trust   Skip image signing (default true)
              
        # 实例测试
        
        

        push的镜像名格式需要符合DockerHub的规范image-20200912190728649

    • 发布镜像到DockerHub

      • 登陆DockerHub账号

        [root@lazyr myLogs]# docker login -u lazyr
        Password: 
        WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
        Configure a credential helper to remove this warning. See
        https://docs.docker.com/engine/reference/commandline/login/#credentials-store
        
        Login Succeeded
        
      • 若镜像名不符合DockerHub规范,则修改镜像名

        lazyr/imageName:TAG

        [root@lazyr myLogs]# docker images
        REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
        mytomcat              1.0                 a0596a8007d9        49 minutes ago      694MB
        [root@lazyr myLogs]# clear
        [root@lazyr myLogs]# docker tag mytomcat:1.0 lazyr/mytomcat:1.0
        [root@lazyr myLogs]# docker images
        REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
        lazyr/mytomcat        1.0                 a0596a8007d9        53 minutes ago      694MB
        mytomcat              1.0                 a0596a8007d9        53 minutes ago
        
      • 上传镜像到DockerHub

        [root@lazyr myLogs]# docker push lazyr/mytomcat:1.0
        The push refers to repository [docker.io/lazyr/mytomcat]
        f515b87da940: Pushed 
        f581e826f5e0: Pushed 
        93dc96f5b9d7: Pushed 
        81a6da5c65ed: Pushed 
        291f6e44771a: Pushed 
        1.0: digest: sha256:88710d7781ae9fe1cdb4f2339c2331a682efd7eb2d40d44d27e81253458b4d27 size: 1373
        
      • 查看仓库

        image-20200912195541982

    • 发布镜像到阿里云容器服务

      • 登陆阿里云网站,进入控制台找到容器镜像服务

        image-20200912193556232

      • 创建命名空间

        image-20200912193713344

        image-20200912193936842

        image-20200912194031721

        image-20200912194104458

      • 点击进入仓库,按照步骤走

        image-20200912194213444

      • 登陆账号

        [root@lazyr ~]# sudo docker login --username=画鸡蛋de达芬奇 registry.cn-shenzhen.aliyuncs.com
        Password: 
        WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
        Configure a credential helper to remove this warning. See
        https://docs.docker.com/engine/reference/commandline/login/#credentials-store
        
        Login Succeeded
        
      • 若镜像名不符合阿里云规范,则修改镜像名

        registry.cn-shenzhen.aliyuncs.com/lazy-r/imageName:TAG

        [root@lazyr ~]# docker images
        REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE        694MB
        mytomcat              1.0                 a0596a8007d9        2 hours ago         694MB
        [root@lazyr ~]# sudo docker tag mytomcat:1.0 registry.cn-shenzhen.aliyuncs.com/lazy-r/mytomcat:1.0
        [root@lazyr ~]# docker images
        REPOSITORY                                          TAG                 IMAGE ID            CREATED             SIZE
        mytomcat                                            1.0                 a0596a8007d9        2 hours ago         694MB
        registry.cn-shenzhen.aliyuncs.com/lazy-r/mytomcat   1.0                 a0596a8007d9        2 hours ago         694MB
        
      • 上传到阿里云

        image-20200912200816348

    • 小结

      • Docker运行结构图img

        Docker运行结构图
      • Docker指令结构图img

        Docker指令结构图
      • Dockerfile运行流程图img

        Dockerfile运行流程图

    十二、Docker网络

    • 前提准备

      • 清空所有镜像、容器,方便理解;

      • 服务器网卡

        # 查看ip地址
        [root@lazyr myLogs]# ip addr
        # 本地回环地址:127.0.0.1
        1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
            link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
            inet 127.0.0.1/8 scope host lo
               valid_lft forever preferred_lft forever
        # 阿里云内网地址:172.17.54.90
        2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
            link/ether 00:16:3e:0a:7c:79 brd ff:ff:ff:ff:ff:ff
            inet 172.17.54.90/20 brd 172.17.63.255 scope global dynamic eth0
               valid_lft 314658825sec preferred_lft 314658825sec
        # docker地址:172.18.0.1
        3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN 
            link/ether 02:42:fe:6d:7e:ba brd ff:ff:ff:ff:ff:ff
            inet 172.18.0.1/16 brd 172.18.255.255 scope global docker0
               valid_lft forever preferred_lft forever
        
    • 测试

      • 创建并运行Tomcat容器

        [root@lazyr myLogs]# docker run -d -P --name tomcatTest tomcat
        Unable to find image 'tomcat:latest' locally
        latest: Pulling from library/tomcat
        57df1a1f1ad8: Pull complete 
        71e126169501: Pull complete 
        1af28a55c3f3: Pull complete 
        03f1c9932170: Pull complete 
        881ad7aafb13: Pull complete 
        9c0ffd4062f3: Pull complete 
        bd62e479351a: Pull complete 
        48ee8bc64dbc: Pull complete 
        6daad3485ea7: Pull complete 
        bc07a0199230: Pull complete 
        Digest: sha256:c2b033c9cee06d6a3eb5a4d082935bbb8afee7478e97dcd6bc452bb6ab28da4b
        Status: Downloaded newer image for tomcat:latest
        baadcb945097bf3a0983618ccb9865bd7cbfbe0df9d048730a0bf6af8b11b180
        
      • 查看容器的内部网卡

        [root@lazyr myLogs]# docker exec -it tomcatTest ip addr
        1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
            link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
            inet 127.0.0.1/8 scope host lo
               valid_lft forever preferred_lft forever
             # docker分配的ip地址:172.18.0.2
        104: eth0@if105: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
            link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
            inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
               valid_lft forever preferred_lft forever
        
      • 尝试ping容器内部分配的ip

        # Linux可以ping通Docker容器内部的IP
        [root@lazyr myLogs]# ping 172.18.0.2
        PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
        64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.097 ms
        64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.068 ms
        64 bytes from 172.18.0.2: icmp_seq=3 ttl=64 time=0.068 ms
        # ...
        
      • 再次测试服务器网卡

        [root@lazyr myLogs]# ip addr
        1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
            link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
            inet 127.0.0.1/8 scope host lo
               valid_lft forever preferred_lft forever
        2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
            link/ether 00:16:3e:0a:7c:79 brd ff:ff:ff:ff:ff:ff
            inet 172.17.54.90/20 brd 172.17.63.255 scope global dynamic eth0
               valid_lft 314657936sec preferred_lft 314657936sec
        3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
            link/ether 02:42:fe:6d:7e:ba brd ff:ff:ff:ff:ff:ff
            inet 172.18.0.1/16 brd 172.18.255.255 scope global docker0
               valid_lft forever preferred_lft forever
        105: vethf83b738@if104: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP 
            link/ether 06:97:86:d5:29:c3 brd ff:ff:ff:ff:ff:ff link-netnsid 0
        
      • 刚才新建一个容器,多出的网卡

        # Docker内多的网卡
        104: eth0@if105: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
            link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
            inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
               valid_lft forever preferred_lft forever
        # 服务器多的网卡     
        105: vethf83b738@if104: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP 
            link/ether 06:97:86:d5:29:c3 brd ff:ff:ff:ff:ff:ff link-netnsid 0
        
      • 再新建一个容器,多出的网卡

        # Docker内多的网卡
        106: eth0@if107: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
            link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
            inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0
               valid_lft forever preferred_lft forever
          
        # 服务器多的网卡
        107: vethf502f74@if106: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP 
            link/ether 22:c1:6b:9d:8e:20 brd ff:ff:ff:ff:ff:ff link-netnsid 1
        
    • 原理

      • Docker安装和启动

        • 只要安装了Docker,就会有一个Docker0IP地址;
        • 每启动一个Docker容器,Docker就会给Docker容器分配一个IP;
      • 查看Docker网络详情

        # 查看docker网络详情
        [root@lazyr ~]# docker network ls
        NETWORK ID          NAME                DRIVER              SCOPE
        7bedd0e5ee27        bridge              bridge              local
        c00558472d7d        host                host                local
        2134ca138baf        none                null                local
        
      • 网络模式

        网络模式 说明
        host host模式,容器和宿主机共享Network namespace
        container container模式,容器和另外一个容器共享Network namespace
        none none模式,容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等
        bridge 桥接模式默认为该模式
      • host模式

        • 如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的;
        • 使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好;
        • 一句话,容器直接使用宿主机网络。同样启动一个nginx,此时共享主机网络;
        • image-20200913161040646
      • container模式

        • 这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信;
        • 一句话,两容器共同使用同一网卡、主机名、IP地址,容器间通讯可直接通过lo回环接口通讯,但是其他名称空间是隔离的,例如User、Mount;
        • image-20200913161000632
      • none模式

        • 使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等;
        • 这种网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过--network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性;
        • 一句话,若不自定义配置网络配置,则无法联网;
        • image-20200913160544305
      • bridge模式

        • 当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中;
        • 从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看;
        • bridge模式是docker的默认网络模式,不写--net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看;
        • 一句话,容器相当于共用一个网桥接收和发送消息;
        • image-20200913160411505

    十三、容器互联

    • 场景

      • 在一个微服务里,数据库的url=ip,若想不重启项目就更换数据库ip,如何解决?
      • 在SpringCloud里的feign采用的是调用微服务名的方式来解决更换微服务ip的问题;
      • 根据SpringCloud的思路,我们可以采用容器名的方式访问。
    • --link方式

      • --link指令就是为了解决容器互联问题而产生的(目前不推荐使用

      • 使用

        # 未使用--link互联,无法通过容器名ping通
        [root@lazyr ~]# docker exec -it tomcatTest ping tomcatTest2
        ping: tomcatTest2: Name or service not known
        
        # 通过--link互联tomcatTest2和tomcatTest3
        [root@lazyr ~]# docker run -d -P --name tomcatTest3 --link tomcatTest2 tomcat
        1801ae965edf5df349674c15a074b7227fc498a4d0eb6166ab493a94b18de83a
        
        # tomcatTest3可以ping通tomcatTest2
        [root@lazyr ~]# docker exec -it tomcatTest3 ping tomcatTest2
        PING tomcatTest2 (172.18.0.3) 56(84) bytes of data.
        64 bytes from tomcatTest2 (172.18.0.3): icmp_seq=1 ttl=64 time=0.124 ms
        64 bytes from tomcatTest2 (172.18.0.3): icmp_seq=2 ttl=64 time=0.085 ms
        
        # tomcatTest2不可以ping通tomcatTest3
        [root@lazyr ~]# docker exec -it tomcatTest2 ping tomcatTest3
        ping: tomcatTest3: Name or service not known
        
      • 查看Docker网络详情

        # 查看docker网络详情
        [root@lazyr ~]# docker network ls
        NETWORK ID          NAME                DRIVER              SCOPE
        7bedd0e5ee27        bridge              bridge              local
        c00558472d7d        host                host                local
        2134ca138baf        none                null                local
        
        # 查看具体网络id详情
        [root@lazyr ~]# docker network inspect 7bedd0e5ee27
        [
            {
                "Name": "bridge",
                "Id": "7bedd0e5ee271027f2d6a2d9a6d448187d6a6c8656217271085a207df0ac71ba",
                "Created": "2020-09-10T15:00:36.244407138+08:00",
                "Scope": "local",
                "Driver": "bridge",
                "EnableIPv6": false,
                "IPAM": {
                    "Driver": "default",
                    "Options": null,
                    "Config": [
                        {
                        	# 子网掩码
                            "Subnet": "172.18.0.0/16",
                            # docker0的ip
                            "Gateway": "172.18.0.1"
                        }
                    ]
                },
                "Internal": false,
                "Attachable": false,
                "Ingress": false,
                "ConfigFrom": {
                    "Network": ""
                },
                "ConfigOnly": false,
                # 容器的详细信息
                "Containers": {
                    "1801ae965edf5df349674c15a074b7227fc498a4d0eb6166ab493a94b18de83a": {
                        "Name": "tomcatTest3",
                        "EndpointID": "c0dda48528c8823a689b07e152ab6e582b1958e0b2a9b311ab3a4c38c229a6a8",
                        "MacAddress": "02:42:ac:12:00:04",
                        "IPv4Address": "172.18.0.4/16",
                        "IPv6Address": ""
                    },
                    "2f7e07c4f66c2a4d1859680adcc7968e7ac9798c3395ff7e6badac7b272a806d": {
                        "Name": "tomcatTest2",
                        "EndpointID": "b12fe98acbe4c651ef0d9293f223f332ec9002caff35b69be690454b97893a08",
                        "MacAddress": "02:42:ac:12:00:03",
                        "IPv4Address": "172.18.0.3/16",
                        "IPv6Address": ""
                    },
                    "baadcb945097bf3a0983618ccb9865bd7cbfbe0df9d048730a0bf6af8b11b180": {
                        "Name": "tomcatTest",
                        "EndpointID": "8d6e400bb34c9ef1675a71c635979d3273af4cd43d1cf3f6b6d585747337cc80",
                        "MacAddress": "02:42:ac:12:00:02",
                        "IPv4Address": "172.18.0.2/16",
                        "IPv6Address": ""
                    }
                },
        		# ...
            }
        ]
        
      • --link的原理

        # 查看tomcatTest3容器内部信息
        [root@lazyr ~]# docker inspect 1801ae965edf
        [
        			# ...
                    "Links": [
                        "/tomcatTest2:/tomcatTest3/tomcatTest2"
                    ],
                    # ...
        ]
        
        # 查看tomcatTest3的hosts文件
        [root@lazyr ~]# docker exec -it tomcatTest3 cat /etc/hosts
        127.0.0.1	localhost
        ::1	localhost ip6-localhost ip6-loopback
        fe00::0	ip6-localnet
        ff00::0	ip6-mcastprefix
        ff02::1	ip6-allnodes
        ff02::2	ip6-allrouters
        # --link本质就是添加了容器的hosts映射关系
        172.18.0.3	tomcatTest2 2f7e07c4f66c
        172.18.0.4	1801ae965edf
        
    • 自定义网络

      • 创建容器指令

        # 创建桥接模式的容器
        docker run --net bridge imageName/imageId
        
        指令参数 说明
        --net bridge 以桥接模式创建容器
        --net none 以none模式创建容器
        --net host 以host模式创建容器
        --net container 以container模式创建容器
      • 创建网络

        # 创建桥接模式的网络
        docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 netName
        
        指令参数 说明
        --driver bridge 网络模式(默认为bridge)
        --subnet 192.168.0.0/16 子网掩码
        --gateway 192.168.0.1 网关
      • 使用

        # 创建自己的网络
        [root@lazyr ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 myNet
        966f6bc9c42999faaa582dbdc916a08433d4a26a3adda082aa1d4a3d1c5fd3b1
        [root@lazyr ~]# docker network ls
        NETWORK ID          NAME                DRIVER              SCOPE
        7bedd0e5ee27        bridge              bridge              local
        c00558472d7d        host                host                local
        88a7b532a92c        myNet               bridge              local
        2134ca138baf        none                null                local
        
        # 在自定义的网络下创建容器
        [root@lazyr ~]# docker run -d -P --name tomcat-myNet-01 --net myNet tomcat
        bc2c094aaeab31987962457e1ccbdbe8d4a1e1cc047816afd6978e37a46d77a4
        [root@lazyr ~]# docker run -d -P --name tomcat-myNet-02 --net myNet tomcat
        16f5db1d26dd975dd080b80a20eb7f5d4328cb8a2726e7a2cb2318adce0cad92
        
        # 查看自定义网络详细信息
        [root@lazyr ~]# docker network inspect myNet
        [
            {
                "Name": "myNet",
                "Id": "88a7b532a92c4ccdb76cb4d9e509268e3ce5202b4dc05ddbff38db2a4da44430",
                "Created": "2020-09-13T16:38:34.30615316+08:00",
                "Scope": "local",
                "Driver": "bridge",
                "EnableIPv6": false,
                "IPAM": {
                    "Driver": "default",
                    "Options": {},
                    "Config": [
                        {
                            "Subnet": "192.168.0.0/16",
                            "Gateway": "192.168.0.1"
                        }
                    ]
                },
                "Internal": false,
                "Attachable": false,
                "Ingress": false,
                "ConfigFrom": {
                    "Network": ""
                },
                "ConfigOnly": false,
                "Containers": {
                    "16f5db1d26dd975dd080b80a20eb7f5d4328cb8a2726e7a2cb2318adce0cad92": {
                        "Name": "tomcat-myNet-02",
                        "EndpointID": "b6e3136ca3656835f72c165dbf6bb453d24c9934838f52e6ee56d2829c53d3e2",
                        "MacAddress": "02:42:c0:a8:00:03",
                        "IPv4Address": "192.168.0.3/16",
                        "IPv6Address": ""
                    },
                    "bc2c094aaeab31987962457e1ccbdbe8d4a1e1cc047816afd6978e37a46d77a4": {
                        "Name": "tomcat-myNet-01",
                        "EndpointID": "bf01e6a73cf2eed61f1f98462152f0d55098d1ec36c1503914aa558fa8eff141",
                        "MacAddress": "02:42:c0:a8:00:02",
                        "IPv4Address": "192.168.0.2/16",
                        "IPv6Address": ""
                    }
                },
                "Options": {},
                "Labels": {}
            }
        ]
        
        # 在自定义网络下容器内ping容器名,可以ping成功了
        [root@lazyr ~]# docker exec -it tomcat-myNet-01 ping tomcat-myNet-02
        PING tomcat-myNet-02 (192.168.0.3) 56(84) bytes of data.
        64 bytes from tomcat-myNet-02.myNet (192.168.0.3): icmp_seq=1 ttl=64 time=0.090 ms
        
      • 自定义网络优点

        • 自定义的网络功能完备,网络内的容器可以通过容器名互相ping通;
        • 不同的集群可以使用的网络(使用不同的子网),保证集群是安全和健康的;
    • 网络联通

      • 初始条件

        # 初始条件,两个在docker0网络下的容器,两个在myNet网络下的容器
        [root@lazyr ~]# docker ps 
        CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
        # docker0网络下的两个容器
        a1ced5f72614        tomcat              "catalina.sh run"   10 seconds ago      Up 9 seconds        0.0.0.0:32774->8080/tcp   tomcat-02
        667e27adfa73        tomcat              "catalina.sh run"   14 seconds ago      Up 13 seconds       0.0.0.0:32773->8080/tcp   tomcat-01
        # myNet网络下的两个容器
        16f5db1d26dd        tomcat              "catalina.sh run"   33 minutes ago      Up 33 minutes       0.0.0.0:32772->8080/tcp   tomcat-myNet-02
        bc2c094aaeab        tomcat              "catalina.sh run"   33 minutes ago      Up 33 minutes       0.0.0.0:32771->8080/tcp   tomcat-myNet-01
        
      • 为什么要网络联通?

        • 在Docker里不同的网络内的容器默认是无法通过容器名ping通的,所以要实现网络联通;

          # 无法ping通
          [root@lazyr ~]# docker exec tomcat-01 ping tomcat-myNet-01
          ping: tomcat-myNet-01: Name or service not known
          
        • image-20200913182950595

      • 实现网络联通

        • 连接docker0网络的tomcat-01容器到myNet网络

          [root@lazyr ~]# docker network connect myNet tomcat-01
          
        • 查看myNet网络详情

          [root@lazyr ~]# docker network inspect myNet
          [
          		# ...
                  "Containers": {
                      "16f5db1d26dd975dd080b80a20eb7f5d4328cb8a2726e7a2cb2318adce0cad92": {
                          "Name": "tomcat-myNet-02",
                          "EndpointID": "b6e3136ca3656835f72c165dbf6bb453d24c9934838f52e6ee56d2829c53d3e2",
                          "MacAddress": "02:42:c0:a8:00:03",
                          "IPv4Address": "192.168.0.3/16",
                          "IPv6Address": ""
                      },
                      # docker0网络下的tomcat-01容器信息配置在了myNet网络里
                      "667e27adfa7311c9b426b1c578d35eb923a03cbfc090fcd29bd610f6e1d96ce3": {
                          "Name": "tomcat-01",
                          "EndpointID": "73f55fe0408794405b76fb80471fa5da5dd2ef0222c333c41dc829aa210a79a9",
                          "MacAddress": "02:42:c0:a8:00:04",
                          "IPv4Address": "192.168.0.4/16",
                          "IPv6Address": ""
                      },
                      "bc2c094aaeab31987962457e1ccbdbe8d4a1e1cc047816afd6978e37a46d77a4": {
                          "Name": "tomcat-myNet-01",
                          "EndpointID": "bf01e6a73cf2eed61f1f98462152f0d55098d1ec36c1503914aa558fa8eff141",
                          "MacAddress": "02:42:c0:a8:00:02",
                          "IPv4Address": "192.168.0.2/16",
                          "IPv6Address": ""
                      }
                  },
          		#...
          ]
          
        • docker0网络下的容器tomcat01ping网络myNet下tomcat-myNet-01名

          # ping通成功
          [root@lazyr ~]# docker exec tomcat-01 ping tomcat-myNet-01
          PING tomcat-myNet-01 (192.168.0.2) 56(84) bytes of data.
          64 bytes from tomcat-myNet-01.myNet (192.168.0.2): icmp_seq=1 ttl=64 time=0.098 ms
          
        • 查看docker0网络详情

          [root@lazyr ~]# docker network inspect 7bedd0e5ee27
          [
          		#...
                  "Containers": {
                  	# docker0中也有tomcat-01的信息
                      "45f71d621ac8d657f1a624467be580713c8afd7ccdcfd0f1b3a5a6c042ef3380": {
                          "Name": "tomcat-01",
                          "EndpointID": "303ce6da7cfd11755eef48ba1962cbaa43352c87c64db2a6d846a6d385e2d6fc",
                          "MacAddress": "02:42:ac:12:00:02",
                          "IPv4Address": "172.18.0.2/16",
                          "IPv6Address": ""
                      },
                      "a1ced5f72614b319815835430ce9549a3db8c9dc75af4fbf13bc970eac41d370": {
                          "Name": "tomcat-02",
                          "EndpointID": "a92d766a5b1f948bc639432cb99bd7a8695215c43d506833f8939e10d5f33b5d",
                          "MacAddress": "02:42:ac:12:00:03",
                          "IPv4Address": "172.18.0.3/16",
                          "IPv6Address": ""
                      }
                  },
                  #...
          ]
          
          
      • 网络互联原理

        • 通过查看docker0网络详情和myNet网络详情发现,tomcat-01容器在两个网络下都具有网卡,所以才可以实现网络互通
        • image-20200913183650165

    十四、Redis集群部署

    • 介绍

      • 集群介绍

        • 实现的功能:分片+高可用+负载均衡;

        • 主从数据库之间数据同步,若主数据库崩溃了,从数据库代替主数据库工作;

        • image-20200913184205349

          集群框架
    • 部署

      • 在Docker里创建Redis网卡

        # 创建网卡
        docker network create --subnet 112.38.0.0/16 --gateway 112.38.0.1 redisNet
        
        # 运行指令
        [root@lazyr ~]# docker network create --subnet 112.38.0.0/16 --gateway 112.38.0.1 redisNet
        cdfb7f91bbcf1029ba783af6b470237fb54cddbc6db4b19b2534e5f964ba1719
        # 查看docker网络信息
        [root@lazyr ~]# docker network ls
        NETWORK ID          NAME                DRIVER              SCOPE
        7bedd0e5ee27        bridge              bridge              local
        c00558472d7d        host                host                local
        2134ca138baf        none                null                local
        cdfb7f91bbcf        redisNet            bridge              local
        
      • 通过脚本创建六个Redis配置(直接粘贴复制到命令行执行)

        for port in $(seq 1 6); 
        do 
        mkdir -p /mydata/redis/node-${port}/conf
        touch /mydata/redis/node-${port}/conf/redis.conf
        cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
        port 6379
        bind 0.0.0.0
        cluster-enabled yes
        cluster-config-file nodes.conf
        cluster-node-timeout 50000
        cluster-announce-ip 112.38.0.1${port}
        cluster-announce-port 6379
        cluster-announce-bus-port 16379
        appendonly yes
        EOF
        done
        
        #运行脚本
        [root@lazyr /]# for port in $(seq 1 6); 
        > do 
        > mkdir -p /mydata/redis/node-${port}/conf
        > touch /mydata/redis/node-${port}/conf/redis.conf
        > cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
        > port 6379
        > bind 0.0.0.0
        > cluster-enabled yes
        > cluster-config-file nodes.conf
        > cluster-node-timeout 50000
        > cluster-announce-ip 112.38.0.1${port}
        > cluster-announce-port 6379
        > cluster-announce-bus-port 16379
        > appendonly yes
        > EOF
        > done
        
        # 查看创建结果(创建成功)
        [root@lazyr /]# cd /mydata/
        [root@lazyr mydata]# ls
        redis
        [root@lazyr mydata]# cd redis/
        [root@lazyr redis]# ls
        node-1  node-2  node-3  node-4  node-5  node-6
        
      • 创建并运行Redis容器

        # 创建并允许六个容器的脚本
        for port in $(seq 1 6); 
        do 
        docker run -d -p 334${port}:6379 -p 400${port}:16379 --name redis-${port} 
        -v /mydata/redis/node-${port}/data:/data 
        -v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf 
        --net redisNet --ip 112.38.0.1${port} 
        redis:5.0.9-alpine3.11 
        redis-server /etc/redis/redis.conf 
        done
        
        # 运行脚本
        [root@lazyr conf]# for port in $(seq 1 6); 
        > do 
        > docker run -d -p 334${port}:6379 -p 400${port}:16379 --name redis-${port} 
        > -v /mydata/redis/node-${port}/data:/data 
        # 挂载目录
        > -v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf 
        # 创建在Docker的redisNet网络中,并绑定ip
        > --net redisNet --ip 112.38.0.1${port} 
        # 运行redis镜像版本
        > redis:5.0.9-alpine3.11 
        # 启动redis
        > redis-server /etc/redis/redis.conf 
        > done
        cde1a865fb48a342e0360e39026d5b93313716222362d260cce2dc37b927f2af
        48e0f64da664ed64cade01e6a771389f53f3dc04b5025faaa4dbaf82476258b1
        66c28da514906fd3ed48880386e525fd49016fb66c4d50a80691fe65a204e76a
        c6c9da54b19a466e6e5dc6cb8c25f5d80d27ac62750c084b47e46ddea0db2d1a
        5890f8fadc77b4dfa182a51d8709f949c6cac8becf584da6ffa96aaf734b5ea9
        c0594438efa0c59de41f7e20a4ac437ac3df7e37a15fe78b28c30e8c90629424
        # 查看创建并运行的脚本
        [root@lazyr conf]# docker ps
        CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS                                             NAMES
        c0594438efa0        redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   3 seconds ago       Up 2 seconds        0.0.0.0:3346->6379/tcp, 0.0.0.0:4006->16379/tcp   redis-6
        5890f8fadc77        redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   4 seconds ago       Up 2 seconds        0.0.0.0:3345->6379/tcp, 0.0.0.0:4005->16379/tcp   redis-5
        c6c9da54b19a        redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   4 seconds ago       Up 3 seconds        0.0.0.0:3344->6379/tcp, 0.0.0.0:4004->16379/tcp   redis-4
        66c28da51490        redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   5 seconds ago       Up 3 seconds        0.0.0.0:3343->6379/tcp, 0.0.0.0:4003->16379/tcp   redis-3
        48e0f64da664        redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   5 seconds ago       Up 4 seconds        0.0.0.0:3342->6379/tcp, 0.0.0.0:4002->16379/tcp   redis-2
        cde1a865fb48        redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   6 seconds ago       Up 5 seconds        0.0.0.0:3341->6379/tcp, 0.0.0.0:4001->16379/tcp   redis-1
        
      • 随机进入一个容器查看详细内容

        [root@lazyr /]# docker exec -it redis-1 /bin/sh
        /data # ls
        appendonly.aof  nodes.conf
        
      • 在容器内创建集群

        # 在redis容器内使用
        redis-cli --cluster create 112.38.0.11:6379 112.38.0.12:6379 112.38.0.13:6379 112.38.0.14:6379 112.38.0.15:6379 112.38.0.16:6379 --cluster-replicas 1
        
        # 创建集群
        /data # redis-cli --cluster create 112.38.0.11:6379 112.38.0.12:6379 112.38.0.13:6379 112.38.0.14:6379 112.38.0.15:6379 112.38.0.16:6379 --cluster-replicas 1
        >>> Performing hash slots allocation on 6 nodes...
        Master[0] -> Slots 0 - 5460
        Master[1] -> Slots 5461 - 10922
        Master[2] -> Slots 10923 - 16383
        Adding replica 112.38.0.15:6379 to 112.38.0.11:6379
        Adding replica 112.38.0.16:6379 to 112.38.0.12:6379
        Adding replica 112.38.0.14:6379 to 112.38.0.13:6379
        M: cab9f7566ac3a65d7f3e4c813b7f9b3fff6cc4ae 112.38.0.11:6379
           slots:[0-5460] (5461 slots) master
        M: 97d480c1cb21cc0b3537a813877acf610111cec0 112.38.0.12:6379
           slots:[5461-10922] (5462 slots) master
        M: e0748630ff78bcffe0476adb76ad2689a6632cbc 112.38.0.13:6379
           slots:[10923-16383] (5461 slots) master
        S: b15ebc328085133637370742e8a869ee50fb09ce 112.38.0.14:6379
           replicates e0748630ff78bcffe0476adb76ad2689a6632cbc
        S: b36387fad1487a5f82b4e535b4936fdc1e699040 112.38.0.15:6379
           replicates cab9f7566ac3a65d7f3e4c813b7f9b3fff6cc4ae
        S: d168a9353f9c4d4f341eef277d84306c975158a0 112.38.0.16:6379
           replicates 97d480c1cb21cc0b3537a813877acf610111cec0
        # 填写yes
        Can I set the above configuration? (type 'yes' to accept): yes
        >>> Nodes configuration updated
        >>> Assign a different config epoch to each node
        >>> Sending CLUSTER MEET messages to join the cluster
        Waiting for the cluster to join
        .......
        >>> Performing Cluster Check (using node 112.38.0.11:6379)
        M: cab9f7566ac3a65d7f3e4c813b7f9b3fff6cc4ae 112.38.0.11:6379
           slots:[0-5460] (5461 slots) master
           1 additional replica(s)
        M: e0748630ff78bcffe0476adb76ad2689a6632cbc 112.38.0.13:6379
           slots:[10923-16383] (5461 slots) master
           1 additional replica(s)
        S: d168a9353f9c4d4f341eef277d84306c975158a0 112.38.0.16:6379
           slots: (0 slots) slave
           replicates 97d480c1cb21cc0b3537a813877acf610111cec0
        S: b36387fad1487a5f82b4e535b4936fdc1e699040 112.38.0.15:6379
           slots: (0 slots) slave
           replicates cab9f7566ac3a65d7f3e4c813b7f9b3fff6cc4ae
        M: 97d480c1cb21cc0b3537a813877acf610111cec0 112.38.0.12:6379
           slots:[5461-10922] (5462 slots) master
           1 additional replica(s)
        S: b15ebc328085133637370742e8a869ee50fb09ce 112.38.0.14:6379
           slots: (0 slots) slave
           replicates e0748630ff78bcffe0476adb76ad2689a6632cbc
        [OK] All nodes agree about slots configuration.
        >>> Check for open slots...
        >>> Check slots coverage...
        [OK] All 16384 slots covered.
        
      • 测试

        /data # redis-cli -c
        127.0.0.1:6379> cluster info
        cluster_state:ok
        cluster_slots_assigned:16384
        cluster_slots_ok:16384
        cluster_slots_pfail:0
        cluster_slots_fail:0
        cluster_known_nodes:6
        cluster_size:3
        cluster_current_epoch:6
        cluster_my_epoch:1
        cluster_stats_messages_ping_sent:344
        cluster_stats_messages_pong_sent:346
        cluster_stats_messages_sent:690
        cluster_stats_messages_ping_received:341
        cluster_stats_messages_pong_received:344
        cluster_stats_messages_meet_received:5
        cluster_stats_messages_received:690
        127.0.0.1:6379> cluster nodes
        e0748630ff78bcffe0476adb76ad2689a6632cbc 112.38.0.13:6379@16379 master - 0 1600000891972 3 connected 10923-16383
        d168a9353f9c4d4f341eef277d84306c975158a0 112.38.0.16:6379@16379 slave 97d480c1cb21cc0b3537a813877acf610111cec0 0 1600000890970 6 connected
        b36387fad1487a5f82b4e535b4936fdc1e699040 112.38.0.15:6379@16379 slave cab9f7566ac3a65d7f3e4c813b7f9b3fff6cc4ae 0 1600000890000 5 connected
        97d480c1cb21cc0b3537a813877acf610111cec0 112.38.0.12:6379@16379 master - 0 1600000890000 2 connected 5461-10922
        cab9f7566ac3a65d7f3e4c813b7f9b3fff6cc4ae 112.38.0.11:6379@16379 myself,master - 0 1600000890000 1 connected 0-5460
        b15ebc328085133637370742e8a869ee50fb09ce 112.38.0.14:6379@16379 slave e0748630ff78bcffe0476adb76ad2689a6632cbc 0 1600000889967 4 connected
        127.0.0.1:6379> set a b
        -> Redirected to slot [15495] located at 112.38.0.13:6379
        OK
        

    十五、SpringBoot微服务部署

    • 前提准备

      • 准备一个SpringBoot的hello项目
    • 部署

      • 测试运行SpringBoot项目

        image-20200914140946654

      • 打包应用
        image-20200914141054314

        image-20200914141533779

      • 本地测试运行jar包

        image-20200914141848961

        image-20200914141923188

      • 编写Dockerfile

        image-20200914142756521

      • 在服务器创建镜像存放目录

        image-20200914143127896

      • 把jar包和Dockerfile文件上传到新建目录

        image-20200914143406305

      • 构建镜像

        image-20200914143612682

      • 运行镜像

        image-20200914143757962

      • 访问网页

        image-20200914143827831

      • 登陆DockerHubimage-20200914144024513

      • 修改镜像名至标准格式,然后push到DockerHub

        image-20200914144625388

      • 查看DockerHub网站

        image-20200914144716525

  • 相关阅读:
    mongoDB 常用函数
    无缓冲通道 vs 有缓冲通道
    go实现终端输出颜色文本
    JavaScript获取当前时间
    201521123082《Java程序设计》第2周学习总结
    201521123082 《Java程序设计》第1周学习总结
    201521123074 《Java程序设计》第2周学习总结
    第2周作业-Java基本语法与类库
    201521123094 《Java程序设计》第1周学习总结
    201521123047 《Java程序设计》第4周学习总结
  • 原文地址:https://www.cnblogs.com/lazyr/p/13668746.html
Copyright © 2011-2022 走看看