一、入門三板斧
- What-Docker是什么
Docker 是世界領先的軟體容器平臺,所以想要搞懂 Docker 的概念我們必須先從容器開始說起,
容器是一種輕量級的、可執行的獨立軟體包,包含軟體運行所需的所有內容:代碼、運行時環境、系統工具、系統庫和設定,
容器虛擬化的是作業系統而不是硬體,是內核級的虛擬化,容器之間是共享同一套作業系統資源的,虛擬機技術是虛擬出一套硬體后,在其上運行一個完整作業系統,因此容器的隔離級別會稍低一些,
- Why-為什么需要用Docker、容器
Docker 的鏡像提供了除內核外的完整運行時環境,確保了應用運行環境一致性,避免再出現 “代碼在這臺機器上正常運行, 換臺機器卻不能啟動; 應用在測驗環境沒問題, 在生產環境報錯” 這類問題 ——一致的運行環境
可以做到秒級、甚至毫秒級的啟動時間, 大大的節約了開發、測驗、部署的時間,——更快速的啟動時間
避免公用的服務器,避免資源容易受到其他用戶的影響,——隔離性
善于處理集中爆發的服務器使用壓力, 十分適合微服務;——彈性伸縮,快速擴展
docker兼容很多平臺, 可以很輕易的將在一個平臺上運行的應用,遷移到另一個平臺上,而不用擔心運行環境的變化導致應用無法正常運行的情況,——遷移方便
使用 Docker 可以通過定制應用鏡像來實作持續集成、持續交付、部署,——持續交付和部署
- How-如何使用Docker
需要先安裝docker,然后接下來介紹docker的組件和常用命令,以及如何使用dockerfile構建自定義的鏡像
二、Docker 架構
Docker 客戶端-Client
Docker 服務端-Docker daemon
Docker 鏡像-Image
Docker 容器-Container
Register -倉庫
Docker采用的是CS架構,客戶端使用docker command 命令列 與服務器行程 Docker daemon 通信,
Docker 內部組件 :鏡像、容器、倉庫
鏡像(image):
Docker 鏡像可以看作是創建容器的模板,
鏡像的作業原理–分層存盤
因為鏡像包含作業系統完整的 根檔案系統root fs,其體積往往是龐大的,因此在 Docker 設計時,就充分利用 聯合檔案系統 Union FS的技術,將其設計為分層存盤的架構,所以嚴格來說,鏡像并非是像一個 ISO 那樣的打包檔案,鏡像只是一個虛擬的概念,其實際體現并非由一個檔案組成,而是由一組檔案系統組成,或者說,由多層檔案系統聯合組成,
鏡像構建時,會一層層構建,前一層是后一層的基礎,每一層構建完就不會再發生改變,后一層上的任何改變只發生在自己這一層,比如,洗掉前一層檔案的操作,實際不是真的洗掉前一層的檔案,而是僅在當前層標記為該檔案已洗掉,在最終容器運行的時候,雖然不會看到這個檔案,但是實際上該檔案會一直跟隨鏡像,因此,在構建鏡像的時候,需要額外小心,每一層盡量只包含該層需要添加的東西,任何額外的東西應該在該層構建結束前清理掉,
分層存盤的特征還使得鏡像的復用、定制變的更為容易,甚至可以用之前構建好的鏡像作為基礎層,然后進一步添加新的層,以定制自己所需的內容,構建新的鏡像,
容器(Container):
鏡像和容器的關系,就像是面向物件程式設計中的 類 和 實體 一樣,鏡像是靜態的定義,容器是鏡像運行的物體,容器可以被創建、啟動、停止、洗掉等,
容器的實質是行程,但與直接在宿主執行的行程不同,容器行程運行于屬于自己的獨立的 命名空間,前面講過鏡像使用的是分層存盤,容器也是如此,
容器存盤層的生存周期和容器一樣,容器被洗掉時,容器存盤層也隨之消亡,因此,任何保存于容器存盤層的資訊都會隨容器洗掉而丟失,如:容器內生成的各種日志檔案, 當容器被洗掉時也會被洗掉. 正如一個物件被回收了,那他的所有成員變數占用的空間也就被釋放了.
按照 Docker 最佳實踐的要求,容器不應該向其存盤層內寫入任何資料 ,容器存盤層要保持無狀態化,**所有的檔案寫入操作,都應該使用資料卷(Volume) **,在這些位置的讀寫會跳過容器存盤層,直接對宿主機(或網路存盤)發生讀寫,其性能和穩定性更高,資料卷的生存周期獨立于容器,容器被洗掉,資料卷也不會消失
倉庫(Registry):
倉庫是存放鏡像的倉庫,分為公有和私有兩種;
最常使用的 Registry 公開服務是Docker官方的中心倉庫 Docker Hub,這也是默認的 Registry,并擁有大量的官方維護的鏡像;一般企業用戶或者個人用戶都會選擇搭建屬于自己的私有倉庫,比如Harbor、Nexus,
Docker生態 – 三劍客
三劍客: docker, docker-compose, docker swarm
docker: 開源專案(go), 開源版本免費, 另有商業版本(有制裁風險)
docker-compose: Docker官方開源專案(Pyhon3), 用于編排一組容器, 使用docker-compose.yml組態檔, 可以同時啟動一個專案需要使用的各種容器, 如mysql, redis, nginx, jar應用. 可以像腳本一樣在新服務器上快速簡單地部署專案
docker swarm: Docker公司官方推出的管理docker集群的平臺,現在大部分市場份額都被google的k8s占去
三、Docker實踐
服務端命令
安裝docker: yum install docker
啟動docker 服務端: service docker start
停止docker 服務端: service docker stop
查看docker 服務端的狀態: service docker status
小試牛刀–hello-world
啟動docker服務端之后, 執行 docker run hello-world, 可以看到歡迎詞, 顯示如下
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
客戶端命令
使用docker command -h 查看docker 客戶端所有的命令用法
1.在倉庫中搜索鏡像: docker search
Usage: docker search [OPTIONS] TERM
Search the Docker Hub for images
Options:
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print search using a Go template
--limit int Max number of search results (default 25)
--no-trunc Don't truncate output
docker search nginx 搜索倉庫中 nginx相關的鏡像
2.從倉庫中下載鏡像: docker pull
Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST]
Pull an image or a repository from a registry
Options:
-a, --all-tags Download all tagged images in the repository
--disable-content-trust Skip image verification (default true)
使用 docker pull[IMAGE_NAME]:[TAG]命令來下載鏡像,其中 IMAGE_NAME 表示的是鏡像的名稱,而 TAG 是鏡像的標簽,也就是說我們需要通過 “鏡像 + 標簽” 的方式來下載鏡像,
注意:
1.Docker 會嘗試先從默認的鏡像倉庫(默認使用 Docker Hub 公共倉庫)去下載,用戶也可以自定義配置鏡像倉庫,
2.您也可以不顯式地指定 TAG, 標簽默認為 latest ,也就是最新版本,它是不穩定的, 在生產環境中,應顯示指定具體的 TAG,
3.如果下載慢可使用國內鏡像加速
docker pull centos:7
3.顯示本機已下載的所有鏡像: docker images
Usage: docker images [OPTIONS] [REPOSITORY[:TAG]]
List images
Options:
-a, --all Show all images (default hides intermediate images)
--digests Show digests
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print images using a Go template
--no-trunc Don't truncate output
-q, --quiet Only show numeric IDs
#使用 docker images命令
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7.27 383867b75fd2 10 months ago 373MB
redis 3.0.7-alpine 856249f48b0c 3 years ago 12.6MB
nginx alpine a624d888d69f 7 months ago 21.5MB
串列包含了 倉庫名、標簽、鏡像 ID、創建時間 以及 所占用的空間,
其中倉庫名、標簽在之前的基礎概念章節已經介紹過了,鏡像 ID 則是鏡像的唯一標識,一個鏡像可以對應多個 標簽,
注意:圖中的鏡像大小資訊只是邏輯上的大小資訊,因為一個鏡像是由多個鏡像層(
layer)組成的,而相同的鏡像層本地只會存盤一份,所以 Docker 在下載之前,會去檢測本地是否會有同樣 ID 的層,如果本地已經存在了,就直接使用本地的就好了,真實情況下,占用的物理存盤空間大小,可能會小于邏輯大小,
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
可以使用docker tag 命令,為本地鏡像添加一個新的標簽,相當于創建一個軟連接/快捷方式,鏡像 ID 是一樣的,只是別名不同而已,
4.洗掉已下載的鏡像: docker rmi
Usage: docker rmi [OPTIONS] IMAGE [IMAGE...]
Remove one or more images
Options:
-f, --force Force removal of the image
--no-prune Do not delete untagged parents
可以通過鏡像名(repository:tag)或者鏡像ID洗掉,
鏡像名洗掉:如果鏡像存在多個標簽,那么洗掉就是洗掉一個標簽而已;
鏡像ID洗掉:它會先嘗試洗掉所有指向該鏡像的標簽,然后在洗掉鏡像本身,
當通過該鏡像創建的容器未被全部銷毀時,鏡像無法直接被洗掉的,通過添加 -f 引數,可以強制洗掉鏡像
5.啟動容器: docker run
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Run a command in a new container
Options: 這里列了一些常用的引數
-d, --detach Run container in background and print container ID 后臺運行容器,并回傳容器ID(唯一)
-e, --env list Set environment variables 注入環境變數
-i, --interactive Keep STDIN open even if not attached 前臺互動式運行
-l, --label list Set meta data on a container 對容器設定標簽
--name string Assign a name to the container 設定容器名(唯一)
--network string Connect a container to a network (default "default")
--read-only Mount the container's root filesystem as read only
--rm Automatically remove the container when it exits
-p, --publish list Publish a container's port(s) to the host 宿主機埠與容器埠的映射
-t, --tty Allocate a pseudo-TTY 偽終端,一般和-i搭配
-v, --volume list Bind mount a volume 資料卷系結(掛載),容器的資料可持久化
--volumes-from list Mount volumes from the specified container(s)
-w, --workdir string Working directory inside the container
#利用 docker run 來創建容器, 將容器內的80埠映射到宿主機的18000埠
docker run -d --name=nginx -p 18000:80 nginx:alpine
6e5b52fae13a6669da0f87d96aef38ec02661df05e5a646eeeb00417b47ad2d5
啟動容器時,如果本地沒有所用的鏡像則會自動下載, 一般而言執行完docker run命令后回傳生成容器的ID
6.查看正在運行的容器: docker ps
展示結果的第一列是容器的ID(唯一), 最后一列NAMES是容器的名字(唯一)
Usage: docker ps [OPTIONS]
List containers
Options:
-a, --all Show all containers (default shows just running)
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print containers using a Go template
-n, --last int Show n last created containers (includes all states) (default -1)
-l, --latest Show the latest created container (includes all states)
--no-trunc Don't truncate output
-q, --quiet Only display numeric IDs
-s, --size Display total file sizes
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6e5b52fae13a nginx:alpine "nginx -g 'daemon of…" About a minute ago Up About a minute 0.0.0.0:18000->80/tcp nginx
可以看到nginx容器正在運行,監聽宿主機的18000埠
我們可以通過訪問 宿主機IP:18000 就可以訪問到容器的nginx
curl http://10.93.181.200:18000/index.html
<!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>
查看所有的容器命令: docker ps -a
容器啟動失敗,就會自動停止,此時就需要使用上面的命令找到已停止的容器
7.查看容器日志: docker logs
Usage: docker logs [OPTIONS] CONTAINER
Fetch the logs of a container
Options:
--details Show extra details provided to logs
-f, --follow Follow log output 實時跟蹤顯示,類似tail -f
--tail string Number of lines to show from the end of the logs (default "all")
-t, --timestamps Show timestamps
--until string Show logs before a timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
# 實時查看nginx 容器的日志
docker logs -f 6e5b52fae13a
8.容器啟停: docker start/stop containerID
9.進入容器: docker attach 和docker exec
docker attach containerID 可以進入當前容器運行的終端,如果從這個終端中 exit,會導致容器的停止,
所以一般都是用exec的方式
Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
Run a command in a running container
Options:
-d, --detach Detached mode: run command in the background
--detach-keys string Override the key sequence for detaching a container
-e, --env list Set environment variables
-i, --interactive Keep STDIN open even if not attached
--privileged Give extended privileges to the command
-t, --tty Allocate a pseudo-TTY
-u, --user string Username or UID (format: <name|uid>[:<group|gid>])
-w, --workdir string Working directory inside the container
# 啟動一個 sh 終端進入容器(只能進入正在運行的容器)
docker exec -it 6e5b52fae13a bash
如果使用以上命令進入容器報錯:
OCI runtime exec failed: exec failed: container_linux.go:344: starting container process caused "exec: \"bash\": executable file not found in $PATH": unknown
還可以使用:docker exec -it 6e5b52fae13a /bin/sh
- 在容器和宿主機之間復制檔案/檔案夾:
docker cp
Usage: docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
Copy files/folders between a container and the local filesystem
Options:
-a, --archive Archive mode (copy all uid/gid information)
-L, --follow-link Always follow symbol link in SRC_PATH
# 1.將宿主機的檔案拷貝進容器內
# 在宿主機創建foo.txt檔案并拷貝到容器內
echo "bar" > foo.txt
docker cp foo.txt nginx:/tmp
# 然后再容器內查看tmp目錄
ls -ltr /tmp/
total 4
-rw-r--r-- 1 root root 4 Jul 8 11:02 foo.txt
# 2.將容器內的檔案拷貝到宿主機外
# 先在容器內創建檔案
echo "a" > b.txt
# 然后再在宿主機執行命令把容器拷貝出來
docker cp nginx:/tmp/b.txt ./
ls b.txt #檔案存在
- 查看鏡像/容器的詳細資訊:
docker inspect
Usage: docker inspect [OPTIONS] NAME|ID [NAME|ID...]
Return low-level information on Docker objects
Options:
-f, --format string Format the output using the given Go template
-s, --size Display total file sizes if the type is container
--type string Return JSON for specified type
# 使用 docker inspect命令查看鏡像詳細資訊
docker inspect nginx:alpine
# 使用 docker inspect命令查看容器詳細資訊
docker inspect CONTAINER_ID
12.鏡像與tar檔案的轉換, 鏡像匯入docker load、匯出docker save
Usage: docker save [OPTIONS] IMAGE [IMAGE...]
Save one or more images to a tar archive (streamed to STDOUT by default)
Options:
-o, --output string Write to a file, instead of STDOUT
# 匯出nginx鏡像到當前目錄的 nginx-image.tar
docker save -o nginx-image.tar nginx:alpine
---------------------------------------------------------------------------
Usage: docker load [OPTIONS]
Load an image from a tar archive or STDIN
Options:
-i, --input string Read from tar archive file, instead of STDIN
-q, --quiet Suppress the load output
# 匯入鏡像
docker load -i nginx-image.tar
四、使用DockerFile定制鏡像
Dockerfile 是一個用來構建鏡像的文本檔案,文本內容包含了構建鏡像所需的指令和說明
常用指令
FROM
指定base鏡像,基于基礎鏡像進行構建
COPY
將檔案從build context 復制到鏡像
ADD
與COPY型別,從build context復制檔案到鏡像,不同的是如果是標準壓縮檔案(tar,zip,tgz,xz),那么檔案會被自動解壓,
ENV
設定環境變數,在Dockerfile中使用,在構建程序中有效,在image被創建和container啟動后作為環境變數依舊也有效,并且可以重寫覆寫,
ARG
在Dockerfile中使用,僅在build docker image的程序中(包括CMD和ENTRYPOINT)可用,在image被創建和container啟動之后不可用,
RUN
在容器執行執行命令,每一個 RUN 都是啟動一個容器、執行命令、然后提交存盤層檔案變更
WORKDIR
為RUN,CMD,ENTRYPONT,ADD或COPY 指令設定鏡像中的當前作業目錄
EXPOSE
指定容器容器中的行程會監聽某個埠,Docker可以將該埠暴露出來
VOLUME
將檔案或者目錄宣告為volume
CMD
容器啟動時運行指定的命令,Dockerfile中可以有多個CMD指令,但是只有最后一個生效;CMD 可以被docker run 后面的引數替換
ENTRYPONT
設定容器啟動時運行的命令,Dockerfile中可以有多個ENTRYPONT指令,但是只有最后一個生效;ENTRYPONT可以被docker run 后面的引數會傳遞給ENTRYPONT 作為引數執行(可以自行了解),
dockerfile實戰-構建簡單SpringBoot應用鏡像
FROM openjdk:8-jdk-alpine
# 配置同級目錄下jar包名字
ENV JAR_NAME=awesomejava-0.1.jar
# 作業目錄/opt,jar包會被復制為/opt/app.jar
WORKDIR /opt
COPY $JAR_NAME app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/opt/app.jar"]
使用docker build命令構建鏡像
docker build --force-rm=true --no-cache=true -t awesome-java:0.1 -f Dockerfile ./
–force-rm=true 洗掉RUN指令的創建中間容器
-t awesome-java:0.1 指定本次構建的鏡像名為 awesome-java:0.1
-f Dockerfile 指定dockerfile檔案
./ build context 為當前目錄,執行構建命令時,docker client 會將當前目錄的所有檔案發
送到服務端 daemon 的臨時目錄,然后按照dockerfile指令一層一層構建
鏡像匯出:
docker save awesome-java:0.1 | gzip > awesome-java:0.1.tar.gz
cook
- docker鏡像名字不能包含大寫字母
學習指南:
Docker教程|菜鳥教程
Docker — 從入門到實踐
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/239641.html
標籤:其他
