###### tags: `lsa` `ncnu` # Week 09 (2023/04/20) - Book mode: https://hackmd.io/@ncnu-opensource/book [TOC] --- ### docker 架構 ![](https://i.imgur.com/9bCGhWt.png) - docker demon 會去 image 看有哪些可以用 - 透過 image 可以建立一個 container **Docker repository (倉庫)** - 存放 docker image 的地方 - 有須多已經 build 好的 image 可以直接 pull 下來使用 :::info ### docker 不加 sudo 的方法 - 創建 docker group ```cmd= sudo groupadd docker ``` - 將自己的使用者名稱加入到 docker ```cmd= sudo usermod -aG docker <user name> ``` - 更新 docker 設定 ```cmd= newgrp docker ``` ::: ### docker 指令 - `docker run -d --name wrb -m 512m -p 8080:80 <image>` - `name` container 名稱 - `-m` 限制 memory 只用 - `-p` port :::info ### socket - docker daemon 平常會監聽 /var/run/docker.io #### 種類 - unix socket - tcp socket - 不同電腦間的 process 溝通 - fd socket ::: ### docker object **docker image(映像檔)** - 設計藍圖 - 目的:建立 Container - image 包含 comtainer 資訊 **container** - container layer - 可讀可寫 - 對於 container 的更改會在這層變更,不會影響 image - - 通常會刪除 container layer,不會刪除 image - `bootfs` - 用來仔入 linux kernel * `docker image history image` - 取得 docker image的方法 - 從 Docker repository pull 下來 > Docker Hub - 使用 docker commit 將正在運行的 container 存成一個新的 image - 使用 dockerfile 自己建立 :::warning - 從 repository 中下載 nginx image ```cmd= docker pull nginx ``` - 查看image 的一些細節 ```cmd= docker image inspect nginx ``` - 透過 run 建造名為 nginxcontainer 的 container ```cmd= docker run -it --name nginxcontainer nginx /bin/bash ``` - 創建新的檔案 ```cmd= touch a.txt ``` - 寫入 字串到 a.txt ```cmd= echo "test" >> a.txt ``` - 開一個新的 terminal - commit 一個新的 image 名為 newnginximage ```cmd= docker commit nginxcontainer newnginximage ``` - 條列所有 image ```cmd docker image ls ``` - 查看 newnginximage image 的細節 ```cmd= docker image inspect newnginximage ``` - 可以發現新的 image 會多一層 > 原本 6 層, 現在 7 層 ::: :::info ### Layer - image 透過層層堆疊的方式堆出來的,最多可以疊到 127 層 - 會儲存這次 build 所需要的文件與上一層之間產生的變化 - dockerfile 每一行指令都會建立一個新的 layer ::: #### overlay2 - 準備環境 - 建立五個資料夾 lower1, lower2, upper, merged, work ```cmd= sudo mkdir <資料夾名稱_1> ... <資料夾名稱_5> ``` - lower1 建立 a.txt, x.txt(A) - lower2 建立 b.txt, x.txt - upper 建立 c.txt - merged, work 保持空的資料夾 - 掛載 ```cmd= sudo mount -t overlay everlay -o lowerdir=lower1:lower2,upperdir=upper,workdir=work merged ``` - 上層的 layer 會蓋掉下層的 layer - Lower 1、2 都有 x.txt,查看 merge 後會怎樣 :point_right: 實做的結果只會出現 A(lower1) 的結果 - 修改 `merged/a.txt`,且加上 merged,會發現只有 `merged/a.txt` 有被修改, `lower1` 的 `a.txt` 沒有被修改 - 因為使用 copy-on-write (COW) - 從 `lowerdir` copy `a.txt` 到 `upperdir` - 只有對 `upperdir` 進行讀寫 - `lowerdir` 的 `a.txt` 保持原樣 ![](https://i.imgur.com/szqTWIt.png) - 刪除 merged 的 b.txt - 不會刪除 lower2 的 b.txt ![](https://i.imgur.com/JeiXAUi.png) > 黃色文字代表透過 **whiteout** 拒絕使用者存取 lower2 的 b.txt - 重新命名 merged 的 x.txt to newx.txt - x.txt 表面上會消失(實際上檔案還是會存在於 merged - x.txt 實際上是被 **whiteout** 讓使用者拒絕存取 x.txt,而只看到重新命名過的 newx.txt #### 總結 - image 包裝了需要的程式、套件、執行時所需的環境 * image 是以 Layer 的方式設計,並且用 **UnionFS** 的方式讓這些不同的 layers 看起來像是同一個檔案目錄 * `docker image inspect newnginximage` 查看 newninximage(is a image) 資料 * 查看 upper dir ```cmd= sudo ls <upper dir layer> ``` * 查看 merge dir ```cmd= sudo ls <merged dir layer> ``` - 為什麼 merge dir 不存在 - 因為 image 的作用是保存資料,但是 merge 的資料夾是將所有資料整合後,呈現在使用者面前,所以不會將 merge dir 變成一個 image 保存 ![](https://i.imgur.com/Ak1u5zw.png) - docker run : 建立 Container - docker commit : 可以將正在運行的 Container 保存為一個新的 image #### volume - 保存 container 內的資料於本機,避免刪除 container 之後資料遺失 > 因為 Container 停駛運作後,就會將所有資料刪除,不會留存在本機 - 預設存放位置 - `/var/lib/docker/...<Container1>` - 當今天 Container 的資料夾 - 有修改資料時,本機 (host) 也會更新 - 被刪除時,本機 (host) 會保留原本的資料夾內容 :::warning - 於本機建 volume 名 storedata1 ```cmd= docker voulume creat --name storedata1 ``` ```cmd= docker volume ls ``` - 查看 ```cmd= sudo ls /var/lib/docker/volumes ``` - 指定 storedata1 下的資料夾 db 跟 container 連通 ```cmd= docker run -v storedata1:/db -it --name volume1 ubuntu ``` ### 兩個 Container 資料共享 - 啟動第一個 COntainer ```cmd= docker run -v /data -t --name sharecontainer1 ubuntu ``` - 啟動後,在 sharecontainer1 的/data 新增資料 - 啟動 Container2 ,與剛剛建立的 container2 資料的共享 ```cmd= docker run --volumes-from share1 ubuntu ``` ::: #### dockerfile - 用來撰寫專案所需要的套件或是程式指令 - 純文字檔案,所以檔案小、容易分享 - 由一行一行指令建立 image layer :::warning #### 實做 透過 docker file 建立 docker image - 撰寫 dockerfile ```cmd= sudo vim Dockerfile ``` - dockerfile 的內容 ```cmd= FRMO ubuntu <!-- 在啟動的時候,就印出 hi --> CMD ["/bin/echo", "hi"] ``` - build a docker image ```cmd= docker bulid -t file2 docker run file2 ``` - 條列 docker image ```cmd= docker image ls ``` ```cmd= docker images ``` ::: ### Docker Network * 因應不同需求發展出了多種類別的網路 * --net=<網路模式> * `docker network ls` ### Bridge networks * 預設的網路模式 * 創造一個 network namespace * Container 會在自己的 network namespace 創造一張網卡 * host 創建一個 bridge,並且透過 veth(Virtual Ethernet) 把 container 與 host 不同的 ### Overlay Networks * 不同實體主機內的 Container 之間可以互相溝通 ### Host networking * 不會有 network namespace * 與 host 共用相同的網路 * port 會共用 ### Macvlan networks * 直接分配實體網卡的 MAC address 給特定的 Container * Container 透過實體網卡使用網路,像一個實體裝置一樣 ### Container networks * 加入現有的 network namespace * docker run --network=container:$(docker ps --filter name=< A container name> -q) -d ### 使用情境 | Network | 使用情境 | | -------- | -------- | | Bridge | 同一台 host 的 Container 之間可以透過 IP 互通 | | Overlay | 不同 host 上的 Container 互相溝通 | | Host | Container 需要針對 host 的網路環境進行操作或控制 | | Maclvan | Container 有自己的網卡跟對外溝通 | | Container | 可以使用 localhost 來存取彼此服務 | | none | 想要開發網路模型 | ### Docker #### 啟動、顯示、連線 Container ```cmd= docker run -it --name <cotainter name> ``` - `-t` 透過 terminel 模式建立 container - `-i` 能跟 container 互動的參數,e.g. 輸入指令後,container 回傳指令結果 - `--name` : 配置一個名稱給 Container > 若 image 不在本機的話 , Docker 會自動幫你 docker pull `<image>` ```cmd= docker container ls -a ``` - `-a` 查看所有 Container (不管有沒有啟動) - 啟動 container ```cmd= docker start <container name or id> ``` - 以 terminal 模式在背景進入 container 執行 ```cmd= docker exec -it <container_name or id> bash ``` - 測試看看離開會不會關閉 - `exit` - `docker container ls` - 查看 container 的使用者 - 在外部向**執行中的 Container** 內部下指令 ```cmd= docker exec -it app1 whoami ``` - 刪除 container ```cmd= docker rm -f <container name or id> ``` - `-f` : force remove - 刪除 image ``` docker rmi <image名稱> ``` #### 限制 Container 資源 - 要先查看 Container 資源使用量 ```cmd= docker run --memory 512MB --name nginx1 -d nginx` docker stats <container> ``` - 限制 CPU 使用量 : 沒限制 V.S. 有限制 ,來分別執行 `while.sh` - 沒限制 ```cmd= docker run --name <container name> -it centos /bin/bash ``` - 有限制 ```cmd= docker run --name --cpu-period=1000000 --cpu-quota=500000 --name centos2 -it centos /bin/bash ``` - `--cpu-period` 分配 CPU 資源多久做一次 - 設置 1000000 代表 1 秒 - `--cpu-quota` 最多有多少時間可以跑 Container - 設置 500000 代表 0.5 秒 - 500000/1000000 = 50%,代表最多只可以使用 50% 的 CPU 資源 - 執行 `while.sh` ```cmd= time bash while.sh ``` #### 在 Container 安裝 & 啟動 Apache 的 http service - 啟動 container ``` docker run -it --name apachecontainer ubuntu ``` - 更新 apt ``` apt-get update ``` - 安裝、啟動 apache service ```cmd= apt-get install -y apache2 service apache2 start ``` ### Docker Compose - 運行多個 docker container 的工具 - 搭配 `docker-compose.yml` 文件使用 - 使用步驟: 1. 安裝 Docker-Compose 2. 寫一個 docker-compose.yml ![](https://i.imgur.com/oIRJWAg.png) > [Compose 參考來源](https://hub.docker.com/_/mariadb) 3. 用 `docker-compose up` - 安裝 ``` apt-get install docker compose ``` - 透過 compose 啟動的 container 有哪些 ```cmd= docker-compose ps ``` - 8080 port :point_right: 在瀏覽器輸入 : `127.0.0.1:8080` - 檢查 conatainer 是否被新建 ```cmd= docker container ls ``` - 停止 container - `docker-compose stop` ## 雲端運算 Cloud Computing ### 雲端運算是... - 會有一個雲端計算機,可以透過網路連線進入 - 跟自己在家架伺服器的差別 - 必須提供一定條件的服務 - e.g. - 根據使用者需求配置、調整資源 - 隨時隨地都能透過網路連線主機 ### 要符合哪些條件才算是雲端運算 NIST (National Institute of Standards and Technology) 定義 : - 5 個必要特性 - 4 種部屬模式 - 3 種服務模式 #### ![](https://i.imgur.com/wArVyJN.png) #### 必要特性 * 硬體 - 多核心處理器,提供大量運算資源 - 虛擬化 - 可以快速配置運算資源 - 可以是情況變動實體資源的配置 - 虛擬機比實體主機更方便集中管理 - 分散式運算 - 網格運算:雲端運算使用網格運算的概念,以分散式運算技術創造龐大的運算資源 - 如果有一台超級電腦無法解決的問題,交給很多台電腦做 - 網路運算通常是解決複雜的單一任務 - 例如:基因定序 > 基因定序因為 DNA 有許有多種排序組合,用一般的方式會花費非常久的時間 - 雲端運算的目的則通常是處理大眾應用的運算,大量的使用者會產生龐大的運算量,所以也需要分散式運算來處理 - MapReduce:將大規模的運算任務割成多段分給多個 Server 做處理,最後再將結果整合在一起。 - 就像是選舉開票一樣,很多個開票所開票,最後在統整投票結果。 :::info ## MapReduce:以計算字串為例 ![](https://i.imgur.com/pA3dO3Q.png) - input : 要做計算的原始資料,以上圖為例其實就是一堆文字清單 - split : 把 input 做切割 - map : 每一個節點會把對應切割出來的資料建立 key value 結果, - key : 字本身 - value : 1 代表找到一筆 - combine : 把每個 key 合併 (combine) , 避免多次傳出去,用於減少網路傳遞的流量來提高性能。 > optional (可選擇) 的步驟 - shuffle & sort : 在進行 reduce 之前,會先做 sort (排序) , 相關的 key vlaue 會放在一起 - reduce: 這個階段會做實際的加總,因此每個 ket 的 value 會被加總 - output: 最後輸出的結果 ::: :::info ### 網格運算 V.S. MapReduce - 網格運算雖然把運算任務切分,但每台電腦共用原始資料 * MapReduce 則會把任務和資料都切分 ::: * NoSQL:解決大量運算產生的資料擴增需求 * Key-value 資料庫 * 每一個 key對應到一個 value * 新增一個 key 等同傳統資料庫新增一個 value * 每一個資料之間沒有關聯,可以隨意新增刪除 - 可儲存多種類型的資料 - 可以把資料分度在不同設備 - 因此可用性較高,若其中一個節點故障,可換到另一個節點,就可繼續使用 * 網路 * 網際網路:讓各個設備互相連接,共享軟體服務 * SOA 服務導向架構 (Service-Oriented Architecture) * Web 2.0 - Mashup:讓使用者可已透過網頁操作軟體 * Web 2.0 以使用者為中心,強化使用者與網頁互動 * Mashup:把不同來源的網頁、應用程式或服務結合 - 系統管理 - 自主運算(Autonomic Computing):讓管理員可以更簡單的管理主機,克服系統快速擴張所帶來的複雜性 :::info * IBM 定義了自主運算系統的 4 種特性和各自對應的共 8 個條件 1. Self-configuration(自我配置):系統自動完成資源配置,並可以根據需求自動調整 - 知道自己可以存取哪些資源 - 基於開放標準,不會限制某個私有環境下 - 可以連續適應環境變化,與周圍的系統互動並建立通訊設定 - 可以預測對資源的需求,同時保持使用者透明度 2. self-healing (自我修復):系統會自動發現、修正故障 3. self-optimization - 可以最佳化性能,確保運作的最高效率 - 可以根據環境變化自動進行配置和重新配置 4. self-protection(自我保護):系統會自動偵測、識別攻擊,並保護系統 - 維持系統的安全性及完整性 ::: - 資料中心自動化:自動化硬體、系統、網路等資源的監控活管理等服務,減少人力涉入,提高資料中心的運作效率,使使用者可快速使用服務。 #### 服務模式 ![](https://i.imgur.com/KayhpeM.png) - 分成需要自己管理(淺藍色)或由供應商負責管理(深藍色)的資源 - 雲端服務依照供應商提供的來判斷是哪種服務 - Network - 實體網路線、switch、router 等設備組重 - VLAN(Virutal LAN 虛擬區域網路) - 在同一個區網內,透過邏輯把區網劃分出多個 VLAN,每個 VLAN 都具備和真實區域網路一樣的功能 - :::info #### VLAN - 在同一個區網底下切多個小段的虛擬網路,每段虛擬網路雖然在同個區網,但無法相互溝通 - 實體區域網路 - ![](https://i.imgur.com/OSqElCg.png) - 虛擬區域網路 - ![](https://i.imgur.com/sv0Sgaa.png) - 三種實現方式 - 實體層:以 switch 讀 port 來區分 VLAN - 資料連接層:以 MAC 來區分 VLAN - 網路層:以 IP 子網路或翁訊協定來區分 VLAN - 優點: - 減少廣播流量浪費,因為只有同 VLAN 下的主機會收到廣播 - 增加網路安全性,沒有使用 VLAN 的網路下,同 switch 下的主機可以從廣播封包中得到每個主機的重要資訊,例如 IP Address 和 MAC Address - 附上一個可以模擬網路的東西-Cisco Packet Tracer ::: - Storage - 資料儲存在資料中心的儲存陣列中 - 儲存管理會確保資料備份和定期刪除過期的備份,也會幫資料加上索引方便查找 - Hardware - 虛擬的雲端運算主機需要有實際的硬體提供資源 - 硬體包括網路設備(switch、router 等)、儲存陣列、備份設備、伺服器等 - Virtualization - 將硬體資源做(memory, couputing power, storage)抽象化並放到集中的資源持,使用者就可從資源持使用這些抽象話的資源 - 使用者可以從資源池自由架設或擴張服務 - 其他 - Middleware:中介軟體,為應用程式提供各種通用服務和功能的軟體,讓開發人員創建應用程式更有效率 - Runtime:程式碼在執行的時候所需要的涵式庫和執行環境 - On Premise - IaaS (Infrastructure as a Service) - 雲端供應商提供基礎設施當作服務 - 常見供應商 - AWS: EC2, VPC - GCP: GCE - Azure: VM - PaaS - 平台即服務 - 常見供應商 - - SaaS - 應用程式都不需要寫,只需要連線就可使用 - e.g. - google meet ### 部署模式 ![](https://i.imgur.com/wGA691f.png) >[圖片來源](https://www.ithome.com.tw/article/93013) 1. 公有雲模式(public cloud) - 供應商負責建置與維護設備 - 資料存取在供應商,敏感資料若存取在別人那,可能會有安全疑慮 - 供應商 - AWS - AZURE 2. 私有雲模式(private cloud) - 只會給企業使用 - 資料和程式都由自己保管 - 費用比較高 3. 社群雲模式(community cloud) - 共同成立的 4. 混合雲模式(Hybird cloud) - 好處是可以結合不同雲的優點 - 缺點:比較難部屬 - 常見混和方式:公 + 私 - 可以將敏感資料自己保管,但使用供應商的服務 | 類型 | 公有雲 | 私有雲 | 混合雲 | |:----:|:----------------------------------------:|:--------------------------------:|:--------------:| | 優點 | 初始成本低 不需要維護成本 容易部屬和擴增 | 資料曝光度比要低;能掌控雲端環境 | 享有公有&私有雲的優點 | | 缺點 | 資料曝光度比要高;無法掌控雲端環境 | 維護成本高 不易擴展 | 整合和管理複雜 | :::info #### VPC 虛擬私有雲 ![](https://i.imgur.com/z7YURzP.png) > [圖片來源](https://www.cloudflare.com/zh-tw/learning/cloud/what-is-a-virtual-private-cloud/) - 全名 Virtual Private Cloud - 在公有雲裡面的隔離私有雲 - 就像餐廳訂位,在公有雲中隔離出來只給某使用者使用 ##### 怎麼隔離? - VPC 把私人資源跟其他公有雲的其他資源隔離開來 - 隔離技術包括: - 子網路 - 在 VPC 定義一個 IP Range - 隔離後自己要怎麼從外網進去 - VPN - 虛擬私人網路 (Virtrual Private Network) - 在VPC 上架設 VPN Server - 從外網透過 VPN 連線至 VPC 上的 VPN Server - VPN 伺服器在將外網 IP 位址改為 VPC 內網 IP,就不會被 VPC 網路隔離 - 虛擬私有雲優點 - 擴展性高:VPC 為公有雲供應商管理,使用者可隨時一需求擴增運算資源 - 部署較容易:與混合雲相比部署較簡單,因混合雲為公+斯 #### AWS VPC #### AWS VPC * security group * 管理虛擬機流量 * 只能設定允許的規則 * 傳輸之前檢查全部的規則 * 有狀態、允許回傳流量 * Network ACL * 管理進出子網路的流量 * 可以設定允許和拒絕的規則 * 傳輸之前,會依規則編號順序 :::