作者:Warm and new
鏈接:https://www.cnblogs.com/peng104/p/10296717.html
1、引言
1.1 Docker是什麼
Docker 最初是 dotCloud 公司創始人 Solomon Hykes 在法國期間發起的一個公司內部專案,於 2013 年 3 月以 Apache 2.0 授權協議開源,主要專案代碼在 GitHub 上進行維護。
Docker 使用 Google 公司推出的 Go 語言 進行開發實現。
docker是linux容器的一種封裝,提供簡單易用的容器使用接口。它是最流行的Linux容器解決方案。
docker的接口相當簡單,用戶可以方便的創建、銷毀容器。
docker將應用程式與程式的依賴,打包在一個檔案裡面。運行這個檔案就會生成一個虛擬容器。
程式運行在虛擬容器里,如同在真實物理機上運行一樣,有了docker,就不用擔心環境問題了。
1.2 應用場景
- web應用的自動化打包和發佈
-
自動化測試和持續集成、發佈
-
在服務型環境中部署和調整資料庫或其他應用
1.3 區別
1、物理機
2、虛擬機
3、docker容器
1.4 Docker的三大概念及優勢
- 鏡像 image
- 容器 container
-
倉庫 repository
docker容器的優勢
# 1、更高效的利用系統資源
由於容器不需要進行硬體虛擬以及運行完整操作系統等額外開銷,Docker 對系統 資源的利用率更高。
無論是應用執行速度、記憶體損耗或者檔案儲存速度,都要比傳 統虛擬機技術更高效。因此,相比虛擬機技術,一個相同配置的主機,往往可以運 行更多數量的應用。
# 2、更快速的啟動時間
傳統的虛擬機技術啟動應用服務往往需要數分鐘,而 Docker 容器應用,由於直接 運行於宿主內核,無需啟動完整的操作系統,因此可以做到秒級、甚至毫秒級的啟 動時間。大大的節約了開發、測試、部署的時間。
# 3、一致的運行環境
開發過程中一個常見的問題是環境一致性問題。由於開發環境、測試環境、生產環 境不一致,導致有些 bug 並未在開發過程中被髮現。
而 Docker 的鏡像提供了除內 核外完整的運行時環境,確保了應用運行環境一致性,從而不會再出現 “這段代碼 在我機器上沒問題啊” 這類問題。
# 4、持續交付和部署
對開發和運維(DevOps)人員來說,最希望的就是一次創建或配置,可以在任意 地方正常運行。
使用 Docker 可以通過定製應用鏡像來實現持續集成、持續交付、部署。開發人員 可以通過 Dockerfile 來進行鏡像構建,並結合 持續集成(Continuous Integration) 系 統進行集成測試,
而運維人員則可以直接在生產環境中快速部署該鏡像,甚至結合 持續部署(Continuous Delivery/Deployment) 系統進行自動部署。
而且使用 Dockerfile 使鏡像構建透明化,不僅僅開發團隊可以理解應用運行環 境,也方便運維團隊理解應用運行所需條件,幫助更好的生產環境中部署該鏡像。
# 5、更輕鬆的遷移
由於 Docker 確保了執行環境的一致性,使得應用的遷移更加容易。Docker 可以在 很多平臺上運行,無論是物理機、虛擬機、公有雲、私有雲,甚至是筆記本,其運 行結果是一致的。
因此用戶可以很輕易的將在一個平臺上運行的應用,遷移到另一 個平臺上,而不用擔心運行環境的變化導致應用無法正常運行的情況。
2、0Docker安裝
系統環境:docker最低支持centos7且在64位平臺上,內核版本在3.10以上
版本:社區版,企業版(包含了一些收費服務)
官方版安裝教程(英文)https://docs.docker.com/install/linux/docker-ce/centos/#upgrade-docker-after-using-the-convenience-script
博主版安裝教程:
# 安裝docker
yum install docker
# 啟動docker
systemctl start/status docker
# 查看docker啟動狀態
docker version
配置加速器
簡介:DaoCloud 加速器 是廣受歡迎的 Docker 工具,解決了國內用戶訪問 Docker Hub 緩慢的問題。DaoCloud 加速器結合國內的 CDN 服務與協議層優化,成倍的提升了下載速度。
DaoCloud官網:https://www.daocloud.io/mirror#accelerator-doc
# 一條命令加速(記得重啟docker)
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://95822026.m.daocloud.io
3、0Docker基礎命令
docker –help(中文註解)
Usage:
docker [OPTIONS] COMMAND [arg...]
docker daemon [ --help | ... ]
docker [ --help | -v | --version ]
A
self-sufficient runtime for containers.
Options:
--config=~/.docker Location of client config files
-D, --debug=false Enable debug mode
-H, --host=[] Daemon socket(s) to connect to
-h, --help=false Print usage
-l, --log-level=info Set the logging level
--tls=false Use TLS; implied by--tlsverify
--tlscacert=~/.docker/ca.pem Trust certs signed only by this CA
--tlscert=~/.docker/cert.pem Path to TLS certificate file
--tlskey=~/.docker/key.pem Path to TLS key file
--tlsverify=false Use TLS and verify the remote
-v, --version=false Print version information and quit
Commands:
attach Attach to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes #提交當前容器為新的鏡像
cp Copy files/folders from a container to a HOSTDIR or to STDOUT
create Create a new container
diff Inspect changes on a container's filesystem #查看docker容器變化
events Get real time events from the server
exec Run a command in a running container
export Export a container's filesystem as a tar archive #匯出容器的內容流作為一個tar歸檔檔案(對應import)
history Show the history of an image
images List images
import Import the contents from a tarball to create a filesystem image
info Display system-wide information
inspect Return low-level information on a container or image
kill Kill a running container
load Load an image from a tar archive or STDIN
login Register or log in to a Docker registry
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within a container
port List port mappings or a specific mapping for the CONTAINER
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart a running container
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save an image(s) to a tar archive
search Search the Docker Hub for images
hub中搜索鏡像
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop a running container
tag Tag an image into a repository
top Display the running processes of a container
unpause Unpause all processes within a container
version Show the Docker version information
wait Block until a container stops, then print its exit code
Run 'docker COMMAND --help' for more information on a command. #運行docker命令在幫助可以獲取更多信息
docker search hello-docker # 搜索hello-docker的鏡像
docker search centos # 搜索centos鏡像
docker pull hello-docker # 獲取centos鏡像
docker run hello-world #運行一個docker鏡像,產生一個容器實體(也可以通過鏡像id前三位運行)
docker image ls # 查看本地所有鏡像
docker images # 查看docker鏡像
docker image rmi hello-docker # 刪除centos鏡像
docker ps #列出正在運行的容器(如果創建容器中沒有行程正在運行,容器就會立即停止)
docker ps -a # 列出所有運行過的容器記錄
docker save centos > /opt/centos.tar.gz # 匯出docker鏡像至本地
docker load /opt/centos.tar.gz #匯入本地鏡像到docker鏡像庫
docker stop `docker ps -aq` # 停止所有正在運行的容器
docker rm `docker ps -aq` # 一次性刪除所有容器記錄
docker rmi `docker images -aq` # 一次性刪除所有本地的鏡像記錄
3.1 啟動容器的兩種方式
容器是運行應用程式的,所以必須得先有一個操作系統為基礎
1、基於鏡像新建一個容器並啟動
# 1. 後臺運行一個docker
docker run -d centos /bin/sh -c "while true;do echo 正在運行; sleep 1;done"
# -d 後臺運行容器
# /bin/sh 指定使用centos的bash解釋器
# -c 運行一段shell命令
# "while true;do echo 正在運行; sleep 1;done" 在linux後臺,每秒中打印一次正在運行
docker ps # 檢查容器行程
docker logs -f 容器id/名稱 # 不間斷打印容器的日誌信息
docker stop centos # 停止容器
# 2. 啟動一個bash終端,允許用戶進行交互
docker run --name mydocker -it centos /bin/bash
# --name 給容器定義一個名稱
# -i 讓容器的標準輸入保持打開
# -t 讓Docker分配一個偽終端,並系結到容器的標準輸入上
# /bin/bash 指定docker容器,用shell解釋器交互
當利用docker run來創建容器時,Docker在後臺運行的步驟如下:
# 1. 檢查本地是否存在指定的鏡像,不存在就從公有倉庫下載
# 2. 利用鏡像創建並啟動一個容器
# 3. 分配一個檔案系統,併在只讀的鏡像層外面掛在一層可讀寫層
# 4. 從宿主主機配置的網橋接口中橋接一個虛擬接口到容器中去
# 5. 從地址池配置一個ip地址給容器
# 6. 執行用戶指定的應用程式
# 7. 執行完畢後容器被終止
2、將一個終止狀態(stopped)的容器重新啟動
[[email protected] ~]# docker ps -a # 先查詢記錄
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ee92fcf6f32d centos "/bin/bash" 4 days ago Exited (137) 3 days ago kickass_raman
[[email protected] ~]# docker start ee9 # 再啟動這個容器
ee9
[[email protected] ~]# docker exec -it ee9 /bin/bash # 進入容器交互式界面
[[email protected] /]# # 註意看用戶名,已經變成容器用戶名
3.2 提交創建自定義鏡像
# 1.我們進入交互式的centos容器中,發現沒有vim命令
docker run -it centos
# 2.在當前容器中,安裝一個vim
yum install -y vim
# 3.安裝好vim之後,exit退出容器
exit
# 4.查看剛纔安裝好vim的容器記錄
docker container ls -a
# 5.提交這個容器,創建新的image
docker commit 059fdea031ba chaoyu/centos-vim
# 6.查看鏡像檔案
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
chaoyu/centos-vim latest fd2685ae25fe 5 minutes ago 348MB
3.3 外部訪問容器
容器中可以運行網絡應用,但是要讓外部也可以訪問這些應用,可以通過-p或-P引數指定端口映射。
docker run -d -P training/webapp python app.py
# -P 引數會隨機映射端口到容器開放的網絡端口
# 檢查映射的端口
docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cfd632821d7a training/webapp "python app.py" 21 seconds ago Up 20 seconds 0.0.0.0:32768->5000/tcp brave_fermi
#宿主機ip:32768 映射容器的5000端口
# 查看容器日誌信息
docker logs -f cfd # #不間斷顯示log
# 也可以通過-p引數指定映射端口
docker run -d -p 9000:5000 training/webapp python app.py
打開瀏覽器訪問服務器的9000端口, 內容顯示 Hello world!表示正常啟動
(如果訪問失敗的話,檢查自己的防火牆,以及雲服務器的安全組)
4、利用dockerfile定製鏡像
鏡像是容器的基礎,每次執行docker run的時候都會指定哪個鏡像作為容器運行的基礎。我們之前的例子都是使用來自docker hub的鏡像,直接使用這些鏡像只能滿足一定的需求,當鏡像無法滿足我們的需求時,就得自定製這些鏡像。
# 鏡像的定製就是定製每一層所添加的配置、檔案。如果可以吧每一層修改、安裝、構建、操作的命令都寫入到一個腳本,用腳本來構建、定製鏡像,這個腳本就是dockerfile。
# Dockerfile 是一個文本檔案,其內包含了一條條的指令(Instruction),每一條指令 構建一層,因此每一條指令的內容,就是描述該層應當如何構建。
引數詳解
FROM scratch #製作base image 基礎鏡像,儘量使用官方的image作為base image
FROM centos #使用base image
FROM ubuntu:14.04 #帶有tag的base image
LABEL version=“1.0” #容器元信息,幫助信息,Metadata,類似於代碼註釋
LABEL maintainer=“[email protected]"
#對於複雜的RUN命令,避免無用的分層,多條命令用反斜線換行,合成一條命令!
RUN yum update && yum install -y vim \
Python-dev #反斜線換行
RUN /bin/bash -c "source $HOME/.bashrc;echo $HOME”
WORKDIR /root #相當於linux的cd命令,改變目錄,儘量使用絕對路徑!!!不要用RUN cd
WORKDIR /test # 如果沒有就自動創建
WORKDIR demo # 再進入demo檔案夾
RUN pwd # 打印結果應該是/test/demo
ADD and COPY
ADD hello / # 把本地檔案添加到鏡像中,吧本地的hello可執行檔案拷貝到鏡像的/目錄
ADD test.tar.gz / # 添加到根目錄並解壓
WORKDIR /root
ADD hello test/ # 進入/root/ 添加hello可執行命令到test目錄下,也就是/root/test/hello 一個絕對路徑
COPY hello test/ # 等同於上述ADD效果
ADD與COPY
- 優先使用COPY命令
-ADD除了COPY功能還有解壓功能
添加遠程檔案/目錄使用curl或wget
ENV # 環境變數,盡可能使用ENV增加可維護性
ENV MYSQL_VERSION 5.6 # 設置一個mysql常量
RUN yum install -y mysql-server=“${MYSQL_VERSION}”
進階知識(瞭解)
VOLUME and EXPOSE
儲存和網絡
RUN and CMD and ENTRYPOINT
RUN:執行命令並創建新的Image Layer
CMD:設置容器啟動後預設執行的命令和引數
ENTRYPOINT:設置容器啟動時運行的命令
Shell格式和Exec格式
RUN yum install -y vim
CMD echo ”hello docker”
ENTRYPOINT echo “hello docker”
Exec格式
RUN [“apt-get”,”install”,”-y”,”vim”]
CMD [“/bin/echo”,”hello docker”]
ENTRYPOINT [“/bin/echo”,”hello docker”]
通過shell格式去運行命令,會讀取$name指令,而exec格式是僅僅的執行一個命令,而不是shell指令
cat Dockerfile
FROM centos
ENV name Docker
ENTRYPOINT [“/bin/echo”,”hello $name”]#這個僅僅是執行echo命令,讀取不了shell變數
ENTRYPOINT [“/bin/bash”,”-c”,”echo hello $name"]
CMD
容器啟動時預設執行的命令
如果docker run指定了其他命令(docker run -it [image] /bin/bash ),CMD命令被忽略
如果定義多個CMD,只有最後一個執行
ENTRYPOINT
讓容器以應用程式或服務形式運行
不會被忽略,一定會執行
最佳實踐:寫一個shell腳本作為entrypoint
COPY docker-entrypoint.sh /usr/local/bin
ENTRYPOINT [“docker-entrypoint.sh]
EXPOSE 27017
CMD [“mongod”]
[[email protected] home]# more Dockerfile
FROm centos
ENV name Docker
#CMD ["/bin/bash","-c","echo hello $name"]
ENTRYPOINT ["/bin/bash","-c","echo hello $name”]
5、發佈到倉庫
5.1 docker hub共有鏡像發佈
docker提供了一個類似於github的倉庫docker hub,
官方網站(需註冊使用)https://hub.docker.com/
# 註冊docker id後,在linux中登錄dockerhub
docker login
# 註意要保證image的tag是賬戶名,如果鏡像名字不對,需要改一下tag
docker tag chaoyu/centos-vim peng104/centos-vim
# 語法是: docker tag 倉庫名 peng104/倉庫名
# 推送docker image到dockerhub
docker push peng104/centps-cmd-exec:latest
# 去dockerhub中檢查鏡像
# 先刪除本地鏡像,然後再測試下載pull 鏡像檔案
docker pull peng104/centos-entrypoint-exec
5.2 私有倉庫
docker hub 是公開的,其他人也是可以下載,並不安全,因此還可以使用docker registry官方提供的私有倉庫
用法詳解點我https://yeasy.gitbooks.io/docker_practice/repository/registry.html
docker pull registry
docker run -d -p 5000:5000 -v /opt/data/registry:/var/lib/registry registry
-d 後臺運行
-p 端口映射 宿主機的5000:容器內的5000
-v 資料捲掛載 宿主機的 /opt/data/registry :/var/lib/registry
registry 鏡像名
/var/lib/registry 存放私有倉庫位置
vim /etc/docker/daemon.json
{
"registry-mirrors": ["http://f1361db2.m.daocloud.io"],
"insecure-registries":["192.168.11.37:5000"]
}
vim /lib/systemd/system/docker.service
[ ]
EnvironmentFile=-/etc/docker/daemon.json
systemctl daemon-reload
systemctl restart docker
docker tag docker.io/peng104/hello-world-docker 192.168.11.37:5000/peng-hello
docker pull 192.168.11.37:5000/peng-hello
6、實體演示
編寫dockerfile,構建自己的鏡像,運行flask程式。
確保app.py和dockerfile在同一個目錄!
# 1.準備好app.py的flask程式
[[email protected] ~]# cat app.py
from flask import Flask
app=Flask(__name__)
@app.route('/')
def hello():
return "hello docker"
if __name__=="__main__":
app.run(host='0.0.0.0',port=8080)
[[email protected] home]# ls
app.py Dockerfile
# 2.編寫dockerfile
[[email protected] ~]# cat Dockerfile
FROM python:2.7
LABEL maintainer="溫而新"
RUN pip install flask
COPY app.py /app/
WORKDIR /app
EXPOSE 8080
CMD ["python","app.py"]
# 3.構建鏡像image,找到當前目錄的Dockerfile,開始構建
docker build -t peng104/flask-hello-docker .
# 4.查看創建好的images
docker image ls
# 5.啟動此flask-hello-docker容器,映射一個端口供外部訪問
docker run -d -p 8080:8080 peng104/flask-hello-docker
# 6.檢查運行的容器
docker container ls
# 7.推送這個鏡像到私有倉庫
docker tag peng104/flask-hello-docker 192.168.11.37:5000/peng-flaskweb
docker push 192.168.11.37:5000/peng-flaskweb