我正在尝试在Ansible的帮助下在EC2 Spot实例上设置一个自定义的Hadoop基础设施。在这样的实例中,只有内部IP是已知的。幸运的是,有一个动态生成清单的ec2.py脚本,可以配置为使用实例的完整外部DNS名称inventory_hostname。因此,我将所有Jinja2模板设置为使用inventory_hostname来设置配置XML文件。到目前为止,这对于HDFS是有效的,对于YARN,Nodemanagers也是向资源管理器注册的。
但是,节点IP设置不正确,即设置为其内部IP地址。
我的yarn-site.xml.j2看起来像这样:
<?xml version="1.0"?>
<!--
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. See accompanying LICENSE file.
-->
<configuration>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>{{resourcemanager_fqdn}}</value>
</property>
<property>
<name>yarn.resourcemanager.address</name>
<value>{{resourcemanager_fqdn}}:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>{{resourcemanager_fqdn}}:8030</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>{{resourcemanager_fqdn}}:8088</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>{{resourcemanager_fqdn}}:8031</value>
</property>
<property>
<name>yarn.resourcemanager.admin.address</name>
<value>{{resourcemanager_fqdn}}:8033</value>
</property>
<property>
<name>yarn.nodemanager.hostname</name>
<value>{{inventory_hostname}}</value>
</property>
<property>
<name>yarn.nodemanager.address</name>
<value>{{inventory_hostname}}:9999</value>
</property>
<property>
<name>yarn.nodemanager.localizer.address</name>
<value>{{inventory_hostname}}:8040</value>
</property>
<property>
<name>yarn.nodemanager.webapp.address</name>
<value>{{inventory_hostname}}:8042</value>
</property>
<property>
<name>yarn.resourcemanager.bind-host</name>
<value>0.0.0.0</value>
</property>
<property>
<name>yarn.nodemanager.bind-host</name>
<value>0.0.0.0</value>
</property>
</configuration>其中,变量resourcemanager_fqdn的获取方式如下:
{{hostvars[groups['tag_hadoop_resourcemanager'][0]].inventory_hostname}}tag_hadoop_resourcemanager是ec2.py动态生成的主机组。
我认为节点id是从yarn.nodemanager.address派生的,但这似乎被忽略了。仅考虑端口9999。
这是个bug,还是我忘了设置一个额外的选项?
发布于 2015-12-29 14:36:00
我看了一下纱线代码,发现了以下内容。
有一个函数buildNodeId(),用于构建节点Id。
Node Id是host和port的组合,并设置为host:port。
buildNodeId()在内部调用以下函数以获取InetAddress
InetAddress inetAddress = InetAddress.getByName(host);此调用始终返回内部IP地址作为第一个IP地址。
让我举个例子来解释一下。例如,我有以下IP:
Ethernet: 172.23.206.41 (External IP)
Host-Only: 192.168.56.1 (Internal IP).让我解释一下这两种情况(内部IP与外部IP)
我在我的yarn-site.xml yarn.nodemanager.address mballur中设置了以下内容:9999
其中mballur是我的主机名。
现在,当我运行yarn node -list -all时,我得到的节点ID如下:
节点总数:1 Node-Id Node-State Node-Http-Address正在运行的容器数量192.168.56.1:9999运行192.168.56.1:50060 0
节点ID为内部IP +端口的组合。因为,InetAddress.getByName(host)会返回内部IP作为第一个IP address.
我在我的yarn-site.xml yarn.nodemanager.address 172.23.206.41中设置了以下内容:9999
其中172.23.206.41是我的外部IP。
现在,当我运行yarn node -list -all时,我得到的节点ID如下:
节点总数:1 Node-Id Node-State Node-Http-Address正在运行的容器数量172.23.206.41:9999运行172.23.206.41:50060 0
现在,节点ID是“外部IP +端口”的组合。
发布于 2015-12-29 22:32:28
我找到了解决此问题的方法。我必须让我的实例认为它们的主机名是外部DNS名称。
这就是我是如何让它工作的:
首先,我创建了一个名为rewrite_hosts的角色,它只包含一个tasks目录,并在此tasks目录中包含以下main.yml
---
- name: "/etc/hostname must contain external DNS"
become: yes
become_method: sudo
shell: echo {{inventory_hostname}} >/etc/hostname
- name: "Determine external IP"
shell: wget -qO- http://ipecho.net/plain ; echo
register: host_ip
- name: "/etc/hosts entry must exist pointing to external IP"
become: yes
become_method: sudo
lineinfile: dest=/etc/hosts line="{{host_ip.stdout}} {{inventory_hostname}}" state=present
- name: "Update current hostname"
become: yes
become_method: sudo
shell: hostname $(cat /etc/hostname)然后,我设置了ec2.py as described here。但是,我在ec2.ini中更改了两项内容
RDS Set RDS(否则,它将使用IP address)
rds = false,因为我不使用vpc_destination_variable = public_dns_name。YMMV在这上面。然后,在设置任何特定于hadoop的内容之前,我将以下内容添加到我的剧本中:
- name: "Update IP information"
hosts: tag_origin_ec2
vars:
ansible_ssh_user: ubuntu
roles:
- rewrite_hosts我用origin: ec2标记我的实例,因为我以后想在非ec2环境中重用大部分攻略,所以这一部分将被跳过。
然后,行动手册中的所有后续行动都将按预期与ansible_fqdn一起工作。但是,要小心使用ansible_eth0.ipv4.address,因为它从eth0获取内部地址。作为一种解决方法,请使用以下任务:
- name: "Determine external IP"
shell: wget -qO- http://ipecho.net/plain ; echo
register: host_ip然后,如果需要,您可以使用host_ip.stdout获取IP地址。
发布于 2016-05-12 15:59:46
是的,你认为正确的,你应该做的包括:
1 .将hdfs-site.xml的dfs.datanode.hostname设置为您的public DNS name。
2、将public DNS name与本端ip的映射添加到每个节点自身的/etc/hosts中,该规则必须出现在hostname与本端ip的映射之前。
3 .将每个节点上hdfs-site.xml的dfs.datanode.use.datanode.hostname和dfs.client.use.datanode.hostname设置为true。
https://stackoverflow.com/questions/34497451
复制相似问题