SAM CLI 无法在 Docker 桌面上与 Windows 的 SSL 通信

SAM CLI cant talk to SSL on Docker Desktop for Windows

我之前安装了 docker-toolbox,现在安装了 docker for desktop 并启用了 linux wsl2 容器。

我正在尝试使用 aws-sam-cli 在我的项目根文件夹中使用以下命令测试我的 hello world lambda 函数:

sam local start-api --debug

这在控制台中给出了以下输出:

2021-07-19 16:00:39,772 | Telemetry endpoint configured to be https://aws-serverless-tools-telemetry.us-west-2.amazonaws.com/metrics
2021-07-19 16:00:39,774 | Using config file: samconfig.toml, config environment: default
2021-07-19 16:00:39,774 | Expand command line arguments to:
2021-07-19 16:00:39,774 | --template_file=F:\upwork\code\dynamodb-lambda-local\.aws-sam\build\template.yaml --host=127.0.0.1 --port=3000 --static_dir=public --layer_cache_basedir=C:\Users\Administrator\AppData\Roaming\AWS SAM\layers-pkg --container_host=localhost --container_host_interface=127.0.0.1
2021-07-19 16:00:40,191 | local start-api command is called
2021-07-19 16:00:40,199 | No Parameters detected in the template
2021-07-19 16:00:40,237 | 3 stacks found in the template
2021-07-19 16:00:40,237 | No Parameters detected in the template
2021-07-19 16:00:40,265 | 3 resources found in the stack
2021-07-19 16:00:40,266 | No Parameters detected in the template
2021-07-19 16:00:40,294 | Found Serverless function with name='HelloWorldFunction' and CodeUri='HelloWorldFunction'
2021-07-19 16:00:40,294 | --base-dir is not presented, adjusting uri HelloWorldFunction relative to F:\upwork\code\dynamodb-lambda-local\.aws-sam\build\template.yaml
2021-07-19 16:00:40,336 | Docker is not reachable
Traceback (most recent call last):
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\urllib3\connectionpool.py", line 699, in urlopen
    httplib_response = self._make_request(
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\urllib3\connectionpool.py", line 382, in _make_request
    self._validate_conn(conn)
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\urllib3\connectionpool.py", line 1010, in _validate_conn
    conn.connect()
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\urllib3\connection.py", line 411, in connect
    self.sock = ssl_wrap_socket(
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\urllib3\util\ssl_.py", line 453, in ssl_wrap_socket
    ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls)
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\urllib3\util\ssl_.py", line 495, in _ssl_wrap_socket_impl
    return ssl_context.wrap_socket(sock)
  File "ssl.py", line 500, in wrap_socket
  File "ssl.py", line 1040, in _create
  File "ssl.py", line 1309, in do_handshake
ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1125)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\requests\adapters.py", line 439, in send
    resp = conn.urlopen(
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\urllib3\connectionpool.py", line 755, in urlopen
    retries = retries.increment(
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\urllib3\util\retry.py", line 574, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='127.0.0.1', port=2375): Max retries exceeded with url: /v1.35/_ping (Caused by SSLError(SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1125)')))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\samcli\local\docker\utils.py", line 89, in is_docker_reachable
    docker_client.ping()
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\docker\client.py", line 187, in ping
    return self.api.ping(*args, **kwargs)
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\docker\api\daemon.py", line 166, in ping
    return self._result(self._get(self._url('/_ping'))) == 'OK'
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\docker\utils\decorators.py", line 46, in inner
    return f(self, *args, **kwargs)
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\docker\api\client.py", line 230, in _get
    return self.get(url, **self._set_request_timeout(kwargs))
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\requests\sessions.py", line 555, in get
    return self.request('GET', url, **kwargs)
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\requests\sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\requests\sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "C:\Program Files\Amazon\AWSSAMCLI\runtime\lib\site-packages\requests\adapters.py", line 514, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='127.0.0.1', port=2375): Max retries exceeded with url: /v1.35/_ping (Caused by SSLError(SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1125)')))
Error: Running AWS SAM projects locally requires Docker. Have you got it installed and running?

我已经试过了,用于在客户端和服务器端接受双重 SSL 行为。 https://docs.docker.com/engine/security/protect-access/#create-a-ca-server-and-client-keys-with-openssl 但卡在这里

docker --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem -H=0.0.0.0:2376 version
docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=172.17.0.2/16:2376 version

注意:dockerd 不适用于 windows。所以我将其替换为 docker [flags value] version.

在端口 2376 上,对于 运行 此 cmd

docker --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem -H=0.0.0.0:2376 version

我收到以下错误

error during connect: Get "https://0.0.0.0:2376/v1.24/version": dial tcp 0.0.0.0:2376: connectex: No connection could be made because the target machine actively refused it.

同样 在 2375 上:

http: server gave HTTP response to HTTPS client Client

在 5354 上:

wsarecv: An existing connection was forcibly closed by the remote host.

我无法找出根本原因,为什么会这样。是否由于端口占用,SSL错误。

这是我花了 1 整天的时间后对我有用的东西。

根据https://github.com/docker/for-win/issues/3546公认的解决方案

I had the same issue. By some reason Windows reserves port 2375:

netsh interface ipv4 show excludedportrange protocol=tcp
If you see that one of port ranges include port 2375 then you have the same issue.

Disable Hyper-V and reboot:

dism.exe /Online /Disable-Feature:Microsoft-Hyper-V
Then reserve port 2375:

netsh int ipv4 add excludedportrange protocol=tcp startport=2375 numberofports=1
Enable Hyper-V and reboot again:

dism.exe /Online /Enable-Feature:Microsoft-Hyper-V /All
Now it should be fine.

Also see this thread where I found this solution.

这让我想到这一切是因为 Docker 本身阻塞了 2375,并再次抱怨它不能保留 2375。Audacity。

所以我做了以下事情

  • 安装了最新的稳定版 Python -> Python3.9。 SAM CLI 使用 python,可能 docker 更新了 SSL 版本,SAM 使用不同的版本
  • 清理了环境。 DOCKER_*
  • 的变量
  • 已验证是否为 Docker
  • 保留了任何注册表项
  • 已重新安装Docker桌面已满
  • 使用 Docker 集线器登录。谷歌搜索时有人在某个地方提出建议
  • 没有选中 Docker 桌面设置中的复选框“在没有 TLS 的情况下在 tcp://localhost:2375 上公开守护程序”