1. Ansible简介
1.1. Ansible简介
ansible是一种自动化运维工具,基于paramiko开发的,并且基于模块化工作,Ansible是一种集成IT系统的配置管理、应用部署、执行特定任务的开源平台,它是基于python语言,由Paramiko和PyYAML两个关键模块构建。集合了众多运维工具的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能.ansible是基于模块工作的,本身没有批量部署的能力.真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架.ansible不需要在远程主机上安装client/agents,因为它们是基于ssh来和远程主机通讯的.
ansible被定义为配置管理工具,配置管理工具通常具有以下功能:
- 确保所依赖的软件包已经被安装
- 配置文件包含正确的内容和正确的权限
- 相关服务被正确运行
常用的自动化运维工具技术特性比较:
项目 | Puppet | SaltStack | Ansible |
---|---|---|---|
开发语言 | Ruby | Python | Python |
是否有客户端 | 有 | 有 | 无 |
是否支持二次开发 | 不支持 | 支持 | 支持 |
服务器与远程机器是否相互验证 | 是 | 是 | 是 |
服务器与远程机器的通信是否加密 | 是,标准的SSL协议 | 是,使用AES加密 | 是,使用OpenSSH |
平台支持 | AIX , BSD, HP-UX, Linux , Mac OSX , Solaris, Windows | BSD, Linux , Mac OS X , Solaris, Windows | AIX , BSD , HP-UX , Linux , Mac OS X , Solaris |
是否提供Web UI | 提供 | 提供 | 提供,但是是商业版本 |
配置文件格式 | Ruby 语法格式 | YAML | YAML |
命令行执行 | 不支持,大师可以通过配置模块实现 | 支持 | 支持 |
1.2. ansible基本架构
ansible系统由控制主机和被管理主机组成,控制主机不支持windows平台
ansible基础架构
- 核心: ansible
- Core Modules: ansible自带的模块
- Custom Modules: 核心模块功能不足时,用户可以添加扩展模块
- Plugins: 通过插件来实现记录日志,发送邮件或其他功能
- Playbooks: 剧本,YAML格式文件,多个任务定义在一个文件中,定义主机需要调用哪些模块来完成的功能
- Connectior Plugins: ansible基于连接插件连接到各个主机上,默认是使用ssh
- Host Inventory: 记录由Ansible管理的主机信息,包括端口、密码、ip等
- 1.3. ansible特点
部署简单, 只需要在控制主机上部署ansible环境,被控制端上只要求安装ssh和python 2.5以上版本,这个对于类unix系统来说相当与无需配置.
[1] no angents: 被管控节点无需安装agent
[2] no server: 无服务端,使用是直接调用命名
[3] modules in any languages: 基于模块工作, 可以使用任意语言开发模块
[4] 易读的语法: 基于yaml语法编写playbook
[5] 基于推送模式: 不同于puppet的拉取模式,直接由调用者控制变更在服务器上发生的时间
[6] 模块是幂等性的:定义的任务已存在则不会做任何事情,意味着在同一台服务器上多次执行同一个playbook是安全的
1.4. 优点
- 轻量级,无需在客户端安装agent,更新时,只需在操作机上进行一次更新即可;
- 批量任务执行可以写成脚本,而且不用分发到远程就可以执行;
- 使用python编写,维护更简单,ruby语法过于复杂;
- 支持sudo。
1.5 任务执行过程
2. 安装Ansible
这里以RedHat系Linux为例,其他系统请参考ansible的官网。
https://ansible-tran.readthedocs.io/en/latest/docs/intro_installation.html
2.1. 管理端安装Ansible
2.1.1. Yum源安裝Ansible软件
# Redhat/CentOS Linux上,Ansible目前放在的epel源中
# Fedora默认源中包含ansible,直接安装包既可
sudo yum -y install epel-release
#检查yum源中是否有ansible的介质和版本
yum list ansible
sudo yum install ansible -y
因为Ansible2.9.0版本有bug,见问题1.
2.1.2. Python方式安装Ansible软件
因此这里不使用epel中带的Ansible版本,而使用源码安装。源码可以从github或者pypi(https://pypi.org/project/ansible/)中下载。下面使用python方式安装示例。
2.1.2.1. 安装pip
centos默认没有安装pip,这里我们要安装pip
curl https://bootstrap.pypa.io/get-pip.py -oget-pip.py
python get-pip.py
[root@localhost ~]# pip -V
pip 19.3.1 from/usr/lib/python2.7/site-packages/pip (python 2.7)
2.1.2.2. 安装基础环境
yuminstallgcc glibc-develzlib-devel rpm-build openssl-deve -y
yuminstall -y python-devel
2.1.2.3. 安装ansible
安装指定版本的Ansible,这里安装2.8.5版本。如果需要其他版本,则修改后面的版本号即可。
pip install ansible==2.8.5
安装完成后检查版本:
ansible --version
2.1.2.4. Ansible默认配置文件
pip安装是没有config file文件的 我们可以将官网的默认文件上传到服务器
官方文档:传送门
mkdir /etc/ansible
touch /etc/ansible/ansible.cfg
将官网的默认配置文件复制到/etc/ansible/ansible.cfg。
2.1.2.5. 使用pip安装jmespath
pip install jmespath
pip show jmespath
2.1.3. 安装sshpass
如果是需要走密码方式访问其他主机,而不是密码方式,则需要安装sshpass模块。
Redhat系Linux系统部署sshpass命令:
yum -y install sshpass
MacOS系统部署sshpass命令:
brew installhttps://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb
2.2. 配置Ansible管理节点和主机的连接
其实就是配置从管理节点到远程主机之间基于key(无密码的方式)的SSH连接:
$ # 生成ssh key
$ ssh-keygen
$ # 拷贝ssh key到远程主机,ssh的时候就不需要输入密码了
$ ssh-copy-id remoteuser@remoteserver
$ # ssh的时候不会提示是否保存key
$ ssh-keyscan remote_servers >>~/.ssh/known_hosts
如果有很多远程主机,可以使用类似下面的命令来进行key复制。
for i in {1..7}; do ssh-copy-id -i~/.ssh/id_rsa.pub root@xxx$i.vpc.cloudera.com ; done
检查所有集群的所有机器都已经配置了互信,从客户端可以不用输入密码访问所有的机器:
2.3. 配置Ansible
2.3.1. 配置Ansible的配置文件
创建Ansible的配置文件:
vi ~/.ansible.cfg
[defaults]
# disable key check if host is not initially in'known_hosts'
host_key_checking = False
[ssh_connection]
# if True, make ansible use scp if the connectiontype is ssh (default is sftp)
scp_if_ssh = True
2.3.2. 配置CDH集群hosts的Inventory 文件
根据集群的实际情况进行调整
vi ~/ansible_hosts
[scm_server]
jacky-1.vpc.cloudera.com
[db_server]
jacky-1.vpc.cloudera.com
[krb5_server]
jacky-1.vpc.cloudera.com
[utility_servers:children]
scm_server
db_server
krb5_server
[edge_servers]
jacky-2.vpc.cloudera.com host_template=HostTemplate-Edgerole_ref_names=HDFS-HTTPFS-1
[master_servers]
jacky-3.vpc.cloudera.com host_template=HostTemplate-Master1
jacky-4.vpc.cloudera.com host_template=HostTemplate-Master2
jacky-5.vpc.cloudera.com host_template=HostTemplate-Master3
[worker_servers]
jacky-6.vpc.cloudera.com
jacky-7.vpc.cloudera.com
jacky-8.vpc.cloudera.com
[worker_servers:vars]
host_template=HostTemplate-Workers
[cdh_servers:children]
utility_servers
edge_servers
master_servers
worker_servers
2.4. 下载Cloudera-playbook
通过git命令下载Cloudera-playbook程序介质:
git clone https://github.com/cloudera/cloudera-playbook.git
2.5. 运行playbook
通过Ansible客户端运行playbook,部署集群
ansible-playbook -i ~/ansible_hostscloudera-playbook/site.yml
通过该playbook部署的集群,是一个开启了Kerberos、配置了安全并启用组件高可靠的集群。
……
这是可以通过访问CM来查看刚刚部署的CDH集群了。
2.6. 集群截图
2.6.1. 进入系统
使用CM的默认管理员账号(admin/admin)进入系统
发现部署任务还没有彻底完成,有部分工作还在继续,如下图:
等待集群部署完成。
2.6.2. 主界面
点击ClouderaManager图标进入主界面,可以看到HDFS有一个橘黄色的预警,这是因为纠删码的配置导致的,可以进入配置将纠删码的配置关闭即可。
2.6.3. 高可用查看
2.6.3.1. HDFS高可用
点击HDFS->实例,查看当前部署的角色,可以看到两个NameNode,HDFS已经配置了高可用。
2.6.3.2. YARN高可用
点击YARN->实例,查看当前部署的角色,可以看到两个ResourceManager角色,YARN已经配置了高可用。
2.6.3.3. HBase高可用
点击HBase->实例,查看当前部署的角色,可以看到三个Master角色,Hbase已经配置了高可用。
2.6.3.4. HMS高可用
点击Hive->实例,查看当前部署的角色,可以看到2个Hive Metastore Server角色,Hive已经配置了高可用。
2.6.3.5. Sentry高可用
点击Sentry->实例,查看当前部署的角色,可以看到2个Sentry Server角色,Sentry已经配置了高可用。
2.6.3.6. 安全确认
点击管理->安全,查看安全配置,可以看到集群已经超过启用了Kerberos。
2.6.3.7. 查看Kerberos配置
点击管理->安全->Kerberos凭据->配置,可以看到使用的是MIT的KDC,配置的Realm为MIT.EXAMPLE.COM
2.7. 调整playbook
2.7.1. 调整inventory文件
通过调整inventory文件,来调整每种功能部署的hosts。尤其是utility_servers, edge_servers和worker_servers的实际规划。
2.7.2. 调整CDH组件
调整使用的CDH组件,这个需要roles/cdh/templates/ host.j2文件。通过调整该文件,来调整每个节点的CDH功能分布。类似下文:
[ {
"refName": "HostTemplate-Gateway",
"cardinality": 1,
"roleConfigGroupsRefNames": [
"HDFS-1-GATEWAY-BASE",
"HIVE-1-GATEWAY-BASE",
"SPARK_ON_YARN-1-GATEWAY-BASE",
"YARN-1-GATEWAY-BASE" ]
}, {
"refName": "HostTemplate-Edge",
"cardinality": 1,
"roleConfigGroupsRefNames": [
"HDFS-1-HTTPFS-BASE",
"HBASE-1-HBASERESTSERVER-BASE",
"HBASE-1-HBASETHRIFTSERVER-BASE",
"HIVE-1-HIVESERVER2-BASE",
"HUE-1-HUE_SERVER-BASE",
"HUE-1-HUE_LOAD_BALANCER-BASE",
{% if(krb5_kdc_type is defined) and (krb5_kdc_type != 'none') %}
"HUE-1-KT_RENEWER-BASE",
{% endif%}
"OOZIE-1-OOZIE_SERVER-BASE",
"SPARK_ON_YARN-1-GATEWAY-BASE",
"YARN-1-GATEWAY-BASE" ]
}, {
"refName": "HostTemplate-Master1",
"cardinality": 1,
"roleConfigGroupsRefNames": [
"HBASE-1-MASTER-BASE",
"HDFS-1-NAMENODE-BASE",
"HDFS-1-FAILOVERCONTROLLER-BASE",
"HDFS-1-JOURNALNODE-BASE",
"HIVE-1-HIVEMETASTORE-BASE",
"SENTRY-1-SENTRY_SERVER-BASE",
"YARN-1-RESOURCEMANAGER-BASE",
"ZOOKEEPER-1-SERVER-BASE" ]
}, {
"refName": "HostTemplate-Master2",
"cardinality": 1,
"roleConfigGroupsRefNames": [
"HBASE-1-MASTER-BASE",
"HDFS-1-NAMENODE-BASE",
"HDFS-1-FAILOVERCONTROLLER-BASE",
"HDFS-1-JOURNALNODE-BASE",
"HIVE-1-HIVEMETASTORE-BASE",
"SENTRY-1-SENTRY_SERVER-BASE",
"YARN-1-RESOURCEMANAGER-BASE",
"ZOOKEEPER-1-SERVER-BASE" ]
}, {
"refName": "HostTemplate-Master3",
"cardinality": 1,
"roleConfigGroupsRefNames": [
"HBASE-1-MASTER-BASE",
"HDFS-1-BALANCER-BASE",
"HDFS-1-JOURNALNODE-BASE",
"IMPALA-1-CATALOGSERVER-BASE",
"IMPALA-1-STATESTORE-BASE",
"SPARK_ON_YARN-1-SPARK_YARN_HISTORY_SERVER-BASE",
{% ifcluster_version_cdh_major < '6' %}
"SPARK2_ON_YARN-1-SPARK2_YARN_HISTORY_SERVER-BASE",
{% endif%}
"YARN-1-JOBHISTORY-BASE",
"ZOOKEEPER-1-SERVER-BASE" ]
}, {
"refName": "HostTemplate-Workers",
"cardinality": 3,
"roleConfigGroupsRefNames": [
"HBASE-1-REGIONSERVER-BASE",
"HDFS-1-DATANODE-BASE",
"HIVE-1-GATEWAY-BASE",
"IMPALA-1-IMPALAD-BASE",
"SPARK_ON_YARN-1-GATEWAY-BASE",
{% ifcluster_version_cdh_major < '6' %}
"SPARK2_ON_YARN-1-GATEWAY-BASE",
{% endif%}
"YARN-1-NODEMANAGER-BASE" ]
} ]
2.7.3. 调整Kerberos配置
不同的客户会有不同的Kerberos配置,如果不需要Kerberos部分,则需要在site.yml文件中将kerberos部分去掉。
- name: Install MIT KDC Server
hosts:krb5_server
roles:
-krb5/server
tags: krb5
- name: Install MIT KDC Client
hosts: all
roles:
- {role: krb5/client, when: (krb5_kdc_type is defined) and (krb5_kdc_type !='none') }
tags: krb5
如果用户需要Kerberos,而是配置不同的信息,则需要调整group_vars/all中的Kerberos信息:
krb5_realm: MIT.EXAMPLE.COM
# 'Active Directory', 'MIT KDC', or 'none' todisable security
krb5_kdc_type: MIT KDC
krb5_kdc_admin_user: "cloudera-scm/admin@{{krb5_realm }}"
krb5_kdc_admin_passwd: changeme
krb5_kdc_master_passwd: changeme
# krb5_realm: AD.EXAMPLE.COM
# krb5_kdc_type: Active Directory
# krb5_kdc_host: my.ad.example.com
# krb5_kdc_admin_user: "admin@{{ krb5_realm}}"
# krb5_kdc_admin_passwd: changeme
# krb5_ad_suffix: "OU=Clusters,DC=ad,DC=example,DC=com"
# krb5_ad_delete_on_regenerate: true
# krb5_cm_managed_krb5_conf: false
# krb5_enc_types: "aes256-cts aes128-ctsrc4-hmac"
ad_domain: "{{ krb5_realm.lower() }}"
kdc: w2k8-1.ad.sec.example.com
computer_ou: OU=computer_hosts,OU=hadoop_prd,DC=ad,DC=sec,DC=example,DC=com
ldap_group_search_base:OU=groups,OU=hadoop_prd,DC=ad,DC=sec,DC=example,DC=com
ldap_user_search_base:DC=ad,DC=sec,DC=example,DC=com?subtree?(memberOf=CN=hadoop_users,OU=groups,OU=hadoop_prd,DC=ad,DC=sec,DC=example,DC=com)
override_gid: 999999
ad_site: Default-First-Site-Name
2.7.4. 配置CDH版本
目前程序默认是使用CDH6.3.0版本,如果需要调整版本,则需要调整group_vars/all中的cluster_version_cdh信息
##------------------------------------------------------------------------------------------------------------
## Cluster software installation options
##------------------------------------------------------------------------------------------------------------
# Version of CDH to install
cluster_version_cdh: 6.3.0
#cluster_version_cdh: 7.x
# Version of Cloudera Manager to install
cluster_version_cm: "{{ cluster_version_cdh }}"
2.7.5. 配置yum源
由于国内网络问题,基本上不可能在线部署CDH集群,需要在本地制作yum源。程序默认使用的是Cloudera公司的repository,因此需要将其调整为本地的yum源来进行部署。
创建本地的yum源和CDH parcel库的方法参考CDH集群部署手册,这里主要讲如果调整Cloudera playbook的内容。需要调整group_vars/all中的configs_by_version信息。主要是配置 scm_repo_url、scm_repo_gpgkey、scm_parcel_repositories、scm_csds和scm_prepare_database_script_path的信息。例如:
"6":
scm_repo_url: "{{cloudera_archive_protocol }}{{ cloudera_archive }}/cm6/{{ cluster_version_cm}}/redhat{{ ansible_distribution_major_version }}/yum"
scm_repo_gpgkey: "{{ cloudera_archive_protocol }}{{cloudera_archive }}/cm6/{{ cluster_version_cm }}/redhat{{ansible_distribution_major_version }}/yum/RPM-GPG-KEY-cloudera"
scm_parcel_repositories:
-"{{ cloudera_archive_protocol }}{{ cloudera_archive }}/cdh6/{{cluster_version_cdh }}/parcels"
scm_prepare_database_script_path:"/opt/cloudera/cm/schema/scm_prepare_database.sh"
3. 问题
3.1. Ansible 2.9.0版本bug
Ansible2.9.0版本在部署Cloudera Playbook时会出现各种各样莫名其妙的bug,例如Kerberos启动问题、no attribute ‘_loader’”等。
因为Ansible2.9.0版本有bug,该版本在epel-release11/12中,因此在安装前检查epel-release的版本,可以使用10版本。或者使用pip等方式来安装对应的版本。
3.2. MacOS部署错误
Ansible客户端如果是安装在MacOS系统上,则很有可能看到下面这个错误:
TASK [scm : Prepare CMS template] ***********************************************************************************
fatal:[xuefeng-1.vpc.cloudera.com]: FAILED! => {"msg": "Failed toget information on remote file (/tmp/cms_base.json): sudo: a password isrequiredn"}
目前这个问题还没有解决方案。建议客户端不要使用Mac系统,而是使用Redhat的Linux系统。
3.3. 出错检查方法
如果执行playbook报错,则使用-vvv参数来打印执行的详细信息,只有—tag来重复执行报错的部分,例如:
ansible-playbook -i ansible_hostscloudera-playbook/site.yml -vvv --tagscluster_template
执行的结果样例如下:
……
从消息上是节点上少安装了jmespath,这是因为在Ansible客户端机器上jmespath没有正确配置造成的。
检查是否安装了jmespath
pip show jmespath
可以看出Ansible客户端机器上没有安装jmespath,因此安装jmespath并验证jmespath是否可以正常使用。
然后进入python,检查是否可以正常使用jmespath
没有报错,可以继续进行了。
4. 参考资料
- Ansible中文权威指南:http://www.ansible.com.cn/
- 来源:https://www.cnblogs.com/liuhongru/p/11174224.html
- https://github.com/cloudera/cloudera-playbook.git