Vin*_*eti 25 docker kubernetes kubernetes-ingress
我想清除Kubernetes命名空间中所有pod中的缓存.我想向端点发送一个请求,然后该端点将向命名空间中的所有pod发送HTTP调用以清除缓存.目前,我只能使用Kubernetes命中一个pod,而我无法控制哪个pod会受到攻击.
即使负载均衡器设置为RR,连续点击pod(n次,其中n是pod的总数)也无济于事,因为其他一些请求可能会进入.
这里讨论了同样的问题,但我找不到实施的解决方案:https: //github.com/kubernetes/kubernetes/issues/18755
我正在尝试使用Hazelcast实现清除缓存部分,其中我将存储所有缓存,Hazelcast自动处理缓存更新.
如果有针对此问题的替代方法,或者配置kubernetes以针对某些特定请求命中所有端点,则在此处共享将是一个很大的帮助.
Mar*_*sch 14
如果你的pod中有kubectl并且可以访问api-server,你可以获得所有端点的adressess并将它们传递给curl:
kubectl get endpoints <servicename> \
-o jsonpath="{.subsets[*].addresses[*].ip}" | xargs curl
Run Code Online (Sandbox Code Playgroud)
在pod中没有kubectl的替代方案:
从pod中访问api服务器的推荐方法是使用kubectl代理:https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/#accessing-the-api-from-a- pod这当然会增加至少相同的开销.或者你可以直接调用REST api,你必须手动提供令牌.
APISERVER=$(kubectl config view --minify | grep server | cut -f 2- -d ":" | tr -d " ")
TOKEN=$(kubectl describe secret $(kubectl get secrets \
| grep ^default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d " ")
Run Code Online (Sandbox Code Playgroud)
如果你提供APISERVER和TOKEN变量,你的pod中不需要kubectl,这样你只需要curl来访问api服务器和"jq"来解析json输出:
curl $APISERVER/api/v1/namespaces/default/endpoints --silent \
--header "Authorization: Bearer $TOKEN" --insecure \
| jq -rM ".items[].subsets[].addresses[].ip" | xargs curl
Run Code Online (Sandbox Code Playgroud)
更新(最终版)
APISERVER通常可以设置为kubernetes.default.svc,并且该标记应该位于pod中的/var/run/secrets/kubernetes.io/serviceaccount/token,因此无需手动提供任何内容:
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token); \
curl https://kubernetes.default.svc/api/v1/namespaces/default/endpoints --silent \
--header "Authorization: Bearer $TOKEN" --insecure \
| jq -rM ".items[].subsets[].addresses[].ip" | xargs curl
Run Code Online (Sandbox Code Playgroud)
jq可以在这里找到:https://stedolan.github.io/jq/download/(<4 MiB,但值得轻松解析JSON)
更新我针对这种方法发表了这篇文章
我也有过类似的情况。这是我解决它的方法(我使用的是“default”之外的命名空间)。
对 API 的访问是通过创建 ServiceAccount 、将其分配给Pod并为其绑定Role来完成的。
1.创建服务账户
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-serviceaccount
namespace: my-namespace
Run Code Online (Sandbox Code Playgroud)
2.创建角色:在此部分中,您需要提供您想要访问的资源列表和操作列表。以下是您想要列出端点并获取特定端点的详细信息的示例。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: my-role
namespace: my-namespace
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list"]
Run Code Online (Sandbox Code Playgroud)
3.将角色与服务帐号绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: my-role-binding
namespace: my-namespace
subjects:
- kind: ServiceAccount
name: my-serviceaccount
roleRef:
kind: Role
name: my-role
apiGroup: rbac.authorization.k8s.io
Run Code Online (Sandbox Code Playgroud)
4.将服务帐户分配给部署中的 Pod(应该位于 template.spec 下)
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
namespace: my-namespace
spec:
replicas: 1
selector:
matchLabels:
app: my-pod
template:
metadata:
labels:
app: my-pod
spec:
serviceAccountName: my-serviceaccount
containers:
- name: my-pod
...
Run Code Online (Sandbox Code Playgroud)
设置完所有安全方面后,您将拥有足够的权限来访问 Pod 中的 API。与 API Server 通信所需的所有信息都安装/var/run/secrets/kubernetes.io/serviceaccount在您的 Pod 中。您可以使用以下 shell 脚本(可能将其添加到 Docker 映像的 COMMAND 或 ENTRYPOINT 中)。
#!/bin/bash
# Point to the internal API server hostname
API_SERVER=https://kubernetes.default.svc
# Path to ServiceAccount token
SERVICE_ACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
# Read this Pod's namespace
NAMESPACE=$(cat ${SERVICE_ACCOUNT}/namespace)
# Read the ServiceAccount bearer token
TOKEN=$(cat ${SERVICE_ACCOUNT}/token)
# Reference the internal certificate authority (CA)
CA_CERT=${SERVICE_ACCOUNT}/ca.crt
Run Code Online (Sandbox Code Playgroud)
从现在开始,这只是简单的 REST API 调用。您可以使用您选择的任何语言读取这些环境变量并访问 API。
以下是列出您的用例的端点的示例
# List all the endpoints in the namespace that Pod is running
curl --cacert ${CA_CERT} --header "Authorization: Bearer ${TOKEN}" -X GET \
"${API_SERVER}/api/v1/namespaces/${NAMESPACE}/endpoints"
# List all the endpoints in the namespace that Pod is running for a deployment
curl --cacert ${CA_CERT} --header "Authorization: Bearer ${TOKEN}" -X GET \
"${API_SERVER}/api/v1/namespaces/${NAMESPACE}/endpoints/my-deployment"
Run Code Online (Sandbox Code Playgroud)
有关可用 API 端点以及如何调用它们的更多信息,请参阅API 参考。