使用Docker前咱們首先要簡單瞭解一下容器的概念。MSDN上有一張虛擬機和容器的對比圖,很好的展現了虛擬機和容器的區別,以下所示,虛擬機包括應用程序、必需的庫或二進制文件以及完整的來賓操做系統,每臺虛擬機都有一個單獨的內核,咱們徹底能夠把虛擬機看作是一臺真實的物理機。 容器包括應用程序及其全部依賴項,與其餘容器共享 OS 內核,容器在主機操做系統上做爲獨立進程運行,咱們能夠把容器看作是一個應用沙盒。node
咱們常常會遇到「我機器上能夠運行」的問題吧,而後部署到其餘機器時就遇到了各類坑,這可能是由於其餘設備上缺乏應用所需的環境或者缺乏應用的依賴項形成的。使用容器技術能夠很好的解決這個問題,容器是一個「應用的沙盒」,這個沙盒內部包含了應用所需的環境和全部依賴項,只要有這個沙盒存在,應用在任何環境下都能正常的運行,容器技術的典型特色就是「一次封裝,處處運行」。mysql
Docker 是一個使用go語言開發的開源的應用容器引擎,讓開發者能夠打包他們的應用以及依賴包到一個可移植的容器中,而後發佈到任何流行的 Linux 機器上,也能夠實現虛擬化。咱們先了解Docker中的三個核心概念:linux
1 鏡像(Image)git
鏡像是一種輕量級、可執行的獨立軟件包,它包含運行某個軟件所需的全部內容,包括代碼、運行時、庫、環境變量和配置文件。github
2 容器(Container)web
容器是鏡像的運行時實例 ,執行鏡像時內存中運行的就是容器。若是把鏡像看作面向對象中的類,容器就是對象。使用類時經過new來獲取一個對象,相似的使用鏡像時經過 docker run <鏡像名/鏡像id> 建立一個容器。sql
3 倉庫(Repository)docker
倉庫時用來存放鏡像的地方,Docker hub是docker官方提供的倉庫,相似於githhub,,經過push推送鏡像到倉庫,經過pull命令拉取鏡像。固然咱們也可使用其餘倉庫,或者本身搭建一個倉庫。npm
docker是運行在Linux系統上的,在Windows上使用docker默認要用到Hyper-V功能,因此咱們在Windows系統上安裝Docker必須先開啓Hyper-V功能。首先打開【控制面板】,找到【啓動或關閉Windows功能】,而後勾選【Hyper-V】,點擊肯定便可安裝Hyper-V。windows
安裝好Hyper-V後,到docker官網下載Windows版本的docker,docker須要登陸帳戶才能下載,咱們能夠建立一個帳戶,牢記這個帳號,咱們之後會常常用到。docke下載地址:docker下載。下載完成後,雙擊安裝包,一路next便可。安裝完成後須要重啓電腦,打開命令行,輸入 docker run hello-world ,若是出現如下界面,表示docker已經安裝成功了。docker run hello-world命令首先會在本地找名字爲hello-world的鏡像,若是本地不存在這個鏡像就會從docker hub上拉取hello-world鏡像,而後運行。
Linux系統安裝經常使用軟件都十分方便,執行下邊的命令便可安裝docker
#刪除舊版本 sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine #安裝一些須要的工具 yum install -y yum-utils device-mapper-persistent-data lvm2 #添加軟件源信息 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #更新yum緩存 yum makecache fast #安裝docker yum -y install docker-ce #啓動docker服務 systemctl start docker #測試docker docker run hello-world
安裝完成後執行 docker run hello-world命令,若是出現下邊的界面表示docker安裝成功了
能夠查看官方教程詳細地瞭解docker的使用,這裏咱們先用兩分鐘分鐘展現一下微軟官方提供的docker栗子,執行命令 docker run -p 8000:80 --name aspnetcore_sample mcr.microsoft.com/dotnet/core/samples:aspnetapp ,-p 8000:80表示將服務器的8000端口和容器的80端口創建映射,訪問服務器8000端口時會去訪問容器的80端口。--name設置鏡像的名字
打開瀏覽器,訪問虛擬機的8000端口以下,說明咱們的容器已經成功啓動了!
咱們使用 docker images 和 docker container ls 查看一下本機的容器和鏡像,結果以下:
其實咱們實際開發中能用到的docker命令並很少,這裏簡單彙總一下最經常使用的docker命令。
## 查看docker版本和信息 #查看docker-cli的版本 docker --version #查看docker版本和信息 docker version docker info ## docker鏡像相關命令 #拉取鏡像 docker pull [imgName:tag] #運行鏡像,執行後會生成一個容器 docker run [imgName:tag/imgID] #查看全部的鏡像 docker images #刪除鏡像 執行rmi命令前必須刪除全部該鏡像的container docker rmi [imgName:tag/imgID] #查看全部的容器,沒有-a表示查詢全部正在運行中的容器 docker container ls -a #查看docker正在運行和已經中止的容器 docker ps -a #啓動容器 docker start [ctnName/cID] #中止容器 docker stop [ctnName/cID] #刪除容器,執行rm命令前必須先中止該容器 docke rm [ctnName/cID] ##清理鏡像和容器 #刪除全部的鏡像和容器 docker kill $(docker ps -q) ; docker rm $(docker ps -a -q) ; docker rmi $(docker images -q -a) #刪除全部的容器 docker kill $(docker ps -q) ; docker rm $(docker ps -a -q) #清除名稱爲none的鏡像 docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker stop docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker rm docker images|grep none|awk '{print $3 }'|xargs docker rmi
有時候咱們須要和容器交互,可使用命令 docker exec -it [name/id] common 。如咱們啓動一個mysql容器mysqlx1,執行 docker exec -it mysqlx1 mysql -p 表示和容器mysqlx1交互,執行的命令是【mysql -p】進行登陸,以下所示。 Ctrl +p+q 退出容器,回到服務器目錄。
大多數用戶使用docker的核心目的是更方便的交付項目,就是將咱們的應用程序構建成鏡像,而後交付鏡像便可,這裏演示怎麼構建一個Aspnet core項目的鏡像。
咱們建立一個Asp net core MVC項目,項目名爲DockerDemo,爲了方便不勾選Https和Docker支持,以下:
簡單修改首頁,運行一下,測試項目沒有bug,運行首頁以下:
發佈項目,而後在發佈文件夾下添加Dockerfile文件,結構以下:
Dockerfile的內容以下:
#拉取runtime父鏡像,運行aspnet core應用必需要用runtime FROM microsoft/dotnet:2.2-aspnetcore-runtime #設置容器工做目錄 WORKDIR /DockerDemo #把當前目錄的全部文件copy到工做目錄中 COPY . /DockerDemo #暴露一個端口讓外部能夠訪問 EXPOSE 8080 #容器入口命令,即容器啓動時執行dotnet DockerDemo.dll命令 ENTRYPOINT ["dotnet", "DockerDemo.dll"]
Dockerfile常見指令簡單說明
Dockerfile經常使用指令: #FROM:一般狀況下,咱們建立的鏡像時基於另一個鏡像的,這時就要用FROM,固然咱們也能夠徹底從頭建立 #WORKDIR:設置容器的工做目錄 #MAINTAINER:該鏡像的維護人 #COPY:常常須要把源碼複製到容器中,只用COPY就能夠實現這一點 #RUN:這裏能夠定義一些須要運行的命令,執行的目錄是WORKDIR。如npm install ,dotnet restore,dotnet run等 #ENTRYPOINT:定義容器的入口,一般是一些dotnet/node等命令,如dotnet xxx.dll #CMD:設置容器運行的默認命令和參數,即容器啓動時執行的命令。當容器運行時,能夠經過命令行覆蓋CMD定義的命令 #EXPOSE:暴露端口 #ENV:設置環境變量
docker建立鏡像很簡單,執行 docker build -t dockerdemo:v1.0 . 命令便可建立鏡像,其中dockerdemo:v1.0是鏡像的名字和版本tag,名字和tag能夠隨便設置。而後經過 docker images 命令查看全部鏡像,以下:
使用命令 docker run -d -p 8080:8080 dockerdemo:v1.0 啓動容器,-d 表示後臺運行,-p 8080:80表示服務器的8080端口映射到容器的80端口,咱們也可使用服務器的其餘端口,容器的端口爲Dockerfile中Expose的端口。執行 docker container ls 查看容器,這裏咱們的容器已經啓動了,以下:
打開瀏覽器,輸入【服務器IP:服務器端口】接口訪問容器,以下:
到這一步,本地建立鏡像和運行容器成功了。
docker提供了遠程倉庫用於存儲和分發鏡像,其做用相似於github,區別在於github託管代碼,而docker hub託管鏡像。咱們建立好了鏡像能夠推送(push)到遠程倉庫,而後在其餘設備上拉取(pull)鏡像,有了docker hub咱們能夠更方便的管理和分發鏡像。docker hub的使用很是簡單,只記住三個命令就能夠了
#標記鏡像,就是設置遠程鏡像名和標記 docker tag localname:localtag dockeruser/repname:reptag #推送鏡像文件到docker hub docker push username/repname:reptag #拉取遠程鏡像 docker pull repname:reptag #注:localname是本地鏡像名 localtag是本地鏡像tag # repname遠程倉庫的鏡像名 reptag是遠程倉庫的tag # username是咱們的dockerhub用戶名
這裏將上邊建立的本地鏡像推進到docker hub。 使用命令 docker tag dockerdemo:v1.0 wyyxxx/resdockerdemo:v1.0 標記,使用命令 docker push wyyxxx/resdockerdemo:v1.0 推進鏡像到遠程倉庫,打開 鏡像倉庫,登錄後就能夠看到咱們自定義的鏡像了,以下所示。
而後使用另外一臺安裝了docker的服務器,執行命令 docker run -p 8080:8080 wyyxxx/resdockerdemo:v1.0 拉取遠程鏡像並啓動 ,打開瀏覽器輸入地址,以下:
咱們在經過拉取遠程鏡像並運行容器時,不須要事先部署環境(如安裝runtime)等,由於鏡像中已經設置了須要的全部環境和依賴資源,只須要使用 docker run 命令運行便可。這也是使用容器交付的方便之處。
① 「3C原則」一個容器只運行一個應用
② 使用鏡像交付應用程序,而不是直接部署
若是要在centos上部署一個aspnet core應用程序。錯誤的作法是:在docker中先安裝一個centos系統,在centos系統中部署環境,而後部署咱們的netcore應用程序,,最後把部署的應用程序生成鏡像。正確的作法是經過Dockerfile定義咱們須要的環境和依賴項,而後生成鏡像,經過鏡像去分發和執行。
③ 分層構建鏡像
仍是上邊centos部署netcore應用的栗子,若是從零定製鏡像時,咱們應該把centos做爲一層鏡像,環境runtime做爲一層鏡像,最後咱們的應用作爲一層鏡像,使用Dockerfile的FROM 指令拉取父鏡像。這樣作的好處是節省空間和複用鏡像。如上邊咱們使用了2.2版本的runtime鏡像,當咱們建立了另外一個web應用再來定製鏡像時,這兩個應用程序鏡像能夠 共用同一個runtime鏡像。
④ 不要把數據存儲在容器中
容器是隨時可能銷燬的,銷燬後容器內部的數據就不存在了,因此最好不要在容器中存儲須要持久化的數據。