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

时间:2019-09-12 19:09:41

标签: kubernetes

我有一个名为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在我的容器中不可用。

2 个答案:

答案 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操作(即动词和资源的组合)的许可权限的方式相同。