一文零基礎教你學會 Docker 入門到實踐

沒有人不愛惜他的生命,但不多人珍視他的時間。 —— 梁實秋php

Docker 自 2013 年發佈至今一直備受關注,從招聘面試角度來看有些職位對於瞭解 Docker、K8S 這些也有一些加分項,同時學習 Docker 也是後續學習 K8S 的基礎,可是對於 Docker 不少人也需並不瞭解,其實 Docker 也並無那麼難,本文從 Docker 入門到應用實踐爲你們進行講解,中間也列舉了不少實例,但願能幫助你們更好的理解。html

做者簡介:五月君,Nodejs Developer,熱愛技術、喜歡分享的 90 後青年,公衆號「Nodejs技術棧」,Github 開源項目 www.nodejs.rednode

快速導航

本篇 Docker 入門到實踐路線圖以下所示mysql

圖片描述

Docker初識

爲何要使用 Docker

Docker 能夠將應用以集裝箱的方式進行打包,經過鏡像的方式能夠實如今不一樣的環境下進行快速部署,在團隊中還可實現一次打包,屢次共享,使用 Docker 能夠輕鬆的爲任何應用建立一個輕量級的、可移植的、自給自足的容器。linux

例如,咱們在本地將編譯測試經過的程序打包成鏡像,能夠快速的在服務器環境中進行部署,有時也能解決不一樣的開發環境形成的問題 「明明我本地是好的,可是一到服務器就不行」。nginx

爲何要使用 Docker?總結下來其有如下優勢:git

  • 高效的利用系統資源(節約成本)
  • 持續交付與部署(敏捷)
  • 多平臺的遷移更容易(可移植性)
  • 容易的沙箱機制(安全性)

Docker 架構一瞥

中間部位爲咱們進行 Docker 操做的宿主機,其運行了一個 Docker daemon 的核心守護程序,負責構建、運行和分發 Docker 容器。github

左邊爲 Docker 客戶端,其與 Docker 守護進程進行通訊,客戶端會將 build、pull、run 命令發送到 Docker 守護進程進行執行。web

右邊爲 Docler 註冊表存儲 Docker 鏡像,是一個全部 Docker 用戶共享 Docker 鏡像的服務,Docker daemon 與之進行交互。面試

圖片描述

Docker 鏡像與容器概述

參考 docs.docker.com/engine/dock…

什麼是 Docker 鏡像

Docker 會把應用程序及依賴打包進鏡像(Images)裏,提供了容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些爲運行時準備的一些配置參數(如匿名卷、環境變量、用戶等),經過這個鏡像文件可生成 Docker 容器。

例如:這個鏡像文件包含了一個完整的 Ubuntu 系統,咱們能夠在 Ubuntu 鏡像基礎之上安裝了 Redis、Mysql 等其它應用程序,能夠回顧下 Docker 架構一瞥 在 DOCKER_HOST 裏面有個 images。

另外在製做好鏡像文件以後能夠拷貝到其它機器使用,它是通用的,鏡像的製做能夠基於 Dockerfile 構建後面會講解。

什麼是 Docker 容器

容器是鏡像的可運行實例,你可使用 Docker API 建立、啓動、中止、移動或刪除它,

在默認狀況下,容器與其它容器及其主機是隔離的,擁有本身的獨立進程空間、網絡配置。

容器由其鏡像以及在建立或啓動容器時提供的任何配置選項定義。當容器被刪除時,對其狀態的任何未存儲在持久存儲中的更改都會消失。

Docker安裝

Docker 是一個開源的商業產品,提供了社區版(CE)和企業版(EE),如下也都是基於企業版進行介紹,我這裏操做系統採用的 Linux 下 Ubuntu 系統,更多安裝方式也可參照官網安裝指南 docs.docker.com/install/

更改 docker 源

這個看狀況,由於 Docker 的源在國外,國內訪問速度可能會不穩定,有須要的能夠按照如下步驟更換爲國內源

  • 編輯 /etc/docker/daemon.json 文件,輸入 docker-cn 鏡像源地址
$ sudo vim /etc/docker/daemon.json

{
  "registry-mirrors": ["https://registry.docker-cn.com"]
}
複製代碼
  • 重啓 Docker 服務
$ sudo service docker restart
複製代碼

設置存儲庫

  1. 更新 apt 軟件包緩存
sudo apt-get update
複製代碼
  1. 在機器上首次安裝的需先設置 Docker 存儲庫,因爲 apt 源使用 HTTPS 以確保軟件下載過程當中不被篡改。所以,咱們首先須要添加使用 HTTPS 傳輸的軟件包以及 CA 證書。
$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
複製代碼
  1. 添加 Docker 的官方 GPG 密鑰
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
複製代碼
  1. 向 source.list 中添加 Docker 軟件源
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable"
複製代碼

安裝 Docker EC(社區版)

  1. 更新 apt 軟件包緩存
sudo apt-get update
複製代碼
  1. 安裝
sudo apt-get install docker-ce docker-ce-cli containerd.io
複製代碼

執行如下命令使用腳本自動安裝,這也是最簡化的安裝流程,它會檢測你當前使用的 Linux 版本,選擇合適的安裝包進行安裝,

sudo wget -qO- https://get.docker.com | sh
複製代碼

添加 Docker 用戶組

因爲 Docker 操做須要擁有 root 權限,爲避免每次都輸入 sudo,能夠把用戶加入 Docker 用戶組,執行如下命令

# https://docs.docker.com/install/linux/linux-postinstall/#manage-docker-as-a-non-root-user
$ sudo usermod -aG docker $USER
複製代碼

驗證

安裝完成後,運行下面的命令,驗證是否安裝成功

$ docker -v
Docker version 19.03.2, build 6a30dfc
複製代碼

鏡像構建初探

上面對 Docker 的鏡像和容器作了簡要概述,有個初步的瞭解以後,再來看下 Docker 鏡像和容器的實踐。

抓取 image 文件到本地

hello-world 爲鏡像名字,docker image pull 爲抓取鏡像命令,Docker 官方提供的 image 文件都放在 library 默認組裏,library/hello-world 也就爲 image 文件的位置。

$ docker image pull hello-world
# 如下爲抓取過程當中的日誌信息
Using default tag: latest
latest: Pulling from library/hello-world
1b930d010525: Pull complete 
Digest: sha256:451ce787d12369c5df2a32c85e5a03d52cbcef6eb3586dd03075f3034f10adcd
Status: Downloaded newer image for hello-world:latest
docker.io/library/hello-world:latest
複製代碼

查看 image 文件列表

image 文件抓取成功經過 docker images 或 docker image ls 命令查看當前都有哪些鏡像

$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              fce289e99eb9        8 months ago        1.84kB
複製代碼

運行 image 文件

執行 docker container run 命令會生成一個正在運行的容器實例,另外 docker container run 發現本地沒有指定的 image 文件,其自身還有自動抓取 image 文件功能,就是上面講解的 docker image pull 命令

$ docker container run hello-world

Hello from Docker!

# 如下內容省略
...
複製代碼

查看容器列表

使用 docker psdocker container ls 命令用來查看正在運行的容器列表,這個時候是沒有正在運行的容器實例的,由於在以上 docker container run hello-world 命令執行以後 hello-world 就會中止,容器也會隨着自動中止,但並非全部的容器運行以後也都會中止的,例如 Nginx 後面會進行實踐。

$ docker ps
複製代碼

經過 docker ps --alldocker container ls --all 命令能夠查看全部的容器實例,包含已經中止的

$ docker ps --all
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
a662ec198a83        hello-world         "/hello"            10 minutes ago      Exited (0) 10 minutes ago                       exciting_wing
複製代碼

構建一個 Nginx 鏡像

如下命令會用 nginx 鏡像啓動一個容器,命名爲 nginxserver,並映射到 8081 端口

$ docker container run --name nginxserver -d -p 8081:80 nginx
複製代碼

好了,咱們如今就可使用 http://localhost:8081/ 來訪問這個 Nginx 服務器,因爲我這裏是在虛擬機上安裝的 Docker 所以要使用個人虛擬機地址 http://192.168.6.128:8081/ 進行訪問,一樣若是你是在虛擬機、雲服務器上安裝的 Docker 也要使用相應的 ip 來訪問,若是是在本機直接 localhost 就能夠。如下爲 Nginx 默認的歡迎頁面。

圖片描述

再分別看下目前的 image 列表和正在運行的容器

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              5a3221f0137b        3 weeks ago         126MB
hello-world         latest              fce289e99eb9        8 months ago        1.84kB

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
b7bf26745b3f        nginx               "nginx -g 'daemon of…"   23 minutes ago      Up 23 minutes       0.0.0.0:8081->80/tcp   nginxserver
複製代碼

終止容器

經過 docker container kill [containID] 命令終止正在運行的容器

# docker container kill [containID]
$ docker container kill b7bf26745b3f
複製代碼

刪除容器文件

上面的終止容器並不會刪除容器文件,僅僅是容器中止運行,經過 docker ps --all 命令查看全部的容器列表

$ docker ps --all
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                            PORTS               NAMES
b7bf26745b3f        nginx               "nginx -g 'daemon of…"   29 minutes ago      Exited (137) About a minute ago                       nginxserver
a662ec198a83        hello-world         "/hello"                 49 minutes ago      Exited (0) 49 minutes ago                             exciting_wing
複製代碼

因爲已經終止容器文件依然會佔據着咱們的磁盤空間,在不使用的狀況可經過 docker container rm [containerID] 命令刪除

$ docker container rm b7bf26745b3f a662ec198a83
複製代碼

執行以上命令以後,再使用 docker ps --all 命令,此時容器列表就爲空了。

刪除鏡像文件

一樣刪除一個鏡像文件也很簡單執行 docker rmi [imageID] 命令便可

$ docker rmi 5a3221f0137b fce289e99eb9
複製代碼

Dockerfile實踐

Dockerfile 是由一系列的參數、命令構成的可執行腳本,用來構建、定製 Docker 鏡像。本節經過一個 Node.js 的簡單項目爲例,介紹下如何編寫 Dockerfile 文件、如何在 Docker 容器裏運行 Node.js 項目。

Nodejs項目準備

/usr/src/nodejs/hello-docker 目錄下新建 app.js

// /usr/src/nodejs/hello-docker/app.js
const http = require('http');
const PORT = 30010;

const server = http.createServer((req, res) => {
    res.end('Hello Docker');
})

server.listen(PORT, () => {
    console.log('Running on http://localhost:', PORT);
});
複製代碼

/usr/src/nodejs/hello-docker 目錄下新建 package.json

// /usr/src/nodejs/hello-docker/package.json
{ 
  "name": "hello-docker", 
  "version": "1.0.0",
  "description": "", 
  "author": "May",
  "main": "app.js",   
  "scripts": { 
    "start": "node app.js"
  },
  "dependencies": { 
    
  }
}
複製代碼

Dockerfile 編寫

首先在項目根目錄下建立 .dockerignore 文件,把不須要打包進 Docker Image 裏的文件進行過濾

# /usr/src/nodejs/hello-docker/.dockerignore
.git
node_modules
複製代碼

Dockerfile

項目根目錄下新建 Dockerfile 文件

# /usr/src/nodejs/hello-docker/Dockerfile

FROM node:10.0

# 在容器中建立一個目錄
RUN mkdir -p /usr/src/nodejs/ 
# 定位到容器的工做目錄
WORKDIR /usr/src/nodejs/ 
# RUN/COPY 是分層的,package.json 提早,只要沒修改,就不會從新安裝包
COPY package.json /usr/src/app/package.json RUN cd /usr/src/app/ RUN npm i 
# 把當前目錄下的全部文件拷貝到 Image 的 /usr/src/nodejs/ 目錄下
COPY . /usr/src/nodejs/ 

EXPOSE 30010
CMD npm start 複製代碼
  • FROM:FROM 是構建鏡像的基礎源鏡像,該 Image 文件繼承官方的 node image
  • RUN:後面跟的是在容器中執行的命令
  • WORKDIR:容器的工做目錄
  • COPY:拷貝文件至容器的工做目錄下,.dockerignore 指定的文件不會拷貝
  • EXPOSE:將容器內的某個端口導出供外部訪問
  • CMD:Dockerfile 執行寫一個 CMD 不然後面的會被覆蓋,CMD 後面的命令是容器每次啓動執行的命令,多個命令之間可使用 && 連接,例如 CMD git pull && npm start

構建 hello-docker 鏡像文件

Dockerfile 文件建立好以後,使用 docker image build 命令建立鏡像文件,-t 參數用來指定鏡像的文件名稱,最後一個 . 也不要省略,表示 Dockerfile 文件的所在目錄

$ docker image build -t hello-docker .
複製代碼

執行以上命令以後,咱們來查看下新生成的鏡像文件 hello-docker

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-docker        latest              6b1c2775591e        4 minutes ago       675MB
node                10.0                1c1272350058        16 months ago       675MB
複製代碼

運行容器

鏡像構建成功以後經過 docker container run 命令來生成一個容器,幾個參數說明:

  • -d:代表容器的運行模式在後臺
  • -p:端口映射,將本機的 30000 端口映射到容器的 30010 端口,這樣在外網就可經過 30000 端口訪問到咱們的服務
  • hello-docker:爲咱們的鏡像名字
$ docker container run -d -p 30000:30010 hello-docker
複製代碼

執行以上命令以後經過 docker ps 查看咱們剛剛運行的容器信息

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                      NAMES
c2891d477edf        hello-docker        "/bin/sh -c 'npm sta…"   15 seconds ago      Up 14 seconds       0.0.0.0:30000->30010/tcp   pedantic_mestorf
複製代碼

不出什麼意外,此時咱們的 Node.js 服務已經運行在 Docker 容器的虛擬環境裏了,訪問 curl http://localhost:30000 能夠進行測試。

$ curl http://localhost:30000
Hello Docker
複製代碼

檢查日誌

查看運行日誌,「c2891d477edf」 爲容器 ID

$ docker logs -f c2891d477edf

> hello-docker@1.0.0 start /usr/src/nodejs/hello-docker
> node app.js

Running on http://localhost: 30010
複製代碼

容器進入退出

爲了方便排查內部容器文件,能夠經過 docker exec -it c2891d477edf /bin/sh 命令進入容器,c2891d477edf 爲容器 ID

$ docker exec -it c2891d477edf /bin/sh
$ ls # 列出目錄列表
Dockerfile  app.js  package-lock.json  package.json
複製代碼

因爲咱們已經啓動了 hello-docker 這個服務,在容器裏再次操做 node app.js 就會報端口衝突

$ node app
events.js:167
      throw er; // Unhandled 'error' event
      ^

Error: listen EADDRINUSE :::30010
複製代碼

按下 Ctrl + d (或者輸入 exit)退出容器

Registry實踐

Registry 是一個註冊服務器,是一個集中存放鏡像倉庫的地方,這裏着重介紹下 Docker Hub,它是官方維護的一個公共倉庫,咱們的大部分需求也均可從這裏下載。

註冊 Docker 帳號

在開始以前你須要先去 Docker 官網註冊一個帳號 hub.docker.com/ 後續講解發布鏡像須要用到

鏡像搜索

使用 docker search 鏡像名稱 能夠搜索你須要的鏡像,搜索結果會根據 STARS 進行排序

$ docker search nginx
NAME                              DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
nginx                             Official build of Nginx.                        11935               [OK]                
jwilder/nginx-proxy               Automated Nginx reverse proxy for docker con…   1651                                    [OK]
richarvey/nginx-php-fpm           Container running Nginx + PHP-FPM capable of…   740                                     [OK]
...
複製代碼

鏡像拉取

搜索到須要的鏡像後執行 docker pull 命令拉取鏡像

$ docker pull nginx
複製代碼

發佈鏡像實現共享

  1. 登錄 Docker,已登錄的能夠忽略這一步
$ docker login
複製代碼
  1. 爲本地鏡像打標籤,tag 不寫默認爲 latest
# docker image tag [imageName] [username]/[repository]:[tag]
$ docker image tag hello-docker mayjun/hello-docker
複製代碼
  1. 發佈鏡像文件
# docker image push [username]/[repository]:[tag]
$ docker image push mayjun/hello-docker
複製代碼

鏡像發佈成功以後,在本身的我的用戶下也能夠看到鏡像信息

圖片描述

若是你想在別的機器上也使用這個鏡像,直接 docker pull 拉取便可,實現鏡像的共享。

DockerCompose實踐

Compose 是 Docker 官方開源的一個項目,能夠管理多個 Docker 容器組成一個應用,例如 Web 服務,除了服務自己還有數據庫、Redis、Nginx 等一系列相關聯服務須要安裝。

有個 Compose 的支持,咱們只須要定義一個 YAML 格式的配置文件(docker-compose.yml),來編寫一個項目所須要的多個容器配置及調用關係,經過簡單的命令便可同時開始或者關閉這些容器。

二進制安裝

github.com/docker/comp…

# compose 下載以後經過管道的方式輸入至 /usr/local/bin/docker-compose
# uname -s 查找是什麼系統,例如:Linux
# uname -m 查找是什麼版本,例如:x86_64
$ curl -L https://github.com/docker/compose/releases/download/1.25.0-rc2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

# 把這個文件變成可執行的
$ chmod +x /usr/local/bin/docker-compose
複製代碼

查看安裝是否成功

$ docker-compose --version 
docker-compose version 1.25.0-rc2, build 661ac20e
複製代碼

Docker Compose 搭建 WordPress 我的博客

WordPress 是一個免費開源的我的博客系統,使用的也是比較多的,而且也有 Docker 鏡像,使用 Docker 部署仍是很是簡單的。

在 /usr/src/wordpress 目錄下,創建 docker-compose.yml 配置文件,寫入以下內容:

mysql:
 image: mysql:5.7
 environment:
 - MYSQL_ROOT_PASSWORD=123456
 - MYSQL_DATABASE=wordpress
web:
 image: wordpress
 links:
 - mysql
 environment:
 - WORDPRESS_DB_PASSWORD=123456
 ports:
 - "192.168.6.128:8080:80"
 working_dir: /var/www/html
 volumes:
 - wordpress:/var/www/html
複製代碼

啓動容器,瀏覽器輸入 http://192.168.6.128:8080 便可看到效果,能夠親自實踐下

# -d 參數表示後臺啓動
$ docker-compose up -d 
複製代碼

關閉容器,執行如下命令須要在 docker-compose.yml 配置文件同級目錄下

$ docker-compose stop
複製代碼

本文是做者 「五月君」 在實踐 Docker 過程當中的一些知識總結,剛開始也是從零開始的,若是你想學習 Docker 不知道該如何入手,能夠參考本文,後續還會有 Docker 在應用程序中的實踐分享,感興趣的能夠關注公衆號 「Nodejs技術棧」 Github: github.com/Q-Angelo/No… 獲取最新消息

相關文章
相關標籤/搜索