首頁>技術>

一:Docker介紹

• Docker簡介

Docker是2013發起的一個專案,早在2013年,Docker自誕生起,就是整個技術界的明星專案,很多技術媒體宣稱docker是一項技術突破,並且是一次技術革命。

Docker是一個雲開源專案,託管在github,任何人都可以通過 git clone 或者fork參與進來,本身是基於linux的容器技術,採用當時如日中天google新推出的Go語言實現。採用apache 2.0協議開源。

Docker的是一個輕量級的作業系統虛擬化解決方案。 主要目標,用官網的概括來說就是“Build,Ship and Run Any App,Anywhere”:編譯,裝載任何App,在任何地方都可以執行,我們大概理解就是一個容器,實現了對應用的封裝,部署,執行等生命週期管理,只要在glibc的環境下,到處都可以執行。


容器有效的將單個作業系統管理的資源劃分到孤立的組中,以便更好的在孤立的組之間平衡有衝突的資源使用需求。與虛擬化相比,這樣既不需要指令級模擬,也不需要即時編譯。容器可以在核心CPU本地執行指令,而不需要任何專門的解釋機制。此外,也避免了準虛擬化(paravirtualization)和系統呼叫替換中的複雜性。

簡而言之就是,Docker是一個盒子,一個盒子裝一個玩具,無論你丟在哪裡,你給他通電(glibc),他就能執行。你的玩具大就用大盒子,小玩具就用小盒子。

兩個應用之間的環境是環境是完全隔離的,建立通訊機制來互相呼叫。容器的建立和停止都十分快速(秒級),容器自身對資源的需求十分有限,遠比虛擬機器本身佔用的資源少。

• Docker 內部

要理解 Docker 內部構建,需要理解以下三種部件:

Docker 映象 - Docker images

Docker 倉庫 - Docker registeries

Docker 容器 - Docker containers

(1) Docker 映象

Docker 映象是 Docker 容器執行時的只讀模板,每一個映象由一系列的層 (layers) 組成。Docker 使用 UnionFS 來將這些層聯合到單獨的映象中。UnionFS 允許獨立檔案系統中的檔案和資料夾(稱之為分支)被透明覆蓋,形成一個單獨連貫的檔案系統。正因為有了這些層的存在,Docker 是如此的輕量。當你改變了一個 Docker 映象,比如升級到某個程式到新的版本,一個新的層會被建立。因此,不用替換整個原先的映象或者重新建立(在使用虛擬機器的時候你可能會這麼做),只是一個新 的層被新增或升級了。現在你不用重新發布整個映象,只需要升級,層使得分發 Docker 映象變得簡單和快速。

(2) Docker 倉庫

Docker 倉庫用來儲存映象,可以理解為程式碼控制中的程式碼倉庫。同樣的,Docker 倉庫也有公有和私有的概念。公有的 Docker 倉庫名字是 Docker Hub。Docker Hub 提供了龐大的映象集合供使用。這些映象可以是自己建立,或者在別人的映象基礎上建立。Docker 倉庫是 Docker 的分發部分。官方的Docker倉庫地址如下:/file/2019/11/23/20191123054255_41163.jpg Docker 公司維護,上面有數以萬計的映象,使用者可以自由下載和使用

(3)Docker 容器

Docker 容器和資料夾很類似,一個Docker容器包含了所有的某個應用執行所需要的環境。每一個 Docker 容器都是從 Docker 映象建立的。Docker 容器可以執行、開始、停止、移動和刪除。每一個 Docker 容器都是獨立和安全的應用平臺,Docker 容器是 Docker 的執行部分。

二:Mac Docker開發環境搭建

官方下載地址誰用誰知道,百度雲:連結:/file/2019/11/23/20191123054255_41164.jpg 密碼:9uly

Docker for Mac一步到位,不需要使用命令進行安裝。安裝完成之後,鯨魚的小圖標出現了。

開啟終端:

註冊Docker hub

/file/2019/11/23/20191123054256_41165.jpg ID用來存放自己的映象.

註冊完成之後,建立自己的Docker倉庫。分為共有和私有,大家根據自己的需要建立即可。

三:Golang Docker部署使用

先在本地生成一個映象,在pull到Dockerhub,然後在伺服器push這個映象,執行。

在本地列出已經下載下來的映象,可以使用 docker images 命令。

下面我們開始正式將我們的Go進行Docker化部署。

(1)main.go檔案我們簡單的實現一個伺服器

package main​import (​ "fmt"​ "net/http"​)​​func handler(rw http.ResponseWriter, req *http.Request) {​ fmt.Fprintf(rw, "hello world, %s", req.URL.Path[1:])​}​func main() {​ http.HandleFunc("/", handler)​ http.ListenAndServe(":8080", nil)​}

監聽8080埠,訪問時返回hello world + 請求引數,功能很簡單。

(2)Dockerfile檔案

Dockerfile 是一個文字檔案,其內包含了一條條的指令(Instruction),每一條指令構建一層,因此每一條指令的內容,就是描述該層應當如何構建。

FROM golang​ADD . $GOPATH/src/firstdocker​WORKDIR $GOPATH/src/firstdocker ​RUN go install firstdocker ​ ​ENTRYPOINT /go/bin/firstdocker​ ​EXPOSE 8080

• FROM 指定基礎映象

所謂定製映象,那一定是以一個映象為基礎,在其上進行定製。而 FROM 就是指定基礎映象,因此一個 Dockerfile 中 FROM 是必備的指令,並且必須是第一條指令。這裡是指定golang的環境。

• ADD

如果 <源路徑> 為一個 tar 壓縮檔案的話,壓縮格式為 gzip, bzip2 以及 xz 的情況下,ADD 指令將會自動解壓縮這個壓縮檔案到 <目標路徑> 去。

在 Docker 官方的最佳實踐文件中要求,儘可能的使用 COPY,因為 COPY 的語義很明確,就是複製檔案而已,而 ADD 則包含了更復雜的功能,其行為也不一定很清晰。最適合使用 ADD 的場合,就是所提及的需要自動解壓縮的場合。

另外需要注意的是,ADD 指令會令映象構建快取失效,從而可能會令映象構建變得比較緩慢。

因此在 COPY 和 ADD 指令中選擇的時候,可以遵循這樣的原則,所有的檔案複製均使用 COPY 指令,僅在需要自動解壓縮的場合使用 ADD。

• WORKDIR 指定工作目錄

格式為WORKDIR <工作目錄路徑>。

使用WORKDIR指令可以來指定工作目錄(或者稱為當前目錄),以後各層的當前目錄就被改為指定的目錄,如該目錄不存在,WORKDIR會幫你建立目錄。

每一個 RUN都是啟動一個容器、執行命令、然後提交儲存層檔案變更。第一層 RUN cd /app 的執行僅僅是當前程序的工作目錄變更,一個記憶體上的變化而已,其結果不會造成任何檔案變更。而到第二層的時候,啟動的是一個全新的容器,跟第一層的容器更完全沒關係,自然不可能繼承前一層構建過程中的記憶體變化。

因此如果需要改變以後各層的工作目錄的位置,那麼應該使用 WORKDIR指令。

• RUN 執行命令

RUN指令是用來執行命令列命令的。由於命令列的強大能力,RUN 指令在定製映象時是最常用的指令之一。其格式有兩種:

shell 格式:RUN <命令>,就像直接在命令列中輸入的命令一樣。剛才寫的 Dockrfile 中的 RUN 指令就是這種格式。

RUN go install firstdocker

exec 格式:RUN ["可執行檔案", "引數1", "引數2"],這更像是函式呼叫中的格式。

既然 RUN 就像 Shell 指令碼一樣可以執行命令,那麼我們是否就可以像 Shell 指令碼一樣把每一層構建需要的命令寫出來,比如這樣:

FROM debian:jessie​ ​RUN buildDeps='gcc libc6-dev make' \\​• && apt-get update \\​• && apt-get install -y $buildDeps \\​• && wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \\​• && mkdir -p /usr/src/redis \\​• && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \\​• && make -C /usr/src/redis \\​• && make -C /usr/src/redis install \\​• && rm -rf /var/lib/apt/lists/* \\​• && rm redis.tar.gz \\​• && rm -r /usr/src/redis \\​• && apt-get purge -y --auto-remove $buildDeps

僅僅使用一個 RUN指令,並使用&&將各個所需命令串聯起來。在撰寫 Dockerfile 的時候,要經常提醒自己,這並不是在寫 Shell 指令碼,而是在定義每一層該如何構建。

並且,這裡為了格式化還進行了換行。Dockerfile 支援 Shell 類的行尾新增 \\的命令換行方式,以及行首#進行註釋的格式。良好的格式,比如換行、縮排、註釋等,會讓維護、排障更為容易,這是一個比較好的習慣。

此外,還可以看到這一組命令的最後添加了清理工作的命令,刪除了為了編譯構建所需要的軟體,清理了所有下載、展開的檔案,並且還清理了 apt 快取檔案。這是很重要的一步,我們之前說過,映象是多層儲存,每一層的東西並不會在下一層被刪除,會一直跟隨著映象。因此映象構建時,一定要確保每一層只新增真正需要新增的東西,任何無關的東西都應該清理掉。

很多人初學 Docker 製作出了很臃腫的映象的原因之一,就是忘記了每一層構建的最後一定要清理掉無關檔案。

• ENTRYPOINT

ENTRYPOINT命令指令指示/go/bin/firestwebapp設定為隨容器啟動

• EXPOSE宣告埠

EXPOSE 指令是宣告執行時容器提供服務埠,這只是一個宣告,在執行時並不會因為這個宣告應用就會開啟這個埠的服務。在 Dockerfile 中寫入這樣的宣告有兩個好處,一個是幫助映象使用者理解這個映象服務的守護埠,以方便配置對映;另一個用處則是在執行時使用隨機埠對映時,也就是 docker run -P時,會自動隨機對映 EXPOSE的埠。

要將 EXPOSE 和在執行時使用 -p <宿主埠>:<容器埠>區分開來。-p,是對映宿主埠和容器埠,換句話說,就是將容器的對應埠服務公開給外界訪問,而 EXPOSE僅僅是宣告容器打算使用什麼埠而已,並不會自動在宿主進行埠對映。

步驟:

(1)開始構建映象

docker build -t="[name]:[tag]" ./​docker build -t firstdocker .

(2)檢視映象

 docker images​ docker rmi firstdocker:class. //刪除 名稱:tag​ docker rmi firstdocker 6712bba50601 //刪除,使用ImageID

(3)執行映象

docker run -v [宿主目錄]:[映象目錄] -ti -p [宿主埠]:[映象埠] 映象名稱:版本

docker run -p 89:8080 --rm firstdocker

-p 80:8080標誌開啟HTTP埠80並將其對映至前面通過EXPOSE命令暴露的8080埠,而—rm標誌則指示Docker在容器已經存在的情況下,先移除已有的容器,然後再建立並啟動新容器。

(4)測試效果

這時候開啟瀏覽器http://localhost,可以看到成功輸出。

(5)將映象上傳

docker login

docker push 註冊使用者名稱/映象名

再去登入自己的dockerHub,就能看到上傳的映象

(6)伺服器拉去映象

docker pull 註冊使用者名稱/映象名

然後執行

 docker run -p 80:8080 --rm firstdocker

這個時候只需要在瀏覽器輸入您的ip地址就會有hello world

(7)docker ps //檢視已啟動容器

(8)docker stop 363e265c7e66 //關閉容器

使用上述的方式,上傳至Dockerhub的時候,會出現問題,程式碼修改為下面的即可。

docker build -t zh/firstdocker:test .docker push zh/firstdocker:testdocker pull 註冊使用者名稱/映象名docker run -p 89:8080 --rm firstdocker

其中zh是我的DockerHub的賬戶名。test是tag,用來標識這個映象。

Docker for Mac 版本,那麼所有的docker images 儲存在下面這個檔案裡。

/Users/ZH/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/Docker.qcow2

很不幸,截止到今天(2016年11月16日)你還沒有辦法指定images和container的儲存路徑,你只能任由docker吃掉你的磁碟。

下面我們將上傳到伺服器的Docker容器進行雲部署,這樣就可以直接訪問了。

操作步驟如下:

(1)配置好騰訊雲的docker,輸入docker version檢視

(2)docker login 登陸dockerhub,輸入使用者名稱和密碼

(3)docker pull zhuyuqiang/firstdocker:test 從伺服器拉取資料

(4)pull成功之後,使用docker images檢視

(5)輸入下面的命令啟動容器

docker run -p 80:8080 --rm docker.io/zhuyuqiang/firstdocker:test

(6)瀏覽器輸入ip以及埠號測試即可

(7)停止容器

docker stop 8cd24fcf9307

其中8cd24fcf9307為docker的CONTAINER ID

四:騰訊雲配置Docker

前提:騰訊雲:CentOS Linux release 7.2.1511 (Core)

(1)使用root使用者登陸騰訊雲,開始安裝docker步驟

(2)安裝配置Docker

# 安裝docker

yum install -y docker

中間會出現各種問題,學會使用goole進行搜尋解決。

[Errno 256] No more mirrors to try 解決方法

輸入下面的命令即可解決問題:

 yum clean all yum makecache

# 配置騰訊雲映象加速(官方的龜速)

vim /etc/sysconfig/docker

#新增如下引數:

OPTIONS='--registry-mirror=https://mirror.ccs.tencentyun.com'

#重啟docker服務:

systemctl restart docker

2、製作基礎映象

拉取 centos官方基礎映象​\tdocker pull centos ​\t檢視當前映象​\tdocker images [root@VM_0_9_centos /]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEdocker.io/centos latest 1e1148e4cc2c 4 weeks ago 202 MB 

執行並進入映象:

docker run -ti docker.io/centos:latest /bin/bash

此時,終端已經進入了映象裡面,現在我們可以根據自己的需求安裝額外的元件,比如我這次需要用到crontab任務計劃服務、程序守護supervisor等,那麼直接在這個終端開始操作:

[root@0d7f7b8769d9 /]# yum install -y epel-release crontabs[root@0d7f7b8769d9 /]# yum install -y python-pip[root@0d7f7b8769d9 /]# pip install --upgrade pip[root@0d7f7b8769d9 /]# pip install supervisor

上面的PS提示符中的 0d7f7b8769d9 就是本次啟動的 CONTAINER ID ,在下面的commit步驟即將用到。 完成必要元件安裝之後,按下 Ctrl +D 退出系統,接著使用 docker commit 命令建立新映象,比如命名為 nginx-proxy-base,版本latest:

docker commit 0d7f7b8769d9 centos/nginx-proxy-base:latest

儲存容器

檢視所有的容器資訊, 能獲取容器的id

docker ps -a

然後執行如下命令[?],儲存映象:

docker commit -m="備註" CONTAINER_ID IMAGE

執行完成後,可以使用 docker images 檢視剛建立的映象:

[root@VM_0_9_centos home]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEcentos/nginx-proxy-base latest ad1c1ce41689 6 seconds ago 272 MBdocker.io/centos latest 1e1148e4cc2c 4 weeks ago 202 MB

退出映象:exit到此,我們就建立了一個自定義的Docker基礎映象(基礎映象類似一個VM虛擬機器的快照,方便後續步驟都可以從這個基礎上重新制作)

這裡展示的是進入Docker裡面通過手工部署的方式,其實我們還可以通過DockerFile來完成上述所有操作,可以極大的減小Docker映象的體積。

啟動docker

service docker start

設定開機啟動

chkconfig docker on

Docker常用命令:

其中<>闊起來的引數為必選,[]闊起來為可選

 docker version 檢視docker的版本號,包括客戶端、服務端、依賴的Go等​ docker info 檢視系統(docker)層面資訊,包括管理的images, containers數等​ docker search 在docker index中搜索image​ docker pull 從docker registry server 中下拉image​ docker push 推送一個image或repository到registry​ docker push :TAG 同上,指定tag​ docker inspect 檢視image或container的底層資訊​ docker images TODO filter out the intermediate image layers (intermediate image layers 是什麼)​ docker images -a 列出所有的images​ docker ps 預設顯示正在執行中的container​ docker ps -l 顯示最後一次建立的container,包括未執行的​ docker ps -a 顯示所有的container,包括未執行的​ docker logs 檢視container的日誌,也就是執行命令的一些輸出​ docker rm 刪除一個或多個container​ docker rm `docker ps -a -q` 刪除所有的container​ docker ps -a -q | xargs docker rm 同上, 刪除所有的container​ docker rmi 刪除一個或多個image​ docker start/stop/restart 開啟/停止/重啟container​ docker start -i 啟動一個container並進入互動模式​ docker attach attach一個執行中的container​ docker run 使用image建立container並執行相應命令,然後停止​ docker run -i -t /bin/bash 使用image建立container並進入互動模式, login shell是/bin/bash​ docker run -i -t -p 將container的埠對映到宿主機的埠​ docker commit [repo:tag] 將一個container固化為一個新的image,後面的repo:tag可選​ docker build​ 尋找path路徑下名為的Dockerfile的配置檔案,使用此配置生成新的image​ docker build -t repo[:tag] 同上,可以指定repo和可選的tag​ docker build - 使用指定的dockerfile配置檔案,docker以stdin方式獲取內容,使用此配置生成新的image​ docker port 檢視本地哪個埠對映到container的指定埠,其實用docker ps 也可以看到​\tdocker build -t webservice .:表示使用當前目錄下的DockerFile來生成映象,-t引數的值表示映象的tagname,如果DockerFile在當前路徑下則使用.,如果不在當前路徑下則使用相對路徑。​\tdocker ps -a: 沒有-a引數表示顯示當前宿主機的正在執行的容器,加上-a表示顯示當前宿主機所有的容器,包括已經退出的容器。​\tdocker run -d -p 2222:22 --name base centos:7.1表示根據指定的映象後臺執行容器,容器的名字是base(--name就是指定容器的名字),centos:7.1表示映象的名字,-p引數表示當前宿主機的2222埠對應容器的22埠。-d引數表示(Run container in background and print container ID)​\tdocker exec -it base /bin/bash以互動式命令進入base容器並且執行/bin/bash命令​\tdocker rmi webservice:刪除webservice映象​\tdocker rm base: 刪除base容器,如果base正在執行,則可以使用\tdocker rm -f base進行強行刪除

使用ps -ef | grep docker檢視docker程序。

管理docker服務:

service docker start

service docker stop

service docker restart

啟動配置檔案儲存位置

Ubuntu: /etc/default/docker

CentOS: /etc/sysconfig/docker

  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Redis 在微博中的應用(一)