首頁  >  文章  >  從Docker受限,列入“實體名單”,談談Docker究竟為何物竟如此重要?

從Docker受限,列入“實體名單”,談談Docker究竟為何物竟如此重要?

青灯夜游
青灯夜游轉載
2020-08-19 14:07:135295瀏覽

新聞:

8 月13 日,Docker 更新網站服務協議,禁止禁運國家和被列入美國「實體清單」等多個清單的組織和個人使用遵循該服務協議的Docker 網站及所有相關網站。

這其中包括:華為、海康威視、大華股份、科大訊飛、曠視科技、商湯科技等多家科技企業 以及 哈工大、哈工程等大學。

從Docker受限,列入“實體名單”,談談Docker究竟為何物竟如此重要?

本文我們就來探索 Docker 的神秘世界,從零到一掌握 Docker 的基本原理與實踐操作,了解一下Docker為何如此重要。 【相關推薦:Docker影片教學

富 Web 時代,應用程式變得越來越強大,同時也越來越複雜。叢集部署、隔離環境、灰階發布以及動態擴容缺一不可,而容器化則成為中間的必要橋樑。

講個故事

為了更好的理解Docker 是什麼,我們先來講個故事:

#我需要蓋一間房子,於是我搬石頭、砍木頭、畫圖紙、蓋房子。一頓操作,終於把這房子蓋好了。

從Docker受限,列入“實體名單”,談談Docker究竟為何物竟如此重要?

結果,住了一段時間,心血來潮想搬到海邊去。這時候照以往的辦法,我只能去海邊,再次搬石頭、砍木頭、畫圖紙、蓋房子。

從Docker受限,列入“實體名單”,談談Docker究竟為何物竟如此重要?

煩惱之際,跑來一個魔法師教我一種魔法。這種魔法可以把我蓋好的房子複製一份,做成「鏡像」,放在我的背包裡。

從Docker受限,列入“實體名單”,談談Docker究竟為何物竟如此重要?

等我到了海邊,就用這個「鏡像」,複製一間房子,拎包入住。

是不是很神奇?對應到我們的專案中來,房子就是專案本身,鏡像就是專案的複製,背包就是鏡像倉庫。

如果要動態擴容,從倉庫中取出項目鏡像,隨便複製就可以了。 Build?once,Run?anywhere!

不用再關注版本、相容、部署等問題,徹底解決了「上線即崩,無止盡建構」的尷尬。

虛擬機器與容器

#開始之前,我們來做一些基礎知識的儲備:

#①虛擬機器:虛擬化硬體

虛擬機器Virtual Machine 指透過軟體模擬的具有完整硬體系統功能的、運行在一個完全隔離環境中的完整電腦系統。在實體電腦中能夠完成的工作在虛擬機器中都能夠實現。

在電腦中建立虛擬機器時,需要將實體機器的部分硬碟和記憶體容量作為虛擬機器的硬碟和記憶體容量。

每個虛擬機器都有獨立的 CMOS、硬碟和作業系統,可以像使用實體機一樣對虛擬機器進行操作。在容器技術之前,業界的網紅是虛擬機器。

虛擬機器技術的代表,是 VMWare 和 OpenStack。

②容器:將作業系統層虛擬化,是一個標準的軟體單元

其特點如下:

  • #隨處運作:容器可以將程式碼與設定檔和相關依賴函式庫進行打包,從而確保在任何環境下的運作都是一致的。

  • 高資源利用率:容器提供進程級的隔離,因此可以更精細地設定 CPU 和記憶體的使用率,進而更好地利用伺服器的運算資源。

  • 快速擴展:每個容器都可作為單獨的進程予以運行,並且可以共享底層作業系統的系統資源,這樣一來可以加快容器的啟動和停止效率。

③區別與聯繫:

  • #虛擬機器雖然可以隔離出很多「子電腦」,但佔用空間更大,啟動更慢。虛擬機器軟體可能還要花錢,例如 VMWare。

  • 容器技術不需要虛擬出整個作業系統,只需要虛擬一個小規模的環境,類似「沙箱」。

  • 運作空間,虛擬機器一般要幾 GB 到 幾十 GB 的空間,而容器只需要 MB 等級甚至 KB 等級。

我們來看看比較數據:

從Docker受限,列入“實體名單”,談談Docker究竟為何物竟如此重要?

#虛擬機屬於虛擬化技術,而Docker 這樣的容器技術,屬於輕量級的虛擬化。

與虛擬機器相比,容器更輕且速度更快,因為它利用了 Linux 底層作業系統在隔離的環境中運作。

虛擬機器的 Hypervisor 創建了一個非常牢固的邊界,以防止應用程式突破它,而容器的邊界不那麼強大。

認識Docker

從Docker受限,列入“實體名單”,談談Docker究竟為何物竟如此重要?

#Docker 是一個開源的應用程式容器引擎,讓開發者可以打包他們的應用程式以及依賴套件到一個可移植的容器中,然後發佈到任何流行的Linux 機器上,也可以實現虛擬化。容器是完全使用沙箱機制,彼此之間不會有任何介面。

Docker 技術的三大核心概念,分別是:

  • 鏡像Image

  • ##容器Container

  • 倉庫Repository

#Docker 輕量級的原因是什麼?相信你也會有這樣的疑惑:為什麼 Docker 啟動快?如何做到和宿主機共享核心?

當我們要求 Docker 運行容器時,Docker 會在電腦上設定一個資源隔離的環境。

然後將打包的應用程式和關聯的檔案複製到 Namespace 內的檔案系統中,此時環境的設定就完成了。之後 Docker 會執行我們預先指定的命令,運行應用程式。

鏡像不包含任何動態數據,其內容在建置之後也不會被改變。

核心概念

核心概念如下:

  • Build,Ship and Run(建構、運輸、運行)。

  • Build once,Run anywhere(一次搭建,處處運行)。

  • Docker 本身並不是容器,它是建立容器的工具,是應用容器引擎。

  • Docker 三大核心概念,分別是:映像 Image,容器 Container、倉庫 Repository。

  • Docker 技術使用 Linux 核心和核心功能(例如 Cgroups 和 namespaces)來分隔進程,以便各進程相互獨立運作。

  • 由於 Namespace 和 Cgroups 功能僅在 Linux 上可用,因此容器無法在其他作業系統上運作。那麼 Docker 如何在 macOS 或 Windows 上運作? Docker 實際上使用了一個技巧,並在非 Linux 作業系統上安裝 Linux 虛擬機,然後在虛擬機內運行容器。

  • 鏡像是一個可執行包,其包含執行應用程式所需的程式碼、執行時間、函式庫、環境變數和設定文件,容器是鏡像的執行時間實例。

更多關於Docker 的原理,可以查看《Docker 工作原理及容器化簡易指南》,這裡不再贅述:

http:// dockone.io/article/8788


#安裝Docker

①命令列安裝

Homebrew 的Cask 已經支援Docker for Mac,因此可以很方便的使用Homebrew Cask 來進行安裝,執行以下命令:

brew cask install docker

更多安裝方式,請查看官方文件:

https://www.docker.com/get-started

#②查看版本

指令如下:

docker -v

③配置映像加速

設定Docker Engine 寫入配置:

{
  registry-mirrors: [
    http://hub-mirror.c.163.com/,
    https://registry.docker-cn.com
  ],
  insecure-registries:[],
  experimental: false,
  debug: true
}

④安裝桌面端

從Docker受限,列入“實體名單”,談談Docker究竟為何物竟如此重要?

  • 桌面端操作非常簡單,先到官網下載[1]。透過 Docker 桌面端,我們可以方便的操作:

clone:複製一個專案。

build:打包鏡像。

run:執行實例。

share:共享鏡像。

好了,準備工作就緒,下面可以大展身手了!

從Docker受限,列入“實體名單”,談談Docker究竟為何物竟如此重要?快速開始

安裝完 Docker 之後,我們先打個實際專案的映像,邊學邊用。

①首先需要大致了解我們將會用到的11 個指令

如下圖:

#########②新建專案#########為了快捷,我們直接使用Vue 鷹架建置專案:###
vue create docker-demo
###嘗試啟動一下:###
yarn serve
## #訪問位址:http://localhost:8080/。專案就緒,我們接著為專案打包:###
yarn build
###這時候,專案目錄下的 Dist 是我們要部署的靜態資源了,我們繼續下一步。 ######要注意:前端專案一般分兩類,一類直接 Nginx 靜態部署,一類需要啟動 Node 服務。本節我們只考慮第一種。關於 Node 服務,後文我會詳細說明。 ###

③新建 Dockerfile

命令如下:

cd docker-demo && touch Dockerfile

此时的项目目录如下:

.
├── Dockerfile
├── README.md
├── babel.config.js
├── dist
├── node_modules
├── package.json
├── public
├── src
└── yarn.lock

可以看到我们已经在 docker-demo 目录下成功创建了 Dockerfile 文件。

④准备 Nginx 镜像

运行你的 Docker 桌面端,就会默认启动实例,我们在控制台拉取 Nginx 镜像:

docker pull nginx

控制台会出现如下信息:

Using default tag: latest
latest: Pulling from library/nginx
8559a31e96f4: Pull complete
8d69e59170f7: Pull complete
3f9f1ec1d262: Pull complete
d1f5ff4f210d: Pull complete
1e22bfa8652e: Pull complete
Digest: sha256:21f32f6c08406306d822a0e6e8b7dc81f53f336570e852e25fbe1e3e3d0d0133
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

如果你出现这样的异常,请确认 Docker 实例是否正常运行。

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

镜像准备 OK,我们在根目录创建 Nginx 配置文件:

touch default.conf

写入:

server {
    listen       80;
    server_name  localhost;
    #charset koi8-r;
    access_log  /var/log/nginx/host.access.log  main;
    error_log  /var/log/nginx/error.log  error;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

⑤配置镜像

打开 Dockerfile ,写入如下内容:

FROM nginx
COPY dist/ /usr/share/nginx/html/
COPY default.conf /etc/nginx/conf.d/default.conf

我们逐行解释一下代码:

  • FROM nginx 指定该镜像是基于 nginx:latest 镜像而构建的。

  • COPY dist/ /usr/share/nginx/html/ 命令的意思是将项目根目录下 dist 文件夹中的所有文件复制到镜像中 /usr/share/nginx/html/ 目录下。

  • COPY default.conf /etc/nginx/conf.d/default.conf 将 default.conf 复制到 etc/nginx/conf.d/default.conf,用本地的 default.conf 配置来替换 Nginx 镜像里的默认配置。

⑥构建镜像

Docker 通过 build 命令来构建镜像:

docker build -t jartto-docker-demo .

按照惯例,我们解释一下上述代码:

  • -t 参数给镜像命名 jartto-docker-demo。

  • . 是基于当前目录的 Dockerfile 来构建镜像。

执行成功后,将会输出:

Sending build context to Docker daemon  115.4MB
Step 1/3 : FROM nginx
 ---> 2622e6cca7eb
Step 2/3 : COPY dist/ /usr/share/nginx/html/
 ---> Using cache
 ---> 82b31f98dce6
Step 3/3 : COPY default.conf /etc/nginx/conf.d/default.conf
 ---> 7df6efaf9592
Successfully built 7df6efaf9592
Successfully tagged jartto-docker-demo:latest

镜像制作成功!我们来查看一下容器:

docker image ls | grep jartto-docker-demo

可以看到,我们打出了一个 133MB 的项目镜像:

jartto-docker-demo latest 7df6efaf9592 About a minute ago 133MB

镜像也有好坏之分,后续我们将介绍如何优化,这里可以先暂时忽略。

⑦运行容器

命令如下:

docker run -d -p 3000:80 --name docker-vue jartto-docker-demo

这里解释一下参数:

  • -d 设置容器在后台运行。

  • -p 表示端口映射,把本机的 3000 端口映射到 container 的 80 端口(这样外网就能通过本机的 3000 端口访问了。

  • --name 设置容器名 docker-vue。

  • jartto-docker-demo 是我们上面构建的镜像名字。

补充一点:在控制台,我们可以通过 docker ps 查看刚运行的 Container 的 ID:

docker ps -a

控制台会输出:

CONTAINER ID IMAGE              COMMAND                  CREATED       STATUS PORTS  NAMES
ab1375befb0b jartto-docker-demo /docker-entrypoint.…   8 minutes ago Up 7 minutes  0.0.0.0:3000->80/tcp  docker-vue

如果你使用桌面端,那么打开 Docker Dashboard 就可以看到容器列表了,如下图:

從Docker受限,列入“實體名單”,談談Docker究竟為何物竟如此重要?

⑧访问项目

因为我们映射了本机 3000 端口,所以执行:

curl -v -i localhost:3000

或者打开浏览器,访问:localhost:3000。

⑨发布镜像

如果你想为社区贡献力量,那么需要将镜像发布,方便其他开发者使用。

发布镜像需要如下步骤:

  • 登陆 dockerhub[2],注册账号。

  • 命令行执行 docker login,之后输入我们的账号密码,进行登录。

  • 推送镜像之前,需要打一个 Tag,执行 docker tag /:

全流程结束,以后我们要使用,再也不需要「搬石头、砍木头、画图纸、盖房子」了,拎包入住。这也是 Docker 独特魅力所在。

常规操作

到这里,恭喜你已经完成了 Docker 的入门项目!如果还想继续深入,不妨接着往下看看。

①参数使用

FROM:

  • 指定基础镜像,所有构建的镜像都必须有一个基础镜像,且 FROM 命令必须是 Dockerfile 的第一个命令

  • FROM [AS ] 指定从一个镜像构建起一个新的镜像名字

  • FROM [:] [AS ] 指定镜像的版本 Tag

  • 示例:FROM mysql:5.0 AS database

MAINTAINER:

  • 镜像维护人的信息

  • MAINTAINER

  • 示例:MAINTAINER Jartto Jartto@qq.com

RUN:

  • 构建镜像时要执行的命令

  • RUN

  • 示例:RUN [executable, param1, param2]

ADD:

  • 將本地的文件加入複製到容器中去,壓縮包會解壓縮,可以存取網路上的文件,會自動下載

  • ADD

  • 範例:ADD *.js /app 加入js 檔案到容器中的app 目錄下

COPY:

  • 功能和ADD 一樣,只是複製,不會解壓縮或下載檔案

CMD:

  • 啟動容器後執行的指令,和RUN 不一樣,RUN 是在建置鏡像是要執行的指令

  • 當使用docker run 執行容器的時候,這個可以在命令列被覆寫

  • 範例:CMD [executable, param1, param2]

#ENTRYPOINT:

  • 也是執行指令,和CMD 一樣,只是這個指令不會被指令列覆寫

  • ##ENTRYPOINT [executable , param1, param2]

  • 範例:ENTRYPOINT [donnet, myapp.dll]

LABEL:為鏡像添加元數據, key-value 形式

  • LABEL = = ...

  • 範例:LABEL version=1.0 description=這是一個web應用
#ENV:設定環境變量,有些容器在運行時會需要某些環境變數

    ENV 一次設定一個環境變數
  • ENV = = = 設定多個環境變數
  • ##範例:ENV JAVA_HOME /usr/java1.8/
  • EXPOSE:暴露對外的端口(容器內部程式的端口,雖然會和宿主機的一樣,但是其實是兩個端口)

EXPOSE
  • 範例:EXPOSE 80
  • 容器運行時,需要用-p 映射外部連接埠才能存取容器內的連接埠
  • VOLUME:指定資料持久化的目錄,官方語言叫做掛載

VOLUME /var /log 指定容器中需要被掛載的目錄,會把這個目錄映射到宿主機的一個隨機目錄上,實現資料的持久化和同步
  • VOLUME [/var/ log,/var/test.....] 指定容器中多個需要被掛載的目錄,會把這些目錄映射到宿主機的多個隨機目錄上,實現資料的持久化和同步
  • VOLUME /var/data var/log 指定容器中的var/log 目錄掛載到宿主機上的/var/data 目錄,這種形式可以手動指定宿主機上的目錄

WORKDIR:設定工作目錄,設定之後,RUN、CMD、COPY、ADD 的工作目錄都會同步變更

  • WORKDIR
  • 範例:WORKDIR /app/test

USER:指定執行指令時所使用的用戶,為了安全性和權限起見,根據要執行的命令選擇不同使用者

  • USER :[]


##範例:USER test
  • ARG:設定建置映像是要傳遞的參數
  • ARG [=]

  • ARG name=sss

更多操作,請移步官方使用文檔[3]:https://docs.docker.com/

#########最佳實踐### #########在掌握Docker 常規操作之後,我們很容易就可以打出自己想要的專案映像。 ######然而不同的操作打出的鏡像也是千差萬別。究竟是什麼原因導致鏡像差異,我們不妨繼續探索。 ######以下是應用 Docker 流程​​中整理的最佳實踐,請盡量遵循以下準則:############Require 明確:需要什麼映像。 ############步驟精簡:變化較少的 Step 優先。 ############版本明確:鏡像命名明確。 ############說明文件:整個鏡像打包步驟可以重現。 ##################總結############容器化技術必將是雲端時代不可或缺的技能之一,而Docker 只是滄海一粟。隨之而來的還有叢集容器管理 Kubernetes、Service Mesh 、Istio 等技術。 ###

打開 Docker 的大門,不斷抽絲剝繭,逐層深入,你將感受到容器化的無窮魅力。

相關連結:

  • https://www.docker.com/products/docker-desktop

  • https://hub.docker.com/

  • https://docs.docker.com/

原文網址:http://jartto.wang/2020/07/04/learn-docker

作者:jartto

想了解更多相關知識,可造訪: Docker使用教學! !

陳述:
本文轉載於:weixin。如有侵權,請聯絡admin@php.cn刪除