文章目錄
- 為什么要用docker
- docker安裝
- docker工作原理
- docker命令
- docker搭建練習
- docker可視化
- docker鏡像
- docker容器數據卷
- DockerFile
- docker全流程
- Docker網絡原理
- docker compose
- docker swarm
為什么要用docker
- 官網:https://www.docker.com
- 文檔地址:https://docs.docker.com
- 倉庫地址:https://hub.docker.com
一款產品:
開發:開發環境 — 開發人員
上線:應用環境,應用配置 — 運維人員
傳統方法:開發人員打包好應用程序,剩下的交給運維
問題:
- 環境不同,版本更新,端口沖突等導致服務不可用,這對于運維來說,考驗很大
- 環境配置費時費力
現在方法:開發打包部署上線,一套流程做完
docker解決了上面的問題:
打包項目帶上環境(鏡像) -> docker倉庫 -> 下載發布的鏡像 -> 直接運行即可
docker核心思想:
隔離:打包裝箱,每個容器時相互隔離的
- 優點:
- 使得容器之間不會相互影響
- 通過隔離機制,使得某個容器能使用的資源被限制,這樣可以節省設備資源,使得設備資源被利用到極致
docker與虛擬機的聯系與區別:
- 虛擬機:例如VMware,通過這個軟件我們可以虛擬出來多臺電腦,缺點是十分笨重
- docker:使用了容器技術,也是一種虛擬化技術,但是十分輕巧
假設需要使用一臺linux機器
- VMware:導入linux鏡像(一臺電腦)。隔離:需要開啟多個虛擬機
- docker:隔離:鏡像(最核心的環境(約4M大小) + 項目需要的運行環境)
- 傳統虛擬機:虛擬出一條硬件,運行一個完整的操作系統,然后在這個系統上安裝和運行軟件
- docker:容器內的應用直接運行在宿主機的內容,容器是沒有自己的內核的,也沒有我們虛擬的硬件,所以就輕便了
docker為什么比VM快:
docker有著比虛擬機更少的抽象層
docker利用的是宿主機的內核,vm需要的是Guest OS。所以說,新建一個容器的時候,docker不需要像虛擬機一樣重新加載一個操作系統內核,避免啟動引導程序。
docker的好處:
- 應用更快速的交付和部署
- 更便捷的升級和擴縮容
- 更簡單的系統運維
- 更高效的計算資源利用
docker安裝
-
docker的基本組成:
- 客戶端(client)
- 服務器(docker_host)
- 倉庫(registry)
- 鏡像(image):docker鏡像就好比一個模板,可以通過這個模板來創建多個容器。
- 容器(Container):docker利用容器技術,獨立運行一個或者一個組應用,通過鏡像來創建的。相當于一個小型linux系統。
- 基本命令:啟動,停止,刪除
- 可以將這個容器理解為一個簡易的linux系統
- 倉庫(repository):存放鏡像的地方。倉庫分為公有倉庫和私有倉庫:
- docker hub(國外)
- 阿里云,華為云等
-
安裝docker
-
環境準備
- linux基礎
- ubuntu22.04
-
環境查看
uname -r #確定內核在3.0以上 cat /etc/os-release # 查看操作系統信息
-
安裝
幫助文檔:https://www.runoob.com/docker/ubuntu-docker-install.html
- 卸載舊版本
sudo apt-get remove docker docker-engine docker.io containerd runc
- 安裝需要的包
sudo apt-get update sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
- 設置倉庫
# 添加Docker的官方GPG密鑰 curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# 驗證是否擁有帶指紋的密鑰 sudo apt-key fingerprint 0EBFCD88
# 設置穩定版倉庫 sudo add-apt-repository \ "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/ \ $(lsb_release -cs) \ stable"
- 安裝 Docker Engine-Community
sudo apt-get install docker-ce docker-ce-cli containerd.io
- 查看是否安裝成功,運行以下hello-world
sudo docker run hello-world
- 查看一下下載的hello-world鏡像
docker images
- 卸載docker
sudo apt-get purge docker-ce # 刪除安裝包 sudo rm -rf /var/lib/docker # 刪除鏡像、容器、配置文件等內容,
/var/lib/docker是docker默認工作路徑
-
配置阿里云鏡像加速
-
-
回顧hello-world鏡像拉取過程
- docker在本機尋找鏡像,判斷是否有鏡像,如果有則使用并運行。否則執行下一步
- 去docker hub上下載。如果沒找到鏡像,返回錯誤。如果找到了鏡像,將鏡像下載到本地
- 使用下載好的鏡像,下次運行時就可以直接從本機找到該鏡像了
docker工作原理
docker是一個client-server結構的系統,docker的守護進程運行在主機上,通過socket從客戶端訪問
docker-server接收到docker-client的指令,就會執行這個命令,可能是啟動一個容器,這個容器就可以看成是一個小的linux系統,在這個容器內可以運行一些服務,例如mysql(3306端口)
docker命令
-
幫助命令
docker version
顯示docker版本信息docker info
顯示docker的系統信息,包括鏡像和容器的數量docker --help
幫助命令docker <命令> --help
查看特定命令的幫助信息
-
幫助文檔的地址:https://docs.docker.com/reference/
-
鏡像命令
docker images
查看所有鏡像
docker search <鏡像名稱>
搜索鏡像
docker pull <鏡像名稱>
下載鏡像
docker pull mysql
等價于docker pull docker.io/library/mysql:latest
下載指定版本mysql:docker pull mysql:5.7
docker rmi --f <鏡像名稱/鏡像id>
刪除鏡像,使用鏡像id不需要全寫上,只需要寫幾個前綴,能夠與別的鏡像區分開即可docker rmi --f <鏡像id> <鏡像id>..
批量刪除鏡像docker rmi -f $(docker images -aq)
docker images -aq會查出所有鏡像的id,這樣可以刪除所有鏡像
-
容器命令
說明:有了鏡像才可以創建容器,linux,下載一個centos鏡像來學習
docker pull centos
-
容器運行
docker run [可選參數] <image>
新建容器并啟動
--name="NAME"
容器名稱-d
后臺方式運行,后臺運行時必須要有一個前臺進程,否則docker發現沒有應用,就會自動停止。具體例如:
docker run -d centos -c "while true;do echo kuangshen;sleep 1;done"
# 這段命令循環運行了一個前端shell腳本,這樣就使得docker不停止-it
使用交互方式運行,進入容器查看內容-p 主機端口:容器端口
指定主機端口和容器端口的映射-p 容器端口
指定容器端口-P
隨機指定端口
-
查看正在運行的容器
docker ps
查看正在運行的dockerdocker ps -a
查看正在+曾經運行的docker
-
終止容器
exit
停止容器并退出ctrl + p + q
容器不停止退出
-
刪除容器
docker rm <容器id>
刪除容器,不能刪除正在運行的容器,如果像刪除,加-f參數docker rm $(docker ps -aq)
刪除所有容器docker ps -a -q|xargs docker rm
刪除所有容器
-
容器啟停
docker start <容器id>
啟動容器docker restart <容器id>
重啟容器docker stop <容器id>
停止當前正在運行的容器docker kill <容器id>
強制停止當前容器
-
日志、進程、元數據的查看
docker logs -tf --tail 10 <容器id>
查看尾部10條日志docker top <容器id>
查看進程信息docker inspect <容器id>
查看容器元數據
-
進入正在運行的容器、拷貝命令
docker exec -it <容器id> /bin/bash
交互模式進入docker attach <容器id>
交互模式進入docker cp <容器id>:<文件路徑> <主機路徑>
從容器內拷貝文件到主機上
-
docker搭建練習
-
Docker 安裝 Nginx
- 搜索鏡像
docker search nginx
或者直接dockerhub上搜索 - 下載鏡像
docker pull nginx
- 查看鏡像
docker images
- 啟動鏡像
docker run -d --name nginx01 -p 3344:80 nginx
給這個容器起一個名:nginx01,外面端口設置為3344(可以進行公網訪問),容器內端口設置為nginx默認端口80,這樣在外面就可以通過3344端口訪問到nginx - 測試鏡像
curl localhost:3344
- 交互模式進入容器
docker exec -it nginx01 /bin/bash
- 找到nginx應用路徑
whereis nginx
問題:每次需要修改nginx配置文件都需要進入容器內部,十分麻煩,如果可以在容器外部提供一個映射路徑,使得能夠修改容器內的文件。
-v 數據卷
- 搜索鏡像
-
docker 安裝 tomcat
- 直接用run自動下載鏡像,啟動容器
docker run -ti --rm tomcat:9.0
--rm參數表示該容器用完(stop)即刪除,是用來測試的 - 正常啟動容器
docker run -d -p 3355:8080 --name tomcat01 tomcat:9.0
- 查看容器
docker ps
- 進入容器
docker exec -it tomcat01 /bin/bash
- 終止容器
docker stop tomcat01
- 刪除容器
docker rm tomcat01
- 直接用run自動下載鏡像,啟動容器
-
docker 部署 es + kibana
問題:
- es 暴露的端口很多
- es 十分耗內存
- es 的數據一般需要放置到安全目錄!掛載
- 去dockerhub搜索elastic鏡像
- 下載鏡像,啟動容器
docker network create somenetwork
docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:tag
- 查看容器cpu狀態
docker stats
- 下載kibana鏡像并運行,思考兩個容器如何通信
docker可視化
-
portainer:docker圖形化界面管理工具!提供一個后臺面板供我們操作
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
訪問測試:
localhost:8088
默認用戶名:admin
,設置密碼:XXX
,選擇local,connect
-
Rancher
docker鏡像
鏡像是一種輕量級、可執行的獨立軟件包,用來打包軟件運行環境和基于運行環境開發的軟件,它包含運行某個軟件所需的所有內容,包括代碼、運行時、庫、環境變量和配置文件。
-
如何得到鏡像
- 遠程倉庫下載
- 朋友拷貝給你
- 自己制作一個鏡像DockerFile
-
核心思想:層級文件系統Union File System(UnionFS)
分層下載的好處在于:當下載一個新的鏡像時,如果之前下載過該鏡像中的某一層,那么就不用重復下載了,節省內存。 -
特點:
docker鏡像都是只讀的,當容器啟動時,一個新的可寫層被加載到鏡像的頂部!這一層就是我們通常說的容器層,容器之下的都叫鏡像層。
-
commit鏡像:
docker commit -m="提交的描述信息" -a="作者" <容器id> 目標鏡像名:<tag>
docker images
查看提交的鏡像
docker容器數據卷
- 問題:docker是將應用和環境打包成一個鏡像,但是不考慮數據。如果數據都存放在容器中,那我們將容器刪除,數據就會丟失
- 需求:數據可以持久化
- 解決方法:容器之間需要一個數據共享的技術。docker容器中產生的數據,同步到本地,這就是卷技術。
簡單來說,卷技術就是目錄的掛載,將容器內的目錄掛載到主機上。舉例:
方式1:使用命令來掛載:
docker run -it -v 主機目錄:容器目錄 <容器id>
docker inspect <容器id>
查看掛載情況,雙向綁定,不管修改主機還是容器,都會同步。即使容器被停止了,也會同步
-
實戰:同步mysql數據
運行容器:
docker run -d -p 3310:3306 -v /home/yonghu/ceshi:/etc/mysql/conf.d -v /home/yonghu/ceshidata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
實現多個掛載,配置文件掛載和數據掛載 -
具名掛載和匿名掛載
- 匿名掛載:
-v 容器路徑:<權限>
- 具名掛載:
-v 卷名:容器路徑:<權限>
- 指定路徑掛載:
-v 主機路徑:容器路徑:<權限>
<權限>
可以設置為ro
只讀、rw
讀寫。ro
權限是只能主機進行修改,容器無法修改了。
docker volume ls
將所有的卷都打印出來
docker volume inspect <卷名>
查看指定卷的細節
所有的docker容器內的卷,沒有指定目錄的情況下都是在
/var/lib/docker/volumes
目錄下 - 匿名掛載:
方式2:使用DockerFile來掛載
DockerFile就是用來構建docker鏡像的構建文件。其實就是一個命令腳本,通過這個腳本可以生成一個鏡像。鏡像是一層一層的,因此腳本是一個一個的命令,每個命令都是一層。
mkdir ceshi
pwd
vim dockerfile1
創建一個dockerfile文件
FROM centos:指定基礎鏡像
VOLUME [“volume01”,“volume02”]:通過volume進行掛載
CMD echo “------end------”:輸出end
CMD /bin/bash:進入到/bin/bash中
docker build -f dockerfile1 -t test/centos .
當前目錄下build鏡像
docker images
docker run -it --name mycentos test/centos /bin/bash
ls -l
exit
docker inspect mycentos
查看卷掛載主機路徑
-
多個mysql同步數據
docker run -it --name centos01 test/centos
創建父容器(數據卷容器)
docker run -it --name centos02 --volumes-from centos01 test/centos
--volumes-from同步兩個容器即使刪除父容器,數據仍然存在
DockerFile
DockerFile就是用來構建docker鏡像的構建文件。其實就是一個命令腳本,通過這個腳本可以生成一個鏡像。鏡像是一層一層的,因此腳本是一個一個的命令,每個命令都是一層。
構建步驟:
- 編寫一個 dockerfile 文件
- 構建一個鏡像:
docker build -f <docker文件名> -t 鏡像名 .
- 運行鏡像:
docker run
- 發布鏡像(dockerhub、阿里云鏡像倉庫):
docker push
-
DockerFile基礎知識
- 每個保留關鍵字都必須是大寫字母
- 執行從上到下順序執行
- # 表示注釋
- 每一個指令都會創建提交一個新的鏡像層,并提交
-
DockerFile指令
- FROM:指定基礎鏡像。
示例:
FROM ubuntu:latest
- MAINTAINER:指定維護者信息。
示例:
MAINTAINER dj<123456@qq.com>
- RUN:在鏡像中執行命令。
示例:
RUN apt-get update && apt-get install -y package
- COPY:將文件從構建上下文復制到鏡像中。
示例:
COPY app.py /app/
- ADD:類似于 COPY 命令,但還支持遠程URL和解壓縮文件。
示例:
ADD http://example.com/file.tar.gz /data/
- WORKDIR:設置工作目錄。
示例:
WORKDIR /app
- EXPOSE:聲明容器在運行時監聽的端口。
示例:
EXPOSE 8080
- ENV:設置環境變量。
示例:
ENV MY_ENV_VAR=value
- CMD:指定容器啟動后要執行的命令。只有最后一個會生效,可被替代。
示例:
CMD ["python", "app.py"]
- ENTRYPOINT:將容器作為可執行程序運行,忽略 CMD 指令。
示例:
ENTRYPOINT ["python","app.py"]
- VOLUME:聲明容器中的掛載點。
示例:
VOLUME /data
-
實戰:構建自己的centos
-
編寫dockerfile文件
vim dockerfile2
FROM centos MAINTAINER dj<123456@qq.com>ENV MYPATH=/usr/local WORKDIR $MYPATHRUN yum -y install vim RUN yum -y install net-toolsEXPOSE 80CMD echo $MYPATH CMD echo "----end----" CMD /bin/bash
-
構建鏡像
docker build -f dockerfile2 -t test/mycentos .
-
運行容器
docker run -it test/mycentos
-
查看鏡像是如何制作的
docker history <容器id>
-
-
CMD和ENTRYPOINT的區別
CMD命令:
vim dockerfile3
FROM centos CMD ["ls","-a"]
docker build -f dockerfile3 -t test/dockerfile3 .
docker run -it test/dockerfile3
正常運行得到:
docker run -it test/dockerfile3 -l
后面加一個-l
參數,報錯:
docker run -it test/dockerfile3 ls -al
,正常運行
ENTRYPOINT命令(追加命令):
vim dockerfile4
FROM centos ENTRYPOINT ["ls","-a"]
docker build -f dockerfile4 -t test/dockerfile4 .
docker run -it test/dockerfile4
正常運行得到:
docker run -it test/dockerfile4 -l
,正常運行:
-
實戰:部署tomcat
bilibili視頻 - 部署tomcat -
發布自己的鏡像到dockerhub
- dockerhub注冊賬號
- 使用命令登錄賬號
docker login -u <用戶名> -p <密碼>
- 提交鏡像
docker tag <鏡像id> <鏡像名>:<tag>
指定某個鏡像id
,復制一個名為<鏡像名>:<tag>
的新鏡像
docker push <鏡像名>或者<鏡像id>:<tag>
docker全流程
Docker網絡原理
- 理解docker0
docker0相當于網關。
問題:docker是如何處理容器網絡訪問的?
-
解決上述問題
-
運行一個tomcat容器
docker run -d -P --name tomcat01 tomcat
-
查看容器內部網絡地址
docker exec -it tomcat01 ip addr
-
嘗試ping容器
ping 172.17.0.2
可以ping通 -
再開啟一個tomcat容器
docker run -d -P --name tomcat02 tomcat
-
tomcat01嘗試ping tomcat02
docker exec -it tomcat01 ping 172.17.0.3
,可以ping通
-
運行
ip addr
,此時多了兩對網卡
每啟動一個docker容器,dockers就回給dockers容器分配一個ip,我們只要安裝了docker,就會有一個網卡docker0(橋接模式),使用的技術是veth-pair技術。
veth-pair:是一對虛擬設備接口,成對出現,一端連接協議,一段彼此相連。例如主機如果想和容器通信,那么主機和容器就會彼此相連,然后再連接協議。
橋接模式:在bridged模式下,VMWare虛擬出來的操作系統就像是局域網中的一臺獨立的主機,它可以訪問網內任何一臺機器。主機網卡和虛擬網卡的IP地址處于同一個網段,子網掩碼、網關、DNS等參數都相同。這種方式簡單,直接將虛擬網卡橋接到一個物理網卡上面,和linux下一個網卡 綁定兩個不同地址類似,實際上是將網卡設置為混雜模式,從而達到偵聽多個IP的能力。在此種模式下,虛擬機內部的網卡(例如linux下的eth0)直接連到了物理網卡所在的網絡上,可以想象為虛擬機和host機處于對等的地位,在網絡關系上是平等的,沒有誰在誰后面的問題。
NAT模式:相當于宿主機再構建一個局域網,虛擬機無法和本局域網中的其他真實主機進行通訊。只需要宿主機器能訪問互聯網,那么虛擬機就能上網,不需要再去配置IP地址,子網掩碼,網關。虛擬機和主機能夠互相ping通。
-
-
容器互聯 link
- 新建一個容器tomcat03來link tomcat02
docker run -d -P --name tomcat03 --link tomcat02 tomcat
- 測試用容器名,看能否ping通
docker exec -it tomcat03 ping tomcat02
,可以ping通
docker exec -it tomcat02 ping tomcat03
,不可以ping通
docker exec -it tomcat03 cat /etc/hosts
,查看路由,發現tomcat03的路由中存放著tomcat02的ip映射
docker exec -it tomcat02 cat /etc/hosts
,查看路由,發現tomcat02的路由中沒有tomcat03的ip映射
- 新建一個容器tomcat03來link tomcat02
-
自定義網絡
- 查看網卡
docker network ls
bridge:橋接模式(自定義網絡)
host:和宿主機共享網絡
none:不配置網絡
container:容器網絡連通
- 自定義網絡
(1)docker run -d -P --name tomcat01 tomcat
等價于docker run -d -P --name tomcat01 --net bridge tomcat
,默認運行容器使用橋接模式
(2)docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
(3)docker network ls
(4)docker network inspect mynet
(5)docker run -d -P --net mynet --name tomcat01 tomcat
,運行一個自己網絡下的容器
(6)自定義網絡無需使用link也可以使用容器名進行ping通
- 查看網卡
問題:不同網段的容器如何互聯?
-
容器連通
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat02 --net mynet tomcat
docker network connect mynet tomcat01
dcoker exec -it tomcat01 ping tomcat02
,可以ping通,反過來也可以ping通
docker network inspect tomcat01
,觀察網卡信息,發現tomcat01被寫入
docker exec -it tomcat01 ip addr
,查看tomcat01網卡信息,發現多了一個IP地址
docker compose
-
docker compose 介紹
之前docker只能每個容器單個操作build,run等命令,現在可以使用docker compose批量處理,輕松高效的管理容器。
-
三步驟:
- Dockerfile保證項目在任何地方運行
- 定義服務,編寫docker-compose.yml文件
- 啟動項目,docker-compose up
- 問題:如果要部署一個web服務,我們要使用到redis、mysql、nginx…多個容器,一個一個去build,run非常麻煩
- 解決:docker compose
-
compose中重要概念:
- 服務services:容器,應用。(web,redis,mysql…)
- 項目project:一組關聯的容器。例如:博客
-
-
docker compose 安裝
sudo curl -L "https://hub.nuaa.cf/docker/compose/releases/download/2.23.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
,修改權限docker-compose --version
,查看是否安裝成功
-
docker compose 使用
官方簡單使用
正常步驟:
- 準備好所有需要的依賴文件
- 寫好DockerFile來構建web應用鏡像
- 倉庫拉取redis鏡像
- run,構造兩個容器
- 對兩個容器做互通
docker-compose:
- 準備好所有需要的依賴文件
- 寫好DockerFile來構建web應用鏡像
- 寫docker-compose.yml文件
- 一鍵部署
docker-compose up
-
命令:
docker-compose up
啟動docker-compose down
或ctrl+c
停止
-
docker-compose.yml文件編寫
共三層:版本、服務、其他配置
官方文檔version: ' ' # 版本 service: # 服務服務1(web):images:build:network:...服務2(redis):... # 其他配置 volumes: networks: configs: secrets: