Как подключиться к хосту MySQL из экземпляра локальной док-станции AWS SAM?
Я пытаюсь вызвать свою функцию Lambda с помощью sam local invoke
но обнаруживаю, что он не может подключиться к моему хосту MySQL. Я попытался добавить --docker-network host
но он также не может подключиться
Traceback (most recent call last):
File "/usr/lib/python3.6/site-packages/docker/api/client.py", line 229, in _raise_for_status
response.raise_for_status()
File "/usr/lib/python3.6/site-packages/requests/models.py", line 935, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: http+docker://localhost/v1.35/networks/6ad3bd87e8437e8410145d169a4edf68d1b0247a67257ce7dd1208dac3664c82/connect
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/bin/sam", line 11, in <module>
load_entry_point('aws-sam-cli==0.5.0', 'console_scripts', 'sam')()
File "/usr/lib/python3.6/site-packages/click/core.py", line 722, in __call__
return self.main(*args, **kwargs)
File "/usr/lib/python3.6/site-packages/click/core.py", line 697, in main
rv = self.invoke(ctx)
File "/usr/lib/python3.6/site-packages/click/core.py", line 1066, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/lib/python3.6/site-packages/click/core.py", line 1066, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/lib/python3.6/site-packages/click/core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/lib/python3.6/site-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/usr/lib/python3.6/site-packages/click/decorators.py", line 64, in new_func
return ctx.invoke(f, obj, *args[1:], **kwargs)
File "/usr/lib/python3.6/site-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/usr/lib/python3.6/site-packages/samcli/commands/local/invoke/cli.py", line 47, in cli
docker_network, log_file, skip_pull_image, profile) # pragma: no cover
File "/usr/lib/python3.6/site-packages/samcli/commands/local/invoke/cli.py", line 79, in do_cli
stderr=context.stderr)
File "/usr/lib/python3.6/site-packages/samcli/commands/local/lib/local_lambda.py", line 80, in invoke
stdout=stdout, stderr=stderr)
File "/usr/lib/python3.6/site-packages/samcli/local/lambdafn/runtime.py", line 83, in invoke
self._container_manager.run(container)
File "/usr/lib/python3.6/site-packages/samcli/local/docker/manager.py", line 61, in run
container.create()
File "/usr/lib/python3.6/site-packages/samcli/local/docker/container.py", line 115, in create
network.connect(self.id)
File "/usr/lib/python3.6/site-packages/docker/models/networks.py", line 57, in connect
container, self.id, *args, **kwargs
File "/usr/lib/python3.6/site-packages/docker/utils/decorators.py", line 19, in wrapped
return f(self, resource_id, *args, **kwargs)
File "/usr/lib/python3.6/site-packages/docker/api/network.py", line 248, in connect_container_to_network
self._raise_for_status(res)
File "/usr/lib/python3.6/site-packages/docker/api/client.py", line 231, in _raise_for_status
raise create_api_error_from_http_exception(e)
File "/usr/lib/python3.6/site-packages/docker/errors.py", line 31, in create_api_error_from_http_exception
raise cls(e, response=response, explanation=explanation)
docker.errors.APIError: 400 Client Error: Bad Request ("container cannot be disconnected from host network or connected to host network")
Я заметил последнюю строку:
docker.errors.APIError: 400 Client Error: Bad Request ("контейнер нельзя отключить от хост-сети или подключиться к сети хоста")
Как это исправить?
Ответы
Ответ 1
Я не могу сказать, почему --docker-network host
производит эту ошибку, но я не думаю, что вам это нужно. Я могу подключиться к MySQL, работающему на моем локальном компьютере, из локального SAM без каких-либо переопределений в сети.
Я делаю это, просто используя свой локальный IP (в отличие от localhost
или 127.0.0.1) для подключения к базе данных.
Следующая функция лямбда подключается к моему локальному MySQL просто отлично, если я использую свой локальный IP-адрес, так как обнаружил такой инструмент, как ipconfig
.
'use strict';
var mysql = require('mysql');
var connection = mysql.createConnection({
host : '192.168.1.6',
user : 'mike',
password : 'password',
database : 'logtest'
});
module.exports.hello = (event, context, callback) => {
connection.connect();
connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
if (error) throw error;
console.log('The solution is: ', results[0].solution);
const response = {
statusCode: 200,
body: JSON.stringify({solution: results[0].solution})
};
connection.end();
callback(null, response);
});
};
Частичный вывод ipconfig
:
Ethernet adapter Local Area Connection 6:
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : fe80::95c2:495c:7226:8ac2%39
IPv4 Address. . . . . . . . . . . : 10.251.19.6
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . :
Wireless LAN adapter Wireless Network Connection:
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : fe80::496a:d34d:8380:3b1c%15
IPv4 Address. . . . . . . . . . . : 192.168.1.6
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.1.1
В этом случае моя lambda-функция может подключаться к локальному MySQL с использованием 10.251.19.6 или 192.168.1.6.
Минимальный пример здесь.
Ответ 2
Не могли бы вы опубликовать, как вы запускаете MySQL контейнер локально? Трудно сказать, что не так с дополнительной информацией.
Вот несколько общих советов.
Если вы работаете на Mac
Вы можете просто использовать специальное имя хоста локально при настройке клиента mysql в контейнере, выполняющем вызов. Он будет разрешен локально без необходимости --docker-network
flag.
Пример:
host = 'docker.for.mac.localhost'
Или на более новых установках докера https://docs.docker.com/docker-for-mac/release-notes/#docker-community-edition-17120-ce-mac49-2018-01-19
host = 'docker.for.mac.host.internal'
Ex python code.
import mysql.connector
host = 'docker.for.mac.host.internal'
cnx = mysql.connector.connect(user='scott', password='password',
host=host,
database='employees')
cnx.close()
Если вы не на Mac
Затем убедитесь, что вы передаете --docker-network
когда запускаете контейнер MySQL, он должен выглядеть примерно так.
docker run -d -v "$PWD":/var/lib/mysql -p 3306:3306 \
--network lambda-local \
--name mysql \
mysql
Тогда при вызове локально
sam local invoke --docker-network lambda-local
Затем в своем лямбда-коде вы просто используете сеть --name
, передавая контейнер MySQL в качестве имени хоста.
Пример:
import mysql.connector
host = 'mysql'
cnx = mysql.connector.connect(user='scott', password='password',
host=host,
database='employees')
cnx.close()
Ответ 3
Вы можете проверить следующие случаи:
- Имеет ли порт докера портфолио.
- Проверьте порт группы безопасности AWS.