v0.3.2 k8s 管理模块 开始写 pod列表

This commit is contained in:
何全
2019-06-10 10:40:19 +08:00
parent e732c88fd0
commit d1b66907f3
14 changed files with 295 additions and 1 deletions

View File

@@ -26,11 +26,13 @@
* drf RESTful api 例子
* 前端 Vue版本
* GraphQL
* k8s管理
## 开发计划
* 一期: 基础模板 (已完成)
* 二期: k8s管理平台 (开发中)
* pod 列表 (已完成)
## DEMO
@@ -130,6 +132,11 @@ nohup python36 manage.py runserver 0.0.0.0:8001 >> /tmp/http.log 2>&1 &
```
## k8s模块
> 修改settings Token 及 APISERVER。
## 异步任务
* redis

1
k8s/__init__.py Normal file
View File

@@ -0,0 +1 @@

1
k8s/k8sApi/__init__.py Normal file
View File

@@ -0,0 +1 @@

15
k8s/k8sApi/core.py Normal file
View File

@@ -0,0 +1,15 @@
from kubernetes import client, config
from seal import settings
import urllib3
def K8sApi():
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
configuration = client.Configuration()
configuration.host = getattr(settings, 'APISERVER')
configuration.verify_ssl = False
configuration.api_key = {"authorization": "Bearer " + getattr(settings, 'Token'), }
client.Configuration.set_default(configuration)
v1 = client.CoreV1Api()
return v1

View File

@@ -0,0 +1,52 @@
## 1.先创建
```
vim k8s-admin.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: dashboard-admin
namespace: kube-system
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: dashboard-admin
subjects:
- kind: ServiceAccount
name: dashboard-admin
namespace: kube-system
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
kubectl apply -f k8s-admin.yaml
```
## 2.获取name
```
kubectl get secret -n kube-system
NAME TYPE DATA AGE
dashboard-admin-token-dhhmc kubernetes.io/service-account-token 3 69s
```
## 3.查询token
```
[root@k8s-master ~]# kubectl describe secret dashboard-admin-token-dhhmc -n kube-system
Name: dashboard-admin-token-dhhmc
Namespace: kube-system
Labels: <none>
Annotations: kubernetes.io/service-account.name: dashboard-admin
kubernetes.io/service-account.uid: 98d070eb-875c-11e9-a538-000c297b4fe7
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1025 bytes
namespace: 11 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tZGhobWMiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiOThkMDcwZWItODc1Yy0xMWU5LWE1MzgtMDAwYzI5N2I0ZmU3Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.XDFpez2E84R_zlopt_uEHPvVGUtSavypyix6UcYJO3J4imHdJy7MEkfV-wltBA1H8x0TT2AW64rLlXaRJ8OkFWJ0myedfKdjnf7i0oLQ8j-7lw6rT3A0e2pKmpnOaBQfgzRm83-t2I5MMp3Iu9VNUiAbqQpjql4AKwRuJEEGCs99tKStUxzIsJKusmUHh9KAK4BAxySn9h16T2URZ7czLP4mty2crYWNV4KwSwFPthGhFPsl8mnet_hiV5k4me5a8frmXytOy64MmGW8w3TBgiM-7hBYSxt84QGGnyi84LU0EFgtLwBWEOTZeUKKQ6IkoAprMmNcSxX8WUJFlx_uJg
```

3
k8s/models.py Normal file
View File

@@ -0,0 +1,3 @@
from django.db import models

21
k8s/tests.py Normal file
View File

@@ -0,0 +1,21 @@
from kubernetes import client, config
def main():
Token = "eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tZGhobWMiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiOThkMDcwZWItODc1Yy0xMWU5LWE1MzgtMDAwYzI5N2I0ZmU3Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.XDFpez2E84R_zlopt_uEHPvVGUtSavypyix6UcYJO3J4imHdJy7MEkfV-wltBA1H8x0TT2AW64rLlXaRJ8OkFWJ0myedfKdjnf7i0oLQ8j-7lw6rT3A0e2pKmpnOaBQfgzRm83-t2I5MMp3Iu9VNUiAbqQpjql4AKwRuJEEGCs99tKStUxzIsJKusmUHh9KAK4BAxySn9h16T2URZ7czLP4mty2crYWNV4KwSwFPthGhFPsl8mnet_hiV5k4me5a8frmXytOy64MmGW8w3TBgiM-7hBYSxt84QGGnyi84LU0EFgtLwBWEOTZeUKKQ6IkoAprMmNcSxX8WUJFlx_uJg"
APISERVER = 'https://192.168.100.111:6443'
configuration = client.Configuration()
configuration.host = APISERVER
configuration.verify_ssl = False
configuration.api_key = {"authorization": "Bearer " + Token}
client.Configuration.set_default(configuration)
v1 = client.CoreV1Api()
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()

7
k8s/urls.py Normal file
View File

@@ -0,0 +1,7 @@
from django.urls import path
from k8s import views
app_name = "k8s"
urlpatterns = [
path('k8s-pod-list', views.K8sPodListView.as_view(), name='k8s-pod-list'),
]

27
k8s/views.py Normal file
View File

@@ -0,0 +1,27 @@
import logging
import json
from django.urls import reverse_lazy
from django.db.models import Q
from django.conf import settings
from pure_pagination import PageNotAnInteger
from pure_pagination import Paginator
from django.shortcuts import render, HttpResponse
from system.decorator.get_list import get_list
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.views.generic import ListView, View, DetailView, CreateView, UpdateView
from assets.models import Ecs
from k8s.k8sApi.core import K8sApi
logger = logging.getLogger('k8s')
class K8sPodListView(LoginRequiredMixin, PermissionRequiredMixin, View):
permission_required = ('k8s.view_ecs',)
template_name = 'k8s/k8s-pod-list.html'
def get(self, request):
ret = K8sApi().list_pod_for_all_namespaces(watch=False)
data = {}
for i in ret.items:
data[i.metadata.name] = {"ip": i.status.pod_ip, "namespace": i.metadata.namespace}
return render(request, "k8s/k8s-pod-list.html", {"data": data})

View File

@@ -247,3 +247,8 @@ CORS_ORIGIN_WHITELIST = (
'*',
)
MIDDLEWARE_CLASSES = ('system.views.DisableCSRFCheck',)
## K8S
Token = "eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tZGhobWMiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiOThkMDcwZWItODc1Yy0xMWU5LWE1MzgtMDAwYzI5N2I0ZmU3Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.XDFpez2E84R_zlopt_uEHPvVGUtSavypyix6UcYJO3J4imHdJy7MEkfV-wltBA1H8x0TT2AW64rLlXaRJ8OkFWJ0myedfKdjnf7i0oLQ8j-7lw6rT3A0e2pKmpnOaBQfgzRm83-t2I5MMp3Iu9VNUiAbqQpjql4AKwRuJEEGCs99tKStUxzIsJKusmUHh9KAK4BAxySn9h16T2URZ7czLP4mty2crYWNV4KwSwFPthGhFPsl8mnet_hiV5k4me5a8frmXytOy64MmGW8w3TBgiM-7hBYSxt84QGGnyi84LU0EFgtLwBWEOTZeUKKQ6IkoAprMmNcSxX8WUJFlx_uJg"
APISERVER = 'https://192.168.100.111:6443'

View File

@@ -15,6 +15,7 @@ urlpatterns = [
path('index', index, name="index"),
path('system/', include('system.urls', namespace='system')),
path('assets/', include('assets.urls', namespace='assets')),
path('k8s/', include('k8s.urls', namespace='k8s')),
path('admin/', admin.site.urls, ),
path('api/token', views.obtain_auth_token),
path('api/docs/', include_docs_urls(title=API_TITLE, description=API_DESCRIPTION, authentication_classes=[],

View File

@@ -90,7 +90,7 @@
<form class="form-horizontal "
method="post">
{% csrf_token %}
<table class="table table-striped table-bordered table-hover dataTables-asset">
<table class="table table-striped table-bordered table-hover dataTables-code">
<thead>
<tr>

View File

@@ -53,6 +53,19 @@
</li>
{% endif %}
</ul>
</li>
<li class="k8s">
<a href="#"> <i class="fa fa-gitlab"></i> <span class="nav-label">k8s管理</span></a>
<ul class="nav nav-second-level">
{% if perms.k8s.view_ecs %}
<li class="k8s-pod-list">
<a href="{% url "k8s:k8s-pod-list" %}">Pod列表</a>
</li>
{% endif %}
</ul>
</li>

View File

@@ -0,0 +1,141 @@
{% extends "base/base.html" %}
{% load asset_filter %}
{% load bootstrap4 %}
{% load static %}
{% block header-css %}
<style type="text/css">
.sort_both_png {
background: url('/static/img/sort_both.png') no-repeat right 1px center;
cursor: pointer;
}
.sort_asc_png {
background: url('/static/img/sort_asc.png') no-repeat right 1px center;
cursor: pointer;
}
.sort_desc_png {
background: url('/static/img/sort_desc.png') no-repeat right 1px center;
cursor: pointer;
}
</style>
{% endblock %}
{% block title %}K8S{% endblock %}
{% block page-content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-lg-12" id="split-right">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>Pod列表</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<div class="table-responsive">
<form class="form-horizontal "
method="post">
{% csrf_token %}
<table class="table table-striped table-bordered table-hover dataTables-example">
<thead>
<tr>
<th>主机名</th>
<th>ip</th>
<th>命名空间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for k,v in data.items %}
<tr class="gradeA" id="{{ row.id }}" name="{{ k }}">
<td class="center">
<div class="">{{ k }}</div>
</td>
<td class="center">
<div class="">{{ v.ip }}</div>
</td>
<td class="center">
<div class="">{{ v.namespace}}</div>
</td>
<td class="center">
</td>
{# {% if perms.assets.view_ecs %}#}
{# <a class="btn btn-success btn-xs "#}
{# href="{% url "assets:ecs-detail" pk=row.id %}">详情</a>#}
{# {% endif %}#}
{# {% if perms.assets.change_ecs %}#}
{# <a class="btn btn-primary btn-xs "#}
{# href="{% url "assets:ecs-update" pk=row.id %}">编辑</a>#}
{# {% endif %}#}
{# {% if perms.assets.delete_ecs %}#}
{# <a class="btn btn-danger btn-xs ecs-delete"#}
{# href="#">删除</a>#}
{# {% endif %}#}
</tr>
{% endfor %}
</tbody>
</table>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
{% block footer-js %}
<script>
window.onload = function () { // 固定左边导航栏
$(".k8s").addClass("active");
$(".k8s-pod-list").addClass("active");
};
</script>
{% endblock %}
{% endblock %}