Google Code Prettify

2023年11月8日 星期三

install nfs server@Ubuntu

在 Linux 上安裝 NFS server,可以用來共享目錄,就像是 Windows 的「共用」一樣,這篇以 Ubuntu 為例。
  1. 先確定系統套件已都更新
    sudo apt update
    sudo apt upgrade
    
  2. 安裝 NFS server
    sudo apt install nfs-kernel-server
    
  3. 建立共享目錄: 目錄可以看自己的需要設定,不一定要這個目錄,而且數量沒有上限。
    sudo mkdir /var/nfs/www
    
  4. 開放共享目錄權限: 確保客戶端可以讀寫
    sudo chown nobody:nogroup /var/nfs/www
    
  5. 設定共享目錄
    sudo vi /etc/exports
    
    在裡面加入如下內容,IP 是我的 NFS server 的 IP, 要自行依自己的環境更改。
    /var/nfs/www 172.31.192.65(rw,sync,no_subtree_check)
    
  6. 導出共享目錄
    sudo exportfs -a
    
  7. 啟動 NFS server,並設定為系統啟動時自動啟動。
    sudo systemctl start nfs-kernel-server
    sudo systemctl enable nfs-kernel-server
    
  8. 開啟防火牆: 下面的 IP 應該要是 client IP,看那些機器要連進來,就開放給它們,這裡設定為和 server 一樣,是因為我只有一台機器。
    sudo ufw allow from 172.31.192.65 to any port nfs
    sudo ufw enable
    sudo ufw status
    
  9. 注意看最後一個指令 showmount -e 可以查詢出目前 NFS server 分享出那些目錄。

2023年10月28日 星期六

install Kubernetes cluster@Macbook M2

要認真的安裝一個正式營運環境可以用的 K8s cluster,一定是需要許多實體機器 (bare metal) 或是 VM,但是,僅僅要測試用的話,有許多的方法,這裡要使用 Kind 在 Macbook M2 上安裝一個含有一個 control-plane、三個 worker node 的 Kubernetes cluster。

1. 安裝 Homebrew

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

2. 安裝 Docker

brew install --cask docker

3. 安裝 Kind

brew install kind

4. 創建 Kind 配置文件,如下: (存檔為 kind-config.yaml)

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  image: kindest/node:v1.28.0
- role: worker
  image: kindest/node:v1.28.0
- role: worker
  image: kindest/node:v1.28.0
- role: worker
  image: kindest/node:v1.28.0
image 的版本可以在 https://hub.docker.com/r/kindest/node/tags 找到。

5. 創建 Kubernetes cluster

kind create cluster --name my-cluster --config kind-config.yaml


用 docker ps 及 kubectl get nodes 檢查一下 K8s cluster 是否正常運作。

Kind 是在 Docker 上架設 K8s cluster,所以和完全用 bare metal 或 VM 架設的仍會有所不同,包括要連入那些 node,不是透過 ssh,而是用 docker exec -it 指令。


如果要刪除 cluster,指令如下:
kind delete cluster --name my-cluster

2023年6月11日 星期日

web server (https)

現在的網站不只對外服務時一定會使用 https 通訊協定,公司內部也很少看到會用 http,底下說明怎麼為一個網站加上 TLS 需要的憑證。

  1. 程式
  2. @RestController
    public class HelloController {

    @GetMapping(value="/hello/{name}")
    public String hello(@PathVariable String name) {
    return "Hello " + name + "!";
    }
    }
    很簡單的 hello 程式,執行時只要在命令列中下 curl http://localhost:8080/hello/Steven 就會回覆 Hello Steven!
  3. 產生金鑰
  4. keytool -genkey -alias hello -keyalg RSA -keysize 4096 -validity 3650 -dname "CN=localhost,OU=Study,O=Home,L=Danshui,S=NewTaipei,C=Taiwan" -keypass changeit -keystore keystore.jks -storeType jks -storepass changeit
    
    JDK 中有附一個 keytool 的工具程式可以用來產生及管理金鑰,如上指令,產生了一個 RSA 的公私鑰,命名為 hello,放在命名為 keystore.jks 的 keystore 裡。 特別注意,CN 要與 web server 網址相同,表示這個憑證是要用在這台主機站台,storeType 選擇 jks 的話,這是 Java 特有,標準的方式是 PKCS#12,這個後面會再說明。 在下指令的目錄下可以找到指令產生的 keystore.jks 這個檔案,將它拷具到專案所在的根目錄。
  5. 修改 application.yml
  6. server:
    ssl:
    key-store: keystore.jks
    key-store-password: changeit
    key-alias: hello
    這樣執行時,這個站台會使用 keystore.jks 裡的 hello 金鑰為 https 做相關的加解密。
    啟動站台後,再執行以下指令:
    http://localhost:8080/hello/Steven
    
    因為沒有走 https,會得到以下訊息,表示 web server 現在提供的是 TLS 通訊協定的服務。
    Bad Request
    This combination of host and port requires TLS.
    
    改成如下指令,改走 https:
    https://localhost:8080/hello/Steven
    
    出現如下訊息,表示是自簽憑證,無法驗證其是否合法!
    curl: (60) SSL certificate problem: self signed certificate
    More details here: https://curl.se/docs/sslcerts.html
    
    curl failed to verify the legitimacy of the server and therefore could not
    establish a secure connection to it. To learn more about this situation and
    how to fix it, please visit the web page mentioned above.
    
    指令可以改成如下,先略過憑證的檢驗,就可以得到正確的結果:
    curl -k https://localhost:8080/hello/Steven
    
    這當然不是我們要的結果! 憑證必預被驗證其合法性!
  7. 驗證憑證
  8. 用以下指令將 hello 的公鑰匯出:
    keytool -export -file hello.crt -alias hello -rfc -keystore keystore.jks -storePass changeit
    
    上面的 -rfc 參數表示匯出公鑰時採用 PEM 格式。接著重新下以下指令:
    curl --cacert hello.crt https://localhost:8080/hello/Steven
    
    在對 web server 進行 request 時,將公鑰帶過去,即可在 TLS 通訊協定下完成安全的交易。
  9. PKCS#12
  10. 以下列指令將 jks 的憑證轉換成 PKCS#12:
    keytool -importkeystore -srckeystore keystore.jks -destkeystore pkcs12.p12
    
    上面改變的是 keystore 裡的key,接下要將公鑰匯出,指令如下:
    openssl pkcs12 -in pkcs12.p12 -out hello.pem -nodes
    
    將 pkcs12.p12 拷具到專案的根目錄,並且修改 application.yml,如下:
    server:
    ssl:
    key-store: pkcs12.p12
    key-store-password: changeit
    key-alias: hello
    測試的指令如下:
    curl --cert hello.pem https://localhost:8080/hello/Steven
    


2023年2月9日 星期四

GCP: Setup Billing Budgets and configuring alerts

  • 參考資料

一、概念

  1. GCP 是以 Project 為單位,掛載各項資源,每個 Project 要設定一個 Billing Account,用以計算資源的花費。
  2. 個人用戶使用 GCP,會被要求在 Billing Account 上綁定信用卡,依用量每月從信用卡扣款。
  3. 企業用戶是另外簽約,但一樣會有個 Billing Acount,依用量每月由 GCP 向企業收費,或是企業預付一筆錢,隨用量遞減。
  4. Project 綁定 Billing Account 後,管理者可以設定該 Project 的使用額度,每個月多少錢,或總額多少錢,或是使用超過多少錢會發出 alert。

二、步驟

  1. CREATE BUDGET

    • 要進入任何功能,最快的辦法就是由 GCP Console 上方的搜尋列輸入相關字詞,這裡輸入「budgets & alerts」按【ENTER】,就會進入Budgets & alterts 頁。 

    • 按上方的【CREATE BUDGET】即可建立一個新的 BUDGET。 
  2. Scope

    • 名稱為必填欄位,這裡取名為 Steven-Test,接下來可以設定的有 Time range、Projects、Services。 

    • 選擇時間區間,我選擇「Yearly」,每年多少額度。 

    • 選擇 Project,如前面說述,GCP 是以 Project 來管理資源,並計算資源使用了多少錢。 

    • 選擇可以使用的 Services,也就是這個預算只能用在這些 service 上,我很懶的全選,然後按【NEXT】。 
  3. Amount

    • 選擇 Budget type,我選了特定的額度,並且限定為 $500,然後按【NEXT】。 
  4. Actions

    • 紅框的部份可以設定發出警示訊息的條件,想設更多條件可以按【ADD THRESHOLD】,設定完按【FINISH】。 
  5. Finish

    • 設定完成會回到 Budgets & Alerts 頁,如下紅框所示,已經成功新增一個預算項目。 

2023年1月27日 星期五

GCP: Basic concepts of Compute Services

GCP 提供四種 Compute Services:

  1. App Engine

    • GCP 提供的第一個 Compute Service,是一種 PaaS,開發人員只要把程式部署到部台上,即可開始運作,簡稱 GAE。
    • 提供有多種許言、framework、library。
    • 分成兩種環境: 
      • Standard: 在沙盒中執行 
      • Flexible: 在 Docker 中執行
  2. Compute Engine

    • 提供 Linux 和 Windows VM,這個環境簡稱 GCE,屬於 IaaS
    • VM 有提供各種機型,可以調整 CPU core 數、RAM、Storage,實際上就像是一台遠端的機器。
  3. Kubernetes Engine

    • 全托管的 Kubernetes 環境,簡稱 GKE,一般稱這樣的一個容器服務為 CaaS
    • GKE 由 Stack Driver 監控,這是 Google Cloud 系統內置的監控平台。
  4. Cloud Functions

    • Serverless 環境,不需要先配置 VM 或 Container、K8s 即可運行程式。
    • 這種程式通常是被事件觸發,當被外部事件觸發才執行。
    • Cloud Functions 支持三種語言: JavaScript、Python 3、Go
    • Cloud Functions 包含三部份: Trigger、event、function,程式員定義一個 event,透過 trigger 連結到 fuction,這樣的服務又稱為 FaaS

四種服務總結如下表: 


GCP: Getting Started with Cloud Shell and gcloud

一、基本觀念

1. Project

  • Project 是 GCP 的計費項目,需要綁定一個 Billing Account (可能是個人信用卡或公司帳號),所有資源會掛在 Project 下,並依使用量計費,從 Billing Account 扣除。
  • Billing 可以開許多個,如下,進入 Billing 功能,按【CREATE ACCOUNT】即可增加,目前我已經有一個命名為 POC 的 Billing Account。 

  • 每個帳號可以開許多 Project,方便管理一個組織中各個不同的工作、組織成員,建立 Project 時,即會選擇要綁定到那一個 Billing Account。 

  • GCP 的資源結構如下,由一個組織,下面可以分 folder,folder 下再分 Project,然後就如上面所說,資源會掛到 Project 下。 

     在 GCP Console 中的「Manage resource」功能中,可以管理 Project。 


2. Cloud Shell

  • GCP Console 是 GUI 管理介面,Cloud Shell 是命令列管理介面。

  • 開啟 Cloud Shell 的方式,很簡單,按下 GCP Console 的右上角紅色框起來的按鍵即可,開啟後會出現在下面,如綠框所示。

  • Cloud Shell 是基於 GCE (Google Compute Engine) 的 VM,這個 VM 的 OS 是 Debian,內附 5 GB 的儲存空間,足夠供管理者安裝一些必要的功具軟體,預設已經安裝好 Google Cloud SDK。

  • Google Cloud SDK 包含 gcloud、gsutil、kubectl、bq 等命令列指令,SDK 也可以安裝在 VM 或任何電腦上,OS 支援 Windows、Linux、Mac,Cloud SDK 本身是免費的,當然如果是安裝在 GCP 上的 VM,VM 會產生費用,安裝在自己的電腦,用來管理公有雲上的資源也是可以,這樣就不會有費用。

二、gcloud 命令

1. activate Cloud Shell

  • gcloud auth list
    列出有效的帳號名稱,如下,目前僅一個有效的帳號,可以同時登入多個,並透過 gcloud config set account … 切換帳號。 

  • gcloud config list project
    ​列出 project ID,如下所示。 

2. Configuration your environment

  • gcloud config get-value compute/region
    如下,可以看到一開始沒有設定預設的 region、zone,因此透過 gcloud config set compute/region asia-east1-b 將預計的 region、zone 設定在台灣彰濱機房的 zone b。 

  • gcloud config set compute/zone
    重新下指令查詢,可以看到 region 已經設定,但是 zone 沒有! 也就是說 set compute/region 真的只設定了 region 卻沒有設定 zone,透過 gcloud config set compute/zone asia-east1-b 才設定好 zone。 

3. Finding project information

  • gcloud config get-value project
    查出目前正在使用的 project。 
  • gcloud compute project-info describe --project $(gcloud config get-value project)
    上面指令 --project 後面的參數是 project id,可以查出這個 project 的詳細設定。 

4. Setting environment variables

  • export PROJECT_ID=$(gcloud config get-value project)
    設定環境變數 PROJECT_ID 為目前 project 的 id。
  • export ZONE=$(gcloud config get-value compute/zone)
    設定環境變數 ZONE 為目前系統所在的 available zone。
  • echo -e "PROJECT ID: $PROJECT_ID\nZONE: $ZONE"
    用 echo 指令顯示出上述兩個環境變數,確認值是正確的。 

5. Creating a virtual machine with the gcloud tool

  • gcloud compute instances create gcelab2 --machine-type e2-medium --zone $ZONE
    在 $ZONE ( asia-east1-b ) 建立一個新的 VM,命名為 gcelab2,VM 型別為 e2-medium。 


    用 GCP Console 查看,確實有建立出來,如下: 


  • gcloud compute instances create --help
    這個指令可以顯示出說明文件,查看有那些參數可以用。

6. Exploring gcloud commands

  • gcloud -h
    -h 參數,可以顯示出如下的命令說明文件。 

  • gcloud config --help or gcloud help config
    這兩個命令是等價的,都顯示出 gcloud config 的命令說明文件。
  • gcloud config list
    列出目前環境裡的所有 gcloud 設定。 

  • gcloud config list --all
    這個指令和上一個指令最大差別的,沒有設定值的也會被列出來,可以看出來有那些值可以設定。
  • gcloud components list
    這個指令會列出已安裝的所有 component 

  • gcloud components install COMPONENT_ID
  • gcloud components remove COMPONENT_ID
    上面兩個指令可以安裝、移除 component

7. Filtering command-line output

  • gcloud compute instances list
    列出目前 project 中的所有 VM,目前只有剛剛建立的 gcelab2 這個 VM。 

  • gcloud compute instances list --filter="name=('gcelab2')"
    如果 project 中 VM 很多,可以加上過濾條件,上面指令的過濾條件是 name。
  • gcloud compute firewall-rules list
    列出 project 中的所有防火牆規則,會非常多,通常會加上過濾條件。
  • gcloud compute firewall-rules list --filter="ALLOW:'icmp'" 

8. Connecting to your VM instance

  • gcloud compute ssh gcelab2 --zone $ZONE
    ssh 到剛剛建立的 VM,當目前的 zone 和要連入的 VM 所處的 zone 不同,才需要指定 zone。 

  • sudo apt install -y nginx
    在 VM 中安裝 NGINX
  • exit
    離開 VM

9. Updating the firewall

  • gcloud compute firewall-rules list
    列出 project 中的所有防火牆規則,會非常多,通常會加上過濾條件,參看上面第 7 項。
  • gcloud compute instances add-tags gcelab2 --tags http-server,https-server
    為 VM 加上 tag http-server、https-server,這只是為了分類及搜尋用途。
  • gcloud compute firewall-rules create default-allow-http --direction=INGRESS --priority=1000 --network=default --action=ALLOW --rules=tcp:80 --source-ranges=0.0.0.0/0 --target-tags=http-server
    為有 tag http-server 的所有 VM 開啟防火牆 port 80。 

  • gcloud compute firewall-rules list --filter=ALLOW:'80'
    列出開放 port 80 的所有防火牆規則 

  • curl http://$(gcloud compute instances list --filter=name:gcelab2 --format='value(EXTERNAL_IP)')
    用 curl 指令,從外部 IP 連線到 VM 裡的 NGINX,確定是否連的到,是否 NGINX 正常運作,如下,表示防火牆確實有開通,NGINX 也正常運作。 

10. Viewing the system logs

  • gcloud logging logs list
    列出可以查看的系統 log 有那些 

  • gcloud logging logs list --filter="compute"
    加上過濾條件,結果如下: 

  • gcloud logging read "resource.type=gce_instance" --limit 5
    讀取 log 的內容,指定讀的是 resource.type=gce_instance 裡的 log,並限制只列出 5 個。
  • gcloud logging read "resource.type=gce_instance AND labels.instance_name='gcelab2'" --limit 5
    讀取指定 VM 的 log

 

2023年1月10日 星期二

GCP: Configuring Networks via gcloud

 準備環境

開啟 Cloud Shell,看一下它是什麼 OS ?

cat /etc/os-release

看來是 Debian,因為這篇是要設定網路組態,需要用到 ping 指令,先執行如下指令安裝:

sudo apt install iputils-ping
進入主題前,先了解以下基本觀念:
  1. VPC (Virtual Private Cloud) 在 GCP 中是彼此隔離的。

  2. 每個 Google Cloud project 建立時,系統會自動建立一個預設的 subnet 網路。

Create network

  • 基礎觀念

  1. VPC 分兩種模式 (mode): auto、custom。

  2. 在同一個 project 裡,VPC 名稱不能重複。

  3. 每個 project 可以有四個 VPC

  • 建立 network

建立一個 custom 模式的網路,指令如下,網路命名為 labnet。

gcloud compute networks create labnet --subnet-mode=custom

上面的指令說明如下:

  1. gcloud: 調用 Cloud SDK 裡的 gcloud 命令

  2. compute: gcloud 指令集之一

  3. network: compute 的指令集之一

  4. create: 執行的動作

  5. labnet: 網路名稱

  6. --subnet-mode=custom: 指定要建立的網路模式為 custom

點選 Google Cloud Console 左邊選單「網路 > 虛擬私有雲網路 > 虛擬私有雲網路」


顯示出如下畫面,確實建立了一個名稱為 labnet 的 Network。

Create a subnetwork

  • 基礎觀念

  1. 一個 project 可以跨好幾個 region

  2. subnetwork 的名稱在同一個 project 的同一個 region 裡不能重複

  3. subnetwork 的名稱在同一個 project 可在不同 region 出現兩次

  4. 每個 subnetwork 要設定一個 IP 網段,這個網段在同一 project 的同一 region 中不可與其它 subnetwork 衝突。

  • 建立 subnetwork

建立 subnetwork 指令如下:

gcloud compute networks subnets create labnet-sub --network labnet --region asia-east1 --range 10.0.0.0/28
這個 subnetwork 的 IP 範圍會是 10.0.0.0 ~ 10.0.0.255
Viewing networks
gcloud compute networks list

顯示出共有兩個網路,一個 default、一個 labnet,與從控制台的「虛擬私有網路」看到是一樣的,要看網路的詳細資料,指令如下:
gcloud compute networks describe labnet
最後一個參數是網路名稱,這裡查看剛剛新建立的 labnet,得到如下結果:

List subnets
gcloud compute networks subnets list
如上指令查看 subnets,得到的結果非常多,找到 labnet-sub 的 subnetwork,內容如下:

內容太多不好找,可以執加過濾條件,如下,只會列出在台灣彰濱機房的 subnetwork。

gcloud compute networks subnets list --filter=“REGION: asis-east1”
Creating firewall rules
  • 基礎觀念
  1. network 的模式 (mode) 為 custom 時,系統不會預設建立任何防火牆規則。

  2. 防火牆規則是定義在 network 層。

  3. 防火牆規則的名稱,在同一個 project 中不可重複。

gcloud compute firewall-rules create labnet-allow-internal --network=labnet --action=ALLOW --rules=icmp,tcp:22 --source-ranges=0.0.0.0/0
  • 建立防火牆規則
上面指令為 network labnet 建立了一條防火牆規則,名為 labnet-allow-internal,允許通過 icmp 及 tcp:22 port,連線來源不設限,說明如下:
  1. firewall-rules: compute 指令的子類別

  2. create: 這次指令要做的事 (動詞)

  3. labnet-allow-internal: 防火牆規則名稱

  4. --network=labnet: 指出這個防火牆規則要套用到那個 network

  5. --action: 有兩個值 ALLOW (允許)、DENY (拒絕),這裡是要開通防火牆,所以用 ALLOW。

  6. --rule=icmp,tcp:22 : 指出要開通的通訊協定 (icmp、tcp) 和 port (22)。

  7. --srouce-ranges=0.0.0.0/0: 規定來源 IP 的範圍

Viewing firewall rules details
gcloud compute firewall-rules describe [FIREWALL_RULE_NAME]
這個指令可以查看防火牆規則的細節,執行後產生的結果如下:

從上面的細節內容 direction: INGRESS,可以看出來,開通的這個防火牆是單向的,只允許由外向內。
Create another network
gcloud compute networks create privatenet --subnet-mode=custom
上面指令,會建立一個名稱為 privatenet 的 network,其 mode=custom,執行結果如下圖,訊息顯示,這個時候這個 network 還沒有套用任何防火牆規則。
gcloud compute networks subnets create private-sub --network=privatenet --region=asia-east1 --range 10.1.0.0/28
上面指令執行結果如下圖,在 network privatent 中建立了一個名稱為 private-sub 的 subnetwork (子網路)。
Create  the firewall rules for privatenet
gcloud compute firewall-rules create privatenet-deny --network=privatenet --action=DENY --rules=icmp,tcp:22 --source-ranges=0.0.0.0/0
這個指令建立的防火牆規則和前面剛好相反,這個規則允許除 icpm、tcp:22 的所有連線通過,執行結果如下:
想看一下這條規則的詳細說明,如下用如下指令:
gcloud compute firewall-rules describe privatenet-deny
到目前建立了兩個 network,可以用以下指令列出來看看
gcloud compute firewall-rules list --sort-by=NETWORK

上面指令包含預設的都會列出來,如果只想列出我們自行建立的,可以加上過濾條件。

gcloud compute firewall-rules list --sort-by=NETWORK --filter=“NETWORK != ‘default’”
Create VM instances

查一下到目前為止,我們建立了那些 subnets。

gcloud compute networks subnets list --filter=“REGION = ‘asia-east1’”

執行結果如下:

接下來要在 labnet-sub 及 privatek-sub 兩個 subnets 中各建立一個 VM,用來測試網路是否有通。
  • Create the pnet-vm instance
gcloud compute instances create pnet-vm --zone=asia-east1-c --machine-type=n1-standard-1 --subnet=private-sub

執行結果如下,在 AZ = asia-east1-c 的機房,在子網路 private-sub 裡建立了名稱為 pnet-vm 的 VM,內部 IP: 10.1.0.2,外部 IP: 35.221.157.5。

  • Create the lnet-vm instance
gcloud compute instances create lnet-vm --zone=asia-east1-c --machine-type=n1-standard-1 --subnet=labnet-sub

執行結果如下,在 AZ = asia-east1-c 的機房,在子網路 labnet-sub 裡建立了名稱為 lnet-vm 的 VM,內部 IP: 10.0.0.2,外部 IP: 34.80.241.172。

檢查上面建立的兩個 VM,列出來看看,指令如下:

gcloud compute instances list --sort-by=ZONE --filter="ZONE='asia-east1-c'"

結果如下, STATUS 都是 RUNNING,正常在運作。

Explore the connectivity

檢查一下防火牆,在自己的電腦開個命令列視窗,ping 上面的兩個外部 IP。

結果是 lnet-vm 可以通,pnet-vm 不通,如預期!