关于如何以分离模式运行容器存在许多问题。
我的问题有点特定于在分离模式容器中运行Atlassian Bitbucket服务器。
我尝试了下面作为我的dockerfile中的最后一层,当我用-d运行容器时,进程没有启动
运行/opt/atlassian-bitbucket/bin/start-bitbucket.sh
我尝试使用如下的ENTRYPOINT
ENTRYPOINT [“/opt/atlassian-bitbucket/bin/start-bitbucket.sh”]
但是容器总是在启动脚本完成后退出。
不确定是否有人在容器中设置了Bitbucket数据中心,但我很想知道他们如何运行同一图像的多个容器并使它们加入一个集群。
完全披露:我为Atlassian Premier Support工作,与我们的Bitbucket Server团队密切合作,并且在过去几年中一直是atlassian/bitbucket-server
Docker映像的主要维护者。
第一:使用我们的official image,我们多年来解决了许多问题,而不是试图从头开始使用我们的基础。
第二:您确实可以在Docker中运行数据中心集群。我的个人测试环境包括3个集群节点和几个智能镜像,全部使用官方图像,前面的HAProxy充当负载平衡器,外部Elasticsearch实例管理搜索。查看上面的README以获取常用配置选项列表 - 可以通过传递环境变量来设置您可能需要的选项
这是我很久以前为我们自己的内部支持团队整理的简单教程。它使用自定义的HAProxy Docker容器为您提供开箱即用的负载均衡器。它适用于在单个主机上进行测试,因此如果您想要执行与生产部署不同或更接近的操作,则不会涵盖这一点。
这里有很多内容,所以让我们从基础开始。
有几种方法可以连接各个Docker容器,以便它们可以找到彼此并进行通信(例如--link
参数),但Docker网络是迄今为止最灵活的。通过专用网络,我们得到以下信息:
--name
参数定义)找到彼此。然而,与真实DNS不同,当容器关闭时,其DNS解析不再存在。这可能会导致像HAProxy这样的服务出现一些问题 - 但我们稍后会讨论这个问题。另外值得注意的是,这不会设置机器的主机名,如果需要,需要单独设置。Docker网络没有做的一件事是将主机连接到其网络,因此您(用户)无法通过容器名称连接到容器,您仍然需要将端口发布到本地计算机。但是,在某些情况下,这样做既有用又必要。最简单的解决方法是向hosts文件添加条目,指向您希望访问环回地址的每个容器名称,127.0.0.1
要创建Docker网络,请运行以下命令。在我的例子中,我们将命名我们的网络atlasNetwork。如果要使用其他名称,请记住在所有后续docker命令中更改网络名称。
docker network create --driver bridge \
--subnet=10.255.0.0/16 \
atlasNetwork
在这里,我们使用桥驱动程序创建网络 - 这是最简单的网络类型。更复杂的网络类型允许网络跨越多个主机。我们还手动指定了子网 - 如果我们将其删除,Docker将随机选择一个,并且它可能与现有网络子网冲突,因此最安全的选择我们自己的子网。我们还指定了一个/ 16掩码,允许我们在最后两个八位字节内使用IP地址范围 - 这将在以后出现!
诸如$BITBUCKET_HOME
之类的持久性数据或您的数据库文件需要存储在容器本身之外的某个位置。对于我们的测试环境,我们可以直接将这些存储在主机,我们的本地操作系统上。这意味着我们可以使用我们喜欢的文本编辑器编辑配置文件,这非常方便!在下面的示例中,我们将把数据文件存储在~/dockerdata
文件夹中。无需创建此文件夹或任何子文件夹,因为Docker会自动执行此操作。如果要使用其他文件夹,请务必更新以下示例。
您可能想知道为什么我们不使用Docker的命名卷而不是在主机上安装文件夹。命名卷是一种更易于管理的抽象,通常建议使用;但是,出于测试环境的目的(特别是在Docker for Mac上,您无法直接访问虚拟化文件系统),能够直接检查每个容器的持久数据有很大的实际好处。您可能希望在Bitbucket或Postgres或HAProxy中编辑许多配置文件,这在使用命名卷时可能很困难,因为它要求您在容器中打开shell - 并且许多容器不包含基本文本编辑器实用程序(甚至不是vi!)。但是,如果您更喜欢使用卷,则只需在以下所有示例中使用命名卷替换主机文件夹即可。
我们网络上需要的第一项服务是数据库。让我们创建一个Postgres实例:
docker run -d \
--name postgres \
--restart=unless-stopped \
-e POSTGRES_PASSWORD=mysecretpassword \
-e PGDATA=/var/lib/postgresql/data/pgdata \
-v ~/dockerdata/postgres:/var/lib/postgresql/data/pgdata \
--network=atlasNetwork \
-p 5432:5432 \
postgres:latest
让我们来看看我们在这里做了什么:
-d
运行容器并从中分离(返回提示符)。如果没有此选项,当容器启动时,我们将直接连接到其标准输出,取消将停止容器。--name postgres
将容器的名称设置为postgres,它也充当我们网络上的DNS记录。--restart=unless-stopped
将容器设置为在Docker启动时自动启动,除非您已明确停止容器。这样,当您重新启动计算机时,Postgres会自动重新启动-e POSTGRES_PASSWORD=mysecretpassword
将默认postgres用户的密码设置为mysecretpassword-e PGDATA=/var/lib/postgresql/data/pgdata
官方Postgres泊坞窗图像建议在将数据文件夹安装到外部卷时指定此自定义位置-v ~/dockerdata/postgres:/var/lib/postgresql/data/pgdata
将容器内的文件夹/var/lib/postgresql/data/pgdata
安装到位于~/dockerdata/postgres
主机上的外部卷。此文件夹将自动创建--network=atlasNetwork
将容器连接到我们的自定义Docker网络-p 5432:5432
将Postgres端口发布到主机,因此我们可以访问localhost:5432
上的Postgres。对于其他容器来说,访问服务并不是必需的,但我们有必要这样做postgres:latest
官方Postgres码头图片的最新版本运行命令,嘿presto,您现在可以访问功能完善的Postgres实例。为了保持一致性,您可能希望在此处添加第一个主机条目:
127.0.0.1 postgres
现在,您和任何正在运行的容器都可以访问postgres:5432
上的实例。在继续之前,您应该使用您选择的数据库管理工具连接到您的数据库。使用用户名postgres,默认数据库postgres和密码mysecretpassword连接到主机名postgres,并创建一个准备好的Bitbucket数据库:
CREATE USER bitbucket WITH PASSWORD 'bitbucket';
CREATE DATABASE bitbucket WITH OWNER bitbucket ENCODING 'UTF8';
如果您没有方便的数据库管理工具,可以使用docker exec直接在容器中运行psql来创建数据库:
# We need to run two commands because psql won't let
# you run CREATE DATABASE from a multi-command string
docker exec -it postgres psql -U postgres -c \
"CREATE USER bitbucket WITH PASSWORD 'bitbucket';"
docker exec -it postgres psql -U postgres -c \
"CREATE DATABASE bitbucket WITH OWNER bitbucket ENCODING 'UTF8';"
我们将设置的下一个服务是Elasticsearch。我们需要一个我们所有数据中心节点都可以访问的专用实例。我们有很多关于如何安装兼容版本,配置它以便与Bitbucket一起使用以及安装Atlassian的buckler安全插件的说明:安装和配置远程Elasticsearch实例那么我们如何在Docker中设置它?嗯,这很简单:
docker pull dchevell/bitbucket-elasticsearch:latest
docker run -d \
--name elasticsearch \
-e AUTH_BASIC_USERNAME=bitbucket \
-e AUTH_BASIC_PASSWORD=mysecretpassword \
-v ~/dockerdata/elastic:/usr/share/elasticsearch/data \
--network=atlasNetwork \
-p 9200:9200 \
dchevell/bitbucket-elasticsearch:latest
简单地说,dchevell/bitbucket-elasticsearch
是一个预配置的Docker镜像,它是根据Atlassian的Install and configure a remote Elasticsearch instance知识库文章中的说明设置的。为您安装了Atlassian的Buckler安全插件,您可以使用上面显示的环境变量配置用户名和密码。我们再次将数据卷安装到我们的主机上,将其加入我们的Docker网络,并发布一个端口,以便我们可以直接访问它。这仅用于故障排除目的,因此如果您想在本地Elasticsearch实例中浏览而不通过Bitbucket,则可以。
现在我们完成了,您可以添加第二个主机条目:
127.0.0.1 elasticsearch
接下来,我们将设置HAProxy。安装Bitbucket数据中心提供了一些示例配置,同样,我们有一个预配置的Docker镜像,可以为我们完成所有艰苦的工作。但首先,我们需要首先弄清楚一些事情。 HAProxy与Docker网络的DNS系统不兼容。在现实世界中,如果系统关闭,DNS记录仍然存在,连接将超时。 HAProxy正好处理这种情况。但是在Docker网络中,当容器停止时,其DNS记录不再存在,并且与它的连接失败并显示“未知主机”错误。发生这种情况时,HAProxy将无法启动,这意味着我们无法将其配置为按容器名称代理与节点的连接。相反,我们需要为每个节点提供一个静态IP地址,并将HAProxy配置为使用IP地址。
即使我们还没有创建节点,我们现在可以决定它们的IP地址。我们的Docker网络的子网是10.255.0.0/16
,Docker将在最后一个八位字节上动态分配容器地址(例如10.255.0.1
,10.255.0.2
等)。由于我们知道这一点,我们可以使用倒数第二个八位字节安全地为我们的Bitbucket节点分配静态IP地址:
10.255.1.1
10.255.1.2
10.255.1.3
除此之外,还有一件事。 HAProxy将成为我们实例的代表,因此它的容器名称将代表我们用来访问实例的URL。在这个例子中,我们将其称为bitbucketdc。我们还要将机器的主机名设置为相同。
docker run -d \
--name bitbucketdc \
--hostname bitbucketdc \
-v ~/dockerdata/haproxy:/usr/local/etc/haproxy \
--network=atlasNetwork \
-e HTTP_NODES="10.255.1.1:7990,10.255.1.2:7990,10.255.1.3:7990" \
-e SSH_NODES="10.255.1.1:7999,10.255.1.2:7999,10.255.1.3:7999" \
-p 80:80 \
-p 443:443 \
-p 7999:7999 \
-p 8001:8001 \
dchevell/bitbucket-haproxy:latest
在上面的示例中,我们将未来Bitbucket节点的HTTP端点以及SSH端点指定为逗号分隔列表。容器会将其转换为有效的HAProxy配置。代理服务将在端口80和端口443上提供,因此我们将两者一起发布。此容器配置为根据计算机的主机名自动生成自签名SSL证书,因此我们可以使用开箱即用的HTTPS访问权限。
由于我们也代理SSH,我们还发布了Bitbucket Server的默认SSH端口7999。您会注意到我们还发布了端口8001.这是为了访问HAProxy的Admin界面,因此我们可以监控在任何给定时间检测到哪些节点为up或down。
最后,我们将HAProxy的config文件夹安装到数据卷。这不是必需的,但它可以让你直接访问haproxy.cfg,这样你就可以了解那里的配置选项。
现在是我们第三次进入主机的时候了。这是因为它会影响基本URL访问等内容,因此绝对需要
127.0.0.1 bitbucketdc
最后,我们准备创建我们的Bitbucket节点。由于这些都将通过负载均衡器进行访问,因此我们不必发布任何端口。但是,出于故障排除和测试目的,有时您需要直接命中特定节点,因此我们将每个节点发布到不同的本地端口,以便我们可以在需要时直接访问它。
docker run -d \
--name=bitbucket_1 \
-e ELASTICSEARCH_ENABLED=false \
-e HAZELCAST_NETWORK_MULTICAST=true \
-e HAZELCAST_GROUP_NAME=bitbucket-docker \
-e HAZELCAST_GROUP_PASSWORD=bitbucket-docker \
-e SERVER_PROXY_NAME=bitbucketdc \
-e SERVER_PROXY_PORT=443 \
-e SERVER_SCHEME=https \
-e SERVER_SECURE=true \
-v ~/dockerdata/bitbucket-shared:/var/atlassian/application-data/bitbucket/shared \
--network=atlasNetwork \
--ip=10.255.1.1 \
-p 7001:7990 \
-p 7991:7999 \
atlassian/bitbucket-server:latest
docker run -d \
--name=bitbucket_2 \
-e ELASTICSEARCH_ENABLED=false \
-e HAZELCAST_NETWORK_MULTICAST=true \
-e HAZELCAST_GROUP_NAME=bitbucket-docker \
-e HAZELCAST_GROUP_PASSWORD=bitbucket-docker \
-e SERVER_PROXY_NAME=bitbucketdc \
-e SERVER_PROXY_PORT=443 \
-e SERVER_SCHEME=https \
-e SERVER_SECURE=true \
-v ~/dockerdata/bitbucket-shared:/var/atlassian/application-data/bitbucket/shared \
--network=atlasNetwork \
--ip=10.255.1.2 \
-p 7002:7990 \
-p 7992:7999 \
atlassian/bitbucket-server:latest
docker run -d \
--name=bitbucket_3 \
-e ELASTICSEARCH_ENABLED=false \
-e HAZELCAST_NETWORK_MULTICAST=true \
-e HAZELCAST_GROUP_NAME=bitbucket-docker \
-e HAZELCAST_GROUP_PASSWORD=bitbucket-docker \
-e SERVER_PROXY_NAME=bitbucketdc \
-e SERVER_PROXY_PORT=443 \
-e SERVER_SCHEME=https \
-e SERVER_SECURE=true \
-v ~/dockerdata/bitbucket-shared:/var/atlassian/application-data/bitbucket/shared \
--network=atlasNetwork \
--ip=10.255.1.3 \
-p 7003:7990 \
-p 7993:7999 \
atlassian/bitbucket-server:latest
您可以看到我们在设置HAProxy时指定了我们决定的静态IP地址。是否为这些节点添加主机条目,或者只是通过localhost访问其端口,由您决定。由于没有其他容器需要通过主机名访问我们的节点,所以这不是必需的,我个人并没有打扰。
官方Docker镜像增加了设置仅限Docker变量ELASTICSEARCH_ENABLED=false
的功能,以防止Elasticsearch在容器中启动。官方docker镜像本身支持剩余的Hazelcast属性,因为Bitbucket 5基于Springboot,可以自动将环境变量转换为它们的等效点属性。
现在我们准备好了!
在https://bitbucketdc(或您选择的任何名称)上访问您的实例。添加数据中心评估许可证(您可以在https://my.atlassian.com上生成30天的许可证)并将其连接到Postgres数据库。登录,然后转到Server Admin并连接您的Elasticsearch实例(请记住,它在端口9200上运行,因此将Elasticsearch URL设置为http://elasticsearch:9200
并使用我们在创建Elasticsearch容器时配置的用户名和密码。
访问Server Admin中的Clustering部分,您应该看到那里的所有节点,证明Multicast正在工作且节点已经找到了彼此。
而已!您的数据中心实例完全正常运行。您可以通过关闭除一个节点之外的所有节点将其用作日常实例,并将其简单地用作单节点测试实例 - 然后,只要您需要,打开其他节点。
看官方码头图片:https://hub.docker.com/r/atlassian/bitbucket-server/
赶紧跑:
docker run -v /data/bitbucket:/var/atlassian/application-data/bitbucket --name="bitbucket" -d -p 7990:7990 -p 7999:7999 atlassian/bitbucket-server
你也可以看一下官方的dockerfile:https://hub.docker.com/r/atlassian/bitbucket-server/dockerfile