Docker基础学习

一、介绍

  • 简介

    • Docker出现前的现况

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

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

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

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

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

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

  • 原理

    • 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
          
      #安装最新版本的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-20200910145012360

    • # 查看镜像
      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 {
              width: 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 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

      • UnionFS结构图img

    • 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 镜像可以由其他用户发布和使用。
      • 有两种库:公共存储库和私有存储库。如果你是一家公司,你可以在你自己的组织内拥有一个私有存储库,而公共镜像可以被任何人使用。
    • 网址
      • https://hub.docker.com/
  • 指令

    • # 登陆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
      
    • 上传到阿里云

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FuPqTCZJ-1600620014568)(Docker学习/image-20200912200816348.png)]

  • 小结

    • Docker运行结构图[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EgwuqSVl-1600620014569)(F:\work\myBlogs\study\Docker学习{6D6EC969-A60A-F9FC-6AA9-2024066833DF}.jpg)]

    • Docker指令结构图[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XY75mVQj-1600620014570)(F:\work\myBlogs\study\Docker学习\timg-1599736715771.jfif)]

    • Dockerfile运行流程图img

十二、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
      
    • 网络模式

      网络模式说明
      hosthost模式,容器和宿主机共享Network namespace
      containercontainer模式,容器和另外一个容器共享Network namespace
      nonenone模式,容器有独立的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

Logo

更多推荐