docker實踐總結——docker常用命令

介紹

docker之前就有過了解,最近工作中有用到,便準備系統的學習一下,順便通過博客的形式做筆記。

docker和虛擬機(如VMware)的區別:docker比虛擬機要輕量級,虛擬機是模擬硬件,然後在虛擬的硬件上安裝操作系統,操作系統本身就是重量級軟件,而docker則是基於容器的虛擬化技術,你可以把容器理解爲沙箱環境,當然容器化的技術是依賴於操作系統的,在Linux中是基於cgroups來實現的,Windows家庭版安裝docker貌似還是依賴虛擬機(Windows專業版則基於Hyper-V實現)。容器中只會有需要運行的應用以及它依賴的必要庫(比如依賴一些操作系統的必要庫文件,而不向虛擬機一樣需要整個操作系統)。docker容器中的軟件是直接與系統通信,而虛擬機中的軟件與系統通信則多了一層“從操作系統”(虛擬機中的操作系統)。

舉個例子,假設我電腦上已經安裝了MySQL,但是我需要安裝另外一個版本的MySQL做測試用,如果我使用虛擬機,則需要在電腦中安裝並啓動一個虛擬機,在虛擬機中安裝操作系統,然後在虛擬機操作系統中安裝MySQL,整個虛擬機跑起來佔用資源是相當大的(操作系統+MySQL)。
如果我使用docker,則只需要一個MySQL鏡像,將鏡像加載到容器中,然後啓動容器,這樣就運行了一個完全獨立於本機的MySQL服務,效果與虛擬機的完全一樣,而且這個MySQL服務佔用的資源很小,只有MySQL軟件本身和一些必要的庫文件(必要的庫+MySQL),而不是整個操作系統+MySQL軟件,非常輕量級的。


幾個概念

docker的三個重要概念:

  1. 鏡像
    在docker中,鏡像屬於只讀層,可以理解爲一個軟件包,有點類似操作系統鏡像的IOS文件,不過比操作系統較輕量級很多。
  2. 容器
    簡單的說,容器可以理解爲一個鏡像在docker中的實例,容器啓動之後便是 docker daemon 的一個子進程,同一個鏡像可以多次運行,可以形成多個容器,每個容器都會有一個容器ID(containerID),當然你也可以指定一個容器名稱(containerName),容器名稱要唯一。
    用面嚮對象語言來打個比方,如果用Java語言中的類來比作鏡像(如Thread類),則容器是這個類的一個對象實例(即 new Thread()),容器本身可以運行和停止,有點像 thread.start() 和tread.stop(),這個比方不一定恰當,能夠增強理解就行。
    注意: docker本身不是容器,它是創建容器的工具,是一個容器引擎。
  3. 倉庫
    倉庫是用於存放鏡像的,有點類似於maven倉庫。用於集中管理鏡像文件。

常用命令


鏡像相關命令

以運行Python容器爲例:

docker search python       #搜索Python鏡像  
docker pull python:3.8.2   #拉取Python3.8.2的鏡像 
docker images              #查看本地鏡像列表,找到 Python 對應的 IMAGE ID。
docker images python       #列出名稱未python的所有鏡像
docker image ls            #執行效果好像與”docker images“相同,沒有具體研究過差異 
docker history [imageId]   #查看鏡像創建歷史  


run命令

如下 “b5b4d78bc90c” 爲我電腦中Python的 imageId。
可以執行 “docker images python” 找到 imageId 。

docker run -it b5b4d78bc90c /bin/bash #用鏡像啓動一個容器,並且直接進入該容器:輸入"exit"退出容器後容器進程也停止,使用“docker ps -a”可以查看該容器運行狀態爲Exited。
docker run -itd b5b4d78bc90c /bin/bash  #使用鏡像啓動一個容器,並在後臺執行,通過"docker ps -a"查看"containerId",然後通過"docker exec -it [containerId] bash"進入該容器,執行"exit"退出容器後該容器進程不退出,任然在後臺運行。
docker run -itd --name py3.8 b5b4d78bc90c /bin/bash  #使用鏡像啓動一個容器,指定容器名稱,並在後臺執行,"--name py3.8" 表示指定容器名稱,名稱和containerId一樣是唯一識別符不能重複,因爲也可以通過容containerName進入容器"docker exec -it py3.8 bash"。 

docker run -v /opt/docker_container/python:/data  -w /data --name py3.8.2 -itd b5b4d78bc90c /bin/bash 
#在本地建立目錄 /opt/docker_container/python 映射給容器的 /data 目錄,並已/data爲容器的工作目錄 
#-v參數:映射本地文件啓動容器
#-w參數:指定進入容器的工作目錄,相當於進入容器自動執行"cd"命令 
#執行完後,可以通過 "docker ps -a" 看到一個正在運行的容器ID。

通過運行python文件

docker run -v $PWD:/usr/code/py -w /usr/code/py [pythonImageId] python hello.py  
#-v $PWD/myapp:/usr/src/myapp: 將主機中當前目錄下的 myapp 掛載到容器的 /usr/src/myapp。hello.py文件在該目錄中。
#-w /usr/src/myapp: 指定容器的 /usr/src/myapp 目錄爲工作目錄。
#python helloworld.py: 使用容器的 python 命令來執行工作目錄中的 helloworld.py 文件。
#執行完後,可以通過 "docker ps -a" 看到一個已經退出的容器ID。

啓動mongodb容器

#參數指定數據的目錄,數據庫的用戶名和密碼等 
docker run --name mongo -p 27017:27017 -v ~/docker-data/mongo:/data/db -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=admin -d mongo


exec命令

通過containerId或者containerName進入容器bash

docker exec -it [containerId] bash     #通過containerId進入容器,然後執行bash交互式命令  
docker exec -it [containerName] bash   #進入containerName進入容器,然後執行bash交互式命令  

#容器bash即交互式的命令行,其實就是一個Linux的shell環境。
#containerID和containerName可以通過 “docker ps -a” 命令找到。
#-i 表示輸入流(標準輸入和錯誤輸入——stdIn和errorIn),如果沒有-i則不會輸出任何內容,比如執行"ls"之後不會有任何輸出。 
#-t 表示分配一個僞終端。  

通過容器執行腳本

docker exec [containId] /test.sh     #用容器執行腳本
docker exec -d [containId] /test.sh  #用容器執行腳本,

#-d 表示在後臺執行,如果腳本執行時間過長,可以使用"-d"在後臺運行。 

通過容器執行命令行

docker exec -it py3.8.2 bash -c "echo hello"               #進入容器執行echo命令,然後退出。  
docker exec -it py3.8.2 bash -c "echo hello && echo world" #連續執行多條命令,然後退出,命令之間用“&&”隔開。  
docker exec -it py3.8.2 bash -c "python main.py"           #進入容器執行python腳本,然後退出。  
docker exec -it py3.8.2 bash -c "echo 'print('\"'\"'hello python!'\"'\"')' > hello.py"  #執行echo並將結果輸出到hello.py文件  

#“py3.8.2”是我本機的python容器名稱。
#-c參數表示執行命令行,後面用雙引號將命令行內容引起來,如 -c "echo hello"。
####題外話:
#注意後面命令行中的 [ \" ]是雙引號轉義,避免與最外層的雙引號衝突,而'"'"'是爲了讓echo能輸出單引號。 
#如 [ echo 'I'"'"'m' ] 能夠正常輸出爲:I'm 
#其實這裏分爲了三段:用單引號引起來的字母I——['I'] 、用雙引號引起來的單引號——["'"] ,以及用單引號引起來的字母m——['m']
#如  [ echo 'I'm' ] 和 [ echo I'm ] 都不能正確輸出。
#說明:echo 後面輸出的內容加雙引號和不加是一樣的, 
#如[ echo $PATH ] 和 [ ehco "$PATH" ] 都會輸出變量PATH的具體值,
#而單引號則表示原樣輸出,如 [ echo '$PATH' ] 則輸出爲“$PATH”字符本身。


top命令

docker top [containerId|containerName] #查看容器內部的進程 

#如:
docker top 894ddc4c6dd1
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                13077               13037               0                   16:38               pts/0               00:00:00            /bin/bash
root                14619               13037               0                   16:57               ?                   00:00:00            /bin/bash
root                14627               14619               0                   16:57               ?                   00:00:00            python

#當然你也可以先進入容器bash:”docker exec -it 894ddc4c6dd1 bash“,然後再執行”top“。 
#不過容器中還不一定有top命令,這時可以使用”docker top“來直接查看容器中正在運行的進程。


容器啓動和停止

docker start [containerId|containerName]    #啓動容器 
docker restart [containerId|containerName]  #重啓容器 
docker stop  [containerId|containerName]    #停止容器,”優雅停止“——讓容器自己停止,在停止前可能有一些”退出前“的工作需要做,比如等待一些未執行完的請求等。
docker kill [containerId|containerName]     #強制停止容器,殺掉一個運行中的容器進程  
docker pause [containerId|containerName]    #暫停容器
docker unpause [containerId|containerName]  #恢復容器 


徹底刪除鏡像

#先停止容器,然後刪除容器,最後刪除鏡像    
docker stop [containerId] #停止容器,通過 docker ps -a 找到container_id
docker rm [containerId]   #刪除容器,通過 docker ps -a 找到container_id
docker rmi [imageId]      #刪除鏡像,通過 docker images 找到image_id


其他命令

docker create [imageId|imageName]  #創建一個新的容器但不啓動它

#與run命令相比較:
#不同點:run命令根據鏡像創建容器,並啓動它,而create只創建不啓動。
#共同點:如果後面的參數是imageName,而不是imageId,則本地不存在該鏡像時,會從倉庫pull該鏡像。 

docker -v        #查看版本號
docker version   #查看詳細的版本信息,包括docker版本以及api版本等
docker info      #查看docker系統信息,包括鏡像和容器數等 

docker ps               #查看正在運行的容器  
docker ps -a            #查看容器列表,包含當前運行的和曾經運行過的  
docker container ls     #查看容器列表,同 “ps” 命令  
docker container ls  -a #查看容器列表,同 “ps -a” 命令 

docker inspect [containerId|containerName] #列出容器的詳細信息(json格式展示)
 
docker attach [containerId|containerName]  
#attach到容器,看似效果與 “docker exec -it [containerId] bash” 類似,
#但是他們功能不同,attach相當於與宿主機器共享屏幕(共享終端),宿主機器指運行docker的機器,
#而 “docker exec -it” 是分配一個僞終端給到宿主機器,有點類似於ssh遠程連接。 
#在“attach共享終端”中執行exit退出後,容器也會退出,執行 “docker ps -a” 可以看到該容器狀態已經exited。  

說明:
上面命令中的 containerId 可以換成 containerName ,執行效果一樣。
docker ps -a 可以列出 containerId 和 containerName
在容器bash環境中執行 exit 退出容器。







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章