从pod内部访问K8s的API比外部访问简单些,访问的话有两种方式:
使用官方的client库 , 可以自动发现API server并进行认证
直接访问REST API
地址: https://github.com/kubernetes-client/python/
config.load_incluster_config()
函数用于处理API server发现与认证
python代码示例:https://github.com/kubernetes-client/python/blob/master/examples/in_cluster_config.py
步骤如下。先创建一个python pod:
kubectl run python --image=python -i --tty -- sh
在python pod中,安装k8s client:
pip install kubernetes
创建一个api.py文件:
cat > api.py << EOL
from kubernetes import client, config
def main():
config.load_incluster_config()
v1 = client.CoreV1Api()
print("Listing pods with their IPs:")
ret = v1.list_pod_for_all_namespaces(watch=False)
for i in ret.items:
print("%s\t%s\t%s" %
(i.status.pod_ip, i.metadata.namespace, i.metadata.name))
if __name__ == '__main__':
main()
EOL
执行python api.py
此时并没有像预期一样返回pod列表,而是报错:
这是因为默认的service account没有list权限,参考文档
( The default
service accounts in each namespace get no permissions by default )
所以需要为这个service account添加权限,新打开一个控制台,执行:
$ cat > roles.yaml << EOL
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pods-list
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["list"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pods-list
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
kind: ClusterRole
name: pods-list
apiGroup: rbac.authorization.k8s.io
EOL
$ kubectl apply -f roles.yaml
此时再回到python pod中运行api.py
,可以成功输出pod列表:
# python api.py
Listing pods with their IPs:
10.10.49.31 default busybox
10.10.43.203 default mycurlpod
10.10.35.210 default mycurlpod2
10.10.53.89 default mycurlpod3
10.10.13.165 default mycurlpod4
10.10.2.145 default python
10.10.58.85 default rebel-base-7bdbfb9c9d-lng8k
10.10.8.194 default rebel-base-7bdbfb9c9d-xxslz
10.10.16.140 default x-wing-d9fccdb9b-hh7j5
10.10.41.198 default x-wing-d9fccdb9b-rb92s
10.10.33.30 kube-system cilium-hdm8z
10.10.33.30 kube-system cilium-node-init-m5wlf
10.10.1.150 kube-system cilium-node-init-vd5f4
10.10.33.30 kube-system cilium-operator-656567b78d-j6djz
10.10.1.150 kube-system cilium-qz7rf
10.10.59.68 kube-system coredns-857b668457-bx27n
访问kubernetes.default.svc
服务,可以获取API server的信息。原理也是使用service account的token信息,这个信息保存在: /var/run/secrets/kubernetes.io/serviceaccount/token
在上面的python pod里执行访问测试:
# Point to the internal API server hostname
APISERVER=https://kubernetes.default.svc
# Path to ServiceAccount token
SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
# Read this Pod's namespace
NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
# Read the ServiceAccount bearer token
TOKEN=$(cat ${SERVICEACCOUNT}/token)
# Reference the internal certificate authority (CA)
CACERT=${SERVICEACCOUNT}/ca.crt
# Explore the API with TOKEN
curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api
结果如下:
参考:https://kubernetes.io/docs/tasks/run-application/access-api-from-pod/