如何使用 Kubernetes Go 客户端调用 Pod 代理动词?
How to invoke the Pod proxy verb using the Kubernetes Go client?
Kubernetes 远程 API 允许使用代理动词对任意 pod 端口进行 HTTP 访问,即使用 /api/v1/namespaces/{namespace}/pods/{name}/proxy
的 API 路径。
Python 客户端提供 corev1.connect_get_namespaced_pod_proxy_with_path()
调用上述代理动词。
尽管阅读、浏览和搜索 Kubernetes client-go 有一段时间了,但我仍然不知道如何用 goclient 做我能用 python 客户端做的事情。我的另一个印象是,如果没有现成的 API corev1 调用可用,我可能需要深入研究客户端变更集的其余客户端?
如何使用其余客户端和上述路径正确构造 GET 调用?
在深入研究 Kubernetes 客户端源后发现,访问代理动词只有在下降到 RESTClient
级别然后构建 GET/... 请求时才有可能手。以下代码以完整示例的形式显示了这一点:
package main
import (
"fmt"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
func main() {
clcfg, err := clientcmd.NewDefaultClientConfigLoadingRules().Load()
if err != nil {
panic(err.Error())
}
restcfg, err := clientcmd.NewNonInteractiveClientConfig(
*clcfg, "", &clientcmd.ConfigOverrides{}, nil).ClientConfig()
if err != nil {
panic(err.Error())
}
clientset, err := kubernetes.NewForConfig(restcfg)
res := clientset.CoreV1().RESTClient().Get().
Namespace("default").
Resource("pods").
Name("hello-world:8000").
SubResource("proxy").
// The server URL path, without leading "/" goes here...
Suffix("index.html").
Do()
if err != nil {
panic(err.Error())
}
rawbody, err := res.Raw()
if err != nil {
panic(err.Error())
}
fmt.Print(string(rawbody))
}
例如,您可以在本地 kind 集群(Docker 中的 Kubernetes)上进行测试。以下命令启动了一个 kind 集群,用所需的 hello-world webserver 启动唯一的节点,然后告诉 Kubernetes 使用所述 hello-world webserver 启动 pod。
kind create cluster
docker pull crccheck/hello-world
docker tag crccheck/hello-world crccheck/hello-world:current
kind load docker-image crccheck/hello-world:current
kubectl run hello-world --image=crccheck/hello-world:current --port=8000 --restart=Never --image-pull-policy=Never
现在运行例子:
export KUBECONFIG=~/.kube/kind-config-kind; go run .
然后它应该显示这个 ASCII 艺术:
<xmp>
Hello World
## .
## ## ## ==
## ## ## ## ## ===
/""""""""""""""""\___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
\______ o _,/
\ \ _,'
`'--.._\..--''
</xmp>
Kubernetes 远程 API 允许使用代理动词对任意 pod 端口进行 HTTP 访问,即使用 /api/v1/namespaces/{namespace}/pods/{name}/proxy
的 API 路径。
Python 客户端提供 corev1.connect_get_namespaced_pod_proxy_with_path()
调用上述代理动词。
尽管阅读、浏览和搜索 Kubernetes client-go 有一段时间了,但我仍然不知道如何用 goclient 做我能用 python 客户端做的事情。我的另一个印象是,如果没有现成的 API corev1 调用可用,我可能需要深入研究客户端变更集的其余客户端?
如何使用其余客户端和上述路径正确构造 GET 调用?
在深入研究 Kubernetes 客户端源后发现,访问代理动词只有在下降到 RESTClient
级别然后构建 GET/... 请求时才有可能手。以下代码以完整示例的形式显示了这一点:
package main
import (
"fmt"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
func main() {
clcfg, err := clientcmd.NewDefaultClientConfigLoadingRules().Load()
if err != nil {
panic(err.Error())
}
restcfg, err := clientcmd.NewNonInteractiveClientConfig(
*clcfg, "", &clientcmd.ConfigOverrides{}, nil).ClientConfig()
if err != nil {
panic(err.Error())
}
clientset, err := kubernetes.NewForConfig(restcfg)
res := clientset.CoreV1().RESTClient().Get().
Namespace("default").
Resource("pods").
Name("hello-world:8000").
SubResource("proxy").
// The server URL path, without leading "/" goes here...
Suffix("index.html").
Do()
if err != nil {
panic(err.Error())
}
rawbody, err := res.Raw()
if err != nil {
panic(err.Error())
}
fmt.Print(string(rawbody))
}
例如,您可以在本地 kind 集群(Docker 中的 Kubernetes)上进行测试。以下命令启动了一个 kind 集群,用所需的 hello-world webserver 启动唯一的节点,然后告诉 Kubernetes 使用所述 hello-world webserver 启动 pod。
kind create cluster
docker pull crccheck/hello-world
docker tag crccheck/hello-world crccheck/hello-world:current
kind load docker-image crccheck/hello-world:current
kubectl run hello-world --image=crccheck/hello-world:current --port=8000 --restart=Never --image-pull-policy=Never
现在运行例子:
export KUBECONFIG=~/.kube/kind-config-kind; go run .
然后它应该显示这个 ASCII 艺术:
<xmp>
Hello World
## .
## ## ## ==
## ## ## ## ## ===
/""""""""""""""""\___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
\______ o _,/
\ \ _,'
`'--.._\..--''
</xmp>