###### tags: `lsa` `ncnu`
# Week 09 (2023/04/20)
- Book mode: https://hackmd.io/@ncnu-opensource/book
[TOC]
---
### docker 架構

- 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` 保持原樣

- 刪除 merged 的 b.txt
- 不會刪除 lower2 的 b.txt

> 黃色文字代表透過 **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 保存

- 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

> [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 種服務模式
####

#### 必要特性
* 硬體
- 多核心處理器,提供大量運算資源
- 虛擬化
- 可以快速配置運算資源
- 可以是情況變動實體資源的配置
- 虛擬機比實體主機更方便集中管理
- 分散式運算
- 網格運算:雲端運算使用網格運算的概念,以分散式運算技術創造龐大的運算資源
- 如果有一台超級電腦無法解決的問題,交給很多台電腦做
- 網路運算通常是解決複雜的單一任務
- 例如:基因定序
> 基因定序因為 DNA 有許有多種排序組合,用一般的方式會花費非常久的時間
- 雲端運算的目的則通常是處理大眾應用的運算,大量的使用者會產生龐大的運算量,所以也需要分散式運算來處理
- MapReduce:將大規模的運算任務割成多段分給多個 Server 做處理,最後再將結果整合在一起。
- 就像是選舉開票一樣,很多個開票所開票,最後在統整投票結果。
:::info
## MapReduce:以計算字串為例

- 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(自我保護):系統會自動偵測、識別攻擊,並保護系統
- 維持系統的安全性及完整性
:::
- 資料中心自動化:自動化硬體、系統、網路等資源的監控活管理等服務,減少人力涉入,提高資料中心的運作效率,使使用者可快速使用服務。
#### 服務模式

- 分成需要自己管理(淺藍色)或由供應商負責管理(深藍色)的資源
- 雲端服務依照供應商提供的來判斷是哪種服務
- Network
- 實體網路線、switch、router 等設備組重
- VLAN(Virutal LAN 虛擬區域網路)
- 在同一個區網內,透過邏輯把區網劃分出多個 VLAN,每個 VLAN 都具備和真實區域網路一樣的功能
-
:::info
#### VLAN
- 在同一個區網底下切多個小段的虛擬網路,每段虛擬網路雖然在同個區網,但無法相互溝通
- 實體區域網路
- 
- 虛擬區域網路
- 
- 三種實現方式
- 實體層:以 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://www.ithome.com.tw/article/93013)
1. 公有雲模式(public cloud)
- 供應商負責建置與維護設備
- 資料存取在供應商,敏感資料若存取在別人那,可能會有安全疑慮
- 供應商
- AWS
- AZURE
2. 私有雲模式(private cloud)
- 只會給企業使用
- 資料和程式都由自己保管
- 費用比較高
3. 社群雲模式(community cloud)
- 共同成立的
4. 混合雲模式(Hybird cloud)
- 好處是可以結合不同雲的優點
- 缺點:比較難部屬
- 常見混和方式:公 + 私
- 可以將敏感資料自己保管,但使用供應商的服務
| 類型 | 公有雲 | 私有雲 | 混合雲 |
|:----:|:----------------------------------------:|:--------------------------------:|:--------------:|
| 優點 | 初始成本低 不需要維護成本 容易部屬和擴增 | 資料曝光度比要低;能掌控雲端環境 | 享有公有&私有雲的優點 |
| 缺點 | 資料曝光度比要高;無法掌控雲端環境 | 維護成本高 不易擴展 | 整合和管理複雜 |
:::info
#### VPC 虛擬私有雲

> [圖片來源](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
* 管理進出子網路的流量
* 可以設定允許和拒絕的規則
* 傳輸之前,會依規則編號順序
:::