我有一个名为my-service
的服务,其端点为refreshCache
。 my-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
在我的容器中不可用。
答案 0 :(得分:3)
要实现这一目标,最好的方法是在广告连播中使用K8s配置。
为此,K8s客户可以提供帮助。这是一个示例python脚本,可用于从容器内部获取容器及其元数据。
from kubernetes import client, config
def trigger_refresh_cache():
# it works only if this script is run by K8s as a POD
config.load_incluster_config()
v1 = client.CoreV1Api()
print("Listing pods with their IPs:")
ret = v1.list_pod_for_all_namespaces(label_selector='app=my-service')
for i in ret.items:
print("%s\t%s\t%s" %
(i.status.pod_ip, i.metadata.namespace, i.metadata.name))
# Rest of the logic goes here to trigger endpoint
这里使用的方法load_incluster_config()
通过附加到该pod的服务帐户将kubeconfig加载到pod中。
答案 1 :(得分:2)
您不需要kubectl
即可访问Kubernetes API。您可以使用任何可以发出HTTP请求的工具来做到这一点。
Kubernetes API是一个简单的HTTP REST API,并且如果它在集群中作为Pod运行,则所需的所有身份验证信息都在容器中。
要从集群中的一个容器内的get the Endpoints object命名为my-service
,您可以执行以下操作:
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
端点资源的命名空间。
要提取返回的JSON的IP地址,您可以将输出通过管道传输到jq
之类的工具:
... | jq -r '.subsets[].addresses[].ip'
请注意,从中执行此操作的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
然后,在pod.spec.serviceAccountName
字段中指定要用于执行上述endpoint-reader
命令的Pod,请使用curl
ServiceAccount。
授予任何其他API操作(即动词和资源的组合)的许可权限的方式相同。