Docker基礎概念與入門

一、Docker簡介

1. 什麼是Docker?

docker的官網是https://www.docker.com/
Docker官網有這麼一句話,這句話很好的說明了Docker技術的目的與優勢,即讓開發者更多的關注應用程序,更少的關心運行環境差異,並且縮短代碼從開發、測試、發佈的週期,讓應用程序具備可移植性,易於構建,並易於協作。
img-1

Docker是一個應用容器引擎 ,基於Go 語言並遵從 Apache2.0 協議開源。

2. 什麼是容器

既然Docker是一個應用容器引擎,那麼什麼又是容器呢?
考慮一下你有沒有碰到這種問題,明明在自己電腦上運行好好的程序,部署到測試環境發現運行出問題了。

測試:你的代碼有bug
開發:怎麼可能,我自己測試過,好好的,你環境有問題吧?你會用嗎?
你花了半個小時,發現是測試環境上有個參數沒有配置,然後你解決了這個問題,測試小姐姐誇了你一番,但是確打亂了你的思路,本來打算下班之前搞定的一個需求,就只能下班之後加班或者拖到第二天了。

一個可用軟件的交付過程,包含兩個部分,開發和維護,不幸的是,我們很難保證軟件開發、測試和運行階段的軟件能夠在一模一樣的環境下運行,很多時候我們不得不花大量的時間去配置環境和教別人配置環境。
並且,當服務器從單機擴展到分佈式集羣模式,或者我們在交付軟件時,需要重新給客戶搭建一套獨立的環境時,想象一下需要再每臺服務器上都進行配置,這多麼讓人頭大啊。

容器: 簡單的來說,一個容器包含了程序運行的時的完整環境,除了應用程序本身外,這個程序全部的依賴、配置等都被統一打包到了一起。

大部分容器實現技術基於開發標準,可以運行在所有主流的Linux發行版、windows等操作系統中。通過容器化技術,操作系統發行版本和其他基礎環境造成的差異,都被抽象掉了。

那如果這樣的話,容器豈不是跟虛擬機是一樣的了?
其實docker與虛擬機是類似的東西,虛擬機是在物理硬件上虛擬運行一臺或多臺獨立虛擬機器。我們拿這個虛擬機就可以在安裝了虛擬機軟件的其他電腦上直接運行,裏面的東西就不用我們來回安裝和配置了。

虛擬機是運行在物理硬件之上,而容器則是直接運行在操作系統內核之上的用戶空間,因此容器虛擬化也被稱爲操作系統虛擬化,容器技術可以讓多個獨立的用戶空間運行在同一臺宿主機上。
如果用一張圖來說明的話,應該是這樣的:
img-2

與傳統的虛擬技術相比,容器運行時使用的是操作系統的系統調用接口,而不需要模擬層和管理層。這也降低了運行單個容器所需的開銷,使得宿主機中運行更多的容器。由於虛擬機在啓動時會通過管理層(hypervisor layer)給虛擬機分配物理資源(CPU、磁盤、網絡、內存等),而容器共享宿主機操作系統內核,所以更加輕量化、啓動速度更快。
儘管容器化的思想有着光輝的歷史,但容器技術複雜性導致容器並沒有得到廣泛的認可,容器本身比較複雜、不易安裝、管理和自動化也很困難。而Docker就是爲了改變這一切而生的。

docker本身並不是容器,而是創建和管理容器的工具。

3. docker的組件

img-3
Docker核心組件包括:

Docker引擎
Docker鏡像
Docker容器
Registry(鏡像倉庫)

二、Docker安裝與Docker管理命令

Docker支持很多的系統,由於系統衆多,本文僅以centos7.6安裝進行示例。
更多的方法可以參考鏈接:https://yq.aliyun.com/articles/110806?spm=5176.8351553.0.0.15d51991WpnOIc

1. 安裝Docker的先決條件

  • 運行64位CPU架構的計算機
  • 運行Linux3.8以上的內核版本
  • 內核必須支持一種適合的存儲驅動
  • 內核必須支持並開啓cgroup和命名空間(namespace)

2.Centos 7 安裝Docker

# step 1: 安裝必要的一些系統工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# Step 2: 添加軟件源信息
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# Step 3: 更新並安裝 Docker-CE
sudo yum makecache fast
sudo yum -y install docker-ce
# Step 4: 開啓Docker服務
sudo service docker start

安裝完成後可以運行docker version 檢查是否安裝成功
img-4

3、常用的docker容器管理命令

這一部分,我們將按照: 查找> 下載> 運行> 停止> 刪除,這個步驟去運行一個實際的nginx容器

1)docker狀態管理

systemctl enable docker #開機自啓動docker
systemctl start docker  #啓動docker
systemctl status docker #查看docker狀態
systemctl stop docker #停止docker
systemctl restart docker #重啓docker

2)下載nginx鏡像

docker search nginx #查找nginx鏡像

其中OFFICIAL列表示是否爲官方鏡像文件
img-5

docker pull nginx #下載nginx鏡像

img-6
下載鏡像完成後會有打印Status: Downloaded newer image for docker.io/nginx:latest
docker pull 命令可以攜帶版本號,如docker pull nginx:5.0,不帶版本號時,默認表示拉取最新版本 docker pull nginx:latest

docker images #查看有哪些鏡像

img-7

3)啓動容器

啓動容器的命令是 docker run,對於該命令詳細的使用方法,可以使用

docker run --help
-p 指定服務器端口映射 例如 -p 8080:80 第一個參數8080代表宿主機端口,後一個參數80代表是容器端口
-d 表示以守護進程模式啓動,將容器啓動到後臺
–name 表示爲容器起的名字,可以爲容器制定一個名稱。不帶該參數時,docker會爲我們創建的每一個容器生成一個隨機的名字

img-8
我們使用以下命令啓動一個nginx容器

docker run -p 8000:80 --name mynginx -d nginx

img-9

我們驗證一下nginx容器功能是否正常,訪問宿主機IP地址80端口
img-10

OK,Nginx訪問正常,這樣一個nginx的容器就運行起來了

4)查看容器

查看容器的命令爲docker ps 對於該命令詳細的使用方法,可以使用docker ps --help來查看

docker ps #查看目前工作的容器,加 -a 查看所有運行過的容器

img-11

5)與容器交互

容器運行起來之後,我們怎麼知道容器內部在幹什麼呢?

docker logs <容器名或容器ID> 可以用來獲取容器的日誌,加 -f 參數可以跟蹤容器日誌

img-12
當然,可以已查看容器內部的進程,命令是:

docker top <容器名或容器ID>

img-13

docker stats 命令可以用來統計Docker信息

img-14
當然,除了查看docker內部的進程信息之外,我們還可以在容器內部運行額外新的進程,命令是:

docker exec 對於該命令詳細的使用方法,可以使用docker exec --help來查看
-d 表示運行一個後臺進程
-t 表示爲我們執行的進程創建TTY終端
-i 表示捕獲STDIN,即我們的輸入

img-15

例如,我們想要進入容器內部,則可以運行以下命令,表示在mynginx容器中運行bash命令,並啓動TTY終端捕獲我們的輸入

docker exec -it mynginx bash

img-16
如果想退出的話,直接輸入exit回車即可。

6)容器狀態管理

docker stop <容器名或容器ID> 停止一個正在運行的容器
docker start <容器名或容器ID> 運行一個已經停止的容器
docker restart <容器名或容器ID> 重啓容器
docker pause <容器名或容器ID> 暫停容器
docker pause <容器名或容器ID> 容器取消暫停

7)自動重啓容器

如果由於某種錯誤而導致容器停止運行,還可以在docker run命令中指定–restart標誌來讓Docker自動重啓該容器

–restart=always 總是自動重啓該容器
–retart=on-failure:5 當容器退出代碼未非0時,自動重啓,最多重啓5次(退出代碼0,表示正常退出)

8)docker詳細信息

docker inspect <容器名或容器ID>

使用 docker inspect 來查看 Docker 的底層信息。它會返回一個 JSON 文件記錄着 Docker 容器的配置和狀態信息。

9)刪除容器

當容器不再使用時,可以使用docker rm 來刪除它們

docker kill <容器名或容器ID> 殺死正在運行的容器
docker rm <容器名或容器ID> 刪除已經停止的容器
docker kill $(docker ps -a -q) 殺死所有正在運行的容器
docker rm $(docker ps -a -q) 刪除所有已經停止的容器

三、Docker鏡像倉庫與鏡像構建

之前,我們學習了Docker的安裝與Docker容器管理的命令,這一部分,我們將學習Docker鏡像
Docker鏡像:用來啓動容器的 構建基石。

1)什麼是Docker鏡像

Docker鏡像是由文件系統疊加而成,最底層是一個引導文件系統,即bootfs,在第二層則是root文件系統,即rootfs,rootfs可以是一種或多種操作系統如Debian或ubuntu,用下圖來說明一下:
img-17
Docker將這樣堆疊的文件系統稱爲鏡像,一個鏡像可以放在另一個鏡像的頂部,位於下面的鏡像稱爲父鏡像,最底層的鏡像稱爲基礎鏡像。當從一個鏡像啓動容器時,Docker會在該鏡像的最頂層加載一個讀寫文件系統,我們在Docker中運行的程序就是在這個讀寫層中執行的。

2)鏡像倉庫

鏡像保存在倉庫中,倉庫存在於Registry中,默認的Registry是由Docker公司運營的公共Registry服務,即DockerHub https://hub.docker.com/ ,鏡像常用的命令如下:

docker search <鏡像名>:<鏡像標籤> 鏡像查找
docker pull <鏡像名>:<鏡像標籤> 鏡像拉取
docker images 列出所有鏡像

對於命令詳細的使用方法,可以使用docker <命令> --help來查看
當使用docker run命令從鏡像啓動一個容器時,如果鏡像不存在於本地,Docker會先從倉庫中下載該鏡像。

3)構建鏡像

鏡像倉庫裏的鏡像爲標準鏡像,那麼我們如何修改定製爲自己的鏡像呢?
構建鏡像有兩種方法

  1. dokcer commit命令
  2. docker build命令和Dockerfile文件

3.1) dokcer commit 構建鏡像

docker commit 構建鏡像之前,我們需要運行一個基於需要修改的鏡像容器.
以修改nginx鏡像爲例,通過修改nginx中的index.html,來定義我們自己的鏡像。

a. 我們先啓動一個nginx容器
docker run -d nginx
b. 然後進入容器進行修改,添加vim命令,並修改index.html文件爲 hello bird!
這樣就完成了我們想要的定製修改,那麼要怎麼保存這個修改爲私人鏡像呢?
c. docker commit ce96035e07d1 bird/nginx 將我們運行的容器保存爲新的鏡像

查看本地鏡像
img-18

運行我們新構建的鏡像

docker run -d --name mynginx -p80:80 bird/nginx

img-19
這樣這個自定義的鏡像就構建成功了

3.1) Dockerfile構建鏡像

推薦使用Dockerfile方式來進行構建鏡像,因爲它更加靈活和強大
docker build命令需要配合Dockerfile來使用,Dockerfile 是一個用來構建鏡像的文本文件,文本內容包含了一條條構建鏡像所需的指令和說明。

FROM nginx

RUN apt update
RUN apt install vim -y
RUN echo "hello bird!" >/usr/share/nginx/html/index.html

我們還是先查看一下docker build —help 命令的使用方法
在Dockerfile目錄下執行

docker build -t birdlearn/mynginx:v2 .
-t 表示 鏡像名稱:鏡像標籤
. 表示上下文路徑爲當前目錄

執行命令後便開始進行鏡像的構建了
img-20
鏡像構建完成後,使用docker images 查看鏡像列表,可以看到我們構建的鏡像已經在本地倉庫了
img-21
運行我們剛剛構建的鏡像

docker run -p80:80 birdlearn/mynginx:v2

可以看到這個自定義構建的鏡像運行起來的容器,已經是我們修改後的效果了
img-22

擴展閱讀: Dockerfile 詳細用法 ————————————TODO

鏡像構建完成後,我們如果想要導出導入鏡像,則需要用到save、load命令,即
docker save
其中-o和>表示輸出到文件,nginx.tar爲目標文件,nginx:latest是源鏡像名(name:tag)

docker save -o nginx.tar nginx:latest
#或
docker save > nginx.tar nginx:latest 

docker load
其中-i和<表示從文件輸入。會成功導入鏡像及相關元數據,包括tag信息

docker load -i nginx.tar
#或
docker load < nginx.tar

鏡像文件可以導出導入,那麼容器能否導入導出呢?當然可以,容器的導入導出命令是 import 和 export,即:

docker import
docker import nginx-test.tar nginx:imp

docker export
docker export -o nginx-test.tar nginx-test

其中-o表示輸出到文件,nginx-test.tar爲目標文件,nginx-test是源容器名(name)

四、Docker的編排 Docker Compose

前面我們講到了docker的安裝與管理,並且知道了docker build 構建鏡像、docker run運行鏡像爲容器。但是當今軟件系統開發中,微服務架構的廣泛應用,使得一個應用系統一般包含很多的微服務,每個微服務一般都會啓動多個實例,如果每個微服務都需要我們手動啓動停止,那麼可以想象維護工作室多麼巨大的。

有沒有一個工具,可以讓我們輕鬆高效的管理容器呢?

答案就是Docker Compose工具,Docker Compose試一個多容器編排的工具。

Compose 項目是由Python編寫的,實際上就是調用了Docker服務提供的API來對容器進行管理,因此,只要所在的操作系統的平臺支持Docker API,就可以在其上利用Compose來進行編排管理。
Docker Compose將管理的容器分爲三層,分別是project、service、container
Docker Compose 運行目錄下的所有文件(docker-compose.yml)組成一個工程,一個工程包含多個服務,每個服務中定義了容器運行的鏡像、參數、依賴,一個服務可包括多個容器實例。

1、Docker Compose安裝

安裝 Docker Compose 可以通過下面命令自動下載適應版本的 Compose,併爲安裝腳本添加執行權限

sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose

爲docker-compose添加可執行權限

sudo chmod +x /usr/local/bin/docker-compose

安裝完成後檢查

docker-compose -v

2.docker-compose.yml文件

模板文件是Compose的核心,涉及的指令關鍵字比較多,但是大部分的指令與docker run相關的參數的含義是類似的詳見官方文檔
官網地址: https://docs.docker.com/compose/compose-file/

這裏講幾個常用的參數
docker-compose.yml的常見結構如下

version: '3'        # 表示該 Docker-Compose 文件使用的是 Version 3 file
services:           # 定義所有的 service 信息, services 下面的第一級別的 key 既是一個 service 的名稱
  blogweb:          # 指定服務名稱
    image: nginx    # 指定 docker 鏡像, 可以是遠程倉庫鏡像、本地鏡像
    build:          # 指定包含構建上下文的路徑, 或作爲一個對象,該對象具有 context 和指定的 dockerfile 文件以及 args 參數值
      context: .    # 指定構建上下文的路徑
      dockerfile: ./Dockerfiles/blogweb/Dockerfile  # 指定 context 指定的目錄下面的 Dockerfile(默認爲 Dockerfile)
    ports:          # 指定端口映射
      - "80:80"     # 容器的 80 端口和宿主機的 80 端口建立映射關係
      - "443:443”   # 容器的 443 端口和宿主機的 443 端口建立映射關係
    restart: always # 定義容器重啓策略 no 禁止自動重啓容器(默認) always 無論如何容器都會重啓 on-failure 當出現 on-failure 報錯時, 容器重新啓動
    links:          # 鏈接到其它服務中的容器,這樣當在本服務器中,建立與其他服務的域名
      - app_articles:app_articles
      - app_auth:app_auth
      - app_files:app_files
    depends_on:     # 定義容器啓動順序 (此選項解決了容器之間的依賴關係, 此選項在 v3 版本中
      - app_articles
      - app_auth
      - app_files

  mysql:
    build: 
      context: .
      dockerfile: Dockerfiles/mysql/Dockerfile  # 指定 Dockerfile 所在路徑
    ports:
      - "3306:3306"
    restart: always
    environment:    # 設置環境變量, environment 的值可以覆蓋 env_file 的值 (等同於 docker run --env 的作用)
      - [email protected]
    volumes:                            # 定義容器和宿主機的卷映射關係
      - ./data/mysql:/var/lib/mysql     # 映射容器內的 /var/lib/mysql 到宿主機的./data/mysql

3、docker-compose 命令

常見的命令如下

  build              Build or rebuild services
  config             Validate and view the Compose file
  create             Create services
  down               Stop and remove containers, networks, images, and volumes
  events             Receive real time events from containers
  exec               Execute a command in a running container
  help               Get help on a command
  images             List images
  kill               Kill containers
  logs               View output from containers
  pause              Pause services
  port               Print the public port for a port binding
  ps                 List containers
  pull               Pull service images
  push               Push service images
  restart            Restart services
  rm                 Remove stopped containers
  run                Run a one-off command
  scale              Set number of containers for a service
  start              Start services
  stop               Stop services
  top                Display the running processes
  unpause            Unpause services
  up                 Create and start containers
  version            Show the Docker-Compose version information

常用的命令

docker-compose up 創建並啓動指定yml文件中的容器  -d 指定以守護進程運行
docker-compose build 當yml文件有修改時,可以使用該命令重新構建鏡像
docker-compose up --build 攜帶build標識,會重新檢測yml變更,如果有變更則會重新構建
docker-compose stop 停止服務

五、Docker實戰,快速搭建一個博客系統

現在我們認識了Docker技術,也認識了Docker編排技術,那麼就讓我們實際部署一個由docker組成的系統吧。
我們以Birdlearn博客爲例,對原有服務進行Docker化。
Birdlearn 源碼地址

基於VUE框架開發的web前端 https://gitee.com/ikachu/BD-Blog
基於Tornado框架開發的後端服務 https://gitee.com/ikachu/bdblog-webapps
docker-compose源碼地址

博客架構
img-23
由於VUE生成的是靜態文件,所以我們只需要將WEB前端的文件掛載到Nginx服務下即可,整個系統需要7個服務,整個docker-compose文件目錄如下:
img-24
使用 docker-compose up -d 構建鏡像並啓動容器, 一鍵完成系統部署

六、Q&A

一個容器裏可以兩個進程嗎?

可以運行多個程序。一般可以用supervisor或腳本來拉起多個程序。但現在一般不建議這麼做。建議每個docker容器中只運行一個程序。

docker 部署中數據庫的連接

https://blog.csdn.net/qq_40770950/article/details/95001874

docker部署 日誌

https://www.cnblogs.com/jingjulianyi/p/6637801.html

docker如何暴露多個端口?

1、創建容器時指定
docker run -p <host_port1>:<container_port1> -p <host_port2>:<container_port2>
2、修改dockerfile expose所需要的端口,這樣可以免去-p參數。

docker獲取運行中容器的IP

docker inspect <容器名> | grep IPAddress

docker給運行中容器添加端口映射

將容器的8000端口映射到docker主機的8001端口
iptables -t nat -A DOCKER -p tcp --dport 8001 -j DNAT --to-destination 172.17.0.19:8000

docker端口映射時如何指定TCP/UDP

docker run -ti -d --name my-nginx5 -p 8099:80/tcp docker.io/nginx
docker run -ti -d --name my-nginx5 -p 8099:80/udp docker.io/nginx

參考:
docker官網
https://www.docker.com/
菜鳥教程 docker
https://www.runoob.com/docker/docker-tutorial.html
通俗講解:什麼是容器?爲什麼我們要使用它?
https://blog.csdn.net/i042416/article/details/85012912
容器化技術與Docker
https://www.jianshu.com/p/34efcaa92ae4
Docker CE 鏡像源站
https://yq.aliyun.com/articles/110806?spm=5176.8351553.0.0.15d51991WpnOIc

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章