<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Peter Lee - Blog</title><link>https://blog.peterlee.app/zh-hant/</link><description>Recent content on Peter Lee - Blog</description><generator>Hugo</generator><language>zh-hant</language><managingEditor>peterlee0127@gmail.com (peterlee)</managingEditor><webMaster>peterlee0127@gmail.com (peterlee)</webMaster><lastBuildDate>Fri, 28 Aug 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://blog.peterlee.app/zh-hant/index.xml" rel="self" type="application/rss+xml"/><item><title>做一個只能看、不能動的 Kubernetes MCP tool</title><link>https://blog.peterlee.app/cloud/read-only-mcp-for-kubernetes-triage/</link><pubDate>Fri, 28 Aug 2026 00:00:00 +0800</pubDate><author>peterlee0127@gmail.com (peterlee)</author><guid>https://blog.peterlee.app/cloud/read-only-mcp-for-kubernetes-triage/</guid><description>&lt;p>我最近在 &lt;code>k8s_infra/plugins/infra-observer&lt;/code> 做了一個給 AI 用的 MCP tool。它不是遠端終端機的包裝，也不是把 &lt;code>kubectl&lt;/code> 直接交給模型；它只做一件事：在不讓 AI 動到環境的前提下，給它排查問題需要的資訊。&lt;/p>
&lt;p>起點其實很單純。讓 AI SSH 到主機後，若工具可以傳任意指令，等於把太多決定權交了出去。就算名義上說是 read-only，也可能讀到 Secret、進 Pod 執行命令，或被 log 裡的內容引導去跑不該跑的東西。我想要的是讓它看得到 Pod 是否不健康、rollout 卡在哪裡、Argo CD 有沒有同步、Service 有沒有 endpoint，以及服務在 OTel 裡有沒有錯誤；除此之外的能力就不要有。&lt;/p></description></item><item><title>讓 AI 讀懂我的 Kubernetes 基礎設施</title><link>https://blog.peterlee.app/cloud/ai-gitops-kubernetes-infrastructure/</link><pubDate>Fri, 28 Aug 2026 00:00:00 +0800</pubDate><author>peterlee0127@gmail.com (peterlee)</author><guid>https://blog.peterlee.app/cloud/ai-gitops-kubernetes-infrastructure/</guid><description>&lt;p>剛開始把 AI 放進 Kubernetes 的工作流程時，我最常遇到的問題不是它不會寫 YAML，而是它太容易只看眼前那一份 YAML。它可以很快補出一個 Deployment，卻不一定知道這個服務要不要經過 Argo CD、它的 Secret 從哪裡來，或是公開入口還少了叢集外的設定。&lt;/p>
&lt;p>後來我沒有再把需求和幾段設定直接貼進對話，而是讓 AI 從 GitOps repository 開始讀。那個 repository 本來就是我維護叢集的地方；裡面的目錄、README 和設定檔，剛好也能讓 AI 補上我平常放在腦中的脈絡。&lt;/p>
&lt;h2 id="我先給-ai-一張地圖">我先給 AI 一張地圖&lt;/h2>
&lt;p>我的 repository 不追求複雜的抽象，重點是讓人能從入口一路找到部署內容：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">gitops/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── bootstrap/ # 初始安裝時才需要的東西
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── clusters/apps/ # Argo CD Applications
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── apps/ # 各服務的 manifests 與 values
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── terraform/ # 叢集外的雲端資源
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">└── docs/ # 架構與操作筆記
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>有了這張地圖，「新增一個服務」就不再只是多一個 Deployment。AI 可以先找出這個服務會碰到的 Application、Kustomization、values、Secret reference 和 Terraform，而不是猜一份看起來合理、實際上接不起來的設定。&lt;/p></description></item><item><title>以 GitOps 管理的 values 在 Kubernetes 執行 Airflow</title><link>https://blog.peterlee.app/cloud/airflow-on-kubernetes-with-gitops-values/</link><pubDate>Mon, 24 Aug 2026 00:00:00 +0800</pubDate><author>peterlee0127@gmail.com (peterlee)</author><guid>https://blog.peterlee.app/cloud/airflow-on-kubernetes-with-gitops-values/</guid><description>&lt;p>我的家用 Kubernetes 叢集將 Apache Airflow 作為以 GitOps 管理的平台服務。它負責編排排程資料工作與維運流程；Kubernetes 則為 scheduler、API server、Celery worker、triggerer 與支援服務提供隔離的執行環境。&lt;/p>
&lt;p>部署刻意拆成兩部分：可公開審查的 Helm values 放在 Git，憑證與產生的金鑰則放在 Vault。Argo CD 負責依正確順序同步這兩部分。&lt;/p>
&lt;h2 id="部署結構">部署結構&lt;/h2>
&lt;p>這個 repository 採用 app-of-apps 模式。根 Argo CD Application 從 &lt;code>clusters/apps/&lt;/code> 同步子 Application；Airflow 的資源則分成以下幾個部分：&lt;/p></description></item><item><title>以 cloudflared 取代 Caddy：不開放 80、443 連接埠也能公開 Kubernetes</title><link>https://blog.peterlee.app/cloud/cloudflare-tunnel-kubernetes-without-open-ports/</link><pubDate>Sat, 22 Aug 2026 00:00:00 +0800</pubDate><author>peterlee0127@gmail.com (peterlee)</author><guid>https://blog.peterlee.app/cloud/cloudflare-tunnel-kubernetes-without-open-ports/</guid><description>&lt;p>我把原本由 Caddy 接收公開流量的架構，改成在 Kubernetes 內執行 &lt;code>cloudflared&lt;/code>。Cloudflare Tunnel 由叢集主動連線至 Cloudflare，因此家用網路不再需要透過 router 將 80、443 連接埠轉送至來源端。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">瀏覽器 → Cloudflare Access → Cloudflare edge
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> → 出站 Cloudflare Tunnel → cloudflared Pod
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> → Kubernetes ClusterIP Service → application Pod
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="新的安全邊界">新的安全邊界&lt;/h2>
&lt;p>舊路徑是「網際網路入站 → router 80/443 → Caddy → Kubernetes」；新路徑則由 &lt;code>cloudflared&lt;/code> 從叢集主動連線至 Cloudflare。這裡的「不開放連接埠」是指不開放入站 HTTP／HTTPS；connector 仍須連線至 Cloudflare，Tunnel 通常使用 TCP 或 UDP 7844。&lt;/p></description></item><item><title>從本機與遠端 Git 歷史移除誤提交的密鑰</title><link>https://blog.peterlee.app/cloud/remove-committed-secret-from-git-history/</link><pubDate>Thu, 30 Jul 2026 00:00:00 +0800</pubDate><author>peterlee0127@gmail.com (peterlee)</author><guid>https://blog.peterlee.app/cloud/remove-committed-secret-from-git-history/</guid><description>&lt;p>誤把 token、密碼、私鑰或憑證提交到 Git 時，&lt;code>git rm&lt;/code> 只會從最新版本移除檔案；舊 commit、branch、tag、fork、CI log 和既有 clone 仍可能保留內容。處理時，應直接假設憑證已經外洩。&lt;/p>
&lt;h2 id="1-先控制事件">1. 先控制事件&lt;/h2>
&lt;p>立即撤銷或輪替機密值，檢查服務供應商的存取與稽核 log；必要時暫時限制 repository 存取，並請協作者停止 push。找出所有曾包含該值的路徑與檔名；如果內容可能曾被複製到其他檔案，也要一併納入清理範圍。&lt;/p>
&lt;h2 id="2-量測外洩範圍再改寫全新-clone">2. 量測外洩範圍，再改寫全新 clone&lt;/h2>
&lt;p>使用 &lt;code>git log --all -- &amp;lt;path&amp;gt;&lt;/code>、&lt;code>git rev-list --all&lt;/code> 與內容搜尋逐一檢查每個 ref。請在乾淨的 clone 中操作，使用 &lt;code>git filter-repo&lt;/code> 移除路徑或替換內容；不要直接在唯一的工作目錄中改寫歷史。&lt;/p></description></item><item><title>用 AI Coding 打造原生 macOS 加密 DNS App：DNS Security Pro</title><link>https://blog.peterlee.app/ios/dns-security-pro-native-macos-ai-coding/</link><pubDate>Sat, 18 Jul 2026 00:00:00 +0800</pubDate><author>peterlee0127@gmail.com (peterlee)</author><guid>https://blog.peterlee.app/ios/dns-security-pro-native-macos-ai-coding/</guid><description>&lt;p>DNS Security Pro for macOS 是一個原生 SwiftUI 應用程式，用於管理系統層級的 DNS over HTTPS（DoH）與 DNS over TLS（DoT）。它的目標不是把所有流量導往 VPN，而是在可控、可理解的前提下保護 DNS 查詢。&lt;/p>
&lt;h2 id="為什麼使用加密-dns">為什麼使用加密 DNS&lt;/h2>
&lt;p>HTTPS 並不代表 DNS 查詢一定經過加密。未加密的 DNS 可能暴露你查詢的網域，也可能遭到竄改。DoH 與 DoT 會將 DNS 查詢加密後傳送至指定的 resolver；但它們並非完整的匿名工具，使用前仍應了解並信任所選的服務供應商。&lt;/p></description></item><item><title>在 GitOps 使用 Mozilla SOPS 加密 Kubernetes Secret</title><link>https://blog.peterlee.app/cloud/gitops-sops-encrypted-secrets/</link><pubDate>Tue, 09 Jun 2026 00:00:00 +0800</pubDate><author>peterlee0127@gmail.com (peterlee)</author><guid>https://blog.peterlee.app/cloud/gitops-sops-encrypted-secrets/</guid><description>&lt;p>SOPS 讓 Kubernetes Secret 的值以加密形式儲存在 Git，再由 GitOps controller 在同步時解密並套用 manifest。它適合小型叢集、機密資料不多而不值得維運 Vault 的環境、建立 Vault／External Secrets 前所需的 bootstrap 機密值，以及希望與 manifest 一併審閱版本的設定。&lt;/p>
&lt;h2 id="安全模型">安全模型&lt;/h2>
&lt;p>Git 中可見的是 metadata、Secret key 與加密後的值；私鑰不應進入 Git。只有持有解密金鑰的人或 controller 才能還原內容，因此仍需限制 repository 存取、保護 GitOps controller、輪替金鑰，並避免將解密結果輸出至 CI 或 controller 日誌。&lt;/p></description></item><item><title>使用 waypoint proxy 執行 Istio ambient mode</title><link>https://blog.peterlee.app/cloud/istio-ambient-waypoint-proxies/</link><pubDate>Wed, 03 Jun 2026 00:00:00 +0800</pubDate><author>peterlee0127@gmail.com (peterlee)</author><guid>https://blog.peterlee.app/cloud/istio-ambient-waypoint-proxies/</guid><description>&lt;p>Istio ambient mode 將 L4 與 L7 的責任拆開：ztunnel 提供透明的 L4 安全防護與遙測，只有需要 HTTP 路由、授權或 L7 policy 的服務才使用 waypoint proxy。如此一來，不必在每個 Pod 中注入 sidecar。&lt;/p>
&lt;h2 id="gitops-同步順序">GitOps 同步順序&lt;/h2>
&lt;p>先安裝 Istio CRD 與 ambient 控制平面，再備妥 ztunnel 所需的節點條件，接著標記要納入 ambient 的 namespace 或 workload。最後建立 waypoint、AuthorizationPolicy、HTTPRoute 與應用程式。被依賴的資源必須先於 workload 建立。&lt;/p></description></item><item><title>用 Argo CD 管理我的家用 Kubernetes 叢集</title><link>https://blog.peterlee.app/cloud/argocd-gitops-for-home-kubernetes/</link><pubDate>Tue, 02 Jun 2026 00:00:00 +0800</pubDate><author>peterlee0127@gmail.com (peterlee)</author><guid>https://blog.peterlee.app/cloud/argocd-gitops-for-home-kubernetes/</guid><description>&lt;p>我以 GitOps 管理家用 Kubernetes 叢集時，核心原則是：將 Kubernetes manifests 放在 Git、由 Argo CD 持續協調期望狀態、真正的機密值不進 Git，並讓新的 RKE 叢集能透過一份精簡的啟動清單復原。&lt;/p>
&lt;h2 id="gitops-流程">GitOps 流程&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">Git repository → Argo CD → Kubernetes API
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Vault → External Secrets Operator → Kubernetes Secret → application Pod
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Argo CD 只處理宣告式設定；Vault 儲存真正的機密值，External Secrets Operator 將其同步為一般的 Kubernetes Secret，再由應用程式以既有方式引用。&lt;/p></description></item><item><title>在 Kubernetes 使用 Vault 與 External Secrets</title><link>https://blog.peterlee.app/cloud/vault-kubernetes-external-secrets/</link><pubDate>Tue, 02 Jun 2026 00:00:00 +0800</pubDate><author>peterlee0127@gmail.com (peterlee)</author><guid>https://blog.peterlee.app/cloud/vault-kubernetes-external-secrets/</guid><description>&lt;p>我的機密資料流程是：Vault 保存真正的值、External Secrets Operator 讀取 Vault、Kubernetes 取得一般的 Secret、Deployment 照常引用，而 Git 只保留 manifests 與非機密設定。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">Vault KV → External Secrets Operator → Kubernetes Secret → Pod
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="安裝-operator-並保存資料">安裝 Operator 並保存資料&lt;/h2>
&lt;p>先安裝 External Secrets Operator 的 CRD 與控制器。接著將機密資料寫入 Vault KV v2，例如把 &lt;code>.env&lt;/code> 內容存放在 &lt;code>secret/example-api/env-file&lt;/code> 的 &lt;code>dotenv&lt;/code> property。不要把 token、密碼或未加密的 &lt;code>.env&lt;/code> 值放進 repository。&lt;/p></description></item><item><title>使用 Istio Gateway API 對外公開 Kubernetes 服務</title><link>https://blog.peterlee.app/cloud/istio-gateway-api-ingress/</link><pubDate>Tue, 02 Jun 2026 00:00:00 +0800</pubDate><author>peterlee0127@gmail.com (peterlee)</author><guid>https://blog.peterlee.app/cloud/istio-gateway-api-ingress/</guid><description>&lt;p>我以 Istio 的 Gateway API 將外部網域導向 Kubernetes 服務。這讓入口、主機名稱與路由規則成為可審核的 Kubernetes 資源，並可與 ambient mesh 的服務網路模型共存。&lt;/p>
&lt;h2 id="為什麼選-gateway-api">為什麼選 Gateway API&lt;/h2>
&lt;p>Gateway API 將責任切分為四種資源：Istio 提供的 &lt;code>GatewayClass&lt;/code>、共用入口的 &lt;code>Gateway&lt;/code>、負責比對主機與路徑的 &lt;code>HTTPRoute&lt;/code>，以及允許跨 namespace 引用後端的 &lt;code>ReferenceGrant&lt;/code>。相較於把所有設定塞進單一 Ingress 物件，這樣的分工更明確。&lt;/p>
&lt;h2 id="以-nodeport-公開-gateway-service">以 NodePort 公開 Gateway Service&lt;/h2>
&lt;p>在家用叢集裡，外部反向代理會將流量轉送到 Istio Gateway 的 NodePort。Gateway listener 定義通訊協定、連接埠與主機名稱；Service 則只開放實際需要的連接埠。不要直接以 NodePort 對外公開後端應用程式。&lt;/p></description></item><item><title>為 GitOps 啟動新的 RKE 叢集</title><link>https://blog.peterlee.app/cloud/bootstrap-rke-cluster-for-gitops/</link><pubDate>Tue, 02 Jun 2026 00:00:00 +0800</pubDate><author>peterlee0127@gmail.com (peterlee)</author><guid>https://blog.peterlee.app/cloud/bootstrap-rke-cluster-for-gitops/</guid><description>&lt;p>這份清單列出 GitOps 接手前必須人工完成的最小工作。Argo CD 很適合持續協調叢集內的宣告式資源，但不該用來建立自己的信任根、修復失聯叢集，或把真正的機密值寫入 Git。&lt;/p>
&lt;h2 id="之後交給-argo-cd-管理的項目">之後交給 Argo CD 管理的項目&lt;/h2>
&lt;p>叢集準備完成後，Argo CD 可管理 namespace、依賴 CRD 的應用程式、External Secrets、Longhorn、Istio、Gateway API 與各項工作負載。依賴關係應以同步波次（sync waves）或明確的 Application 順序表示。&lt;/p>
&lt;h2 id="人工前置條件">人工前置條件&lt;/h2>
&lt;p>在第一次同步前，確認下列事項：&lt;/p>
&lt;ol>
&lt;li>可用 &lt;code>kubectl&lt;/code> 連線 RKE 叢集。&lt;/li>
&lt;li>Argo CD 已安裝於 &lt;code>argocd&lt;/code> namespace。&lt;/li>
&lt;li>Argo CD 已取得讀取私有 Git repository 所需的憑證。&lt;/li>
&lt;li>叢集 Pod 可連線 Vault。&lt;/li>
&lt;li>此叢集的 Vault Kubernetes auth、policy 與 role 已建立。&lt;/li>
&lt;li>External Secrets 所需的資料已存在 Vault KV v2。&lt;/li>
&lt;li>Longhorn 的節點與儲存需求已準備好。&lt;/li>
&lt;li>Istio ambient 的節點前置條件已完成。&lt;/li>
&lt;li>公開服務需要的 Ingress 或 Gateway 路徑已存在。&lt;/li>
&lt;/ol>
&lt;h2 id="取得-git-與-vault-的信任">取得 Git 與 Vault 的信任&lt;/h2>
&lt;p>將 repository 的 deploy key 或 token 建成 Argo CD repository Secret，並透過 SSH 連線測試 repository 存取。接著為 Kubernetes 建立 Vault 驗證設定、token reviewer JWT、CA 與 API server 位址；policy 的 KV v2 路徑必須與實際掛載點相符，例如 &lt;code>secret/data/...&lt;/code>。&lt;/p></description></item><item><title>為 Kubernetes 應用程式建立 OpenTelemetry 堆疊</title><link>https://blog.peterlee.app/cloud/opentelemetry-stack-for-kubernetes-apps/</link><pubDate>Tue, 02 Jun 2026 00:00:00 +0800</pubDate><author>peterlee0127@gmail.com (peterlee)</author><guid>https://blog.peterlee.app/cloud/opentelemetry-stack-for-kubernetes-apps/</guid><description>&lt;p>這套可觀測性後端以 Docker Compose 執行，集中接收 Kubernetes 應用程式送出的指標、日誌與追蹤資料。核心元件包括 OpenTelemetry Collector、Prometheus、Loki、Tempo 與 Grafana；各元件分工處理資料，Grafana 則提供統一的查詢入口。&lt;/p>
&lt;h2 id="服務與-compose-架構">服務與 Compose 架構&lt;/h2>
&lt;p>Collector 對應用程式提供 OTLP gRPC／HTTP receiver，並依訊號類型將資料送往各後端。Prometheus 儲存指標，Loki 儲存日誌，Tempo 儲存追蹤資料，Grafana 則連接這三套系統。所有持久化資料都應存放在具有備份策略的 volume 中。&lt;/p>
&lt;h2 id="collector-receivers-與-resource-attributes">Collector receivers 與 resource attributes&lt;/h2>
&lt;p>應用程式應透過 OTLP 將遙測資料傳送至 Collector，不要各自直接連接後端。統一補上 &lt;code>service.name&lt;/code>、&lt;code>service.namespace&lt;/code>、&lt;code>deployment.environment&lt;/code>、&lt;code>k8s.namespace.name&lt;/code> 等資源屬性後，才能在 Grafana 中把同一服務的指標、日誌與追蹤資料關聯起來。&lt;/p></description></item><item><title>部署 Rancher Kubernetes Engine</title><link>https://blog.peterlee.app/cloud/deploy-rancher-kubernetes/</link><pubDate>Sun, 10 Oct 2021 00:00:00 +0800</pubDate><author>peterlee0127@gmail.com (peterlee)</author><guid>https://blog.peterlee.app/cloud/deploy-rancher-kubernetes/</guid><description>&lt;h3 id="為什麼用-rancher-部署-kubernetes-叢集">為什麼用 Rancher 部署 Kubernetes 叢集？&lt;/h3>
&lt;p>對我的環境而言，RKE 比 kubeadm 更方便集中管理 kube-dns、CoreDNS、Flannel 與 StorageClass 等設定。我的機器混用 Ubuntu 20.04.3 LTS 與 CentOS 7，升級與差異處理較複雜；RKE 將 Kubernetes 服務以 Docker 執行，能降低這類環境差異。它也會透過 SSH 設定各節點，因此不必手動在控制平面逐一加入 worker。&lt;/p>
&lt;p>以下是精簡的 RKE &lt;code>cluster.yml&lt;/code> 範例：&lt;/p></description></item><item><title>iOS／macOS 的 DNS Security</title><link>https://blog.peterlee.app/ios/dns_security_ios/</link><pubDate>Fri, 20 Nov 2020 00:00:00 +0800</pubDate><author>peterlee0127@gmail.com (peterlee)</author><guid>https://blog.peterlee.app/ios/dns_security_ios/</guid><description>&lt;h1 id="dns-security">DNS Security&lt;/h1>
&lt;div style="text-align:center">&lt;a href='https://apps.apple.com/us/app/id1533938029'>&lt;img src="https://blog.peterlee.app/assets/images/posts/2020-11-20-dns-security-ios/mac-logo.png" width='200px' style='alignment:center'>&lt;/a>&lt;/div>
&lt;h4 id="最早在-ios-14-使用加密-dns-profile且不必設定-vpn-的應用程式之一">最早在 iOS 14 使用加密 DNS profile、且不必設定 VPN 的應用程式之一。&lt;/h4>
&lt;p>保護 DNS 查詢，不必把所有網路流量都改經 VPN。&lt;/p>
&lt;h3 id="什麼是-dns-over-https-與-dns-over-tls">什麼是 DNS over HTTPS 與 DNS over TLS？&lt;/h3>
&lt;p>即使造訪的網站使用 HTTPS，DNS 查詢仍可能經由未加密的連線送出。監看網路的人可能看見你查詢哪些網域；攻擊者也可能竄改 DNS 回應，將訪客導向釣魚、惡意軟體或監控網站。你的 ISP、路由器或網路服務商也可能追蹤這些查詢。DNS over HTTPS 與 DNS over TLS 可協助保護 DNS 查詢，降低這類暴露風險。&lt;/p></description></item><item><title>使用 GitHub Pages 託管網站</title><link>https://blog.peterlee.app/web/host-your-website-on-github-pages/</link><pubDate>Thu, 24 Oct 2019 00:00:00 +0800</pubDate><author>peterlee0127@gmail.com (peterlee)</author><guid>https://blog.peterlee.app/web/host-your-website-on-github-pages/</guid><description>&lt;p>使用 GitHub Pages 託管你的網站。&lt;/p>
&lt;h3 id="前置條件">前置條件&lt;/h3>
&lt;ol>
&lt;li>向 Namecheap、GoDaddy 等註冊商購買的網域名稱。&lt;/li>
&lt;li>GitHub 帳號。&lt;/li>
&lt;li>用於管理 DNS 的 Cloudflare。&lt;/li>
&lt;/ol>
&lt;h2 id="步驟">步驟&lt;/h2>
&lt;p>在 Git 專案中建立 &lt;code>CNAME&lt;/code> 檔案：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">resume.peterlee.app
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;p>&lt;img src="https://blog.peterlee.app/assets/images/posts/2019-10-24-host-your-website-on-github-pages/domain-dns.jpg" alt="網域管理服務的 DNS 設定">&lt;/p>
&lt;p>&lt;img src="https://blog.peterlee.app/assets/images/posts/2019-10-24-host-your-website-on-github-pages/cloudflare-dns.jpg" alt="Cloudflare DNS 設定">&lt;/p></description></item><item><title>為 Kubernetes 部署 NFS StorageClass</title><link>https://blog.peterlee.app/cloud/deploy-storage-class-for-kubernetes/</link><pubDate>Tue, 27 Aug 2019 00:00:00 +0800</pubDate><author>peterlee0127@gmail.com (peterlee)</author><guid>https://blog.peterlee.app/cloud/deploy-storage-class-for-kubernetes/</guid><description>&lt;h4 id="相關文章使用-kubeadm-建立-kubernetes-叢集">相關文章：&lt;a href="https://blog.peterlee.app/cloud/start_a_kubernetes_with_kubeadm/">使用 kubeadm 建立 Kubernetes 叢集&lt;/a>&lt;/h4>
&lt;p>NFS client provisioner 能根據 PersistentVolumeClaim 動態建立目錄，讓私有 Kubernetes 叢集取得簡單且共享的持久化儲存。&lt;/p>
&lt;h3 id="在-centos-安裝-nfs-伺服器">在 CentOS 安裝 NFS 伺服器&lt;/h3>
&lt;p>安裝 &lt;code>nfs-utils&lt;/code>，建立要分享的目錄，並在 &lt;code>/etc/exports&lt;/code> 只授權叢集網段讀寫。例如：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">/opt/nfs 192.168.2.0/24(rw,sync,no_root_squash)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>啟用 &lt;code>nfs-server&lt;/code> 後，以 &lt;code>showmount -e &amp;lt;nfs-server&amp;gt;&lt;/code> 或在其他主機掛載測試，確認分享路徑可用。實際環境應採最小網段權限，並評估 &lt;code>no_root_squash&lt;/code> 是否符合安全需求。&lt;/p></description></item><item><title>使用 kubeadm 建立 Kubernetes 叢集</title><link>https://blog.peterlee.app/cloud/start_a_kubernetes_with_kubeadm/</link><pubDate>Sun, 25 Aug 2019 00:00:00 +0800</pubDate><author>peterlee0127@gmail.com (peterlee)</author><guid>https://blog.peterlee.app/cloud/start_a_kubernetes_with_kubeadm/</guid><description>&lt;p>這份筆記記錄我用 &lt;code>kubeadm&lt;/code> 建立私有 Kubernetes 叢集的流程。範例採用 VirtualBox 與 Vagrant 建立多個 Linux 虛擬機，再由一個控制平面節點初始化叢集並加入工作節點。&lt;/p>
&lt;h2 id="硬體與環境">硬體與環境&lt;/h2>
&lt;p>多節點測試環境至少需要足以同時執行多台 VM 的 CPU、32 GB RAM 與 SSD；若要跑 GPU 工作負載，另需 NVIDIA GPU。主機端使用 VirtualBox、Vagrant，節點可使用 Ubuntu、Debian 或 CentOS。&lt;/p>
&lt;h2 id="準備每個節點">準備每個節點&lt;/h2>
&lt;p>每台節點都必須完成相同基礎設定：&lt;/p></description></item></channel></rss>