參考
狂神說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/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://73z5h6yb.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo 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 centos
VOLUME ["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 centos
VOLUME ["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
官網centos
dockerfile: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 $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 8088
CMD 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 k
vim-common x86_64 2:8.0.1763-15.el8 appstream 6.3 M
vim-filesystem noarch 2:8.0.1763-15.el8 appstream 48 k
which x86_64 2.21-12.el8 baseos 49 k
Transaction Summary
================================================================================
Install 5 Packages
Total download size: 7.8 M
Installed size: 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 C65D
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : which-2.21-12.el8.x86_64 1/5
Installing : vim-filesystem-2:8.0.1763-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.noarch
which-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 k
Transaction Summary
================================================================================
Install 1 Package
Total 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 transaction
Preparing : 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 1500
inet 172.18.0.5 netmask 255.255.0.0 broadcast 172.18.255.255
ether 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 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX 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.txt
ADD jdk-8u281-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.41.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV 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/bin
EXPOSE 8080
CMD /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 k
vim-common x86_64 2:8.0.1763-15.el8 appstream 6.3 M
vim-filesystem noarch 2:8.0.1763-15.el8 appstream 48 k
which x86_64 2.21-12.el8 baseos 49 k
Transaction Summary
================================================================================
Install 5 Packages
Total download size: 7.8 M
Installed size: 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 C65D
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : which-2.21-12.el8.x86_64 1/5
Installing : vim-filesystem-2:8.0.1763-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.noarch
which-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/javaee
http://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 --help
Usage: docker login [OPTIONS] [SERVER]
Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.
Options:
-p, --password string Password
--password-stdin Take the password from stdin
-u, --username string Username

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 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
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 0
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
valid_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:6379
slots:[0-5460] (5461 slots) master
M: b233e1c2053a77c2351b511e784579cd50a3e5a8 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
M: da06f6994fe142969f313fa7c6d8cb94cd1facb7 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
S: 944f7e0f2e3082745c2e999470f969d53cd1bdd9 172.38.0.14:6379
replicates da06f6994fe142969f313fa7c6d8cb94cd1facb7
S: eaab096391c79d4d3d42be66fcc66cb2d724720b 172.38.0.15:6379
replicates f693f5b7cc515154a532aa5f48ff627d2827e205
S: 09ba78c0f4f1848a6a9c6d0b9ccc42a159a394a4 172.38.0.16:6379
replicates 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:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 944f7e0f2e3082745c2e999470f969d53cd1bdd9 172.38.0.14:6379
slots: (0 slots) slave
replicates da06f6994fe142969f313fa7c6d8cb94cd1facb7
M: da06f6994fe142969f313fa7c6d8cb94cd1facb7 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: eaab096391c79d4d3d42be66fcc66cb2d724720b 172.38.0.15:6379
slots: (0 slots) slave
replicates f693f5b7cc515154a532aa5f48ff627d2827e205
S: 09ba78c0f4f1848a6a9c6d0b9ccc42a159a394a4 172.38.0.16:6379
slots: (0 slots) slave
replicates b233e1c2053a77c2351b511e784579cd50a3e5a8
M: b233e1c2053a77c2351b511e784579cd50a3e5a8 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
1 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下來即可運行
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/265374.html
標籤:其他

