1.03 docker的映象和容器

尹成發表於2018-12-10

1.docker的底層技術實現架構

  • docker提供了一個開發、打包、執行app的平臺
  • 把app和底層infrastructure(基礎設施)隔離開
    在這裡插入圖片描述

2.docker engine

  • docker engine是核心,裡面有後臺程式,叫dockerd,提供了REST API介面,還提供了CLI介面,可以看出,docker就是一種C/S的架構

3.整體架構

  • Client是客戶端,命令列用的命令
  • 中間docker_host是安裝docker的機器,可以與Client在同一臺機器,這裡面重要的概念是映象(Images)和容器(Containers)
  • Registry是儲存映象公共的伺服器,類似於Github,可以儲存和獲取Registry

4.底層技術支援

  • Namespaces:做隔離pid、net、ipc、mnt、uts,隔離後,可以啟多個容器
  • Control groups:做資源限制,可以讓一個容器只用200M記憶體,另一個用300M等
  • Union file systems:Container和image的分層

5.docker image概述

  • 檔案和meta data的集合(root filesystem)
  • 分層的,並且每一層都可以新增、改變、刪除檔案,成為一個新的image
  • 不同的image可以共享相同的layer(層)
  • image本身是read-only的
  • linux有系統空間和使用者空間,在系統空間之上,建立不同發行版本的image,在baseImage之上可以進行新增和刪除檔案,例如安裝mysql,就會產生新的一層,成為一個新的image
  • 檢視本地存在的image
    在這裡插入圖片描述
  • 寫一個Dockerfile
#選擇了一個baseImage
FROM ubuntu
#在image之上執行了update和install
RUN apt-get update && apt-get install -y stress
#要暴露的埠
EXPOSE 6379
#程式入口
ENTRYPOINT ["/usr/bin/redis-server"]
  • 也可以從Registry拉取image,類似於github
  • 例如拉取一個image
    在這裡插入圖片描述
  • 檢視本地image
    在這裡插入圖片描述
  • 點選Explore,可以檢視官方提供的一些image
    在這裡插入圖片描述
  • 點進某個image,下載時,參照右邊的命令就可以,也可以點選左邊Tag,根據版本號獲取
    在這裡插入圖片描述
    在這裡插入圖片描述

6.製作baseImage

  • baseImage:基於系統的基礎映象
  • 建立檔案
    在這裡插入圖片描述
#include<stdio.h>
int main(){
  printf("hello docker\n");
}
  • 安裝依賴包
    在這裡插入圖片描述
  • 編譯.c檔案
    在這裡插入圖片描述
  • 可以簡單執行一下
    在這裡插入圖片描述
  • 在當前目錄建立檔案Dockerfile
    在這裡插入圖片描述
#從頭開始
FROM scratch
#加到根目錄
ADD hello /
#執行command,就是根目錄下的hello
CMD ["/hello"]
  • 製作baseImage
    在這裡插入圖片描述
  • 檢視製作的image
    在這裡插入圖片描述
  • 檢視image分層
    在這裡插入圖片描述
  • 執行docker
    在這裡插入圖片描述

7.container概念和使用

  • 列舉當前本地正在執行的container容器
    在這裡插入圖片描述
  • 列舉出所有容器,包括正在執行的和退出的
    在這裡插入圖片描述
  • 執行一個不存在的image,檢視container執行並釋放
    在這裡插入圖片描述
  • 互動式執行容器
    在這裡插入圖片描述
  • 克隆一個會話,檢視當前正在執行的container
    在這裡插入圖片描述
  • 可以在裡面進行centOS相關操作,退出後
    在這裡插入圖片描述
  • 檢視所有docker命令,分為Management Commands和Commands
    在這裡插入圖片描述
    在這裡插入圖片描述
    在這裡插入圖片描述
  • 刪除container
    在這裡插入圖片描述
  • 簡寫:刪除一個container
    在這裡插入圖片描述
  • 簡寫:刪除一個image
    在這裡插入圖片描述
  • 列舉出所有的containerID
    在這裡插入圖片描述
  • 批量清理執行釋放後的container
    在這裡插入圖片描述
  • container有正在執行的,還有未執行的情況下,先列出status=exited的container,然後最後只刪除已經執行結束的container
    在這裡插入圖片描述
    在這裡插入圖片描述
    在這裡插入圖片描述
    在這裡插入圖片描述
    在這裡插入圖片描述

8.建立Image的兩種方式

  • 第一種
    在這裡插入圖片描述
  • 執行centos
    在這裡插入圖片描述
  • 安裝上傳下載工具
    在這裡插入圖片描述
  • 退出container
    在這裡插入圖片描述
  • 根據安裝了lrzsz的image,建立新的image
    在這裡插入圖片描述
  • 檢視新建立的image,與原本centos大小不一樣
    在這裡插入圖片描述
    在這裡插入圖片描述
  • 第二種
    在這裡插入圖片描述
  • 建立目錄
    在這裡插入圖片描述
  • 建立Dockerfile檔案
FROM centos
RUN yum -y install lrzsz
  • 建立image
    在這裡插入圖片描述
  • 在一個臨時的container中安裝lrzsz
    在這裡插入圖片描述
  • 檢視建立的image
    在這裡插入圖片描述
  • 建議採用第二種方式建立image,分享時,可以將Dockerfile分享給別人,不涉及共享層

9.Dockerfile詳解

  • FROM
  • 為了安全,儘量使用官方的image作為base image
FROM scratch			#從頭製作base image
FROM centos			#使用已有的base image
FROM ubuntu:14.04	#指定使用的base image的版本
  • LABEL
  • 定義了一些說明資訊
  • LABEL Metadata不可少,就像程式碼的註釋
LABEL maintainer="sjc@126.com"
LABEL version="1.0"
LABEL description="This is description"
  • RUN
  • 每執行一條RUN,就會多一層
  • 為了美觀,儘量避免無用的分層
  • 用&&合併語句,用反斜槓合併多條命令為一行
#反斜線換行
RUN yum -y update && yum -y install lrzsz \
	net-tools
RUN apt-get -y update && apt-get -y install lrzsz \
	net-tools
#/bin/bash是shell的一種
RUN /bin/bash -c 'source $HOME/.bashrc;echo $HOME'
  • WORKDIR
  • 進入或建立目錄
  • 使用WORKDIR,不要使用RUN cd
  • 儘量使用絕對目錄
WORKDIR /root		#進入/root目錄
WORKDIR /test		#如果沒有會自動建立/test目錄
WORKDIR demo
RUN pwd			#輸出結果應該是/test/demo
  • ADD and COPY
  • 將本地的檔案,新增到Docker image裡
  • ADD還可以解壓縮到指定目錄
  • 大部分情況下,優先使用COPY
ADD hello /
ADD test.tar.gz /	#新增到根目錄並解壓
WORKDIR /root
COPY hello test/  #最終hello會在目錄 /root/test/hello 中
  • ENV
  • 可以增加Dockerfile的可維護性,儘量使用
ENV MYSQL_VERSION 5.6					#設定常量
RUN apt-get -y install mysql-server="${MYSQL_VERSION}" \
	&& rm -rf /var/lib/apt/lists/*	#引用常量

10.Dockerfile——CMD vs ENTRYPOINT

  • 先介紹Shell和Exec格式
#Shell格式
RUN apt-get -y install lrzsz
CMD echo "hello docker"
ENTRYPOINT echo "hello docker"
#Exec格式,需要特定的格式
RUN ["apt-get","-y","install","lrzsz"]
CMD ["/bin/echo","hello docker"]
ENTRYPOINT ["/bin/echo","hello docker"]
  • ENTRYPOINT(比CMD使用的多)
  • 設定容器啟動時執行的命令
  • 讓容器以應用程式或者服務的形式執行
  • 不會被忽略,一定會執行
  • 演示如下兩個Dockerfile構建出的image,執行有什麼不同,shell和exec的區別
#Dockerfile1,shell格式
FROM centos
ENV name Docker
ENTRYPOINT echo "hello $name"
#Dockerfile2,exec格式
FROM centos
ENV name Docker
ENTRYPOINT ["/bin/echo","hello $name"]
  • 先使用Dockerfile1建立檔案,然後構建如下
    在這裡插入圖片描述

  • 執行構建出來的image
    在這裡插入圖片描述

  • 用Dockerfile2建立檔案,然後構建如下
    在這裡插入圖片描述

  • 執行構建出來的image
    在這裡插入圖片描述

  • linux能夠識別shell,替換成ENV並執行

  • 修改Dockerfile如下,使之能夠識別Exec格式的命令

  • 重新構建和執行image看效果

FROM centos
ENV name Docker
#-c指明引數,-c後的命令要作為一個命令,在一個引號裡
ENTRYPOINT ["/bin/bash","-c","echo hello $name"]
  • CMD
  • 設定容器啟動後預設執行的命令和引數
  • 如果docker指定了其他命令,CMD命令被忽略
  • 如果定義了多個CMD,只有最後一個會執行(可以演示)
  • 如下Dockerfile,與上面ENTRYPOINT的效果一樣
FROM centos
ENV name Docker
CMD echo "hello $name"
  • 實踐:再建立另一個ENTRYPOINT的image,執行對比
#CMD
FROM centos
ENV name Docker
CMD echo "hello $name"
#ENTRYPOINT
FROM centos
ENV name Docker
ENTRYPOINT echo "hello $name"
  • 構建image
    在這裡插入圖片描述
    在這裡插入圖片描述
  • 執行image,建立container,CMD的執行列印命令,被/bin/bash覆蓋了
    在這裡插入圖片描述
    在這裡插入圖片描述

11.分享docker image

  • image名字一定要以自己docker hub的使用者名稱開頭
  • 檢視所有image
    在這裡插入圖片描述
  • 登入,輸入使用者名稱和密碼
    在這裡插入圖片描述
  • 上傳自己的image
    在這裡插入圖片描述
  • 刪除本地的image
    在這裡插入圖片描述
  • 從docker hub下載自己上傳的image
    在這裡插入圖片描述

12.分享Dockerfile

  • 直接分享image不安全
  • 分享docker image不如分享Dockerfile
  • 點選如下
    在這裡插入圖片描述
  • 與gitHub賬戶關聯
    在這裡插入圖片描述
    在這裡插入圖片描述
    在這裡插入圖片描述
    在這裡插入圖片描述
    在這裡插入圖片描述

13.搭建私有docker registry

  • github是公開的,也可以建立自己的倉庫
  • 官方提供了搭建私有倉庫的方法
  • docker hub搜尋registry如下
    在這裡插入圖片描述
  • 開啟後,可以檢視快速搭建本地私有倉庫的方法,執行如下命令即可
    在這裡插入圖片描述
  • 開啟另一臺安裝並啟動了docker的虛擬機器,關機,複製當前機器就可以
    在這裡插入圖片描述
  • 檢視啟動了的registry
    在這裡插入圖片描述
  • 在之前的機器上安裝telnet,檢視埠是否可以訪問
    在這裡插入圖片描述
    在這裡插入圖片描述
  • 在之前機器上重新構建image,IP是倉庫機器的IP
    在這裡插入圖片描述
  • 將image放到本地私有的registry,但此時會報錯,不可信任
    在這裡插入圖片描述
  • 本機建立如下檔案
    在這裡插入圖片描述
  • 加入如下內容,IP是倉庫機器的IP
{"insecure-registries":["192.168.174.142:5000"]}

在這裡插入圖片描述

  • 修改docker的啟動檔案
    在這裡插入圖片描述
  • 加入如下內容
EnvironmentFile=-/etc/docker/daemon.json

在這裡插入圖片描述

  • 重啟docker服務
    在這裡插入圖片描述
  • 檢視第二臺機器的registry中有什麼 http://192.168.174.142:5000/v2/_catalog
    在這裡插入圖片描述
  • 第一臺機器將image放到本地私有的registry,IP是倉庫機器的
    在這裡插入圖片描述
  • 瀏覽器再次檢視如下
    在這裡插入圖片描述
  • 刪掉第一臺機器的image
    在這裡插入圖片描述
  • 從第二臺機器的私有倉庫中下載image
    在這裡插入圖片描述

14.Dockerfile案例

  • 建立python檔案
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
    return "hello docker"
if __name__ == '__main__':
    app.run()
  • 執行app.py
    在這裡插入圖片描述
  • 安裝flask
    在這裡插入圖片描述
  • 安裝pip
    在這裡插入圖片描述
  • 安裝flask
    在這裡插入圖片描述
  • 再次執行app.py
    在這裡插入圖片描述
  • 瀏覽器訪問如下,這就建立好了一個最簡單的web應用
    在這裡插入圖片描述
  • 將這個web應用打包成docker image,將image執行
  • 建立目錄
    在這裡插入圖片描述
  • 將app.py移到該目錄下
    在這裡插入圖片描述
  • 建立Dockerfile
    在這裡插入圖片描述
FROM python:2.7
LABEL maintainer="Sun sjc_job@126.com"
RUN pip install flask
COPY app.py /app/
WORKDIR /app
EXPOSE 5000
CMD ["python","app.py"]
  • 構建image
    在這裡插入圖片描述
  • 執行image
    在這裡插入圖片描述
  • 後臺執行image
    在這裡插入圖片描述
  • 檢視程式
    在這裡插入圖片描述

15.執行中對container操作

  • 後臺執行image
    在這裡插入圖片描述
  • 檢視所有container
    在這裡插入圖片描述
  • 互動式執行
  • 進入執行中的容器執行/bin/bash
    在這裡插入圖片描述
  • 檢視程式
    在這裡插入圖片描述
  • 退出
    在這裡插入圖片描述
  • 進入container的python shell
    在這裡插入圖片描述
    在這裡插入圖片描述
  • 檢視執行中容器的ip
    在這裡插入圖片描述
  • 停止container
    在這裡插入圖片描述
  • 刪除所有退出狀態的container
    在這裡插入圖片描述
  • 為container指定名稱並啟動
    在這裡插入圖片描述
    在這裡插入圖片描述
  • 名字也是唯一的,可以用名字停止
    在這裡插入圖片描述
  • 用名字啟動
    在這裡插入圖片描述
  • 顯示容器的詳細資訊
    在這裡插入圖片描述
  • 檢視container的執行日誌
    在這裡插入圖片描述
  • 修改container的名稱
    在這裡插入圖片描述

16.Dockerfile案例2

  • 方式一:
    在這裡插入圖片描述
  • 安裝stress
    在這裡插入圖片描述
  • 檢視stress位置
    在這裡插入圖片描述
  • 檢視幫助文件
    在這裡插入圖片描述
  • 啟動一個worker,佔用256M記憶體
    在這裡插入圖片描述
  • 指定記憶體超出了容器記憶體
    在這裡插入圖片描述
  • 方式二:
    在這裡插入圖片描述
  • 建立Dockerfile
    在這裡插入圖片描述
	FROM ubuntu
	RUN apt-get update && apt-get -y install stress
	#執行容器,執行stress
	ENTRYPOINT ["/usr/bin/stress"]
	#定義引數,[]是空,等待接收引數
	CMD []
  • 構建image
    在這裡插入圖片描述
  • 直接互動執行,類似於檢視幫助文件
    在這裡插入圖片描述
  • 後面直接加引數執行容器
    在這裡插入圖片描述

17.對容器資源限制

  • 虛擬機器可以對資源進行限制,容器也一樣可以
  • 檢視幫助文件
    在這裡插入圖片描述
  • 執行stress,200+200,用了400M記憶體
    在這裡插入圖片描述
  • 退出時如果卡死,開啟另一個會話,檢視docker程式並關閉
    在這裡插入圖片描述
  • 執行一個500M記憶體的程式,顯示記憶體不夠,證明記憶體限制生效
    在這裡插入圖片描述
  • 對CPU的限制
  • 限制CPU的使用,這裡是限制相對權重,例如一個容器權重10,另一個5,第一個是第二個的二倍
  • 開三個視窗,前兩個視窗執行指令CPU,第三個視窗top檢視記憶體使用
    在這裡插入圖片描述
    在這裡插入圖片描述
    在這裡插入圖片描述
  • 先執行第一視窗,然後檢視top
    在這裡插入圖片描述
  • 再執行第二視窗,檢視top,兩個容器佔用的CPU是有權重的
    在這裡插入圖片描述
  • 可以給重要的容器設定多一點,就等於設定了優先順序
  • 底層技術支援:
    • Namespaces:做隔離pid、net、ipc、mnt、uts
    • Control groups:做資源限制
    • Union file systems:container和image的分層

學院Go語言視訊主頁
https://edu.csdn.net/lecturer/1928

[清華團隊帶你實戰區塊鏈開發]
(https://ke.qq.com/course/344443?tuin=3d17195d)
掃碼獲取海量視訊及原始碼 QQ群:
721929980
在這裡插入圖片描述

相關文章