Docker 容器的核心概念與使用
Docker背景
Docker 可以讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,然後釋出到任何流行的 Linux 機器上,也可以實現虛擬化。
容器是完全使用沙箱機制,相互之間不會有任何介面(類似手機app,一個容器就是一個app),更重要的是容器效能開銷極低。
Docker可以實現的功能:
Web 應用的自動化打包和釋出。
自動化測試和持續整合、釋出。
在服務型環境中部署和調整資料庫或其他的後臺應用。
從頭編譯或者擴充套件現有的OpenShift或Cloud Foundry平臺來搭建自己的PaaS環境。
Docker的優點:
1、更快速的交付和部署
對開發和運維(devop)人員來說,最希望的就是一次建立或配置,可以在任意地方正常執行。
開發者可以使用一個標準的映象來構建一套開發容器,開發完成之後,運維人員可以直接使用這個容器來部署程式碼。 Docker 可以快速建立容器,快速迭代應用程式,並讓整個過程全程可見,使團隊中的其他成員更容易理解應用程式是如何建立和工作的。 Docker 容器很輕很快!容器的啟動時間是秒級的,大量地節約開發、測試、部署的時間。
2、更高效的虛擬化
Docker 容器的執行不需要額外的 hypervisor 支援,它是核心級的虛擬化,因此可以實現更高的效能和效率。
3、更輕鬆的遷移和擴充套件
Docker 容器幾乎可以在任意的平臺上執行,包括物理機、虛擬機器、公有云、私有云、個人電腦、伺服器等。 這種相容性可以讓使用者把一個應用程式從一個平臺直接遷移到另外一個。
4、更簡單的管理
使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分發和更新,從而實現自動化並且高效的管理。
Docker架構
Docker 使用客戶端-伺服器 (C/S) 架構模式,使用遠端API來管理和建立Docker容器。
Docker 容器通過 Docker 映象來建立。容器與映象的關係類似於面向物件程式設計中的物件與類。
架構中主要有兩個概念:
Docker daemon: 執行在宿主機上,Docker守護程序,使用者通過Docker client(Docker命令)與Docker daemon互動
Docker client: Docker 命令列工具,是使用者使用Docker的主要方式,Docker client與Docker daemon通訊並將結果返回給使用者,Docker client也可以通過socket或者RESTful api訪問遠端的Docker daemon
Docker還有三個主要概念:
Docker image:映象是隻讀的,映象中包含有需要執行的檔案。映象用來建立container,一個映象可以執行多個container;映象可以通過Dockerfile建立,也可以從Docker hub/registry上下載。
Docker container:容器是Docker的執行元件,啟動一個container就是一個容器,容器是一個隔離環境,多個容器之間不會相互影響,保證容器中的程式執行在一個相對安全的環境中。
Docker hub/registry: 共享和管理Docker映象,使用者可以上傳或者下載上面的映象,官方地址為https://registry.hub.docker.com/,也可以搭建自己私有的Docker registry。
我們通過客戶端寫命令,然後客戶端將命令傳送給守護程序,守護程序再將命令執行的結果返回給客戶端,這就使我們能通過命令檢視執行結果,映象就是容器的原始碼,容器通過映象啟動,使用倉庫來儲存使用者構建的映象,倉庫分為共有和私有。
Docker安裝
建議在linux環境下安裝Docker,window環境搭建比較複雜且容易出錯,使用Centos7+yum來安裝Docker環境很方便。
yum install docker
安裝完成後,使用下面的命令來啟動 docker 服務,並將其設定為開機啟動:
service docker start
chkconfig docker on
此處採用了舊式的 sysv 語法,如採用CentOS 7中支援的新式 systemd 語法,如下:
systemctl start docker.service
systemctl enable docker.service
測試
docker version
Ubuntu Docker 安裝
Docker 支援以下的 Ubuntu 版本:
Ubuntu Precise 12.04 (LTS)
Ubuntu Trusty 14.04 (LTS)
Ubuntu Wily 15.10
其他更新的版本
安裝:
~$ wget -qO- https://get.docker.com/ | sh
輸入當前使用者的密碼後,就會下載指令碼並且安裝Docker及依賴包。
安裝完成後有個提示:
If you would like to use Docker as a non-root user, you should now consider
adding your user to the "docker" group with something like:
sudo usermod -aG docker runoob
Remember that you will have to log out and back in for this to take effect!
當要以非root使用者可以直接執行docker時,需要執行 sudo usermod -aG docker runoob 命令,然後重新登陸,否則會有報錯
啟動docker後臺服務
~$ sudo service docker start
測試執行hello-world
[email protected]:~$ docker run hello-world
映象加速
鑑於國內網路問題,後續拉取 Docker 映象十分緩慢,我們可以需要配置加速器來解決。
Docker 中國官方映象加速可通過registry.docker-cn.com訪問。該映象庫只包含流行的公有映象,私有映象仍需要從美國映象庫中拉取。
或者使用的網易的映象地址:http://hub-mirror.c.163.com。
新版的 Docker 使用 /etc/docker/daemon.json(Linux) 或
者 %programdata%\docker\config\daemon.json(Windows) 來配置 Daemon。
vi /etc/docker/daemon.json
#請在該配置檔案中加入(沒有該檔案的話,請先建一個):
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"live-restore": true
}
或者
{
"registry-mirrors": ["http://hub-mirror.c.163.com"]
"live-restore": true
}
Hello World
一:執行一個helloworld映象
抓取hello world映象執行下面的命令,將 image 檔案從倉庫抓取到本地。
docker image pull是抓取 image 檔案的命令
docker pull library/hello-world
library/hello-world是 image 檔案在倉庫裡面的位置,其中library是 image 檔案所在的組,hello-world是 image 檔案的名字。
使用docker images列出本地已有映象
$ sudo docker images
使用docker run執行
docker run hello-world
#顯示結果
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
二:啟動指定映象的容器,在容器中執行helloworld指令
執行命令 例如:
~$ docker run ubuntu:15.10 /bin/echo "Hello world"
各個引數解析:
- docker: Docker 的二進位制執行檔案。
- run:與前面的 docker 組合來執行一個容器。
- ubuntu:15.10指定要執行的映象,Docker首先從本地主機上查詢映象是否存在,如果不存在,Docker 就會從映象倉庫 Docker Hub 下載公共映象。
- /bin/echo "Hello world": 在啟動的容器裡執行的命令
以上命令完整的意思可以解釋為:Docker 以 ubuntu15.10 映象建立一個新容器,然後在容器裡執行 bin/echo "Hello world",然後輸出結果。
docker常用命令
拉取docker映象
docker pull image_name
檢視宿主機上的映象,Docker映象儲存在/var/lib/docker目錄下:
docker images
刪除映象
docker rmi docker.io/tomcat:7.0.77-jre7
或者
docker rmi b39c68b7af30
檢視當前有哪些容器正在執行
docker ps
檢視所有容器
docker ps -a
啟動、停止、重啟容器命令:
docker start container_name/container_id
docker stop container_name/container_id
docker restart container_name/container_id
後臺啟動一個容器後,如果想進入到這個容器,可以使用attach命令:
docker attach container_name/container_id
刪除容器的命令:
docker rm container_name/container_id
檢視當前系統Docker資訊
docker info
從Docker hub上下載某個映象:
docker pull centos:latest
docker pull centos:latest
執行docker pull centos會將Centos這個倉庫的所有映象下載到本地repository。
Docker 容器使用
Docker 客戶端
輸入 docker 命令來檢視到 Docker 客戶端的所有命令選項。
通過命令 docker command --help 更深入的瞭解指定的 Docker 命令使用方法。例如要檢視 docker stats 指令的具體使用方法:
~# docker stats –help
檢視 WEB 應用容器
使用 docker ps 來檢視正在執行的容器:
~# docker ps
埠資訊。
PORTS
0.0.0.0:32769->5000/tcp
表示Docker 開放了 5000 埠(預設 Python Flask 埠)對映到主機埠 32769 上。,可以通過32769埠訪問該應用
也可以通過 -p 引數來設定不一樣的埠,-d是後臺執行的意思:
~$ docker run -d -p 5000:5000 training/webapp python app.py
docker 還提供了另一個快捷方式 docker port,使用 docker port 可以檢視指定 (ID 或者名字)容器的某個確定埠對映到宿主機的埠號。
檢視 WEB 應用程式日誌
docker logs [ID或者名字] 可以檢視容器內部的標準輸出。
例如:~$ docker logs -f bf08b7f2cd89
-f: 讓 docker logs 像使用 tail -f 一樣來輸出容器內部的標準輸出。
檢視WEB應用程式容器的程序
使用 docker top 來檢視容器內部執行的程序
例如~$ docker top wizardly_chandrasekhar
檢查 WEB 應用程式
使用 docker inspect 來檢視 Docker 的底層資訊。它會返回一個 JSON 檔案記錄著 Docker 容器的配置和狀態資訊
例如~$ docker inspect wizardly_chandrasekhar
停止 WEB 應用容器
例如~$ docker stop wizardly_chandrasekhar
重啟WEB應用容器
已經停止的容器,可以使用命令 docker start 來啟動。
例如~$ docker start wizardly_chandrasekhar
使用docker ps -l 查詢最後一次建立的容器
Docker 映象使用
當執行容器時,使用的映象如果在本地中不存在,docker 就會自動從 docker 映象倉庫中下載,預設是從 Docker Hub 公共映象源下載。
列出映象列表
使用 docker images 來列出本地主機上的映象
~$ docker images
列表項說明:
- REPOSITORY:表示映象的倉庫源
- TAG:映象的標籤
- IMAGE ID:映象ID
- CREATED:映象建立時間
- SIZE:映象大小
同一倉庫源可以有多個 TAG,代表這個倉庫源的不同個版本,如ubuntu倉
庫源裡,有15.10、14.04等多個不同的版本,使用 REPOSITORY:TAG 來定義不同的映象。
如果要使用版本為15.10的ubuntu系統映象來執行容器時,命令如下:
~$ docker run -t -i ubuntu:15.10 /bin/bash
如果不指定一個映象的版本標籤,只使用 ubuntu,docker 將預設使用 ubuntu:latest 映象。
查詢映象
可以從 Docker Hub 網站來搜尋映象: https://hub.docker.com/
也可以使用 docker search 命令來搜尋映象。比如通過 docker search 命令搜尋 httpd 來尋找適合的httpd映象作為web服務。
~$ docker search httpd
建立映象
當從docker映象倉庫中下載的映象不能滿足需求時,可以通過以下兩種方式對映象進行更改。
1.從已經建立的容器中更新映象,並且提交這個映象
2.使用 Dockerfile 指令來建立一個新的映象
更新映象
更新映象之前,需要使用映象來建立一個容器。
在執行的容器內使用 apt-get update 命令進行更新
在完成操作之後,輸入 exit命令來退出這個容器。
通過命令 docker commit來提交容器副本。
~$ docker commit -m="has update" -a="xxxx" e218edb10161 xxxx/ubuntu:v2
各個引數說明:
- -m:提交的描述資訊
- -a:指定映象作者
- e218edb10161:容器ID
- runoob/ubuntu:v2:指定要建立的目標映象名
構建映象
使用命令 docker build , 從零開始來建立一個新的映象。為此,我們需要建立一個 Dockerfile 檔案,其中包含一組指令來告訴 Docker 如何構建我們的映象。
~$ cat Dockerfile
FROM centos:6.7
MAINTAINER Fisher "[email protected]"
RUN /bin/echo 'root:123456' |chpasswd
RUN useradd runoob
RUN /bin/echo 'runoob:123456' |chpasswd
RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd –D
每一個指令都會在映象上建立一個新的層,每一個指令的字首都必須是大寫的。
第一條FROM,指定使用哪個映象源必須指定且需要在Dockerfile其他指令的前面。後續的指令都依賴於該指令指定的image。FROM指令指定的基礎image可以是官方遠端倉庫中的,也可以位於本地倉庫。
MAINTAINER(用來指定映象建立者資訊)構建指令,用於將image的製作者相關的資訊寫入到image中。當我們對該image執行docker inspect命令時,輸出中有相應的欄位記錄該資訊。
RUN 指令告訴docker 在映象內執行命令,安裝了什麼。RUN可以執行任何被基礎image支援的命令。如基礎image選擇了ubuntu,那麼軟體管理部分只能使用ubuntu的命令。RUN指令可以有多條,每條RUN指令將在當前映象基礎上執行指定命令,並提交為新的映象。當命令較長時,可以用\來換行。
CMD(設定容器啟動時執行的操作)設定指令,用於容器啟動時指定的操作。該操作可以是執行自定義指令碼,也可以是執行系統命令。該指令只能在檔案中存在一次,如果有多個,則只執行最後一條。
注意:
1) CMD執行在映象構建之後,容器啟動的時候;
2) CMD只執行最後一條
3) CMD可以被使用者指定的命令覆蓋
ENTRYPOINT(設定容器啟動時執行的操作)設定指令,指定容器啟動時執行的命令,可以多次設定,但是隻有最後一個有效。
該指令的使用分為兩種情況,一種是獨自使用,另一種和CMD指令配合使用。
當獨自使用時,如果你還使用了CMD命令且CMD是一個完整的可執行的命令,那麼CMD指令和ENTRYPOINT會互相覆蓋只有最後一個CMD或者ENTRYPOINT有效:
CMD echo “Hello, World!”
ENTRYPOINT ls –l
另一種用法和CMD指令配合使用來指定ENTRYPOINT的預設參指令不是一個完整的可執行命令,僅僅是引數部分;ENTRYPOINT指令只能使用JSON方式指定執行命令,而不能指定引數:
FROM ubuntu
CMD ["-l"]
ENTRYPOINT ["/usr/bin/ls"]
USER(設定容器的使用者)設定指令,設定啟動容器的使用者,預設是root使用者。
EXPOSE(指定容器需要對映到宿主機器的埠)設定指令,該指令會將容器中的埠對映成宿主機器中的某個埠。格式為
EXPOSE <port> [<port> ...]--- EXPOSE 80 443 11211
ENV(用於設定環境變數)構建指令,在image中設定一個環境變數。格式:
ENV JAVA_HOME /path/to/java/dirent
ADD(從src複製檔案到容器的dest路徑)構建指令,所有拷貝到容器中的檔案和資料夾許可權為0755,uid和gid為0。格式為:
ADD <src> <dest>
<src> 是相對被構建的源目錄的相對路徑,可以是檔案或目錄的路徑,也可以是一個遠端的檔案url;<dest>是容器中的絕對路徑。
COPY複製本地主機的<src>(為Dockerfile所在目錄的相對路徑,檔案或目錄)為容器中的<dest>。目標路徑不存在時,會自動建立。
當使用本地目錄為源目錄時,推薦使用COPY。
格式為
COPY <src> <dest>
VOLUME(指定掛載點)設定指令,使容器中的一個目錄具有持久化儲存資料的功能,該目錄可以被容器本身使用,也可以共享給其他容器使用。我們知道容器使用的是AUFS,這種檔案系統不能持久化資料,當容器關閉後,所有的更改都會丟失。當容器中的應用有持久化資料的需求時可以在Dockerfile中使用該指令。格式:
FROM base
VOLUME ["/tmp/data"]
執行通過該Dockerfile生成image的容器,/tmp/data目錄中的資料在容器關閉後,裡面的資料還存在。例如另一個容器也有持久化資料的需求,且想使用上面容器共享的/tmp/data目錄,那麼可以執行下面的命令啟動一個容器:
docker run -t -i -rm -volumes-from container1 image2 bash
WORKDIR(切換目錄)設定指令,可以多次切換(相當於cd命令),對RUN,CMD,ENTRYPOINT生效。格式:
WORKDIR /path/to/workdir
ONBUILD(在子映象中執行)ONBUILD 指定的命令在構建映象時並不執行,而是在它的子映象中執行。
ONBUILD <Dockerfile關鍵字>
ARG(指定構建過程中使用的環境變數)
然後,使用 Dockerfile 檔案,通過 docker build 命令來構建一個映象。
~$ docker build -t runoob/centos:6.7 .
引數說明:
- -t :指定要建立的目標映象名
- . :Dockerfile 檔案所在目錄,可以指定Dockerfile 的絕對路徑
設定映象標籤
使用 docker tag 命令,為映象新增一個新的標籤。
~$ docker tag 860c279d2fec runoob/centos:dev
docker tag 映象ID,這裡是 860c279d2fec ,使用者名稱稱、映象源名(repository name)和新的標籤名(tag)。
Docker 容器連線
實現通過埠連線到一個docker容器
案例:
網路埠對映
先建立一個 python 應用的容器。
~$ docker run -d -P training/webapp python app.py
另外,可以指定容器繫結的網路地址,比如繫結 127.0.0.1。
使用 -P 引數建立一個容器,使用 docker ps 來看到埠5000繫結主機埠32768。
我們也可以使用 -p 標識來指定容器埠繫結到主機埠。
另外,我們可以使用 -p指定容器繫結的網路地址,比如繫結127.0.0.1。
這樣我們就可以通過訪問127.0.0.1:5001來訪問容器的5000埠。