创建低成本的工作在VPC内网的OpenSearch单节点并配置用户名密码身份验证

摘要:本文介绍如何快速创建一个低成本的、工作在VPC内网的OpenSearch单节点集群,并允许Master用户密码身份验证,然后测试上传文档和搜索,并分别在VPC内网的EC2 Windows和开发者本机用Session Manager转发方式访问Kibana。

一、背景

1、关于OpenSearch

Amazon OpenSearch Service (以下简称AOS或OpenSearch)是一款开源的分布式搜索和分析套件,衍生自 Elasticsearch。Amazon OpenSearch Service 是 Amazon Elasticsearch Service 的后继者。引擎版本差异在这里。插件版本差异在这里。更多信息参考官网的FAQ页面这里(中文)。

2、关于多节点和单节点

当数据量较大时候,一般推荐使用OpenSearch独立的三个Master节点做高可用,搭配多个Data Node节点提升查询性能,然后将只读类的日志数据写入到独立的Ultrawarm温数据节点。

当数据量较小时候,使用OpenSearch仅需要存储少量数据作为开发辅助的日志调试工具,而非业务搜索引擎等重型数据库场景。此时,关注点一般是如何优化配置降低成本。此时可创建单节点的OpenSearch,其功能上是单节点同时包含Master Node、Data Node角色,并提供Kibana图形界面。

3、关于安全性

在网络模式上,OpenSearch可工作在Public互联网,并通过身份验证接受来自互联网应用程序的访问。OpenSearch也可以配置为VPC Only的模式,即只能通过VPC内网访问,外网没有入口。如此配置将大大提升OpenSearch的安全性。

在身份认证上,OpenSearch支持传统的用户名和密码的身份验证,也支持通过IAM User和对应的AccessKey/Secret Key的SignV4签名认证,还支持Cogonito认证,以及支持其他第三方SAML认证。一般从现有开发好的应用程序兼容性上考虑,为了减少上云的代码修改,可使用传统用户名密码身份验证。

4、本文场景

本文描述的就是这种数据量很小的场景,从节约成本角度考虑,创建一台单节点OpenSearch,并配置为仅从VPC内可访问,同时设置用户名和密码身份验证。

二、创建OpenSearch

1、创建安全规则组

首先进入EC2服务界面或者VPC服务界面,点击左侧菜单的Security Groups安全规则组界面。点击右上角创建按钮,为OpenSearch创建对应的安全规则组。

安全组规则如下:

  • 入站:允许来自本VPC网段(例如172.31.0.0/16)访问HTTPS协议(TCP 443端口)
  • 出战:允许去往0.0.0.0/0任意地址

将安全规则组保存为opensearch,后文将会使用。

2、创建OpenSearch集群

进入OpenSearch服务界面,点击左上角Dashboard按钮,点击右上角创建域Create domain按钮。继续向下滚动页面。如下截图。

在设置名称位置,输入名称,例如prod或者demo1。在创建方式的位置,不要选择默认的Easy create,因为这样将创建成本较高的多AZ版本。选择Standard create,即可按自定义方式创建低配的。继续向下滚动页面。如下截图。

在选择创建模版Template的位置,选择开发/测试即Dev/test,在部署选项Deployment option(s)的位置,选择Domain without standby。继续向下滚动页面。如下截图。

在Availability Zone(s)部分,选择1-AZ。继续向下滚动页面。如下截图。

在Engine version位置,选择最新版本,截止本文编写时候是OpenSearch 2.7。由于OpenSearch与Elastic Search高度兼容(如本文片头介绍的开源许可证变化),因此不需要可以选择老的7.10版本去兼容现有应用。基本上现有应用都可以直接使用OpenSearch 2.7版本来运行。此外下方的Include older versions包括历史版本这个选项不需要选中,以及Enable compatibility mode打开兼容模式这个选项也不需要选中。继续向下滚动页面。如下截图。

在机型选择位置,从下拉框中选择t3.medium.search机型,即2vCPU/4GB机型,是属于成本节约的机型选择。此外下拉框中还有一个更小的t3.small.search机型,即2vCPU/2GB,适合只用HTTPS程序接口不使用Kibana的场景。本文选择t3.medium.search。节点数量Number of nodes输入1。继续向下滚动页面。如下截图。

在磁盘配置界面,默认存储类型已经是EBS,无须修改。默认磁盘类型是General Purpose (SSD) - gp3,已经是成本最佳选择,默认提供3000IOPS,无须修改。在下方EBS storage size per node每个节点容量位置,输入20表示对应的GB容量。如果还需要分配更多的IOPS和吞吐,此时可以点击Advanced volume type options (IOPs and throughput configurations),展开详情菜单,继续给EBS gp3类型增加IOPS。本文不需要额外增加配置了,因此不展开这个菜单。继续向下滚动页面。如下截图。

Warm and cold data storage界面,无须调整。因为当前创建的是最小机型节省成本,因此不支持Ultrawarm特性。下方的Dedicated master node适合较大规模的集群使用,如果打开的话,会创建三台独立的Master节点用于接受和转发访问。本文创建的是成本节约的单节点,因此不打开这个选项。继续向下滚动页面。如下截图。

在快照配置Snapshot configuration界面无须修改。在Custom endpoint自定义终端节点位置,不需要选中,不要打开Enable custom endpoint,而是继续向下滚动页面。如下截图。

在网络配置界面,首先在网络模式上选择VPC Access(Recommended),这是因为只允许OpenSearch被当前VPC内的EC2上的应用访问是非常安全的。如果选择Public Access,那么OpenSearch会被暴露在互联网,仅靠用户名密码认证,存在被攻击的风险。接下来从下拉框中选择VPC,再选择OpenSearch所在的子网。建议选择一个私有子网。如果选择了一个公有子网的话,那么OpenSearch节点将依然有被外部网络访问的可能,所以请谨慎选择。最后选择本文第一步创建的额安全规则组。继续向下滚动页面。如下截图。

现在开始配置认证。点击Enable fine-grained access control开关,在下方Master username位置,输入用户名admin,在下方Master password位置输入密码(输入两次)。继续向下滚动页面。如下截图。

SAML Authentication for OpenSearch Dashboards/Kibana部分留空不用选中。在Amazon Cognito authentication部分留空不用选中。继续向下滚动页面。如下截图。

Access policy位置,选择第一项Only use-fine-grained access control(Allow open access to the domain)。注意这里所谓的Open access是需要上文设置的Master用户的用户名和密码的,并不是无密码的开放访问。继续向下滚动页面。如下截图。

在数据落盘加密的位置,选择Use AWS owned key。在维护窗口Off-peak window位置,输入起始时间0:00(UTC)。这里UTC 0点表示北京时间8点,因此这样设置维护窗口并不好。建议设置为18:00(UTC)即北京时间凌晨两点。请注意下边截图使用的0:00(UTC),请自行修改为您需要的时间。继续向下滚动页面。如下截图。

在是否启动自动软件升级位置,选中Enable automatic software update。建议开启自动升级,这样从安全性上较好。继续向下滚动页面。如下截图。

所有设置完成,可以点击创建按钮生成集群了。如下截图。

集群创建中。如下截图。

创建集群完成。如下截图。

三、使用Linux系统的EC2从VPC内网访问OpenSearch

1、从VPC内网访问OpenSearch和Kibana

由于选择了VPC内访问,后续的应用测试将使用EC2在VPC内来对OpenSearch发起压力。从互联网上是无法直接访问OpenSearch和Kibana的。这样使用VPC内访问是非常安全的,无须担心外部网络攻击。使用Linux系统的EC2,程序接口可通过Linux shell上的curl直接访问OpenSearch。

访问Kibana的时候,直接使用Windows系统上现代浏览器例如Firefox/Chrome/Edge等浏览器即可直接操作。如果当前系统是Linux的EC2默认没有图形GUI,就无法直接浏览Kibana了,此时可使用Sesison Manager功能,请参考下一章节介绍Session Manager。

2、从Linux EC2上通过VPC内网用curl访问OpenSearch

(1)获取访问Endpoint

首先获取OpenSearch的Endpoint。进入OpenSearch服务界面,从网页上找到标记为Domain Endpoint (VPC)。注意这里只复制即可,不要点击打开新浏览器窗口。因为OpenSeach被设置为只能从VPC访问,因此这里即便点击了新浏览器窗口,也是无法打开网页的。如下截图。

复制获得的Endpoint如下格式:

https://vpc-demo1-rtavdqgb4fq72otjlavglnlc3y.ap-southeast-1.es.amazonaws.com

(2)写入单个文件

在Linux shell上使用curl执行如下命令。需要注意的是Windows系统上的curl参数和Linux的curl参数写法不相同。本文的如下例子是按照Linux shell上的curl参数编写。

请替换如下命令中的admin密码为上文创建的密码,替换Endpoint地址为上文创建的地址。注意需要保留Endpoint后方movies/_doc/1的后缀,因为这是要上传的index文档。

curl -XPUT \
  -u 'admin:!qAzXsW2' \
  'https://vpc-demo1-rtavdqgb4fq72otjlavglnlc3y.ap-southeast-1.es.amazonaws.com/movies/_doc/1' \
  -H 'Content-Type: application/json' \
  -d '{"director": "Burton, Tim", "genre": ["Comedy","Sci-Fi"], "year": 1996, "actor": ["Jack Nicholson","Pierce Brosnan","Sarah Jessica Parker"], "title": "Mars Attacks!"}'

返回如下信息表示写入成功:

{"_index":"movies","_id":"1","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":0,"_primary_term":1}

(3)批量加载文件

在上一步操作的EC2上,将如下文件保存为bulk_movies.json,稍后用于批量上传。

{ "index" : { "_index": "movies", "_id" : "2" } }
{"director": "Frankenheimer, John", "genre": ["Drama", "Mystery", "Thriller", "Crime"], "year": 1962, "actor": ["Lansbury, Angela", "Sinatra, Frank", "Leigh, Janet", "Harvey, Laurence", "Silva, Henry", "Frees, Paul", "Gregory, James", "Bissell, Whit", "McGiver, John", "Parrish, Leslie", "Edwards, James", "Flowers, Bess", "Dhiegh, Khigh", "Payne, Julie", "Kleeb, Helen", "Gray, Joe", "Nalder, Reggie", "Stevens, Bert", "Masters, Michael", "Lowell, Tom"], "title": "The Manchurian Candidate"}
{ "index" : { "_index": "movies", "_id" : "3" } }
{"director": "Baird, Stuart", "genre": ["Action", "Crime", "Thriller"], "year": 1998, "actor": ["Downey Jr., Robert", "Jones, Tommy Lee", "Snipes, Wesley", "Pantoliano, Joe", "Jacob, Ir\u00e8ne", "Nelligan, Kate", "Roebuck, Daniel", "Malahide, Patrick", "Richardson, LaTanya", "Wood, Tom", "Kosik, Thomas", "Stellate, Nick", "Minkoff, Robert", "Brown, Spitfire", "Foster, Reese", "Spielbauer, Bruce", "Mukherji, Kevin", "Cray, Ed", "Fordham, David", "Jett, Charlie"], "title": "U.S. Marshals"}
{ "index" : { "_index": "movies", "_id" : "4" } }
{"director": "Ray, Nicholas", "genre": ["Drama", "Romance"], "year": 1955, "actor": ["Hopper, Dennis", "Wood, Natalie", "Dean, James", "Mineo, Sal", "Backus, Jim", "Platt, Edward", "Ray, Nicholas", "Hopper, William", "Allen, Corey", "Birch, Paul", "Hudson, Rochelle", "Doran, Ann", "Hicks, Chuck", "Leigh, Nelson", "Williams, Robert", "Wessel, Dick", "Bryar, Paul", "Sessions, Almira", "McMahon, David", "Peters Jr., House"], "title": "Rebel Without a Cause"}

保存为bulk_movies.json,使用如下命令上传到OpenSearch。

curl -XPOST \
  -u 'admin:!qAzXsW2' \
  'https://vpc-demo1-rtavdqgb4fq72otjlavglnlc3y.ap-southeast-1.es.amazonaws.com/_bulk' \
  -H 'Content-Type: application/json' \
  --data-binary @bulk_movies.json

上传成功的话,返回信息:

{"took":25,"errors":false,"items":[{"index":{"_index":"movies","_id":"2","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":0,"_primary_term":1,"status":201}},{"index":{"_index":"movies","_id":"3","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":0,"_primary_term":1,"status":201}},{"index":{"_index":"movies","_id":"4","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":0,"_primary_term":1,"status":201}}]}

以上返回信息中,所有文件都返回successfulfailed的数量是0。由此表示上传成功。如下截图。

(4)检索上一步上传的文件

执行如下命令在上一步创建的电影信息内搜索带有mars火星关键字的电影。执行如下命令:

curl -XPOST \
  -u 'admin:!qAzXsW2' \
  'https://vpc-demo1-rtavdqgb4fq72otjlavglnlc3y.ap-southeast-1.es.amazonaws.com/movies/_search?q=mars&pretty=true'

查询成功的话,可以看到返回结果如下就是包含关键字:

{
  "took" : 305,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "movies",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "director" : "Burton, Tim",
          "genre" : [
            "Comedy",
            "Sci-Fi"
          ],
          "year" : 1996,
          "actor" : [
            "Jack Nicholson",
            "Pierce Brosnan",
            "Sarah Jessica Parker"
          ],
          "title" : "Mars Attacks!"
        }
      }
    ]
  }
}

由此表示OpenSearch工作正常。

四、使用Windows系统的EC2使用图形界面通过浏览器在VPC内网访问Kibana

1、获取Kibana URL

OpenSearch集群启动后,已经内置了Kibana,可以使用Endpoint/_dashboards的格式访问。由于本文配置是仅在VPC内可用的OpenSearch集群,因此这里就启动一个Windows的EC2实例来访问Kibana。

首先在OpenSearch界面上,获取本OpenSearch的Kibana入口。在页面右上角位置可以看到OpenSearch Dashboards URL (VPC)。如下截图。

获得如下URL:

https://vpc-demo1-rtavdqgb4fq72otjlavglnlc3y.ap-southeast-1.es.amazonaws.com/_dashboards

2、在VPC内使用Windows EC2上的浏览器登录并初始化Kibana

使用浏览器访问Kibana的URL,即可打开。如下截图。

输入创建Kibana时候的Master用户名和密码。然后点击Log in按钮。如下截图。

登录成功后,点击页面上的Explore on my own按钮,开始配置。如下截图。

在配置多租户位置,选择Global全局配置,即不需要多租户。如下截图。

进入Kibana完成。如下截图。

3、配置索引并查看数据

Kibana上初始化后还需要配置索引,才可以查看上一步从curl上写入的数据。

点击左上角的菜单,点击其中的Discover按钮。如下截图。

Index Patterns菜单位置,点击右上角的Create index pattern按钮。如下截图。

在定义索引位置,输入movies,后变会自动带出*通配符,然后点击Next step按钮进入下一步。如下截图。

在向导第二步,不需要调整设置,点击Create index pattern按钮创建索引。如下截图。

所以创建成功。如下截图。

现在重新进入菜单的Discover界面。如下截图。

在搜索框中,输入mars关键字进行检索,即可看到获得了搜索结果。如下截图。

五、使用Linux系统的EC2借助EC2 Session Manager功能在开发者本机访问Kibana

上文以Windows系统为例,通过Windows的GUI访问Kibana。如果在VPC内没有Windows实例,那么可以使用Session Manager功能进行转发,将Kibana的Endpoint转发到开发者本机。这

1、准备EC2和Session Manager并确认工作正常

本方式要求在本VPC内有一台EC2,其上部署有Session Manager,并且可以在本机通过Session Manager Plugin正常访问这个Linux。这需要分别完成云端配置Amazon Linux AMI、IAM Role、EC2 Instance Profile、Access Key/Secret Key,以及在开发者本机上配置AWSCLI、Sesison manager Plugin(支持开发者本机MacOS/Windows)。

在以上流程完毕后,可以使用Session Manager登录命令验证下和OpenSearch位于同一个VPC的EC2访问正常。在开发者本机执行如下命令,登录命令如下:(请替换其中的EC2 ID为实际的ID值)

aws ssm start-session --target i-1234567890abcdefg

如果登录EC2 Linux的SSH成功,就表示Session Manager工作正常。

操作流程请参考本文档

2、启动Session Manager设置转发

设置转发之前,要获得Kibana在本VPC的Endpoint,这一步方法与上文使用Windows EC2直接访问Kibana的步骤相同。例如获得如下URL:

https://vpc-demo1-rtavdqgb4fq72otjlavglnlc3y.ap-southeast-1.es.amazonaws.com/_dashboards

现在构建Session Manager的转发命令。注意命令中不需要填写https:///_dashboards,只填写Endpoint名称即可。构建好的命令如下:(请替换其中的EC2 ID为实际的ID值)

aws ssm start-session \
    --target i-1234567890abcdefg \
    --document-name AWS-StartPortForwardingSessionToRemoteHost \
    --parameters '{"host":["vpc-demo1-rtavdqgb4fq72otjlavglnlc3y.ap-southeast-1.es.amazonaws.com"],"portNumber":["443"], "localPortNumber":["56789"]}'

在以上命令中,56789是开发者本机要监听的端口。OSI网络模型和TCP/IP协议对本机端口的定义范围是0~65535,其中1024以下是服务预留。对于此类端口转发,一般选择端口大于50000的高位端口。如果开发者本机有任何安全软件,类似XXX电脑管家、XXX电脑助手,那么大概率会拦截本转发行为,本机的56789端口将不能工作。此时请手工停用这些安全软件,或者在安全软件上配置信任Session Manager Plugin插件在本机创建转发规则的行为。

启动成功后,返回信息如下。

Starting session with SessionId: pcman-009385c79b747a7e7
Port 56789 opened for sessionId pcman-009385c79b747a7e7.
Waiting for connections...

若有新的连接,此时就会提示有连接建立成功。如下截图。

注意此时本机的Session Manager窗口需要一直保留,可以被其他窗口遮挡住,但是不能关闭也不能退出。如果退出会造成连接断开。

3、验证从开发者本机访问Kibana

在开发者本机打开浏览器,使用浏览器访问:

https://127.0.0.1:56789/_dashboards/

请替换端口号为上一步转发时候使用的端口号。然后连接形式为https,网址请手工添加_dashboards/

此时浏览器会提示证书不合法。这是因为OpenSearch生成的默认证书是使用AWS结尾的域名的,不是匹配本机地址127.0.0.1的,由此才会提示这个错误。此时可以点击浏览器的高级按钮,信任这个证书,继续访问Kibana。如下截图。

继续正常登录。如下截图。

登录成功,可以正常使用Kibana了。如下截图。

至此本实验完成。

六、参考文档

Getting started with Amazon OpenSearch Service

https://docs.aws.amazon.com/opensearch-service/latest/developerguide/gsg.html