背景描述
随着容器化进程的加速,相比于传统虚拟机存在的巨大优势,分布式云计算的兴起,以docker为代表的容器化技术解决方案越来越流行。作为一种不算新兴技术的技术,毕竟docker所用到的技术在早很多年就存在,只是docker的出现让这些技术真正的组合在了一起,并开始发挥效用。docker相比于虚拟机的解决方案使用更少的宿主机资源,可扩展性更加优秀,相比于单独的软件安装,出现的问题更少,更容易部署。
尤其是在当前微服务架构以及云计算当道的时代下,docker更有其发挥长处的舞台。
问题描述
在开发的过程中。开始需要在项目中需要数据库来存储数据,以及作为多线程之间的一种解耦方法,初步计划从一下几种方式中做出选择。
安装单独的数据库,比如mysql,redis,或者Postgres,leveldb。
安装上述数据库的docker版本。
后来考虑到安装独立软件的复杂性,就采用了方案2,最开始本来想安装mysql的docker,但是发现web.py使用的连接mysql的驱动MySQLdb安装不上,原因是太老了,很久没有更新过了。于是,选择了docker版本的postgres。
但是在用独立的python脚本连接docker版本的postgres的时候出现了问题。本博客的主要目的就是解决单独的脚本,如何成功连接容器内的数据库。
环境设置
今年双十一的时候购买了最便宜的阿里云,单核2G,40G硬盘空间,三年300块。当然普通的Linux环境也可以测试这个功能。需要注意的是,阿里云默认占用80端口号,阿里云盾占用了这个端口,所使用的web.py框架需要这个端口,关闭阿里云盾。本博客默认使用了阿里云服务器。
首先,更新一下服务器,安装对应的软件
更新服务器(我的服务器实例是centos)。
yum update
yum install *
安装python2.7(服务器默认安装)。
yum install python***(Google)
安装pip
安装web.py,用于连接Postgres的测试。
pip install web.py
创建python测试脚本所在目录
mkdir wx
安装docker版本的Postgres读一读doc,直接安装。
# start a postgres instance命令来自上述的链接,下边的命令意思是用docker运行了一个Postgres实例,容器的名字叫做some-postgres(可修改),密码是mysecretpassword(可修改),默认简历的数据库是postgres,默认的用户名是postgres,默认暴露的端口是127.0.0.1
docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres
安装对应的python驱动。
pip install psycopg2
在上述wx目录下写如下脚本
# sql.py
imoprt psycopg2
try:
connection = psycopg2.connect(user = "postgres",
password = "root",
host = "127.0.0.1",
port = "5432",
database = "postgres")
cursor = connection.cursor()
# Print PostgreSQL Connection properties
print ( connection.get_dsn_parameters(),"\n")
# Print PostgreSQL version
cursor.execute("SELECT version();")
record = cursor.fetchone()
print("You are connected to - ", record,"\n")
except (Exception, psycopg2.Error) as error :
print ("Error while connecting to PostgreSQL", error)
finally:
#closing database connection.
if(connection):
cursor.close()
connection.close()
print("PostgreSQL connection is closed")
问题诊断
用上述的脚本运行,得到结果如下:
python sql.py
/usr/lib64/python2.7/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>.
""")
('Error while connecting to PostgreSQL', OperationalError('could not connect to server: Connection refused\n\tIs the server running on host "127.0.0.1" and accepting\n\tTCP/IP connections on port 5432?\n',))
Traceback (most recent call last):
File "sql.py", line 22, in <module>
if(connection):
NameError: name 'connection' is not defined
前半部分的psycopg2-binary可以不予以关注,只是告诉我们这个驱动以后可能不叫这个名字了,我们暂且不管,毕竟现在可以用。
后边逐渐诊断,发现问题在于,postgres的IP不是localhost,而是docker分配的某一个IP。
那么,问题变成了,docker用的IP是什么呢?
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
81bac6277944 postgres "docker-entrypoint..." 18 hours ago Up 18 hours 5432/tcp postgres
可以注意到上边运行的容器实例,注意我的本机容器的名字是postgres。
需要查看一下这个容器实例的信息:
docker inspect postgres
"NetworkSettings": {
"Bridge": "",
"SandboxID": "131fea24669611632eb4fdceb4c475c246a7e5ffa25746defd3c4ab45d93d55f",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"5432/tcp": null
},
"SandboxKey": "/var/run/docker/netns/131fea246696",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "5d2a5af617dc56c11f95b874cd6e61a5f410d00b20c62e4ec1c12d13057c6234",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.4",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:04",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "e91322f0782411ef7fdb56da968e30b8c0d19c95894f8fef993431c197660239",
"EndpointID": "5d2a5af617dc56c11f95b874cd6e61a5f410d00b20c62e4ec1c12d13057c6234",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.4",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:04"
}
}
}
可以注意到IPAddress这个字段,这个字段标明了当前这个实例的网络相关参数,需要将上述的127.0.0.1 参数换成 172.17.0.4,这个参数需要根据实际的docker实例运行的实际参数进行设置,将参数更该之后运行上述sql.py脚本。
[root@izm5eezkmfgg9tyd15gha9z wx]# python sql.py
/usr/lib64/python2.7/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>.
""")
({'tty': '', 'sslcompression': '0', 'dbname': 'postgres', 'options': '', 'host': '172.17.0.4', 'target_session_attrs': 'any', 'user': 'postgres', 'sslmode': 'prefer', 'port': '5432', 'krbsrvname': 'postgres'}, '\n')
('You are connected to - ', ('PostgreSQL 11.1 (Debian 11.1-1.pgdg90+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516, 64-bit',), '\n')
PostgreSQL connection is closed
可以注意到,python脚本链接docker的postgres成功。
Note:
这个策略在Linux发行版上是成功的。
在Mac 版本上是失败的,由于在Mac宿主机上根本就ping不通容器的IP,完善有相关的教程解决这个问题。我自己没有尝试。参考,还有理论。
Windows环境没有尝试,原因是由于我自己的机子是win7,只能使用dockerToolbox,并且没有安装成功。于是放弃。
————————————————
原文链接:https://blog.csdn.net/u011233383/article/details/84387717
个人微信公众号:杂感123