欢迎访问www.showerlee.com, 您的支持就是我前进的动力.

Kubernetes之python client连接k8s API cluster

showerlee 2018-10-23 22:01 DevTools, Kubernetes, 其他 阅读 (32,499) 5条评论

大家在平时使用k8s可以说用到的最多的命令应该就是kubectl, 这个命令默认会在master上安装并与本地的k8s API cluster绑定token认证, 实现日常k8s的数据交互. 不过问题在于, 如果我们需要远程调用k8s API或者需要实现k8s自动化集成, 仅靠每次远程ssh集成使用kubectl命令这种偷懒的办法是远远不够的.

这里k8s官方给我们提供了两种比较主流的连接k8s API cluster的语言, 一种是GO, 另外一种就是我们DevOps比较主流的Python.

今天这里我将给大家介绍如何使用python client扩展包去编写脚本并远程连接k8s API cluster.

这样我们平时除了可以远程使用ssh+kubectl去与kubernetes进行命令行数据交互外, 同样可以在远程不依赖命令行直接连接k8s cluster API cluster, 与k8s进行python API交互, 方便我们后期利用python去对k8s进行自动化集成与二次开发.

这里我们不多说, 直接进入我们的runbook配置环节:

一.部署python client环境连接我们的k8s API cluster.

1.安装python3.6.5源及依赖包

# yum install epel-release -y

# yum groupinstall "Development tools" -y

# yum install zlib-devel bzip2-devel openssl-devel ncurses-devel zx-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel -y

2.编译安装python3.6.5以及pip package manager

# wget https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tar.xz --no-check-certificate

# tar xf Python-3.6.5.tar.xz

# cd Python-3.6.5

# ./configure --prefix=/usr/local --with-ensurepip=install --enable-shared LDFLAGS="-Wl,-rpath /usr/local/lib"

# make && make altinstall

3.安装virtualenv

# pip3.6 install --upgrade pip

# pip3.6 install virtualenv

4.配置加载virtualenv环境

# virtualenv -p /usr/local/bin/python3 .py3env

# source .py3env/bin/activate

5.安装kubernetes python client扩展包

# pip install kubernetes


二.在k8s master获取API cluster URL与token

我们需要在创建python脚本前, 在k8s主机上创建一个admin权限的service account, 并获取其token 用来作为我们的脚本凭证.

1.抓取Cluster URL地址

# APISERVER=$(kubectl config view --minify | grep server | cut -f 2- -d ":" | tr -d " ")

# echo $APISERVER

2.创建k8s admin-user

# mkdir -p /kube/role

# cd /kube/role

在kube-system下创建admin-user

# vi CreateServiceAccount.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system

给admin-user赋予admin权限

# vi CreateServiceAccount.yaml

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system

# kubectl create -f CreateServiceAccount.yaml
# kubectl create -f RoleBinding.yaml

3.获取admin-user token

# Token=$(kubectl describe secret $(kubectl get secret -n kube-system | grep ^admin-user | awk '{print $1}') -n kube-system | grep -E '^token'| awk '{print $2}')

# echo $Token

最后将token与APISERVER地址返回内容复制到python client主机上, 供脚本使用.

. 在python client主机上编写脚本

1. 创建目录结构

# mkdir -p /kube/auth

# cd /kube/auth

# touch token.txt

2. 创建token.txt文件并将k8s主机上获取的Token字符串复制到该文件

这里我们获取的token会引入到我们的脚本下, 作为bearer authorization的api key与远程k8s API建立认证连接.

3. 编写python client脚本

# vi k8s_auth.py

#!/usr/bin/env python


from kubernetes import client, config


def main():
    # Define the barer token we are going to use to authenticate.
    # See here to create the token:
    # https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/

    with open('token.txt', 'r') as file:
        Token = file.read().strip('\n')

    APISERVER = 'https://10.110.16.14:6443'

    # Create a configuration object
    configuration = client.Configuration()

    # Specify the endpoint of your Kube cluster
    configuration.host = APISERVER

    # Security part.
    # In this simple example we are not going to verify the SSL certificate of
    # the remote cluster (for simplicity reason)
    configuration.verify_ssl = False

    # Nevertheless if you want to do it you can with these 2 parameters
    # configuration.verify_ssl=True
    # ssl_ca_cert is the filepath to the file that contains the certificate.
    # configuration.ssl_ca_cert="certificate"
    configuration.api_key = {"authorization": "Bearer " + Token}

    # configuration.api_key["authorization"] = "bearer " + Token
    # configuration.api_key_prefix['authorization'] = 'Bearer'
    # configuration.ssl_ca_cert = 'ca.crt'
    # Create a ApiClient with our config
    client.Configuration.set_default(configuration)

    # Do calls
    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()

这个脚本通过抓取同目录的k8s token字符串, 以及我们之前获取到的api server地址,利用python kubernetes扩展模块连接我们的远程API, 最终实现打印我们k8s所有namespace下的所有pods.

实际效果与kubectl get pods --all-namespaces类似.

4. 修改权限并执行

# chmod 755 k8s_auth.py

# ./k8s_auth.py

Listing pods with their IPs:
...
10.244.1.3	default	db
10.244.1.2	default	kubernetes-downwardapi-volume-example
10.244.1.245	default	nginx1-7-deployment-667547b6d8-c5nsr
10.244.1.239	default	nginx1-7-deployment-667547b6d8-mjxq4
10.244.1.247	default	nginx1-8-deployment-d46768cf9-888v8
10.244.1.242	default	nginx1-8-deployment-d46768cf9-fglq2
10.110.16.14	kube-system	etcd-kube-master
10.110.16.14	kube-system	kube-apiserver-kube-master
10.110.16.14	kube-system	kube-controller-manager-kube-master
10.244.1.241	kube-system	kube-dns-6f4fd4bdf-qsxrj
10.110.16.14	kube-system	kube-flannel-ds-5sdlg
10.110.16.15	kube-system	kube-flannel-ds-qctv4
10.110.16.14	kube-system	kube-proxy-5nscq
10.110.16.15	kube-system	kube-proxy-6g7jc
10.110.16.14	kube-system	kube-scheduler-kube-master
10.244.1.246	kube-system	kubernetes-dashboard-58f5cb49c-6dxgn
10.244.1.240	kube-system	tiller-deploy-cbb85d8dc-f6rsv
10.110.16.15	kube-system	traefik-ingress-lb-765c44656f-fkzxb
10.244.1.243	spinnaker	kubelive-create-bucket-wxlv4
10.244.1.244	spinnaker	kubelive-delete-jobs-zhn75

这样我们就成功的编写完成python client脚本连接k8s API cluster, 将所有namespace下的pod的基本信息打印出来.

Finished...

正文部分到此结束
版权声明:除非注明,本文由(showerlee)原创,转载请保留文章出处!
本文链接:http://www.showerlee.com/archives/2804

继续浏览:k8sPYTHON

5条大神的评论

loading
  1. 沙发
    yang.wenjian2019年9月16日下午3:54 回复

    不错! 亲测好用

  2. 板凳
    harcker2019年10月6日上午10:09 回复

    怎么执行yaml来创建pod呢?

    • showerlee2020年2月17日下午5:26 回复

      详见python kubernetes 模块的配置文档

  3. 地板
    Lesliezhang2019年10月21日下午2:48 回复

    如果要启用SSL的话,怎样从数据库中实现读取CA而不是从文件读取?

    不启用SSL验证的话,总感觉不安全。而且urllib3会告警,又必须要关闭这个警告。urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

    我想从数据库中读取对应K8S集群的TOKEN。官方默认是指定ca.crt的路径,而我也想从数据库中读取它。

    • showerlee2020年2月17日下午5:27 回复

      这个要看你怎么设计数据库了

发表评论

icon_wink.gif icon_neutral.gif icon_mad.gif icon_twisted.gif icon_smile.gif icon_eek.gif icon_sad.gif icon_rolleyes.gif icon_razz.gif icon_redface.gif icon_surprised.gif icon_mrgreen.gif icon_lol.gif icon_idea.gif icon_biggrin.gif icon_evil.gif icon_cry.gif icon_cool.gif icon_arrow.gif icon_confused.gif icon_question.gif icon_exclaim.gif