Docker容器學習梳理 - 基礎知識(1)

散盡浮華發表於2016-03-08

 

Docker是PaaS 提供商 dotCloud 開源的一個基於 LXC 的高階容器引擎,原始碼託管在 Github 上, 基於go語言並遵從Apache2.0協議開源。
Docker是通過核心虛擬化技術(namespace以及cgroups等)來提供容器的資源隔離與安全保障。由於Docker通過作業系統層的虛擬化實現隔離,所以Docker容器在執行時,不需要類似虛擬機器( VM)額外的作業系統開銷,提高資源利用率。

原理建立-->傳送-->執行

image

架構:C/S架構

元件:映象(Image)、容器(Container)、倉庫(Repository)

Docker與VM的區別:

image

docker與Openstack的對比

image

Docker用途簡單配置、程式碼流水線管理、開發效率、應用隔離、伺服器整合、除錯能力、多租戶、快速部署

image

Docker改變了什麼?
面向產品:產品交付
面向開發:簡化環境配置
面向測試:多版本測試
面向運維:環境一致性
面向架構:自動化擴容

Docker環境的安裝部署
環境準備(centos7)

yum install -y docker
systemctl start docker
systemctl enable docker

映象的檢視(docker images資訊結果包括:映象倉庫、標籤、映象ID、建立時間、映象大小   )

[root@linux-node2 ~]# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
docker.io/centos     latest              60e65a8e4030        36 hours ago        196.6 MB
docker.io/nginx      latest              813e3731b203        9 days ago          133.8 MB
docker.io/registry   latest              a8706c2bfd21        2 weeks ago         422.8 MB

映象的匯出、匯入和下載(可以將本機下載的映象匯出,然後將匯出檔案上傳到別的機器上,在別的機器上進行映象匯入)

[root@linux-node2 ~]# docker pull centos
[root@linux-node2 ~]# docker save centos > /opt/centos.tar.gz

將linux-node2的映象匯出檔案上傳到linux-node1機器上,然後在linux-node1機器上匯入
[root@linux-node1 ~]# docker load < /opt/centos.tar.gz

映象的刪除(rmi後面可以跟多個id,用空格隔開)
docker rmi container_id

[root@linux-node2 ~]# docker rmi 813e3731b203

Docker重新命名映象名稱和TAG
# docker tag IMAGEID(映象id) REPOSITORY:TAG(倉庫:標籤)

[root@docker-test2 ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
<none>              <none>              93ec41b5ed04        About an hour ago   435.9 MB

[root@docker-test2 ~]# docker tag 93ec41b5ed04 kevin/nginx:v1

[root@docker-test2 ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
kevin/nginx         v1                  93ec41b5ed04        About an hour ago   435.9 MB

首次建立一個簡單的容器

[root@linux-node2 ~]# docker run centos /bin/echo "hehe"
hehe

命令解讀:使用centos映象,run執行命令,使用echo命令輸出hehe

檢視容器狀態
可以使用docker ps只能看見存活的容器,docker ps -a 檢視全部的容器,結果資訊表示:
容器ID、使用的映象、執行的命令、建立的時間、狀態、埠、名稱(如果不指定,自動生成)

[root@linux-node2 ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                          PORTS               NAMES
daeb4d7f7aab        centos              "/bin/echo hehe"    About a minute ago   Exited (0) About a minute ago                       insane_einstein

建立容器
--name:指定容器名稱
-t :分配一個tty終端
-i :容器的標準輸保持開啟的狀態

[root@linux-node2 ~]# docker run --name mydocker -t -i centos /bin/bash
[root@94ab7a046f7c /]# ps aux
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.1  11772  1872 ?        Ss   03:42   0:00 /bin/bash
root         14  0.0  0.0  35888  1472 ?        R+   03:43   0:00 ps aux

這種方式建立自動進入容器,開啟的容器只執行/bin/bash;

在容器中檢視主機名

[root@94ab7a046f7c /]# hostname
94ab7a046f7c
[root@94ab7a046f7c /]# exit

啟動、停止容器

[root@linux-node2 ~]# docker stop  ID
[root@linux-node2 ~]# docker start  ID

進入容器

[root@linux-node2 ~]# docker attach 94ab7a046f7c
[root@94ab7a046f7c /]#

刪除容器

[root@linux-node2 ~]# docker rm ID/名稱
加-f 強制刪除,包括正在執行中的容器

對映

image

隨機對映
埠的對映是系統自動分配的?

[root@linux-node2 ~]# docker run -d -P nginx
90316d97ee975b4e62e1927a9fb31f20703556b1a3ea07880d0c68dcb5bbd3bb
[root@linux-node2 ~]# docker ps -l
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                           NAMES
90316d97ee97        nginx               "nginx -g 'daemon off"   25 seconds ago      Up 23 seconds       0.0.0.0:32769->80/tcp, 0.0.0.0:32768->443/tcp   ecstatic_almeida

指定對映
指定埠的對映

[root@linux-node2 ~]# docker run -d -p 81:80 nginx
0294a8f5b4fc81ba31383a8eb98ec62b136826eba92360c84afd87bf1bf819fc
[root@linux-node2 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                           NAMES
0294a8f5b4fc        nginx               "nginx -g 'daemon off"   11 seconds ago      Up 10 seconds       443/tcp, 0.0.0.0:81->80/tcp                     admiring_ramanujan

檢視日誌

[root@linux-node2 ~]# docker logs +ID

資料管理

image

資料卷
預設掛載目錄
建立一個資料卷,名稱是volume-test1,掛載到data下預設掛載目錄

[root@linux-node2 ~]# docker run -it --name volume-test1 -v /data centos 
[root@1768d6414cfc /]# ls -l /data/
total 0

開啟一個新的視窗

列出容器的所有資訊,檢視mounts模組

[root@linux-node2 ~]# docker inspect 1768d6414cfc 
 "Mounts": [
        {
            "Name": "55c97df0276bb8879398b4e7286fc41f9872e9203267da7e23060e24ba06d167",
            "Source": "/var/lib/docker/volumes/55c97df0276bb8879398b4e7286fc41f9872e9203267da7e23060e24ba06d167/_data",
            "Destination": "/data",
            "Driver": "local",
            "Mode": "",
            "RW": true
        }
    ],

查詢掛載點並進入

檢視掛載的位置
[root@linux-node2 ~]# ll /var/lib/docker/volumes/55c97df0276bb8879398b4e7286fc41f9872e9203267da7e23060e24ba06d167/_data
總用量 0
進入到掛載點
[root@linux-node2 ~]# cd /var/lib/docker/volumes/55c97df0276bb8879398b4e7286fc41f9872e9203267da7e23060e24ba06d167/_data

建立一個cgt測試,並重新回到容器中檢視

[root@linux-node2 _data]# mkdir cgt

去容器中檢視
[root@1768d6414cfc /]# ls -l /data/
total 4
drwxr-xr-x 2 root root 4096 Jan  4 14:04 cgt

指定掛載目錄

將/opt掛載到/opt目錄下
[root@linux-node2 ~]# docker run -it --name volume-test1 -v /opt:/opt centos

指定許可權

只需要在掛載後面加上許可權即可。

加讀寫rw;只讀ro

[root@linux-node2 ~]# docker run -it --name volume-test1 -v /opt:/opt:rw centos

掛載單個檔案

記錄歷史記錄

[root@linux-node2 ~]# docker run -it -v ~/.bash_history:/.bash_history centos

資料卷容器

讓一個容器可以訪問另一個容器的資料卷

啟動兩個容器

啟動nfs容器,掛在一個卷,使用-d直接在後臺執行
[root@linux-node2 ~]# docker run -d --name nfs -v /data centos 
209bc89b365ad6bc1eeae693ada01c04c2d08e9ee2b8816e624882944c116126

啟動test1容器,掛載到nfs的資料卷容器上,
[root@linux-node2 ~]# docker run -it --name test1 --volumes-from nfs centos
[root@5e399198d6a8 /]# ls /data/
檢視沒內容

找到nfs容器的掛載點

(可以使用名稱,不僅僅是ID)

找到nfs容器的ID
[root@linux-node2 opt]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                     PORTS               NAMES
209bc89b365a        centos              "/bin/bash"         2 minutes ago        Exited (0) 2 minutes ago                       nfs
找到nfs容器的掛載點
[root@linux-node2 _data]# docker inspect nfs
[root@linux-node2 opt]# cd /var/lib/docker/volumes/3938c9b1143d41340e148a4c7bc12d13b53966b15380c5b958a9e035897450d5/_data
[root@linux-node2 _data]# touch cgt

在test1上檢視

到test1上檢視
[root@5e399198d6a8 /]# ls /data/
cgt

注意:資料卷容器不論停止還是開啟,不影響其他容器掛載使用
如何製作映象
方式一:手動構建容器
1)建立一個容器mynginx,使用centos映象

[root@linux-node2 ~]# docker run --name mynginx -it centos
[root@f9c7dfb6f552 /]# rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
[root@f9c7dfb6f552 /]# yum -y install nginx
[root@f9c7dfb6f552 /]# exit 
exit

2)基於mynginx容器做一個映象mynginx:v1

[root@linux-node2 ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
f9c7dfb6f552        centos              "/bin/bash"         3 minutes ago       Exited (0) 15 seconds ago                       mynginx
基於mynginx這個容器做一個映象
[root@linux-node2 ~]# docker commit -m "my nginx" f9c7dfb6f552 cgt/mynginx:v1
3f3adc859b77b2b47c3631229761bee6c7066f1c708bc01c5173c2ef5c0adce8
提交映象,同時打一個標籤叫mynginx:v1,cgt相當於你向github上提交的使用者名稱

檢視映象
[root@linux-node2 ~]# docker images
REPOSITORY                           TAG                 IMAGE ID            CREATED              VIRTUAL SIZE
cgt/mynginx                          v1                  3f3adc859b77        About a minute ago   326.4 MB

3)基於mynginx:v1建立一個容器mynginxv1

目的是修改nginx不讓其在後臺執行

[root@linux-node2 ~]# docker run -it --name nginxv1 cgt/mynginx:v1
[root@ea64c5855006 /]# vi /etc/nginx/nginx.conf
daemon off;      # 不再後臺執行
[root@ea64c5855006 /]# exit 
exit

[root@linux-node2 ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
ea64c5855006        cgt/mynginx:v1      "/bin/bash"         2 minutes ago       Exited (0) 42 seconds ago                       nginxv1

4)基於mynginxv1提交mynginxv2版本

重新提交V2版本
[root@linux-node2 ~]# docker commit -m "my nginx" ea64c5855006  cgt/mynginx:v2
a480cdf9055ec4e640c65df6404c6ba42903ea77198a26cec75eef0e4965fe67
檢視V2映象
[root@linux-node2 ~]# docker images
REPOSITORY                           TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
cgt/mynginx                          v2                  a480cdf9055e        25 seconds ago

5)基於mynginxv2映象,建立mynginxv2容器

啟動容器,-d後臺執行,-p指定埠 在後面是映象,最後是命令(因為是yum安裝的,可以直接寫nginx,如果不是yum,那要寫絕對路徑)
[root@linux-node2 ~]# docker run -d -p 82:80 cgt/mynginx:v2 nginx
4eaf8a19034a673100f9355504628fad45e6ecbab91615afd6cb4e7a18b82171

[root@linux-node2 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
4eaf8a19034a        cgt/mynginx:v2      "nginx"             15 seconds ago      Up 14 seconds       0.0.0.0:82->80/tcp   elegant_leakey
可以在瀏覽器訪問82埠

方式二:Dockerfile

1)Dockerfile包含的資訊

    基礎映象資訊 
    維護者資訊 
    映象操作指令 
    容器啟動時執行指令

2)檔案的編寫

[root@linux-node2 ~]# mkdir /opt/dockerfile/nginx/ -p
[root@linux-node2 ~]# cd /opt/dockerfile/nginx/
將index.html上傳到此處
[root@linux-node2 nginx]# vim Dockerfile
# This is docker file
# version v1
# Author wangshibo
# Base image(基礎映象)
FROM centos

# Maintainer(維護者資訊)
MAINTAINER wangshibo  2134728394@qq.com

# Commands(執行命令)
RUN rpm -ivh  http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
RUN yum -y install nginx
# Add(新增檔案)
ADD index.html /usr/share/nginx/html/index.html    # index.html是自己編寫的檔案,放在後面的目錄中,因為yum安裝後Documentroot是在這裡
RUN echo "daemon off;" >>/etc/nginx/nginx.conf
EXPOSE 80           # 對外的埠
CMD ['nginx']       # 執行的命令

3)構建容器,並執行

建立newnginx容器,-t:標籤,執行/opt/dockerfile/nginx/下面的預設的Dockerfile檔案
[root@linux-node2 nginx]# docker build -t cgt/mynginx:v3 /opt/dockerfile/nginx/

[root@linux-node2 nginx]# docker run -d -p 83:80 cgt/mynginx:v3

Docker是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然後釋出到任何流行的Linux機器上,也可以實現虛擬化。當你真正投入容器Docker的懷抱,不但可以發現它能解決很多問題,而且還具有眾多的優點:

1)它是不可變的-作業系統,庫版本,配置,資料夾和應用都是一樣的。您可以使用通過相同QA測試的映象,使產品具有相同的表現。  
2)它是輕量級的-容器的記憶體佔用非常小。不需要幾百幾千MB,它只要對主程式分配記憶體再加上幾十MB。  
3)它很快速-啟動一個容器與啟動一個單程式一樣快。不需要幾分鐘,您可以在幾秒鐘內啟動一個全新的容器。  

但是,許多使用者依然像對待典型的虛擬機器那樣對待容器,似乎都忘記了除了與虛擬機器相似的部分,容器還有一個很大的優點:它是一次性的。  
這個“特性”本身促使使用者改變他們關於使用和管理容器的習慣;下面將會說明下在容器中不應該做這些事,以確保最大地發揮容器的作用。

1)不要在容器中儲存資料 – 容器可能被停止,銷燬,或替換。一個執行在容器中的程式版本1.0,應該很容易被1.1的版本替換且不影響或損失資料。有鑑於此,如果你需要儲存資料,請存在卷中,並且注意如果兩個容器在同一個捲上寫資料會導致崩潰。確保你的應用被設計成在共享資料儲存上寫入。

2)不要將你的應用釋出兩份 – 一些人將容器視為虛擬機器。他們中的大多數傾向於認為他們應該在現有的執行容器裡釋出自己的應用。在開發階段這樣是對的,此時你需要不斷地部署與除錯;但對於質量保證與生產中的一個連續部署的管道,你的應用本該成為映象的一部分。記住:容器應該保持不變。

3)不要建立超大映象 – 一個超大映象只會難以分發。確保你僅有執行你應用/程式的必需的檔案和庫。不要安裝不必要的包或在建立中執行更新(yum更新)。

4)不要使用單層映象 – 要對分層檔案系統有更合理的使用,始終為你的作業系統建立你自己的基礎映象層,另外一層為安全和使用者定義,一層為庫的安裝,一層為配置,最後一層為應用。這將易於重建和管理一個映象,也易於分發。

5)不要為執行中的容器建立映象 – 換言之,不要使用“docker commit”命令來建立映象。這種建立映象的方法是不可重現的也不能版本化,應該徹底避免。始終使用Dockerfile或任何其他的可完全重現的S2I(源至映象)方法。

6)不要只使用“最新”標籤 – 最新標籤就像Maven使用者的“快照”。標籤是被鼓勵使用的,尤其是當你有一個分層的檔案系統。你總不希望當你2個月之後建立映象時,驚訝地發現你的應用無法執行,因為最頂的分層被非向後相容的新版本替換,或者建立快取中有一個錯誤的“最新”版本。在生產中部署容器時應避免使用最新。

7)不要在單一容器中執行超過一個程式-容器能完美地執行單個程式(http守護程式,應用伺服器,資料庫),但是如果你不止有一個程式,管理、獲取日誌、獨立更新都會遇到麻煩。

8)不要在映象中儲存憑據。使用環境變數 –不要將映象中的任何使用者名稱/密碼寫死。使用環境變數來從容器外部獲取此資訊。

9)使用非root使用者執行程式 – “docker容器預設以root執行。(…)隨著docker的成熟,更多的安全預設選項變得可用。現如今,請求root對於其他人是危險的,可能無法在所有環境中可用。你的映象應該使用USER指令來指令容器的一個非root使用者來執行。”

10)不要依賴IP地址 – 每個容器都有自己的內部IP地址,如果你啟動並停止它地址可能會變化。如果你的應用或微服務需要與其他容器通訊,使用任何命名與(或者)環境變數來從一個容器傳遞合適資訊到另一個。

相關文章