Docker
1 Docker簡介
1.1 什麼是虛拟化
在計算機中,虛拟化(英語:Virtualization)是一種資源管理技術,是将計算機的各種實體資源,如伺服器、網絡、記憶體及存儲等,予以抽象、轉換後呈現出來,打破實體結構間的不可切割的障礙,使使用者可以比原本的組态更好的方式來應用這些資源。這些資源的新虛拟部份是不受現有資源的架設方式,地域或實體組态所限制。一般所指的虛拟化資源包括計算能力和資料存儲。
在實際的生産環境中,虛拟化技術主要用來解決高性能的實體硬體産能過剩和老的舊的硬體産能過低的重組重用,透明化底層實體硬體,進而最大化的利用實體硬體 對資源充分利用
虛拟化技術種類很多,例如:軟體虛拟化、硬體虛拟化、記憶體虛拟化、網絡虛拟化(vip)、桌面虛拟化、服務虛拟化、虛拟機等等。
1.2 什麼是Docker
Docker 是一個開源項目,誕生于 2013 年初,最初是 dotCloud 公司内部的一個業餘項目。它基于 Google 公司推出的 Go 語言實作。 項目後來加入了 Linux 基金會,遵從了 Apache 2.0 協定,項目代碼在 GitHub 上進行維護。

Docker 自開源後受到廣泛的關注和讨論,以至于 dotCloud 公司後來都改名為 Docker Inc。Redhat 已經在其 RHEL6.5 中集中支援 Docker;Google 也在其 PaaS 産品中廣泛應用。
Docker 項目的目标是實作輕量級的作業系統虛拟化解決方案。 Docker 的基礎是 Linux 容器(LXC)等技術。
在 LXC 的基礎上 Docker 進行了進一步的封裝,讓使用者不需要去關心容器的管理,使得操作更為簡便。使用者操作 Docker 的容器就像操作一個快速輕量級的虛拟機一樣簡單。
為什麼選擇Docker?
(1)上手快。
使用者隻需要幾分鐘,就可以把自己的程式“Docker化”。Docker依賴于“寫時複制”(copy-on-write)模型,使修改應用程式也非常迅速,可以說達到“随心所緻,代碼即改”的境界。
随後,就可以建立容器來運作應用程式了。大多數Docker容器隻需要不到1秒中即可啟動。由于去除了管理程式的開銷,Docker容器擁有很高的性能,同時同一台主控端中也可以運作更多的容器,使使用者盡可能的充分利用系統資源。
(2)職責的邏輯分類
使用Docker,開發人員隻需要關心容器中運作的應用程式,而運維人員隻需要關心如何管理容器。Docker設計的目的就是要加強開發人員寫代碼的開發環境與應用程式要部署的生産環境一緻性。進而降低那種“開發時一切正常,肯定是運維的問題(測試環境都是正常的,上線後出了問題就歸結為肯定是運維的問題)”
(3)快速高效的開發生命周期
Docker的目标之一就是縮短代碼從開發、測試到部署、上線運作的周期,讓你的應用程式具備可移植性,易于建構,并易于協作。(通俗一點說,Docker就像一個盒子,裡面可以裝很多物件,如果需要這些物件的可以直接将該大盒子拿走,而不需要從該盒子中一件件的取。)
(4)鼓勵使用面向服務的架構
Docker還鼓勵面向服務的體系結構和微服務架構。Docker推薦單個容器隻運作一個應用程式或程序,這樣就形成了一個分布式的應用程式模型,在這種模型下,應用程式或者服務都可以表示為一系列内部互聯的容器,進而使分布式部署應用程式,擴充或調試應用程式都變得非常簡單,同時也提高了程式的内省性。(當然,可以在一個容器中運作多個應用程式)
1.3 容器與虛拟機比較
下面的圖檔比較了 Docker 和傳統虛拟化方式的不同之處,可見容器是在作業系統層面上實作虛拟化,直接複用本地主機的作業系統,而傳統方式則是在硬體層面實作。
與傳統的虛拟機相比,Docker優勢展現為啟動速度快、占用體積小。
1.4 Docker 元件
1.4.1 Docker伺服器與用戶端
Docker是一個用戶端-伺服器(C/S)架構程式。Docker用戶端隻需要向Docker伺服器或者守護程序送出請求,伺服器或者守護程序将完成所有工作并傳回結果。Docker提供了一個指令行工具Docker以及一整套RESTful API。你可以在同一台主控端上運作Docker守護程序和用戶端,也可以從本地的Docker用戶端連接配接到運作在另一台主控端上的遠端Docker守護程序。
1.4.2 Docker鏡像與容器
鏡像是建構Docker的基石。使用者基于鏡像來運作自己的容器。鏡像也是Docker生命周期中的“建構”部分。鏡像是基于聯合檔案系統的一種層式結構,由一系列指令一步一步建構出來。例如:
添加一個檔案;
執行一個指令;
打開一個視窗。
也可以将鏡像當作容器的“源代碼”。鏡像體積很小,非常“便攜”,易于分享、存儲和更新。
Docker可以幫助你建構和部署容器,你隻需要把自己的應用程式或者服務打包放進容器即可。容器是基于鏡像啟動起來的,容器中可以運作一個或多個程序。我們可以認為,鏡像是Docker生命周期中的建構或者打包階段,而容器則是啟動或者執行階段。 容器基于鏡像啟動,一旦容器啟動完成後,我們就可以登入到容器中安裝自己需要的軟體或者服務。
是以Docker容器就是:
一個鏡像格式;
一些列标準操作;
一個執行環境。
Docker借鑒了标準集裝箱的概念。标準集裝箱将貨物運往世界各地,Docker将這個模型運用到自己的設計中,唯一不同的是:集裝箱運輸貨物,而Docker運輸軟體。
和集裝箱一樣,Docker在執行上述操作時,并不關心容器中到底裝了什麼,它不管是web伺服器,還是資料庫,或者是應用程式伺服器什麼的。所有的容器都按照相同的方式将内容“裝載”進去。
Docker也不關心你要把容器運到何方:我們可以在自己的筆記本中建構容器,上傳到Registry,然後下載下傳到一個實體的或者虛拟的伺服器來測試,在把容器部署到具體的主機中。像标準集裝箱一樣,Docker容器友善替換,可以疊加,易于分發,并且盡量通用。
1.4.3 Registry(注冊中心)
Docker用Registry來儲存使用者建構的鏡像。Registry分為公共和私有兩種。Docker公司營運公共的Registry叫做Docker Hub。使用者可以在Docker Hub新增賬號,分享并儲存自己的鏡像(說明:在Docker Hub下載下傳鏡像巨慢,可以自己建構私有的Registry)。
https://hub.docker.com/
2 Docker安裝與啟動
2.1 安裝Docker
Docker官方建議在Ubuntu中安裝,因為Docker是基于Ubuntu釋出的,而且一般Docker出現的問題Ubuntu是最先更新或者打更新檔的。在很多版本的CentOS中是不支援更新最新的一些更新檔包的。
由于我們學習的環境都使用的是CentOS,是以這裡我們将Docker安裝到CentOS上。注意:這裡建議安裝在CentOS7.x以上的版本,在CentOS6.x的版本中,安裝前需要安裝其他很多的環境而且Docker很多更新檔不支援更新。
請直接挂載課程配套的Centos7.x鏡像
(1)yum 包更新到最新
sudo yum update
(2)安裝需要的軟體包, yum-util 提供yum-config-manager功能,另外兩個是devicemapper驅動依賴的
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
(3)設定yum源為阿裡雲
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
(4)安裝docker
sudo yum install docker-ce
(5)安裝後檢視docker版本
docker -v
2.2 設定ustc的鏡像
ustc是老牌的linux鏡像服務提供者了,還在遙遠的ubuntu 5.04版本的時候就在用。ustc的docker鏡像加速器速度很快。ustc docker mirror的優勢之一就是不需要注冊,是真正的公共服務。
https://lug.ustc.edu.cn/wiki/mirrors/help/docker
編輯該檔案:
vi /etc/docker/daemon.json
在該檔案中輸入如下内容:
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}
2.3 Docker的啟動與停止
systemctl指令是系統服務管理器指令
啟動docker:
systemctl start docker
停止docker:
systemctl stop docker
重新開機docker:
systemctl restart docker
檢視docker狀态:
systemctl status docker
開機啟動:
systemctl enable docker
檢視docker概要資訊
docker info
檢視docker幫助文檔
docker --help
3 常用指令
3.1 鏡像相關指令
3.1.1 檢視鏡像
docker images
REPOSITORY:鏡像名稱
TAG:鏡像标簽
IMAGE ID:鏡像ID
CREATED:鏡像的建立日期(不是擷取該鏡像的日期)
SIZE:鏡像大小
這些鏡像都是存儲在Docker主控端的/var/lib/docker目錄下
3.1.2 搜尋鏡像
如果你需要從網絡中查找需要的鏡像,可以通過以下指令搜尋
docker search 鏡像名稱
NAME:倉庫名稱
DESCRIPTION:鏡像描述
STARS:使用者評價,反應一個鏡像的受歡迎程度
OFFICIAL:是否官方
AUTOMATED:自動建構,表示該鏡像由Docker Hub自動建構流程建立的
3.1.3 拉取鏡像
拉取鏡像就是從中央倉庫中下載下傳鏡像到本地
docker pull 鏡像名稱
例如,我要下載下傳centos7鏡像
docker pull centos:7
3.1.4 删除鏡像
按鏡像ID删除鏡像
docker rmi 鏡像ID
删除所有鏡像
docker rmi `docker images -q`
3.2 容器相關指令
3.2.1 檢視容器
檢視正在運作的容器
docker ps
檢視所有容器
docker ps –a
檢視最後一次運作的容器
docker ps –l
檢視停止的容器
docker ps -f status=exited
3.2.2 建立與啟動容器
建立容器常用的參數說明:
建立容器指令:docker run
-i:表示運作容器
-t:表示容器啟動後會進入其指令行。加入這兩個參數後,容器建立就能登入進去。即配置設定一個僞終端。
–name :為建立的容器命名。
-v:表示目錄映射關系(前者是主控端目錄,後者是映射到主控端上的目錄),可以使用多個-v做多個目錄或檔案映射。注意:最好做目錄映射,在主控端上做修改,然後共享到容器上。
-d:在run後面加上-d參數,則會建立一個守護式容器在背景運作(這樣建立容器後不會自動登入容器,如果隻加-i -t兩個參數,建立後就會自動進去容器)。
-p:表示端口映射,前者是主控端端口,後者是容器内的映射端口。可以使用多個-p做多個端口映射
(1)互動式方式建立容器
docker run -it --name=容器名稱 鏡像名稱:标簽 /bin/bash
這時我們通過ps指令檢視,發現可以看到啟動的容器,狀态為啟動狀态
退出目前容器
exit
(2)守護式方式建立容器:
docker run -di --name=容器名稱 鏡像名稱:标簽
登入守護式容器方式:
docker exec -it 容器名稱 (或者容器ID) /bin/bash
3.2.3 停止與啟動容器
停止容器:
docker stop 容器名稱(或者容器ID)
啟動容器:
docker start 容器名稱(或者容器ID)
3.2.4 檔案拷貝
如果我們需要将檔案拷貝到容器内可以使用cp指令
docker cp 需要拷貝的檔案或目錄 容器名稱:容器目錄
也可以将檔案從容器内拷貝出來
docker cp 容器名稱:容器目錄 需要拷貝的檔案或目錄
3.2.5 目錄挂載
我們可以在建立容器的時候,将主控端的目錄與容器内的目錄進行映射,這樣我們就可以通過修改主控端某個目錄的檔案進而去影響容器。
建立容器 添加-v參數 後邊為 主控端目錄:容器目錄,例如:
docker run -di -v /usr/local/myhtml:/usr/local/myhtml --name=mycentos3 centos:7
如果你共享的是多級的目錄,可能會出現權限不足的提示。
這是因為CentOS7中的安全子產品selinux把權限禁掉了,我們需要添加參數 --privileged=true 來解決挂載的目錄沒有權限的問題
3.2.6 檢視容器IP位址
我們可以通過以下指令檢視容器運作的各種資料
docker inspect 容器名稱(容器ID)
也可以直接執行下面的指令直接輸出IP位址
docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名稱(容器ID)
3.2.7 删除容器
删除指定的容器:
docker rm 容器名稱(容器ID)
4 應用部署
4.1 MySQL部署
(1)拉取mysql鏡像
docker pull centos/mysql-57-centos7
(2)建立容器
docker run -di --name=tensquare_mysql -p 33306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
-p 代表端口映射,格式為 主控端映射端口:容器運作端口
-e 代表添加環境變量 MYSQL_ROOT_PASSWORD 是root使用者的登陸密碼
(3)遠端登入mysql
連接配接主控端的IP ,指定端口為33306
4.2 tomcat部署
(1)拉取鏡像
docker pull tomcat:7-jre7
(2)建立容器
建立容器 -p表示位址映射
docker run -di --name=mytomcat -p 9000:8080
-v /usr/local/webapps:/usr/local/tomcat/webapps tomcat:7-jre7
4.3 Nginx部署
(1)拉取鏡像
docker pull nginx
(2)建立Nginx容器
docker run -di --name=mynginx -p 80:80 nginx
4.4 Redis部署
(1)拉取鏡像
docker pull redis
(2)建立容器
docker run -di --name=myredis -p 6379:6379 redis
5 遷移與備份
5.1 容器儲存為鏡像
我們可以通過以下指令将容器儲存為鏡像
docker commit mynginx mynginx_i
5.2 鏡像備份
我們可以通過以下指令将鏡像儲存為tar 檔案
docker save -o mynginx.tar mynginx_i
5.3 鏡像恢複與遷移
首先我們先删除掉mynginx_img鏡像 然後執行此指令進行恢複
docker load -i mynginx.tar
-i 輸入的檔案
執行後再次檢視鏡像,可以看到鏡像已經恢複
6 Dockerfile
6.1 什麼是Dockerfile
Dockerfile是由一系列指令和參數構成的腳本,這些指令應用于基礎鏡像并最終建立一個新的鏡像。
1、對于開發人員:可以為開發團隊提供一個完全一緻的開發環境;
2、對于測試人員:可以直接拿開發時所建構的鏡像或者通過Dockerfile檔案建構一個新的鏡像開始工作了;
3、對于運維人員:在部署時,可以實作應用的無縫移植。
6.2 常用指令
指令 | 作用 |
---|---|
FROM image_name:tag | 定義了使用哪個基礎鏡像啟動建構流程 |
MAINTAINER user_name | 聲明鏡像的建立者 |
ENV key value | 設定環境變量 (可以寫多條) |
RUN command | 是Dockerfile的核心部分(可以寫多條) |
ADD source_dir/file dest_dir/file | 将主控端的檔案複制到容器内,如果是一個壓縮檔案,将會在複制後自動解壓 |
COPY source_dir/file dest_dir/file | 和ADD相似,但是如果有壓縮檔案并不能解壓 |
WORKDIR path_dir | 設定工作目錄 |
6.3 使用腳本建立鏡像
步驟:
(1)建立目錄
mkdir –p /usr/local/dockerjdk8
(2)下載下傳jdk-8u171-linux-x64.tar.gz并上傳到伺服器(虛拟機)中的/usr/local/dockerjdk8目錄
(3)建立檔案Dockerfile
vi Dockerfile
#依賴鏡像名稱和ID
FROM centos:7
#指定鏡像建立者資訊
MAINTAINER ITCAST
#切換工作目錄
WORKDIR /usr
RUN mkdir /usr/local/java
#ADD 是相對路徑jar,把java添加到容器中
ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/
#配置java環境變量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
(4)執行指令建構鏡像
docker build -t='jdk1.8' .
注意後邊的空格和點,不要省略
(5)檢視鏡像是否建立完成
docker images
7 Docker私有倉庫
7.1 私有倉庫搭建與配置
(1)拉取私有倉庫鏡像(此步省略)
docker pull registry
(2)啟動私有倉庫容器
docker run -di --name=registry -p 5000:5000 registry
(3)打開浏覽器 輸入位址http://192.168.184.141:5000/v2/_catalog看到
{"repositories":[]}
表示私有倉庫搭建成功并且内容為空
(4)修改daemon.json
vi /etc/docker/daemon.json
添加以下内容,儲存退出。
此步用于讓 docker信任私有倉庫位址
(5)重新開機docker 服務
systemctl restart docker
7.2 鏡像上傳至私有倉庫
(1)标記此鏡像為私有倉庫的鏡像
docker tag jdk1.8 192.168.184.141:5000/jdk1.8
(2)再次啟動私服容器
docker start registry
(3)上傳标記的鏡像
docker push 192.168.184.141:5000/jdk1.8