1. 程式人生 > 實用技巧 >Linux15 docker入門

Linux15 docker入門

什麼是docker

Docker 最初是 dotCloud 公司創始人 Solomon Hykes 在法國期間發起的一個公司內部專案,於 2013 年 3 月以 Apache 2.0 授權協議開源,主要專案程式碼在 GitHub 上進行維護。
Docker 使用 Google 公司推出的 Go 語言 進行開發實現。
docker是linux容器的一種封裝,提供簡單易用的容器使用介面。它是最流行的Linux容器解決方案。
docker的介面相當簡單,使用者可以方便的建立、銷燬容器。
docker將應用程式與程式的依賴,打包在一個檔案裡面。執行這個檔案就會生成一個虛擬容器。
程式執行在虛擬容器裡,如同在真實物理機上執行一樣,有了docker,就不用擔心環境問題了。

為什麼要用docker?

我們先看看很久很久以前,伺服器是怎麼部署應用的!

由於物理機的諸多問題,後來出現了虛擬機器

但是虛擬化也是有侷限性的,每一個虛擬機器都是一個完整的作業系統,要分配系統資源,虛擬機器多道一定程度時,作業系統本身資源也就消耗殆盡,或者說必須擴容

docker與虛擬機器的區別

docker VS 傳統虛擬機器

特性

容器

虛擬機器

啟動

秒級

分鐘級

硬碟使用

一般為 MB

一般為 GB

效能

接近原生

系統支援量

單機支援上千個容器

一般幾十個

環境配置的難題

讓開發人員最頭疼的麻煩事之一就是環境配置了,每臺計算機的環境都不相同,應該如何確保自己的程式換一臺機器能執行起來呢?

使用者必須確保的是:

  1. 作業系統的相同
  2. 各種平臺庫和元件的安裝
  3. 例如python依賴包,環境變數等

如何一些低版本的依賴模組和當前環境不相容,那就頭疼了。。。。。

如果環境配置這麼痛苦的話,換一臺機器,就得重新配置一下,那麼在安裝軟體的時候,帶著原始環境一模一樣的複製過來。

然而,開發和運維之間聊天一般是這樣的

解決方案一 虛擬機器

虛擬機器也可以製作模板,基於模板建立虛擬機器,保證環境問題一致

虛擬機器(virtual machine)就是帶環境安裝的一種解決方案。它可以在一種作業系統裡面執行另一種作業系統,比如在 Windows 系統裡面執行 Linux 系統。應用程式對此毫無感知,因為虛擬機器看上去跟真實系統一模一樣,而對於底層系統來說,虛擬機器就是一個普通檔案,不需要了就刪掉,對其他部分毫無影響。

雖然使用者可以通過虛擬機器還原軟體的原始環境。但是,這個方案有幾個缺點。

(1)資源佔用多

虛擬機器會獨佔一部分記憶體和硬碟空間。它執行的時候,其他程式就不能使用這些資源了。哪怕虛擬機器裡面的應用程式,真正使用的記憶體只有 1MB,虛擬機器依然需要幾百 MB 的記憶體才能執行。

(2)冗餘步驟多

虛擬機器是完整的作業系統,一些系統級別的操作步驟,往往無法跳過,比如使用者登入。

(3)啟動慢

啟動作業系統需要多久,啟動虛擬機器就需要多久。可能要等幾分鐘,應用程式才能真正執行。

解決方案二 Linux容器

現在:自從用上docker容器後,可以實現開發、測試和生產環境的統一化和標準化。

映象作為標準的交付件,可在開發、測試和生產環境上以容器來執行,最終實現三套環境上的應用以及執行所依賴內容的完全一致。

由於虛擬機器的諸多問題,Linux發展出了另一種虛擬化技術:Linux容器(Linux Containers,縮寫LXC)

Linux容器不是模擬一個完整的作業系統,而是對程序進行隔離。在正常程序的外面套了一個保護層,對於容器裡面程序來說,它接觸的資源都是虛擬的,從而實現和底層系統的隔離。

(1)啟動快

容器裡面的應用,直接就是底層系統的一個程序,而不是虛擬機器內部的程序。所以,啟動容器相當於啟動本機的一個程序,而不是啟動一個作業系統,速度就快很多。

(2)資源佔用少

容器只佔用需要的資源,不佔用那些沒有用到的資源;虛擬機器由於是完整的作業系統,不可避免要佔用所有資源。另外,多個容器可以共享資源,虛擬機器都是獨享資源。

(3)體積小

容器只要包含用到的元件即可,而虛擬機器是整個作業系統的打包,所以容器檔案比虛擬機器檔案要小很多。

總之,容器有點像輕量級的虛擬機器,能夠提供虛擬化的環境,但是成本開銷小得多。

docker容器的優勢

更高效的利用系統資源
由於容器不需要進行硬體虛擬以及執行完整作業系統等額外開銷,Docker 對系統 資源的利用率更高。
無論是應用執行速度、記憶體損耗或者檔案儲存速度,都要比傳 統虛擬機器技術更高效。因此,相比虛擬機器技術,一個相同配置的主機,往往可以運 行更多數量的應用。
更快速的啟動時間
傳統的虛擬機器技術啟動應用服務往往需要數分鐘,而 Docker 容器應用,由於直接 運行於宿主核心,無需啟動完整的作業系統,因此可以做到秒級、甚至毫秒級的啟 動時間。大大的節約了開發、測試、部署的時間。
一致的執行環境
開發過程中一個常見的問題是環境一致性問題。由於開發環境、測試環境、生產環 境不一致,導致有些 bug 並未在開發過程中被發現。
而 Docker 的映象提供了除內 核外完整的執行時環境,確保了應用執行環境一致性,從而不會再出現 “這段程式碼 在我機器上沒問題啊” 這類問題。
持續交付和部署
對開發和運維(DevOps)人員來說,最希望的就是一次建立或配置,可以在任意 地方正常執行。
使用 Docker 可以通過定製應用映象來實現持續整合、持續交付、部署。開發人員 可以通過 Dockerfile 來進行映象構建,並結合 持續整合(Continuous Integration) 系 統進行整合測試,
而運維人員則可以直接在生產環境中快速部署該映象,甚至結合 持續部署(Continuous Delivery/Deployment) 系統進行自動部署。
而且使用 Dockerfile 使映象構建透明化,不僅僅開發團隊可以理解應用執行環 境,也方便運維團隊理解應用執行所需條件,幫助更好的生產環境中部署該映象。
更輕鬆的遷移
由於 Docker 確保了執行環境的一致性,使得應用的遷移更加容易。Docker 可以在 很多平臺上執行,無論是物理機、虛擬機器、公有云、私有云,甚至是筆記本,其運 行結果是一致的。
因此使用者可以很輕易的將在一個平臺上執行的應用,遷移到另一 個平臺上,而不用擔心執行環境的變化導致應用無法正常執行的情況。

工作中的虛擬化和容器

docker三大概念

容器三大基本概念
映象 image
容器 container
倉庫 repository (存放映象檔案的地方) 我可以去公網去,下載映象
docker整個生命週期就是這三個概念。

docker映象

Docker映象就是一個只讀的模板。

例如:一個映象可以包含一個完整的CentOS作業系統環境,裡面僅安裝了Apache或使用者需要的其他應用程式。

映象可以用來建立Docker容器。

Docker提供了一個很簡單的機制來建立映象或者更新現有的映象,使用者甚至可以直接從其他人那裡下載一個已經做好的映象來直接使用。

image的分層儲存

因為映象包含完整的root檔案系統,體積是非常龐大的,因此docker在設計時按照Union FS的技術,將其設計為分層儲存的架構。
映象不是ISO那種完整的打包檔案,映象只是一個虛擬的概念,他不是一個完整的檔案,而是由一組檔案組成,或者多組檔案系統聯合組成。

docker容器(container)

image和container的關係,就像面向物件程式設計中的 類和例項一樣,映象是靜態的定義(class),容器是映象執行時的實體(object)。
容器可以被建立、啟動、停止、刪除、暫停
Docker利用容器來執行應用。

容器是從映象建立的執行例項。它可以被啟動、開始、停止、刪除。每個容器都是相互隔離的,保證安全的平臺。

可以把容器看做是一個簡易版的Linux環境(包括root使用者許可權、程序空間、使用者空間和網路空間等)和執行在其中的應用程式。

注意:映象是隻讀的,容器在啟動的時候建立一層可寫層作為最上層。

docker倉庫(repository)

倉庫是集中存放映象檔案的場所。有時候把倉庫和倉庫註冊伺服器(Registry)混為一談,並不嚴格區分。實際上,倉庫註冊伺服器上往往存放著多個倉庫,每個倉庫中又包含了多個映象,每個映象有不同的標籤(tag)。

倉庫分為公開倉庫(Public)和私有倉庫(Private)兩種形式。

最大的公開倉庫是Docker Hub,存放了數量龐大的映象供使用者下載。國內的公開倉庫包括Docker Pool等,可以提供大陸使用者更穩定快讀的訪問。

當用戶建立了自己的映象之後就可以使用push命令將它上傳到公有或者私有倉庫,這樣下載在另外一臺機器上使用這個映象時候,只需需要從倉庫上pull下來就可以了。

注意:Docker倉庫的概念跟Git類似,註冊伺服器可以理解為GitHub這樣的託管服務。

docker Registry

Docker Registry 公開服務是開放給使用者使用、允許使用者管理映象的 Registry 服 務。一般這類公開服務允許使用者免費上傳、下載公開的映象,並可能提供收費服務 供使用者管理私有映象。
最常使用的 Registry 公開服務是官方的 Docker Hub,這也是預設的 Registry,並 擁有大量的高質量的官方映象。

除此以外,還有 CoreOS 的 Quay.io,CoreOS 相 關的映象儲存在這裡;Google 的 Google Container Registry,Kubernetes 的映象 使用的就是這個服務。 由於某些原因,在國內訪問這些服務可能會比較慢。
國內的一些雲服務商提供了針 對 Docker Hub 的映象服務(Registry Mirror),這些映象服務被稱為加速器。常見 的有 阿里雲加速器、DaoCloud 加速器、靈雀雲加速器等。
使用加速器會直接從國內的地址下載 Docker Hub 的映象,比直接從官方網站下載速度會提高很多。在後 面的章節中會有進一步如何配置加速器的講解。 國內也有一些雲服務商提供類似於 Docker Hub 的公開服務。比如 時速雲映象倉 庫、網易雲映象服務、DaoCloud 映象市場、阿里雲映象庫等。

CentOS安裝docker(兩種方式)

1.編譯安裝,原始碼安裝
	1.解除安裝舊版本
	sudo yum remove docker \
					  docker-client \
					  docker-client-latest \
					  docker-common \
					  docker-latest \
					  docker-latest-logrotate \
					  docker-logrotate \
					  docker-selinux \
					  docker-engine-selinux \
					  docker-engine

	2.設定儲存庫
	sudo yum install -y yum-utils \
	  device-mapper-persistent-data \
	  lvm2

	sudo yum-config-manager \
		--add-repo \
		https://download.docker.com/linux/centos/docker-ce.repo

	3.安裝docker社群版
	sudo yum install docker-ce
	4.啟動關閉docker
	systemctl start docker

2.yum安裝
	#如果網速太慢,你可以選擇阿里雲的源,缺點就是版本低
	#你可以選擇用aliyun的yum源,docker就存在epel源中
	#如果網速夠快,或者在公司中,一定要裝官方源
	#配置docker的官方源,一定是官方的最好啊
	
	
	#由於配置不了官方的docker倉庫,咱們選擇阿里雲
	1.yum install docker* docker-*  -y  #安裝docker服務端
	2.啟動docker
	systemctl start docker 
	
	systemctl status  docker 

3.檢視docker是否正確安裝

docker version

4.簡單使用docker

docker search hello-world #搜尋hello-workd
docker pull hello-world #下載hello-workd
docker images #檢視映象
docker run 映象名/映象id(可以寫前三位) #執行一個docker容器例項
docker ps #檢視docker程序
docker ps -a #檢視所有執行過的docker容器記錄

5.rpm安裝 #docker映象加速器

curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io

#其實就是更改了,docker的一個倉庫源
[root@node1 /opt/redis-4.0.10/src 14:48:26]#cat /etc/docker/daemon.json
{
    "registry-mirrors": [
        "http://95822026.m.daocloud.io"
    ],
    "insecure-registries": []
}

docker常用命令: 

增加(增加容器與啟動容器)

docker run 映象id/映象名  #執行建立一個容器container例項

docker run -it  centos   #此命令會 進入到容器空間內,進入到容器的centos中
-i 互動式介面
-t 是開啟一個終端

docker run -it  --rm  ubuntu   #執行一個烏班圖容器,並且在退出是,刪除容器執行記錄

docker run centos   
#直接執行這個centos映象,會生成一個容器記錄
#此時就會生成一個容器記錄,但是容器中並沒有任何的後臺程式,因此直接就掛掉
# 你會發現,容器死活不生成,docker ps 看不到記錄,

docker run -d centos /bin/sh -c "while true;do echo hello s14 docker~~~~; sleep 1;done"
#一定會生成一個容器記錄
#docker ps  能不能看到記錄?

-d 引數是  後臺執行
/bin/sh  呼叫shell直譯器
-c 指明一段shell語法

docker pull centos  #下載docker的映象

刪除 

docker rm 容器id  #docker rm刪除的是已經停止的容器id

docker rmi  映象id   #刪除一個映象記錄 

docker rm `docker ps -aq` # 一次性刪除所有容器id記錄
	` `   #反引號是取命令的執行結果 

docker rmi `docker images -aq`   #一次性刪除所有映象記錄

修改

docker commit  #提供容器記錄,為新的映象
docker stop  容器id  #停止正在執行的容器
docker start 容器id  #啟動一個關閉中的容器

#匯出映象
docker save centos > /opt/centos.tar.gz  #匯出docker映象至本地

#匯入映象
docker load < /opt/centos.tar.gz
#通過--name引數給容器記錄,加上別名
docker run --name s14hehe -d centos /bin/sh -c "while true;do echo hello s14 docker~~~~; sleep 1;done"

#進入正在執行的容器
docker exec -it c49  /bin/bash

-it  互動式的操作終端
/bin/bash使用shell直譯器,只有在redhat,centos系統中,才能用/bin/bash  

檢視

docker image  ls  #檢視映象記錄
docker images  #檢視映象記錄 

docker ps    #檢視容器記錄  ,只能檢視到正在執行中的容器
		     #正在執行中的容器,代表,容器後臺一定有個程序在執行
			 
docker ps -a #檢視停止的和在執行的容器記錄

docker container ls -a  #等同於docker ps -a 

docker logs -f 容器id  #檢視正在執行中的 容器內日誌
-f  不間斷列印 

#示例: 提交自定義的映象檔案(自己修改了容器記錄,提交成一個新的映象,可以發給別人使用)

1.預設的centos映象,沒有vim 
2.我們自己run一個容器記錄,安裝vim,然後提交成新的映象檔案
docker commit cd6f77ac634c  wind/centos-vim
3.檢視新的映象記錄
docker images  
wind/centos-vim         latest               9e40b6cbc9a0        7 seconds ago       327 MB
4.可以通過新的帶有vim的映象執行容器記錄,通過此方法可以解決環境難配置的問題
docker run -it wind/centos-vim    /bin/bash 

docker基本命令分類

映象
docker image ls
docker images
docker pull 映象名  	#docker倉庫,dockerhub
docker push 映象名    #把本地的映象推送到 dockerhub倉庫
docker search 映象名
docker rmi  刪除映象
docker version #檢視docker版本,檢視到server 和client兩個端
systemctl start docker   #啟動docker
docker save  映象名  >  /data/centos.tar.gz  #匯出映象
docker load  <  /data/centos.tar.gz  #匯入映象    
docker run  映象名  #執行映象檔案,產生一個容器例項


容器
docker start 容器id 
docker stop 容器id
docker exec -it   容器id #進入正在執行的容器
	-i 互動式操作
	-t  開啟一個終端

docker run 映象名 #建立容器例項
docker rm  容器id  #刪除容器記錄,必須提前docker stop 容器id ,只能殺死已經停止的容器
docker ps  #檢視容器正在執行記錄
docker ps -aq  #顯示所有容器記錄的id號
	-a  顯示所有容器記錄
	-q	 顯示容器id
	
docker rm  `docker ps -aq`  #一次性刪除所有容器記錄

docker container ls  #檢視容器正在執行記錄
docker commit  容器id記錄  #提交這個容器,建立一個新的映象
docker logs  #檢視容器執行日誌 
	-f   #不間斷列印容器日誌
	
docker port   #檢視容器的埠對映關係(外部訪問到容器內的埠)
docker run -d  centos  -P  
-d 後臺執行
-P   隨機對映埠  
-p  9000(宿主機):5000(容器內) 
--name   給建立的容器記錄,新增別名


倉庫
1.docker pull 

2.docker run    #如果沒有這個映象,直接docker run 它也會內部去下載這個映象

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
   - 優先使用ADD命令
    -ADD除了COPY功能還有解壓功能
新增遠端檔案/目錄使用curl或wget

ENV #環境變數,儘可能使用ENV增加可維護性
ENV MYSQL_VERSION 5.6 #設定一個mysql常量
RUN yum install -y mysql-server=“${MYSQL_VERSION}” 

 RUN ./cofigure --prefix=/opt/
 RUN make&& make install

dockerfile實驗

首先, mkdir mydocker , cd mydocker , touch Dockerfile(固定名稱) ,touch myflask.py

1.準備一個flask程式碼,準備python程式碼, vim myflask.py

from flask import Flask
app=Flask(__name__)
@app.route('/')
def hello():
	return "hello docker,i am  cj, i am in huainan "
if __name__=="__main__":
	app.run(host='0.0.0.0',port=8080)

2.準備Dockerfile,準備好所有需要的檔案

2.1 touch 4個檔案  CentOS-Base.repo  Dockerfile  epel.repo  myflask.py
[root@node1 /data/mydocker 10:33:53]#ls
CentOS-Base.repo  Dockerfile  epel.repo  myflask.py

2.2 vim Dockerfile
	FROM centos
	LABEL maintainer="Bo Jie<[email protected]>"
	ADD CentOS-Base.repo /etc/yum.repos.d/
	ADD epel.repo /etc/yum.repos.d/
	RUN yum clean all
	RUN yum install python2-pip -y
	RUN pip2 install -i https://pypi.tuna.tsinghua.edu.cn/simple flask
	COPY myflask.py /app/
	WORKDIR /app
	EXPOSE 8080
	CMD ["python","myflask.py"]
	
	#說明:
	1.引入一個centos映象,為基礎映象
	2.作者註釋資訊
	3.新增本地的兩個yum檔案,到容器的/etc/yum.repos.d/底下
	4.清空yum快取
	5.yum安裝pip工具
	6.pip安裝flask模組,指定清華源
	7.拷貝本地的flask程式碼,到容器的/app/目錄下
	8.切換工作目錄,到/app底下
	9.暴露容器的8080埠,然後在執行映象時候,加上-p引數,指定埠對映
	10.執行命令,執行flask

3.構建docker映象檔案

docker build -t bojie/wind-flask-docker . (注意末尾有個.)
#構建當前目錄的Dcokerfile,然後構建出一個名為bojie/wind-flask-docker 這個的映象檔案
-t  tag引數,給映象加上標記名

dockerhub賬戶名:bojie
dockerhub賬戶名/映象名   #是為了後面講docker映象,推送到dockerhub

4.檢視映象是否構建完成

docker images 

5.執行這個映象檔案,產生容器例項

docker run -p 9000:8080   -d 43d
-p  對映9000埠到容器的8080
-d 後臺執行 
43d  映象id

6.檢視已經執行的docker例項

docker ps 

7.學習dockerhub,釋出自己的docker映象

1.我可以先下載其他人的docker映象

docker pull yuchao163/hello-world-docker

2.上傳自己的docker映象 
	docker login  #登入自己的docker hub賬號 ,輸入密碼 
	#docker就會有你自己的dockerhub賬號資訊  bojie
	
3.更改docker映象的名字,也就是加上一個tag標記
	docker tag wind/centos-vim  bojie/wind-centos-vim
	docker tag  現有映象名字     dockerhub賬戶名/新的映象名
4.登入後可以推送映象檔案,此時推送給的是自己的yuchao163賬號倉庫下
	docker push bojie/wind-centos-vim
	
5.登入https://hub.docker.com/檢視自己推送的公網映象

構建公司私有docker倉庫,其實就是搭建一個api伺服器,通過api可以下載映象

1.下載docker官方提供的私有倉庫映象

docker pull  registry

2.檢視映象

docker images 

3.啟動一個私有倉庫容器

docker run -d -p 5000:5000 -v /opt/data/registry:/var/lib/registry registry
解釋: docker run -p 8000:8080 -v /opt/s14:/opt/data/ -d 43d
        啟動容器,通過-v引數掛載,掛載容器內的/opt/data/資料夾,其實訪問的是宿主機的/opt/s14/

4.此時可以檢查容器程序  

docker ps

5.此時私有倉庫就打開了5000埠,通過埠對映,訪問宿主機的5000埠,檢視是否通訊

yum install telnet -y 
	
telnet 127.0.0.1 5000   #檢測5000埠是否通訊

6.修改本地映象的tag標籤,標註我要往哪push映象

docker tag bojie/wind-centos-vim 192.168.0.102:5000/bojie-vim

7.修改docker配置,允許非安全的傳輸方式

1.vim /etc/docker/daemon.json,寫入資訊,私有倉庫地址,都得改成自己的
	{"registry-mirrors": ["http://95822026.m.daocloud.io"],
	"insecure-registries":["192.168.0.102:5000"]
	}
2.修改docker.server 
	vim /lib/systemd/system/docker.service
	#寫入如下資訊,請在[service]中寫入		
	[Service]
	EnvironmentFile=/etc/docker/daemon.json		

8.重啟docker服務,使得生效

systemctl daemon-reload #重新載入docker配置檔案

systemctl restart docker #重啟docker服務

9. #重啟docker服務,會停止容器,因此要再次啟動

docker ps -a 
docker start b23bcfe42e80 #啟動這個私有倉庫容器

  

10.推送本地映象到 私有倉庫 192.168.0.102:5000

docker push 192.168.0.102:5000/bojie-vim

  


11.此時訪問api介面,檢視私有倉庫的資料

http://192.168.0.102:5000/v2/_catalog

  

docker的資料集掛載功能

-v 引數 掛載宿主機的檔案:容器內的資料夾 
-v /opt/data:/opt/s14/ 

docker run -p 8000:8080 -v /opt/s14:/opt/data/ -d 43d
啟動容器,通過-v引數掛載
掛載容器內的/opt/data/資料夾,其實訪問的是宿主機的/opt/s14/