## GCP簡單入門手冊 先去看完古古的30天(理論)介紹 https://ithelp.ithome.com.tw/m/articles/10318700 首先要先有信用卡和Google帳戶 然後GCP服務眾多 目標是可以把完整專案丟上雲端,並且可以遠程調用(API或是完整Web服務) 然後因為很重要 所以我會每隔一段就附上 --- ▼▼▼▼▼▼▼▼ [**<font style='color:red; font-size:30px;'>強烈警告</font>**](#強烈警告) ▲▲▲▲▲▲▲▲ --- ## 啟用GCP服務 先啟用服務和試用 google搜尋<font style='color:red;'>GCP</font>就可以看到 ![image](https://hackmd.io/_uploads/S1R3IWj-1l.png) 進入之後可以看到畫面,點擊==免費試用== ![image](https://hackmd.io/_uploads/rJsEDbj-yg.png) 然後就把該填的資料填一填 ![image](https://hackmd.io/_uploads/ryYvPbjWJl.png =60%x) ![image](https://hackmd.io/_uploads/rkYTDboWyx.png) 然後下面要填寫信用卡 ![image](https://hackmd.io/_uploads/S101dZsZJg.png) 完成啟用之後就可以進入到GCP首頁,可以看到啟用了,也有顯示免費試用的抵免額(300鎂轉台幣) ![image](https://hackmd.io/_uploads/Syuhd-sW1e.png) 可以點擊==資訊主業==,看更詳細內容,也都有帳單金額,不用擔心 ![image](https://hackmd.io/_uploads/rJCQKZjZ1e.png) ![image](https://hackmd.io/_uploads/rJVDYZjZkx.png) 點擊上面的選單可以看到,目前所在就是系統自動創建的專案,有需要也可以自己做新增或修改 ![image](https://hackmd.io/_uploads/BkOWsWiZJe.png) 名稱可以在這邊改 ![image](https://hackmd.io/_uploads/S1uLsZoWJg.png =50%x) 但會有一些名稱限制 ![image](https://hackmd.io/_uploads/rkGcobjZJx.png) 儲存之後就可以看到 ![image](https://hackmd.io/_uploads/rJB0oWibJg.png) ## Compute Engine(VM)-練習 ### 簡單部屬 先簡單開個機器來使用 點擊==Compute Engine==,可以進到相關管理畫面,就直接啟用 ![image](https://hackmd.io/_uploads/HJpP2Zi-kg.png =50%x) 啟用之後就可以看到這個畫面,現在還沒有任何VM ![image](https://hackmd.io/_uploads/SJn-V7oZ1e.png) 這邊就點建立執行個體,進入設置頁面 地區可以選台灣,先選最便宜的機器(==f1-micro==) ![image](https://hackmd.io/_uploads/rJEmFXs-Jg.png) ![image](https://hackmd.io/_uploads/SJBAKmsZ1x.png =80%x) 這邊可以指定作業系統 ![image](https://hackmd.io/_uploads/Hy-KcmsW1e.png) ==注意==會依照作業系統不同而有不同的收費,這邊先選<font style='color:red;'>Ubuntu</font>就好 ![image](https://hackmd.io/_uploads/HkZW3XiZyl.png) ![image](https://hackmd.io/_uploads/HJ42nXjbye.png) ![image](https://hackmd.io/_uploads/S1KN67s-Jl.png =60%x) 防火牆部分先勾==HTTP==和==HTTPS== ![image](https://hackmd.io/_uploads/Hyv6TQj-1x.png) 其他部分就先不用設定,就直接點建立,先建起來 ![image](https://hackmd.io/_uploads/S1btR7obye.png) 馬上就好了 然後點擊SSH的按鈕,就可以連線到該機器 ![image](https://hackmd.io/_uploads/r1JlJNjZyx.png) ![image](https://hackmd.io/_uploads/BkiVJVsWJl.png) 然後就可以開始下指令操作,先==sudo apt update== ![image](https://hackmd.io/_uploads/H1zcyEjbyx.png) ![image](https://hackmd.io/_uploads/Sk2RyNj-Jx.png) OK 先安裝apache2,==sudo apt install apache2 -y== ![image](https://hackmd.io/_uploads/Syp7xEiWye.png) 安裝好就可以測試,看看外部IP打開能不能連上(==要改成http,因為https還沒配置==) ![image](https://hackmd.io/_uploads/H1EAl4oZJx.png) ![image](https://hackmd.io/_uploads/S11V-NsZyl.png) 應該就可以看見apache2的畫面了 ![image](https://hackmd.io/_uploads/Byj8bEjb1g.png =60%x) 接下來測試一下靜態網頁 這邊都先不管域名,目前連線到對外IP的畫面就是apache2的畫面 默認路徑為 ==/var/www/html/== 先移動到該路徑底下 ![image](https://hackmd.io/_uploads/Syv4n4jZyl.png) 然後創建一個自己名稱的資料夾,==sudo mkdir -p== index.html是apache2默認建立的首頁 ![image](https://hackmd.io/_uploads/r12cnEi-yl.png) 然後這邊先修改權限 ==sudo chown -R \$USER:$USER testweb.com/== ==sudo chmod -R 755 /var/www== ![image](https://hackmd.io/_uploads/rkz6a4sbyl.png) 接下來就是在新建的資料夾底下新增想呈現的靜態頁面,==sudo vim index.html== ![image](https://hackmd.io/_uploads/BJPvC4iWkg.png) 至於內容,就隨便寫個html標籤吧 ```html= <html> <head> <title>TestTitle123</title> </head> <body> <h1>Welcome to testWeb</h1> </body> </html> ``` 好了就存檔,記得確定一下內容 ![image](https://hackmd.io/_uploads/ry4aRVsbkx.png) 要顯示的頁面處理好了,接下來就是要==更改預設路徑的指向到剛剛新增的路徑== 先移動到路徑 ==/etc/apache2/sites-available/== 底下 ![image](https://hackmd.io/_uploads/rJAulHsW1e.png) 可以看到底下的文件==000-default.conf== 就是配置文件 ![image](https://hackmd.io/_uploads/BkBCeSoW1g.png) 這邊就直接複製一份==sudo cp 000-default.conf testweb.com.conf==到本地 ![image](https://hackmd.io/_uploads/rkhXZHiZJl.png) 然後一樣vim編輯內容 ![image](https://hackmd.io/_uploads/SJVgMrsZyl.png) 把內容改成 ![image](https://hackmd.io/_uploads/HJ8IMBiWkg.png) 主要就是把root指向改到剛剛新增的路徑下,好了一樣存檔退出 再來就是要把預設的配置檔改成使用剛剛複製的新配置 ==sudo a2ensite testweb.com.conf== 指向新配置 ==sudo a2dissite 000-default.conf== 停止舊配置 然後下指令時會顯示需要重啟apache2,==sudo systemctl reload apache2== ![image](https://hackmd.io/_uploads/SJiUQHib1e.png) 這樣就更改完配置指向了 可以測試==sudo apache2ctl configtest== ![image](https://hackmd.io/_uploads/SyFhErjW1e.png) 然後就重新整理剛剛的對外IP的頁面,應該就會指向到新增的靜態頁面了 ![image](https://hackmd.io/_uploads/S1K_BriWke.png) ### 遠端連線(SFTP_FileZilla) 如果要更新文件或是有其他比較複雜的動作,不想只依靠指令,可以利用fileZilla連線操作,但要透過SFTP連線需要設定雙向金鑰 1. 先在服務端輸入指令==ssh-keygen -t rsa -b 2048 -f ~/.ssh/gcp_key== 會產生gcp_key的金鑰檔案 ![image](https://hackmd.io/_uploads/Hy7BnSs-1x.png) 2. 複製==gcp_key.pub==檔案內容 ![image](https://hackmd.io/_uploads/Sy6d2BsWJl.png) 3. 進入VM點擊編輯,往下看到金鑰,新增並且把剛剛複製的金鑰貼上並儲存 ![image](https://hackmd.io/_uploads/B1032Sj-yl.png) ![image](https://hackmd.io/_uploads/BkdBpSjWyg.png) 4. 回到VM首頁,複製對外IP ![image](https://hackmd.io/_uploads/ryEsaHjW1x.png) 5. 開啟fileZilla,開啟檔案>站台管理 ![image](https://hackmd.io/_uploads/H11FULobJx.png) 金鑰檔案的部分就回到ubuntu終端,這次複製==gcp_key==文件內容,然後本地隨便建立一個文件儲存,之後把連線金鑰指向該文件 ![image](https://hackmd.io/_uploads/SyinASs-kx.png =70%x) ![image](https://hackmd.io/_uploads/HkXjlIi-1e.png =70%x) 好了之後點選連線,就可以成功連線到系統了 ![image](https://hackmd.io/_uploads/Syl9JLjbJg.png) ### Free-domain(DNS) 現在可以利用對外IP來連線到雲端服務器的頁面 但要記憶IP實在麻煩,所以接下來會需要綁個域名到IP,就需要用到DNS 網上有很多DNS商,這邊就用免費的[Duck DNS](https://www.duckdns.org/) 只要登入就可以使用,很方便 (當然還是有很多其他免費DNS,選喜歡的就好) ![image](https://hackmd.io/_uploads/ByojIElzyg.png) 1. 輸入想建立的域名,點擊add domain,就會在下面新增剛剛創建的<font style='color:red;'>domainName</font>.duckdns.org 2. 把GCP服務的對外external IP綁到這個current IP 3. 測試連線到<span>domainName</span>.duckdns.org,應該就可以連上服務了 ![image](https://hackmd.io/_uploads/ryY_HEgGkx.png) 但還有一個問題,就是現在GCP的服務IP還是dynamic IP,如果服務重啟IP就會改變,那這個綁定的domain就會失效,還需要手動更改,所以接下來就是要在服務器上利用bash排程和DuckDNS的API來更新綁定的IP 1. 先回到GCP,開啟服務終端 ![image](https://hackmd.io/_uploads/BkNOdVgM1g.png =70%x) 2. 先安裝curl,等下要用來裝其他東西 ```bash= sudo apt update sudo apt install curl ``` ![image](https://hackmd.io/_uploads/rkeBFExf1g.png =70%x) 3. 建個duckdns的資料夾 ```bash= mkdir ~/duckdns cd ~/duckdns ``` ![image](https://hackmd.io/_uploads/By1u5VxGkl.png) 4. nano新增一個bash文件,內容放上修改IP的API和帳戶Token,也可以在[官方教學](https://www.duckdns.org/install.jsp)找到 這邊有稍微修改一下log,加上時間,並且用 ==>>== 不用複寫的方式,整理log格式 ```bash= #!/bin/bash datetime=$(date '+%Y-%m-%d %H:%M:%S') result=$(echo url="https://www.duckdns.org/update?domains=exampledomain&token=yourToken&ip=" | curl -k -K -) echo "[$datetime: $result]" >> ~/duckdns/duck.log ``` ![image](https://hackmd.io/_uploads/B190GBgzJx.png =70%x) ![image](https://hackmd.io/_uploads/SkP8TBeMyg.png) 5. 編輯文件權限,這樣bash部分就完成了 ```bash= chmod +x duckdns.sh ``` ![image](https://hackmd.io/_uploads/rJSAmSxfye.png) 6. 接下來就是建立Cron排程,編輯器一樣nano就好 ```bash= crontab -e ``` 內容如下,就是寫Cron ```bash= */5 * * * * ~/duckdns/duckdns.sh >/dev/null 2>&1 ``` 7. 可以自己觸發bash看看 ![image](https://hackmd.io/_uploads/Sk2ihrgM1x.png) 因為有加上時間,也可看cron有沒有觸發(這邊是設置5分鐘) ![image](https://hackmd.io/_uploads/HkSORrxMkl.png) 如果以上執行都沒問題 就可以重啟Compute engine,連線到domain,看看浮動IP指向有沒有成功生效 ### SSL憑證(Compute Engine) [參考這篇](https://www.kjnotes.com/devtools/62) 幫服務免費申請SSL憑證,目前服務還是http ![image](https://hackmd.io/_uploads/SJuNLNgGye.png) 一樣按步驟來 1. 先安裝certbot ```baash= sudo apt-get install certbot python3-certbot-apache -y ``` ![image](https://hackmd.io/_uploads/HyMyYwlMJx.png) 2. 安裝好certbot,就可以申請SSL了,輸入指令 要寫上==自己的email==和換上剛剛申請的==DuckDNS的domain== ```bash= sudo certbot --apache --email yourEmail@gmail.com --agree-tos -d yourDomain.duckdns.org ``` 會先問說要不要分享Email,就依需求選擇 ![image](https://hackmd.io/_uploads/H1G4iPxGJe.png) 再來會問需不需要redirect Http到Https,我是輸入2繼續,確定就會往下執行完成 ![image](https://hackmd.io/_uploads/Sy4y2wlzJl.png) 到這邊就申請完成了 3. 完成之後就可以檢查看看能不能連上 ==https:/\/yourDomain.duckdns.org== 的網域了 然後可以檢查稍早做conf設定的資料夾內,應該會出現新的ssl設置,到這邊就完成了 ![image](https://hackmd.io/_uploads/rJqNTPlz1g.png) ![image](https://hackmd.io/_uploads/BJ-jaPefkl.png) 連上了 不過要注意的是,免費SSL效期只有三個月,如果想要避免重複上述動作,應該就是要另外寫個bash來自動化?這部分我就不太確定,效期可以從剛剛申請完成提供的測試網址看到 ![image](https://hackmd.io/_uploads/BJ5zeOxzJg.png) ![image](https://hackmd.io/_uploads/HJ6PlOgMkg.png) 或是直接在網頁上看憑證也可以 ![image](https://hackmd.io/_uploads/Bkmy-dgzye.png) ### 靜態IP 回到GCP,可以從這邊看到目前使用中的IP ![image](https://hackmd.io/_uploads/SyG7GOgzke.png) 可以看到臨時對外IP ![image](https://hackmd.io/_uploads/rkRUzugGye.png) 點右邊三個點就可以看到==升級為靜態IP== ![image](https://hackmd.io/_uploads/SypazOlM1l.png) 輸入名稱,確認就可以看到轉為靜態IP ![image](https://hackmd.io/_uploads/rJne4uxGJx.png =40%x) ![image](https://hackmd.io/_uploads/Sku4QOez1g.png) ### SSL憑證(Load Balancer) 接下來要講的是由GCP託管的SSL 概念如下 ![image](https://hackmd.io/_uploads/S1Ow-tgf1g.png) ▲這是之前設置的結構,每個compute engine都需要各自申請設置憑證,針對VM的憑證,除了憑證維護、更新繁瑣外,都是要走到GCP內才會經過SSL驗證 所以接下來要做的就是改為憑證交由Google託管,放在Load balancer層,請求可以在外層就被驗證,也可以維護單一SSL就好,如下▼ ![image](https://hackmd.io/_uploads/H1UnQtlfJl.png) 可以看到目前憑證還是主機憑證 ![image](https://hackmd.io/_uploads/r1BnEtgzkg.png =70%x) Load balancer是基於==執行個體群組== 會把幾個VM做成群組這樣才能load balance 就算只有單一VM也要多包一層執行個體群組 接下來流程就是: ->==把要執行的VM instance包成群組== ->==新增Load Balancer和Load Balancer層的SSL== ->==DNS解析到LB層的IP== ->==停用VM層的SSL== 就直接開始 1. 先用[快照](###快照)做個簡單備份 2. 建立一個==執行個體群組== ![image](https://hackmd.io/_uploads/rJbSIYeMJe.png =30%x) ![image](https://hackmd.io/_uploads/ryn9IFeG1e.png =70%x) 3. 這邊要自定義Load Balancer,選非代管群組 <font style='color:red;'>這邊位置區域要選和vm服務器相同,不然執行個體不會出現選項</font> ![image](https://hackmd.io/_uploads/ByoUCKgGJl.png) 4. 通訊埠對應就新增==http==、==80==,代表把連入流量導向到底下instance的80 port ![image](https://hackmd.io/_uploads/BJq4k9ez1g.png) 5. 好了就直接建立 ![image](https://hackmd.io/_uploads/HkD5Jcezyg.png) 6. 再來就是建立Load Balancer和Load Balancer層的SSL ![image](https://hackmd.io/_uploads/HkZrg5lMyx.png) ![image](https://hackmd.io/_uploads/S1IkZ5xGyl.png =70%x) 依序選擇==應用程式負載平衡==>==公開(外部)==>==全域==>==全域== 7. 接下來設定前後端,可以簡單理解為: ==前端==: client連線到GCP Load Balancer的方式 ==後端==: Load Balancer連線到Compute Engine instance的方式 前端協定選HTTPS,就是說client要用https連線到Load Balancer ![image](https://hackmd.io/_uploads/ByUxE5xfJg.png) 8. 建立IP位址,新預留一個靜態IP ![image](https://hackmd.io/_uploads/r1Ow4qgzyl.png =40%x) 9. 建立新憑證,這邊選google代管,然後輸入自己的==domain==,前端到這邊結束 ![image](https://hackmd.io/_uploads/rJNjV5gzJe.png =60%x) ![image](https://hackmd.io/_uploads/rJnV7qez1l.png =50%x) 10. 再來建立後端服務 ![image](https://hackmd.io/_uploads/BJRtHqlGke.png =60%x) ==執行個體群組選剛剛建的那個== 然後Load Balancer連到VM的方式就走http就好,SSL會做在Load Balancer層前端 ![image](https://hackmd.io/_uploads/rJy4wceMkg.png =60%x) ==設定健康檢查== ![image](https://hackmd.io/_uploads/BJHDw9xG1g.png =60%x) ==把Log打開== ![image](https://hackmd.io/_uploads/SJzTwclz1x.png =60%x) ==這裡也打勾,好了就建立== ![image](https://hackmd.io/_uploads/H1gOOqxMkg.png =60%x) 11. 後端服務完成就可以看到轉送服務也打勾了,這裡不用做任何動作,直接建立 ![image](https://hackmd.io/_uploads/BkATdcxGkl.png) 12. 建立完成點進去就可以看到相關配置和IP ![image](https://hackmd.io/_uploads/HJWl5qxGyl.png) 這就是Load Balancer對外的IP,但現在應該還是連不上的 ![image](https://hackmd.io/_uploads/rJcf9cezkg.png =90%x) 點開憑證可以看到,憑證還在路上,這部分可能會需要等好一陣子?先處理其他配置 ![image](https://hackmd.io/_uploads/rJzQj5eGJg.png =70%x) 13. 把DNS解析改成Load Balancer的IP ![image](https://hackmd.io/_uploads/BJIaC5gMyl.png) 14. 進入服務器把最早配置在VM內的SSL副檔名直接改 ==.bak==讓它失效,然後重啟apache2 ![image](https://hackmd.io/_uploads/rk6GA5xfJg.png) 15. 要記得把之前布置的cron任務停掉,不然DNS解析IP會跑掉,因為現在希望是解析到LB的IP不是VM的IP,我是直接註解掉 ![image](https://hackmd.io/_uploads/HyUREilG1e.png =70%x) 接下來就是只能等LB的SSL生效了,包含DNS更改解析IP,最久可能要等個2天... 可以用[https://dnschecker.org/](https://dnschecker.org/)查全球同步,但還是只能等... --- 過了一天回來看,GCP這邊就顯示處理好了 ![image](https://hackmd.io/_uploads/BJV0SnWM1l.png) 接下來就可以連線看看 ![image](https://hackmd.io/_uploads/Sk_U7pbfJg.png =80%x) 顯示重新導向問題,檢查一下conf檔,==/etc/apache2/sites-available/testweb.com.conf== ![image](https://hackmd.io/_uploads/BklxETWM1g.png =80%x) 發現這段,==sudo vim==編輯,把這段註解掉 ![image](https://hackmd.io/_uploads/HJPQB6bG1l.png =80%x) 註解完重啟apache2 ```bash= sudo systemctl reload apache2 ``` 重啟完應該就可以連上了 ![image](https://hackmd.io/_uploads/H1LkUpbMkx.png) 可以看下SSL,現在就變成是Google核發的憑證,走Load Balancer進服務的方式 不過因為是用免費domain,所以google核發的也是==letsencrypt== 只能從核發時間確認是不是新的憑證 ![image](https://hackmd.io/_uploads/r1geT0WGke.png =60%x) 不然正常應該會顯示類似這樣(==GTS==) ![image](https://hackmd.io/_uploads/H1zNT0Wfke.png) ### 快照 就想像是一個快速備份的方式,備份方式是增量不是全量,所以不要隨便刪除舊快照 ![image](https://hackmd.io/_uploads/ryr6KYxfkx.png =30%x) 這邊是簡單快速備份,就選即時快照就好 ![image](https://hackmd.io/_uploads/rJJ_9tlGkg.png =70%x) 好了就直接建立,就可以了 ![image](https://hackmd.io/_uploads/SknT9Yxzyg.png) ## 建構CI/CD完整服務 --- ▼▼▼▼▼▼▼▼ [**<font style='color:red; font-size:30px;'>強烈警告</font>**](#強烈警告) ▲▲▲▲▲▲▲▲ --- ### 服務架構 這邊就先把舊服務停用移除了,雖然是免費試用的額度但還是不想浪費, 也不要多留個有風險的漏洞在那邊 靜態IP和Load Balancer也都清除,就整個重頭開始 理想架構如下 ![image](https://hackmd.io/_uploads/HJAG6sGB1x.png) 主要分為兩個部分: 1. 開一個單一Compute Engine,用docker啟動一個Jenkins服務,做CI的部分,限制連入IP 2. 利用GKE做CD,自動部屬相關服務,服務全部都走ClusterIP內部調用 連入只能透過LoadBalancer,防火牆另外處理(練習建議針對特定IP開放就好) LoadBalancer指向Ingress,SSL做在Ingress,透過路由往下到服務內 服務間透過ClusterIP相互溝通 這是到目前為止進度 :::success √ 專案commit, push上Repository ::: :::danger × Repository自動觸發Jenkins CI,自動打包images上Dockerhub ::: :::danger × CI觸發CD,讓GKE自動更新部署 ::: :::danger × GKE部屬完成確定功能正常 ::: :::danger × 對外服務確定網路安全或流量問題 ::: --- ▼▼▼▼▼▼▼▼ [**<font style='color:red; font-size:30px;'>強烈警告</font>**](#強烈警告) ▲▲▲▲▲▲▲▲ --- 然後專案的資源需求我是依靠本地練習時使用docker-desktop的資源紀錄來看 ### Jenkins服務 就先做jenkins server吧 決定是用E2-medium,作業系統一樣Ubuntu吧,順便練習Linux ![image](https://hackmd.io/_uploads/H1lytBQMJx.png) 就建起來 ![image](https://hackmd.io/_uploads/SkfDlD4fJl.png) 一樣先==sudo apt update==更新 ```bash= sudo apt update ``` 然後就開始安裝需要的東西吧 先裝一些常用工具 ```bash= sudo apt install apt-transport-https ca-certificates curl software-properties-common ``` ![image](https://hackmd.io/_uploads/H1U7Lw4zJl.png) 接下來是安裝docker [參考這裡](https://medium.com/@jieshiun/%E5%A6%82%E4%BD%95%E5%9C%A8-ubuntu-20-04-%E5%AE%89%E8%A3%9D-docker-%E8%88%87-docker-compose-27a88b3d746b) 先下載docker的GPG密鑰 ```bash= curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg ``` 添加軟體源 ```bash= echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null ``` 然後就安裝docker ```bash= sudo apt install docker-ce docker-ce-cli containerd.io -y ``` docker-compose不能用apt裝,因為apt庫版本太舊,要用curl裝 ```bash= #安裝docker-compose sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/bin/docker-compose #更新執行權限 sudo chmod +x /usr/bin/docker-compose ``` 安裝完就可以==docker version==看看有沒有安裝成功 應該就可以看到docker版本了,但這邊應該會出現提示說權限不足 ![image](https://hackmd.io/_uploads/r1PBVOEz1x.png) gcp登入的用戶是沒有docker group的,這邊有兩種方式,一種是每個指令都用sudo,一種就是把用戶加docker group ```bash= sudo usermod -aG docker $USER ``` 加完之後重啟終端才會生效 ![image](https://hackmd.io/_uploads/S1mlU_4fJx.png) 這樣就可以不加sudo了 ![image](https://hackmd.io/_uploads/H1E0LO4fyg.png =50%x) 到這邊docker就安裝完了,接下來就是把先前[配置](https://hackmd.io/SHki-PsHQayuExX-qSXmbQ)做好的docekrfile和docker-compose上傳到Server,直接用建構好的配置來啟動容器,一樣先綁定filezilla的ssh方便之後操作 ![image](https://hackmd.io/_uploads/r1H7yFNM1g.png) 然後預設用戶不是root,所以是沒有資料夾存取權限的, 這邊看到默認目標資料夾 ==(/var/local)== 存取權限是==staff group== ![image](https://hackmd.io/_uploads/r14xPK4zJl.png) 這邊就把本人加到staff組 ```bash= sudo usermod -aG staff your_user ``` 偷懶也可以直接開==777== 如果遇到權限問題也可以善用filezilla會顯示每個文件權限 ![image](https://hackmd.io/_uploads/HyivhFVMJl.png =70%x) 然後這邊可以直接把dynamic IP生成static IP 用static IP連線,因為後面就直接常態使用了 ![image](https://hackmd.io/_uploads/HJiy0K4fJg.png) 連線把要建構的檔案放上Server ![image](https://hackmd.io/_uploads/ryDxZYNGJx.png =70%x) 就都和上面練習差不多 確定放上服務器 ![image](https://hackmd.io/_uploads/rJTMcK4fke.png =70%x) ![image](https://hackmd.io/_uploads/rJ8I9K4zke.png) 接下來就運行docker-compose,確認是不是有在運行 ```bash= docker-compose up --build -d ``` ![image](https://hackmd.io/_uploads/BJUlv5Vzyg.png) 確定成功跑在8080port,但實際測試會發現連不上,原因是因為GCP防火牆會擋掉外部端口連線 但這邊先不管,因為要做成https,先做SSL憑證,後面再處理防火牆 ![image](https://hackmd.io/_uploads/BJrRDc4Mkx.png) DuckDNS加一個domain,解析到VM的外部IP ![image](https://hackmd.io/_uploads/BJ04ceiGJx.png) 然後一樣先安裝apache2,==sudo apt install apache2 -y== 接下來就參照[免費SSL配置](###SSL憑證(Compute-Engine)) 過程省略 ![image](https://hackmd.io/_uploads/BkSyAbszJx.png) 申請好之後,會發現一個問題就是HTTPS連線是443 port進線轉默認80 port(目前是apache2) 也因為這邊沒有走Load Balancer層,不能用執行個體群組導向其他port 但現在要使用的服務在8080 port上,所以這邊要做反向代理服務把默認80轉到8080上 一般可以用==nginx==或是==apache==,這邊就用apache2繼續吧 先確保相關代理模組有安裝,安裝完重啟apache2 ```bash= sudo a2enmod proxy sudo a2enmod proxy_http sudo systemctl restart apache2 ``` ![image](https://hackmd.io/_uploads/Bkta3Wof1x.png) 再來就是要修改apache2的SSL連線配置 ![image](https://hackmd.io/_uploads/B1Eg4Mozyx.png) ==000-default-le-ssl.conf==是監聽443端口 ==000-default.conf==是監聽80端口 ```bash= #就打開編輯配置 sudo nano 000-default-le-ssl.conf ``` 打開可以看到監聽端口,配置ProxyPass就是反向代理服務 ![image](https://hackmd.io/_uploads/SJZVHziz1g.png =90%x) 更新之後,可以==sudo apach2ctl configtest==測試 通過就會顯示==Syntax OK==,就重啟 ![image](https://hackmd.io/_uploads/BJktwzoMkl.png) 重啟之後反向代理就會生效,就可以連上(8080 port)了 ![image](https://hackmd.io/_uploads/B1Vg_GjMyx.png) ### 防火牆配置 先來設定防火牆,因為目前的配置應該是完全公開域名,沒有任何限制IP 但希望改成只有特定IP能連線 私有雲網路找到防火牆 ![image](https://hackmd.io/_uploads/BkD46zoG1x.png =50%x) 可以看到這邊已經有一些默認規則了, 要注意的是==目標==就是會套用到該規則的服務標籤,==0.0.0.0/0==就是允許所有外部IP連接 ![image](https://hackmd.io/_uploads/ryeA6zoG1e.png) 可以比對instance的設定 ![image](https://hackmd.io/_uploads/rJd8nzoGyg.png =80%x) :::info 這邊只希望對特定IP開放,又不想去修改默認防火牆,這邊就不套默認規則 自己給instance一個標籤,再針對這個標籤去新增防火牆,只針對想開放的對外做開放 ::: 把instance默認防火牆拔掉,自己新增一個標籤 ![image](https://hackmd.io/_uploads/r11b-mizJl.png =80%x) 拔掉之後可以連到domain試試,應該就會變成連不上了 1. 接下來先處理遠端FileZilla SSH(SFTP)連線到VM的防火牆 就開一個新的防火牆,流量==輸入==表示外部連入服務器 重點是目標標記設成針對<font style='color:red;'>剛剛創建的標籤</font> 來源設==要放行的連線IP==,port就==TCP:22==(ssh) ![image](https://hackmd.io/_uploads/HyjBrmozyl.png =60%x) 好了就建立,建完測試FileZilla應該就可以正常連上了 ![image](https://hackmd.io/_uploads/HkjtO7iGye.png) 2. 再來是做特定IP用HTTPS連線的防火牆 一樣新增防火牆,流量==輸入== 目標標記設成針對<font style='color:red;'>剛剛創建的標籤</font> 來源設==要放行的連線IP==,port就==TCP:443==(https) ![image](https://hackmd.io/_uploads/ByuFqmoMkg.png =60%x) 一樣好了建立,實際測試jenkins UI應該就可以連上了 ![image](https://hackmd.io/_uploads/H1iCsXjMkl.png) :::success 這邊總共加了兩個防火牆 1. 外部特定IP走HTTPS連線到VM 2. 外部特定IP走SSH連線到VM ![image](https://hackmd.io/_uploads/H1KdjQjGkx.png) ::: ### Jenkins防火牆番外篇(github webhook) 因為instance防火牆只針對特定IP開放,但jenkins要綁定Github webhook 所以==防火牆==要針對Github的請求IP做開放,==看hooks== [官方文件](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/about-githubs-ip-addresses) [官方IP文件](https://api.github.com/meta) ![image](https://hackmd.io/_uploads/SJLPq3GXyl.png) 加到防火牆,ipv4和ipv6都加 ![image](https://hackmd.io/_uploads/ry3hMpzmyg.png) 可以從Github的Recent Deliveries看觸發紀錄 ![image](https://hackmd.io/_uploads/HJknBafmJe.png) 也可以從GCP log確定,可以看到請求從剛剛新增放行的IP過來 ![image](https://hackmd.io/_uploads/SkuvmpzQ1e.png) 然後就一樣確保CI流程(綁webhook觸發),image可以成功打包更新到repository ![image](https://hackmd.io/_uploads/HJQoiyQXye.png) ![image](https://hackmd.io/_uploads/HyXyn1XXJx.png) 這樣Jenkins端的服務就全部完成了 :::success 全部總共加了三個防火牆 1. 外部特定IP走HTTPS連線到VM(包含Github webhook ipv4 IP) 2. 外部特定IP走SSH連線到VM 2. Github webhook IP走SSH連線到VM ::: 這是到目前為止進度 :::success √ 專案commit, push上Repository ::: :::success √ Repository自動觸發Jenkins CI,自動打包images上Dockerhub ::: :::danger × CI觸發CD,讓GKE自動更新部署 ::: :::danger × GKE部屬完成確定功能正常 ::: :::danger × 對外服務確定網路安全或流量問題 ::: ### GKE(Google Kubernetes Engine) 目前已經完成CI的部分,image上dockerhub了,建構k8s服務的yml先前[本地部屬練習](https://hackmd.io/@S1MNxjTORYSfAfivxMlEQw/r16KxTmkkx)也做完了 CD的部屬,在我的理解可以分為兩種方式: 1. 統一由Jenkins的pipeline來做操作,原理就和[本地部屬練習](https://hackmd.io/@S1MNxjTORYSfAfivxMlEQw/r16KxTmkkx)一樣,差別只在要確保jenkins內部可以調用操作GKE,畢竟服務是要運行在GKE上的,不是透過相同的本地k8s 2. CI和CD拆分,jenkins就只負責CI,把專案打包成images推到repository CD只要專心做好從repository拉images部屬的動作,剩下就是解決CI後的自動通知觸發 (可能用GitOps或是Google Cloud 的 Pub/Sub) 接下來做CD,就按順序來: 1. 先進到Google Kubernetes頁面,啟用GKE服務 ![image](https://hackmd.io/_uploads/SkYFTIB4kl.png =40%x) ![image](https://hackmd.io/_uploads/SkWIaLSV1g.png =60%x) 2. 先建立一個cluster,叢集位置可以選和instance服務一樣 ![image](https://hackmd.io/_uploads/By_7b-X7yg.png =60%x) 3. 就給個名稱,zone我是選和CI服務相同區域但不確定有沒有差別 剩下都不用改,就直接建立 ![image](https://hackmd.io/_uploads/BJ48NwSN1l.png) 4. 建構需要一點時間,點擊可以看到 ![image](https://hackmd.io/_uploads/B17q8DSEJe.png =70%x) 5. 建構完成之後可以開啟右上角==Cloud Shell終端== ![image](https://hackmd.io/_uploads/H1is6PrNkl.png) 6. 開啟後要點▼選正確專案(應該也是只有一個能選就是了) ![image](https://hackmd.io/_uploads/SkRqB_AE1x.png =70%x) 檢查專案的指令: ==gcloud config get-value project== ![image](https://hackmd.io/_uploads/HyWpjKR41e.png) 檢查叢集的指令: ==gcloud container clusters list== ![image](https://hackmd.io/_uploads/B17y2YRVJg.png) 7. 切換到專案後,要配置系統預設zone,方便後續指令可以省略相關指令 這邊我直接按照叢集的zone做配置 ==gcloud config set compute/zone asia-east1== 配置完檢查相關系統設定,確認有project和zone ==gcloud config list== ![image](https://hackmd.io/_uploads/rk_kxc0Eyl.png) 8. 接下來應該就是用kubectl去做後續操作,但會發現kubectl指令錯誤,類似這樣 ![image](https://hackmd.io/_uploads/r1Gb6F0EJx.png) 原因是叢集還沒做GKE驗證,做了才能連結kubectl和叢集 指令: ==gcloud container clusters get-credentials <叢集名>== 因為前面有配置系統默認project和zone所以這邊指令比較簡單 不然都要加上指定zone和project ![image](https://hackmd.io/_uploads/rJfIW9A4kx.png) 驗證連結後就可以使用Kubectl指令了 9. 再來就可以開始建構需要的服務了,先前已經有做好建構服務的yml文件,這邊就傳上終端運行 點擊終端右上角==三點圖示==,選上傳,然後就把做好的yml傳上去 ![image](https://hackmd.io/_uploads/SySbNcREye.png =60%x) ![image](https://hackmd.io/_uploads/HkEni9A4Je.png =40%x) ![image](https://hackmd.io/_uploads/ryUy2qREyg.png) 10. 然後就按照之前[本地測試部屬的流程](https://hackmd.io/@S1MNxjTORYSfAfivxMlEQw/r16KxTmkkx#%E5%AE%8C%E6%95%B4%E5%BB%BA%E6%A7%8B)去apply 本地測試已經排除大部分問題了,這邊就是剩下一些小問題做個紀錄 * ==redis==是用官方images沒什麼問題 * ==mssql==要注意密碼規範 * ==mssql==持久化的部分GCP不能用hostPath,要選一個靜態磁碟(我直接放在Jenkins服務器上) ![image](https://hackmd.io/_uploads/BJ5NDnANyx.png =60%x) * ==mssql==會遇到調用init腳本權限不足問題,要在yml針對執行權限加上配置 ![image](https://hackmd.io/_uploads/Syxsw3CNkl.png =50%x) * ==erp-base==沒什麼問題,要注意啟動log有沒有系統權限,初次啟動可能會抓不到,重啟即可 * ==erp-view==要配置外部連入,比較複雜,除了原先的yml, 要多做一個Ingress的yml用來轉發外部連線到前端port跟處理SSL憑證,這邊就按順序來 11. <b>Ingress Controller</b>: [關於Ingress說明,講蠻好的](https://ithelp.ithome.com.tw/articles/10272717?sc=pt),有兩種方式做 * Nginx Ingress搭配cert-manager做SSL證書,但就是要手動做配置 * GCE Ingress Controller整合GTS證書<font style='color:red;'>(既然都要做在GCP上了就選這個方法)</font> ▼最終版的erp-view.yml ```yaml= apiVersion: apps/v1 kind: Deployment metadata: name: erp-view labels: app: erp-view spec: replicas: 1 selector: matchLabels: app: erp-view template: metadata: labels: app: erp-view spec: imagePullSecrets: - name: dockerhub containers: - name: erp-view image: ryanimay840121/erp-view:latest imagePullPolicy: Always ports: - containerPort: 8082 --- apiVersion: v1 kind: Service metadata: name: erp-view spec: type: ClusterIP # 使用 ClusterIP,外部流量由ingress統一處理轉發 ports: - port: 80 # 暴露80端口,就不用另外帶port targetPort: 8082 selector: app: erp-view ``` ▼新增的ingress.yml ```yaml= # Google Managed Certificates管理證書 apiVersion: networking.gke.io/v1 kind: ManagedCertificate metadata: name: gts-managed-cert spec: domains: - erppp.duckdns.org --- # GCE Ingress Controller apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: erp-ingress annotations: kubernetes.io/ingress.class: "gce" # 這邊特別注意 networking.gke.io/managed-certificates: gts-managed-cert # 將 GTS 憑證綁定 spec: ingressClassName: gce #為了版本兼容,不寫也可以正常執行但kubectl指令都會顯示CLASS<none> # defaultBackend: # 可以設定預設,如果沒有匹配路由就轉發到這 # service: # name: erp-view # port: # number: 80 rules: - host: erppp.duckdns.org # 匹配路由轉發到這 http: paths: - path: / pathType: Prefix backend: service: name: erp-view port: number: 80 ``` <font style='color:red;'>特別注意`kubernetes.io/ingress.class` 雖然會提示K8s捨棄這種用法改用**ingressClassName**,但GKE不支持,所以還是要用這個寫法,這邊兩種都寫是為了兼容</font> ![image](https://hackmd.io/_uploads/S1yZcylBke.png) [官方文件說明](https://cloud.google.com/kubernetes-engine/docs/how-to/load-balance-ingress) <font style='color:red;'>然後不寫**defaultBackend**是因為希望只有匹配domain才能連入,等於也不能走外部IP連線</font> 做完一樣上傳到Cloud終端,然後apply運行 最終結果應該會長這樣 ![image](https://hackmd.io/_uploads/rkORn3yr1g.png) 這邊都是直接用cloud terminal指令去操作,GKE的UI介面看看就好 全部服務都是僅限集群內部調用 可以從介面確認Ingress創建狀況 ==這是有寫**defaultBackend**,可以看到有匹配規則是`IP/*`== ![image](https://hackmd.io/_uploads/ry0URkgBJe.png) ==這是沒寫**defaultBackend**,可以看到有匹配規則只有`domain/`== ![image](https://hackmd.io/_uploads/ByXFLvGH1l.png) 也可以==kubectl get ingress==確認有沒有新增成功 ![image](https://hackmd.io/_uploads/Hy0Upygr1g.png) 可以看到一組IP,就是對外IP,拿去<font style='color:red;'>做DNS解析</font>,DNS這邊一樣走==Duck DNS== 然後再來就只能等證書了,==kubectl describe managedcertificate gts-managed-cert==查結果 ![image](https://hackmd.io/_uploads/HJqTaJlrke.png) 這是通過之後的終端顯示 ![image](https://hackmd.io/_uploads/rJSIZegH1g.png) 然後看到網路服務>負載平衡,可以看到自動創建了一個LoadBalancer ![image](https://hackmd.io/_uploads/HJnnkKzH1g.png) --- ▼▼▼▼▼▼▼▼ [**<font style='color:red; font-size:30px;'>強烈警告</font>**](#強烈警告) ▲▲▲▲▲▲▲▲ --- 進去會發現**前後端服務都會分別有兩個** 前端原因是因為 ![image](https://hackmd.io/_uploads/HJ8VeKGH1g.png) 後端除了導向到ingress的服務,還有自動創建一個**default-http-backend** 原因是因為ingress沒有配置defaultBackend,LB會自動把沒匹配到的請求導向到一個用於處理「未找到匹配路徑」的預設HTTP錯誤處理器。 ![image](https://hackmd.io/_uploads/rJujxYGrJl.png) 證書的部分點進去可以看到相關配置和證書狀態 ![image](https://hackmd.io/_uploads/HJy2kxeHJx.png) --- ▼▼▼▼▼▼▼▼ [**<font style='color:red; font-size:30px;'>強烈警告</font>**](#強烈警告) ▲▲▲▲▲▲▲▲ --- 通過就可以連線了~~然後就可以測試看看功能和ClusterIP內部調用有沒有什麼問題 ![image](https://hackmd.io/_uploads/r1dYJelrkg.png) 然後就發現websocket連線爆炸...因為現在只有開ClusterIP,沒有對外的port了,和測試時不同 :::info Websocket問題原因很複雜,總結就是 1. 前端發起WS連線是使用SockJS,所以不支持`ws://`或`wss://` 2. 前端有配置GCE ingress controller和SSL證書,走HTTPS連線 因為這樣導致前端頁面只能用HTTPS開啟,連帶原先測試時可以用http進行websocket連線,現在不行,只能走`https://domain`,一定要經過ingress,剩下有兩種方法到後端: * 寫`https://domain/特定url`,<font style='color:red;'>由ingress轉發到後端</font>,不走原先的nginx * 一樣寫`https://domain`,一樣ingress到nginx,再<font style='color:red;'>由nginx轉發到後端</font> ![image](https://hackmd.io/_uploads/BJYw7D-SJe.png) ::: 這邊就統一都走nginx轉發的方式,這樣nginx也不用修改,也不用另外配置ingress,按順序來: 1. 改websocket連線的方式,直接走`https://domain` ![image](https://hackmd.io/_uploads/SJrlSLbryl.png) 2. 改完一樣重新打包image上dockerhub,再重新部屬應該就可以了 Ingress的Log可以看到,ws連線成功 ![image](https://hackmd.io/_uploads/Bk9BBvbH1x.png) --- ▼▼▼▼▼▼▼▼ [**<font style='color:red; font-size:30px;'>強烈警告</font>**](#強烈警告) ▲▲▲▲▲▲▲▲ --- 這是到目前為止進度 :::success √ 專案commit, push上Repository ::: :::success √ Repository自動觸發Jenkins CI,自動打包images上Dockerhub ::: :::danger × CI觸發CD,讓GKE自動更新部署 ::: :::success √ GKE部屬完成確定功能正常 ::: :::danger × 對外服務確定網路安全或流量問題 ::: 關於自動觸發CD,相對沒有這麼急迫,既然現在連線可以對外,就趕快處理防火牆吧 我不想收到莫名其妙的帳單 ## <font style='color:red;'>強烈警告</font> :::danger 先快速感受一下,來自這個世界滿滿的善意,各種kill各種攻擊,所以能擋就擋吧 強烈建議練習的話開自己需要連線的IP就好,其他全部都要擋掉,認真看完底下說明 ![image](https://hackmd.io/_uploads/rJDcHozH1x.png) ::: ### 關於網路安全性(防火牆/Cloud Armor) 既然現在服務可以讓外部連上,那就要開始擔心安全性和風險, 包含資料隱私或流量攻擊(DDos、Spam...)的防護 雖然目前是試用帳戶,沒開通完整帳戶 就算免費流量用完也不會被多扣,但還是要了解一下相關知識 然後如果要真的夠穩,不怕爆流量,最好還是用VPS,流量超過就終止服務(GCP只能發通知...) 本來就也只是為了練習,==重點還是使用完要記得關掉== 不然大部分雲服務都只能做到發送通知,但錢包還在繼續跳 [前幾天才看到的被攻擊經驗談](https://www.facebook.com/share/1TB5zrvi8j/) [求退費經驗談](https://medium.com/%E7%A8%8B%E5%BC%8F%E4%B9%BE%E8%B2%A8/gcp-%E9%80%80%E8%B2%BB-%E6%9C%8D%E5%8B%99%E5%BF%98%E8%A8%98%E9%97%9C%E9%96%89-a7db63e51186) ==!!這都還只是流量大的問題,重點是還會有像上面範例那種奇怪的指令請求!!== 關於請求進GCP的完整流程,上面簡單練習只有 做到==DNS -> (CDN) -> Load Balancer -> 服務== 其中Load Balancer自帶Cloud CDN(靜態資源緩存,可選),這邊就不多做配置 後續最好就是要加上連線到服務的==Cloud Armor==, 變成==DNS -> (CDN) -> Load Balancer -> Cloud Armor -> 服務==,可以<font style='color:red;'>稍微</font>做到限制防範流量 ![image](https://hackmd.io/_uploads/ByFQT8_GJl.png) 但要注意, <font style='color:red;'>有時候人家的請求量甚至沒有達到需要防範攻擊的標準,但問題是你的錢包先沒錢了</font> ![image](https://hackmd.io/_uploads/S1azMPOMJg.png) :::success 大致理解一下就好,這邊預計也只開特定IP訪問權限 ::: 先前配置Jenkins時已經順帶做好相關防火牆 接下來主要就是針對==全域的防火牆==和前端服務去設置 前端服務因為是走GKE LoadBalancer不是走ComputeEngine,所以要做限制要從==CloudArmor==,接下來會提到 需要做的有幾個部分: 1. 到==防火牆==,<font style='color:red;'>default-allow-ssh</font>的部分原先是對外所有IP都打開 ![image](https://hackmd.io/_uploads/BJDy1atz1x.png) 這邊改成只針對<font style='color:red;'>35.235.240.0/20</font>,就是只針對GCP開放用SSH連線 ![image](https://hackmd.io/_uploads/SJ65ahtMkg.png) :::info 做完這邊之後,所有的instance都只能透過GCP去做SSH連線,外部要連都要另外放行 ::: 2. 再來就是要做==Cloud Armor==,用意就是可以 限制經過<font style='color:red;'>Load Balancer層</font>(基於)往服務的IP(黑/白名單)或流量速率 點進頁面可以看到有一條預設政策 ![image](https://hackmd.io/_uploads/Bk7g4hWX1g.png) 3. 點擊就可以看到這個政策底下的規則和適用的服務,預設兩個,要簡單限制就是直接這邊做修改 ![image](https://hackmd.io/_uploads/SJR4ta-m1g.png) 4. 舉例,編輯節流 ![image](https://hackmd.io/_uploads/rkTnYpZ71x.png) 規則類型創建後不可更改,但是可以更新參數,也可以設定受限後返回結果 ![image](https://hackmd.io/_uploads/S1BWcaWQkg.png) 5. 儲存後,<font style='color:red;'>通常要過幾分鐘才會生效</font> 實際測試多次刷新頁面,就可以看到超過頻率限制被擋下 這樣就可以針對最基本的流量攻擊做個限制 ![image](https://hackmd.io/_uploads/BJGpNjfmJe.png) 6. 也可以對LB進來的請求做IP限制 (不然正常是不能針對LB做防火牆,一般防火牆是只針對instance) ==新開一個規則,僅限特定IP放行== :::danger **特別注意!! Cloud Armor的規則,不是一層一層篩選 只要匹配到相符的規則就只有放行(ACCEPT)或拒絕(DENY) 所以假設優先級0是放行所有IP,那優先級後面的所有規則都不會生效,因為已經被放行了 不管是限流還是拒絕所有IP都是一樣** ![image](https://hackmd.io/_uploads/Hkso8qGBJe.png) **我目前就只開放自己的IP,拒絕其他所有IP** ::: 7. 點擊目標可以看到目前有套用到這個限制規則的LB服務,把有開的服務都加一加吧 ![image](https://hackmd.io/_uploads/H1mld9zByg.png) 8. 到這裡就可以對陌生外部請求有基本的防範了,只要不是名單內IP,請求都會直接返回403 ![image](https://hackmd.io/_uploads/H1b7ghzHye.png) :::info 但說到底,網頁本身總不可能永遠都只有自己使用,總是要對外的 防範的基礎主要還是在服務本身,要想辦法自己避免各種注入攻擊或怪怪的操作 像我練習時一開始沒注意到對外服務會被亂帶指令的問題,瘋狂被攻擊了快一個月 也是因為程式本身有做好(大概?)所以沒遇到什麼問題 ::: --- <font style='color:red;'>**※**</font> 如果有遇到instance被健康檢查會失敗的原因,可能是因為沒有開放對應埠,這邊就新增一個防火牆針對健康檢查放行,標記就是剛剛新增的標記,來源設定==35.191.0.0/16==和==130.211.0.0/22==,這是GCP內部發起請求的IP,開放埠就是看健康檢查是要檢查哪裡,好了就儲存 [▼官方說明]() ![image](https://hackmd.io/_uploads/ryfxe_781x.png) ![image](https://hackmd.io/_uploads/SkibEsW7Je.png =80%x) 再回Load Balancer,就可以看到健康檢查通過了 ![image](https://hackmd.io/_uploads/rk3ySsWXkg.png) 到這邊關於防火牆和CloudArmor也差不多了,這是到目前為止進度 :::success √ 專案commit, push上Repository ::: :::success √ Repository自動觸發Jenkins CI,自動打包images上Dockerhub ::: :::danger × CI觸發CD,讓GKE自動更新部署 ::: :::success √ GKE部屬完成確定功能正常 ::: :::success √ 對外服務確定網路安全或流量問題 ::: 最後就剩下把CI觸發CD串起來了 ## 最後CI串CD 要讓CI/CD串接的部屬流程就會和上面手動部屬不太一樣 yml的部分不是手動放到環境中端執行,會改成和CI一樣放倉庫,要做大致有兩種方式: * ==直接用Jenkins的pipeline去操作GKE,就像測試本地部屬時一樣== * 綁GitOps工具(ArgoCD或FluxCD),把yml配置放Git,CI做完工作之後去自動更新配置檔(更新版號)推上倉庫,利用webhook的方式,觸發GKE拉配置檔來部屬,[[參考](https://blog.csdn.net/djuyqnixvh/article/details/135096432?ops_request_misc=%257B%2522request%255Fid%2522%253A%252250ce3352b88a9ebef536c1268ddb9286%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=50ce3352b88a9ebef536c1268ddb9286&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~hot_rank-6-135096432-null-null.142^v100^control&utm_term=jenkins%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90%E7%89%88%E6%9C%AC%E5%8F%B7&spm=1018.2226.3001.4187)] 這邊走Jenkins統一調用的方式,要在Jenkins內操作GKE需要 * GCP拿service account金鑰(要確定有權限) * GKE拿kubeconfig證書 * Jenkins安裝gcloud和kubectl用來操作 * Jenkins配置剛剛拿到的金鑰和證書 這樣就可以遠程調用了,就案順序來: 1. 先到服務帳戶,點帳戶的管理金鑰 ![image](https://hackmd.io/_uploads/Bys13FPHJe.png) ![image](https://hackmd.io/_uploads/Sk4E3FvB1l.png) 2. 建立新的金鑰,格式選json,應該就會下載一個文件到本地,這就是GCP的金鑰 ![image](https://hackmd.io/_uploads/HkSd2KDHJg.png) ![image](https://hackmd.io/_uploads/r1UK3KvHkl.png =60%x) 3. 金鑰處理好再來是GKE憑證,開啟終端進入要遠端調用的專案 輸入指令==gcloud container clusters get-gredentials 叢集名稱 --zone 叢集區域== 像這樣 ![image](https://hackmd.io/_uploads/By-cTKwrkx.png =40%x) ![image](https://hackmd.io/_uploads/H1K3TKwrJx.png) 這樣系統就會創建~/.kube/config證書 4. 但接下來就會遇到一個問題,就是要把證書下載到本地,方式有很多種,cloud terminal也有提供UI操作下載 ![image](https://hackmd.io/_uploads/HkYURYPHJe.png =50%x) 但打開會發現,找不到.kube資料夾,原因是因為.kube是因藏資料夾 這邊用最簡單的方式,直接指令複製到外層 ![image](https://hackmd.io/_uploads/SJrekqwHJl.png) 這樣就可以直接用UI找到config文件下載到本地了 5. 再來就是要把下載的本地文件配置給Jenkins,先進入Jenkins服務器UI ==資訊主頁== > ==管理Jenkins== > ==Credentials== > ==+Add Credentials== --- 做到一半因為一些因素擱置了一陣子,GCP的免費試用沒了QQ,剩下就單純文字記錄,整體用GCP+GKE做CI/CD都可以了,剩下就是一些細節的微調: 1. 關於版號,一開始偷懶都用<font style='color:red;'>:lastest</font>,但造成後續部屬k8s的問題,因為版號沒有變動導致更新不生效,本地練習k8s手動去跑yml更新就可以了,但用GKE時不確定是不是有什麼緩存問題,手動刪除在重新更新也是沒有生效,這部分也沒解決,但重點還是版號區隔,簡單做的話預計是用時間戳或是git