장고 WebSSH 동작 포드는 Kubernetes 달성

면책 조항 :이 문서는 블로거 원본입니다, 추적 에 의해-SA의 CC 4.0 저작권 계약, 복제, 원본 소스 링크이 문을 첨부 해주세요.
이 링크 : https://blog.csdn.net/dengyu810/article/details/102661791

우수한 피드백 시스템은 점진적인 개선을 기반으로 밖으로

이 기사는 우리가 보안 및 다중 지점 자주 테스트를 처리해야하고 Alodi 시스템을 개발하는 문제를 설명 Alodi 신속하게이 문서를 볼 수있는 자세한 정보를 액세스하기 위해 임시 주소를 생성하는 버튼을 통해 테스트 환경을 구축 할 수 있습니다 : Alodi은 : 비밀을 유지하기 위해 나는 시스템을 개발

시스템이 온라인, SSH 로그인이 급선무 콘솔이 되신 후에 WebSSH 기능을하지만 대시 보드 콘솔,하지만 Alodi 시스템, 통합 의사 결정 WebSSH 기능 Alodi, 첫 번째와 결합 할 수있는 방법는 Kubernetes 보면 마지막 효과를 실현 그것을

관련된 기술

  • 는 Kubernetes 스트림 : 데이터 실행을 받고, 반환 실시간 데이터 스트림을 제공
  • 장고 채널 : 이상 데이터가 선단부는 Kubernetes 리턴 전송하는 동안, 선단부는 Kubernetes로 전송 데이터를 수신하고, 접속을 유지
  • xterm.js : 프런트 엔드 단자 조립체 아날로그 디스플레이 터미널 인터페이스

기본 데이터 흐름은 다음과 같습니다 : 사용자 -> xterm.js -> 장고 채널 ->는 Kubernetes 스트림, 다음 특정 코드 구현을보고

는 Kubernetes 스트림

다음과 같이는 Kubernetes 자체가 간부 인 기능을 구현하는 방법을 제공합니다 스트리밍, 데이터 스트림이 반환됩니다 웹 소켓은 사용하기에도 매우 쉽게 사용할 수있다 :

from kubernetes import client, config
from kubernetes.stream import stream

class KubeApi:
    def __init__(self, namespace='alodi'):
        config.load_kube_config("/ops/coffee/kubeconfig.yaml")

        self.namespace = namespace

    def pod_exec(self, pod, container=""):
        api_instance = client.CoreV1Api()

        exec_command = [
            "/bin/sh",
            "-c",
            'TERM=xterm-256color; export TERM; [ -x /bin/bash ] '
            '&& ([ -x /usr/bin/script ] '
            '&& /usr/bin/script -q -c "/bin/bash" /dev/null || exec /bin/bash) '
            '|| exec /bin/sh']

        cont_stream = stream(api_instance.connect_get_namespaced_pod_exec,
                             name=pod,
                             namespace=self.namespace,
                             container=container,
                             command=exec_command,
                             stderr=True, stdin=True,
                             stdout=True, tty=True,
                             _preload_content=False
                             )

        return cont_stream

여기에 포드의 이름이 될 수 있습니다 list_namespaced_pod다음과 같은 코드로 인수 :

def get_deployment_pod(self, RAND):
    api_instance = client.CoreV1Api()

    try:
        r = api_instance.list_namespaced_pod(
            namespace=self.namespace,
            label_selector="app=%s" % RAND
        )

        return True, r
    except Exception as e:
        return False, 'Get Deployment: ' + str(e)
        
state, data = self.get_deployment_pod(RAND)
pod_name = data.items[0].metadata.name

list_namespaced_pod윌은 여기에 나열된 네임 스페이스에서 모든 세부 사항 포드는 두 개의 매개 변수를 통과, 첫 번째는 namespace필수입니다, 우리는 네임 스페이스 포드, 두 번째 대표 목록에있는 label_selector네임 스페이스에서 설정 라벨을 기준으로 필터링 할 수있는, 비 본질적인을 우리가 배포시 생성하기 때문에 포드는 각각의 고유 한 추가됩니다 app=RAND그래서 여기에 우리가 포드에 해당하는 항목을 필터링 할 수 있습니다, 라벨

전개는 여러 포드에 대응할 수있다, 인수가 data.items모든 정보 포드, 목록 파일이 포함 된 이름은 얻을 필요 포드에 해당 할 수있다

장고 채널

도입 장고 채널 전에 세부 사항이 기사 캔에게 첫 번째보기를 이해하지 못하고있다 : 장고 WebSocket-- 부 달성하기 위해 채널을 사용 하고 장고 다음 WebSocket-- 달성하기 위해 채널을 사용하여 다음과 같이 코드의 가장 중요한 부분은

라우팅 코드 :

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter

from django.urls import path, re_path
from medivh.consumers import SSHConsumer

application = ProtocolTypeRouter({
    'websocket': AuthMiddlewareStack(
        URLRouter([
            re_path(r'^pod/(?P<name>\w+)', SSHConsumer),
        ])
    ),
})

일치하는 모든 일반 pod시작이라는라고 연결된 웹 소켓 SSHConsumer, 소비자의 처리는 다음과 같이 소비자 코드는 다음과 같습니다

from channels.generic.websocket import WebsocketConsumer
from medivh.backends.kube import KubeApi
from threading import Thread

class K8SStreamThread(Thread):
    def __init__(self, websocket, container_stream):
        Thread.__init__(self)
        self.websocket = websocket
        self.stream = container_stream

    def run(self):
        while self.stream.is_open():
            if self.stream.peek_stdout():
                stdout = self.stream.read_stdout()
                self.websocket.send(stdout)

            if self.stream.peek_stderr():
                stderr = self.stream.read_stderr()
                self.websocket.send(stderr)
        else:
            self.websocket.close()


class SSHConsumer(WebsocketConsumer):
    def connect(self):
        self.name = self.scope["url_route"]["kwargs"]["name"]

        # kube exec
        self.stream = KubeApi().pod_exec(self.name)
        kub_stream = K8SStreamThread(self, self.stream)
        kub_stream.start()

        self.accept()

    def disconnect(self, close_code):
        self.stream.write_stdin('exit\r')

    def receive(self, text_data):
        self.stream.write_stdin(text_data)

WebSSH는 웹 소켓 긴 각 연결이 설정된 후 간단한 접속으로 볼 독립적이며 다른 연결과 데이터를 공유하지 않기 때문에 그룹을 사용할 필요가 없습니다 수 있습니다

연결이를 통해 설정되면 self.scopeURL 이름에 인수, 새로운 데이터의 연속 사이클이 생성되는 경우가 웹 소켓으로 전송되는 경우는 Kubernetes API는, 또한, 새 스레드를 재생됩니다 통과

데이터는 Kubernetes의 웹 소켓 API를 작성 직접 수신되면, 폐쇄 웹 소켓은 송신된다 exit는 Kubernetes 명령을

프론트 페이지

메인의 선단부 전체 코드는 비교적 간단 xterm.js 사용

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Alodi | Pod Web SSH</title>
  <link rel="Shortcut Icon" href="/static/img/favicon.ico">
  
  <link href="/static/plugins/xterm/xterm.css" rel="stylesheet" type="text/css"/>
  <link href="/static/plugins/xterm/addons/fullscreen/fullscreen.css" rel="stylesheet" type="text/css"/>
</head>

<body>
  <div id="terminal"></div>
</body>

<script src="/static/plugins/xterm/xterm.js"></script>
<script src="/static/plugins/xterm/addons/fullscreen/fullscreen.js"></script>
<script>
  var term = new Terminal({cursorBlink: true});
  term.open(document.getElementById('terminal'));

  // xterm fullscreen config
  Terminal.applyAddon(fullscreen);
  term.toggleFullScreen(true);

  var socket = new WebSocket(
    'ws://' + window.location.host + '/pod/{{ name }}');

  socket.onopen = function () {
    term.on('data', function (data) {
        socket.send(data);
    });

    socket.onerror = function (event) {
      console.log('error:' + e);
    };

    socket.onmessage = function (event) {
      term.write(event.data);
    };

    socket.onclose = function (event) {
      term.write('\n\r\x1B[1;3;31msocket is already closed.\x1B[0m');
      // term.destroy();
    };
  };
</script>
</html>

term.open터미널 초기화

term.on콘텐츠 백엔드에 대한 모든 실시간 전송을 입력합니다

도입이 전체 화면을 구성 할 수 있습니다 후 xterm.js는 전체 화면 플러그인을 가지고, 또는 터미널 창 페이지의 일부가 될 수 있습니다

현재 여전히 문제가 윈도우가 해결되지 크기를 조정할 수 없습니다 경험, 예비 판단은 백 엔드 데이터는 Kubernetes 결정, 쿼리 관련 정보는 찾아 반환 kubectl추가하여 명령을 COLUMNS하고 LINESENV 설정

#!/bin/sh
if [ "$1" = "" ]; then
  echo "Usage: kshell <pod>"
  exit 1
fi
COLUMNS=`tput cols`
LINES=`tput lines`
TERM=xterm
kubectl exec -i -t $1 env COLUMNS=$COLUMNS LINES=$LINES TERM=$TERM bash

그러나 스트림는 Kubernetes 파이썬 API는 당신이 알고있는 경우에, 저에게 문제를 이야기, 장소를 찾기 위해 구성되어 있지 않습니다


관련 기사 추천 도서 :

추천

출처blog.csdn.net/dengyu810/article/details/102661791