1 簡介
docker官方網站,https://www.docker.com
docker文檔的官方網站 ,https://docs.docker.com,有時候比較慢,請使用以下內網訪問。
docker文檔的官方鏡像docs/archive:v1.11,大家可以內網訪問http://192.168.3.61:4000,由於此網站引用了google網站的相關內容,請大家務必將google的hosts添加到本機,否則頁面加載會比較慢。
1.1 歷史
1979年Unix chroot,實現了系統程序隔離。
2013年,28歲的Solomon在使用python開發dotCloud的PaaS雲時發現,使用 LXC技術可以打破產品發佈過程中應用開發工程師和系統工程師兩者之間無法輕鬆協作發佈產品的難題,2013年3月發佈docker 0.1版本,完整提出了一整套打包、分發、運維方案,拉開了基於雲計算平臺發佈產品方式的變革序幕。
1.2 目的
平臺產品在開發、測試、交付過程中,需要運維人員配置環境,修改表結構,還需要關注依賴軟件庫的安裝。
目前我司平臺產品在開發、測試、交付環節中的內容相差很大,開發時大家使用eclipse直接調試;測試時在測試平臺上上傳軟件包供測試人員測試;交付時再由開發人員上傳生產平臺供用戶使用。即上述開發、測試、交付的過程是一致的,有可能會因爲環境問題導致生產平臺出現問題,但在測試平臺上沒有發現。
docker的初衷正是如此,即“Build once, Run anywhere; Configureonce, Run anything”。產品的交付就是一個鏡像,開發、測試、交付都是這個鏡像,確保產品過程中的一致性,減少環境干擾的影響。
基於應用的發佈,每個鏡像僅是一個應用,多個應用可以共存於同一臺機器,一臺機器上可以運行成千上萬個應用,目前的服務器性能都是過剩的,對於某些低併發應用來講,一臺機器顯得過於浪費,使用docker可以很方便的運行多個應用,而且確保這些應用完全隔離,互不影響。
1.3 區別
基於Linux的虛擬技術早在1979年就推出了chroot,而在後續時間裏又推出了虛擬機產品,比如vmware、virtualbox、xen等。docker與現有的虛擬機技術不相同,如下圖說明:
傳統的虛擬機技術,是在現有宿主機上再虛擬一層操作系統,它是一個完整操作系統內核。但docker是在宿主機上運行dockerengine這個應用程序,再在其上隔離運行多個應用。
1.4 是什麼
docker,碼頭工人,logo是一個大鯨魚揹着若干個集裝箱。docker的思想與集裝箱非常一致,力求建立類似集裝箱似的標準塊(鏡像),通過鯨魚(docker registry)進行分發、部署使用。docker旨在加快“寫代碼=》運行代碼”的時間,即通過標準化的接口加快產品的“測試、分發、部署、運維”。
每個應用都可以對應一個鏡像,舉例來說,對於一個標準的基於django的web產品,需要nginx、django、mysql、redis這些應用,如此建立四個鏡像(nginx、django、mysql、redis),開發人員的代碼打進django鏡像,這四個鏡像可以部署在同一個機器上,也可以部署在不同機器。用戶訪問此web產品時,首先由nginx對應的容器捕獲,再分發給django容器,django容器調用mysql容器獲取數據進行處理。
1.5 做什麼
編譯環境的統一
單應用環境的統一部署
多應用間方便的通信
應用方便的遷移
同一臺機器,運行多個隔離的應用
1.6 不做什麼
不是虛擬機,一個鏡像僅僅完成一個業務,一般只有一個進程。
不要將數據和應用共存於一個鏡像。
2 安裝docker
僅支持64bit的操作系統,詳細安裝步驟請參考官方docs。
2.1 Linux
必須確保Linux內核版本在3.10以上。
2.1.1 ubuntu
必須按照如下步驟進行,不要直接使用apt-get安裝!
(1) 版本號,確保ubuntu版本爲12.04、14.04、16.04其中之一,這些ubuntu版本都是LTS版本,即long term support。
(2) apt版本升級,確保可以使用docker源。
命令如下:
$ sudo apt-get update
$ sudo apt-get install apt-transport-httpsca-certificates
$ sudo apt-key adv \
--keyserver hkp://ha.pool.sks-keyservers.net:80 \
--recv-keys 58118E89F3A912897C070ADBF76221572C52609D
(3) 添加docker源
$ echo "<REPO>" | sudo tee/etc/apt/sources.list.d/docker.list
上述的<REPO> 使用下表的數據,根據ubuntu版本。
版本號 |
<REPO> |
12.04 (LTS) |
deb https://apt.dockerproject.org/repo ubuntu-precise main |
14.04 (LTS) |
deb https://apt.dockerproject.org/repo ubuntu-trusty main |
16.04 (LTS) |
deb https://apt.dockerproject.org/repo ubuntu-xenial main |
(4) 下載內核支持
$ sudo apt-get update
$ sudo apt-get installlinux-image-extra-$(uname -r) linux-image-extra-virtual
(5) 下載docker
$ sudo apt-get update
$ sudo apt-get install docker-engine
2.1.2 centos
僅支持centos7及以上,必須按照如下步驟進行,不要直接使用yum安裝!
(1) yum源更新
$ sudo yum update
$ sudo tee /etc/yum.repos.d/docker.repo<<-'EOF'
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/7/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF
(2) 下載docker
$ sudo yum install docker-engine
2.2 MAC
最新的docker原生支持mac,不需要安裝虛擬機了。
參考網址:https://docs.docker.com/engine/installation/mac/
2.3 Windows
最新的docker原生支持windows10 企業版,不需要安裝虛擬機了。
參考網址:https://docs.docker.com/engine/installation/windows/
3 安裝docker-compose
必須在Linux下運行,僅支持64位的x86,直接下載可執行程序。也可以直接從某個已經下載好的機器上直接複製,就可以使用了。
如果是Mac或者windows版本,請參考網址下載。
參考網址:https://docs.docker.com/compose/install/
4 使用
docker默認使用root用戶執行,如果非root執行命令請添加sudo,下同。
4.1 準備
(1) 運行docker
ubuntut和centos下,使用service docker restart;重啓docker服務也使用這個命令。
centos下如果想開機就運行docker,請使用命令sudo chkconfig docker on
(2) 查看版本
使用命令docker version,目前docker版本已經到了1.12,請使用最新版本。
root@server-ubuntu:~# docker version
Client:
Version: 1.12.3
API version: 1.24
Go version: go1.6.3
Git commit: 6b644ec
Built: Wed Oct 26 21:44:32 2016
OS/Arch: linux/amd64
Server:
Version: 1.12.3
API version: 1.24
Go version: go1.6.3
Git commit: 6b644ec
Built: Wed Oct 26 21:44:32 2016
OS/Arch: linux/amd64
(3) 添加docker源
默認使用docker.io這個國外網站,下載非常慢,建議使用國內中科大的源。
修改文件/etc/default/docker,增加一行如下,再重啓docker服務:
DOCKER_OPTS="--registry-mirror=https://docker.mirrors.ustc.edu.cn"
4.2 熱身
(1) hello-world
執行命令:docker run hello-world,如果看到以下輸出則表示成功。
……………..
Hello from Docker!
This message shows that your installationappears to be working correctly.
…………………………
然後再執行命令:docker images,則可以看到hello-world鏡像已經下載,此鏡像大小爲1.848kB
root@wdq-desktop:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest c54a2cc56cbb 5 months ago 1.848kB
(2) ubuntu
執行命令:docker run -it ubuntu /bin/bash
可以看到我們已經進入了一個新的環境,與原有的宿主機完全不相同,其中pid爲1的進程居然是/bin/bash。
這個環境是一個mini版本的ubuntu,在其中可以做很多事情。同時這個鏡像是後續所有鏡像的基石,即其他鏡像都是以ubuntu鏡像爲基礎的。
4.3 基本概念
4.3.1 架構
docker是一個C/S架構的產品,分爲兩個部分:docker engine和docker hub。
docker engine,安裝在使用者的主機上,C/S架構,Client即手動運行各個docker命令,Server即是docker daemon,利用主機上的鏡像Images運行進入容器環境Containers。
docker hub,用於分發鏡像的Saas平臺,官網是docker.io,用戶可以自行創建私有的平臺,供內部人員使用。
4.3.2 鏡像
類似於iso鏡像文件,是靜態存儲的文件集合,鏡像是隻讀系統。比如在前面章節下載的ubuntu,就是一個典型的鏡像。可以直接使用client從docker官網下載已有的鏡像,或者自已build一個鏡像,詳細參見《docker之鏡像管理》。
鏡像文件一般存儲於/var/lib/docker/目錄下,也可以在/etc/default/docker配置文件中指定位置。其中的文件內容非常難以理解,一般通過docker client進行操作。
鏡像文件的描述格式爲“[url:port/][group/]name[:/TAG]”,可以看到除name外,其他均是可選項,以上述的ubuntu爲例,在使用docker pull下載時,name爲ubuntu,TAG爲空則默認爲latest(所以使用docker images可以看到TAG),url和port也爲空則表示從官網下載,由於我們已經配置了中科大的源爲鏡像源則會首先從中科大的源下載,group也爲空。
鏡像文件是分層結構,使用命令docker history查看:
ubuntu鏡像由6層組成,最底層爲一個128.2MB大小的文件,其上五層都是一堆shell命令,這6層系統通過Linux的aufs文件系統合併之後,呈現給用戶的是一個完整的文件系統。
因爲鏡像的分層原因,會節省主機的存儲開銷。舉例來說,如果已經下載了ubuntu鏡像,再下載基於此ubuntu鏡像的其他鏡像,則此最基本的ubuntu鏡像不需要再下載了,只需要下載ubuntu鏡像之上的內容。這個也很類似代碼管理系統中的diff。
4.3.3 容器
容器是鏡像的運行環境,鏡像只有在容器中才有意義,容器必須依賴一個鏡像,如下圖:
從上圖可以看出,容器在運行時在鏡像層之外又單獨加了可讀寫的一層,所有對容器的修改動作均在這一層中處理,鏡像內容不會作任何改變。
使用docker run命令啓動一個容器,容器創建後只要其主進程退出(pid==1)則容器退出,默認情況下退出的容器仍然存在,可以繼續使用命令dockerstart運行,如果不需要可以使用docker rm 刪除容器。
上圖是運行docker run的示意圖,docker run相當於執行了兩重命令,一個是創建一個容器,使用docker create,從鏡像創建容器;另一個是docker start,運行一個容器。
4.3.4 倉庫
docker registry,存儲鏡像的倉庫,docker官方的倉庫是docker.io,有兩個部分,一個是僅有倉庫,容許所有人下載、上傳、搜索,另一個是私有倉庫,僅允許特定人員操作。
公司內部使用的話一般建議搭建私有倉庫,搭建docker 倉庫用的也是一個鏡像,此鏡像的名稱是registry,版本是2。目前有價值的業務均以docker鏡像的方式提供,registr如是,文檔docs也如是。
4.4 任務管理系統
本章節搭建基於django的任務管理系統,需要用到mysql、redis、task三個鏡像,其中mysql/redis爲兩個公共的鏡像,其Dockerfile都是從官網的github下載來的,task鏡像是基於django的工程,任務管理系統的代碼鏡像。這三個鏡像目前已經構建好,只需要從私有倉庫下載即可。
4.4.1 使用私有倉庫
目前公司內部搭建了一個docker私有倉庫,域名是dockerreg.maxnetsys.com,對應的IP目前必須是192.168.3.61。
l 修改/etc/hosts
確保域名dockerreg.maxnetsys.com指向的是192.168.3.61。如下圖:
l 使用HTTPS證書
將文件ca.crt放置到如下目錄位置,再重啓docker服務。
4.4.2 下載鏡像
docker pull dockerreg.maxnetsys.com:5000/maxnet-mysql
docker pull dockerreg.maxnetsys.com:5000/maxnet-django
docker pull dockerreg.maxnetsys.com:5000/maxnet-redis
使用如下三個命令下載鏡像。
4.4.3 構建運行環境
使用docker-compose工具同時操作多個容器。在當前目錄下生成docker-compose.yml文件,此文件爲yml格式(類似xml),請務必使用對應的編輯器進行編輯,內容如下:
version: "2"
services:
db:
image: dockerreg.maxnetsys.com:5000/maxnet-mysql:latest
expose:
-"3306"
volumes:
-mysql_data:/var/lib/mysql
-mysql_log:/var/log/mysql
environment:
MYSQL_ROOT_PASSWORD: '123456'
MYSQL_USER: 'xdpi'
MYSQL_PASSWORD: 'maxnet@5668'
redis_main: # slave redis must using anothercontainer with the same image
image: dockerreg.maxnetsys.com:5000/maxnet-redis:latest
volumes:
-redis_data:/var/lib/redis
-redis_log:/var/log/redis
expose:
-"6379"
task:
image: dockerreg.maxnetsys.com:5000/maxnet-task:latest
command: python3 manage.py runserver 0.0.0.0:8000
# volumes:
# -../image:/code
links:
-db
-redis_main
ports:
-"8000:8000"
volumes:
mysql_data:
mysql_log:
redis_data:
redis_log:
4.4.4 運行業務
在當前目錄下執行docker-compose up,如此會以前臺方式進行,當前窗口被掛住。可以使用-d參數讓其後臺運行,如此當前窗口可以繼續使用。
在瀏覽器在輸入http://IP:8000/report,如此就進入了任務管理系統。
需要停止業務時,請使用docker-compose down,還可以使用start/stop停止其中的某個容器,詳細請參考docker-compose相關文檔。
4.4.5 環境說明
mysql容器監聽在3306端口,其服務名稱爲db,故在report鏡像的代碼中,對應django工程的settings.py文件中的database 配置,其中mysql的主機名請使用db;mysql的數據區寫到了數據卷“mysql_data”,日誌區也寫到了數據卷“mysql_log”,這些數據卷不屬於某容器,即使容器被刪除,這些數據卷內容仍然存在。
task容器爲主業務,監聽端口8000且映射到宿主機8000端口,如此其他機器可以訪問此機器的8000端口來使用此業務。task容器需要使用數據庫db和緩存redis,故在links指定。redis也使用了數據捲來存儲日誌和數據。
5 FAQ
本章節記錄經常遇到的問題。
(1) 如何進入一個正在運行的容器?
docker exec -it your_container_name /bin/bash
千萬不要在容器中運行sshd再登錄了。
(2) 如何執行容器中的命令?
docker exec -it your_container_name your_cmd_with_args
注意your_cmd_with_args,其中可以有分號,比如可以查看容器中的某個文件
(3) 如何導出容器中的數據卷內容?
docker run -v .:/cpdir --from-volume volume_name your_image_name cp volumedir /cpdir
基本思想是將當前目錄掛載到容器中的某個固定目錄比如/cpdir,然後同時掛載數據卷再將數據卷的內容複製出來。
(4) docker-compose.yml所在目錄名稱修改後原有容器無法刪除?
docker-compose創建容器和數據卷時,都加了一個前綴,此前綴恰好是目錄名稱,故修改所在目錄名稱後,導致docker-compose原有的容器無法管理了,也無法停止掉,此時必須使用docker-compose down --remove-orphans
6 深度瞭解
關於數據卷內容請參考《docker之數據存儲》;
docker-compose內容請參考《docker之compose》;
鏡像相關內容請參考《docker之鏡像製作》;
倉庫相關內容請參考《docker之倉庫管理》;