Ich möchte Docker Remote API von Python Requests verwenden. Es kann von TCP aus verwendet werden, wenn es verschlüsselt ist. Da wir jedoch daran denken, die API vom selben Host aus zu verwenden, verwenden wir den Unix-Socket.
Die Docker-Socket-Datei befindet sich in / var / run / docker.sock
. Das Lesen und Schreiben von Socket-Dateien ist wie folgt.
import socket
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect("/var/run/docker.sock")
# s.recv, s.send, etc.
Dies ist ziemlich ärgerlich und erfordert die Implementierung von Transport Adapter. Zu diesem Zweck müssen PoolManager, HTTPConnectionPool und HTTPConnection zusammen implementiert werden.
import socket
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3 import PoolManager, HTTPConnectionPool
from httplib import HTTPConnection
class MyAdapter(HTTPAdapter):
def __init__(self, sockfile, **kwargs):
self._sockfile = sockfile
super(MyAdapter, self).__init__(**kwargs)
def init_poolmanager(self, connections, maxsize, **kwargs):
self.poolmanager = MyPoolManager(self._sockfile,
num_pools=connections, maxsize=maxsize)
class MyPoolManager(PoolManager):
def __init__(self, sockfile, **kwargs):
self._sockfile = sockfile
super(MyPoolManager, self).__init__(**kwargs)
def _new_pool(self, scheme, host, port):
return MyConnectionPool(self._sockfile, host, port, **self.connection_pool_kw)
class MyConnectionPool(HTTPConnectionPool):
def __init__(self, sockfile, host, port, **kwargs):
self._sockfile = sockfile
super(MyConnectionPool, self).__init__(host, port, **kwargs)
def _new_conn(self):
self.num_connections += 1
return MyConnection(self._sockfile,
host=self.host, port=self.port, strict=self.strict)
class MyConnection(HTTPConnection):
def __init__(self, sockfile, **kwargs):
self._sockfile = sockfile
HTTPConnection.__init__(self, **kwargs)
def connect(self):
self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self.sock.connect(self._sockfile)
if self._tunnel_host:
self._tunnel()
Beachten Sie, dass HTTPConnection eine alte Klasse ist. Seien Sie also vorsichtig mit der Initialisierungsmethode.
Das Verwendungsbeispiel lautet wie folgt.
req = requests.Session()
req.mount("http://", MyAdapter("/var/run/docker.sock"))
print req.get("http://127.0.0.1/images/json?all=0").json()
Der Ort, an dem es als http://127.0.0.1 geschrieben ist, ist nicht gut ...
Recommended Posts