云原生小技巧 :OrbStack — 本地 K8s 環境的域名映射優化,開發者的新寵
今天,我要介紹的這個新伙伴: OrbStack[2],它的 Slogan 是: Say goodbye to slow, clunky containers and VMs。不過,說實話,我最喜歡的還是它的 Local domain names 的能力,因為它是零配置的。
Container domain names
OrbStack 對待容器的態度可謂是親(強)密(大)無間,它為每個容器賦予了一個獨一無二的域名。
舉個例子,假設我在本地啟動了一個名為 getting-started 的容器,并將容器內的 80 端口映射到了本地的 3000 端口
docker run -d -p 3000:80 --name getting-started docker/getting-started
下面是我本地容器運行的情況
圖片
在以往,我需要通過 localhost + port 的方式來訪問這個容器。
圖片
現在呢?只需通過 OrbStack 分配的域名,我就可以暢通無阻地訪問它,而且不需要指定端口,非常的絲滑。
圖片
mDNS
通過一系列的命令和檢查,我們可以看到 getting-started.orb.local 這個域名確實被解析到了容器的 IP 地址:192.168.215.3。
? ping getting-started.orb.local
PING getting-started.orb.local (192.168.215.3): 56 data bytes
64 bytes from 192.168.215.3: icmp_seq=0 ttl=63 time=1.714 ms
64 bytes from 192.168.215.3: icmp_seq=1 ttl=63 time=0.472 ms
64 bytes from 192.168.215.3: icmp_seq=2 ttl=63 time=1.204 ms
? docker inspect getting-started \
-f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
192.168.215.3
我本機的 /etc/hosts 文件內容也沒發生過變化,那么它是怎么做到的呢?我們先來看下系統的 DNS 配置信息。
? scutil --dns
DNS configuration
resolver #1
...
resolver #2
domain : local
options : mdns
timeout : 5
flags : Request A records
reach : 0x00000000 (Not Reachable)
order : 300000
resolver #3
...
在 scutil --dns 命令的輸出中,resolver #2 部分的 options 字段包含 mdns,這表示該解析器配置用于處理 .local 域名的多播 DNS 查詢。
mDNS 即多播 DNS(Multicast DNS[3])它是一種在本地網絡上無需傳統 DNS 服務器即可解析主機名的協議。這是 Bonjour(Apple 的實現)用來在本地網絡上發現服務和主機名的一種機制。
# 獲取本地 getting-started.orb.local 域名的地址
? dns-sd -G v4v6 getting-started.orb.local
DATE: ---Sat 04 Nov 2023---
9:52:21.350 ...STARTING...
Timestamp A/R Flags IF Hostname Address TTL
9:52:21.351 Add 40000003 18 getting-started.orb.local. FD07:B51A:CC66:0000:A617:DB5E:C0A8:D703%<0> 300
9:52:21.352 Add 40000002 18 getting-started.orb.local. 192.168.215.3 300
# 再查看特定主機的解析信息
? dns-sd -Q getting-started.orb.local
DATE: ---Sat 04 Nov 2023---
9:55:31.664 ...STARTING...
Timestamp A/R Flags IF Name Type Class Rdata
9:55:31.668 Add 40000002 18 getting-started.orb.local. Addr IN 192.168.215.3
Cool...有了這個能力就非常贊了,我可以輕松地將我的本地 Mysql 連接調整成這個樣子。
圖片
自定義域名
OrbStack 允許用戶自定義容器的域名,在啟動容器時通過標簽的方式方便的注入。
docker run --rm -l dev.orbstack.domains=foobar.local docker/getting-started
正如上面提到的 OrbStack 是通過 mDNS 來實現域名到 IP 的解析,所以它只對 .local 這個 TLD 有效,在做自定義域名的時候需要注意下。
圖片
Domain names
通過訪問 http://orb.local 我們可以看到所有正在運行的容器鏈接。
圖片
甚至可以在它的客戶端上查看容器列表,單擊信息圖標獲取。
圖片
OrbStack + Kind
接下來,我們利用 Local domain names 的能力,重新部署下自簽 TLS 證書的流程,看下和上次的分享有什么區別?
1. 獲取集群的域名
通過 UI,獲取到 Kind 集群的域名:local-control-plane.orb.local
圖片
2. 創建 K8s TLS Secret
然后,我們利用 mkcert[4] 創建了一個通配符證書
? mkcert '*.local-control-plane.orb.local'
Created a new certificate valid for the following names ??
- "*.local-control-plane.orb.local"
Reminder: X.509 wildcards only go one level deep, so this won't match a.b.local-control-plane.orb.local ??
The certificate is at "./_wildcard.local-control-plane.orb.local.pem" and the key at "./_wildcard.local-control-plane.orb.local-key.pem" ?
It will expire on 4 February 2026 ??
并將其作為 K8s TLS Secret 添加到我們的集群中。
kubectl create secret tls tls-secret \
--key=_wildcard.local-control-plane.orb.local-key.pem \
--cert=_wildcard.local-control-plane.orb.local.pem
3. 配置 K8s Ingress 使用 TLS Secret
# 創建一個 Nginx Deployment
kubectl create deployment nginx-deployment --image=nginx:1.25.3
# 暴露 Deployment 作為一個 Service
kubectl expose deployment nginx-deployment --port=80
最后,我們在 K8s Ingress 資源中引用了這個 TLS Secret,以啟用 HTTPS,對應的域名為:nginx.local-control-plane.orb.local。
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx
spec:
tls: # 以下 4 行是為了支持 TLS
- hosts: #
- nginx.local-control-plane.orb.local #
secretName: tls-secret #
rules:
- host: nginx.local-control-plane.orb.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-deployment
port:
number: 80
EOF
完成這些步驟后,我們就可以愉快地驗證一下了,中間我們不需要對 DNS 做任何的配置。??
圖片
HTTPS for containers
?? 小貼士:OrbStack 在其即將到來的穩定版中將默認啟用 HTTPS 支持,這意味著我們將不再需要手動創建、安裝或信任自簽名證書,為本地開發者帶來前所未有的便捷。
圖片
對于那些迫不及待想要體驗最新功能的小伙伴們,可以通過以下步驟來搶先體驗:進入設置,選擇更新通道為 Canary(faster),然后在 OrbStack 菜單中選擇檢查更新。
調整更新通道
檢查更新
升級完后,容器里已有的服務就可以直接通過 https://getting-started.orb.local/ 訪問了。
圖片
OrbStack 的原生 K8s 支持
事實上 OrbStack 提供了一個輕量級的單節點 K8s 集群,它對于開發環境來說是優化的。
圖片
在本地開發,如果沒有 multi-node clusters 需求的話,我們可以不用 Kind 自建集群,直接用它就好。
除了以上提到的域名能力之外,我們還可以通過 Pod 的 IP 又或者 Service 的 IP 直接訪問,這對于我們平時開發或者測試來說非常的方便,不需要再做 port-forward 了。
大家可以直接看 Using Kubernetes[5],這里不再贅述。
寫在后面
從傳統的 DNS 解決方案,到現代的 OrbStack,我們見證了本地開發環境的巨大變革。通過 OrbStack,我們不僅提升了工作效率,還享受到了前所未有的便捷。無論是容器的即時訪問,還是 Kind 集群的無縫連接,OrbStack 都展現了其強大的能力。
在云原生的世界里,每一次技術的進步都是為了讓開發者的生活變得更加簡單。而今天,我們又向這個目標邁進了一大步。我希望你們能夠嘗試 OrbStack,并且享受它帶來的便利。
在下一篇文章中,我將探索更多云原生技術的奧秘。敬請期待,我們下次見!??
參考資料
[1]Dnsmasq: https://en.wikipedia.org/wiki/Dnsmasq
[2]OrbStack: https://orbstack.dev/
[3]Multicast DNS: https://en.wikipedia.org/wiki/Multicast_DNS
[4]mkcert: https://github.com/FiloSottile/mkcert
[5]Using Kubernetes: https://docs.orbstack.dev/kubernetes/