用 HashiCorp Vault 當 SSH CA:跟 authorized_keys 說再見
前言 當你管理的機器從 1 台變成 50 台之後,SSH 金鑰一定會讓你半夜驚醒: 「有個工程師離職了,他的 public key 到底散在哪幾台機器的 authorized_keys 裡?我要一台一台去刪嗎?」 「跳板機(bastion / control node)上放了一把萬能私鑰,只要那把鑰匙外洩,整個機房就全裸了。」 「我只想讓 CI 在『部署的那 5 分鐘』內能連進去,但傳統金鑰一放上去就是永久有效,根本沒有『到期』這回事。」 這些痛點的共通根源是:傳統 SSH 是「一把鑰匙配一把鎖」的信任模型——你得把每一把公鑰(public key)事先塞進每一台目標主機。機器一多,這件事就變成災難。 這篇文章要介紹一個更聰明的解法:把 HashiCorp Vault 當成一個「SSH 憑證中心(CA, Certificate Authority)」。 🔑 CA(Certificate Authority,憑證簽發中心)是什麼? 你可以把它想成「機場的證件核發櫃檯」。目標主機不再認得每一位旅客(每一把公鑰),它只認得「這張登機證是不是機場官方蓋章的」。只要 Vault 蓋...
在 k3s 上手把手打造 Prometheus + Grafana 監控系統
前言 當你把服務一個個丟進 Kubernetes 叢集之後,一定會遇到這些讓人半夜驚醒的時刻: 「使用者說網站很慢,但我怎麼知道是哪個節點的 CPU 爆了?」 「某個 Pod 一直重啟,到底是記憶體不夠,還是被 OOMKill 了?」 「我想做一張漂亮的儀表板給老闆看,但數據要從哪裡來?」 這些問題的答案,其實都指向同一套解法:Prometheus 負責『收集與儲存』數據,Grafana 負責『把數據畫成人看得懂的圖』。 這兩個工具幾乎是雲原生世界的監控黃金組合。 網路上大部分教學都叫你直接 helm install 一鍵安裝,但那樣你永遠不會知道「箱子裡面到底裝了什麼」。這篇文章反其道而行——我們用手寫 YAML manifests 的方式,在一個 k3s 輕量叢集上,一塊磚一塊磚地把整套監控系統疊起來。等你讀完,你不只會「用」,更會「懂」。 📦 本文所有範例都跑在 k3d 叢集(namespace 為 monitoring)。k3s 是輕量級的 Kubernetes 發行版,而 k3d 則是把 k3s 跑在 Docker 裡的工具,很適合本機學習。指令換成任何標準 K...
Pyproject.toml 手把手教學
前言 在過去,Python 的世界裡安裝套件、打包專案各有各的工具(setup.py、requirements.txt、Pipfile 等),生態系相當分散。pyproject.toml 是 Python 社群為了統一這些標準而誕生的格式,從 PEP 518 開始逐漸成為官方推薦的專案設定入口。它就像專案的「身分證」與「說明書」,集中描述專案名稱、依賴套件、建置方式等所有關鍵資訊。 核心結構 pyproject.toml 主要由以下兩個區塊組成: [build-system]:宣告要用哪個工具來打包專案(常見為 setuptools 或 hatchling)。 [project]:最核心的區塊,包含專案名稱、版本、作者,以及執行時所需的依賴套件(dependencies)。 建立 pyproject.toml Step 1:建立專案資料夾 以一個需要 requests 套件的爬蟲程式為例,建立以下目錄結構: 123my_project/├── pyproject.toml└── main.py Step 2:撰寫 pyproject.toml 在 pyproject.toml...
LeetCode - 刷題之旅的總結與心得
前言 這裡是我寫Leetcode總結核心概念的地方,不同的情境會使用到的武器不同,這裡我會描述在什麼樣的情境滿足下,適合的資料結構或是演算法。而這個演算法的核心概念是什麼,同時我也會紀錄一些我在刷題時的心得,以及刷題的時間,來慢慢看到成長與進步。 Leetcode時間紀錄 Hash Table 情境1: 快速找元素 通常使用 Hash 的關鍵在於要用 O(1) 的時間複雜度來查找元素,這樣就可以不用遍歷整個 list 從 O(n) 變成 O(1) 的時間內完成整個問題。 相關題目: leetcode-1-two-sum: 給定一個 target 數值,從 list 中找到兩個數字相加等於 target leetcode-12-integer-to-roman: 整數轉羅馬數字 leetcode-13-roman-to-integer: 羅馬數字轉整數 情境2: 比對無序的東西 如果要比對兩個無序的東西,像是兩個字串是否是 Anagram,這時候可以使用 Hash 來記錄每個字元出現的次數,然後比對兩個 Hash 是否相同。 相關題目: leetcode-49-gr...
Ansible - 自己寫 Ansible Module 與 Action Plugin 的比較
前言 最近嘗試在使用 Ansible 寫出針對 Inventory 的 Current State 狀態整理, Inventory 會記錄 kubernetes 中 cluster 所有的 nodes,但很多時候我們在開始執行 playbook 時才發現有些 node 的狀態不是健康的,所以希望寫出一個流程可以先做一些 precheck 捕捉 inventory 的狀態,這樣在執行 playbook 時就可以針對這些 unhealthy node 先排除,不會因為 node 的狀態不健康而導致 playbook 執行失敗。這種自己定義的邏輯我希望自己寫 .py 來實現,所以我在思考應該使用 module 還是 action plugin 來實現。這兩者的差異還是有點模糊,於是就寫下這篇文章來做個比較。 在開始之前,先來講一些 ansible 常見的術語: Modules: 透過 ansible 推送到各個節點的腳本 (像是那個 module 的 .py 檔案),我們稱為module。 而需要注意的事情是,這些 module 是在 ansible 的目標主機上執行的,你在 Pl...
Ansible - 如果對 Ansible Module 在 Pycharm 中進行 Debug
介紹 最近在開發 Ansible Module 時,想要在 Pycharm 中進行 Debug,不然每次去猜測每個變數裡面現在的值真的是太痛苦了…於是就嘗試使用 Pycharm 的 Debug 功能來進行除錯。 因為最近在開發 collection 的 module 所以本篇主要會以 collection 的 module debug 為主。 這篇文章會介紹如何在 Pycharm 中進行 Ansible Module 的 Debug,並且提供一些小技巧來讓你更有效率地進行除錯。 前置作業 先確保你已經安裝了 Pycharm 和 Ansible。 (這邊建議您使用 venv 或是 conda 來建立虛擬環境,這樣可以避免跟系統的 Python 衝突) 在 Pycharm 中建立一個新的專案,並且將 Ansible Module 的程式碼放到專案中。 12345678910111213141516171819202122# 可以使用 ansible-galaxy init 來建立 collection 的基本架構# 然後放在 collections 底下 .├── collect...
GitLab CI/CD Components 介紹與使用
前言 你有沒有曾經想過,在部署程式碼之前,希望先檢查一下有沒有錯誤,或者程式碼格式有沒有符合規範?這時候,CI/CD 就可以派上用場。CI(持續整合)可以幫你自動檢查程式碼品質,而 CD(持續交付/部署)則可以自動化部署流程,讓你的程式碼從開發到上線都更順暢。 但是,如果你有很多專案,而且每個專案都需要寫一模一樣或非常相似的 CI/CD 腳本,這就會變成一件既繁瑣又浪費時間的事情。你可能會想:「有沒有辦法只要簡單放入某些內容,就可以套用特定的腳本?」 其實,GitLab CI/CD 就提供了這樣的功能。透過重複利用與共享配置,你可以「讓多個專案共用同一套 CI/CD 流程」,不但節省時間,還能確保所有專案都遵循相同的規範。 例如,你可以在 .gitlab-ci.yml 套用別人是先撰寫好的腳本: 1234include: - component: $CI_SERVER_FQDN/my-org/security-components/secret-detection@1.0.0 inputs: stage: build 這樣,你的 stages 裡面就會載入 se...
手把手教你如何在本機透過 ssh 的方式連到 Docker 容器
前言 在開發 Docker 應用程式時,有時候我們會需要進入到容器內部進行操作,例如查看 log、修改設定檔等等。這時候,我們可以透過 ssh 的方式連接到容器,這樣就不用每次都透過 docker exec 進入容器,更加方便快捷。本章節將會介紹如何在本機透過 ssh 的方式連到 Docker 容器。 步驟 步驟 1:建立 Ubuntu 22.04 的 Docker 容器 我們要使用 host 模式來讓容器共享主機的網路。先拉取 Ubuntu 22.04 輕量版的 Docker image 1docker pull ubuntu:22.04 運行容器並使用 --network host,--network host 讓容器直接使用主機的網路環境,因此不需要手動進行 port mapping。因為 ubuntu:22.04 是一個最小化的 Docker image,預設沒有執行任何長時間運行的程序,所以當 docker run 完成初始化後,容器就會立即退出。所以這裡可以使用 tail -f /dev/null 這會讓容器內一直執行,確保它不會退出。 tail 是一個用來查看文件...
Bash Cheatsheet - 腳本的小抄大全
前言 最近寫了很多腳本,但是有太多參數會忘記了,這篇文章主要是整理了一些常用的 bash 腳本技巧,包括變數、邏輯判斷、迴圈、重導向、子殼層、Here Documents 等等。 1. Built-in Variables 1234567$0, $1, $2 # 第 n 個參數,即 argv[n]$# # 參數數量,即 argc$@ # 所有的參數$* # 所有的參數,但是會把所有參數當成一個字串 可以搭配 IFS (Internal Field Separator) 使用來分割$? # 上一個指令的回傳值$$ # 目前程式的 pid$! # 上一個在背景執行的程式的 pid 2. Bash Builins 數學運算,這兩個寫法等價。 12echo $((1+1))echo $[1+1] 變數,{} 可省略 123456name="Shannon"echo $nameecho ${name}# 字串長度echo ${#name} # 7 指令替換,兩個寫法等價 12echo $(whoami)echo `whoami` ...
養成撰寫 Bash 腳本的好習慣 - Bash Best Practice Guide
前言 因為最近為了撰寫 CI/CD Pipeline,因此有很大的時間都在寫 bash 腳本,寫著寫著就覺得應該來好好了解一些最佳實踐!因此整理出這篇教學。 在目前的世界裡面,Bash 繼承了 shell 的寶座,Bash 是可執行檔唯一允許的 shell 腳本語言。幾乎可以在所有 Linux 上找到,包括 Docker 鏡像。這是大多數後端運行的環境。因此,如果您需要編寫伺服器應用程式啟動、CI/CD 步驟或集成測試運行的腳本,Bash 隨時為您服務。 這篇主要參考了 google 所撰寫的 Shell Style Guide。然後還有網路常見的建議所組成,詳細可以參考 Reference。希望自己在寫腳本的時候可以養成良好的習慣… google 如果您正在編寫超過 100 行的腳本,或者使用不直覺的控制流邏輯,那麼現在應該用更結構化的語言重寫它。請記住,腳本會不斷增長。儘早重寫腳本,以避免以後更耗時的重寫。 Environment 所有錯誤消息都應轉到 STDERR 這使得更容易區分正常狀態和實際問題。 建議使用列印錯誤消息和其他狀態資訊的功能。 ps.我自己覺得還可以...