日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

从零开始学Docker(超详细讲解+案例分析)

發布時間:2023/12/20 编程问答 59 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从零开始学Docker(超详细讲解+案例分析) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考狂神說Docker:https://www.bilibili.com/video/BV1og4y1q7M4?p=40

目錄

  • 一、Docker概述
    • 1. Docker為什么出現
    • 2. Docker歷史
    • 3. 對比虛擬化技術
    • 4. 為什么選擇Docker
    • 引入Docker后:DevOps(開發、運維)
  • 二、Docker安裝配置
    • 1. Docker的基本組成
      • 鏡像(image)
      • 容器(container)
      • 倉庫(repository)
    • 2. 環境準備
    • 3. 安裝
      • 1. 卸載舊版本
      • 2. 安裝Docker軟件包
      • 3. 設置鏡像倉庫地址
      • 4. 安裝最新版Docker Engine和容器
      • 5. 啟動Docker
      • 6. 運行Hello World映像測試
    • 4. 卸載Docker方法
      • 1. 卸載Docker依賴
      • 2. 刪除Docker資源
    • 5. 阿里云鏡像加速
  • 三、Docker run的流程和底層原理
    • 1. 流程圖
    • 2. 底層原理
      • Docker是怎么工作的?
      • Docker為什么比VM快?
  • 四、Docker常用命令
    • 1. 幫助命令
    • 2. 鏡像命令
      • 查看所有鏡像
      • 搜索鏡像
      • 下載鏡像
      • 刪除鏡像
    • 3. 容器命令
      • 新建容器并啟動
      • 列出所有運行的容器
      • 退出容器
      • 刪除容器
      • 啟動停止容器
    • 4. 常用其他命令
      • 后臺啟動容器
      • 查看日志
      • 查看容器中的進程
      • 查看鏡像元數據
      • 進入當前正在運行的容器
      • 從容器內拷貝文件到主機
  • 五、Docker命令實戰
    • 1. 部署Nginx
    • 2. 部署Tomcat
    • 3. 部署es+kibana
  • 六、Portainer可視化面板
    • 1. 什么是 portainer ?
    • 2. 下載
    • 3. 訪問測試
  • 七、Docker鏡像講解
    • 1. 鏡像是什么
    • 2. Docker鏡像加載原理
    • 3. 分層理解
      • 下載示例
      • 理解
      • 特點
    • 4. Commit鏡像
  • 八、容器數據卷
    • 1. 什么是容器數據卷
    • 2. 使用數據卷
    • 實戰:安裝MySQL
    • 3. 具名和匿名掛載
      • 匿名掛載
      • 具名掛載(常用)
      • 拓展
    • 4. 初識Dockerfile
    • 5. 數據卷容器
  • 九、DockerFile
    • 1. DockerFile介紹
    • 2. DockerFile的構建過程
    • 3. DockerFile指令
      • 常見指令
      • CMD和ENTRYPOINT的區別
    • 4. 實戰:構建自己的CentOS
      • 1. 編寫dockerfile
      • 2. 通過dockerfile構建鏡像
      • 3. 通過鏡像啟動容器
    • 5. 實戰:構建自己的Tomcat
      • 1. 準備鏡像文件
      • 2. 編寫dockerfile文件
      • 3. 構建鏡像
      • 4. 啟動容器
      • 5. 進入容器
      • 6. 訪問測試
      • 7. 發布項目
    • 6. 發布鏡像到 Docker Hub
      • 1. 登錄 Docker Hub
      • 2. 提交到 Docker Hub
    • 7. 發布鏡像到阿里云鏡像
      • 1. 創建阿里云鏡像倉庫
      • 2. 提交到阿里云鏡像倉庫
    • 小結
  • 十、Docker網絡
    • 1. Docker網絡原理
    • 2. 容器互聯--link
    • 3. 自定義網絡
    • 4. 網絡聯通
    • 實戰:部署Redis集群
  • 十一、SpringBoot微服務&docker
    • 1. 構建springboot項目
    • 2. 打包應用
    • 3. 編寫Dockerfile
    • 4. 構建鏡像
    • 5. 啟動容器測試
    • 6. 發布鏡像

一、Docker概述

官網:https://www.docker.com/

文檔地址:https://docs.docker.com/

倉庫地址:https://hub.docker.com/

1. Docker為什么出現

一款產品的開發往往需要多套環境,比如開發環境、測試環境以及最終的上線環境;環境的配置是時分麻煩的,每一個機器都要部署環境(Redis、ES、Hadoop集群…),尤其是各種集群的部署特別浪費時間,常常會遇到 ”在我電腦上可以運行,在你電腦上不能運行“、”版本更新導致服務不用“、”不能跨平臺“ 等等大量問題,這對運維人員來說就十分棘手。

在以前,開發人員發開完成就發布一個jar或者war包,其他的都交給運維人員來做;而現在,開發即運維,打包部署上線一套流程走完:開發人員會將項目及其附帶的環境一起打包jar+(Redis Jdk ES MySQL)成一整套發布,稱為鏡像,這樣就不再需要再配置環境,直接執行一整套即可,省去環境配置的麻煩且保證了一致性;

Docker的出現就是為了解決以上問題,類似于安卓應用:

  • java – apk – 發布到應用商店 – 下載即可使用
  • java – jar(環境) – 打包項目+環境(鏡像) – 發布到Docker倉庫 – 下載鏡像即可直接運行


Docker 的思想來源于集裝箱,打包裝箱,每個箱子互相隔離

Docker 通過隔離機制,可以將服務器運行到極致


2. Docker歷史

參考:Docker的前生今世

2010 年,幾個搞 IT 的年輕人,在美國舊金山成立了一家名叫 dotCloud 的公司。dotCloud 的平臺即服務(Platform-as-a-Service, PaaS)提供商。底層技術上,dotCloud 平臺利用了 Linux 的 LXC 容器技術。

為了方便創建和管理這些容器,dotCloud 基于 Google 公司推出的 Go 語言開發了一套內部工具,之后被命名為 Docker。Docker 就是這樣誕生的。

如同 Docker 的 Logo 一樣,Docker 的思想來源于集裝箱。集裝箱解決了什么問題?在一艘大船上,可以把貨物規整的擺放起來,并且各種各樣的貨物被集裝箱標準化,集裝箱與集裝箱之間互不影響。那么就不需要專門運送水果的船和專門運送化學用品的船了。只要這些貨物封裝在不同的集裝箱里,就可以用一艘大船把它們都運走。

Docker 技術誕生之后,并沒有引起行業的關注。而 dotCloud 公司,作為一家小型創業企業,在激烈的競爭之下,也步履維艱。

正當他們快要堅持不下去的時候,腦子里蹦出了“開源”的想法。什么是“開源”?開源,就是開放源代碼。也就是將原來內部保密的程序源代碼開放給所有人,然后讓大家一起參與進來,貢獻代碼和意見。

有的軟件一開始就是開源的。也有的軟件,是混不下去,創造者又不想放棄,所以選擇開源。自己養不活,就吃“百家飯”嘛。2013 年 3 月,dotCloud 公司的創始人之一,Docker 之父,28 歲的 「Solomon?Hykes」 正式決定,將 Docker 項目開源。

不開則已,一開驚人。越來越多的 IT 工程師發現了 Docker 的優點,然后蜂擁而至,加入 Docker 開源社區。Docker 的人氣迅速攀升,速度之快,令人瞠目結舌。

開源當月, Docker 0.1 版本發布。此后的每一個月, Docker 都會發布一個版本。到 2014 年 6 月 9 日, Docker 1.0 版本正式發布。

此時的 Docker,已經成為行業里人氣最火爆的開源技術,沒有之一。甚至像 Google、微軟、Amazon、 VMware 這樣的巨頭們都對它青睞有加,表示將全力支持。

Docker 火了之后, dotCloud 公司干脆把公司名字也改成了 Docker Inc.


3. 對比虛擬化技術

虛擬機技術

缺點

  • 資源占用十分大
  • 冗余步驟多
  • 啟動慢

容器化技術:不是模擬的一個完整的操作系統

Docker 和 虛擬機技術 的不同:

  • 傳統虛擬機技術,虛擬出一套硬件,運行一個完整的操作系統,在這個系統上安裝和運行軟件
  • 容器內的應用直接運行在宿主機的內核上,容器沒有自己的內核,也沒有虛擬硬件,輕便快速,
  • 每個容器互相隔離,每個容器都有一個自己的文件系統,互不影響

4. 為什么選擇Docker

更高效的利用系統資源

由于容器不需要進行硬件虛擬以及運行完整操作系統等額外開銷,Docker 對系統資源的利用率更高。無論是應用執行速度、內存損耗或者文件存儲速度,都要比傳統虛擬機技術更高效。因此,相比虛擬機技術,一個相同配置的主機,往往可以運行更多數量的應用。

更快速的啟動時間

傳統的虛擬機技術啟動應用服務往往需要數分鐘,而 Docker 容器應用,由于直接運行于宿主內核,無需啟動完整的操作系統,因此可以做到秒級、甚至毫秒級的啟動時間。大大的節約了開發、測試、部署的時間。

一致的運行環境

開發過程中一個常見的問題是環境一致性問題。由于開發環境、測試環境、生產環境不一致,導致有些 bug 并未在開發過程中被發現。而 Docker 的鏡像提供了除內核外完整的運行時環境,確保了應用運行環境一致性,從而不會再出現「這段代碼在我機器上沒問題啊」 這類問題。

持續交付和部署

對開發和運維(DevOps)人員來說,最希望的就是一次創建或配置,可以在任意地方正常運行。

使用 Docker 可以通過定制應用鏡像來實現持續集成、持續交付、部署。開發人員可以通過 Dockerfile 來進行鏡像構建,并結合持續集成(Continuous Integration)系統進行集成測試,而運維人員則可以直接在生產環境中快速部署該鏡像,甚至結合持續部署(Continuous Delivery/Deployment)系統進行自動部署。

而且使用 Dockerfile 使鏡像構建透明化,不僅僅開發團隊可以理解應用運行環境,也方便運維團隊理解應用運行所需條件,幫助更好的在生產環境中部署該鏡像。

更輕松的遷移

由于 Docker 確保了執行環境的一致性,使得應用的遷移更加容易。Docker 可以在很多平臺上運行,無論是物理機、虛擬機、公有云、私有云,甚至是筆記本,其運行結果是一致的。因此用戶可以很輕易的將在一個平臺上運行的應用,遷移到另一個平臺上,而不用擔心運行環境的變化導致應用無法正常運行的情況。

更輕松的維護和擴展

Docker 使用的分層存儲以及鏡像的技術,使得應用重復部分的復用更為容易,也使得應用的維護更新更加簡單,基于基礎鏡像進一步擴展鏡像也變得非常簡單。此外,Docker 團隊同各個開源項目團隊一起維護了一大批高質量的 官方鏡像,既可以直接在生產環境使用,又可以作為基礎進一步定制,大大的降低了應用服務的鏡像制作成本。


引入Docker后:DevOps(開發、運維)

Docker技術的出現以后,DevOps的概念由然而生,即開發即運維

應用更快速的交付和部署

  • 傳統:一堆幫助文檔,安裝程序

  • Docker:打包鏡像發布測試,一鍵運行

更便捷的升級和擴縮容

  • 使用Docker之后,部署應用就和搭積木一樣
  • 項目打包成一個鏡像,比如服務器A出現性能瓶頸,水平拓展,在服務器B上一鍵運行鏡像

更簡單的系統運維

  • 容器化之后,開發、測試環境高度一致

更高效的計算資源利用

  • Docker是內核級別的虛擬化,可以在一個物理機上運行很多容器實例,服務器性能可以被壓榨到極致


二、Docker安裝配置

1. Docker的基本組成

鏡像(image)

鏡像就是一個只讀的模板,可以通過這個模板創建容器服務,一個鏡像可以創建多個容器(最終服務運行或者項目運行就是在容器中)

容器(container)

  • Docker利用容器技術,獨立運行的一個或一組應用。容器是用鏡像創建的運行實例。
  • 它可以被啟用,開始,停止,刪除。每個容器都是相互隔離的,保證安全的平臺。
  • 可以把容器看作是一個簡易版的Linux系統(包括root用戶權限,進程空間,用戶空間和網絡空間等)和運行在其中的應用程序。
  • 容器的定義和鏡像幾乎一摸一樣,也是一堆層的統一視角,唯一區別在于容器的最上面那一層是可讀可寫的

倉庫(repository)

  • 倉庫是集中存放鏡像文件的場所。

  • 倉庫和倉庫注冊服務器(Registry)是有區別的,倉庫注冊服務器上往往存放著多個倉庫,每個倉庫中又包含了多個鏡像,每個鏡像有不同的標簽

  • 倉庫分為公開倉庫(public)和私有倉庫(private)兩種形式

  • 最大的開放倉庫是國外的 Docker Hub,存放了數量龐大的鏡像供用戶下載。

  • 國內的公開倉庫包括阿里云,網易云都有容器服務器(需要配置鏡像加速)等


2. 環境準備

要安裝Docker Engine,您需要CentOS 7或8的維護版本。不支持或未測試存檔版本。

這里為阿里云 CentOS7 服務器,用 XShell 連接遠程服務器工具

# 系統內核 [root@iZ2ze3zdx4jq8v6hetjjuxZ /]# uname -r 3.10.0-1127.13.1.el7.x86_64# 系統版本 [root@iZ2ze3zdx4jq8v6hetjjuxZ /]# cat /etc/os-release NAME="CentOS Linux" VERSION="7 (Core)" ID="centos" ID_LIKE="rhel fedora" VERSION_ID="7" PRETTY_NAME="CentOS Linux 7 (Core)" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:centos:centos:7" HOME_URL="https://www.centos.org/" BUG_REPORT_URL="https://bugs.centos.org/"CENTOS_MANTISBT_PROJECT="CentOS-7" CENTOS_MANTISBT_PROJECT_VERSION="7" REDHAT_SUPPORT_PRODUCT="centos" REDHAT_SUPPORT_PRODUCT_VERSION="7"


3. 安裝

官網安裝教程十分詳細,可參照此教程:https://docs.docker.com/engine/install/centos/

1. 卸載舊版本

sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine


yum報告沒有安裝這些軟件包,即可

2. 安裝Docker軟件包

sudo yum install -y yum-utils

3. 設置鏡像倉庫地址

# 默認是國外的 sudo yum-config-manager \--add-repo \https://download.docker.com/linux/centos/docker-ce.repo# 換成阿里云鏡像地址 sudo yum-config-manager \--add-repo \http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

4. 安裝最新版Docker Engine和容器

安裝前建議先將將服務器上的軟件包信息現在本地緩存,以提高安裝軟件的速度

sudo yum makecache fast

# docker-ce社區版(docker-ee企業版) sudo yum install docker-ce docker-ce-cli containerd.io


安裝完成后,Docker只安裝但并未啟動

5. 啟動Docker

sudo systemctl start docker

然后可用docker version命令測試Docker是否安裝成功,并查看Docker的版本信息

6. 運行Hello World映像測試

sudo docker run hello-world


我們可用docker images查看Docker所有的鏡像信息


4. 卸載Docker方法

1. 卸載Docker依賴

# 1、卸載Docker依賴: Docker Engine,CLI和Containerd軟件包 sudo yum remove docker-ce docker-ce-cli containerd.io

2. 刪除Docker資源

# 2、刪除Docker資源: 所有鏡像,容器和卷(主機上的鏡像,容器,卷或自定義配置文件不會自動刪除) sudo rm -rf /var/lib/docker

/var/lib/docker為Docker的默認工作路徑

5. 阿里云鏡像加速

登錄阿里云賬號,找到產品與服務下的彈性計算中的容器鏡像服務
點擊進入,找到左側欄 鏡像加速器,選擇對應的系統,便可看到對用的命令

然后就可配置使用,逐條執行以下命令

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


到此則配置完畢



三、Docker run的流程和底層原理

1. 流程圖

2. 底層原理

Docker是怎么工作的?

  • Docker 是一個 Client-Server 結構的系統,Docket 的守護進程運行在主機上,通過Socket從客戶端訪問
  • DockerServer 接收到 DockerClient 的指令,就會執行這個命令

Docker為什么比VM快?

  • Docker有著比虛擬機更少的抽象層,由于Docker不需要Hypervisor實現硬件資源虛擬化,運行在Docker容器上的程序直接使用的都是實際物理機的硬件資源,因此在Cpu、內存利用率上Docker將會在效率上有明顯優勢。

  • Docker利用的是宿主機的內核,而不需要Guest OS,因此,當新建一個容器時,Docker不需要和虛擬機一樣重新加載一個操作系統,避免了引導、加載操作系統內核這個比較費時費資源的過程,當新建一個虛擬機時,虛擬機軟件需要加載Guest OS,這個新建過程是分鐘級別的,而Docker由于直接利用宿主機的操作系統則省略了這個過程,因此新建一個Docker容器只需要幾秒鐘。

  • Docker容器虛擬機(VM)
    操作系統與宿主機共享OS宿主機OS上運行宿主機OS
    存儲大小鏡像小,便于存儲與傳輸鏡像龐大(vmdk等)
    運行性能幾乎無額外性能損失操作系統額外的cpu、內存消耗
    移植性輕便、靈活、適用于Linux笨重、與虛擬化技術耦合度高
    硬件親和性面向軟件開發者面向硬件運維者


    四、Docker常用命令

    幫助文檔地址:https://docs.docker.com/reference/

    1. 幫助命令

    # 顯示docker的版本信息 docker version# 顯示docker的系統信息(包括鏡像和容器數量) docker info# 幫助命令 docker 命令 --help

    2. 鏡像命令

    查看所有鏡像

    # 查看本地主機所有的鏡像 docker images

    測試:

    [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest bf756fb1ae65 12 months ago 13.3kB# 解釋 REPOSITORY 鏡像倉庫源 TAG 鏡像的標簽 IMAGE ID 鏡像的ID CREATED 鏡像的創建時間 SIZE 鏡像大小#可選項 --all , -a 列出所有鏡像 --quiet , -q 只顯示鏡像ID

    搜索鏡像

    # 搜索鏡像 docker search 鏡像名

    測試:

    [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker search mysql NAME DESCRIPTION STARS OFFICIAL AUTOMATED mysql MySQL is a widely used, open-source relation… 10414 [OK] mariadb MariaDB is a community-developed fork of MyS… 3865 [OK] mysql/mysql-server Optimized MySQL Server Docker images. Create… 762 [OK] percona Percona Server is a fork of the MySQL relati… 524 [OK] centos/mysql-57-centos7 MySQL 5.7 SQL database server 87 mysql/mysql-cluster Experimental MySQL Cluster Docker images. Cr… 79 centurylink/mysql Image containing mysql. Optimized to be link… 59 [OK] bitnami/mysql Bitnami MySQL Docker Image 47 [OK] deitch/mysql-backup REPLACED! Please use http://hub.docker.com/r… 41 [OK] databack/mysql-backup Back up mysql databases to... anywhere! 37 prom/mysqld-exporter 37 [OK] tutum/mysql Base docker image to run a MySQL database se… 35 schickling/mysql-backup-s3 Backup MySQL to S3 (supports periodic backup… 29 [OK] linuxserver/mysql A Mysql container, brought to you by LinuxSe… 27 circleci/mysql MySQL is a widely used, open-source relation… 20 centos/mysql-56-centos7 MySQL 5.6 SQL database server 20 arey/mysql-client Run a MySQL client from a docker container 17 [OK] mysql/mysql-router MySQL Router provides transparent routing be… 17 fradelg/mysql-cron-backup MySQL/MariaDB database backup using cron tas… 10 [OK] yloeffler/mysql-backup This image runs mysqldump to backup data usi… 7 [OK] openshift/mysql-55-centos7 DEPRECATED: A Centos7 based MySQL v5.5 image… 6 devilbox/mysql Retagged MySQL, MariaDB and PerconaDB offici… 3 ansibleplaybookbundle/mysql-apb An APB which deploys RHSCL MySQL 2 [OK] jelastic/mysql An image of the MySQL database server mainta… 1 widdpim/mysql-client Dockerized MySQL Client (5.7) including Curl… 1 [OK]# 可選項 -f, --filter filter 根據提供的條件過濾輸出 # 例如搜索STARS大于3000的 [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker search mysql -f STARS=3000 NAME DESCRIPTION STARS OFFICIAL AUTOMATED mysql MySQL is a widely used, open-source relation… 10414 [OK] mariadb MariaDB is a community-developed fork of MyS… 3865 [OK]

    下載鏡像

    # 下載鏡像 docker pull 鏡像名[:tag]

    測試:

    # 不指定版本號默認下載最新版latest [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker pull mysql Using default tag: latest latest: Pulling from library/mysql a076a628af6f: Pull complete #分層下載,docker image的核心:聯合文件系統 f6c208f3f991: Pull complete 88a9455a9165: Pull complete 406c9b8427c6: Pull complete 7c88599c0b25: Pull complete 25b5c6debdaf: Pull complete 43a5816f1617: Pull complete 1a8c919e89bf: Pull complete 9f3cf4bd1a07: Pull complete 80539cea118d: Pull complete 201b3cad54ce: Pull complete 944ba37e1c06: Pull complete Digest: sha256:feada149cb8ff54eade1336da7c1d080c4a1c7ed82b5e320efb5beebed85ae8c Status: Downloaded newer image for mysql:latest docker.io/library/mysql:latest #真實地址# 指定版本號下載 [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker pull mysql:5.7 5.7: Pulling from library/mysql a076a628af6f: Already exists f6c208f3f991: Already exists 88a9455a9165: Already exists 406c9b8427c6: Already exists 7c88599c0b25: Already exists 25b5c6debdaf: Already exists 43a5816f1617: Already exists 1831ac1245f4: Pull complete 37677b8c1f79: Pull complete 27e4ac3b0f6e: Pull complete 7227baa8c445: Pull complete Digest: sha256:b3d1eff023f698cd433695c9506171f0d08a8f92a0c8063c1a4d9db9a55808df Status: Downloaded newer image for mysql:5.7 docker.io/library/mysql:5.7

    下載完再次查看所有鏡像,即可看到剛下載的鏡像

    刪除鏡像

    # 刪除鏡像 docker rmi`docker rmi -f 鏡像id`:刪除指定鏡像`docker rmi -f 鏡像id 鏡像id 鏡像id`:刪除指定多個鏡像`docker rmi -f $(docker images -aq)`:刪除全部鏡像

    測試:

    [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mysql 5.7 a70d36bc331a 5 days ago 449MB mysql latest c8562eaf9d81 5 days ago 546MB hello-world latest bf756fb1ae65 12 months ago 13.3kB #刪除指定鏡像 [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker rmi -f a70d36bc331a Untagged: mysql:5.7 Untagged: mysql@sha256:b3d1eff023f698cd433695c9506171f0d08a8f92a0c8063c1a4d9db9a55808df Deleted: sha256:a70d36bc331a13d297f882d3d63137d24b804f29fa67158c40ad91d5050c39c5 Deleted: sha256:50c77bf7bcddd1f1d97789d80ac2404eec22c860c104e858620d2a2e321f0ef7 Deleted: sha256:14244329b83dfc8982398ee4104a548385652d2bffb957798ff86a419013efd6 Deleted: sha256:6d990477f90af28473eb601a9bca22253f6381e053c5a8edda0a4f027e124a3c Deleted: sha256:ee0449796df204071589162fc16f8d65586312a40c68d1ba156c93c56f5e5ce8 [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mysql latest c8562eaf9d81 5 days ago 546MB hello-world latest bf756fb1ae65 12 months ago 13.3kB #刪除所有鏡像 [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker rmi -f $(docker images -aq) Untagged: mysql:latest Untagged: mysql@sha256:feada149cb8ff54eade1336da7c1d080c4a1c7ed82b5e320efb5beebed85ae8c Deleted: sha256:c8562eaf9d81c779cbfc318d6e01b8e6f86907f1d41233268a2ed83b2f34e748 Deleted: sha256:1b649b85960473808c6b812fc30c3f6a3ff1c0ffdcba5c9435daf01cf7d5373a Deleted: sha256:19cc889447050c16c797fd209fa114ee219de23facb37c00d4137a4ed4aad922 Deleted: sha256:3c793c06a026d276cf56a6a6a75527026ed9eafa7a7d21a438f7d5ed2314148e Deleted: sha256:1e1cd89a2bc183a7fea3dab0b543e9924278321ad0921c22cc088adbf3c2e77b Deleted: sha256:83b2015dfd000588c7c947b2d89b3be7a8e5a3abc6ab562668c358033aa779ec Deleted: sha256:d08533f1e2acc40ad561a46fc6a76b54c739e6b24f077c183c5709e0a6885312 Deleted: sha256:4f9d91a4728e833d1062fb65a792f06e22e425f63824f260c8b5a64b776ddc38 Deleted: sha256:20bf4c759d1b0d0e6286d2145453af4e0e1b7ba3d4efa3b8bce46817ad4109de Deleted: sha256:a9371bbdf16ac95cc72555c6ad42f79b9f03a82d964fe89d52bdc5f335a5f42a Deleted: sha256:5b02130e449d94f51e8ff6e5f7d24802246198749ed9eb064631e63833cd8f1d Deleted: sha256:ab74465b38bc1acb16c23091df32c5b7033ed55783386cb57acae8efff9f4b37 Deleted: sha256:cb42413394c4059335228c137fe884ff3ab8946a014014309676c25e3ac86864 Untagged: hello-world:latest Untagged: hello-world@sha256:d58e752213a51785838f9eed2b7a498ffa1cb3aa7f946dda11af39286c3db9a9 Deleted: sha256:bf756fb1ae65adf866bd8c456593cd24beb6a0a061dedf42b26a993176745f6b [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE

    3. 容器命令

    有了鏡像才能夠創建容器,這里下載一個centos鏡像為以下測試做準備

    [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker pull centos Using default tag: latest latest: Pulling from library/centos 7a0437f04f83: Pull complete Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1 Status: Downloaded newer image for centos:latest docker.io/library/centos:latest

    新建容器并啟動

    # 新建容器并啟動 docker run [可選參數] image# 參數說明 --name="Name" 容器名字,用于區分容器 -d 后臺方式運行 -it 使用交互方式運行,進入容器查看內容 -p 指定容器端口(小寫)-p ip:主機端口:容器端口-p 主機端口:容器端口(最常用)-P 容器端口容器端口 -P 隨機執行端口(大寫)

    測試:

    #測試,啟動進入容器 [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker run -it centos /bin/bash [root@22d0484830c9 /]# ls 查看容器內的centos,基礎版本,很多命令不完善 bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var#退出容器到主機 [root@22d0484830c9 /]# exit exit [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# ls 3000 cp cp.tar.gz f.sh hello.c install.sh login.sh read.sh time.sh

    列出所有運行的容器

    # 列出所有運行的容器 docker ps [可選參數]# 參數說明 -a 列出當前正在運行以及歷史運行過的容器 -n=? 顯示最近創建的容器 -q 只顯示容器編號 [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 22d0484830c9 centos "/bin/bash" About a minute ago Exited (0) About a minute ago condescending_mcnulty 3efe49d28bdd bf756fb1ae65 "/hello" 7 hours ago Exited (0) 7 hours ago confident_babbage 40fc94e7b0a4 bf756fb1ae65 "/hello" 7 months ago Exited (0) 7 months ago inspiring_lovelace [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker ps -n=1 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 22d0484830c9 centos "/bin/bash" 4 minutes ago Exited (0) 3 minutes ago condescending_mcnulty [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker ps -aq 22d0484830c9 3efe49d28bdd 40fc94e7b0a4

    退出容器

    # 容器停止并退出 exit# 容器不停止退出 Ctrl+p+q

    刪除容器

    # 刪除指定容器,不能刪除正在運行的容器,強制刪除用rm -f docker rm 容器id # 刪除所有容器 docker rm -f $(docker ps -aq) docker ps -a -q|xargs docker rm

    測試:

    [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker ps -aq 6518909c5fb2 3dfd73738e3b 22d0484830c9 3efe49d28bdd 40fc94e7b0a4 [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker rm 6518909c5fb2 6518909c5fb2 [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker ps -aq 3dfd73738e3b 22d0484830c9 3efe49d28bdd 40fc94e7b0a4 [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker rm -f $(docker ps -aq) 3dfd73738e3b 22d0484830c9 3efe49d28bdd 40fc94e7b0a4 [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker ps -aq

    啟動停止容器

    docker start 容器id # 啟動容器 docker restart 容器id # 重啟容器 docker stop 容器id # 停止正在運行的容器 docker kill 容器id # 強制停止當前容器

    4. 常用其他命令

    后臺啟動容器

    # 后臺啟動容器 docker run -d 容器名

    測試:

    [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker run -d centos 9606d8980f73ff313c64388f5f82e036072cc7191c3305ab80b371e37d8b1ad7 [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9606d8980f73 centos "/bin/bash" 54 seconds ago Exited (0) 53 seconds ago youthful_dubinsky
    • 問題:后臺啟動容器,再用 docker ps 查看發現容器停止
    • 原因:docker 容器使用后臺運行,就必須有一個前臺進程;如果僅僅后臺啟動,沒有應用來提供服務,就會自動停止

    查看日志

    docker logs [可選參數] 容器ID--details 顯示提供給日志的其他詳細信息-f, --follow 跟蹤日志輸出-n, --tail string 指定要顯示的日志條數 (默認為全部)-t, --timestamps 顯示時間戳

    測試:

    # 后臺啟動容器,同時執行腳本不停打印zsr [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker run -d centos /bin/bash -c "while true;do echo zsr;sleep 1;done" 980daf06de5878e2d3e5c048c7de92817e09e92f20d2d6242ecb15b9b7a5bd02 # 查看運行的容器,此時可以查看到 [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 980daf06de58 centos "/bin/bash -c 'while…" 6 seconds ago Up 6 seconds distracted_germain # 查看日志信息,顯示時間戳,指定顯示10條日志 [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker logs -t -n 10 980daf06de58 2021-01-25T04:53:47.619357189Z zsr 2021-01-25T04:53:48.621476433Z zsr 2021-01-25T04:53:49.623833490Z zsr 2021-01-25T04:53:50.626253957Z zsr 2021-01-25T04:53:51.628526460Z zsr 2021-01-25T04:53:52.630878536Z zsr 2021-01-25T04:53:53.633046201Z zsr 2021-01-25T04:53:54.635296632Z zsr 2021-01-25T04:53:55.637614256Z zsr 2021-01-25T04:53:56.640358130Z zsr

    查看容器中的進程

    # 查看容器中的進程 docker top 容器ID

    測試:

    [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker top 980daf06de58 UID PID PPID C STIME TTY TIME CMD root 28359 28339 0 12:52 ? 00:00:00 /bin/bash -c while true;do echo zsr;sleep 1;done root 29065 28359 0 12:58 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1

    查看鏡像元數據

    # 查看鏡像元數據 docker inspect 容器ID

    測試:

    [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker inspect 980daf06de58 [{"Id": "980daf06de5878e2d3e5c048c7de92817e09e92f20d2d6242ecb15b9b7a5bd02","Created": "2021-01-25T04:52:46.079489883Z","Path": "/bin/bash","Args": ["-c","while true;do echo zsr;sleep 1;done"],"State": {"Status": "running","Running": true,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 28359,"ExitCode": 0,"Error": "","StartedAt": "2021-01-25T04:52:46.469990116Z","FinishedAt": "0001-01-01T00:00:00Z"},"Image": "sha256:300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55","ResolvConfPath": "/var/lib/docker/containers/980daf06de5878e2d3e5c048c7de92817e09e92f20d2d6242ecb15b9b7a5bd02/resolv.conf","HostnamePath": "/var/lib/docker/containers/980daf06de5878e2d3e5c048c7de92817e09e92f20d2d6242ecb15b9b7a5bd02/hostname","HostsPath": "/var/lib/docker/containers/980daf06de5878e2d3e5c048c7de92817e09e92f20d2d6242ecb15b9b7a5bd02/hosts","LogPath": "/var/lib/docker/containers/980daf06de5878e2d3e5c048c7de92817e09e92f20d2d6242ecb15b9b7a5bd02/980daf06de5878e2d3e5c048c7de92817e09e92f20d2d6242ecb15b9b7a5bd02-json.log","Name": "/distracted_germain","RestartCount": 0,"Driver": "overlay2","Platform": "linux","MountLabel": "","ProcessLabel": "","AppArmorProfile": "","ExecIDs": null,"HostConfig": {"Binds": null,"ContainerIDFile": "","LogConfig": {"Type": "json-file","Config": {}},"NetworkMode": "default","PortBindings": {},"RestartPolicy": {"Name": "no","MaximumRetryCount": 0},"AutoRemove": false,"VolumeDriver": "","VolumesFrom": null,"CapAdd": null,"CapDrop": null,"CgroupnsMode": "host","Dns": [],"DnsOptions": [],"DnsSearch": [],"ExtraHosts": null,"GroupAdd": null,"IpcMode": "private","Cgroup": "","Links": null,"OomScoreAdj": 0,"PidMode": "","Privileged": false,"PublishAllPorts": false,"ReadonlyRootfs": false,"SecurityOpt": null,"UTSMode": "","UsernsMode": "","ShmSize": 67108864,"Runtime": "runc","ConsoleSize": [0,0],"Isolation": "","CpuShares": 0,"Memory": 0,"NanoCpus": 0,"CgroupParent": "","BlkioWeight": 0,"BlkioWeightDevice": [],"BlkioDeviceReadBps": null,"BlkioDeviceWriteBps": null,"BlkioDeviceReadIOps": null,"BlkioDeviceWriteIOps": null,"CpuPeriod": 0,"CpuQuota": 0,"CpuRealtimePeriod": 0,"CpuRealtimeRuntime": 0,"CpusetCpus": "","CpusetMems": "","Devices": [],"DeviceCgroupRules": null,"DeviceRequests": null,"KernelMemory": 0,"KernelMemoryTCP": 0,"MemoryReservation": 0,"MemorySwap": 0,"MemorySwappiness": null,"OomKillDisable": false,"PidsLimit": null,"Ulimits": null,"CpuCount": 0,"CpuPercent": 0,"IOMaximumIOps": 0,"IOMaximumBandwidth": 0,"MaskedPaths": ["/proc/asound","/proc/acpi","/proc/kcore","/proc/keys","/proc/latency_stats","/proc/timer_list","/proc/timer_stats","/proc/sched_debug","/proc/scsi","/sys/firmware"],"ReadonlyPaths": ["/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]},"GraphDriver": {"Data": {"LowerDir": "/var/lib/docker/overlay2/c836c661b72e93a97b704d62711facfd82b4f080359405a4382a8dca3f7ce2ed-init/diff:/var/lib/docker/overlay2/e7eaf7928b9265d758185f4ac2e84ab99cb6146cbf37d10a9d9b3ce1ad30ab3e/diff","MergedDir": "/var/lib/docker/overlay2/c836c661b72e93a97b704d62711facfd82b4f080359405a4382a8dca3f7ce2ed/merged","UpperDir": "/var/lib/docker/overlay2/c836c661b72e93a97b704d62711facfd82b4f080359405a4382a8dca3f7ce2ed/diff","WorkDir": "/var/lib/docker/overlay2/c836c661b72e93a97b704d62711facfd82b4f080359405a4382a8dca3f7ce2ed/work"},"Name": "overlay2"},"Mounts": [],"Config": {"Hostname": "980daf06de58","Domainname": "","User": "","AttachStdin": false,"AttachStdout": false,"AttachStderr": false,"Tty": false,"OpenStdin": false,"StdinOnce": false,"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd": ["/bin/bash","-c","while true;do echo zsr;sleep 1;done"],"Image": "centos","Volumes": null,"WorkingDir": "","Entrypoint": null,"OnBuild": null,"Labels": {"org.label-schema.build-date": "20201204","org.label-schema.license": "GPLv2","org.label-schema.name": "CentOS Base Image","org.label-schema.schema-version": "1.0","org.label-schema.vendor": "CentOS"}},"NetworkSettings": {"Bridge": "","SandboxID": "6a7fa868d1b07689ed1307cd6eaffa3d102c13440bddf41b7eedd526a328f03e","HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"Ports": {},"SandboxKey": "/var/run/docker/netns/6a7fa868d1b0","SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "ab462efd8637f15fd7aabe6250429571db2f4dc22e3248278dbe513af5e47e38","Gateway": "172.18.0.1","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"IPAddress": "172.18.0.2","IPPrefixLen": 16,"IPv6Gateway": "","MacAddress": "02:42:ac:12:00:02","Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "0524bfb4e90c798594ceca6e4099d5b1407f7dcef80435f023f4a1963a35fbb4","EndpointID": "ab462efd8637f15fd7aabe6250429571db2f4dc22e3248278dbe513af5e47e38","Gateway": "172.18.0.1","IPAddress": "172.18.0.2","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:12:00:02","DriverOpts": null}}}} ]

    進入當前正在運行的容器

    容器通常都是使用后臺方式運行的,這時候可能需要進入容器,修改一些配置

    # 方式一: 進入容器后開啟一個新的終端,可在里面進行操作(常用) docker exec -it 容器id /bin/bash# 方式二: 進入容器正在執行的終端,不會啟動新的進程 docker attach 容器ID

    測試:

    # 測試方式一 [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 980daf06de58 centos "/bin/bash -c 'while…" 2 hours ago Up 2 hours distracted_germain # 進入到容器 [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker exec -it 980daf06de58 /bin/bash [root@980daf06de58 /]# ls bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var# 測試方式二 [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 980daf06de58 centos "/bin/bash -c 'while…" 2 hours ago Up 2 hours distracted_germain [root@iZ2ze3zdx4jq8v6hetjjuxZ ~]# docker attach 980daf06de58 zsr zsr zsr zsr zsr zsr zsr #進入死循環...

    從容器內拷貝文件到主機

    # 從容器內拷貝文件到主機 docker cp 容器id:容器內路徑 目的主機路徑

    測試:

    [root@iZ2ze3zdx4jq8v6hetjjuxZ home]# docker run -it centos /bin/bash [root@64b40f051756 /]# cd /home [root@64b40f051756 home]# ls # 在容器內部新建一個文件 [root@64b40f051756 home]# touch 1.txt [root@64b40f051756 home]# exit exit [root@iZ2ze3zdx4jq8v6hetjjuxZ home]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@iZ2ze3zdx4jq8v6hetjjuxZ home]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 64b40f051756 centos "/bin/bash" 4 minutes ago Exited (0) 59 seconds ago beautiful_ganguly c1b3f151ae12 centos "/bin/bash" 7 minutes ago Exited (127) 4 minutes ago nervous_lamarr 60b1f058de74 centos "/bin/bash" 14 minutes ago Exited (0) 12 minutes ago vibrant_jemison 980daf06de58 centos "/bin/bash -c 'while…" 2 hours ago Exited (137) 14 minutes ago distracted_germain d77c3cdfb7e2 centos "/bin/bash -c 'while…" 3 hours ago Exited (137) 2 hours ago relaxed_meninsky 7706ccced225 centos "/bin/bash -c 'whilr…" 3 hours ago Exited (1) 3 hours ago romantic_hopper 6eebf828ab4c centos "/bin/bash -c 'whilr…" 3 hours ago Exited (1) 3 hours ago brave_goldberg df422d73861f centos "/bin/bash" 3 hours ago Exited (0) 3 hours ago frosty_panini 744b9b044715 centos "/bin/bash" 3 hours ago Exited (127) 3 hours ago amazing_cori 9606d8980f73 centos "/bin/bash" 3 hours ago Exited (0) 3 hours ago youthful_dubinsky [root@iZ2ze3zdx4jq8v6hetjjuxZ home]# cd /home [root@iZ2ze3zdx4jq8v6hetjjuxZ home]# ls redis www zsr # 將容器內創建的1.txt拷貝到主機 [root@iZ2ze3zdx4jq8v6hetjjuxZ home]# docker cp 64b40f051756:/home/1.txt /home [root@iZ2ze3zdx4jq8v6hetjjuxZ home]# ls 1.txt redis www zsr

    五、Docker命令實戰

    1. 部署Nginx

    # 1. 搜索鏡像 docker search nginx# 2. 下載鏡像 docker pull nginx# 3. 查看鏡像是否下載成功 docker images# 4. 啟動容器(-d:后臺運行 --name:容器名 -p:暴露端口 宿主機端口3344:容器端口80) docker run -d --name nginx01 -p 3344:80 nginx# 5. 查看容器是否啟動 docker ps# 6. 本機測試 curl localhost:3344

    完整代碼:

    # 1. 搜索鏡像 [root@iZ2ze3zdx4jq8v6hetjjuxZ home]# docker search nginx -f STARS=6000 NAME DESCRIPTION STARS OFFICIAL AUTOMATED nginx Official build of Nginx. 14341 [OK] # 2. 下載鏡像 [root@iZ2ze3zdx4jq8v6hetjjuxZ home]# docker pull nginx Using default tag: latest latest: Pulling from library/nginx a076a628af6f: Pull complete 0732ab25fa22: Pull complete d7f36f6fe38f: Pull complete f72584a26f32: Pull complete 7125e4df9063: Pull complete Digest: sha256:10b8cc432d56da8b61b070f4c7d2543a9ed17c2b23010b43af434fd40e2ca4aa Status: Downloaded newer image for nginx:latest docker.io/library/nginx:latest# 3. 查看鏡像是否下載成功 [root@iZ2ze3zdx4jq8v6hetjjuxZ home]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest f6d0b4767a6c 12 days ago 133MB centos latest 300e315adb2f 6 weeks ago 209MB# 4. 啟動容器(-d:后臺運行 --name:容器名 -p:暴露端口 宿主機端口3344:容器端口80) [root@iZ2ze3zdx4jq8v6hetjjuxZ home]# docker run -d --name nginx01 -p 3344:80 nginx 1f9dbdf7f36d69731578314cd861eeed776174ea839100ae2f8987f1bd1b509a# 5. 查看容器是否啟動 [root@iZ2ze3zdx4jq8v6hetjjuxZ home]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1f9dbdf7f36d nginx "/docker-entrypoint.…" 8 seconds ago Up 7 seconds 0.0.0.0:3344->80/tcp nginx01# 6. 本機測試 [root@iZ2ze3zdx4jq8v6hetjjuxZ home]# curl localhost:3344 <!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># 進入容器 [root@iZ2ze3zdx4jq8v6hetjjuxZ home]# docker exec -it nginx01 /bin/bash root@1f9dbdf7f36d:/# whereis nginx nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx root@1f9dbdf7f36d:/# cd /etc/nginx/ root@1f9dbdf7f36d:/etc/nginx# ls conf.d fastcgi_params koi-utf koi-win mime.types modules nginx.conf scgi_params uwsgi_params win-utf

    2. 部署Tomcat

    # 官方使用 # 之前我們都是后臺啟動,停止容器后,仍可以通過docker ps -a命令查到容器的使用記錄 # --rm表示用完就刪除容器及歷史記錄,通過命令查不到; docker run -it --rm tomcat:9.0 # tomcat啟動運行 [root@zsr home]# docker run -d -p 3355:8080 --name tomcat01 tomcat Unable to find image 'tomcat:latest' locally latest: Pulling from library/tomcat Digest: sha256:94cc18203335e400dbafcd0633f33c53663b1c1012a13bcad58cced9cd9d1305 Status: Downloaded newer image for tomcat:latest ffc2e1098b06fc0c0eb259fd93801e97087cbc33d0034a534208a44c491ab7a3 # 進入容器,發現webapps為空 [root@zsr home]# docker exec -it tomcat01 /bin/bash root@ffc2e1098b06:/usr/local/tomcat# ls BUILDING.txt LICENSE README.md RUNNING.txt conf logs temp webapps.dist CONTRIBUTING.md NOTICE RELEASE-NOTES bin lib native-jni-lib webapps work root@ffc2e1098b06:/usr/local/tomcat# cd webapps root@ffc2e1098b06:/usr/local/tomcat/webapps# ls

    3. 部署es+kibana

    # es暴露的端口很多 # es十分耗內存 # es的數據一般需要放置在安全目錄!掛載# 啟動elasticsearch容器(啟動后會很卡頓,因為很占內存) docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2# 監控容器資源消耗(該命令也十分耗資源,服務器卡死) docker stats [容器ID]

    可以看到內存占用率很高;這時候趕緊關閉容器,增加內存的限制,再重新啟動一個容器

    # 重新啟動elasticsearch容器,增加內存限制(-e ES_JAVA_OPTS="-Xms64m -Xmx512m" 最小64m 最大512m),防止服務器卡死 docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2# 查看運行的容器 [root@zsr ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b6e7bc8063a5 elasticsearch:7.6.2 "/usr/local/bin/dock…" 39 seconds ago Up 37 seconds 0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp elasticsearch01# 監控容器資源消耗 [root@zsr ~]# docker stats b6e7bc8063a5


    可以看到內存占用被限制住,也不再卡了



    六、Portainer可視化面板

    1. 什么是 portainer ?

    Docker 圖形化界面管理工具,提供一個后臺面板供我們操作

    portainer(先用這個,不是最佳選項;學習CI/CD時再用 Rancher)

    2. 下載

    docker run -d -p 8088:9000 \ --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

    3. 訪問測試

    我們用docker ps命令查看一下正在運行的容器,可以看到 portainer 正在運行

    [root@zsr ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b72d6033ae2e portainer/portainer "/portainer" 25 seconds ago Up 23 seconds 0.0.0.0:8088->9000/tcp vibrant_dhawan

    這時候我們訪問外網8088端口測試一下,這里訪問 阿里云服務器公網ip:8088 (注意安全組打開8088端口),就會出現如下界面

    然后自己設置一個密碼創建用戶登錄

    然后選擇 Local,再點擊 Connect

    然后就進入了后臺管理界面



    七、Docker鏡像講解

    1. 鏡像是什么

    鏡像 是一種輕量級,可執行的軟件包,用來打包軟件運行環境和基于運行軟件開發的軟件,它包含運行某個軟件所需的所有內容,包括代碼、運行時、庫、環境變量和配置文件。

    所有的應用,直接打包成docker鏡像,就可以直接跑起來

    如何獲取鏡像

    • 從遠程倉庫下載
    • 自己制作一個 Dockerfile

    2. Docker鏡像加載原理

    UnionFS(聯合文件系統):一種分層、輕量級且高性能的文件系統,它支持對文件系統的修改作為一次提交來一層層的疊加,同時可以將不通目錄掛載到同一個虛擬文件系統下(unite serveral directories into a single virtual filesystem)。Union 文件系統是 Docker 鏡像的基礎,鏡像可以通過分層來繼承,基于基礎鏡像(沒有父鏡像),可以制作各種具體的應用鏡像。

    特性:一次同時加載多個文件系統,但從外面看起來,只能看到一個文件系統,聯合加載會把各層文件系統疊加起來,這樣最終的文件系統會包含所有底層的文件和目錄。

    Docker 的鏡像實際上由一層一層的文件系統組成,這種層級的文件系統就是 UnionFS 。

    bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引導加載kerel,Linux剛啟動時會加載 bootfs文件系統,在Docker鏡像的最底層時bootfs。這一層與我們典型的Linux/Unix內核是一樣的,包含boot加載器和內核。當boot加載完成之后整個內核就都在內存中了,此時內存的使用權已由bootfs轉交給內核,此時系統也會卸載bootfs

    rootfs(root file system)在bootfs之上,包含的就是典型的 Linux系統中的 /dev、/proc、/bin、/etc 等標準文件。rootfs 就是各種不同的操作系統發行版。


    平時安裝的虛擬機的CentOS都是好幾個G,為什么Docker中才200MB?

    對于一個精簡的 OS,rootfs 可以很小,只需要包含最基本的命令、工具和程序庫就可以了,因為底層使用的是主機的Kernel,自己只需要提供rootfs就可以了。由此可見,對于不同linux發行版,bootfs是基本一致的,rootfs會有差別,因此不同的發行版可以公用bootfs


    3. 分層理解

    下載示例

    當我們下載一個鏡像的時候,可以看到,是一層一層的在下載!

    為什么Docker鏡像要采取這種分層的結構呢?

    資源共享:如果有多個鏡像從相同的Base鏡像構建而來,那么宿主機只需要在磁盤上保留一份base鏡像,同時內存中也只需要加載一份base鏡像,這樣就可以為所有的容器服務,且每一層的鏡像都可以被共享。

    • 查看鏡像分層方式可以通過docker image inspect命令

      [root@zsr ~]# docker image inspect mysql:latest [{"Id": "sha256:c8562eaf9d81c779cbfc318d6e01b8e6f86907f1d41233268a2ed83b2f34e748","RepoTags": ["mysql:latest"],"RepoDigests": ["mysql@sha256:feada149cb8ff54eade1336da7c1d080c4a1c7ed82b5e320efb5beebed85ae8c"],"Parent": "","Comment": "","Created": "2021-01-18T23:25:55.311110441Z","Container": "1b772a9e2045f2e123c3ff1d11cc67c9a5fe78b33af9f6a9213aa8cf91f58a6b","ContainerConfig": {"Hostname": "1b772a9e2045","Domainname": "","User": "","AttachStdin": false,"AttachStdout": false,"AttachStderr": false,"ExposedPorts": {"3306/tcp": {},"33060/tcp": {}},"Tty": false,"OpenStdin": false,"StdinOnce": false,"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","GOSU_VERSION=1.12","MYSQL_MAJOR=8.0","MYSQL_VERSION=8.0.23-1debian10"],"Cmd": ["/bin/sh","-c","#(nop) ","CMD [\"mysqld\"]"],"Image": "sha256:ec58f145c941b51747ba729ab510ff01ca99fa797ec6f4bb8830f6e878e5c66e","Volumes": {"/var/lib/mysql": {}},"WorkingDir": "","Entrypoint": ["docker-entrypoint.sh"],"OnBuild": null,"Labels": {}},"DockerVersion": "19.03.12","Author": "","Config": {"Hostname": "","Domainname": "","User": "","AttachStdin": false,"AttachStdout": false,"AttachStderr": false,"ExposedPorts": {"3306/tcp": {},"33060/tcp": {}},"Tty": false,"OpenStdin": false,"StdinOnce": false,"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","GOSU_VERSION=1.12","MYSQL_MAJOR=8.0","MYSQL_VERSION=8.0.23-1debian10"],"Cmd": ["mysqld"],"Image": "sha256:ec58f145c941b51747ba729ab510ff01ca99fa797ec6f4bb8830f6e878e5c66e","Volumes": {"/var/lib/mysql": {}},"WorkingDir": "","Entrypoint": ["docker-entrypoint.sh"],"OnBuild": null,"Labels": null},"Architecture": "amd64","Os": "linux","Size": 546118644,"VirtualSize": 546118644,"GraphDriver": {"Data": {"LowerDir": "/var/lib/docker/overlay2/468543c2b5fe15aad545f6f06c1a9447f7f12d9c4d846fd2a52cb7e777f95366/diff:/var/lib/docker/overlay2/b9d1aafa99f328fd606f9bc36617d8248d8b66abfe28b61ee29c7f3bb077992f/diff:/var/lib/docker/overlay2/63e10d9d7feec935439a9e001c681fdde27ce10a178b25c486acca518a4fbe4f/diff:/var/lib/docker/overlay2/f6e3f6c93b7d6e5470453603e17b3275677297d7c85edbe1a3ac742454d7a7ff/diff:/var/lib/docker/overlay2/59b36124a39b50c0f2b6c0543a0c4ee1ff6aeaa888f5debaf4ce22c38eaee34f/diff:/var/lib/docker/overlay2/ccff5c078d0a22a57e230f31c1794c6afa643697f9304ba588c301fdbe801ac0/diff:/var/lib/docker/overlay2/98dae5544da3f76f7754d291a7b5532955f06d0f70e7b18d8b962ad8f7800c9e/diff:/var/lib/docker/overlay2/4e76b3dfd15a940cc6c1cd1259f874286c3552eb3bcaa860ead70bbac102b999/diff:/var/lib/docker/overlay2/a95a0edca5d7b3a2b76349964602101194998b4d73b52da526a6067b49240ce3/diff:/var/lib/docker/overlay2/14ebff0838af4ff47eed6e8c712608b48ece23b8262043cd03391819bf2223ae/diff:/var/lib/docker/overlay2/9d91a52dd5189c9f9b4f731398fe1752b3a19155c569222c008dcb58ed214b43/diff","MergedDir": "/var/lib/docker/overlay2/dc057fc0332771f0a3b2e5f7a94c6bb3624e9a93cd350825c7816a378d312d77/merged","UpperDir": "/var/lib/docker/overlay2/dc057fc0332771f0a3b2e5f7a94c6bb3624e9a93cd350825c7816a378d312d77/diff","WorkDir": "/var/lib/docker/overlay2/dc057fc0332771f0a3b2e5f7a94c6bb3624e9a93cd350825c7816a378d312d77/work"},"Name": "overlay2"},"RootFS": {"Type": "layers","Layers": ["sha256:cb42413394c4059335228c137fe884ff3ab8946a014014309676c25e3ac86864","sha256:ef4a33cee7a02ffa3c1dd5d2618dcb95e37b899fb7e90d0bb2df32a37396e174","sha256:74c86dffd46f095d4961730b731a33b19c1abd19f0a7ec1b81ddf09e6d3dfe85","sha256:6d23902c2a54f36f80946d7225044b2681bac18570af3a58970e325b40ac0d60","sha256:c484a3b6d84133f3618780f11216facc49f743cefc86e04409f28784a3a0a733","sha256:0394a41efa739604258181808606eb47798a83383ff52241547583939ffb297c","sha256:98d98806c8acefda16226c37045e3733a751c3cb165fde1182cbc324cde06f78","sha256:d35a1217c926c4d5fc2e8a9f914e565d46a1da65f461e5cb9f09f7b34953bb97","sha256:9577a2d5d759695f1b0e92efd95e7e46b1ac4c4c75350bac0045c94bd308732a","sha256:d60ed0726e3751a08f8d1d1696f51bb3ac47276b2c4f271272f167f532b4285a","sha256:ab82e085fd825c64ed10839fcae191d2169657b9585438676d1f54fb626162be","sha256:c080af299e3f1cab9e0bbe183259aa64014e6c560fea1c0534ffe95b0180b2a3"]},"Metadata": {"LastTagTime": "0001-01-01T00:00:00Z"}} ]

      其中Layers就表示了每一層

    理解

    • 所有的 Docker鏡像都起始于一個基礎鏡像層,當進行修改或增加新的內容時,就會在當前鏡像層之上創建新的鏡像層

    • 舉一個簡單的例子,假如基于 Ubuntu Linux 16.04 創建一個新的鏡像,這就是新鏡像的第一層;如果要在該鏡像中添加python包,就會在基礎鏡像層之上創建了新的一個鏡像層;如果繼續添加一個安全補丁,就會創建第三個鏡像層


      在添加額外的鏡像層的同時,鏡像始終保持是當前所有鏡像的組合。下圖中舉了一個簡單的例子,每個鏡像層包含 3 個文件,而鏡像包含了來自兩個鏡像層的 6 個文件

      上圖中的鏡像層跟之前圖中的略有區別,主要目的是便于展示文件。
      下圖中展示了一個稍微復雜的三層鏡像,在外部看來整個鏡像只有 6 個文件,這是因為最上層中的文件7 是文件 5 的一個更新版本

      這種情況下,上層鏡像層中的文件覆蓋了底層鏡像層中的文件。這樣就使得文件的更新版本作為一個新鏡像層添加到鏡像當中。
      Docker 通過存儲引擎(新版本采用快照機制)的方式來實現鏡像層堆棧,并保證多鏡像層對外展示為統一的文件系統。
      Linux 上可用的存儲引擎有 AUFS、Overlay2、Device Mapper、Btrfs 以及 ZFS。顧名思義,每種存儲引擎都基于 Linux 中對應的文件系統或者塊設備技術,并且每種存儲引擎都有其獨有的性能特點。
      Docker 在 Windows 上僅支持 windowsfilter 一種存儲引擎,該引擎基于 NTFS 文件系統之上實現了分層和 CoW[1]。
      下圖展示了與系統顯示相同的三層鏡像。所有鏡像層堆疊并合并,對外提供統一的視圖。

    特點

    Docker鏡像都是只讀的,當容器啟動時,一個新的可寫層被加載到鏡像的頂部!

    這一層就是我們通常說的容器層,容器之下的都叫鏡像層!


    4. Commit鏡像

    當我們通過鏡像啟動一個容器時,分為了兩層:容器層和鏡像層;鏡像層是可讀的,容器層可寫,我們的所有操作都是基于容器層,當我們對容器層修改完后,就可以再將修改后的容器層和不變的鏡像曾一起打包成一個新的鏡像,也就是本節要講的Commit鏡像

    # 提交容器成為一個新的副本 docker commit docker commit -m="提交的描述信息" -a="作者" 容器id 目標鏡像名:[TAG]

    實戰測試:

    # 啟動一個默認的Tomcat [root@zsr ~]# docker run -it -p 8088:8080 tomcat /bin/bash root@2594ca9eefcb:/usr/local/tomcat# cd webapps root@2594ca9eefcb:/usr/local/tomcat/webapps# ls root@2594ca9eefcb:/usr/local/tomcat/webapps# cd ..# 發現這個默認的Tomcat沒有webapps應用(官方鏡像默認沒有) root@2594ca9eefcb:/usr/local/tomcat# cd webapps root@2594ca9eefcb:/usr/local/tomcat/webapps# ls# 從webapps.dist拷貝到webapps中,使其有基本文件 root@2594ca9eefcb:/usr/local/tomcat/webapps# cd .. root@2594ca9eefcb:/usr/local/tomcat# ls BUILDING.txt LICENSE README.md RUNNING.txt conf logs temp webapps.dist CONTRIBUTING.md NOTICE RELEASE-NOTES bin lib native-jni-lib webapps work root@2594ca9eefcb:/usr/local/tomcat# cp -r webapps.dist/* webapps root@2594ca9eefcb:/usr/local/tomcat# cd webapps root@2594ca9eefcb:/usr/local/tomcat/webapps# ls ROOT docs examples host-manager manager# 提交修改后的容器 [root@zsr ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7c548ecd440f tomcat "/bin/bash" 39 seconds ago Up 38 seconds 0.0.0.0:8088->8080/tcp brave_hertz [root@zsr ~]# docker commit -a "zsr" -m="copy files from webapps.dist to webapps" 7c548ecd440f tomcat_zsr:1.0 sha256:3be2283d4c0d49f733f33f849c5ae95415ba7dfb71672112c0f36391c694ef8b [root@zsr ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE tomcat_zsr 1.0 3be2283d4c0d 37 seconds ago 653MB mysql latest c8562eaf9d81 9 days ago 546MB tomcat 9.0 040bdb29ab37 2 weeks ago 649MB tomcat latest 040bdb29ab37 2 weeks ago 649MB nginx latest f6d0b4767a6c 2 weeks ago 133MB centos latest 300e315adb2f 7 weeks ago 209MB portainer/portainer latest 62771b0b9b09 6 months ago 79.1MB elasticsearch 7.6.2 f29a1ee41030 10 months ago 791MB

    八、容器數據卷

    1. 什么是容器數據卷

    docker的理念:將應用和環境打包成一個鏡像!通過鏡像啟動容器運行

    • 問題:在容器中存儲的程序數據是需要持久化的,不能容器刪了數據也隨之刪除。比如,安裝一個MySQL容器,在其中存儲了大量數據,結果把容器刪了數據也沒了,就相當于刪庫跑路,這是不可能發生的

    數據卷技術的引入:我們希望Docker容器產生的數據可以自動同步到本地,這樣容器刪了數據并不會丟失;同時數據也可在容器之間共享。這就是卷技術,也就是目錄的掛載,將容器內的目錄掛載到linux上

    總結:容器的持久化和同步操作!容器間也可以實現數據共享!

    2. 使用數據卷

    docker run -it -v 主機目錄:容器內目錄

    測試:

    [root@zsr ~]# docker run -it -v /home/test:/home centos /bin/bash

    啟動之后可以用docker inspect查看容器詳細信息,可以看到掛載的信息

    我們開兩個窗口分別進入相對應掛載的目錄,在容器內/home目錄下新建一個文件,在主機/home/test目錄下同步出現該文件

    同樣,如果我們關閉退出停止容器,在主機內的/home/test路徑下新建文件2.txt,在容器內/home下也會同步,我們再次打開容器可以看到2.txt


    實戰:安裝MySQL

    # 1. 下載mysql:5.7鏡像 [root@zsr test]# docker pull mysql:5.7 5.7: Pulling from library/mysql a076a628af6f: Already exists f6c208f3f991: Already exists 88a9455a9165: Already exists 406c9b8427c6: Already exists 7c88599c0b25: Already exists 25b5c6debdaf: Already exists 43a5816f1617: Already exists 1831ac1245f4: Pull complete 37677b8c1f79: Pull complete 27e4ac3b0f6e: Pull complete 7227baa8c445: Pull complete Digest: sha256:b3d1eff023f698cd433695c9506171f0d08a8f92a0c8063c1a4d9db9a55808df Status: Downloaded newer image for mysql:5.7 docker.io/library/mysql:5.7# 2. 啟動mysql容器-d 后臺運行-p 端口映射-v 卷掛載-e 環境配置--name 容器名字 [root@zsr test]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7 67271dad5e807c42dccfa4803c2743d59e7bf75937bb8adc0df504e151965385

    啟動之后,我們本機連接一下試試,記得打開阿里云服務器安全組設置的3310端口

    點擊連接,連接成功,則說明docker部署成功

    我們回到xshell,查看主機下的`/home/mysql`目錄,可以看到`conf`和`data`兩個目錄,我們進入`data`目錄,可以看到相關文件


    如果我們在navicat中新建一個數據庫

    再回到xhell,查看data目錄,可以看到新增了test,即進行了同步

    如果我們刪除容器,數據仍在不會丟失,仍保留在本地


    3. 具名和匿名掛載

    匿名掛載

    # 匿名掛載: -v:容器內路徑(沒有寫容器外路徑) docker run -d -P --name nginx01 -v /etc/nginx nginx# 查看所有volume的情況 docker volume ls

    具名掛載(常用)

    # 具名掛載: -v 卷名:容器內路徑 docker run -d -P --name nginx02 -v specific-nginx:/etc/nginx nginx# 查看所有volume的情況 docker volume ls# 查specific-nginx卷的具體信息 docker volume inspect specific-nginx

    所有docker容器內的卷,沒有指定目錄情況下都是在/var/lib/docker/volumes/卷名/_data下

    拓展

    # 通過 容器內路徑:ro/rw 限制讀寫權限 ro:read only 只讀,該路徑文件只能通過宿主機來操作,容器內無法操作 rw:read write 可讀可寫docker run -d -P --name nginx02 -v specific-nginx:/etc/nginx:ro nginx docker run -d -P --name nginx02 -v specific-nginx:/etc/nginx:rw nginx

    4. 初識Dockerfile

    Dockerfile就是用來構建 docker 鏡像的構建文件,就是一段命令腳本,通過這個腳本可以生成一個鏡像

    通過這個腳本可以生成鏡像,鏡像是一層一層的,腳本中就是一個個命令,每個命令對應一層

    # 創建一個dockerfile文件FROM centosVOLUME ["volume01","volume02"]CMD echo "----end----"CMD /bin/bash

    完整:

    [root@zsr home]# ls 1.txt mysql redis test www zsr [root@zsr home]# mkdir docker-test-volume [root@zsr home]# ls 1.txt docker-test-volume mysql redis test www zsr [root@zsr home]# cd docker-test-volume/ [root@zsr docker-test-volume]# clear [root@zsr docker-test-volume]# pwd /home/docker-test-volume [root@zsr docker-test-volume]# vim dockerfile1 [root@zsr docker-test-volume]# cat dockerfile1 FROM centosVOLUME ["volume01","volume02"]CMD echo "----end----" CMD /bin/bash [root@zsr docker-test-volume]# docker build -f ./dockerfile1 -t zsr/centos:1.0 . Sending build context to Docker daemon 2.048kB Step 1/4 : FROM centos---> 300e315adb2f Step 2/4 : VOLUME ["volume01","volume02"]---> Running in 50aca2e71aa4 Removing intermediate container 50aca2e71aa4---> fab18ace6a3a Step 3/4 : CMD echo "----end----"---> Running in 6de412d0d33e Removing intermediate container 6de412d0d33e---> dd29a1e732b7 Step 4/4 : CMD /bin/bash---> Running in bb9c9b146eea Removing intermediate container bb9c9b146eea---> 52d008bba0ac Successfully built 52d008bba0ac Successfully tagged zsr/centos:1.0

    然后就可以查到自己構建的鏡像

    我們來通過自己創建的鏡像啟動容器,查看其中的內容,可以看到生成鏡像時自動掛載的數據卷目錄volume01和volume02

    這兩個數據卷一定與外部有一個同步的目錄!且我們設置的是匿名掛載

    通過以下命令查看具體的外部掛載路徑

    docker inspect b7cf8107f9fb


    5. 數據卷容器

    實現多個容器之間同步數據

    啟動3個容器,通過我們自己創建的鏡像啟動

    docker run -it --name docker01 zsr/centos:1.0

    docker run -it --name docker02 --volumes-from docker01 zsr/centos:1.0

    docker run -it --name docker03 --volumes-from docker01 zsr/centos:1.0


    我們可以刪除docker01,但數據并不會丟失;只要有一個容器再用,就不會丟失,因為數據卷是采用雙向拷貝的技術,即使刪除了一個容器,但數據已經拷貝到了其他容器中

    總結

    • 容器之間配置信息的傳遞,數據卷容器的聲明周期一直持續到沒有容器使用為止
    • 如果數據同步到了本地,本地的數據是不會刪除的


    九、DockerFile

    1. DockerFile介紹

    dockerfile是用來構建docker鏡像的文件

    構建步驟

  • 編寫一個dockerfile文件
  • docker build 構建成一個鏡像
  • docker run 運行鏡像
  • docker push 發布鏡像(DockerHub、阿里云鏡像倉庫)
  • dockerHub:https://hub.docker.com/

    這里以搜索centos鏡像為例

    我們點擊官方的鏡像源,會跳轉到一個github地址,里面就是dockerfile

    FROM scratch ADD centos-8-x86_64.tar.xz / LABEL org.label-schema.schema-version="1.0" org.label-schema.name="CentOS Base Image" org.label-schema.vendor="CentOS" org.label-schema.license="GPLv2" org.label-schema.build-date="20201204" CMD ["/bin/bash"]

    可以看到功能很少,官方的鏡像都是基礎包,我們通常要搭建自己的鏡像


    2. DockerFile的構建過程

    基礎知識

  • 每個保留關鍵字(指令)都必須是大寫字母
  • 執行順序從上往下順序執行
  • #代表注釋
  • 每條指令都會創建并提交一個新的鏡像層

  • DockerFile是面向開發的,逐漸成為企業交付的標準,以后發布項目就是打包成一個鏡像,就需要編寫dockerfile文件,十分簡單!


    3. DockerFile指令

    常見指令

    FROM # 基礎鏡像,從此開始構建 MAINTAINER # 鏡像作者,通常為姓名+郵箱 RUN # 鏡像構建時需要執行的命令 ADD # 在鏡像中需要添加的文件(比如基礎鏡像centos中要添加tomcat) WORKDIR # 鏡像的工作目錄 VOLUME # 容器數據卷,掛載主機的目錄 EXPOSE # 對外的暴露端口 CMD # 指定容器啟動時要運行的命令(只有最后一個生效,可被替代) ENTRYPOINT # 指定容器啟動時要運行的命令(可以追加命令) ONBUILD # 當構建一個被繼承DockerFile時就會運行ONBUILD指令 COPY # 類似ADD,將文件拷貝到鏡像中 ENV # 構建時的環境變量 FROM基礎鏡像,從此開始構建
    MAINTAINER鏡像作者,通常為姓名+郵箱
    RUN鏡像構建時需要執行的命令
    ADD在鏡像中需要添加的文件(比如基礎鏡像centos中要添加tomcat)
    WORKDIR鏡像的工作目錄
    VOLUME容器數據卷,掛載主機的目錄
    EXPOSE對外的暴露端口
    CMD指定容器啟動時要運行的命令(只有最后一個生效,可被替代)
    ENTRYPOINT指定容器啟動時要運行的命令(可以追加命令)
    ONBUILD當構建一個被繼承DockerFile時就會運行ONBUILD指令
    COPY類似ADD,將文件拷貝到鏡像中
    ENV構建時的環境變量

    CMD和ENTRYPOINT的區別

    測試CMD

    # 編寫的dockerfile文件 [root@zsr dockerfile]# cat test-CMD-dockerfile FROM centos CMD ["ls","-a"]# 構建鏡像 [root@zsr dockerfile]# docker build -f test-CMD-dockerfile -t cmdtest . Sending build context to Docker daemon 3.072kB Step 1/2 : FROM centos---> 300e315adb2f Step 2/2 : CMD ["ls","-a"]---> Running in 36cf3cc47759 Removing intermediate container 36cf3cc47759---> da35633333da Successfully built da35633333da Successfully tagged cmdtest:latest# 通過鏡像啟動容器,看到 ls -a 命令生效 [root@zsr dockerfile]# docker run da35633333da . .. .dockerenv bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var# 啟動容器時追加 -l 命令,發現報錯,這是因為CMD會覆蓋以前的命令 [root@zsr dockerfile]# docker run da35633333da -l docker: Error response from daemon: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.# 啟動容器時追加 ls -al 命令,不報錯,這是因為CMD會覆蓋以前的命令 [root@zsr dockerfile]# docker run da35633333da ls -al total 56 drwxr-xr-x 1 root root 4096 Jan 30 10:58 . drwxr-xr-x 1 root root 4096 Jan 30 10:58 .. -rwxr-xr-x 1 root root 0 Jan 30 10:58 .dockerenv lrwxrwxrwx 1 root root 7 Nov 3 15:22 bin -> usr/bin drwxr-xr-x 5 root root 340 Jan 30 10:58 dev drwxr-xr-x 1 root root 4096 Jan 30 10:58 etc drwxr-xr-x 2 root root 4096 Nov 3 15:22 home lrwxrwxrwx 1 root root 7 Nov 3 15:22 lib -> usr/lib lrwxrwxrwx 1 root root 9 Nov 3 15:22 lib64 -> usr/lib64 drwx------ 2 root root 4096 Dec 4 17:37 lost+found drwxr-xr-x 2 root root 4096 Nov 3 15:22 media drwxr-xr-x 2 root root 4096 Nov 3 15:22 mnt drwxr-xr-x 2 root root 4096 Nov 3 15:22 opt dr-xr-xr-x 119 root root 0 Jan 30 10:58 proc dr-xr-x--- 2 root root 4096 Dec 4 17:37 root drwxr-xr-x 11 root root 4096 Dec 4 17:37 run lrwxrwxrwx 1 root root 8 Nov 3 15:22 sbin -> usr/sbin drwxr-xr-x 2 root root 4096 Nov 3 15:22 srv dr-xr-xr-x 13 root root 0 Jan 28 13:30 sys drwxrwxrwt 7 root root 4096 Dec 4 17:37 tmp drwxr-xr-x 12 root root 4096 Dec 4 17:37 usr drwxr-xr-x 20 root root 4096 Dec 4 17:37 var

    測試ENTRYPOINT

    # 編寫的dockerfile文件 FROM centos ENTRYPOINT ["ls","-a"]# 構建鏡像 [root@zsr dockerfile]# docker build -f test-ENTRYPOINT-dockerfile -t entrypoint-test . Sending build context to Docker daemon 4.096kB Step 1/2 : FROM centos---> 300e315adb2f Step 2/2 : ENTRYPOINT ["ls","-a"]---> Running in 74c8223d1e35 Removing intermediate container 74c8223d1e35---> 27f4e359bf92 Successfully built 27f4e359bf92 Successfully tagged entrypoint-test:latest# 通過鏡像啟動容器,看到 ls -a 命令生效 [root@zsr dockerfile]# docker run 27f4e359bf92 . .. .dockerenv bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var# 啟動容器時追加 -l 命令,成功,這是因為ENTRYPOINT會追加到以前的命令 [root@zsr dockerfile]# docker run 27f4e359bf92 -l total 56 drwxr-xr-x 1 root root 4096 Jan 30 11:03 . drwxr-xr-x 1 root root 4096 Jan 30 11:03 .. -rwxr-xr-x 1 root root 0 Jan 30 11:03 .dockerenv lrwxrwxrwx 1 root root 7 Nov 3 15:22 bin -> usr/bin drwxr-xr-x 5 root root 340 Jan 30 11:03 dev drwxr-xr-x 1 root root 4096 Jan 30 11:03 etc drwxr-xr-x 2 root root 4096 Nov 3 15:22 home lrwxrwxrwx 1 root root 7 Nov 3 15:22 lib -> usr/lib lrwxrwxrwx 1 root root 9 Nov 3 15:22 lib64 -> usr/lib64 drwx------ 2 root root 4096 Dec 4 17:37 lost+found drwxr-xr-x 2 root root 4096 Nov 3 15:22 media drwxr-xr-x 2 root root 4096 Nov 3 15:22 mnt drwxr-xr-x 2 root root 4096 Nov 3 15:22 opt dr-xr-xr-x 119 root root 0 Jan 30 11:03 proc dr-xr-x--- 2 root root 4096 Dec 4 17:37 root drwxr-xr-x 11 root root 4096 Dec 4 17:37 run lrwxrwxrwx 1 root root 8 Nov 3 15:22 sbin -> usr/sbin drwxr-xr-x 2 root root 4096 Nov 3 15:22 srv dr-xr-xr-x 13 root root 0 Jan 28 13:30 sys drwxrwxrwt 7 root root 4096 Dec 4 17:37 tmp drwxr-xr-x 12 root root 4096 Dec 4 17:37 usr drwxr-xr-x 20 root root 4096 Dec 4 17:37 var

    4. 實戰:構建自己的CentOS

    官網centosdockerfile:Docker Hub 大多數基礎鏡像都是scratch,然后添加所需的配置進行構建

    FROM scratch ADD centos-8-x86_64.tar.xz / LABEL org.label-schema.schema-version="1.0" org.label-schema.name="CentOS Base Image" org.label-schema.vendor="CentOS" org.label-schema.license="GPLv2" org.label-schema.build-date="20201204" CMD ["/bin/bash"]

    1. 編寫dockerfile

    基于官網的centos構建自己的centos,編寫一個centos-dockerfile

    # 編寫自己的centos-dockerfile [root@zsr dockerfile]# vim centos-dockerfile [root@zsr dockerfile]# cat centos-dockerfile FROM centos MAINTAINER zsr<1412578784@qq.com>ENV MYPATH /usr/local WORKDIR $MYPATHRUN yum -y install vim RUN yum -y install net-toolsEXPOSE 8088CMD echo $MYPATH CMD echo "----end----" CMD /bin/bash

    2. 通過dockerfile構建鏡像

    # 通過centos-dockerfile構建鏡像 # 命令: docker build -f dockerfile路徑 -t 鏡像名:[tag] . [root@zsr dockerfile]# docker build -f centos-dockerfile -t mycentos:0.1 . Sending build context to Docker daemon 2.048kB Step 1/10 : FROM centos---> 300e315adb2f Step 2/10 : MAINTAINER zsr<1412578784@qq.com>---> Running in 07cb579c0233 Removing intermediate container 07cb579c0233---> 47a448db7079 Step 3/10 : ENV MYPATH /usr/local---> Running in fb3d1ac73261 Removing intermediate container fb3d1ac73261---> 74e47975e555 Step 4/10 : WORKDIR $MYPATH---> Running in c596e71a7e68 Removing intermediate container c596e71a7e68---> 9588d6a7b4b9 Step 5/10 : RUN yum -y install vim---> Running in f005ef7c0b02 CentOS Linux 8 - AppStream 3.4 MB/s | 6.3 MB 00:01 CentOS Linux 8 - BaseOS 1.4 MB/s | 2.3 MB 00:01 CentOS Linux 8 - Extras 15 kB/s | 8.6 kB 00:00 Dependencies resolved. ================================================================================Package Arch Version Repository Size ================================================================================ Installing:vim-enhanced x86_64 2:8.0.1763-15.el8 appstream 1.4 M Installing dependencies:gpm-libs x86_64 1.20.7-15.el8 appstream 39 kvim-common x86_64 2:8.0.1763-15.el8 appstream 6.3 Mvim-filesystem noarch 2:8.0.1763-15.el8 appstream 48 kwhich x86_64 2.21-12.el8 baseos 49 kTransaction Summary ================================================================================ Install 5 PackagesTotal download size: 7.8 M Installed size: 30 M Downloading Packages: (1/5): gpm-libs-1.20.7-15.el8.x86_64.rpm 316 kB/s | 39 kB 00:00 (2/5): vim-filesystem-8.0.1763-15.el8.noarch.rp 1.2 MB/s | 48 kB 00:00 (3/5): which-2.21-12.el8.x86_64.rpm 1.6 MB/s | 49 kB 00:00 (4/5): vim-enhanced-8.0.1763-15.el8.x86_64.rpm 4.8 MB/s | 1.4 MB 00:00 (5/5): vim-common-8.0.1763-15.el8.x86_64.rpm 20 MB/s | 6.3 MB 00:00 -------------------------------------------------------------------------------- Total 3.5 MB/s | 7.8 MB 00:02 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 Linux 8 - AppStream 983 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 C65DFrom : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial Key imported successfully Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transactionPreparing : 1/1 Installing : which-2.21-12.el8.x86_64 1/5 Installing : vim-filesystem-2:8.0.1763-15.el8.noarch 2/5 Installing : vim-common-2:8.0.1763-15.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-15.el8.x86_64 5/5 Running scriptlet: vim-enhanced-2:8.0.1763-15.el8.x86_64 5/5 Running scriptlet: vim-common-2:8.0.1763-15.el8.x86_64 5/5 Verifying : gpm-libs-1.20.7-15.el8.x86_64 1/5 Verifying : vim-common-2:8.0.1763-15.el8.x86_64 2/5 Verifying : vim-enhanced-2:8.0.1763-15.el8.x86_64 3/5 Verifying : vim-filesystem-2:8.0.1763-15.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-15.el8.x86_64 vim-enhanced-2:8.0.1763-15.el8.x86_64 vim-filesystem-2:8.0.1763-15.el8.noarchwhich-2.21-12.el8.x86_64 Complete! Removing intermediate container f005ef7c0b02---> 0c3951bc6949 Step 6/10 : RUN yum -y install net-tools---> Running in 4646de41c5d7 Last metadata expiration check: 0:00:11 ago on Sat Jan 30 04:10:15 2021. Dependencies resolved. ================================================================================Package Architecture Version Repository Size ================================================================================ Installing:net-tools x86_64 2.0-0.52.20160912git.el8 baseos 322 kTransaction Summary ================================================================================ Install 1 PackageTotal download size: 322 k Installed size: 942 k Downloading Packages: net-tools-2.0-0.52.20160912git.el8.x86_64.rpm 4.4 MB/s | 322 kB 00:00 -------------------------------------------------------------------------------- Total 692 kB/s | 322 kB 00:00 Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transactionPreparing : 1/1 Installing : net-tools-2.0-0.52.20160912git.el8.x86_64 1/1 Running scriptlet: net-tools-2.0-0.52.20160912git.el8.x86_64 1/1 Verifying : net-tools-2.0-0.52.20160912git.el8.x86_64 1/1 Installed:net-tools-2.0-0.52.20160912git.el8.x86_64 Complete! Removing intermediate container 4646de41c5d7---> 72be4892b90e Step 7/10 : EXPOSE 8088---> Running in 57afa2232032 Removing intermediate container 57afa2232032---> afadc63b8b9b Step 8/10 : CMD echo $MYPATH---> Running in 29d0dd8ea502 Removing intermediate container 29d0dd8ea502---> 909e565c58a0 Step 9/10 : CMD echo "----end----"---> Running in 04c2f5807be3 Removing intermediate container 04c2f5807be3---> d4dcc5359a4d Step 10/10 : CMD /bin/bash---> Running in 10a0d1c49ad2 Removing intermediate container 10a0d1c49ad2---> 1c97191097fc Successfully built 1c97191097fc Successfully tagged mycentos:0.1

    然后用docker images命令就可以查看到構建的鏡像mycentos

    同樣,我們可以用docker history命令查看鏡像的構建過程

    3. 通過鏡像啟動容器

    [root@zsr dockerfile]# docker run -it mycentos:0.1 [root@a5f99e5c1589 local]# pwd /usr/local [root@a5f99e5c1589 local]# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 172.18.0.5 netmask 255.255.0.0 broadcast 172.18.255.255ether 02:42:ac:12:00:05 txqueuelen 0 (Ethernet)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 (0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536inet 127.0.0.1 netmask 255.0.0.0loop txqueuelen 1000 (Local Loopback)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 (0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0[root@a5f99e5c1589 local]# vim 1.txt

    對比之前官方的centos,新增了ifconfig、vim等命令


    5. 實戰:構建自己的Tomcat

    1. 準備鏡像文件

    準備Tomcat壓縮包,而Tomcat運行需要依賴于jdk,所以還需要jdk的壓縮包

    tomcat下載地址:https://tomcat.apache.org/download-90.cgi

    jdk下載地址:https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html

    然后將兩個壓縮包通過xftp拷貝到服務器的/home/tomcat目錄下

    可在服務器中查看

    2. 編寫dockerfile文件

    編寫dockerfile文件,官方命名為Dockerfile,這樣就不需要通過-f指定,build時會自動尋找這個文件

    FROM centos MAINTAINER zsr<1412578784@qq.com>COPY readme.txt /usr/local/readme.txtADD jdk-8u281-linux-x64.tar.gz /usr/local/ ADD apache-tomcat-9.0.41.tar.gz /usr/local/RUN yum -y install vimENV MYPATH /usr/local WORKDIR $MYPATHENV JAVA_HOME /usr/local/jdk ENV CALSSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.41 ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.41 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/binEXPOSE 8080CMD /usr/local/apache-tomcat-9.0.41/bin/startup.sh && tail -F /url/local/apache-tomcat-9.0.41/bin/logs/catalina.out

    3. 構建鏡像

    [root@zsr tomcat]# docker build -t mytomcat . Sending build context to Docker daemon 155.2MB Step 1/15 : FROM centos---> 300e315adb2f Step 2/15 : MAINTAINER zsr<1412578784@qq.com>---> Using cache---> 47a448db7079 Step 3/15 : COPY readme.txt /usr/local/readme.txt---> 8dd0d2ce8867 Step 4/15 : ADD jdk-8u281-linux-x64.tar.gz /usr/local/---> 7c5ab3a8ed6e Step 5/15 : ADD apache-tomcat-9.0.41.tar.gz /usr/local/---> e2f1d80dde55 Step 6/15 : RUN yum -y install vim---> Running in 75ad35b83d68 CentOS Linux 8 - AppStream 4.2 MB/s | 6.3 MB 00:01 CentOS Linux 8 - BaseOS 633 kB/s | 2.3 MB 00:03 CentOS Linux 8 - Extras 14 kB/s | 8.6 kB 00:00 Dependencies resolved. ================================================================================Package Arch Version Repository Size ================================================================================ Installing:vim-enhanced x86_64 2:8.0.1763-15.el8 appstream 1.4 M Installing dependencies:gpm-libs x86_64 1.20.7-15.el8 appstream 39 kvim-common x86_64 2:8.0.1763-15.el8 appstream 6.3 Mvim-filesystem noarch 2:8.0.1763-15.el8 appstream 48 kwhich x86_64 2.21-12.el8 baseos 49 kTransaction Summary ================================================================================ Install 5 PackagesTotal download size: 7.8 M Installed size: 30 M Downloading Packages: (1/5): gpm-libs-1.20.7-15.el8.x86_64.rpm 495 kB/s | 39 kB 00:00 (2/5): vim-filesystem-8.0.1763-15.el8.noarch.rp 1.5 MB/s | 48 kB 00:00 (3/5): which-2.21-12.el8.x86_64.rpm 201 kB/s | 49 kB 00:00 (4/5): vim-enhanced-8.0.1763-15.el8.x86_64.rpm 2.3 MB/s | 1.4 MB 00:00 (5/5): vim-common-8.0.1763-15.el8.x86_64.rpm 2.9 MB/s | 6.3 MB 00:02 -------------------------------------------------------------------------------- Total 792 kB/s | 7.8 MB 00:10 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 Linux 8 - AppStream 1.0 MB/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 C65DFrom : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial Key imported successfully Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transactionPreparing : 1/1 Installing : which-2.21-12.el8.x86_64 1/5 Installing : vim-filesystem-2:8.0.1763-15.el8.noarch 2/5 Installing : vim-common-2:8.0.1763-15.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-15.el8.x86_64 5/5 Running scriptlet: vim-enhanced-2:8.0.1763-15.el8.x86_64 5/5 Running scriptlet: vim-common-2:8.0.1763-15.el8.x86_64 5/5 Verifying : gpm-libs-1.20.7-15.el8.x86_64 1/5 Verifying : vim-common-2:8.0.1763-15.el8.x86_64 2/5 Verifying : vim-enhanced-2:8.0.1763-15.el8.x86_64 3/5 Verifying : vim-filesystem-2:8.0.1763-15.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-15.el8.x86_64 vim-enhanced-2:8.0.1763-15.el8.x86_64 vim-filesystem-2:8.0.1763-15.el8.noarchwhich-2.21-12.el8.x86_64 Complete! Removing intermediate container 75ad35b83d68---> 223e446850cd Step 7/15 : ENV MYPATH /usr/local---> Running in 75bb312ba150 Removing intermediate container 75bb312ba150---> 0365605d3b03 Step 8/15 : WORKDIR $MYPATH---> Running in 3a21e6991d81 Removing intermediate container 3a21e6991d81---> 29130451ac38 Step 9/15 : ENV JAVA_HOME /usr/local/jdk---> Running in 1ecd36c1d9f7 Removing intermediate container 1ecd36c1d9f7---> fe6bf481c29a Step 10/15 : ENV CALSSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar---> Running in 02236cc9eea3 Removing intermediate container 02236cc9eea3---> c30c9a3c9b7a Step 11/15 : ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.41---> Running in b6e97820a257 Removing intermediate container b6e97820a257---> adc11a0fcc4b Step 12/15 : ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.41---> Running in b92bfa0ad8ab Removing intermediate container b92bfa0ad8ab---> 9604504f196d Step 13/15 : ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin---> Running in 025388f720e6 Removing intermediate container 025388f720e6---> 486df4c3100f Step 14/15 : EXPOSE 8080---> Running in 46a3f73f7a63 Removing intermediate container 46a3f73f7a63---> 3decd97962e6 Step 15/15 : CMD /usr/local/apache-tomcat-9.0.41/bin/startup.sh && tail -F /url/local/apache-tomcat-9.0.41/bin/logs/catalina.out---> Running in b0c9afffc1f1 Removing intermediate container b0c9afffc1f1---> 42338715d10f Successfully built 42338715d10f Successfully tagged mytomcat:latest

    4. 啟動容器

    [root@zsr tomcat]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mytomcat latest 42338715d10f About a minute ago 640MB entrypoint-test latest 27f4e359bf92 4 hours ago 209MB cmdtest latest da35633333da 4 hours ago 209MB mycentos 0.1 1c97191097fc 11 hours ago 291MB zsr/centos 1.0 52d008bba0ac 2 days ago 209MB tomcat_zsr 1.0 3be2283d4c0d 2 days ago 653MB mysql 5.7 a70d36bc331a 11 days ago 449MB mysql latest c8562eaf9d81 11 days ago 546MB tomcat 9.0 040bdb29ab37 2 weeks ago 649MB tomcat latest 040bdb29ab37 2 weeks ago 649MB nginx latest f6d0b4767a6c 2 weeks ago 133MB centos latest 300e315adb2f 7 weeks ago 209MB portainer/portainer latest 62771b0b9b09 6 months ago 79.1MB elasticsearch 7.6.2 f29a1ee41030 10 months ago 791MB [root@zsr tomcat]# docker run -d -P 47.95.238.165:8088:8080 --name zsrtomcat -v /home/tomcat/test:/usr/local/apache-tomcat-9.0.41/webapps/test -v /home/tomcat/logs:/usr/local/apache-tomcat-9.0.41/logs mytomcat 04d4ec8d3986250927c3d2174ac11130e3b29b943b18fd908e434cf7545d4aab [root@zsr tomcat]# ls apache-tomcat-9.0.41.tar.gz Dockerfile jdk-8u281-linux-x64.tar.gz logs readme.txt test

    5. 進入容器

    [root@zsr tomcat]# docker exec -it 04d4ec8d3986 /bin/bash [root@04d4ec8d3986 local]# pwd /usr/local [root@04d4ec8d3986 local]# ls -l total 52 drwxr-xr-x 1 root root 4096 Jan 30 14:58 apache-tomcat-9.0.41 drwxr-xr-x 2 root root 4096 Nov 3 15:22 bin drwxr-xr-x 2 root root 4096 Nov 3 15:22 etc drwxr-xr-x 2 root root 4096 Nov 3 15:22 games drwxr-xr-x 2 root root 4096 Nov 3 15:22 include drwxr-xr-x 8 10143 10143 4096 Dec 9 12:50 jdk1.8.0_281 drwxr-xr-x 2 root root 4096 Nov 3 15:22 lib drwxr-xr-x 3 root root 4096 Dec 4 17:37 lib64 drwxr-xr-x 2 root root 4096 Nov 3 15:22 libexec -rw-r--r-- 1 root root 0 Jan 30 12:18 readme.txt drwxr-xr-x 2 root root 4096 Nov 3 15:22 sbin drwxr-xr-x 5 root root 4096 Dec 4 17:37 share drwxr-xr-x 2 root root 4096 Nov 3 15:22 src [root@04d4ec8d3986 local]# cd apache-tomcat-9.0.41/ [root@04d4ec8d3986 apache-tomcat-9.0.41]# ls -l total 148 -rw-r----- 1 root root 18982 Dec 3 11:48 BUILDING.txt -rw-r----- 1 root root 5409 Dec 3 11:48 CONTRIBUTING.md -rw-r----- 1 root root 57092 Dec 3 11:48 LICENSE -rw-r----- 1 root root 2333 Dec 3 11:48 NOTICE -rw-r----- 1 root root 3257 Dec 3 11:48 README.md -rw-r----- 1 root root 6898 Dec 3 11:48 RELEASE-NOTES -rw-r----- 1 root root 16507 Dec 3 11:48 RUNNING.txt drwxr-x--- 2 root root 4096 Dec 3 11:48 bin drwx------ 2 root root 4096 Dec 3 11:48 conf drwxr-x--- 2 root root 4096 Dec 3 11:45 lib drwxr-xr-x 2 root root 4096 Jan 30 15:06 logs drwxr-x--- 2 root root 4096 Dec 3 11:45 temp drwxr-x--- 1 root root 4096 Jan 30 15:06 webapps drwxr-x--- 2 root root 4096 Dec 3 11:43 work

    6. 訪問測試


    同樣,用公網IP:8088可以訪問到

    7. 發布項目

    我們已經做了卷掛載,本機的/home/tomcat/test掛載到容器的/usr/local/apache-tomcat-9.0.41/webapps/test目錄,因此我們只需要在本機對應目錄項發布項目就會自動同步到容器中

    我們在/home/tomcat/test目錄下新建WEB-INF目錄,在其中創建web.xml文件

    <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"version="2.5"></web-app>

    然后在test目錄下創建一個index.jsp頁面

    <%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>zsr</title> </head> <body> Hello World!<br/> <% out.println("mytomcat測試"); %> </body> </html>

    然后瀏覽器輸入localhost:8088/test即可看到頁面


    6. 發布鏡像到 Docker Hub

    首先要有自己Docker Hub的賬號

    1. 登錄 Docker Hub

    docker login命令用于登錄

    [root@zsr test]# docker login --helpUsage: 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

    2. 提交到 Docker Hub

    用docker tag命令重命名要發布到鏡像,名稱格式為:賬戶名/鏡像名:版本號

    [root@zsr test]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mytomcat latest 42338715d10f 6 days ago 640MB [root@zsr test]# docker tag 42338715d10f bareth/tomcat:1.0 [root@zsr test]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE bareth/tomcat 1.0 42338715d10f 6 days ago 640MB mytomcat latest 42338715d10f 6 days ago 640MB

    然后push即可

    [root@zsr ~]# docker push bareth/tomcat:1.0 The push refers to repository [docker.io/bareth/tomcat] 95a2375d854b: Pushing 15.68MB/58.05MB 028764aa589d: Pushing 5.345MB/15.83MB aea92a4c5330: Pushing 4.422MB/356.6MB ea60ecf88e36: Pushed 2653d992f4ef: Pushing 10.95MB/209.3MB

    7. 發布鏡像到阿里云鏡像

    1. 創建阿里云鏡像倉庫

    首先登錄阿里云,找到 容器鏡像服務

    點擊進入,然后 創建一個鏡像倉庫

    倉庫類型選擇 本地倉庫

    便成功創建了倉庫

    我們點擊進入剛創建的倉庫可以查看相關信息

    2. 提交到阿里云鏡像倉庫


    1、登錄阿里云Docker Registry

    docker login --username=bareth registry.cn-beijing.aliyuncs.com

    • 登錄的用戶名為阿里云賬號全名,密碼為開通服務時設置的密碼

    2、使用docker tag命令重命名要發布的鏡像

    [root@zsr test]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mytomcat latest 42338715d10f 6 days ago 640MB [root@zsr test]# docker tag 42338715d10f registry.cn-beijing.aliyuncs.com/bareth/docker-test:1.0 [root@zsr ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mytomcat latest 42338715d10f 2 weeks ago 640MB registry.cn-beijing.aliyuncs.com/bareth/docker-test 1.0 42338715d10f 2 weeks ago 640MB

    3、push到阿里云鏡像倉庫

    [root@zsr ~]# docker push registry.cn-beijing.aliyuncs.com/bareth/docker-test:1.0 The push refers to repository [docker.io/bareth/tomcat]

    小結



    十、Docker網絡

    1. Docker網絡原理

    當我們用ip addr命令查看服務器內部網絡地址時,可以發現三個地址:

    • 127.0.0.1 本機回環地址
    • 172.17.223.207 服務器內網IP地址
    • 172.18.0.1 docker0地址

    這里的docker0地址就是安裝docker時,采用 橋接模式 使用 evth-pair 技術分配的地址

    ==docker是如何處理容器網絡訪問的?==比如有一個tomcat容器,一個mysql容器;tomcat中運行著一個web項目,這個項目需要訪問mysql。這是如何實現的呢?

    我們首先啟動一個tomcat容器

    # 啟動一個容器 [root@zsr ~]# docker run -d -P --name tomcat01 tomcat Unable to find image 'tomcat:latest' locally latest: Pulling from library/tomcat b9a857cbf04d: Pull complete d557ee20540b: Pull complete 3b9ca4f00c2e: Pull complete 667fd949ed93: Pull complete 661d3b55f657: Pull complete 511ef4338a0b: Pull complete a56db448fefe: Pull complete 00612a99c7dc: Pull complete 326f9601c512: Pull complete c547db74f1e1: Pull complete Digest: sha256:94cc18203335e400dbafcd0633f33c53663b1c1012a13bcad58cced9cd9d1305 Status: Downloaded newer image for tomcat:latest c3b8a6a222bfcd73d5cf350d330b3a1c536d0eb5a0676eb24e193664659f2fcd

    然后我們查看容器內部網絡地址,可以發現 eth0@if89 這個ip地址127.0.0.1,這是docker分配的

    # 查看容器內部網絡地址,可以發現 eth0@if89 這個ip地址,這是docker分配的 [root@zsr ~]# docker exec -it tomcat01 ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever 88: eth0@if89: <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 0inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0valid_lft forever preferred_lft forever

    我們ping該容器內地址,發現可以ping通,因為127.0.0.2和docker0地址127.0.0.1網絡前綴相同,是處于統一網段的,所以可以ping通

    # ping容器內地址,發現可以ping通docker容器內部 [root@zsr ~]# 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.100 ms 64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.071 ms 64 bytes from 172.18.0.2: icmp_seq=3 ttl=64 time=0.070 ms

    原理

    • 每啟動一個docker容器時,docker就會給該容器分配一個ip地址

    我們再次在服務器上使用ip addr測試,可以發現多了一對網絡地址,這就是啟動tomcat容器docker為其分配的地址

    如果我們再啟動一個tomcat容器,可以看到又多了一對網絡地址

    我們發現每次新增的網絡地址都是一對一對的88/89 90/91,這就是evth-pair技術,就是一對虛擬設備接口,成對出現,一段連著協議,一段彼此相連;容器內的88連接了主機的89,容器內的90連接了主機的91;

    evth-pair充當了一個橋梁,實現了主機可以ping通容器內部ip地址,用于連接各種虛擬網絡設備

    那么 tomcar01和tomcat02 這兩個容器能否ping通呢?當然是可以的,因為兩個容器內的ip地址都橋接了主機相應的ip地址,都與docker0地址處于同一網段,因此可以ping通

    # tomcat02 ping tomcat01可以ping通 [root@zsr ~]# docker exec -it tomcat02 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.127 ms 64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.109 ms 64 bytes from 172.18.0.2: icmp_seq=3 ttl=64 time=0.100 ms

    可用docker netowork命令查看該網橋中的所有配置

    [root@zsr ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 81fa37acd3b5 bridge bridge local d1c3276f2d1f host host local 40b12350fa4a none null local [root@zsr ~]# docker network inspect 81fa37acd3b5 [{"Name": "bridge","Id": "81fa37acd3b5fe63542a50cb6dda629a7434fa9fdebccedb7e8c24e859a31b76","Created": "2021-02-06T20:58:24.660018691+08:00","Scope": "local","Driver": "bridge","EnableIPv6": false,"IPAM": {"Driver": "default","Options": null,"Config": [{"Subnet": "172.18.0.0/16","Gateway": "172.18.0.1"}]},"Internal": false,"Attachable": false,"Ingress": false,"ConfigFrom": {"Network": ""},"ConfigOnly": false,"Containers": {"1cc06da893c10d4ef1bdf7e590860b44cf55a0c506b57b64dda44551ef06d816": {"Name": "tomcat03","EndpointID": "1c3a39f04598dc4b966f51b54e82c15a77c522e49fbfe618d70668332abc9ba3","MacAddress": "02:42:ac:12:00:04","IPv4Address": "172.18.0.4/16","IPv6Address": ""},"c3b8a6a222bfcd73d5cf350d330b3a1c536d0eb5a0676eb24e193664659f2fcd": {"Name": "tomcat01","EndpointID": "1b5015b0de628870b5498984aae24c0175dd8cb2663de9c9c6f6bce0694771e0","MacAddress": "02:42:ac:12:00:02","IPv4Address": "172.18.0.2/16","IPv6Address": ""},"ff19965390f0f4231130227b252290ea759d407ecbb2b0c0dcc11261d5687f26": {"Name": "tomcat02","EndpointID": "8ae0342e9e42fe3b9a19c70f1646500ae7dae519781719b7b8097eb9b43b5811","MacAddress": "02:42:ac:12:00:03","IPv4Address": "172.18.0.3/16","IPv6Address": ""}},"Options": {"com.docker.network.bridge.default_bridge": "true","com.docker.network.bridge.enable_icc": "true","com.docker.network.bridge.enable_ip_masquerade": "true","com.docker.network.bridge.host_binding_ipv4": "0.0.0.0","com.docker.network.bridge.name": "docker0","com.docker.network.driver.mtu": "1500"},"Labels": {}} ]

    結論:容器和容器之間是可以互相ping通的

    所有的容器不指定網絡的情況下,都是通過 docker0路由的,docker會給容器分配一個默認的可用ip

    • Docker 使用的是Linux的橋接,宿主機中是一個Docker容器的網橋docker0
    • Docker 中所有的網絡接口都是虛擬的,轉發效率高,只要容器刪除,對應的網橋就刪除

    2. 容器互聯–link

    如果我們編寫了一個微服務,連接數據庫的ip地址變化了,此時數據連接就會斷開,服務不可用;如果此時能夠通過容器名字連接數據庫,就可以解決數據庫連接的問題;

    如果tomcat01直接通過pingtomcat02的容器名,會報錯

    [root@zsr ~]# docker exec -it tomcat01 ping tomcat02 ping: tomcat02: Name or service not known

    那么如何解決這個問題呢?可以在創建容器時用--link指定連接的容器,此時就可以通過容器名來ping通了

    [root@zsr ~]# docker run -d -P --name tomcat03 --link tomcat01 tomcat 1cc06da893c10d4ef1bdf7e590860b44cf55a0c506b57b64dda44551ef06d816 [root@zsr ~]# docker exec -it tomcat03 ping tomcat01 PING tomcat01 (172.18.0.2) 56(84) bytes of data. 64 bytes from tomcat01 (172.18.0.2): icmp_seq=1 ttl=64 time=0.127 ms 64 bytes from tomcat01 (172.18.0.2): icmp_seq=2 ttl=64 time=0.103 ms 64 bytes from tomcat01 (172.18.0.2): icmp_seq=3 ttl=64 time=0.103 ms

    但是反過來ping則無法ping通

    [root@zsr ~]# docker exec -it tomcat01 ping tomcat03 ping: tomcat03: Name or service not known

    原理:通過--link 使tomcat03 在本地hosts中配置了 tomcat02的ip與容器名的映射


    3. 自定義網絡

    # 查看所有的網絡 [root@zsr ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 81fa37acd3b5 bridge bridge local d1c3276f2d1f host host local 40b12350fa4a none null local

    網絡模式

    • bridge:橋接(默認)
    • none:不配置網絡
    • host:主機模式,和宿主機共享網絡
    • container:容器網絡聯通(使用少!)

    測試

    當我們啟動一個容器時,其實有默認參數--net bridge,這也就是docker0,是默認的方式,上述提到可以用--link進行互聯實現通過容器名訪問,但是比較繁瑣,不建議使用;

    # 啟動一個容器時帶默認參數 --net bridge docker run -d -P --name mytomcat tomcat docker run -d -P --name mytomcat --net bridge tomcat

    建議自定義一個網絡,所有的服務都在自定義的網絡中進行使用!

    # 創建一個網絡mynet,采用默認的橋接模式,子網地址192.168.0.0,網關192.168.0.1 [root@zsr ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet 2e6be259e1f43f884fbf9e24aa3cc1b238b91bd1e9be3ba0abcfbefd3e106450 [root@zsr ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 81fa37acd3b5 bridge bridge local d1c3276f2d1f host host local 2e6be259e1f4 mynet bridge local 40b12350fa4a none null local

    可查看自定義網絡的詳細信息

    我們指定使用自定義網絡mynet來啟動兩個容器

    [root@zsr ~]# docker run -d -P --name mynet-tomcat01 --net mynet tomcat 2795bf15cd21ec608c02840bd7488942da4838d47662b0b204e663003fa49a3b [root@zsr ~]# docker run -d -P --name mynet-tomcat02 --net mynet tomcat 41b416dbf35eb55164ffe024d120a17db60aa0a501f20ef3ce40d3c180a67517

    然后再查看mynet的詳細信息,可以看到這兩個容器以及分配的IP地址

    再次測試ping連接,發現自定義的網絡解決了docker0的缺點,可以直接通過容器名來訪問

    [root@zsr ~]# docker exec -it mynet-tomcat01 ping mynet-tomcat02 PING mynet-tomcat02 (192.168.0.3) 56(84) bytes of data. 64 bytes from mynet-tomcat02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.094 ms 64 bytes from mynet-tomcat02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.094 ms 64 bytes from mynet-tomcat02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.158 ms ^C --- mynet-tomcat02 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 3ms rtt min/avg/max/mdev = 0.094/0.115/0.158/0.031 ms

    應用場景

    不同的集群(redis,mysql)用不同的網絡,使用自己的子網,保證集群的安全及健康


    4. 網絡聯通

    上述我們啟動了四個容器,分別是默認docker0網絡下的tomcat01/tomcat02,自定義網絡mynet網絡下的mynet-tomcat01/mynet-tomcat02

    我們畫個圖來理解一下

    此時可以實現tomcat01到mynet-tomcat01的互聯嗎?答案當然是否定的,因為是處于不同的網段,我們可以進行測試

    [root@zsr ~]# docker exec -it 192.18.0.2 ping 172.18.0.2 Error: No such container: 192.18.0.2

    那么怎么實現tomcat01到mynet-tomcat01的互聯呢?可以使用docker network connect命令

    # 測試聯通tomcat01到mynet-tomcat01 [root@zsr ~]# docker network connect mynet tomcat01

    然后查看mynet得詳細信息,可以發現聯通之后就是將tomcat01的放入mynet網絡中,也就實現了一個容器兩個ip,類似于阿里云的公網IP和私網IP,都是可以訪問

    聯通后我們再次ping連接測試,成功ping通!

    [root@zsr ~]# docker exec -it tomcat01 ping mynet-tomcat01 PING mynet-tomcat01 (192.168.0.2) 56(84) bytes of data. 64 bytes from mynet-tomcat01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.091 ms 64 bytes from mynet-tomcat01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.100 ms ^C --- mynet-tomcat01 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1ms rtt min/avg/max/mdev = 0.091/0.095/0.100/0.010 ms

    實戰:部署Redis集群

    # 自定義一個網絡 [root@zsr ~]# docker network create redis --subnet 172.38.0.0/16 92f7a807fc739e3eb7b6e56df5a1c6bc3e701e0a61a544f04e7a2e549538ad20# 通過腳本創建6個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 5000 cluster-announce-ip 172.38.0.1${port} cluster-announce-port 6379 cluster-announce-bus-port 16379 appendonly yes EOF done

    # 通過腳本啟動6個容器 for i in `seq 1 6`; \ do \ docker run -d -p 637${i}:6379 -p 1637${i}:16379 --name redis-${i} \ -v /mydata/redis/node-${i}/data:/data \ -v /mydata/redis/node-${i}/conf/redis.conf:/etc/redis/redis.conf \ --net redis --ip 172.38.0.1${i} redis:6.0 redis-server /etc/redis/redis.conf done

    # 進入redis-1容器 [root@zsr /]# docker exec -it redis-1 /bin/sh # pwd /data # ls appendonly.aof nodes.conf# 配置集群 # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.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 172.38.0.15:6379 to 172.38.0.11:6379 Adding replica 172.38.0.16:6379 to 172.38.0.12:6379 Adding replica 172.38.0.14:6379 to 172.38.0.13:6379 M: f693f5b7cc515154a532aa5f48ff627d2827e205 172.38.0.11:6379slots:[0-5460] (5461 slots) master M: b233e1c2053a77c2351b511e784579cd50a3e5a8 172.38.0.12:6379slots:[5461-10922] (5462 slots) master M: da06f6994fe142969f313fa7c6d8cb94cd1facb7 172.38.0.13:6379slots:[10923-16383] (5461 slots) master S: 944f7e0f2e3082745c2e999470f969d53cd1bdd9 172.38.0.14:6379replicates da06f6994fe142969f313fa7c6d8cb94cd1facb7 S: eaab096391c79d4d3d42be66fcc66cb2d724720b 172.38.0.15:6379replicates f693f5b7cc515154a532aa5f48ff627d2827e205 S: 09ba78c0f4f1848a6a9c6d0b9ccc42a159a394a4 172.38.0.16:6379replicates b233e1c2053a77c2351b511e784579cd50a3e5a8 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 172.38.0.11:6379) M: f693f5b7cc515154a532aa5f48ff627d2827e205 172.38.0.11:6379slots:[0-5460] (5461 slots) master1 additional replica(s) S: 944f7e0f2e3082745c2e999470f969d53cd1bdd9 172.38.0.14:6379slots: (0 slots) slavereplicates da06f6994fe142969f313fa7c6d8cb94cd1facb7 M: da06f6994fe142969f313fa7c6d8cb94cd1facb7 172.38.0.13:6379slots:[10923-16383] (5461 slots) master1 additional replica(s) S: eaab096391c79d4d3d42be66fcc66cb2d724720b 172.38.0.15:6379slots: (0 slots) slavereplicates f693f5b7cc515154a532aa5f48ff627d2827e205 S: 09ba78c0f4f1848a6a9c6d0b9ccc42a159a394a4 172.38.0.16:6379slots: (0 slots) slavereplicates b233e1c2053a77c2351b511e784579cd50a3e5a8 M: b233e1c2053a77c2351b511e784579cd50a3e5a8 172.38.0.12:6379slots:[5461-10922] (5462 slots) master1 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.# 連接集群查看信息 # 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:461 cluster_stats_messages_pong_sent:454 cluster_stats_messages_sent:915 cluster_stats_messages_ping_received:449 cluster_stats_messages_pong_received:461 cluster_stats_messages_meet_received:5 cluster_stats_messages_received:915 127.0.0.1:6379> cluster nodes # 查看集群節點信息,三主三從 f693f5b7cc515154a532aa5f48ff627d2827e205 172.38.0.11:6379@16379 myself,master - 0 1613876713000 1 connected 0-5460 944f7e0f2e3082745c2e999470f969d53cd1bdd9 172.38.0.14:6379@16379 slave da06f6994fe142969f313fa7c6d8cb94cd1facb7 0 1613876713071 3 connected da06f6994fe142969f313fa7c6d8cb94cd1facb7 172.38.0.13:6379@16379 master - 0 1613876714675 3 connected 10923-16383 eaab096391c79d4d3d42be66fcc66cb2d724720b 172.38.0.15:6379@16379 slave f693f5b7cc515154a532aa5f48ff627d2827e205 0 1613876713000 1 connected 09ba78c0f4f1848a6a9c6d0b9ccc42a159a394a4 172.38.0.16:6379@16379 slave b233e1c2053a77c2351b511e784579cd50a3e5a8 0 1613876715175 2 connected b233e1c2053a77c2351b511e784579cd50a3e5a8 172.38.0.12:6379@16379 master - 0 1613876713673 2 connected 5461-10922

    此時我們添加一個鍵值對,可以看到是由172.38.0.13也就是redis-3主機來處理的服務

    也就是a的值存在redis-3主機中,那對應的從機應該也有a的值,也就是說如果redis-3服務掛掉,可以從對應的從機中取出a的值

    # 停止redis-3容器 [root@zsr ~]# docker stop redis-3 redis-3

    然后再重新獲取a的值,可以看到是從redis-4中取得值,也就是redis-3的從機,實現了高可用,主機掛掉從機自動替代主機

    再查看節點的詳細信息,可以看到redis-3主機掛掉,redis-4成為新的主機



    十一、SpringBoot微服務&docker

    1. 構建springboot項目

    首先新建一個springboot項目


    然后編寫一個controller,在主程序目錄下新建controller包,其中新建HelloController.java

    package com.zsr.docker_test.controller;import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;@RestController public class HelloController {@RequestMapping("/hello")public String hello() {return "hello";} }

    然后啟動主程序進行測試,訪問localhost:8080/hello,出現如下頁面即成功


    2. 打包應用

    點擊package進行打包

    打包成功后,可以看到生成的target目錄中打包生成的.jar文件

    我們用命令行測試一下該jar包能否運行,在其目錄下打開cmd,輸入以下命令

    jaava -jar docker_test-0.0.1-SNAPSHOT.jar

    成功啟動代表打包成功


    3. 編寫Dockerfile

    在項目根目錄下新建Dockerfile

    FROM java:8 COPY *.jar /app.jar CMD ["--server.port=8080"] EXPOSE 8080 ENTRYPOINT ["java","-jar","/app.jar"]


    4. 構建鏡像

    將編寫好的Dockerfile和打包生成的docker_test-0.0.1-SNAPSHOT.jar文件上傳到服務器

    然后用命令構建鏡像

    [root@zsr IDEA]# ls Dockerfile docker_test-0.0.1-SNAPSHOT.jar [root@zsr IDEA]# docker build -t first-project . Sending build context to Docker daemon 16.55MB Step 1/5 : FROM java:8 8: Pulling from library/java 5040bd298390: Pull complete fce5728aad85: Pull complete 76610ec20bf5: Pull complete 60170fec2151: Pull complete e98f73de8f0d: Pull complete 11f7af24ed9c: Pull complete 49e2d6393f32: Pull complete bb9cdec9c7f3: Pull complete Digest: sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d Status: Downloaded newer image for java:8---> d23bdf5b1b1b Step 2/5 : COPY *.jar /app.jar---> 63fda5bdcb6d Step 3/5 : CMD ["--server.port=8080"]---> Running in 5e94d333492d Removing intermediate container 5e94d333492d---> 59bd2f4e0120 Step 4/5 : EXPOSE 8080---> Running in 99c4427313de Removing intermediate container 99c4427313de---> d4792bf4f884 Step 5/5 : ENTRYPOINT ["java","-jar","/app.jar"]---> Running in da3be5f92a55 Removing intermediate container da3be5f92a55---> 2df101d6382c Successfully built 2df101d6382c Successfully tagged first-project:latest

    然后便可看到剛生成的鏡像


    5. 啟動容器測試

    [root@zsr IDEA]# docker run -d -P --name springboot-project first-project 33bbe58ea88c99f0cdc40cda78f04b81c21d48d0dab59c2e9e2896a8899f5cc8 [root@zsr IDEA]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 33bbe58ea88c first-project "java -jar /app.jar …" 4 seconds ago Up 3 seconds 0.0.0.0:49163->8080/tcp springboot-project [root@zsr IDEA]# curl localhost:49163/hello hello[root@zsr IDEA]#

    根據測試結果,成功啟動項目,訪問的/hello請求返回結果正確


    6. 發布鏡像

    將鏡像發布至Docker Hub或者阿里云鏡像倉庫,然后別人使用直接pull下來即可運行

    總結

    以上是生活随笔為你收集整理的从零开始学Docker(超详细讲解+案例分析)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    国产精品毛片久久久久久 | 国产精品免费在线观看视频 | 亚洲成人黄色网址 | 美女视频国产 | 色91在线 | 麻豆成人网 | 成人永久在线 | 中文字幕中文字幕中文字幕 | 黄在线免费看 | 久久久黄色 | 亚洲精品在线观看不卡 | 91精品系列 | 成人97人人超碰人人99 | 伊人视频 | 色在线视频网 | 天天爱天天操 | 国产亚洲精品久久19p | 手机av看片 | 国产精品成人一区二区三区吃奶 | 射九九| 区一区二在线 | 亚洲视频在线视频 | 国产群p视频 | 久久久国产电影 | 久久久精品综合 | 夜夜夜夜夜夜操 | 久久人人爽爽 | 9免费视频 | 97成人资源站 | 午夜a区| 婷婷久月 | 一区二区电影在线观看 | 麻豆91精品91久久久 | 国产精品一区二区62 | 日韩精品免费专区 | 久久草 | 国产精品6 | 狠狠躁日日躁夜夜躁av | 人人盈棋牌 | 国产精品丝袜久久久久久久不卡 | 九九欧美视频 | 四虎永久免费 | 亚洲视频精品在线 | 久久久久久欧美二区电影网 | 日韩高清三区 | 91视频在线自拍 | 激情视频一区二区三区 | 99国产精品视频免费观看一公开 | 亚洲国产欧美一区二区三区丁香婷 | 久久久精品欧美 | 亚洲精品一区二区网址 | 黄色大片免费网站 | 91精品国产综合久久福利 | av动态图片 | 欧美一级性生活 | www.天天射| 国产999精品 | 亚洲高清免费在线 | 久草在线费播放视频 | 韩国在线一区二区 | 日韩高清不卡一区二区三区 | 精品夜夜嗨av一区二区三区 | 久久久黄色免费网站 | 嫩草伊人久久精品少妇av | 日韩精品一区二区三区第95 | 欧洲av不卡| av福利第一导航 | 亚洲天天在线日亚洲洲精 | 在线播放av网址 | 99精品国产99久久久久久福利 | 精品久久一区 | 视频直播国产精品 | 手机成人免费视频 | 日韩av中文字幕在线 | av电影免费在线看 | 色婷婷亚洲 | 国产资源免费 | 热久久国产 | 国产这里只有精品 | 国产精品免费久久久久 | 天天在线视频色 | 91.麻豆视频 | 国产1区2区3区精品美女 | 精品福利国产 | 在线免费观看国产 | 亚洲一二视频 | 亚洲影院色 | 91av亚洲 | 成人在线小视频 | a在线观看免费视频 | 黄色毛片在线观看 | 国产中文字幕一区二区 | 国产黄色免费在线观看 | 亚洲第一成网站 | 国产亚洲精品成人av久久影院 | 中文字幕在线一二 | 四虎永久精品在线 | 久久精品国产美女 | 精品国产伦一区二区三区免费 | 国产精品日韩久久久久 | 西西444www大胆高清视频 | 亚洲天天在线日亚洲洲精 | 91人人网 | 日韩一区视频在线 | 亚洲色图 校园春色 | 久久色在线播放 | 91九色最新地址 | 国产色婷婷在线 | 一区二区三区四区五区在线 | 亚洲婷婷在线视频 | 五月婷婷色综合 | 久久99精品国产麻豆宅宅 | 天天操人人要 | 亚洲精品视频网站在线观看 | 成人香蕉视频 | 麻豆精品传媒视频 | 少妇搡bbbb搡bbb搡69 | 天天艹天天操 | 色姑娘综合天天 | 成人91av| 91在线观看高清 | 日日干夜夜骑 | 婷婷六月丁 | 精品 激情 | 美女福利视频网 | 97色涩 | 亚洲精区二区三区四区麻豆 | 在线天堂中文www视软件 | 欧美成人精品欧美一级乱黄 | 最近中文字幕第一页 | 国产亚洲精品女人久久久久久 | 香蕉视频网站在线观看 | 日韩免费成人av | 91欧美精品| 国产网站av | 日b视频国产| 日韩在线观看视频中文字幕 | 免费观看的av网站 | 精品亚洲免a | 天天在线操 | 免费高清男女打扑克视频 | 香蕉在线视频观看 | 国产成人一区二区三区影院在线 | 国产黄色在线网站 | 亚洲综合在线播放 | 久久国产精品视频 | 成人中文字幕在线 | 欧美一区二区三区在线播放 | 亚洲视频 一区 | 色婷婷狠狠五月综合天色拍 | 国产一区二区精品在线 | www.色午夜.com | 六月色丁| 中文字幕在线观看一区二区 | 六月丁香久久 | 日韩特黄av| 国模视频一区二区三区 | 在线看毛片网站 | 91免费观看国产 | 亚洲 欧美 精品 | 精壮的侍卫呻吟h | 国产视频久久 | 天天射综合网视频 | 国产精品一区二区久久久 | 黄色在线观看免费网站 | 日日夜夜免费精品视频 | 亚洲欧美日韩国产 | 日韩www在线 | 国产手机av在线 | 亚洲黄色片在线 | 中文字幕av专区 | 久草视频在线资源 | 久久精品999 | av免费网站 | 欧美一区二区三区在线视频观看 | 久久国产精品久久w女人spa | 中文在线www | 国产午夜精品免费一区二区三区视频 | 国产黄色片免费在线观看 | 在线国产视频观看 | 国产精品免费在线 | 麻豆极品| www五月 | 色悠悠久久综合 | 日韩视频www | 97精品国产aⅴ | 伊人伊成久久人综合网小说 | 日韩有码在线观看视频 | 久久有精品 | 国产特级毛片aaaaaa高清 | 国产视频一区二区在线播放 | 国内精品福利视频 | 亚洲欧洲精品久久 | www黄色com| www.天天草 | 国产精品色 | 成 人 免费 黄 色 视频 | 日韩国产精品一区 | 日韩二区三区在线 | 深爱开心激情 | 日韩色在线观看 | 97福利在线观看 | 日韩乱码中文字幕 | 一区二区三区在线观看免费 | 中国精品少妇 | 国产精品白浆视频 | 免费观看一区 | 国产精品美女毛片真酒店 | 国产精品毛片一区视频 | 欧美先锋影音 | 17videosex性欧美 | 久久婷婷一区 | 国产精品国产精品 | 色综合天天在线 | 久草在线手机观看 | 婷婷综合电影 | 亚洲电影自拍 | 亚洲国内精品在线 | 成人午夜网 | 中文字幕三区 | 又色又爽又激情的59视频 | 97av在线视频 | 久久短视频 | 欧美性色19p | 国产在线观看国语版免费 | 久久久久久免费视频 | 国产精品综合在线 | 天天插夜夜操 | 中文字幕 影院 | 天天色天天射天天操 | 国产精品视频你懂的 | 国产高清在线观看av | 免费麻豆视频 | 国产精品视频你懂的 | 久久成人国产精品 | 国产精品露脸在线 | 国产精品2020 | 日韩在线不卡 | 97超碰色| 蜜臀av性久久久久av蜜臀妖精 | 国产成人一区二区三区在线观看 | 国产日韩在线观看一区 | 国产成人av一区二区三区在线观看 | 美女黄频免费 | 久久久久久久久久久福利 | 久久a级片| 午夜视频在线观看一区二区三区 | 99久久久久久久久 | 一级α片| 久久99久久99精品免观看软件 | 狠狠色丁香久久婷婷综合五月 | 久久久久久网 | 免费看黄电影 | 日韩黄色免费看 | 久久男人中文字幕资源站 | 国产乱对白刺激视频在线观看女王 | 337p西西人体大胆瓣开下部 | 亚洲精品视频一二三 | 婷婷亚洲最大 | 久久网站免费 | 欧美综合久久 | www.xxxx欧美| 国产精品v欧美精品 | 国产精品久久影院 | 亚洲日本在线视频观看 | 日本中文字幕免费观看 | 九九九热| 91看片一区二区三区 | 久久免费精品一区二区三区 | 婷婷天天色 | 在线观看精品国产 | 91av手机在线观看 | 国产成人久久久久 | 97视频免费在线看 | 免费特级黄色片 | 91福利小视频 | 蜜臀91丨九色丨蝌蚪老版 | 久久久官网 | 在线观看国产高清视频 | 免费在线观看av网站 | 中文字幕在线观看完整版 | 亚洲欧美日韩国产一区二区三区 | 婷婷色站 | 免费a网址 | 欧美日韩亚洲在线观看 | 欧美精品一区二区在线观看 | 成年人看片网站 | 亚洲精品视频久久 | 激情五月婷婷 | 激情视频在线高清看 | 欧美一区免费在线观看 | 狠狠干网站 | 久久精品国产成人精品 | 最新av网址在线 | av大片免费看 | 欧美影院久久 | 日韩欧美高清在线观看 | 国产资源在线播放 | 日精品 | 免费aa大片 | 天天爱天天射 | 欧美精品在线一区 | 99视频| 婷婷丁香自拍 | 久久黄色a级片 | 安徽妇搡bbbb搡bbbb | 91色偷偷 | 在线观看亚洲a | 亚洲电影在线看 | 欧美日韩天堂 | 九九亚洲视频 | 国产精品一区专区欧美日韩 | 麻豆免费精品视频 | 国产在线自 | 最近中文字幕免费av | av在线免费观看不卡 | 日本性生活免费看 | 国产麻豆视频网站 | 国产成人一区三区 | 亚洲国产精品99久久久久久久久 | 一级特黄av | 国产不卡视频 | 日韩,中文字幕 | 444av| 99麻豆视频| 91理论片午午伦夜理片久久 | 天天综合网 天天 | 丁香激情综合国产 | 久久精品牌麻豆国产大山 | 日日摸日日添日日躁av | 波多野结衣视频一区二区三区 | av电影中文字幕在线观看 | 黄色片网站免费 | 久久久久成| 午夜精品久久久久久中宇69 | 成人午夜在线观看 | 视频在线观看99 | 日本成人免费在线观看 | av中文国产 | 一级黄色网址 | 国产精品青青 | 亚洲国产精品小视频 | 中文字幕亚洲欧美日韩2019 | 久久一区91 | 国产黄色观看 | 在线欧美a | 精品国产精品久久一区免费式 | 亚洲黄色小说网 | 成人在线视频免费观看 | 黄a网| 免费日韩| 日本黄色免费电影网站 | 精品国产伦一区二区三区观看体验 | 欧美性视频网站 | 亚洲电影在线看 | 久久超碰免费 | 欧美一二三在线 | 欧美另类巨大 | 91秒拍国产福利一区 | 天天草综合 | 2019中文| japanesefreesex中国少妇 | 夜夜躁日日躁狠狠久久av | 成人在线视频在线观看 | 欧美精品一区二区三区一线天视频 | av福利在线播放 | 91精品成人久久 | 国产99久| 操操日日 | 欧美激情视频一二三区 | 在线99视频 | 久草手机视频 | 日韩肉感妇bbwbbwbbw | 久久人人爽人人爽人人片av软件 | 免费高清av在线看 | av资源在线看 | 国产又粗又长又硬免费视频 | 欧美一级片在线免费观看 | 欧美乱大交 | 国产小视频在线观看免费 | 色偷偷中文字幕 | 午夜精品久久久99热福利 | 精品久久毛片 | 国产精品手机播放 | 国产亚洲精品日韩在线tv黄 | 日韩欧美黄色网址 | 日韩一级精品 | 在线观看理论 | 精品a级片| 香蕉在线观看 | 日日躁夜夜躁aaaaxxxx | av在线不卡观看 | 中文字幕在线乱 | 免费在线观看日韩欧美 | 欧美一级性生活视频 | 99久久99久久精品国产片果冰 | 欧美日韩国产在线精品 | 91精选在线观看 | 国产艹b视频 | 免费看国产黄色 | 天天躁日日| 久久尤物电影视频在线观看 | 狠狠干夜夜爱 | 激情婷婷色 | 一区二区三区日韩视频在线观看 | 日韩高清一二区 | 色播五月激情综合网 | 伊人网综合在线观看 | 久久久观看 | 久久99国产精品 | 精品影院 | 久久夜色电影 | 精品国产乱码久久 | 在线免费观看一区二区三区 | 久久久久久久久久久久久久av | 国产真实在线 | 亚洲三级黄 | 精品久久久久久久久久久久久久久久 | 亚洲午夜久久久久久久久电影网 | 久久人人爽人人爽人人片av免费 | 国产精品一区二区在线免费观看 | 五月婷婷色播 | 亚洲国产精品电影 | 国产在线观看a | 国产高清区 | 欧美激情精品 | 欧美性久久久 | 日韩大片免费观看 | 美女搞黄国产视频网站 | 一区二区三区日韩视频在线观看 | 免费网站在线 | 亚洲激情在线 | 日韩av免费网站 | 久草视频视频在线播放 | 日本黄色免费网站 | 丰满少妇一级片 | 免费在线一区二区 | 在线观看免费观看在线91 | 天天操天天操天天操天天操天天操 | 深夜免费福利 | 69久久久久久久 | 欧美色综合天天久久综合精品 | 亚洲在线视频播放 | 狠狠色丁香久久婷婷综合_中 | 国产成人精品一区二三区 | 在线看片视频 | 亚洲国产精品传媒在线观看 | 在线观看亚洲 | 正在播放 久久 | 久久成人精品电影 | 国产不卡免费 | 欧美激情va永久在线播放 | 日韩av黄 | 91精品在线免费观看 | 最近最新mv字幕免费观看 | 黄色a视频 | 在线视频欧美亚洲 | 91麻豆精品国产91久久久久久 | 欧美日韩精品在线一区二区 | 午夜精品一区二区三区在线 | 日韩成人免费在线电影 | 国产亚州av | 国产九九精品视频 | 成人亚洲网 | 丁香婷婷色综合亚洲电影 | 国产精品一区二区中文字幕 | 日韩欧美大片免费观看 | 成人av高清在线观看 | 久草网首页 | 天天爱天天操天天射 | av成年人电影 | 五月婷婷在线视频观看 | 91中文字幕在线 | 亚洲国产午夜视频 | 亚洲精品视频偷拍 | 日韩欧美视频在线免费观看 | 二区视频在线观看 | 99精品国产亚洲 | 久久精品视频一 | 欧美另类高潮 | 天天操天天爽天天干 | 激情网色| 久久黄色片子 | 亚洲精品综合一区二区 | 日韩网站在线观看 | 国产精品久久久久影院 | 亚洲综合狠狠干 | 色姑娘综合 | 特黄免费av | 国产3p视频 | 日韩在线第一 | 69久久夜色精品国产69 | 成年人在线观看视频免费 | 99久久精品国产毛片 | 91网页版免费观看 | 国色天香在线 | 亚洲国产美女精品久久久久∴ | 激情综合网在线观看 | 中文字幕一区二区三区在线观看 | 欧美精品久| 天干啦夜天干天干在线线 | 91成年人在线观看 | 久久男人中文字幕资源站 | 亚洲国产成人久久综合 | 99精品乱码国产在线观看 | 深夜国产在线 | 天天在线操 | 亚洲精品国产精品国自产在线 | 麻豆传媒电影在线观看 | 手机看片国产日韩 | 精品久久一级片 | 91夫妻自拍| 人人超碰免费 | 婷婷激情综合五月天 | 国产一区二区在线看 | 国产亚洲小视频 | 最新国产视频 | 99精品视频在线播放免费 | 免费看黄网站在线 | 免费观看视频的网站 | 狠狠狠色丁香综合久久天下网 | 97色婷婷成人综合在线观看 | 久久夜色精品国产欧美一区麻豆 | 天天干天天做 | 最新国产精品亚洲 | 国产精品99久久久久 | 久久天天躁狠狠躁亚洲综合公司 | 97国产精品一区二区 | 91禁看片| 五月天婷婷综合 | 国产一二三区在线观看 | 日韩在线观看第一页 | 去看片| www.五月天 | 色婷婷精品大在线视频 | 超碰人人91 | 日韩精品你懂的 | 精品国内自产拍在线观看视频 | 综合网久久 | 天天色棕合合合合合合 | 天堂av网在线 | 免费欧美精品 | 国产一区 在线播放 | 天天天天天天天操 | 中文字幕成人在线 | 精品国产精品一区二区夜夜嗨 | 国产精品久久久久久五月尺 | 天天操天天干天天 | 天堂在线视频免费观看 | 91九色在线观看 | 久久国产区 | 成 人 黄 色 视频 免费观看 | 狠狠色狠狠色综合日日小说 | 亚洲精品国产综合久久 | 91传媒视频在线观看 | 黄色免费观看网址 | 亚洲精品乱码久久久久久蜜桃欧美 | 日韩国产在线观看 | 国产 在线观看 | 色综合天天色综合 | 成 人 黄 色 视频 免费观看 | www.久草.com | 一区二区三区在线观看免费 | 91av视频在线免费观看 | 91桃色国产在线播放 | 免费av观看 | 天天综合天天做天天综合 | 久久高清片 | 国产黄色免费观看 | 99久久免费看 | 欧美少妇18p | 免费在线观看a v | 深爱激情综合 | 亚洲精品国产欧美在线观看 | 激情综合啪啪 | 久久久久国产精品免费网站 | 97人人超碰在线 | 亚洲精品久久激情国产片 | 国产色综合天天综合网 | 又黄又爽又无遮挡免费的网站 | 深爱激情综合网 | 六月丁香色婷婷 | 色综合久久久久综合体桃花网 | 伊人色综合久久天天 | 精品99久久 | 婷婷精品 | 亚洲伦理一区二区 | 97久久久免费福利网址 | 日本中文在线 | 天堂视频一区 | 日韩在线免费看 | 五月天com | 欧美性色黄| 天天透天天插 | 九九热精品在线 | 久草在线视频免费资源观看 | 国产精品久久久久久久久久尿 | 国产成人精品区 | 97精品欧美91久久久久久 | 在线看国产一区 | 亚洲精品小区久久久久久 | 四虎影视4hu4虎成人 | 国产精品第一视频 | 久久久av免费 | 国产精品扒开做爽爽的视频 | 欧美激情第一区 | 久久国产福利 | 五月婷婷六月丁香 | 免费网站观看www在线观看 | 久草99 | 91精品伦理| 人人爱爱| 久久久久久久久亚洲精品 | 成人动漫一区二区 | 成人a毛片 | 91精品一区二区三区蜜桃 | 婷婷国产精品 | 久久久国产一区二区三区四区小说 | 狠狠干狠狠久久 | 麻豆视频免费入口 | 久久超级碰视频 | 亚洲欧美成人综合 | av免费在线播放 | 欧美精品二 | 国产综合香蕉五月婷在线 | 中文字幕在线观看网址 | 久久草在线视频国产 | 91精品啪在线观看国产81旧版 | 成人在线一区二区三区 | 亚洲网站在线看 | 99精品乱码国产在线观看 | 成人午夜网址 | 黄色精品一区二区 | 天天操欧美| 国产精品女人久久久久久 | 久久夜色精品国产亚洲aⅴ 91chinesexxx | 人成在线免费视频 | 人人射人人爱 | 天天躁天天躁天天躁婷 | 天天综合网久久综合网 | 国产精品二区三区 | 久久久久久久国产精品影院 | 亚洲综合一区二区精品导航 | 在线观看成人网 | 精品亚洲va在线va天堂资源站 | 狠狠狠色丁香婷婷综合激情 | 丁香花在线观看免费完整版视频 | 天天躁日日躁狠狠躁 | 色九色| 国产精品99精品久久免费 | 五月婷婷激情五月 | 男女啪啪网站 | 国产视频在线免费观看 | 亚洲专区在线播放 | 国产精品第一视频 | 婷婷成人综合 | 国产尤物在线 | 久久精品之 | 91av在线视频播放 | 成人国产精品入口 | 久久夜色精品国产亚洲aⅴ 91chinesexxx | 九九精品视频在线观看 | 伊人手机在线 | 国产精品电影在线 | 97在线观看免费观看高清 | 99视屏| 高清国产午夜精品久久久久久 | 久久视频这里有久久精品视频11 | 欧美性色网站 | 久久色中文字幕 | 亚洲国产中文字幕在线观看 | 日本成人免费在线观看 | 青青河边草免费观看完整版高清 | 久久公开视频 | 亚洲精品456在线播放乱码 | 国产精品中文久久久久久久 | 欧美激情综合五月色丁香 | 久久精品女人毛片国产 | 97久久久免费福利网址 | 操天天操| 欧美日韩成人一区 | 中文字幕在线看视频国产中文版 | 伊人六月 | 中文字幕中文 | 国产精品一区二区久久精品爱微奶 | 超级碰碰免费视频 | 欧美激情xxxx性bbbb | 国产美女在线免费观看 | 欧美激情综合五月色丁香 | 日韩av免费在线看 | 在线午夜 | 在线观看91 | 狠狠gao| 日操操 | 国产 一区二区三区 在线 | av在观看 | 91精品国产麻豆 | 欧美久久精品 | 国产成人精品免高潮在线观看 | 国产综合福利在线 | 白丝av免费观看 | 色视频国产直接看 | 欧美一级日韩三级 | 精品福利av| 欧美国产日韩一区二区三区 | 六月丁香激情综合色啪小说 | av黄色影院 | 国产一级免费在线 | 国产剧情一区二区在线观看 | www.人人草 | 99久久999久久久精玫瑰 | 欧美日韩视频在线观看免费 | 日女人免费视频 | 亚洲精品综合久久 | 国产精品丝袜久久久久久久不卡 | 2000xxx影视| 99精品国产高清在线观看 | 婷婷日韩 | 国产高清在线视频 | 国产在线无| 日韩av片无码一区二区不卡电影 | 天天色视频 | 国产成人av网 | 亚洲高清视频在线观看 | 超碰在线人人 | 免费观看全黄做爰大片国产 | bbbb操bbbb| 天天操天天弄 | 久久久国产一区二区三区 | 午夜av在线播放 | 91视频91色| 男女激情麻豆 | 黄色在线免费观看网站 | 91av原创| 精品国产美女 | 久久人人爽人人爽 | 成人黄色大片网站 | 夜夜躁狠狠躁日日躁 | 香蕉网址 | 国产对白av| 在线视频国产区 | 豆豆色资源网xfplay | 欧美日韩精品免费观看视频 | 欧美一级裸体视频 | 伊人导航 | 在线亚洲激情 | 综合天天久久 | 91免费网 | 久久久久久久国产精品 | 国产专区在线视频 | 欧美精品乱码久久久久久按摩 | 久久久黄色免费网站 | 日韩国产在线观看 | 中午字幕在线观看 | 久久国产热视频 | 韩国一区二区三区在线观看 | 91自拍视频在线 | 久99视频 | 国产精品美乳一区二区免费 | 亚洲精品自在在线观看 | 久久国产经典 | 久久综合干 | 97碰在线视频 | 久久精品久久精品久久精品 | 久久福利小视频 | 五月天激情视频在线观看 | 天天操天天射天天舔 | 五月天伊人 | 免费看一及片 | 免费能看的黄色片 | 在线天堂视频 | 人人搞人人干 | 精品亚洲视频在线 | 国产不卡av在线 | 91自拍视频在线观看 | 最近中文字幕国语免费高清6 | 久久久久久久国产精品影院 | 狠狠激情中文字幕 | 黄色91免费观看 | 亚洲一区网站 | 国内精品久久久久久久久久久久 | 又黄又爽又色无遮挡免费 | 亚洲精品国产精品99久久 | av日韩中文 | 91视频免费网址 | 久久久久国产精品免费免费搜索 | 91av原创| 日日干网 | 免费观看第二部31集 | 成人免费网站视频 | 欧美日韩高清一区二区三区 | 久久精品综合 | 天天艹天天 | 91大神精品视频 | 中文字幕中文字幕在线中文字幕三区 | 欧美有色| 国产在线一卡 | 亚洲国产网站 | 婷婷久久综合九色综合 | 亚洲高清激情 | 国产精品久久久视频 | 狠狠狠狠狠狠干 | 久久综合中文字幕 | 国产在线精品区 | 亚洲综合色播 | 四虎欧美 | 亚洲国产无 | 一区二区不卡在线观看 | 午夜av片 | 久久成人福利 | 国产精品一区二 | 国产亚洲欧洲 | a'aaa级片在线观看 | 日韩艹 | 日韩视频中文字幕在线观看 | 狠狠做深爱婷婷综合一区 | 丰满少妇在线观看资源站 | 久久久久久久久久久久久国产精品 | 操老逼免费视频 | 五月天丁香综合 | 999国内精品永久免费视频 | av免费黄色| 成人一区二区在线观看 | 2019免费中文字幕 | 精品国产成人在线影院 | 国产精品18久久久久久首页狼 | 日韩理论片中文字幕 | 日韩视频一区二区在线观看 | 久草www | 精品一区二区亚洲 | 成人性生交大片免费看中文网站 | 久久精品日本啪啪涩涩 | 国产精品久久久久久久久搜平片 | 久草免费在线观看 | 国内精品免费 | 黄色软件视频网站 | 一区二区三区电影在线播 | 日韩成人欧美 | 亚洲视频免费在线观看 | 国产xxxxx在线观看 | 国产成人久久精品一区二区三区 | 黄色小说免费在线观看 | 夜夜视频资源 | 免费看十八岁美女 | 亚洲国产色一区 | 精品国自产在线观看 | 中文在线字幕免费观看 | 日韩精品一区二区三区免费视频观看 | 国产一卡二卡在线 | 国产黄色av | 亚州视频在线 | 欧美久久久久久久久久 | 国产亚洲精品久久久久久无几年桃 | 探花视频在线版播放免费观看 | 免费在线观看日韩视频 | 美女视频免费精品 | 99久久99| 日韩欧美99 | 中文字幕一区二区三区在线观看 | 亚洲精品国产精品乱码不99热 | 日韩免费在线播放 | 在线看小早川怜子av | av在线免费播放网站 | 97在线精品国自产拍中文 | 国产99久久九九精品 | 免费观看成人网 | 欧美日韩国产综合网 | 日韩在线观看中文 | 黄色小说在线免费观看 | 麻豆国产在线播放 | 中文日韩在线 | 日韩一级电影网站 | 精品久久一二三区 | 这里只有精品视频在线观看 | 国产高清在线视频 | 国产午夜麻豆影院在线观看 | 永久av免费在线观看 | 91av在线视频免费观看 | 精品久久久久久久久久 | 九月婷婷人人澡人人添人人爽 | 久久看免费视频 | 最新中文在线视频 | 国产剧在线观看片 | 女人18片毛片90分钟 | 97视频在线观看免费 | 中文字幕免费高清在线 | 久久99精品久久只有精品 | 日韩二区精品 | 婷婷丁香在线视频 | 亚洲三级在线播放 | 日韩精品一区二 | 国产精品久久在线观看 | 五月开心六月伊人色婷婷 | 中文字幕在线看视频 | 国产精品成人一区二区三区吃奶 | 成人小视频免费在线观看 | 狠狠色丁香婷婷综合久小说久 | 九九欧美 | 久草剧场 | 亚洲激精日韩激精欧美精品 | aaa毛片视频| 久草视频国产 | 国产91精品一区二区绿帽 | 国内成人av| 久久国产99| 欧美另类sm图片 | 在线观看国产永久免费视频 | 精品一区二区三区四区在线 | 久久精品99国产精品酒店日本 | 中国精品少妇 | 精品久久久久免费极品大片 | 国产成人av免费在线观看 | 欧美日韩精品在线观看视频 | 97操碰| 久久国产视屏 | 91在线视频观看 | 久久久久国产免费免费 | 久久情侣偷拍 | 久久综合影院 | 国产在线观看黄 | 中文字幕电影在线 | 国产片网站 | 视频国产一区二区三区 | 精品一区电影 | 97电院网手机版 | 国产精品久久三 | 日韩三级免费观看 | 亚洲区另类春色综合小说 | 日韩在线第一 | 91精品视频免费 | 五月婷婷综合在线 | 在线观看亚洲精品视频 | 国产在线a不卡 | 在线观看视频一区二区三区 | 人人干人人草 | 色吊丝在线永久观看最新版本 | 国产网站在线免费观看 | 国产精品亚洲综合久久 | 午夜精品av在线 | 亚洲美女在线国产 | 亚洲伊人av| 欧美日韩在线精品一区二区 | 99色人 | 久草视频在线新免费 | 久久爱资源网 | 99在线观看 | 午夜免费福利视频 | 丁香婷婷综合五月 | 国产精品欧美日韩在线观看 | 日韩在线不卡视频 | 久一在线 | 中文字幕在线看视频国产中文版 | 韩国av一区二区三区在线观看 | 成人精品一区二区三区电影免费 | 亚洲女欲精品久久久久久久18 | 国产高清视频色在线www | 中文字幕高清在线播放 | 精品国产综合区久久久久久 | 久久精品久久国产 | 精品国产一区二区久久 | 色婷婷激情网 | 在线观看视频97 | 国产91成人在在线播放 | 丁香视频免费观看 | 欧美激情精品久久久久久免费印度 | 97视频网站 | 波多野结衣电影一区二区三区 | 精品一区在线 | 激情久久一区二区三区 | 成人欧美一区二区三区黑人麻豆 | 午夜精品一二区 | 美女久久久久久久久久久 | 麻豆视频网址 | 91九色在线 | 99精品国自产在线 | 97超碰在线人人 | 97超碰资源 | 亚洲mv大片欧洲mv大片免费 | va视频在线观看 | 欧美有色 | 中文字幕免费一区二区 | 91av视频免费观看 | 日韩美女高潮 | 狠色狠色综合久久 | 欧美在线视频一区二区 | 成年人av在线播放 | av电影中文 | 国产亚洲一区 | 国产精品一区二区三区在线免费观看 | 欧美另类sm图片 | 久草在线视频免费资源观看 | 丁香综合五月 | 久久综合99| 国产成人av网址 | 日本三级香港三级人妇99 | 99精品久久精品一区二区 | 九九国产精品视频 | 欧美日韩首页 |