1.03 docker的映象和容器
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
相關文章
- Docker--容器和映象的使用Docker
- docker 映象和容器的基本命令Docker
- docker 批量刪除容器和映象Docker
- Docker 最常用的映象命令和容器命令Docker
- Docker——理解好映象和容器的關係Docker
- docker刪除所有容器和映象命令Docker
- Docker 匯出容器 / 映象Docker
- docker容器與映象的區別Docker
- Docker容器和映象的建立/匯出/刪除/匯入Docker
- 容器技術之Docker映象Docker
- 還不明白 Docker 的映象跟容器?Docker
- 細述docker容器建立MariaDB映象Docker
- docker學習6:在Centos7 更改Docker預設映象和容器的位置DockerCentOS
- 淺述容器和容器映象的區別
- 通過容器提交映象(docker commit)以及推送映象(docker push)筆記DockerMIT筆記
- Docker掃盲之容器與映象的基本使用Docker
- Docker配置本地映象與容器的儲存位置Docker
- docker 修改容器內容後更新映象的流程Docker
- Linux檢查Docker映象,容器的磁碟空間LinuxDocker
- 實踐:Docker容器與映象管理Docker
- Docker 映象及容器操作命令介紹Docker
- docker修改預設映象、容器路徑Docker
- HyperLedger/Fabric SDK使用Docker容器映象快Docker
- Docker容器 關於映象構建的安全問題Docker
- 突破難關:Docker映象和容器的區別以及構建的最佳實踐Docker
- Docker 基礎-映象&容器&網路&儲存Docker
- 容器技術之Docker私有映象倉庫docker-distributionDocker
- 對容器映象的思考和討論
- 批量刪除容器和映象
- 容器和容器映象的區別,您真的瞭解嗎
- 如何配置極狐GitLab Docker 容器映象倉庫GitlabDocker
- 容器技術之Docker私有映象倉庫harborDocker
- Docker學習筆記:映象、容器、資料卷Docker筆記
- 細述docker容器中建立SSH服務映象Docker
- 《前端運維》三、Docker--1映象與容器前端運維Docker
- docker容器 如何精簡映象減小體積Docker
- Docker執行基於ubuntu映象的容器後沒有ifconfig和ping的解決方法DockerUbuntu
- Docker | Docker技術基礎梳理(四) - 深入理解映象與容器Docker