1. 程式人生 > 實用技巧 >Docker基礎學習

Docker基礎學習

Docker基礎學習

一、介紹

  • 簡介

    • Docker出現前的現況

      • 開發-上線
        • 問題:兩套環境(應用環境、應用配置)
      • 開發-運維
        • 版本更新導致服務不可用
        • 換臺電腦就不可以運行了
      • 傳統解決方式
        • 環境配置等由運維來做
    • 什麼是Doceker?

      • 針對上述問題,Docker技術應運而生,實現了開發部署上線,一套流程搞定;

      • Docker 是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的映象中,然後釋出到任何流行的 Linux或[Windows 機器上,也可以實現虛擬化;

      • Docker容器是完全使用沙箱機制,相互之間不會有任何介面;

      • 一個完整的Docker有以下幾個部分組成:

        • DockerClient客戶端;
        • Docker Daemon守護程序;
        • Docker Image映象;
        • DockerContainer容器;
      • Docker發展史
  • 原理

    • Docker是如何工作的?

      • Docker是一個Client-Server結構的系統;
      • DockerClient的守護程序執行在主機上,通過socket從客戶端訪問;
      • DockersServer接收到DockerClient的指令,就會執行這個指令;
    • Docker比虛擬機器快的原因

      • Docker比虛擬機器抽象層少;

      • Docker利用的是宿主機的核心;

      • 新建一個容器,docker不需要像虛擬機器一樣重新載入一個作業系統核心,虛擬機器載入的是Guest OS,分鐘級別;Docker是利用宿主機的OS,秒級

      • 對比圖
    • Docker指令結構圖

  • 相關網站

二、安裝

  • 解除安裝

    • # 停止執行
      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
  • 配置映象加速

    • 登陸阿里雲控制檯首頁,單擊容器映象服務

    • 執行一下命令

      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
      

      映象執行流程
    • # 檢視映象
      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
      

    • # 搜尋映象
      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官網裡查詢後填寫

    • # 刪除映象
      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(練習)

    • 搜尋映象資訊

    • 下載映象

      [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>
      
    • 網站訪問

    • 訪問流程原理

    • 問題

      • 我們現在若想修改nginx配置檔案,必須進入容器內部,而容器內部有很多指令等因素不方便修改,怎麼解決?
      • 採用資料卷技術解決上述問題
  • 部署Tomcat(練習)

    • 搜尋映象資訊

    • 下載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是不完整的)

    • 進入容器內檢視

      [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命令發現並沒有在執行

      • 原因: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/

五、Docker映象

  • 載入原理

    • UnionFS(聯合檔案系統)

      • 聯合檔案系統(UnionFS)是一種分層、輕量級並且高效能的檔案系統,它支援對檔案系統的修改作為一次提交來一層層的疊加,同時可以將不同目錄掛載到同一個虛擬檔案系統下;

      • 聯合檔案系統是 Docker 映象的基礎。映象可以通過分層來進行繼承,基於基礎映象(沒有父映象),可以製作各種具體的應用映象。

      • 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
      
    • 訪問網站(顯示正常)

    • 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上面,實現本地和容器內資料同步

  • 使用

    • 指定位置掛載

      # -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
      
    • 本地資料庫連線

    • 在本地建立新資料庫

    • 檢視Linux伺服器掛載的目錄

九、資料卷容器

  • 介紹

    • 什麼是資料卷容器?
      • 容器資料卷解決了容器和主機間資料同步的問題,那不同容器之間資料如何同步呢?
      • 資料卷容器解決了不同容器間的資料同步問題,且只有若多個容器資料都同時刪除,容器內的資料才會刪除(沒掛載到本地時;掛載到本地時,所有容器都刪除,本地資料也在)
  • 指令

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

    • 只有父容器掛載了檔案,子容器才可以同步資料

    • 建立父容器(父容器必須掛載目錄)

    • 建立子容器

    • 檢視父容器的資料變化

十、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
      
    • 執行構建的映象

    • 檢視容器詳細資訊

      [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的檔案;
    • 指令 作用
      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<[email protected]>
      
      # 環境變數
      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<[email protected]>
      # 複製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<[email protected]>
       ---> 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) <[email protected]>"
       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/

    • 釋出專案

      # 往myWeb資料夾裡上傳自己的網站程式碼
      [root@lazyr myWeb]# pwd
      /home/wjr/myTomcat/myWeb
      [root@lazyr myWeb]# ls
      index.jsp  WEB-INF
      
    • 訪問網站:http://119.23.231.254:3456/myWeb/

十一、釋出映象

  • 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的規範

  • 釋出映象到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
      
    • 檢視倉庫

  • 釋出映象到阿里雲容器服務

    • 登陸阿里雲網站,進入控制檯找到容器映象服務

    • 建立名稱空間

    • 點選進入倉庫,按照步驟走

    • 登陸賬號

      [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
      
    • 上傳到阿里雲

  • 小結

    • Docker執行結構圖

      Docker執行結構圖
    • Docker指令結構圖

      Docker指令結構圖
    • Dockerfile執行流程圖

      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,此時共享主機網路;
    • container模式

      • 這個模式指定新建立的容器和已經存在的一個容器共享一個 Network Namespace,而不是和宿主機共享。新建立的容器不會建立自己的網絡卡,配置自己的 IP,而是和一個指定的容器共享 IP、埠範圍等。同樣,兩個容器除了網路方面,其他的如檔案系統、程序列表等還是隔離的。兩個容器的程序可以通過 lo 網絡卡裝置通訊;
      • 一句話,兩容器共同使用同一網絡卡、主機名、IP地址,容器間通訊可直接通過lo迴環介面通訊,但是其他名稱空間是隔離的,例如User、Mount;
    • none模式

      • 使用none模式,Docker容器擁有自己的Network Namespace,但是,並不為Docker容器進行任何網路配置。也就是說,這個Docker容器沒有網絡卡、IP、路由等資訊。需要我們自己為Docker容器新增網絡卡、配置IP等;
      • 這種網路模式下容器只有lo迴環網路,沒有其他網絡卡。none模式可以在容器建立時通過--network=none來指定。這種型別的網路沒有辦法聯網,封閉的網路能很好的保證容器的安全性;
      • 一句話,若不自定義配置網路配置,則無法聯網;
    • 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檢視;
      • 一句話,容器相當於共用一個網橋接收和傳送訊息;

十三、容器互聯

  • 場景

    • 在一個微服務裡,資料庫的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
        
    • 實現網路聯通

      • 連線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容器在兩個網路下都具有網絡卡,所以才可以實現網路互通

十四、Redis叢集部署

  • 介紹

    • 叢集介紹

      • 實現的功能:分片+高可用+負載均衡;

      • 主從資料庫之間資料同步,若主資料庫崩潰了,從資料庫代替主資料庫工作;

      • 叢集框架
  • 部署

    • 在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專案

    • 打包應用

    • 本地測試執行jar包

    • 編寫Dockerfile

    • 在伺服器建立映象存放目錄

    • 把jar包和Dockerfile檔案上傳到新建目錄

    • 構建映象

    • 執行映象

    • 訪問網頁

    • 登陸DockerHub

    • 修改映象名至標準格式,然後push到DockerHub

    • 檢視DockerHub網站