摘要:有沒有方法繞開CCE的限制,自由的調用K8s的API呢?有還便宜,2.4元/集群/天。
申明:所有的一切都是為了使得華為雲可以更好,而不是為了diss它。
通過華為雲購買多個K8s集群,又想使用原生K8s接口調用這些集群,有什么好的方式?目前使用CCE服務的API依然是最好的選擇。但同時CCE的API又存在諸多限制,如API限流,部分原生接口未開放等。那有沒有方法繞開CCE的限制,自由的調用K8s的API呢?本文就是給出一個繞開“防線”的思路。歡迎交流指正~
一、使用場景+遇到的困難
使用場景:我有多個K8s集群。我的“管理模塊”(即主系統,是一個批處理系統)跑在一個獨立的VPC中,與干活的K8s隔離。然后會調用K8s的接口,投遞Job任務到對應的K8s集群中開始干活。如下圖:
當前遇到的困難:限流+部分API未暴露。所以希望能有一條上圖黃色的通道。
1.1 給每個K8s集群,買個EIP唄?
顯然,可行性沒問題。但是這個方案並不好:
(1) EIP需要額外付費,價格也不便宜。
(2) EIP是互聯網地址,明明我所有程序都在華為雲,為什么報文要走互聯網繞一圈。
(3) K8s集群並不想對互聯網外部暴露,徒增安全風險。
那看看其他方式吧
1.2 華為雲VPC打通服務 VPC-endpoint
我們知道跨vpc(特別是跨租戶的vpc),可通過華為雲的 vpc-endpoint 服務完成連接通道的打通。
參考:https://support.huaweicloud.com/productdesc-vpcep/zh-cn_topic_0131645196.html
既然EIP不合適,那我們就走全部華為雲內網的 vpc-endpoint 方案吧。
二、跨VPC打通通道
定下整體方案是就是利用 vpc-endpoint 來打通繞開CCE API-Server的限制。
以下就是操作過程:
2.1 VPCEP直接連3台K8s-Master。(失敗)
每個CCE集群,都會有一個內網訪問的IP地址。其Master的IP可以在界面看到。
那咱直接讓 vpc-endpoint 對接這個IP不就完了么?
如下圖:
想法雖然好,可是事實是殘酷的。
(1) CCE給出的這個內網IP地址是一個vip(虛IP),本身是用來保證可靠性的。當某台master掛了,會自動漂移到其他2台Master上面。
(2) 經過確認:Vpc-endpoint使用的是vxlan隧道,走的是點對點協議。 也就是vpcep會最終綁定到Master節點的實際IP地址。當vip發生漂移時,vpcep就會失效(不支持自動檢測漂移,需要重新綁定到新的節點)。
所以也就沒辦法通過vpcep直接連3台Master了。
三、通過ELB中轉一次連K8s-Master
vpcep服務當前只能對接 (1)ELB實例 or (2)具體的ECS 這2種后端。
而這里咱們有3台Master節點,顯然第(2)種就不合適。所以咱就走(1)elb實例吧。
接下來==》那咱重點分析 “k8s集群怎么對接elb”吧。
3.1 使用CCE提供的:Service綁定elb功能。(失敗)
K8s自帶了一個訪問api-server的 service。
所有集群里面的容器,都可以通過這個地址,訪問Master。
那我們通過elb去連接這個svc,不就可以了么?
根據CCE的文檔,操作起來:
https://support.huaweicloud.com/usermanual-cce/cce_01_0014.html
給SVC設置一個:annotation,帶上elb實例id。走起~
嗯?報錯了。。
k8s里面的controller報錯說:連elb的svc必須要有selector。
也就使用elb直接連那個“無selector”的 “kubernetes” service,CCE的controller會報錯,此路走不通。。。
唐老師注:說明controller實現時,考慮的兼容性不夠強。當已經有 endpoints 了,應沒必要強制要求有 selector了(因為k8s的selector的目的就是為了找到目標地址,咱這里目標都已經提前知道了)
3.2 使用ELB去連3台K8s-Master地址。(失敗)
既然CCE的Service實現帶了約束,導致Master無法直接對接elb。 那咱就直接從elb角度,直接去連3台master吧(cce的controller,也是調用elb的api來關聯的)。
如下圖:
可是,事實還是失敗告終。
原因:當前華為雲的elb只能連 ECS 的主網卡,而咱們的3台CCE Master節點的網卡,都是從網卡。如下圖:
ELB實例不支持連從網卡(如下圖)。。。
據說華為雲的下一代elb(v3)支持連從網卡。於是當前,此路不通~
四、再找個Nginx中轉一次吧
Elb不能直接連master節點,而elb連Service又必須得帶selector。那就只能額外部署一個proxy容器,使用selector先到這個proxy容器,再轉到Master。
4.1 通過Configmap掛載Nginx配置文件。(失敗)
啟動 Nginx 得有個 conf 配置。 咱們通過 configmap 將nginx.conf配置文件掛載到Nginx容器里面。
嗯?怎么報錯了。華為雲的WAF將CCE的這個創建Configmap的API攔截了。。。
所以自動化啟動Nginx(通過CCE的API-server)是行不通了。
4.2 從K8s內部創建Configmap並掛載。(成功)
走CCE雲服務API接口失敗,那就走K8s內部的原生接口吧。
# kubectl create configmap nginx --from-file=nginx.conf
其中 nginx.conf 的內容如下:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
stream {
log_format proxy '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
access_log /opt/software/nginx/logs/tcp-access.log proxy ;
open_log_file_cache off;
upstream kubeapi {
server kubernetes.default:443;
}
server {
listen 443;
proxy_connect_timeout 8s;
proxy_timeout 24h;
proxy_pass kubeapi;
}
}
創建configmap完成。
4.3 啟動Nginx容器,然后vpcep連接該容器。(失敗)
配置文件好了,那我們啟動Nginx吧(記得掛載上面那個configmap哦)。
我的configmap掛載地址是:
/etc/nginx/configmap
容器啟動命令:
mv nginx.conf nginx.conf.bak; cp configmap/nginx.conf nginx.conf; mkdir -p /opt/software/nginx/logs; nginx &
啟動Deployment的同時,創建類型為 Loadbalancer 類型的 Service(使得ELB連通到Nginx容器)。
可以看到elb實例已經創建出來。
4.4 開始創建 vpc-endpoint。
(1)先在目的vpc(即K8s集群對應的vpc網絡)創建 vpc-endpoint-service。選擇連咱們的elb實例。
重點:權限設置里面,記得允許別人連接。(如果有跨租戶調用K8s接口)
(2)然后在客戶端的vpc(即管理邏輯模塊所在vpc)創建 vpc-endpoint。
通過名字,找到步驟(1)的endpoint-service,並綁定成功:
重點:這里這個 vpc-endpoint 需要 1毛錢/小時。一天2塊4,標題說的花點錢就是在這里了。
(3)創建好的vpc-endpoint如下:
咱們直接從客戶端訪問這個 vpcep(直接代表了那個Nginx容器)吧。
額,不通呀。。。
4.5 終於大功告成
經過定位:是 Nginx容器綁定ELB的時候,CCE沒有自動創建elb的backend導致的(應該是小bug,我的集群版本也比較舊,才1.11的)。
后面通過:擴容pod數量,再次觸發一次刷新elb后端backend行為:可以看到有backed了
這個時候,通過 vpcep 終於可以訪問到目標CCE集群的API了。
(上面401,是因為沒有帶token。 帶了“Authorization: Bearer iam-token”是OK的)
打通的完整流程圖如下:
到此,我們就可以隨意跨租戶、跨VPC、跨集群 來訪問K8s的API了,不用經過CCE的Api-server了。
(相當於我們自己造了一個 “偽CCE-API-Server”)
五、總結
通過精心挖掘的通道,花費2.4元/集群/天,即可繞開華為雲CCE服務的API-Server的“防線”,“暢通”地調用你購買的K8s接口。
關鍵在於,為了獲得“自由調用K8s接口”這個目的,是否值得這一路上的各種坎坷?至少從這些困難點來看,華為雲還存在很大的可改進空間。如:
(1) API-Server限制可否放開一點?
(2) ELB能否直接對接K8s-Master?
(3) VPC-endpoint能否直接對接K8s集群?
(4) VPC-endpoint,無法提供報文日志,用戶無法自己排查問題。
(5) 能否有更簡潔的管理多K8s集群的“偽API-server”功能。
但是,正是因為有人去發現問題,才能有變得更好的可能,不是么? 感謝各位,Thanks~