Die Geheimnisse des Container Runtime Interface: Streaming leicht gemacht!
Entdecken Sie, wie das Container Runtime Interface die Interaktion mit Containern revolutioniert und welche Vorteile die neuen RPCs bieten.
Das Kubernetes Container Runtime Interface (CRI) ist die zentrale Verbindung zwischen dem kubelet und der Container Runtime. Diese Runtimes müssen einen gRPC-Server bereitstellen, der eine von Kubernetes definierte Protocol Buffer-Schnittstelle erfüllt. Diese API-Definition entwickelt sich im Laufe der Zeit weiter, wenn beispielsweise neue Funktionen hinzugefügt oder Felder veraltet werden.
In diesem Blogbeitrag möchte ich die Funktionalität und die Geschichte von drei außergewöhnlichen Remote Procedure Calls (RPCs) beleuchten, die in ihrer Funktionsweise wirklich herausragend sind: Exec
, Attach
und PortForward
.
Exec kann verwendet werden, um bestimmte Befehle innerhalb des Containers auszuführen und die Ausgabe an einen Client wie kubectl oder crictl zu streamen. Es ermöglicht auch die Interaktion mit diesem Prozess über die Standard-Eingabe (stdin), beispielsweise wenn Benutzer eine neue Shell-Instanz innerhalb einer bestehenden Arbeitslast ausführen möchten.
Attach streamt die Ausgabe des aktuell laufenden Prozesses über Standard I/O vom Container an den Client und ermöglicht ebenfalls die Interaktion mit ihnen. Dies ist besonders nützlich, wenn Benutzer sehen möchten, was im Container vor sich geht, und mit dem Prozess interagieren möchten.
PortForward kann genutzt werden, um einen Port vom Host zum Container weiterzuleiten, um mit ihm über Drittanbieter-Netzwerktools zu interagieren. So kann er die Kubernetes-Services für eine bestimmte Arbeitslast umgehen und mit ihrer Netzwerkschnittstelle interagieren.
Was ist so besonders an ihnen?
Alle RPCs des CRI verwenden entweder die gRPC unary calls zur Kommunikation oder die Funktion des Server-Seiten-Streaming (nur GetContainerEvents
momentan). Das bedeutet, dass hauptsächlich alle RPCs eine einzelne Client-Anfrage abrufen und eine einzelne Server-Antwort zurückgeben müssen. Das gilt auch für Exec
, Attach
und PortForward
, deren Protokolldefinition wie folgt aussieht:
protobuf
// Exec prepares a streaming endpoint to execute a command in the container.
rpc Exec(ExecRequest) returns (ExecResponse) {}
protobuf
// Attach prepares a streaming endpoint to attach to a running container.
rpc Attach(AttachRequest) returns (AttachResponse) {}
protobuf
// PortForward prepares a streaming endpoint to forward ports from a PodSandbox.
rpc PortForward(PortForwardRequest) returns (PortForwardResponse) {}
Die Anfragen enthalten alles, was erforderlich ist, damit der Server die Arbeit ausführen kann, beispielsweise die ContainerId
oder den Befehl (Cmd
), der im Fall von Exec
ausgeführt werden soll. Interessanterweise enthalten alle ihre Antworten nur eine url
:
protobuf
message ExecResponse {
// Fully qualified URL of the exec streaming server.
string url = 1;
}
protobuf
message AttachResponse {
// Fully qualified URL of the attach streaming server.
string url = 1;
}
protobuf
message PortForwardResponse {
// Fully qualified URL of the port-forward streaming server.
string url = 1;
}
Warum ist das so implementiert? Nun, das ursprüngliche Entwurfsdokument für diese RPCs stammt sogar aus einer Zeit vor den Kubernetes Enhancements Proposals (KEPs) und wurde ursprünglich bereits 2016 skizziert. Der kubelet hatte eine native Implementierung für Exec
, Attach
und PortForward
, bevor die Initiative zur Einführung dieser Funktionalitäten ins Leben gerufen wurde.
Bei ayedo sind wir stolz darauf, als Kubernetes-Partner an der Spitze dieser Entwicklungen zu stehen und unseren Kunden dabei zu helfen, das volle Potenzial von Kubernetes auszuschöpfen.
Quelle: Kubernetes Blog