docker 筆記一

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

docker概述
docker 出現的原因,解決了什么問題
在我們接觸的傳統專案開發中,專案或者說產品的一般擁有多套環境,開發,測驗,運維,不同的階段我們都需要在相應的服務器上重新搭建一套環境來進行使用,可能我們開發在用windows,測驗和上線用到的環境是linux,我們不能很簡便的通過一套統一流程來完成,需要根據具體的平臺等等去相應解決,
docker的出現和應用,能有效解決上面的問題,比如我們開發一個java專案,通過docker,可以把我們的代碼應用(jar包)+jre環境打包成一個docker鏡像,然后在其他的環境,我們只需要通過部署這個docker鏡像然后進行實體化就可以,
docker 是什么
docker 是一個開源的應用容器引擎,是一種輕量級的pass虛擬化技術,基于Go語言開發,通過docker可以讓開發者打包他們的應用以及依賴環境成為一個鏡像,然后上傳到倉庫中保存,在需要運行這個應用時,可以在任意平臺環境(win/linux/mac)上獲取這個鏡像,并實體化一個容器使用,實體化的應用相當于一個個小沙箱,每個應用都相當于一個小型的作業系統+服務,是相互隔離的,網路,存盤,因為輕量級,容器性能開銷極低,
大家都用過vmware,上面的概念可能過于抽象,我們可以從相對于vmware的角度來理解docker,通過vmware我們可以在原有作業系統之上虛擬化出一個與作業系統的虛擬機,docker 其實也是這樣,也是在原有系統之上,進行虛擬化,只不過相較于vmware,docker虛擬化更加輕量,docker是一種輕量的容器化虛擬技術,
vmware 與 docker 虛擬化技術對比
vmware: 傳統虛擬機技術,屬于type2虛擬化,虛擬出一套硬體,運行一個完整的作業系統包括系統內核,然后在這個系統之上安裝運行軟體,與宿主機之間完全隔離開來,資源占用十分多, 冗余步驟多, 啟動很慢!
docker:容器應用直接運行在宿主機內核之上,不進行硬體的虛擬化,相比較與vmware沒有硬體虛擬化,更加輕便,容器之間相互隔離,容器內擁有屬于自己的檔案系統,互相隔離,互不影響,
docker 應用場景
1.應用更快速交付部署
傳統:一對幫助檔案,安裝程式,
Docker:打包鏡像發布測驗一鍵運行,
2.更便捷的升級和擴縮容
使用了 Docker之后,我們部署應用就和搭積木一樣
專案打包為一個鏡像,擴展服務器A!服務器B3.更簡單的系統運維
在容器化之后,我們的開發,測驗環境都是高度一致的
4.更高效的計算資源的利用
Docker是內核級別的虛擬化,可以在一個物理機上可以運行很多的容器實體!服務器的性能可以被壓榨到極致,
docker 基本概念

鏡像(image)
docker 的鏡像是我們的程式打包出來的具體服務應用包括依賴環境,我們可以通過鏡像實體化我們的服務,一個實體化的服務我們稱之為容器,一個鏡像可以實體化多個容器,鏡像可以進行更新迭代的,
容器(container)
容器是鏡像的一個實體化,docker 利用容器化虛擬技術,獨立運行一個或者一組應用在一個容器內,容器是由鏡像來進行創建的,容器可以啟動,洗掉,停止,執行基本linux命令,可以把容器理解為一個包含我們應用的簡易linux系統,
倉庫(repository)
倉庫是存放鏡像的地方,倉庫可以分為公有倉庫和私有倉庫,倉庫起到了代管鏡像的作用,這和我們的github是一樣的,倉庫在我們的docker中可以分為本地倉庫和遠程倉庫,我們本地鏡像在docker中的管理的位置就是本地倉,常用的遠程docker倉庫 docker hub,國內云服務廠商也有各自的容器倉庫和容器鏡像加速,
docker安裝(ubutu 為例)
docker 安裝與使用要參考官方檔案:https://docs.docker.com/
# 卸載原有docker相關組件 sudo apt-get remove docker docker-engine docker.io containerd runc # 更新apt依賴 sudo apt-get update # 安裝docker相關依賴 sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ gnupg \ lsb-release # 增加Docker的官方GPG密鑰: curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg # 添加docker 源官方庫 echo \ "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 更新apt sudo apt-get update # 安裝最新版docker sudo apt-get install docker-ce docker-ce-cli containerd.io # 運行docker hello-world demo sudo docker run hello-world
# 安裝其他版本docker sudo apt-cache madison docker-ce # 查看其他版本docker資訊 sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io # 安裝docker,把VERSION_STRING替換為版本號 # 卸載docker和殘留檔案 sudo apt-get purge docker-ce docker-ce-cli containerd.io sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerddocker 在ubuntu 下還支持deb包方式的安裝,其他作業系統和包的安裝參照官方檔案,
docker 配置鏡像加速服務
docker 鏡像倉庫默認是docker hub,docker hub 在國外,為了加速下載鏡像我們可以配置阿里云鏡像加速服務,
登錄阿里云鏡像服務器
找到鏡像配置,按照阿里說明配置鏡像加速服務
sudo mkdir -P /etc/docker # 級聯創建docker配置目錄 # 添加鏡像倉庫地址到組態檔 sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://t60v9rvb.mirror.aliyuncs.com"] } EOF # 重新加載配置,重啟服務 sudo systemctl daemon-reload sudo systemctl restart dockerhello-world案例探究
docker run 流程
- docker run 運行一個鏡像,實體化一個容器,會先從本地倉查看是否有鏡像
- 本地有鏡像,直接運行,實體化一個容器
- 本地沒有,會先去遠程倉庫拉取,默認拉取最新版,拉取成功,實體化容器
- 遠程沒有,回傳錯誤找不到鏡像
docker 作業原理
docker 是一個client-server架構,docker的守護行程運行在服務主機上,通過socket通信從客戶端訪問,docker-server接收到這條docker-client指令,解釋執行
為什么docker 比 vm 速度快?
1、docker有著比虛擬機更少的抽象層,由于docker不需要Hypervisor實作硬體資源虛擬化,運行在docker容器上的程式直接使用的都是實際物理機的硬體資源,因此在CPU、記憶體利用率上docker將會在效率上有明顯優勢,
2、docker利用的是宿主機的內核,而不需要Guest OS(虛擬機的作業系統),因此,當新建一個 容器時,docker不需要和虛擬機一樣重新加載一個作業系統內核,仍而避免引導、加載作業系統內核返個比較費時費資源的程序,當新建一個虛擬機時,虛擬機軟體需要加載GuestOS,返個新建程序是分鐘級別的,而docker由于直接利用宿主機的作業系統,則省略了這個復雜的程序,因此新建一個docker容器只需要幾秒鐘,

docker基本命令使用
官方客戶端命令檔案和API:https://docs.docker.com/reference/,docker 命令操作需要用戶有root權限
1.幫助命令
docker version # 顯示docker 版本資訊 docker info # 顯示docker的系統資訊,包括docker鏡像容器和數量 docker 命令 --help # 查看命令幫助2.鏡像命令
docker images # 查看本地主機docker倉庫中的docker鏡像 -a # 列出所有鏡像 -q # 只顯示鏡像id docker search 鏡像名 # 搜索鏡像 -f # 通過條件過濾鏡像 -f=START=3000 過濾出START大于3000的鏡像 docker pull 鏡像名 # 下載鏡像 docker pull 鏡像名:版本號 # 下載指定tag版本的鏡像 docker rmi 鏡像名 # 洗掉所有同名鏡像 docker rmi 鏡像id # 洗掉指定鏡像id鏡像 docker rmi -f $(docker images -aq) #洗掉全部的鏡像 docker inspect 容器id # 查看鏡像元資料資訊3.容器命令
docker run 鏡像id # 通過鏡像新建容器并啟動 docker run [可選引數] image --name="指定容器名字" -d 后臺方式啟動 # 通常需要以后臺互動這種方式啟動,否則容器會運行一下就退出結束,無法對外提供服務 -it 互動方式啟動 # 一旦退出互動界面,容器停止,docker 容器底層都有系統內核,可以執行基本的linux/win指令 -p ip:主機埠:容器埠 # 配置服務通信埠,常用 -p 主機埠:容器埠(常用) -p 容器埠 容器埠 -P(大寫) 隨機指定埠 -v # 掛載資料卷 # 三種掛載: 匿名掛載、具名掛載、指定路徑掛載 -v 容器內路徑 #匿名掛載 -v 卷名:容器內路徑 #具名掛載 -v /宿主機路徑:容器內路徑 #指定路徑掛載 docker volume ls 是查看不到的 --link 容器名 # 添加 /etc/hosts 映射關系,支持容器名ping docker ps # 列出所有正在運行的鏡像 docker container list 與docker ps 等價 -a, --all #列出當前正在運行的容器 + 帶出歷史運行過的容器 -n=?, --last int #列出最近創建的?個容器 ?為1則只列出最近創建的一個容器,為2則列出2個 -q, --quiet #只列出容器的編號 exit # 容器直接結束退出 Ctrl+P+Q # 容器不停止退出 -- 常用,與容器互動完成,需要容器在后臺繼續服務 docker rm 容器id # 洗掉指定容器,容器需要先停止 docker rm -f $(docker ps -aq) #洗掉所有的容器 docker ps -a -q|xargs docker rm #洗掉所有的容器 docker start 容器id # 啟動指定容器 docker stop 容器id # 停止指定容器 docker restart 容器id # 重啟容器 docker kill 容器id # 強制殺死容器docker 容器的補充說明
# 命令 docker run -d 鏡像名 [root@iz2zeak7sgj6i7hrb2g862z ~]# docker run -d centos a8f922c255859622ac45ce3a535b7a0e8253329be4756ed6e32265d2dd2fac6c [root@iz2zeak7sgj6i7hrb2g862z ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES # 問題docker ps. 發現centos 停止了 # 常見的坑,docker容器使用后臺運行,就必須要有要一個前臺行程,docker發現沒有應用,就會自動停止 # nginx,容器啟動后,發現自己沒有提供服務,就會立刻停止,就是沒有程式了 docker run -d centos /bin/sh -c "while true;do echo 6666;sleep 1;done" #模擬前臺行程4.日志/行程相關命令
docker logs -- help # 查看docker日志 docker logs 容器id # 查看指定容器id 的日志,通常需要配合引數使用 -tf #顯示日志資訊(一直更新) --tail number #需要顯示日志條數 docker logs -t --tail n 容器id #查看n行日志 docker logs -tf 容器id #跟著日志 類似于linux 作業系統中的tail -f docker top 容器id # 查看容器中行程相關資訊5.進入正在后臺運行的容器/容器與主機檔案之間的相互拷貝(后面會有資料卷)
docker 容器通常是以后臺服務的形式運行的,我們有時候需要進入后臺服務的容器的內部進行操作修改配置
docker exec -it 容器id/容器名 /bin/bash #進入當前容器后開啟一個新的終端,可以在里面操作,(常用) 配合CTRL+Q+P/exit退出 docker exec 容器id/容器名 cat /etc/hosts #容器執行單一命令 docker attach 容器id/容器名 #進入容器正在執行的終端 docker cp 容器id:容器內路徑 主機目的路徑 # 拷貝容器內檔案到宿主機 docker cp 主機路徑 容器id:容器內路徑 # 拷貝宿主機檔案到容器
attach Attach local standard input, output, and error streams to a running container
#當前shell下 attach連接指定運行的鏡像
build Build an image from a Dockerfile # 通過Dockerfile定制鏡像
commit Create a new image from a container's changes #提交當前容器為新的鏡像
cp Copy files/folders between a container and the local filesystem #拷貝檔案
create Create a new container #創建一個新的容器
diff Inspect changes to files or directories on a container's filesystem #查看docker容器的變化
events Get real time events from the server # 從服務獲取容器實時時間
exec Run a command in a running container # 在運行中的容器上運行命令
export Export a container's filesystem as a tar archive #匯出容器檔案系統作為一個tar歸檔檔案[對應import]
history Show the history of an image # 展示一個鏡像形成歷史
images List images #列出系統當前的鏡像
import Import the contents from a tarball to create a filesystem image #從tar包中匯入內容創建一個檔案系統鏡像
info Display system-wide information # 顯示全系統資訊
inspect Return low-level information on Docker objects #查看容器詳細資訊
kill Kill one or more running containers # kill指定docker容器
load Load an image from a tar archive or STDIN #從一個tar包或標準輸入中加載一個鏡像[對應save]
login Log in to a Docker registry #
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes
docker 搭建環境使用案例
docker 安裝nginx
docker search nginx # 搜索nginx鏡像,

docker pull nginx # 可以后面跟:加版本號
docker images # 查看下載鏡像

docker run -d --name="nginx01" -p 3344:80 nginx # 根據鏡像構建容器運行,80 nginx 默認埠
docker ps # 查看正在運行中的容器

docker exec -it nginx01 /bin/bash # 后臺進入容器,基本linux系統操作
cd /etc/nginx
ls

docker stop 容器id # 停止nginx
docker ps # 查看運行中的容器

docker 安裝portainer: portainer 是docker圖型化工具,可以通過portainer可視化面板對docker進行管理
docker search portainer
docker images
docker run -d -p 8082:9000 \
--restart=always --name="portainer" -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer # 9000 portainer 默認埠
docker ps

可以通過web面板對我們的docker 進行可視化操作
docker鏡像原理之聯合檔案系統
鏡像是一種輕量級,可執行的獨立軟體包,用于打包軟體運行環境和基于運行環境開發的軟體,它包含運行某個軟體所需的所有的內容,包括代碼,運行時的庫,環境變數和組態檔,所有的應用,可以直接打包成docker鏡像跑起來,
獲取docker鏡像的方式:1.遠程倉庫下載 2.拷貝別人鏡像 3.自己制作一個DockerFile
unionfs 聯合檔案系統:union 檔案系統是一種分層,輕量級并且高性能的檔案系統,他支持對檔案系統的修改作為一次提交來層層的疊加,同時可以將不同目錄掛載到同一個虛擬檔案系統下,聯合檔案系統是制作docker鏡像的基礎,鏡像可以通過分層來進行繼承,基于基礎鏡像,可以制作各種具體的鏡像,特性:一次同時加載多個檔案系統,但從外面看起來是一個整體檔案系統,聯合加載會把各層的檔案系統疊加起來形成最終包含底層檔案和目錄的檔案系統,
docker鏡像加載的原理:docker 的鏡像是由一層層的檔案系統組成的,這種層級檔案系統,就是我們說的聯合檔案系統unionfs:
boots(boot file system)主要包含 bootloader和 Kernel, bootloader主要是引導加 kernel, Linux剛啟動時會加bootfs檔案系統,在 Docker鏡像的最底層是 boots,這一層與我們典型的Linux/Unix系統是一樣的,包含boot加載器和內核,當boot加載完成之后整個內核就都在記憶體中了,此時記憶體的使用權已由 bootfs轉交給內核,此時系統也會卸載bootfs,
rootfs(root file system),在 bootfs之上,包含的就是典型 Linux系統中的/dev,/proc,/bin,/etc等標準目錄和檔案, rootfs就是各種不同的作業系統發行版,比如 Ubuntu, Centos等等,
問題:平時我們安裝進虛擬機的CentOS都是好幾個G,為什么Docker這里才200M?
對于個精簡的OS,rootfs可以很小,只需要包合最基本的命令,工具和程式庫就可以了,因為底層直接用Host的kernel,自己只需要提供rootfs就可以了,由此可見對于不同的Linux發行版, boots基本是一致的, rootfs會有差別,因此不同的發行版可以公用bootfs.
虛擬機是分鐘級別,容器是秒級!
docker 鏡像原理之分層加載
我們在在下載一個鏡像,觀察日志輸出,可以看到是一層層的下載
docker 鏡像采用這種分層結構,帶來的最大的好處是資源共享,宿主機上只需要保留一份base基礎鏡像,同時記憶體也只需要加載一份,這樣所有的鏡像容器在啟動應用時就可以共享這一份base鏡像,并且鏡像的每一層都是可以共享的,只要有容器運行需要,查看鏡像分層的命令可以通過docker image inspact命令查看,
理解:
所有的docker鏡像都起始于一個基礎鏡像,當進行修改或添加新的內容時,就會在當前鏡像層之上創建新的鏡像層,
舉一個簡單的例子,假如基于 Ubuntu Linux16.04創建一個新的鏡像,這就是新鏡像的第一層;如果在該鏡像中添加 Python包,就會在基礎鏡像層之上創建第二個鏡像層;如果繼續添加一個安全補丁,就會創健第三個鏡像層該像當前已經包含3個鏡像層,如下圖所示(這只是一個用于演示的很簡單的例子),
在添加額外的鏡像層的同時,鏡像始終保持是當前所有鏡像的組合,理解這一點,
在添加額外的鏡像層時,鏡像始終是保持當前所有鏡像的組合,下圖中舉了一個簡單的例子,每個鏡像層包含3個檔案,而鏡像包含了來自兩個鏡像層的6個檔案,
上圖中的鏡像層跟之前圖中的略有區別,主要目的是便于展示檔案下圖中展示了一個稍微復雜的三層鏡像,在外部看來整個鏡像只有6個檔案,這是因為最上層中的檔案7是檔案5的一個更新版
文種情況下,上層鏡像層中的檔案覆寫了底層鏡像層中的檔案,這樣就使得檔案的更新版本作為一個新鏡像層添加到鏡像當中,Docker通過存盤引擎(新版本采用快斬訓制)的方式來實作鏡像層堆疊,并保證多鏡像層對外展示為統一的檔案系統,
Linux上可用的存盤引撃有AUFS、 Overlay2、 Device Mapper、Btrfs以及ZFS,顧名思義,每種存盤引擎都基于 Linux中對應的
件系統或者塊設備技術,井且每種存盤引擎都有其獨有的性能特點,Docker在 Windows上僅支持 windowsfilter 一種存盤引擎,該引擎基于NTFS檔案系統之上實作了分層和CoW [1],
下圖展示了與系統顯示相同的三層鏡像,所有鏡像層堆并合井,對外提供統一的視圖,
特點:
docker 鏡像都是只讀的,當容器啟動時,一個新的可寫層加載到鏡像的頂部,這一層就是我們所說的容器層,容器之下都叫鏡像層,我們在對當前的容器層進行修改,進行打包發布時,現在的容器層會變成新容器的只讀鏡像層,
docker commit 鏡像
docker 可以理解為我們的版本控制系統,我們對一個容器進行了修改,可以通過commit命令打包成一個新的命令推送到我們的本地image倉庫中,也可以push推送到遠程倉庫中,如果你想要保存當前容器的狀態,就可以通過commit來提交,獲得一個鏡像,就好比我們我們使用虛擬機的快照,
docker commit 提交容器成為一個新的副本 # 命令和git原理類似 docker commit -m="描述資訊" -a="作者" 容器id 目標鏡像名:[版本TAG]實體:
docker 安裝tomcat并打包鏡像
docker search tomcat docker pull tomcat:8.5 docker run -d --name="tomcat01" -P 8080:8080 tomcat:8.5 # 后臺啟動tomcat,完成宿主機與容器網路的埠映射 docker ps -a
此時我們發現訪問宿主機的8080埠沒有出現tomcat主頁而是報了tomcat的404界面
解決方式
docker exec -it tomact /bin/bash # 后臺方式進入容器 # 容器內執行如下命令,原因是docker的Tomcat鏡像webapp下沒有內容,內容在webapp.dist目錄下 cd /usr/local/tomcat cp -r webapp.dist/* webapp exit docker ps # 退出查看容器運行狀態
再次通過瀏覽器訪問tomcat成功出現主頁,成功
docker stop 容器id docker commit -a="ldy" -m="添加webapp" 容器id 鏡像名:版本號 docker images
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/280333.html
標籤:其他
下一篇:Redis事務控制





















