kubernetes - 从容器中获取所有k8s pod的IP地址

我有一个名为my-service的服务,其端点名为refreshCachemy-service托管在多个服务器上,有时我希望其中一台服务器上my-service中的事件触发所有服务器上refreshCache上的my-service。为此,我手动维护所有托管my-service的服务器的列表,拉出该列表,然后为每个服务器向<server>/.../refreshCache发送REST请求。

我现在将服务迁移到k8s。与之前类似,在托管refreshCache的所有服务器上运行my-service的地方,现在我希望能够在托管refreshCache的所有Pod上运行my-service的地方。不幸的是,我无法手动维护Pod IP列表,因为我的理解是IP在k8s中是短暂的,因此我需要能够从其中一个Pod中的容器内动态获取节点中所有Pod的IP。这可能吗?

注意:我知道kubectl get endpoints ...提供了此信息,但是kubectl在我的容器中不可用。

最佳答案

您不需要kubectl即可访问Kubernetes API。您可以使用任何可以发出HTTP请求的工具来执行此操作。

Kubernetes API是一个简单的HTTP REST API,并且如果它在集群中作为Pod运行,则所需的所有身份验证信息都将出现在容器中。

要从集群中的容器内命名为my-serviceget the Endpoints object,可以执行以下操作:

curl -k -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
  https://kubernetes.default.svc:443/api/v1/namespaces/{namespace}/endpoints/my-service

注意:将 {namespace}替换为 my-service Endpoints资源的 namespace 。

为了提取返回的JSON的IP地址,您可以将输出通过管道传递给 jq这样的工具:
... | jq -r '.subsets[].addresses[].ip'

请注意,从中执行此Pod的Pod需要Endpoints资源的读取权限,否则API请求将被拒绝。

您可以使用ClusterRole,ClusterRoleBinding和Service Account来执行此操作(只需设置一次):
kubectl create sa endpoint-reader
kubectl create clusterrole endpoint-reader --verb=get,list --resource=endpoints
kubectl create clusterrolebinding endpoint-reader --serviceaccount=default:endpoint-reader --clusterrole=endpoint-reader

然后,通过在 endpoint-reader 字段中指定要用于执行上述 curl命令的Pod,使用 pod.spec.serviceAccountName ServiceAccount。

授予其他任何API操作(即,动词和资源的组合)的权限都以相同的方式进行。