最近,Docker技術真是一片火熱,它的出現也彌補了虛擬機資源消耗過高的問題,直接讓虛擬化技術有了質的飛躍。那么本文我們來聊一聊Docker,和大家一起認識Docker,簡單入門Docker.
二、虛擬化技術簡介和發展
1. 階段一:無虛擬化技術
眾所周知,在虛擬化技術出現之前,我們依靠擴展物理機的方式來擴展我們的應用,這個階段很痛苦,也有很多的缺點,比如:
-
Capex費用昂貴
-
Go to Product速度極其慢
-
系統可移植行極低
-
資源利用率極低
2. 階段二:基於Hypervisor的虛擬化技術
這個階段,出現的虛擬化技術讓很多人開心不已,隨着時間的流逝,市面上也出現不少相關的實際應用的技術,如:VMware、KVM、AWS、Microsoft的Hyper-V等。
基於Hypervisor的虛擬化技術的優點:
-
資源利用率高
-
易於擴展、伸縮
-
Go to Product快速
-
成本降低
基於Hypervisor的虛擬化技術的缺點:
-
OS內核資源被重復消耗資源
-
應用移植性較低
3. 階段三:基於容器的虛擬化技術
由於Hypervisor的虛擬化技術不是很完美,對內核的資源重復消耗,那隨着技術的發展就出現了基於容器的虛擬化技術,最熱的就是Docker Container了。它底層使用CGroup和Namespace來實現多個容器之間共享內核資源。而且它還能保證運行時相互隔離,互不影響。
基於容器虛擬化技術的優點:
-
資源利用率更高
-
非常高效
-
更易於擴展、伸縮
-
Go to Product更快速
-
一致性
-
可封裝性
-
應用隔離性
運行時隔離,最典型的應用就是使得我們可以很方便和簡單的實現在同一台機器上運行基於不同版本Java開發的應用。如下圖:
基於Hypervisor的虛擬化技術 VS 基於容器的虛擬化技術
-
容器提供OS層的虛擬化(OS Virtualization)
-
容器可以避免Machine Virtualiztion啟動的開銷
-
容器主要給應用提供虛擬化的運行環境
-
容器只提供給應用所需的可執行文件和依賴庫
-
虛擬機主要給操作系統提供運行環境
三、Docker架構
-
Docker daemon
-
處理Docker API 請求
-
管理Docker對象:如鏡像、容器、網絡等。
-
-
Docker client
-
Docker client使用Docker API 跟 Docker daemon進行通信交互
-
可以跟多個不同的Docker Daemon進行通信
-
-
Docker Registries
-
存儲Docker鏡像
-
公有和私有Docker Registry
-
-
Docker對象
-
鏡像
-
容器
-
四、Docker術語
-
鏡像
-
鏡像是用來創建容器的只讀模板
-
鏡像是通過Docker build命令創建的
-
鏡像由鏡像層構成
-
鏡像存儲於Docker Registry
-
-
容器
-
容器是鏡像的運行實例
-
容器是應用運行環境的封裝,具有輕量級、移植性高等特點
-
容器由鏡像創建,內部封裝所有運行應用所需依賴及可執行文件
-
-
Registries和Repositories
-
Registry是存儲Docker鏡像的地方(可類比為Maven倉庫)
-
可自建私有Registry和使用公用Registry,如:Docker Hub
-
在Registry中,鏡像存儲在Repository
-
Docker Repository是具有相同名字,不同標簽的Docker鏡像的集合(可類比為Maven倉庫中的某個依賴所在的文件夾,可以有不同版本)
-
-
Docker Hub
-
公有:Docker Registry
-
私有:Docker Registry
-
-
官方Docker鏡像
-
文檔清晰、完整
-
安全,更新及時
-
安全性更高
-
五、Docker的安裝
-
環境准備
-
Centos 7
-
-
Docker社區版安裝步驟
-
刪除已安裝所有老版本docker相關(docker或者docker-engine)
yum remove -y docker docker-common docker-selinux docker-engine
-
安裝devicemapper驅動和yum工具
yum install -y yum-utils device-mapper-persistent-data lvm2
-
配置repo
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
-
安裝docker社區版
yum install -y docker-ce
-
啟動docker
systemctl start docker
-
注:如果在沒有啟動docker的情況下運行[docker info]命令,則會出現:Cannot connect to the Docker daemon. Is the docker daemon running on this host? 錯誤。
-
Centos官方版安裝步驟
yum install -y docker
-
驗證安裝
docker version
docker info
六、Docker常用命令
-
docker version 查看docker版本信息
-
docker info 查看docker基本信息
-
docker images 查看所有本地鏡像
-
docker ps [-a] 查看所有正在運行的容器
-
-a查看所有的容器
-
-
docker search repository:tag 在遠程倉庫搜索指定鏡像
-
docker pull repository:tag 從遠程倉庫下載指定鏡像
-
docker run [-t -i -d --name containerName -p port] repository:tag cmd命令 基於一個鏡像運行一個容器
-
-t 綁定終端
-
-i 交互模式
-
-d 后台運行
-
--name 指定容器的名稱
-
-p 指定容器暴露的端口,如:8080:8080
-
-P 和-p互斥,當使用 -P 標記時,Docker 會隨機映射一個
49000~49900
的端口到內部容器開放的網絡端口
-
-
docker start containerId 啟動一個已經停止的容器
-
docker stop containerId 停掉一個正在運行的容器
-
docker rm [-f] containerId/containerName 刪除指定容器
-
-f 強制刪除,不論容器是否正在運行
-
-
docker rmi imageId/imageName 刪除指定鏡像
-
docker commit [-a author] containerId repository:tag
-
-a author 指定作者
-
-
docker logs [-f] containerId 查看容器日志
-
docker history imageId/repository:tag 查看鏡像的各層信息
-
docker inspect containerId/containerName 查看容器更底層的信息
-
docker save -o fileName imageId/repository:tag 將指定的鏡像打包保存
-
docker import fileName repository:tag 使用指定文件創建鏡像
-
docker exec [-t -i] containerId/containerName CMD 利用指定容器執行指定的cmd命令
-
docker build -t repository:tag . [--no-cache=true] 使用當前目錄下的Dockerfile文件構建鏡像
-
“.” 代表使用當前目錄下Dockerfile
-
--no-cache=true 不使用緩存,默認是緩存
-
-
docker login 登陸到遠程倉庫
-
docker push repository[:tag] 提交鏡像到遠程倉庫
- docker rm -f $(docker ps -qa -f status=exited) 刪除所有已經停掉的容器
前台運行 VS 后台運行
-
前台運行Docker容器
-
默認方式
-
docker run 運行容器中的應用並將console和應用進程中的標准輸入、輸出及錯誤關聯起來
-
容器啟動后不能在console中執行其他命令
-
-
后台運行Docker容器
-
需要指定 -d 選項
-
docker run 將容器在后台啟動,通常容器中的主程序退出后容器隨之退出
-
容器啟動后可以在console中繼續執行其他命令
-
七、Docker端口映射和日志
最典型的案例是:當我們運行tomcat鏡像的時候,我們需要為該容器指定向外暴露的端口以及查看容器運行時tomcat的日志信息。
-
端口暴露
-
運行時指定 -p或者-P選項,-p允許我們指定端口信息,-P是docker默認隨機映射一個
49000~49900
的端口到內部容器開放的網絡端口
-
-
查看日志
-
docker logs containerId 查看容器輸出的日志信息
-
也可以后台運行容器,然后使用docker exec -ti containerId bash 命令進到logs目錄下查看catlina.log日志信息
-
八、Docker 鏡像
-
Docker鏡像是容器的基礎
-
Docker鏡像是由有序文件系統層以及容器運行時所需參數組成
-
Docker鏡像是無狀態的
-
Docker鏡像是不可更改的
-
運行中的容器,所有的變化被寫入可寫層
-
一旦容器被刪除,可寫入層隨之刪除,但base鏡像依舊存在
-
多個容器共享相同的base鏡像層
九、創建Docker鏡像
-
通過docker commit命令來基於容器創建Docker鏡像
-
通過docker build 命令配合Dockerfile文件創建Docker鏡像
下面是一個簡單的Dockerfile文件
FROM centos:7 LABEL maintainer "hafiz.zhang(hafiz.zhang@example.com)" RUN yum update -y RUN yum install -y git
-
Dockerfile是一個包含用戶創建Docker鏡像的所有命令的文本文件
-
Dockerfile中的命令指定在創建Docker鏡像時做什么操作
-
Docker讀取Dockerfile中的命令來創建Docker鏡像
-
Dockerfile中的每個命令都將被Docker使用來創建一個新的Docker鏡像層
Docker build 上下文
-
Docker客戶端以當前目錄為build上下文
-
默認讀取當前目錄的Dockerfile進行build
-
Docker客戶端開始build后會將build上下文目錄的文件打包成tar包並上傳給Docker Daemon守護進程
十、深入Dockerfile
-
RUN指令
-
RUN指令在容器的可寫入層執行命令,並commit容器為新的鏡像
-
上一步RUN命令生成的鏡像會被接下來的RUN指令使用,每次RUN指令生成一個新的鏡像
-
Dockerfile中最好使用鏈式輸入命令以減少創建鏡像層的數量
-
-
CMD指令
-
CMD指令指定容器啟動時執行什么命令
-
如果在Dockerfile中不指定CMD指令,Docker將使用基礎鏡像提供的默認命令
-
CMD指令在創建Docker鏡像時不執行,只有在容器啟動時才執行
-
既可以以exec形式也可以以shell形式指定要執行的命令
-
CMD 指令指定命令使用JSON格式,只能使用雙引號,不能使用單引號
-
CMD ["echo", "HelloWorld"] 使用exec形式,不能獲取到$HOME等環境變量信息
-
CMD ["sh", "-c", "echo $HOME"] 使用shell腳本形式,能獲取到HOME等環境變量信息
-
-
build鏡像的時候不會運行CMD指令指定的命令,只要在使用鏡像啟動容器時才運行CMD指令指定的命令
-
-
COPY指令
-
COPY指令從build上下文復制文件或者文件夾到容器文件系統
-
-
ADD指令
-
ADD指令不但可以復制文件到容器文件系統,而且還可以從internet上下載文件並復制到容器
-
ADD指令可以自動解壓壓縮文件
-
通常我們使用COPY指令,除非明確需要ADD指令
-
-
Docker緩存
-
每次Docker執行一個指令將創建新的鏡像
-
如果下一次指令沒有發生變化,Docker默認使用現有的緩存
-
可以通過指定 --no-cache=true 來指定不使用緩存
-
也可以使用鏈式命令來避免使用緩存
-
十一、上傳Docker鏡像到Docker Hub
-
首先注冊Docker Hub賬號
-
docker tag 給鏡像打標簽
-
Repository格式:ID/鏡像名字
-
Latest標簽
-
默認Docker使用latest作為標簽
-
通常Repository用latest表示竟像是最新穩定版,但這只是默認傳統,不是強制要求
-
當新版本鏡像上傳到Repository,latest標簽的鏡像不會自動更新
-
盡量避免使用latest標簽
十二、總結
通過本文,我們就對Docker有了一個直觀的理解,也明白了如何從遠程倉庫拉取鏡像,運行鏡像,如何進行端口映射等等Docker基礎知識。感覺很充實~