天天看點

Docker系列(一)Docker概述,核心概念講解,安裝部署

部分内容參考連結:

  • Docker實戰總結(非常全面,建議收藏)

一、 Docker概述

Docker是一個開源的應用容器引擎(基于Go語言開發),讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然後釋出到任何流行的Linux機器上,也可以實作虛拟化,容器是完全使用沙箱機制,互相之間不會有任何接口。簡言之,就是可以在Linux上鏡像使用的這麼一個容器。

Docker可以在容器内部快速自動化部署應用,并可以通過核心虛拟化技術(namespaces及cgroups等)來提供容器的資源隔離與安全保障等。

Docker的思想來自于集裝箱,集裝箱解決了什麼問題?在一艘大船上,可以把貨物規整的擺放起來。并且各種各樣的貨物被集裝箱标準化了,集裝箱和集裝箱之間不會互相影響。那麼我就不需要專門運送水果的船和專門運送化學品的船了。隻要這些貨物在集裝箱裡封裝的好好的,那我就可以用一艘大船把他們都運走。

簡單的了解,docker就是一個軟體集裝箱化平台,就像船隻、火車、卡車運輸集裝箱而不論其内部的貨物一樣,軟體容器充當軟體部署的标準單元,其中可以包含不同的代碼和依賴項。

按照這種方式容器化軟體,開發人員和 IT 專業人員隻需進行極少修改或不修改,即可将其部署到不同的環境,如果出現的故障,也可以通過鏡像,快速恢複服務。

1.1 Docker的優勢

二、從容器化技術說起

2.1 背景

在虛拟機和雲計算較為成熟的時候,各家公司想在雲伺服器上部署應用,通常都是像部署實體機那樣使用腳本或手動部署,但由于本地環境和雲環境不一緻,往往會出現各種小問題。

這時候有個叫Paas的項目,就是專注于解決本地環境與雲端環境不一緻的問題,并且提供了應用托管的功能。簡單得說,就是在雲伺服器上部署Paas對應的服務端,然後本機就能一鍵push,将本地應用部署到雲端機器。然後由于雲伺服器上,一個Paas服務端,會接收多個使用者送出的應用,是以其底層提供了一套隔離機制,為每個送出的應用建立一個沙盒,每個沙盒之間彼此隔離,互不幹涉。

看看,這個沙盒是不是和docker很類似呢?實際上,容器技術并不是docker的專屬,docker隻是衆多實作容器技術中的一個而已。

2.2 docker實作原理

說起docker,很多人都會将它與虛拟機進行比較,

其中左邊是虛拟機的結構,右邊是docker容器的結構。

在虛拟機中,通過Hypervisor對硬體資源進行虛拟化,在這部分硬體資源上安裝作業系統,進而可以讓上層的虛拟機和底層的主控端互相隔離。

但docker是沒有這種功能的,我們在docker容器中看到的與主控端互相隔離的沙盒環境(檔案系統,資源,程序環境等),本質上是通過Linux的Namespace機制,CGroups(Control Groups)和Chroot等功能實作的。實際上Docker依舊是運作在主控端上的一個程序(程序組),隻是通過一些障眼法讓docker以為自己是一個獨立環境。

是以,容器=Cgroup+Namespace+rootfs+容器引擎(使用者态工具)

  • Cgroup:資源控制。
  • Namespace:通路隔離。
  • rootfs:檔案系統隔離。
  • 容器引擎:生命周期控制。

2.3 Cgroup

Cgroup是control group的簡寫,屬于Linux核心提供的一個特性,用于限制和隔離一組程序對系統資源的使用,也就是做資源QoS,這些資源主要包括CPU、記憶體、block I/O和網絡帶寬。

  • devices:裝置權限控制。
  • cpuset:配置設定指定的CPU和記憶體節點。
  • cpu:控制CPU占用率。
  • cpuacct:統計CPU使用情況。
  • memory:限制記憶體的使用上限。
  • freezer:當機(暫停)Cgroup中的程序。
  • net_cls:配合tc(traffic controller)限制網絡帶寬。
  • net_prio:設定程序的網絡流量優先級。
  • huge_tlb:限制HugeTLB的使用。
  • perf_event:允許Perf工具基于Cgroup分組做性能監測。

2.4 NameSpace

Namespace又稱為命名空間(也稱為名字空間),它是将核心的全局資源做封裝,使得每個Namespace都有一份獨立的資源,是以不同的程序在各自的Namespace内對同一種資源的使用不會互相幹擾。

  • IPC:隔離System V IPC和POSIX消息隊列。
  • Network:隔離網絡資源。
  • Mount:隔離檔案系統挂載點。
  • PID:隔離程序ID。
  • UTS:隔離主機名和域名。
  • User:隔離使用者ID群組ID。

2.5 徹底了解docker隔離機制

如果在一個docker容器裡面,使用ps指令檢視程序,可能隻會看到如下的輸出:

/ # ps
PID  USER   TIME COMMAND
  1 root   0:00 /bin/bash
  10 root  0:00 ps
           

在容器中執行ps,隻會看到1号程序/bin/bash和10号程序ps。前面有說到,docker容器本身隻是Linux中的一個程序(組),也就是說在主控端上,這個/bin/bash的pid可能是100或1000,那為什麼在docker裡面看到的這個/bin/bash程序的pid是1呢?答案是linux提供的Namespace機制,将/bin/bash這個程序的程序空間隔離開了。

具體的做法呢,就是在建立程序的時候添加一個可選的參數,比如下面這樣:

int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL); 
           

那樣後,建立的線程就會有一個新的命名空間,在這個命名空間中,它的pid就是1,當然在主控端的真實環境中,它的pid還是原來的值。

上面的這個例子,其實隻是pid Namespace(程序命名空間),除此之外,還有network Namespace(網絡命名空間),mount Namespace(檔案命名空間,就是将整個容器的根目錄root挂載到一個新的目錄中,然後在其中放入核心檔案看起來就像一個新的系統了)等,用以将整個容器和實際主控端隔離開來。而這其實也就是容器基礎的基礎實作了。

但是,上述各種Namespace其實還不夠,還有一個比較大的問題,那就是系統資源的隔離,比如要控制一個容器的CPU資源使用率,記憶體占用等,否則一個容器就吃盡系統資源,其他容器怎麼辦。

而Linux實作資源隔離的方法就是Cgroups。Cgroups主要是提供檔案接口,即通過修改 /sys/fs/cgroup/下面的檔案資訊,比如給出pid,CPU使用時間限制等就能限制一個容器所使用的資源。

是以,docker本身隻是linux中的一個程序,通過Namespace和cgroup将它隔離成一個個單獨的沙盒。明白這點,就會明白docker的一些特性,比如說太過依賴核心的程式在docker上可能執行會出問題,比如無法在低版本的主控端上安裝高本版的docker等,因為本質上還是執行在主控端的核心上。

三、Docker的核心:鏡像、容器、倉庫

3.1 鏡像

鏡像是一個可執行包,包含運作應用程式所需的所有内容——代碼、運作時、庫、環境變量和配置檔案。

3.2 容器

容器:

  • 容器是通過運作鏡像啟動容器,是鏡像的運作時執行個體。鏡像實際上就是一個容器的模闆,通過這個模闆可以建立很多相同的容器。
    • 容器就是一個認為隻有其本身在運作狀态的linux程式,隻服從使用者指定的指令。(容器程式有自己的IP位址;一個可通路網絡的獨立裝置)

通過Java去類比了解Docker的一些概念:

  • Class檔案 - 相當于Docker鏡像,定義了類的一些所需要的資訊
  • 對象 - 相當于容器,通過Class檔案建立出來的執行個體
  • JVM - 相當于Docker引擎,可以讓Docker容器屏蔽底層複雜邏輯,實作跨平台操作

3.3 倉庫

存放鏡像的地方,和git倉庫類似。

四、Docker的安裝方式

4.1 方式一:yum方式安裝

# 更新yum源
yum update
# 安裝所需環境
yum install -y yum-utils device-mapper-persistent-data lvm2
# 配置yum倉庫
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 安裝Docker
yum install docker-ce
# 啟動Docker
systemctl start docker
systemctl enable docker
           

4.2 方式二:curl

curl -sSL https://get.daocloud.io/docker | sh
           

4.3 離線安裝

  1. 下載下傳docker的安裝檔案:https://download.docker.com/linux/static/stable/x86_64/
  1. 将下載下傳後的tgz檔案傳至伺服器,通過FTP工具上傳即可
  2. 解壓

    tar -zxvf docker-19.03.8-ce.tgz

  3. 将解壓出來的docker檔案複制到 /usr/bin/ 目錄下:

    cp docker/* /usr/bin/

  4. 進入/etc/systemd/system/目錄,并建立docker.service檔案
[root@localhost java]# cd /etc/systemd/system/
[root@localhost system]# touch docker.service
           
  1. 打開docker.service檔案,将以下内容複制
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd --selinux-enabled=false --insecure-registry=192.168.200.128
ExecReload=/bin/kill -s HUP $MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
# restart the docker process if it exits prematurely
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s

[Install]
WantedBy=multi-user.target
           
  1. 給docker.service檔案添加執行權限:

    chmod 777 /etc/systemd/system/docker.service

  2. 重新加載配置檔案:

    systemctl daemon-reload

  3. 啟動Docker

    systemctl start docker

  4. 設定開機啟動:

    systemctl enable docker.service

  5. 檢視Docker狀态:

    systemctl status docker

如出現如圖界面,則表示安裝成功!

五、Docker思維導圖總結

思維導圖下載下傳連結:

Docker思維導圖下載下傳