1. 程式人生 > 實用技巧 >使用async await通過for迴圈在圖片onload載入成功後獲取成功的圖片地址

使用async await通過for迴圈在圖片onload載入成功後獲取成功的圖片地址

容器概念

容器是一種基礎的工具;泛指任何可以用於容納其他物品的工具,可以部分或完全封閉,被用於容納,儲存,運輸物品;物體可以被放置在容器中,而容器則可以保護內容物;
人類使用容器的歷史至少有十萬年,甚至可能有數百萬年的歷史
容器的型別
瓶 —— 指口部比腹部窄小,頸長的容器.
罐 —— 指那些開控較大,一般為近圓筒形的器皿.
箱 —— 通常是立方體或圓柱體.形狀固定.
籃 —— 以條狀物編織而成.
桶 —— 一種圓柱形的器皿
袋 —— 柔性材料製成額容器,形狀會受內容物而變化
甕 —— 通常是指陶製,口小肚大的容器
碗 —— 用來盛載食品的容器
櫃 —— 指一個由盒組成的傢俱
鞘 —— 用於裝載刀刃的容器

------------- LXC(Linux容器 Docker是LXC的增強版) 虛擬化 --------------
主機級虛擬化: (作用:環境隔離)
Type-I
Type-II

Linux Namespace
namespace 系統呼叫引數 隔離內容 核心版本
UTS CLONE_NEWUTS 主機名和域名 2.6.19
IPC CLONE_NEWIPC 訊號量,訊息佇列和共享記憶體 2.6.19
PID CLONE_NEWPID 程序編號 2.6.24
Network CLONE_BEWNET 網路裝置,網路線,埠等 2.6.29
Mount CLONE_NEWNS 掛載點(檔案系統) 2.4.19
USer CLONE_NEWUSER 使用者和使用者組 3.8

-------------------- Cgroups --------------
Control Group(cgroups)
資源控制組,是Linux核心提供的一種可以限制,記錄,隔離程序組(process groups)所使用的物理資源(如 cpu memory i/o 等等)的機制,2007年進入Linux2.6.24的核心,Cgroups不是全新創造的,它將程序管理從cpuset中剝離出來

cgroups
blkio: 塊裝置IO
cpu: CPU
cpuacct: CPU資源使用報告
cpuset: 多處理器平臺上的CPU集合
devices: 裝置訪問
freezer: 掛起或恢復任務
memory: 記憶體用量及報告
perf_event: 對cgroup中的任務進行統一效能測試
net_cls: cgroup中的任務建立的資料報文的類別識別符號

Cgroup四大功能:
資源限制: 可以對任務使用的資源總額進行限制
優先順序分配: 通過分配的CPU時間片數量以及磁碟IO頻寬大小,實際上相當於控制了任務執行優先順序
資源統計: 可以統計系統的資源使用量,如CPU時長,記憶體用量等
任務控制: Cgroup可以對任務執行掛起,恢復等操作

OCF
Open Container Format

OCI
Open Container Initiative
由Linux基金會主導與2015年6月創立
旨在圍繞容器格式和執行時指定一個開放的工業化標準
contains two specifications
the Runtime Specifications # 執行標準
the Image Specifications # 映象標準

======================= Docker =======================

Docker解決的問題

  • 環境不一致
  • 多版本測試

Docker VS 虛擬機器

型別 Docker 虛擬機器
部署難度 非常簡單 元件多,部署複雜
啟動速度 秒級別 分鐘級
執行能力 與物理系統幾乎一致 VM會佔用一些資源
映象體積 映象體積是MB級別 映象體積是GB級別
管理效率 建立簡單 元件相互依賴,管理複雜
隔離性 隔離性高 徹底隔離
客觀理性 單程序 完整的系統管理
網路連線 比較弱 藉助Neutron可以靈活元件各類網路架構

Docker下載
linux:
1.安裝依賴包
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

2.設定阿里雲映象源

sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

3.安裝 Docker-CE
重建 Yum 快取。
安裝 Docker-CE ,請執行一下命令進行安裝:

sudo yum install docker-ce

Linux Docker配置檔案地址
/etc/docker/daemon.json

4.啟動 Docker-CE
sudo systemctl enable docker
sudo systemctl start docker

5.[可選] 為 Docker 建立使用者組#
docker 命令與 Docker 引擎通訊之間通過 UnixSocket ,但是能夠有許可權訪問 UnixSocket 的使用者只有 root 和 docker 使用者組的使用者才能夠進行訪問,所以我們需要建立一個 docker 使用者組,並且將需要訪問 docker 的使用者新增到這一個使用者組當中來。

  1. 建立 Docker 使用者組

sudo groupadd docker

2.添加當前使用者到 docker 組

sudo usermod -aG docker $USER
sudo systemctl enable docker
sudo systemctl start docker

6.映象加速配置#

這裡使用的是 阿里雲提供的映象加速 ,登入並且設定密碼之後在左側的 Docker Hub 映象站點 可以找到專屬加速器地址,複製下來。
阿里雲映象加速官網
https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

然後執行以下命令:

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'


{
"registry-mirrors": ["你的加速器地址"],
"dns":["192.168.56.2","223.5.5.5"], # 選填 增加dns解析
"bip": xxx.xx.x.xx, # 選填 更改docker 自己的網路橋地址
"hosts": ["tcp://ip:埠","unix:///var/run/docker/sock"], # 選填 跟修改vi /usr/lib/systemd/system/docker.service 中的 ExecStart 一致
"data-root":"/data/docker"	# 選填 指定存放docker下載檔案以及其他儲存地址 預設在/var/lib/docker/
"cluster-store":"consul://啟動consul的裝置ip:埠", # 選填 多臺裝置叢集引數
"cluster-advertise":"本機ip:2375" # 必須配置下面遠端控制的引數 vi /usr/lib/systemd/system/docker.service 
}

EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

如果需要遠端控制
vi /usr/lib/systemd/system/docker.service
修改
ExecStart=/usr/bin/dockerd -H tcp://ip -H unix:///var/run/docker.sock # -H unix:///var/run/docker.sock 是本地訪問 必須要加

之後重新載入配置,並且重啟 Docker 服務
systemctl daemon-reload
systemctl restart docker

Mac:
https://yeasy.gitbooks.io/docker_practice/content/install/mac.html

$ brew cask install docker

手動下載:
https://download.docker.com/mac/stable/Docker.dmg
https://download.docker.com/mac/edge/Docker.dmg

映象加速配置 訪問阿里檢視詳細demo
https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

右鍵點選桌面頂欄的 docker 圖示,選擇 Preferences ,在 Daemon 標籤(Docker 17.03 之前版本為 Advanced 標籤)下的 Registry mirrors 列表中將

https://mk3q07hr.mirror.aliyuncs.com加到"registry-mirrors"的數組裡,點選 Apply & Restart按鈕,等待Docker重啟並應用配置的映象加速器。

Docker 命令

補充:
在容器中使用exit會關閉容器(docker預設機制,當容器沒有程序,會關閉容器)
需要在不關閉容器的同時退出 在鍵盤按住 control 先按 "p" 再按 "q"


docker version	# 檢視客戶端以及服務端的版本

docker info # 詳細docker資訊 # Containers 容器數量 # Running 執行數量 # Paused 暫停狀態 # Stopped 停止狀態 # Images 映象數量 # Server Version 伺服器版本 # Storage Driver 儲存驅動後端 # Plugins 外掛 # Volume 儲存外掛 # Network網路外掛 # Log 日誌外掛 # Security Options 安全選項  # Kernel Version 核心版本 # Registry Mirrors 加速映象

docker search	關鍵字	# 搜尋映象

docker inspect 容器name # 檢查容器資訊
-f {{.xxx}} # 根據go模板語法進行層級查詢 # .可以理解/

docker rmi 映象id	# 刪除映象

images

docker pull xxx # 拉取映象
busybox (雜物箱)

docker images # 檢視所有映象

docker rm	xxx # 刪除容器
-f # 強制刪除 例如刪除正在執行的容器

docker history xxx # 查詢映象層級

Management Commands

docker network ls	# 檢視網路
# bridge 橋接 # 預設
# host # 網絡卡資訊與速度與宿主機是一樣的

docker network create name # 新建網路
--driver 網路模式	# 必須加 可以不寫網路模式 預設是橋接
--subnet xxx.xxx.xxx.xxx # 指定網段
--geteway xxx.xxx.xxx.xxx # 指定閘道器
-d 驅動name	# 指定驅動
-d overlay # 如果使用這個 建立一個全域性的網絡卡 overlay網路模式
# 使用同一個使用者建立的網路建立容器是可以互相ping通的

docker network connect 網路端 容器name # 將某網絡卡放入容器中 可以實現在同一網段的容器間的通訊

commands


docker commit 容器name/ID [倉庫名/映象名:版本]
-m 新增一些註釋資訊
-p 容器name # 建立新映象
-c 'CMD ["/bin/httpd","-f"]'	# 修改容器起始命令 'CMD ["/bin/httpd","-f"]' 命令格式
docker -H ip:埠 指令 # 指定ip執行某指令

docker create xxx # 建立容器

docker start xxx	# 啟動一個或多個處於停止狀態的容器
-l # 互動模式
# 或者使用 docker attach xxx 連線進入shell # 如果多端連入會同步一個螢幕操作
# 或使用 docker exec -it xxx bash/sh # 在容器中 # 多端連線不會出現attach現象

docker stop xxx # 停止一個或多個處於執行狀態的容器

docker kill	xxx	# 強制停止執行狀態的容器

docker run 指令 指定映象 起始命令	# 直接建立完直接啟動 如果沒有起始命令則會執行預設的起始命令
-t	# 互動式介面 開啟shell
-l # 允許互動
--name xxx	# 起名 也可以直接ping xxx 跨容器通訊
--network # 指定網路
# 預設是bridge 如果需要指定其他 
# overlay 叢集網路
-h name # 指定主機名 # 在映象中輸入hostname檢視
--dns xxx # 指定dns解析地址
--rm # 容器停止自動刪除
-d	# 執行在後臺
-e # -e 後跟指令變數 用於攜帶引數 類似ansible的-e
-m # -m後跟記憶體 例如50M 細粒度控制
--memory-swap # 必須先設定 -m 引數後才能使用這個引數 例如 -m 正數M --memory-swap 正數S 容器的可用總空間為S,其中ram(實體記憶體)為M,swap(交換記憶體)為(S-M),若S=M則無可swap空間 // -m 正數M --memory-swap 0 相當未設定swap(unset) 若主機啟用(docer host)swap則容器可用swap為2*M // -m 正數M --memory-swap -1 若主機啟用(docer host)swap則容器可使用最大至主機上的所有swap空間的swap資源

--omm-kill-disable # 禁止omm被kill掉
--cpuset-cpus num # 指定cpu執行 num也可以指定範圍 1-3 表示1-3核
-c	num # 指定cpu權重 如果不指定預設為1024 按照權重分配CPU 
--cpus=<value> # 指定cpu核數 例如 --cpus="1.5" 使用1.5核
--link 容器name:別名 # 連結容器name 可以通過ping別名來ping被連結的容器ip
--ip xxx.xxx.xxx.x # 指定ip
-v path # 將容器中的 path目錄隨機繫結到本機上 需要使用docker inspect 容器name 檢視"Mounts" 中隨機分配的路徑 兩者路徑互通
-v path1:path # 將本地檔案path1掛載到path
--volumes-from 容器name # 複製容器name的卷 建立新容器

docker pause	xxx	# 暫停容器

docker unpause xxx # 取消暫停

docker top # 檢視執行的容器詳情 (根據資源消耗排名)

docker ls # 列出所有容器 等於 docker ps
-a # 為檢視所有的容器,包括已經停止的。

docker logs -f <容器名 or ID> # 檢視容器日誌

docker exec 容器名 指令 # 在容器內執行外部的指令 # 指令必須為絕對指令 例如 /bin/sh
-t	# 互動式介面 開啟shell
-l # 互動模式
-e # -e後加入指令

docker save 映象name # 可以支援多映象打包
-o 絕對地址/檔案name # 將打包的映象匯出到檔案

docker load -i 打包的映象檔案 # 將壓縮包的映象容器匯入

docker container ls -a 檢視執行容器
- f 增加條件檢索 例如 $docker container ls -f "status=exited" 狀態為停止的


# 一共有三種形式進行埠對映
docker -p ip:hostPort:containerPort # 對映指定地址的主機埠到容器埠
# 例如:docker -p 127.0.0.1:3306:3306 對映本機3306埠到容器的3306埠
docker -p ip::containerPort # 對映指定地址的任意可用埠到容器埠
# 例如:docker -p 127.0.0.1::3306 對映本機的隨機可用埠到容器3306埠
docer -p hostPort:containerPort # 對映本機的指定埠到容器的指定埠
# 例如:docker -p 3306:3306 # 對映本機的3306埠到容器的3306埠

docker port 容器ip/name # 檢視容器中對映內容

對映資料卷

docker -v /home/data:/opt/data # 這裡/home/data 指的是宿主機的目錄地址,後者則是容器的目錄地址

Tag
-alpine # docker pull xxx:版本-alpine 構建小映象版本

command
bash
sh

容器container

1.建立容器
docker create -it boke-oraclexe:1.0

# 建立臨時容器,退出後不再存在,常用於排錯

docker run -it --rm boke-mysql5.5:1.1 bash

2.檢視容器
docker ps -a

docker ps -a -q # 檢視哪些是停止狀態的容器

3.啟動容器
docker start 容器ID


4.建立啟動容器
docker run

# 當使用docker run命令建立啟動容器時,Docker在後臺執行的標準操作有下面幾個步驟

# 1、檢測本地是否存在指定的映象,不存在就從公有倉庫下載

# 2、利用映象建立並啟動一個容器

# 3、分配一個檔案系統,並在只讀的映象層外面掛載一層可讀寫層

# 4、從宿主主機配置的網橋介面中橋接一個虛擬介面到容器中去

# 5、從地址池配置一個IP地址給容器

# 6、執行使用者指定的應用程式

# 7、執行完畢後終止容器


5.停止容器

# 執行中的容器status 為 up

# 停止中的容器status 為exit

docker stop 容器ID


6.進入容器
幾種方式 1.docker attach 命令、2.docker exec 命令、3.nsenter工具
6.1.attach命令
docker attach 容器ID

docker attach是一個Docker自帶的命令,下面來說說attach命令的使用方法:

其實使用docker attach命令有時候很不方便,當多個視窗同時attach到同一個容器的時候,所有視窗都會同步顯示,當某個視窗因命令阻塞的時候,其他視窗也無法執行操作了。


6.2.exec命令
在Docker1.3版本開始,提供了一個更方便的命令exec。可以直接在容器內執行命令。


7.刪除容器
刪除容器我們可以使用docker rm命令,被刪除的容器需要是終止狀態的

命令用法:docker rm [OPTIONS] CONTAINER [CONTINER...]。支援的引數有-f -l -v

-f, --force=false:強項終止並刪除一個執行中的容器。

-l, --link=false:刪除容器的連線,但保留容器。

-v, --volumes=false:刪除容器掛載的資料卷。


8.容器遷移

匯出 docker export 容器ID

匯入docker import 容器ID

 

### 登入到官方倉庫 並將映象提交至官方倉庫
docker login
user:songzhibin
password:xxxxxxxx

docker tag 映象id 你的使用者名稱/映象名:版本號 # 版本號不輸入預設是latest

docker push 已經打好的tag

GUI 管理配置

這裡推薦使用 Portainer 作為容器的 GUI 管理方案。

官方地址:https://portainer.io/install.html

安裝命令:

docker volume create portainer_data
docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
訪問你的 IP:9000 即可進入容器管理頁面。

===============單級容器的編排

docker-compose

安裝 pip install docker-compose
所有引數詳解
http://wiki.jikexueyuan.com/project/docker-technology-and-combat/yaml_file.html

編輯規則:

選擇存放路徑 一般放在opt下
cd /opt
vim docker-compose.yml

規則name:
image: 映象name
volumes: # 掛在地址
- 本地絕對地址:需要掛載絕對地址
expose:
- 內部開放埠

規則name2:
image: 映象name
volumes: # 掛在地址
- 本地絕對地址:需要掛載絕對地址
expose:
- 內部開放埠

haproxy: # haproxy是映象name
image: haproxy
valumes:
- 本地絕對地址:需要掛載絕對地址
links: # 依賴容器
- 規則name
- 規則name2
prots:
- 本機對映埠:容器埠 
- 本機對映埠:容器埠 

啟動方式
docker-compose -f 規則檔案 up -d # up -d 在後臺啟動 不加-d在前臺啟動 # 如果不加-f 規則檔案 則會在docker-compose中本地尋找規則檔案

=============容器中的資料持久化

資料卷


# -v 掛載引數
例如
docker run -it --rm -v /opt/data:/opt centos bash # 本地路徑:容器路徑 或 本地路徑即可 # 只寫本地路徑則預設容器路徑與本機掛載路徑相同 # 將容器的/opt目錄掛載到本地/opt/data下 例如在容器/opt下建立一個目錄或者檔案 在本地/opt/data也可以看到 當容器被刪除 掛載建立的檔案或者目錄不會被刪除
# 注意 一個目錄可以被多個容器掛載

補充:如果在容器中建立使用者 建議從後往前建立

資料卷容器
# 依賴容器
例如
docker run -it --volumes-from 已建立的容器 --name data1 centos bash # 使用--volumes-from 建立容器卷 # 利用容器卷建立的容器不受建立容器卷選擇的容器依賴,及時被刪除也會存在
# 當真的需要刪除容器卷
docker rm -fv xxx

# 刪除沒有使用的所有容器
docker volume prune

============通過Dockerfile 建立映象

# Dockerfile是一個包含用於組合映像的命令的文字文件。可以使用在命令列中呼叫任何命令。 Docker通過讀取Dockerfile中的指令自動生成映像。
# docker build命令用於從Dockerfile構建映像。可以在docker build命令中使用-f標誌指向檔案系統中任何位置的Dockerfile。

# 注意 []中的json陣列中一定要用 "" # 雙引號


docker build -f /path/to/a/ # 指定檔案

docker build -t debian-jdk8:v1.0 . 
# 其中-t debian-jdk8:v1.0表示打包的映象名為debian-jdk,tag為v1.0(前面說過,tag是可以任意命名的,不一定要是這種格式),注意命令的最後有一個.,這個表示打包的上下文(其實就是Dockerfile所在目錄)是在當前目錄,然後目錄下的Dockerfile就會被編譯執行。

 

Dockerfile的基本結構
# Dockerfile 一般分為四部分:基礎映象資訊、維護者資訊、映象操作指令和容器啟動時執行指令,’#’ 為 Dockerfile 中的註釋。

Dockerfile檔案說明
# Docker以從上到下的順序執行Dockerfile的指令。為了指定基本映像,第一條指令必須是FROM。一個宣告以#字元開頭則被視為註釋。可以在Docker檔案中使用RUN,CMD,FROM,EXPOSE,ENV等指令。


常用的指令:
FROM:指定基礎映象,必須為第一個命令
格式:
  FROM <image>
  FROM <image>:<tag>
  FROM <image>@<digest> # digest雜湊碼
示例:
  FROM mysql:5.6
注:
  tag或digest是可選的,如果不使用這兩個值時,會使用latest版本的基礎映象

 


MAINTAINER: 維護者資訊 # 新版使用LABEL
格式:
MAINTAINER <name>
示例:
MAINTAINER Jasper Xu
MAINTAINER [email protected]
MAINTAINER Jasper Xu <[email protected]>


RUN:構建映象時執行的命令
RUN用於建立映象容器中執行命令,其有以下兩種命令執行方式:

shell執行
格式:
RUN <command>
多條指令推薦使用 && 連線 多Run會增加分層

exec執行
格式:
RUN ["executable", "param1", "param2"]
示例:
RUN ["executable", "param1", "param2"]
RUN apk update
RUN ["/etc/execfile", "arg1", "arg1"]
注:
  ***RUN指令建立的中間映象會被快取,並會在下次構建中使用。如果不想使用這些快取映象,可以在構建時指定--no-cache引數,如:docker build --no-cache

 

ADD:將本地檔案新增到容器中,tar型別檔案會自動解壓(網路壓縮資源不會被解壓),可以訪問網路資源,類似wget

格式: # 如果路徑中有空白字元建議使用第二種格式
# src如果是目錄 則會複製目錄下的所有內容 而不是複製整個目錄
# dest必須是一個目錄並且以/結尾
ADD <src>... <dest> # src 要複製的原始檔或目錄,支援使用萬用字元 被copy的檔案需要在Dockfile同級目錄中 dest 目標路徑,即正在建立image的檔案路徑 建議使用絕對路徑

ADD ["<src>",... "<dest>"] 用於支援包含空格的路徑
示例:
ADD hom* /mydir/ # 新增所有以"hom"開頭的檔案
ADD hom?.txt /mydir/ # ? 替代一個單字元,例如:"home.txt"
ADD test relativeDir/ # 新增 "test" 到 `WORKDIR`/relativeDir/
ADD test /absoluteDir/ # 新增 "test" 到 /absoluteDir/
ADD test # 新增 "test" 到 當前目錄



COPY:功能類似ADD,但是是不會自動解壓檔案,也不能訪問網路資源
格式:
COPY <src>... <dest>
COPY ["<src>",... "<dest>"] 用於支援包含空格的路徑


CMD:構建容器後呼叫,也就是在容器啟動時才進行呼叫。 # 啟動執行 // 如果docker執行其他命令 cmd可能會被忽略
格式:
CMD ["executable","param1","param2"] (執行可執行檔案,優先) # executable指的是以什麼命令去執行後面的命令 例如["/bin/sh","-c", "echo xxx "] # 如果不使用/bin/sh 不會使用環境變數的內容
CMD ["param1","param2"] (設定了ENTRYPOINT,則直接呼叫ENTRYPOINT新增引數)
CMD command param1 param2 (執行shell內部命令) # 這裡的command指的是shell命令 預設是/bin/sh -c 來執行 
示例:
CMD echo "This is a test." | wc -
CMD ["/usr/bin/wc","--help"]
注:
  CMD不同於RUN,CMD用於指定在容器啟動時所要執行的命令,而RUN用於指定映象構建時所要執行的命令。
*** 如果存在多個CMD 只會執行最後一條



ENTRYPOINT:配置容器,使其可執行化。配合CMD可省去"application",只使用引數。
格式:
ENTRYPOINT ["executable", "param1", "param2"] (可執行檔案, 優先) exec指令
ENTRYPOINT command param1 param2 (shell內部命令) shell 格式
示例:
FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
注:
   ENTRYPOINT與CMD非常類似,不同的是通過docker run執行的命令不會覆蓋ENTRYPOINT,而docker run命令中指定的任何引數,都會被當做引數再次傳遞給ENTRYPOINT。Dockerfile中只允許有一個ENTRYPOINT命令,多指定時會覆蓋前面的設定,而只執行最後的ENTRYPOINT指令。
# 如果需要在外部修改ENTRYPOINT設定的指令 需要增加引數 -enterpoint string 指令
# 如果ENTRYPOINT 與 CMD同時存在 CMD接收到的內容用作ENTRYPOINT的引數使用 # 一般用如果ENTRYPOINT指定容器執行命令的方式

 

LABEL:用於為映象新增元資料
格式:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
示例:
  LABEL version="1.0" description="這是一個Web伺服器" by="IT筆錄"
注:
  使用LABEL指定元資料時,一條LABEL指定可以指定一或多條元資料,指定多條元資料時不同元資料之間通過空格分隔。推薦將所有的元資料通過一條LABEL指令指定,以免生成過多的中間映象。

 

ENV:設定環境變數
格式:
ENV <key> <value> #<key>之後的所有內容均會被視為其<value>的組成部分,因此,一次只能設定一個變數
ENV <key>=<value> ... #可以設定多個變數,每個變數為一個"<key>=<value>"的鍵值對,如果<key>中包含空格,可以使用\來進行轉義,也可以通過""來進行標示;另外,反斜線也可以用於續行
示例:
ENV myName John Doe # myName 後 是value # 理論上ENV一次只能設定一個變數 可以通過 && 來執行多條命令
ENV myDog Rex The Dog
ENV myCat=fluffy


EXPOSE:指定於外界互動的埠
格式:
EXPOSE <port> [<port>...]
示例:
EXPOSE 80 443
EXPOSE 8080
EXPOSE 11211/tcp 11211/udp
注:
  EXPOSE並不會讓容器的埠訪問到主機。要使其可訪問,需要在docker run執行容器時通過-p來發布這些埠,或通過-P引數來發布EXPOSE匯出的所有埠

 


VOLUME:用於指定持久化目錄 # 只能指定容器內的路徑 不能指定宿主機的路徑
格式:
VOLUME ["/path/to/dir"]
示例:
VOLUME ["/data"]
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"
注:
  一個卷可以存在於一個或多個容器的指定目錄,該目錄可以繞過聯合檔案系統,並具有以下功能:
1 卷可以容器間共享和重用
2 容器並不一定要和其它容器共享卷
3 修改卷後會立即生效
4 對卷的修改不會對映象產生影響
5 卷會一直存在,直到沒有任何容器在使用它

 

WORKDIR:工作目錄,類似於cd命令
格式:
WORKDIR /path/to/workdir
示例:
WORKDIR /a (這時工作目錄為/a) // 如果有進入 如果沒有建立
WORKDIR b (這時工作目錄為/a/b)
WORKDIR c (這時工作目錄為/a/b/c)
注:
  通過WORKDIR設定工作目錄後,Dockerfile中其後的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都會在該目錄下執行。在使用docker run執行容器時,可以通過-w引數覆蓋構建時所設定的工作目錄。

 

USER:指定執行容器時的使用者名稱或 UID,後續的 RUN 也會使用指定使用者。使用USER指定使用者時,可以使用使用者名稱、UID或GID,或是兩者的組合。當服務不需要管理員許可權時,可以通過該命令指定執行使用者。並且可以在之前建立所需要的使用者
格式:
  USER user
  USER user:group
  USER uid
  USER uid:gid
  USER user:gid
  USER uid:group

示例:
  USER www

注:
  使用USER指定使用者後,Dockerfile中其後的命令RUN、CMD、ENTRYPOINT都將使用該使用者。映象構建完成後,通過docker run執行容器時,可以通過-u引數來覆蓋所指定的使用者。
# uid 必須要在/etc/passwd中某使用者有效的UID否則docker run 會執行失敗
# 預設是root使用者執行

HEALTHCHECK :檢測容器是否健康
# HEALTHCHECK引數:
--interval=num(default:30s) # 連線時間
--timeout=num(default:30s) # 超時時間
--start-period=num(default:0s) # 啟動容器等待檢測時間
--retries=num(default:0)
# 返回值:
0 seccuess
1 unhealthy
2 reserved

示例:
HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ || exit 1 
# CMD是關鍵字 必須加 # 成功執行 curl http://localhost/ 失敗則退出



ARG:用於指定傳遞給構建執行時的變數
格式:
ARG <name>[=<default value>]
示例:
ARG site
ARG build_user=www
# 在build中使用 --build-arg
demo 
docker build --build-arg site=xxx

 


ONBUILD:用於設定映象觸發器
格式:
  ONBUILD [INSTRUCTION]
示例:
  ONBUILD ADD . /app/src
  ONBUILD RUN /usr/local/bin/python-build --dir /app/src
注:
  當所構建的映象被用做其它映象的基礎映象,該映象中的觸發器將會被鑰觸發
# 不能執行FROM 以及 ONBUILD指令

 

以下是一個小例子:
# This my first nginx Dockerfile
# Version 1.0

# Base images 基礎映象
FROM centos

#MAINTAINER 維護者資訊
MAINTAINER tianfeiyu

#ENV 設定環境變數
ENV PATH /usr/local/nginx/sbin:$PATH

#ADD 檔案放在當前目錄下,拷過去會自動解壓
ADD nginx-1.8.0.tar.gz /usr/local/ 
ADD epel-release-latest-7.noarch.rpm /usr/local/

#RUN 執行以下命令 
RUN rpm -ivh /usr/local/epel-release-latest-7.noarch.rpm
RUN yum install -y wget lftp gcc gcc-c++ make openssl-devel pcre-devel pcre && yum clean all
RUN useradd -s /sbin/nologin -M www

#WORKDIR 相當於cd
WORKDIR /usr/local/nginx-1.8.0

RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-pcre && make && make install

RUN echo "daemon off;" >> /etc/nginx.conf

#EXPOSE 對映埠
EXPOSE 80

#CMD 執行以下命令
CMD ["nginx"]

===============映象倉 registry


yum install docker-registry
# 主配置檔案 /etc/docker-distribution/registry/config.yml
# 主程式 /usr/bin/registry
# 啟動目錄 /usr/lib/sysyemd/system/docker-distribution.service
# 上傳映象預設儲存位置 /var/lib/registry
啟動 systemctl start docker-distribution # 預設監聽 5000埠 在config.yml檔案中配置

# 打標籤
docker tag 域名(ip):埠/倉庫專案名/映象名

# 修改標籤
docker tag 舊標籤 新標籤
例如:
docker tag mysql:5.5 mysql:latest

# 上傳

docker push 域名/倉庫專案名/映象名

==============多容器串聯使用示例
// 啟動mysql容器 # MYSQL_ALLOW_EMPTY_PASSWORD=true 不需要密碼
docker run -d --name mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
// 啟動WordPress容器 # WORKPRESS_DB_HOST=mysql:3306指定資料庫 --link mysql 連結剛才啟動的mysql容器 -p 8080:80對映埠
docker run -d -e WORKPRESS_DB_HOST=mysql:3306 --link mysql -p 8080:80 wordpress

==============docker compose安裝使用 (多容器並聯啟動)
https://www.jianshu.com/p/658911a8cff3

安裝 Docker 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
$ sudo chmod +x /usr/local/bin/docker-compose

檢視安裝是否成功

$ docker-compose -v

Docker Compose 常用命令與配置
常見命令
- ps:列出所有執行容器
docker-compose ps
- logs:檢視服務日誌輸出 
docker-compose logs
- port:列印繫結的公共埠,下面命令可以輸出 eureka 服務 8761 埠所繫結的公共埠
docker-compose port eureka 8761
- build:構建或者重新構建服務
docker-compose build
- start:啟動指定服務已存在的容器
docker-compose start eureka
- stop:停止已執行的服務的容器
docker-compose stop eureka
- rm:刪除指定服務的容器
docker-compose rm eureka
- up:構建、啟動容器
docker-compose up
- kill:通過傳送 SIGKILL 訊號來停止指定服務的容器
docker-compose kill eureka
- pull:下載服務映象
- scale:設定指定服務運氣容器的個數,以 service=num 形式指定 // 必須使用負載均衡器才能正常使用
docker-compose scale user=3 movie=3
# 負載均衡器

version: '3'
services:
web:
image: nginx

redis:
image: redis
// 負載均衡器
lib: 
image: dockercloud/haproxy 
links: 
- web 
ports: 
- 8080:80

- run:在一個服務上執行一個命令
docker-compose run web bash

docker-compose.yml 屬性
- version:指定 docker-compose.yml 檔案的寫法格式
- services:多個容器集合
- build:配置構建時,Compose 會利用它自動構建映象,該值可以是一個路徑,也可以是一個物件,用於指定 Dockerfile 引數
build: ./dir


build:
context: ./dir
dockerfile: Dockerfile
args:
buildno: 1

- command:覆蓋容器啟動後預設執行的命令
command: bundle exec thin -p 3000


command: [bundle,exec,thin,-p,3000]

- dns:配置 dns 伺服器,可以是一個值或列表
dns: 8.8.8.8


dns:
- 8.8.8.8
- 9.9.9.9

- dns_search:配置 DNS 搜尋域,可以是一個值或列表
dns_search: example.com


dns_search:
- dc1.example.com
- dc2.example.com

- environment:環境變數配置,可以用陣列或字典兩種方式
environment:
RACK_ENV: development
SHOW: 'ture'


environment:
- RACK_ENV=development
- SHOW=ture

- env_file:從檔案中獲取環境變數,可以指定一個檔案路徑或路徑列表,其優先順序低於 environment 指定的環境變數
env_file: .env


env_file:
- ./common.env

- expose:暴露埠,只將埠暴露給連線的服務,而不暴露給主機
expose:
- "3000"
- "8000"

- image:指定服務所使用的映象
image: java

- network_mode:設定網路模式
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"

- ports:對外暴露的埠定義,和 expose 對應
ports: # 暴露埠資訊 - "宿主機埠:容器暴露埠"
- "8763:8763"
- "8763:8763"

- links:將指定容器連線到當前連線,可以設定別名,避免ip方式導致的容器重啟動態改變的無法連線情況

links: # 指定服務名稱:別名 
- docker-compose-eureka-server:compose-eureka

- volumes:卷掛載路徑
volumes:
- /lib
- /var

- logs:日誌輸出資訊
--no-color 單色輸出,不顯示其他顏.
-f, --follow 跟蹤日誌輸出,就是可以實時檢視日誌
-t, --timestamps 顯示時間戳
--tail 從日誌的結尾顯示,--tail=200

Docker Compose 其它
當服務的配置發生更改時,可使用 docker-compose up 命令更新配置
此時,Compose 會刪除舊容器並建立新容器,新容器會以不同的 IP 地址加入網路,名稱保持不變,任何指向舊容起的連線都會被關閉,重新找到新容器並連線上去

links
服務之間可以使用服務名稱相互訪問,links 允許定義一個別名,從而使用該別名訪問其它服務


version: '2'
services:
web:
build: .
links:
- "db:database"
db:

image: postgres

===============映象倉搭建 harbor

需要依賴
docker-compose

安裝 Harbor
cd /etc/opt # 如果滿先下載好匯入
wget https://github.com/vmware/harbor/releases/download/v1.2.0/harbor-online-installer-v1.2.0.tgz

解壓
tar -xf harbor-online-installer-v1.2.0.tgz

進入 
cd harbor

主要 修改harbor.cfg # 主要修改hostname(ip,域名)
hostname = redg.mydomain.com 
harbor_admin_password = Harbor12345

harbor.cfg 詳解
## Configuration file of Harbor
#The IP address or hostname to access admin UI and registry service.
#DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
***# 指定 hostname,一般為IP,或者域名,用於登入 Web UI 介面
hostname = redg.mydomain.com 

#The protocol for accessing the UI and token/notification service, by default it is http.
#It can be set to https if ssl is enabled on nginx.
***# URL 訪問方式,SSL 需要配置 nginx
ui_url_protocol = http

#Email account settings for sending out password resetting emails.
# 郵件相關資訊配置,如忘記密碼傳送郵件
email_server = smtp.xxxxxx.com
email_server_port = 465
email_username = [email protected]
email_password = xxxxxx
email_from = docker <[email protected]>
email_ssl = true

##The password of Harbor admin, change this before any production use.
# 預設的 Harbor 的管理員密碼,管理員使用者名稱預設 admin
harbor_admin_password = Harbor12345

##By default the auth mode is db_auth, i.e. the credentials are stored in a local database.
#Set it to ldap_auth if you want to verify a user's credentials against an LDAP server.
# 指定 Harbor 的許可權驗證方式,Harbor 支援本地的 mysql 資料儲存密碼,同時也支援 LDAP
auth_mode = db_auth

#The url for an ldap endpoint.
# 如果採用了 LDAP,此處填寫 LDAP 地址
ldap_url = ldaps://ldap.mydomain.com

#The basedn template to look up a user in LDAP and verify the user's password.
# LADP 驗證密碼的方式(我特麼沒用過這麼高階的玩意)
ldap_basedn = uid=%s,ou=people,dc=mydomain,dc=com

#The password for the root user of mysql db, change this before any production use.
# mysql 資料庫 root 賬戶密碼
db_password = root123

#Turn on or off the self-registration feature
# 是否允許開放註冊
self_registration = on

#Turn on or off the customize your certicate
# 允許自簽名證書
customize_crt = on

#fill in your certicate message
# 自簽名證書資訊
crt_country = CN
crt_state = State
crt_location = CN
crt_organization = mritd
crt_organizationalunit = mritd
crt_commonname = mritd.me
crt_email = reg.mritd.me


執行指令碼
./prepare
./install.sh

訪問測試
對host域名進行訪問測試,登入賬號密碼在harbor.cfg設定,預設為admin Harbor12345。harbor.cfg裡設定了self_registration = on可以進行賬號開放註冊,設定off就只能管理員進行賬號分配
# 可以設定策略 例如ip1倉庫映象推送至ip2倉庫映象
# 在系統管理下的複製管理介面 新建規則


上傳下載都要先進行登入操作,否則會報錯
如果 docker login報錯
vi /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd --insecure-registry=ip


vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://mk3q07hr.mirror.aliyuncs.com"]
}
# 新增一個大括號
{
"insecure-registries":["ip"] # 預設埠為80
}

sudo systemctl daemon-reload
sudo systemctl restart docker

登入命令操作為
docker login +訪問的hostname

退出登入:
docker logout +訪問的hostname

Push映象到倉庫建立的專案
docker push 域名/倉庫專案名/映象名:版本

Pull映象到本地
docker pull 域名/專案名/映象名

# 停止harbor執行
在解壓harbor資料夾中
docker-compose pause # 全部暫停

# 重新啟動已經暫停的
docker-compose unpause

===========================
hub.docker.com/_/registry

=====================docker叢集 swarm

// 初始化
$ docker swarm init
// $ docker swarm init --advertise-addr=ip 初始化並指定ip為主節點
// 初始化成功後會生成token 複製token在其他docker中貼上即可加入叢集

// 檢視叢集狀態
$ docker node ls

// 退出叢集
$ docker swarm leave -f

// 叢集中檢視服務
$ docker service ls

// 叢集中檢視具體的服務屬性
$ docker service ps 服務name

// 叢集狀態下啟動服務
$ docker service create 
// #--name表示服務名稱,--replicas表示副本任務數,--publish表示埠對映,將容器的80埠對映到物理機的80埠,nginx表示使用nginx映象
// docker service create --name web --publish 80:80 --replicas 3 nginx

// 叢集狀態下刪除服務
$ docker service rm -f 服務name	

// 叢集狀態下服務拉伸
$ docker service scale 服務name=number

// 叢集狀態下更新服務
// 預設配置下,Swarm一次只更新一個副本,並且兩個副本之間沒有等待時間。
--update-parallelism #設定並行更新的副本數目
--update-delay #指定滾動更新的間隔時間

$ docker service update --image rhel7 --update-delay 5s --update-parallelism 3 web
// #更新服務,實質上就是將原來的nginx映象更換為rhel7映象;

// 叢集狀態下建立監控服務 網頁輸入ip:8080即可
$ docker service create \
> --name=viz \
> --publish=8080:8080/tcp \
> --constraint=node.role==manager \
> --mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
> visualizer


// 叢集建立祕鑰 
vim password
隨機密碼
$ docker secret create xxx password (這裡的password是檔案)
$ echo "xxx" | docker secret create xxx2 -

// 檢視祕鑰
$ docker secret ls

// 快速使用祕鑰
$ docker service create --name xx --secret xxx -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/xxx mysql

===========================

映象補充:
busybox # 不用加任何引數啟動 自帶一些網路工具
docker run -it --rm busybox

progrium/consul	# 配置管理中心
docker run -d -p 8500:8500 --name consul progrium/consul -server -bootstrap


nginx # nginx

haproxy # 負載均衡

sebp/elk	# 日誌收集系統 # 後面附上filebeat內容
docker run -p 5601:5601 -p 9200:9200 -p 5044:5044 -it --rm --name elk sebp/elk # 如果記憶體小於1G可能會報錯 使用sysctl命令進行臨時修改
訪問 ip:9200/_search?pretty 
# filebeat下載安裝(原始碼安裝 推薦先cd /etc/opt中)
https://www.elastic.co/cn/downloads/beats/filebeat # 下載好拖到linux中
tar -zxf filebeat-7.4.0-linux-x86_64.tar.gz # 解壓
cd filebeat-7.4.0-linux-x86_64

# 修改配置檔案
vim filebeat.yml
enabled: true
path: # 收集日誌目錄地址 /var/lib/docker/containers 預設docker存放容器地址
- /var/lib/docker/containers/*/*.log
output.elasticsearch: # 連線收集log的ip
hosts: ["localhost:9200"]
# 啟動
./filebeat -e -c filebeat.yml -d "publish" 

訪問 ip:5601 # k8



fluent/fluentd # 用作日誌收集
# 主機1
mkdir /ex_log

# 主機1
docker run -d -p 24224:24224 -p 24224:24224/udp -v /ex_log:/ex/log fluent/fluentd # -v 掛載本地檔案至某處 

主機2
/etc/docker/daemon.json 中新增
{
"log-driver": "fluentd",
"log-opts": {
"fluentd-address": "開啟fluent/fluentd映象的容器ip:對映埠",
"tag": "自定義標籤"
}
}

重啟
systemctl daemon-reload

systemctl restart docker

# 主機1
修改 filebeat配置檔案
vim /etc/opt/filebeat-7.4.0-linux-x86_64/filebeat.yml
enabled: true
path: # 收集日誌目錄地址 /var/lib/docker/containers 預設docker存放容器地址
- /ex_log/*.log # 前面建立的log目錄

# 啟動
./filebeat -e -c filebeat.yml -d "publish" 

=================== 異常處理
如果出現
Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service"

yum remove docker-*

yum update

sudo yum install docker-ce

systemctl daemon-reload

systemctl restart docker