Client: Version: 17.04.0-ce API version: 1.28 Go version: go1.7.5 Git commit: 4845c56 Built: Wed Apr 5 06:06:36 2017 OS/Arch: darwin/amd64
Server: Version: 17.04.0-ce API version: 1.28 (minimum version 1.12) Go version: go1.7.5 Git commit: 4845c56 Built: Tue Apr 4 00:37:25 2017 OS/Arch: linux/amd64 Experimental: true
Client 和 Server 除了本身的 Version 外还有一个 API Version。实时上 Docker 的 API 版本和代码的版本是完全相互独立的,虽然每个代码版本都会唯一对应一个 API 版本,但 API 版本并不会随着代码版本变更。我们翻看 Docker 官网的文档可以发现罗列的从 v1.1.8 开始的各个 API 版本。
每个版本所有 API 都属同一版本,用户可以通过 /info 来访问,也可以通过 /v1.28/info 来访问 API。
文档定义版本
看到如此多的 API 版本和复杂的变更,我们会想,在代码层面 Docker(moby) 项目是如何标记这么多版本的 API 兼容,变更,丢弃的呢?
答案是:并没有,除了极少数 API 在代码中会根据版本有特殊处理外,兼容、变更、丢弃都没有体现在代码里。
# docker/api/network.py classNetworkApiMixin(object): @minimum_version('1.21') defnetworks(self, names=None, ids=None, filters=None): """ List networks. Similar to the ``docker networks ls`` command. Args: names (:py:class:`list`): List of names to filter by ids (:py:class:`list`): List of ids to filter by filters (dict): Filters to be processed on the network list. Available filters: - ``driver=[<driver-name>]`` Matches a network's driver. - ``label=[<key>]`` or ``label=[<key>=<value>]``. - ``type=["custom"|"builtin"]`` Filters networks by type. Returns: (dict): List of network objects. Raises: :py:class:`docker.errors.APIError` If the server returns an error. """
if filters isNone: filters = {} if names: filters['name'] = names if ids: filters['id'] = ids params = {'filters': utils.convert_filters(filters)} url = self._url("/networks") res = self._get(url, params=params) return self._result(res, json=True)
我们注意到 networks 方法有一个 @minimum_version('1.21') 装饰器,根据文档的记述标记了 networks 是从哪个 API 版本开始引入的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# docker/utils/decorators.py defminimum_version(version): defdecorator(f): @functools.wraps(f) defwrapper(self, *args, **kwargs): if utils.version_lt(self._version, version): raise errors.InvalidVersion( '{0} is not available for version < {1}'.format( f.__name__, version ) ) return f(self, *args, **kwargs) return wrapper return decorator
在访问这些 API 的时候客户端会检测服务端的 API 版本是否满足最小版本要求,不满足则会报错。
1 2 3 4 5 6 7
if utils.version_lt(self._version, MINIMUM_DOCKER_API_VERSION): warnings.warn( 'The minimum API version supported is {}, but you are using' 'version {}. It is recommended you either upgrade Docker' 'Engine or use an older version of Docker SDK for' 'Python.'.format(MINIMUM_DOCKER_API_VERSION, self._version) )
Client 类实例化的时候通过指定或者访问 Docker 的 /version 接口自动得到 API 版本,并且会检查版本是否满足要求。