Docker初體驗


斷斷續續的使用Docker好幾年了,但是一直沒有全面深入的去了解過,每次用到都是Google一下相關的命令解決臨時的問題,到頭來卻毫無收獲。好在,我終於意識到了這個問題,便決定從頭開始,耐心的學學Docker,並把學習過程記錄下來,方便以后參考,也望與大家交流學習。

本人比較偏愛Ubuntu,故本文所用命令皆基於Ubuntu 16.04,其他版本的命令會有稍有不同,本文不多做介紹。

目錄

  1. 簡介
  2. 安裝
  3. 常用命令
  4. Dockerfile

簡介

容器:將軟件打包成標准化單元,以用於開發、交付和部署,而 Docker 是世界領先的軟件容器平台。

容器鏡像是輕量的、可執行的獨立軟件包,包含軟件運行所需的所有內容:代碼、運行時環境、系統工具、系統庫和設置。

容器 VS 虛擬機:

容器和虛擬機具有相似的資源隔離和分配優勢,但功能有所不同,因為容器虛擬化的是操作系統,而不是硬件,因此容器更容易移植,效率也更高。

  • 容器是一個應用層抽象,用於將代碼和依賴資源打包在一起。多個容器可以在同一台機器上運行,共享操作系統內核,但各自作為獨立的進程在用戶空間中運行。與虛擬機相比,容器占用的空間較少(容器鏡像大小通常只有幾十兆),瞬間就能完成啟動。

  • 虛擬機 (VM) 是一個物理硬件層抽象,用於將一台服務器變成多台服務器。管理程序允許多個 VM 在一台機器上運行。每個 VM 都包含一整套操作系統、一個或多個應用、必要的二進制文件和庫資源,因此占用大量空間。而且 VM 啟動也十分緩慢。

container-vm

安裝

准備

首先更新Package索引:

sudo apt-get update

添加Https支持:

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common -y

然后添加Docker官方的GPG key:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

## 如果上面的地址不能下載,可以使用國內鏡像
curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg  | sudo apt-key add -

添加Docker-CE穩定版倉儲地址:

sudo add-apt-repository \
   "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

由於Docker官方倉儲download.docker.com的訪問較慢,故使用了中科大鏡像源替代。

安裝

最后,便可以直接安裝了:

sudo apt-get update
sudo apt-get install docker-ce

我們可以運行一下Hello Word來驗證一下是否安裝成功:

sudo docker run hello-world

默認情況下,Docker需要使用root身份來訪問,每次都使用sudo命令較為麻煩,我們可以將當前用戶添加到docker用戶組來實現非root用戶訪問:

sudo usermod -aG docker $USER

重新登錄一下,便可以不使用sudo命令來操作docker了。

鏡像加速

默認情況下,Docker鏡像是從Docker官方市場store.docker.com來拉取的,同樣非常緩慢,好在Docker官方提供了國內鏡像庫,可使用如下命令來配置:

docker --registry-mirror=https://registry.docker-cn.com daemon

為了永久性保留更改,可以修改/etc/docker/daemon.json文件並添加上 registry-mirrors 鍵值:

{
  "registry-mirrors": ["https://registry.docker-cn.com"]
}

修改保存后重啟 Docker 以使配置生效:

sudo systemctl restart docker

安裝Docker Compose

Docker Compose 是一個用來定義和運行復雜應用的Docker工具。我們的應用通常會由多個容器組成,使用Docker Compose可以非常容易的將一組容器當成一個整體來配置部署。

curl -L https://github.com/docker/compose/releases/download/1.23.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

可以在 https://github.com/docker/compose/releases 查看具體的發布列表。

常用命令

運行容器(run)

run是我們最常用的命令:

docker run nginx

如上,便啟動了一個nginx容器。

端口映射(-p)

此時,我們還無法通過訪問宿主機的IP來訪問剛才部署的Nginx,需要先進行端口映射:

docker run -p 8080:80 nginx

后台運行(-d)

默認情況下,當我們推出命令行時,容器也會被關閉。我們可以使用-d參數使容器保持后台運行:

docker run -d <image-name>

然后訪問宿主機的IP:8080,便可以看到“Welcome to nginx!”。

指定名稱(-n)

docker run --name <container-name> <image-name>

docker run --name myredis redis

如上,創建了一個名稱為redis的容器。

持久化數據(-v)

容器被設計為無狀態的,當我們刪除一個容器時,保存在其中的數據也會隨之刪除。如果我們希望某些數據不隨着容器的刪除而刪除,則可以使用目錄綁定(通常稱為卷),將容器中的某個文件夾於主機上的文件夾綁定,來實現數據的持久化。

docker run -v <host-dir>:<container-dir> <image-name>

除此之外,我們還可以使用Data Containers來實行數據的持久化,數據容器(Data Containers)唯一的職責就是存儲和管理數據:

docker create -v /config --name dataContainer busybox

如上,我們使用busybox鏡像創建了一個數據容器,並使用-v參數來指定容器存儲和管理數據的目錄位置。

然后我們可以將文件拷貝到容器中:

docker cp config.conf dataContainer:/config/

接下來,我們就可以在新的容器中引用該數據容器了:

docker run --volumes-from dataContainer ubuntu

新創建的ubuntu容器掛載了數據容器的/config目錄。

重啟策略(--restart)

通過--restart選項,可以設置容器的重啟策略,以決定在容器退出時Docker守護進程是否重啟剛剛退出的容器。

docker run -d --restart=always <image-name>

有如下4種重啟策略:

  • no,默認策略,在容器退出時不重啟容器
  • on-failure,在容器非正常退出時(退出狀態非0),才會重啟容器
    • on-failure:3,在容器非正常退出時重啟容器,最多重啟3次
  • always,在容器退出時總是重啟容器
  • unless-stopped,在容器退出時總是重啟容器,但是不考慮在Docker守護進程啟動時就已經停止了的容器

進入交互模式(-it)

docker run -it [image-name] /bin/bash
  • -i interact 進入交互模式。
  • -t tty 分配一個偽終端。

執行之后,可以看到命令行的主機名已經變成了容器的Id,表示成功進入到了容器中,可以使用exit命令退出容器。

其他

# 啟動一個SQLServer容器
docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=Qwer1234' -p 1433:1433 -d --restart=unless-stopped microsoft/mssql-server-linux

管理容器

查看容器(ps)

docker ps

通過ps命令可以看到當前運行的容器,添加-a參數,則可以看到停止的容器。

我們可以使用docker inspect <friendly-name|container-id>來查看某個容器的詳細信息:

dokcer inspect redis

附加容器(attach)

ttach可以附加到一個已經運行的容器的stdin中。

docker attach [containerid]

進入容器(exec)

docker exec -it [containerid] /bin/bash

是需要注意的是,對於attach,如果從這個stdin中exit,會導致容器的停止。而exec則不會,推薦使用exec

停止容器(stop)

docker stop [containerid]

刪除容器(rm)

docker rm [containerid]

如果要刪除的容器正在運行,則無法刪除,可以添加-f參數來強制刪除,也可以先停止容器再刪除:

如果我們想刪除所有的容器,可以使用如下命令:

docker rm $(docker ps -a -q) -f

鏡像管理

Docker把應用程序及其運行環境等打包在 image 文件里面,相當於容器的模板。

搜索鏡像

我們可以在 registry.hub.docker.com 查找鏡像,也可以使用 dokcer search <name> 命令來搜索,如:我們使用如下命令來搜索redis鏡像。

docker search redis

查看鏡像

# 查看鏡像列表
docker images

# 查看所有鏡像(包括中間層鏡像)
docker image -a

# 查看所有鏡像的ID
docker images -q

# 查看所有的虛懸鏡像(-f 顯示滿足條件的鏡像)
docker images -f "dangling=true"

# 按倉庫名過濾
docker images [REPOSITORY]

# 按倉庫名和標簽過濾
docker images [REPOSITORY:TAG]

鏡像列表輸出如下:

REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest e38bc07ac18e 2 weeks ago 1.85kB

每列含義:

  • REPOSITORY:倉儲名
  • TAG:標簽, 一個鏡像可以有多個標簽
  • IMAGE ID:鏡像的唯一標識,通常在刪除鏡像時使用
  • CREATED:創建時間
  • SIZE:所占用的空間,展開后的各層所占空間的總和。

刪除鏡像

# 刪除鏡像
docker rmi [imageid]

docker image rm [imageid]

# 刪除所有鏡像
docker image rm $(docker images -q) -f

# 刪除虛懸鏡像(dangling image)
docker image prune

倉庫名和標簽均為<none>,這類無標簽、無倉儲名的鏡像被稱為dangling image

拉取推送

# 拉取鏡像
docker pull [imagename]

# 構建鏡像
docker build

# 推送鏡像
docker push [imagename]

其他

# 查看鏡像、容器、卷占用的空間
docker system df

Dockerfile

Dcoker鏡像是從一個基礎鏡像開始的,基礎鏡像包括應用程序所需的平台依賴項, 例如, 安裝了JVMCLR等。

鏡像的定義是使用dockerfile文件來表達的。dockerfile是描述如何部署應用的列表。一個簡單的Dockerfile文件如下:

FROM nginx:alpine
COPY . /usr/share/nginx/html

如上,我們的基礎鏡像是一個alpine版本的nginx,從而擁有了一個安裝了nginx的linux環境。

接下來,我們可以通過定義的dockerfile文件來構建鏡像:

docker build -t webserver-image:v1 .

-t參數為鏡像指定一個友好的名字和標記,.則表示使用當前目錄的dockerfile文件。

OnBuild

通常,dockerfile文件的執行順序是從上到下,但我們可以使用ONBUILD指令來延后執行(在子鏡像構建時執行)。

如下,我們定義一個經典的Node應用程序基礎鏡像:

FROM node:10
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
ONBUILD COPY package.json /usr/src/app/
ONBUILD RUN npm install
ONBUILD COPY . /usr/src/app
CMD [ "npm", "start" ]

當我們構建該鏡像時,ONBUILD指令包含的內容將不會執行,然后我們定義一個該鏡像的子鏡像:

FROM node:10-onbuild
EXPOSE 3000

當我們構建該鏡像時,上面的ONBUILD才會被執行。這樣做的優勢是可以在多個鏡像中共享一份基礎鏡像,大大減少構建的速度。

Ignore File

為了防止將一個不必要或者敏感的數據打包到鏡像中,可以使用.dockerignore文件進行配置。

下面的命令將passwords.txt文件加到了忽略中,確保它不會意外的被打包到鏡像中發布出去。

echo passwords.txt >> .dockerignore

我們可以將.dockerignore文件存儲在源代碼管理中,保持團隊間的一致。

總結

Docker是革命性的,干凈利落的UX俘獲了技術人員的芳心,ASP.NET Core 也是全面擁抱Docker,我們也要緊跟時代的步伐。

本文主要介紹docker的一些基本用法,可作為一個docker使用筆記來參考,並不斷的補充完善,但不會涉及到比較深入的介紹,后續在其他文章中會詳細介紹一些具體的用法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM