Docker
what is docker ?
- 根據官網描述,docker 是一個容器平臺,是標準化的軟體單元,使用了虛擬化技術(cgroup:提供容器隔離;UnionFS:儲存映象並使容器變得短暫),基於Google推出的go語言實現的開源專案,程式碼在 GitHub 上進行維護。
why use docker ?
-
快速交付和部署
- 輕快:一次建立或配置,可在任意地方正常執行,秒級啟動,節約開發、測試、部署時間。
-
高效虛擬化
- 基於核心的虛擬化,不需要額外hypervisor支援,CPU/記憶體的低消耗,更高效。
-
可移植、可擴充套件
- 物理機、虛擬機器、公有云、私有云、個人電腦、伺服器等平臺均可以執行
-
對比傳統虛擬機器
特性 容器 虛擬機器 啟動 秒級 分鐘級 硬碟使用 一般MB 一般GB 效能 接近原生 弱於原生 系統支援量 單機上千個容器 一般幾十個 -
可以總結出,docker可以實現:
- 隔離應用依賴
- 建立應用映象並進行復制
- 建立易分發的即啟即用的應用
- 允許例項簡單、快速擴充套件
- 測試應用並隨後銷燬
可見docker的 野心 是建立 ===軟體程式可移植的輕量容器===,讓其可以在任何安裝了docker的機器上執行,而不用關心底層作業系統。
how to use docker ?
先了解一下幾個基本概念:
映象:是一個只讀的模版,用來建立docker容器,容器在啟動的時候建立一層可寫層作為最上層
容器:從映象建立的執行例項,可以被啟動、開始、停止、刪除。容器間是相互隔離的,看上去是一個簡易版的Linux環境(包括root使用者許可權、程式空間、使用者空間和網路空間等)和執行在其中的應用程式
倉庫:類似 git,集中存放映象檔案的場所,分為公開倉庫(Public)和私有倉庫(Private),最大的公開倉庫是 Docker Hub
註冊伺服器:類似GitHub 這樣的託管服務,存放著多個倉庫
宿主機:docker所在的伺服器
資料卷:可供一個或多個容器使用的特殊目錄,類似於 Linux 下對目錄或檔案進行 mount,它繞過 UFS,可以提供很多有用的特性:
- 在容器之間共享和重用
- 對資料卷的修改會立馬生效
- 對資料卷的更新,不會影響映象
- 卷會一直存在,直到沒有容器使用
網路模式:用來實現容器的網路通訊,大概包括五種:
- bridge模式,--net=bridge(預設)
- host模式,--net=host
- none模式,--net=none
- 其他容器模式(即container模式),--net=container:NAME_or_ID
- 使用者自定義:docker 1.9版本以後新增的特性
Dockerfile:易於自動化的命令,包含建立映象所需的全部指令,基於dockerfile中的指令,我們可以使用
$ docker build
命令來建立映象,通過減少映象和容器的建立過程來簡化部署。語法命令:
- INSTRUCTION argument 指令不區分大小寫,但命名約定為全部大寫
- FROM
- 格式為
FROM <image>
或FROM <image>:<tag>
- 第一條指令必須為
FROM
指令。並且,如果在同一個Dockerfile中建立多個映象時,可以使用多個FROM
指令(每個映象一次)- MAINTAINER
- 格式為
MAINTAINER <name>
,指定維護者資訊- RUN
- 格式為
RUN <command>
或RUN ["executable", "param1", "param2"]
- 前者將在 shell 終端中執行命令,即
/bin/sh -c
;後者則使用exec
執行。指定使用其它終端可以通過第二種方式實現,例如RUN ["/bin/bash", "-c", "echo hello"]
- 每條
RUN
指令將在當前映象基礎上執行指定命令,並提交為新的映象。當命令較長時可以使用 \ 來換行- CMD
CMD ["executable","param1","param2"]
使用exec
執行,推薦方式CMD command param1 param2
在/bin/sh
中執行,提供給需要互動的應用CMD ["param1","param2"]
提供給ENTRYPOINT
的預設引數- 指定啟動容器時執行的命令,每個 Dockerfile 只能有一條
CMD
命令。如果指定了多條命令,只有最後一條會被執行- 如果使用者啟動容器時候指定了執行的命令,則會覆蓋掉
CMD
指定的命令- EXPOSE
- 格式為
EXPOSE <port> [<port>...]
- 告訴 Docker 服務端容器暴露的埠號,供互聯絡統使用。在啟動容器時需要通過 -P,Docker 主機會自動分配一個埠轉發到指定的埠
- ENV
- 格式為
ENV <key> <value>
。 指定一個環境變數,會被後續RUN
指令使用,並在容器執行時保持。- ADD
- 格式為 ADD
<src> <dest>
- 該命令將複製指定的
<src>
到容器中的<dest>
。 其中<src>
可以是Dockerfile所在目錄的一個相對路徑;也可以是一個 URL;還可以是一個 tar 檔案(自動解壓為目錄)- COPY
- 格式為
COPY <src> <dest>
- 複製本地主機的
<src>
(為 Dockerfile 所在目錄的相對路徑)到容器中的<dest>
。當使用本地目錄為源目錄時,推薦使用COPY
,能用COPY
的情況下不用ADD
- ENTRYPOINT
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
(shell中執行)- 配置容器啟動後執行的命令,並且不可被
docker run
提供的引數覆蓋- 每個 Dockerfile 中只能有一個
ENTRYPOINT
,當指定多個時,只有最後一個起效- VOLUME
- 格式為
VOLUME ["/data"]
- 建立一個可以從本地主機或其他容器掛載的掛載點,一般用來存放資料庫和需要保持的資料等
- USER
- 格式為
USER daemon
- 指定執行容器時的使用者名稱或 UID,後續的
RUN
也會使用指定使用者- 當服務不需要管理員許可權時,可以通過該命令指定執行使用者。並且可以在之前建立所需要的使用者,例如:
RUN groupadd -r postgres && useradd -r -g postgres postgres
。要臨時獲取管理員許可權可以使用gosu
,而不推薦sudo
- WORKDIR
格式為
WORKDIR /path/to/workdir
為後續的 RUN、CMD、ENTRYPOINT 指令配置工作目錄
可以使用多個 WORKDIR 指令,後續命令如果引數是相對路徑,則會基於之前命令指定的路徑。例如:
WORKDIR /a
WORKDIR b
WORKDIR c
則最終路徑為 /a/b/c
- ONBUILD
格式為
ONBUILD [INSTRUCTION]
配置當所建立的映象作為其它新建立映象的基礎映象時,所執行的操作指令
例如,Dockerfile 使用如下的內容建立了映象
image-A
:[...] ONBUILD ADD . /app/src ONBUILD RUN /usr/local/bin/node-build --dir /app/src [...] 複製程式碼
如果基於 image-A 建立新的映象時,新的Dockerfile中使用 FROM image-A指定基礎映象時,會自動執行 ONBUILD 指令內容,等價於在後面新增了兩條指令:
FROM image-A #Automatically run the following ADD . /app/src RUN /usr/local/bin/node-build --dir /app/src 複製程式碼
使用
ONBUILD
指令的映象,推薦在標籤中註明,例如ruby:1.9-onbuild
編寫完成 Dockerfile 之後,可以通過
$ docker build
命令來建立映象
- 基本的格式為
$ docker build [選項] 路徑
,該命令將讀取指定路徑下(包括子目錄)的 Dockerfile,並將該路徑下所有內容傳送給 Docker 服務端,由服務端來建立映象。因此一般建議放置 Dockerfile 的目錄為空目錄。也可以通過.dockerignore
檔案(每一行新增一條匹配模式)來讓 Docker 忽略路徑下的目錄和檔案- 例如:
$ docker build -t ${dockerImageName} --force-rm -f ./Dockerfile .
=========================================================
以上是一些基本概念,現在ubuntu下開始安裝docker並啟動一個nginx容器(其實大多數場景下nginx沒必要跑在容器裡,這裡只是舉個例子)
=========================================================
$ cat /etc/issue
Ubuntu 16.04.6 LTS \n \l
複製程式碼
-
通過shell命令安裝:
$ curl -sSL https://get.docker.com/ | sh
- 更多平臺及安裝方式
-
檢驗安裝,顯示版本資訊,說明已成功安裝:
$ docker -v Docker version 18.09.5, build e8ff056 複製程式碼
ps:
$ docker info
可檢視更多資訊 -
下面開始建立一個容器:
$ docker run❶ \ -d❷ \ --name=demo❸ \ -u root❹ \ -p 8002:80❺ \ -v /var/demo:/var/demo❻ \ nginx:latest❼ 複製程式碼
該命令表示:基於nginx:latest這個映象,建立一個名稱為demo的容器,並把容器內部的80埠與宿主機上的8002埠做對映,使得通過宿主機8002埠的流量轉發到容器內部的80埠上
❶:
run
新建並啟動容器,更多選項,其標準過程:- 檢查本地是否存在指定的映象,不存在就從公有倉庫下載(docker pull xxx)
- 利用映象建立並啟動一個容器
- 分配一個檔案系統,並在只讀的映象層外面掛載一層可讀寫層
- 從宿主主機配置的網橋介面中橋接一個虛擬介面到容器中去
- 從地址池配置一個 ip 地址給容器
- 執行使用者指定的應用程式
- 執行完畢後容器被終止
❷:
-d
Daemonized模式,以守護態形式在後臺執行容器
❸:
--name=demo
為容器起一個名字
❹:
-u
指定容器的使用者
❺:
-p
埠對映,規則是 -p 宿主機埠:容器埠,可多次使用對映多個埠
❻:
-v
掛載資料卷,規則是 -v 宿主機目錄:容器目錄,可多次使用掛載多個資料卷
❼:映象名,該容器所用的映象名,可通過
$ docker images
檢視本地映象 -
檢視正在執行的容器:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c24cfee8226a nginx:latest "nginx -g 'daemon of…" 6 minutes ago Up 6 minutes 0.0.0.0:8002->80/tcp demo 複製程式碼
ps:
$ docker ps -a
檢視所有容器(包括正在執行的、已停止的)現在訪問宿主機的8002埠(安全組開通),即可看到nginx的歡迎頁面:
-
進入容器:
執行
$ docker exec -it demo bash
,demo也可以換成容器的id即:$ docker exec -it c24cfee8226a bash
在容器內可執行
$ netstat -lntp
檢視埠使用情況:Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1/nginx: master pro 複製程式碼
若發現netstat not found,先執行
$ apt update && apt install net-tools
執行
$ exit
退出容器ps:
$ docker inspect demo
可以檢視該容器更多資訊$ docker stop 容器名/id
終止容器$ docker rm 容器名/id
刪除未執行的容器$ docker rmi 映象名/id
刪除未佔用(無容器正在執行)的映象$ docker rmi $(docker images -f "dangling=true" -q)
批量刪除為none
(無容器正在執行)的映象
【參考】:
- www.kancloud.cn/kancloud/do…
- leilux.github.io/lou/docker_…
- docs.docker.com
- blog.csdn.net/ithaibianti…
===?? 文中不足,歡迎指正 ??===