引言
今天,是你去新公司入職的第一天。
早上起了個大早,洗漱幹淨帶着材料去新公司報道。簽完合同到達工位,開機,泡一杯紅糖枸杞(不要問我為什麼,我也不知道。。。)。然後開始下載下傳 vscode、chrome、nodejs,配置 NODE_PATH、cnpm、安裝 webpack、webpack-cli、@vue-cli、yarn、、、(此處省略 1k+插件)。
如果順利的話,這個時候你應該已經準備下班了。當然,一般都不會很順利。。。在這個過程中,你可能會遇到網絡問題、環境問題、配置問題、相容問題、、、(此處省略 1w+問題)。
然後周五新人周報:配置環境,熟悉項目。
上面這個經曆想必每位到新公司的同學都經曆過吧,是不是感覺很低效、很繁瑣。可能你會感覺這還好,能接受,那如果公司的項目很複雜,需要配置的環境很複雜呢,是不是每次新同學來,老員工都要手把手幫忙配置環境呢?想想都頭疼,那有沒有什麼好的解決辦法呢?
方法肯定是有的,今天的主角登場,它就是 docker。
什麼是 docker
docker 可以看成是一個高性能的虛拟機,主要用于 linux 環境的虛拟化。開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然後釋出到任何流行的 linux 機器上。容器完全使用沙箱機制,互相之間不會有任何接口。
docker 的優點
環境隔離
docker 實作了資源隔離,一台機器運作多個容器互無影響。
更高效的資源利用
docker 容器的運作不需要額外的虛拟化管理程式的支援,它是核心級的虛拟化,可以實作更高的性能,同時對資源的額外需求很低。
更快速的傳遞部署
使用 docker,開發人員可以利用鏡像快速建構一套标準的研發環境,開發完成後,測試和運維人員可以直接通過使用相同的環境來部署代碼。
更易遷移擴充
docker 容器幾乎可以在任意的平台上運作,包括虛拟機、公有雲、私有雲、個人電腦、伺服器等,這種相容性讓使用者可以在不同平台之間輕松的遷移應用。
更簡單的更新管理
使用 Dockerfile,隻需要很少的配置修改,就可以替代以往大量的更新工作。并且所有修改都是以增量的方式進行分發和更新,進而實作自動化和高效的容器管理。
docker 安裝
macos 安裝 docker
- 使用 Homebrew 安裝
brew -v
sudo brew update
brew cask install update
複制
- 手動下載下傳安裝官網下載下傳即可
https://docs.docker.com/docker-for-mac/install/
centos 安裝 docker
- 搭建 centos 虛拟機
- 下載下傳
, 位址virtualbox
https://www.virtualbox.org/wiki/Downloads
- 下載下傳
, 位址vagrant
https://www.vagrantup.com/downloads.html
- 下載下傳
-
基于 vagrant 建構
vagrant init centos/7 vagrant up vagrant ssh sudo yum update exit vagrant status vagrant halt vagrant destroy
- 在 centos 上安裝 docker sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine sudo yum install -y yum-utils device-mapper-persistent-data lvm2 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo yum install docker-ce docker-ce-cli containerd.io sudo systemctl start docker sudo docker run hello-world
dockerfile
docker 使用 Dockerfile 作為配置檔案進行鏡像的建構,簡單看一個 node 應用建構的 dockerfile
FROM node:12.10.0
WORKDIR /usr/app
COPY package*.json ./
RUN npm ci -qy
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
複制
FROM
基于這個 Image 開始
WORKDIR
設定工作目錄
COPY
複制檔案
RUN
新層中執行指令
EXPOSE
聲明容器監聽端口
CMD
容器啟動時執行指令預設值
更多指令參考文末 dockerfile 指令集合
docker 核心概念
docker image(鏡像)
- 作業系統分為核心和使用者空間。對于 Linux 而言,核心啟動後,會挂載 root 檔案系統為其提供使用者空間支援。而 Docker 鏡像(Image),就相當于是一個 root 檔案系統。
- Docker 鏡像是一個特殊的檔案系統,除了提供容器運作時所需的程式、庫、資源、配置等檔案外,還包含了一些為運作時準備的一些配置參數(如匿名卷、環境變量、使用者等)。鏡像不包含任何動态資料,其内容在建構之後也不會被改變。
- Docker 設計時,就充分利用 Union FS 的技術,将其設計為 分層存儲的架構 。鏡像實際是由多層檔案系統聯合組成。
- 鏡像建構時,會一層層建構,前一層是後一層的基礎。每一層建構完就不會再發生改變,後一層上的任何改變隻發生在自己這一層。
docker container(容器)
- 鏡像(Image)和容器(Container)的關系,就像是面向對象程式設計中的 類 和 執行個體 一樣,鏡像是靜态的定義,容器是鏡像運作時的實體。容器可以被建立、啟動、停止、删除、暫停等 。
- 容器的實質是程序,但與直接在宿主執行的程序不同,容器程序運作于屬于自己的獨立的 命名空間。前面講過鏡像使用的是分層存儲,容器也是如此。
- 容器存儲層的生存周期和容器一樣,容器消亡時,容器存儲層也随之消亡。是以,任何儲存于容器存儲層的資訊都會随容器删除而丢失。
- 按照 Docker 最佳實踐的要求,容器不應該向其存儲層内寫入任何資料 ,容器存儲層要保持無狀态化。所有的檔案寫入操作,都應該使用資料卷(Volume)、或者綁定宿主目錄,在這些位置的讀寫會跳過容器存儲層,直接對宿主(或網絡存儲)發生讀寫,其性能和穩定性更高。資料卷的生存周期獨立于容器,容器消亡,資料卷不會消亡。是以, 使用資料卷後,容器可以随意删除、重新 run ,資料卻不會丢失。
docker 倉庫(Repository)
- 鏡像建構完成後,可以很容易的在目前宿主上運作,但是, 如果需要在其它伺服器上使用這個鏡像,我們就需要一個集中的存儲、分發鏡像的服務,Docker Registry 就是這樣的服務。
- 一個 Docker Registry 中可以包含多個倉庫(Repository);每個倉庫可以包含多個标簽(Tag);每個标簽對應一個鏡像。是以說:鏡像倉庫是 Docker 用來集中存放鏡像檔案的地方類似于我們之前常用的代碼倉庫。
- 通常,一個倉庫會包含同一個軟體不同版本的鏡像,而标簽就常用于對應該軟體的各個版本 。我們可以通過<倉庫名>:<标簽>的格式來指定具體是這個軟體哪個版本的鏡像。如果不給出标簽,将以 latest 作為預設标簽.。
這裡補充一下
Docker Registry 公開服務
和
私有 Docker Registry
的概念:
- Docker Registry 公開服務 是開放給使用者使用、允許使用者管理鏡像的 Registry 服務。一般這類公開服務允許使用者免費上傳、下載下傳公開的鏡像,并可能提供收費服務供使用者管理私有鏡像。
- 最常使用的 Registry 公開服務是官方的 Docker Hub ,這也是預設的 Registry,并擁有大量的高品質的官方鏡像,網址為:hub.docker.com/ 。在國内通路 Docker Hub 可能會比較慢國内也有一些雲服務商提供類似于 Docker Hub 的公開服務。比如 時速雲鏡像庫、網易雲鏡像服務、DaoCloud 鏡像市場、阿裡雲鏡像庫等。
- 除了使用公開服務外,使用者還可以在 本地搭建私有 Docker Registry 。Docker 官方提供了 Docker Registry 鏡像,可以直接使用做為私有 Registry 服務。開源的 Docker Registry 鏡像隻提供了 Docker Registry API 的服務端實作,足以支援 docker 指令,不影響使用。但不包含圖形界面,以及鏡像維護、使用者管理、通路控制等進階功能。
docker 常用指令
鏡像操作
功能 | 指令 |
---|---|
拉取鏡像 | docker pull [鏡像名稱:版本] |
鏡像清單 | docker images |
删除鏡像 | docker rmi[鏡像名稱:版本] |
鏡像操作記錄 | docker history [鏡像名稱:版本] |
給鏡像設定新的倉庫 | docker tag [鏡像名稱:版本][新鏡像名稱:新版本] |
檢視鏡像詳細 | docker inspect [鏡像名稱:版本] |
搜尋鏡像 | docker search [關鍵字] |
倉庫登入 | docker login |
容器操作
功能 | 指令 |
---|---|
啟動容器并進入 | docker run -ti --name [容器名稱][鏡像名稱:版本] bash |
容器清單 | docker ps -a |
容器送出為新的鏡像 | docker commit [容器名稱] my_image:v1.0 |
容器背景運作 | docker run -d --name [容器名稱][鏡像名稱:版本] bash -c "echo hello world" |
容器結束後自動删除 | docker run --rm --name [容器名稱][鏡像名稱:版本] bash -c "echo hello world" |
删除容器 | docker rm [容器名稱] |
進入容器 exec | docker exec -ti [容器名稱] bash |
進入容器 attach | docker attach [容器名稱] |
停止容器 | docker stop [容器名稱] |
Docker 日志 | docker logs [容器名稱] |
檢視容器詳細 | docker inspect [容器名稱] |
檢視容器最近一個程序 | docker top [容器名稱] |
docker top [容器名稱] | docker restart [容器名稱] |
暫停一個容器程序 | docker pause [容器名稱] |
取消暫停 | docker unpause [容器名稱] |
終止容器 | docker kill [容器名稱] |
端口映射 | docker run -ti --name [容器名稱] -p 8080:80 [鏡像名稱:版本] bash |
記憶體限制
參數 | 簡介 |
---|---|
-m, - -memory | 記憶體限制,格式:數字+機關,機關可以是 b, k, m, g,最小 4M |
CPU 限制
參數 | 簡介 |
---|---|
-- -cpuset-cpus="" | 允許使用的 CPU 集 |
-c,- -cpu-shares=0 | CPU 共享權值 |
dockerfile 指令
指令 | 說明 | 示例 |
---|---|---|
FROM | 基于這個 Image 開始 | FROM nginx:latest |
ENV | 環境變量 | ENV localfile /usr/local/nginx |
RUN | 新層中執行指令 | RUN /bin/bash -c 'source HOME |
LABEL | 設定 metadata | LABEL version="1.0" |
MAINTAINER | 維護者 (deprecated) | maintainer="feng [email protected]" |
EXPOSE | 聲明容器監聽端口 | EXPOSE 80 443 |
ADD | 添加檔案 | ADD ./dist ${foo}/html |
COPY | 複制檔案 | COPY ./dist ${foo}/html |
ENTRYPOINT | 容器啟動時執行指令 | |
CMD | 容器啟動時執行指令預設值 | CMD ["-la"] |
WORKDIR | 設定工作目錄 | WORKDIR /path/to/workdir |
VOLUME | 挂載點 | VOLUME ["/data"] |
USER | 指定操作使用者 | USER www |