利用Ansible自动化部署zookeeper集群
准备工作
先在ansible主机上下载 zookeeper 或者通过FTP方式上传下载好的zookeeper到ansible主机上, 没采用在ansible中用get-url模块下载,因为通常在部署集群方式的时候,很多机器使在内网中,不会有权限直接连到外网, 所以一般是先下载下来拷贝到主控机器上,然后再用Ansible脚本去完成批量部署.
ansible zookeeper role文件夹准备
在ansible roles 目录下 创建zookeeper 目录, 并在zookeeper 目录下创建如下子目录, 如果没有roles 目录,请先创建role 目录。
mkdir -p {tasks,handlers,files,templates,vars}
创建完毕之后,roles目录结构如下:
[root@bigdata111 roles]# tree ./ ./ └── zookeeper ├── files ├── handlers ├── tasks ├── templates └── vars
文件目录说明如下(没有用到的目录,可以忽略):
tasks目录: 至少应该包含一个名为main.yaml的文件,其定义了此角色的任务列表,此文件可以使用include包含 其它的位于此目录中的task文件。
files目录:存放由copy或script等模块调用的文件。
templates目录:template模块会自动在此目录中寻找jenja2模板文件。
handlers目录: 此目录中应包含一个main.yaml的文件,用于定义此角色用到的各handlers。
vars目录: 应当包含一个main.yaml文件,用于定义此角色用到的变量。
mate目录: 应当包含一个main.yaml文件,用于定义此角色的特殊设定及其依赖关系
准备好 zoo.cfg 文件
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/opt/apache-zookeeper-3.5.8-bin/data clientPort=2181 server.1=192.168.222.114:2888:3888 server.2=192.168.222.115:2888:3888 server.3=192.168.222.116:2888:3888
定义需要安装zookeeper的服务器清单
在ansible目录下,编辑或者新增hosts 文件, 并编写需要配置zookeeper的服务器地址
文件:/etc/ansible/hosts
#新增内容如下: [zookeeper] 192.168.222.114 machine_id=1 192.168.222.115 machine_id=2 192.168.222.116 machine_id=3
可以看到, 为每台主机增加了变量 machine_id, 这是在后面task 里面会用到,因为zookeeper 集群需要有一个myid的配置文件。后面的task/main.yml 里面会看到这个变量.
定义主ansible的yml文件 zookeeper.yml
文件:/etc/ansible/roles/zookeeper.yml
- hosts: zookeeper remote_user: root roles: - zookeeper tags: zookeeper
定义ansible 批量部署zookeeper时用到的变量
文件: roles/zookeeper/vars/main.yml 文件
AnsibleDir: /etc/ansible ZOOKEEPER_RESOURCE_Dir: /opt/resources/zookeeper ZOOKEEPER_SOFT_DIR: /opt
AnsibleDir: Ansible 目录
ZOOKEEPER_RESOURCE_Dir:目标主机上,zookeeper 拷贝到的文件目录
ZOOKEEPER_SOFT_DIR: 目标机器上, zookeeper 被解压的位置,也就是解压之后,实际安装的目录
定义role/zookeeper 的task
文件: roles/zookeeper/task/main.yml 文件
- name: copy and unzip zookeeper unarchive: src={{AnsibleDir}}/roles/zookeeper/files/apache-zookeeper-3.5.8-bin.tar.gz dest={{ZOOKEEPER_SOFT_DIR}} - name: create zookeeper data folder file: path={{ZOOKEEPER_SOFT_DIR}}/apache-zookeeper-3.5.8-bin/data state=directory - name: copy zookeeper config copy: src={{ item.src }} dest={{ item.dest }} mode={{ item.mode }} with_items: - {src: "{{AnsibleDir}}/roles/zookeeper/files/zoo.cfg", dest: "{{ZOOKEEPER_SOFT_DIR}}/apache-zookeeper-3.5.8-bin/conf/zoo.cfg", mode: "0755"} - name: Create zookeeper id shell: "echo {{machine_id}} > {{ZOOKEEPER_SOFT_DIR}}/apache-zookeeper-3.5.8-bin/data/myid" - name: set env lineinfile: dest=/etc/profile line="{{item.value}}" state=present with_items: - {value: "export ZOOKEEPER_HOME={{ZOOKEEPER_SOFT_DIR}}/apache-zookeeper-3.5.8-bin"} - {value: "export PATH=$ZOOKEEPER_HOME/bin:$PATH"} - name: chmod bin file: dest={{ZOOKEEPER_SOFT_DIR}}/apache-zookeeper-3.5.8-bin/bin mode=0755 recurse=yes - name: enforce env shell: source /etc/profile notify: restart zookeeper handler
这里最后一步这个nofify 是可以不需要的,也可以添加到你需要的任何其他地方。这里仅仅是演示notify 与 handler的配合.
定义一个Handler
可以看到在上一步中的task里面的最后一步定义了一个notify, 也就是完成这一步的时候,会触发一个handler, 例子中的handler的名字为:restart zookeeper handler
编辑文件:roles/zookeeper/handlers/main.yml
里面的内容可以是ansible 支持的任何module, 在通常的情况下可以是启动服务,重启服务等任务,我这里就只打印一行文本就好了,
- name: restart zookeeper handler shell: "sh {{ZOOKEEPER_SOFT_DIR}}/apache-zookeeper-3.5.8-bin/bin/zkServer.sh restart"
执行 ansible-playbook.
在 /etc/ansible 目录下,执行
ansible-playbook roles/zookeeper.yml
稍等片刻,会发现,一切都成功,除了启动zookeeper, 也就是handler 执行报错了。报的错误就是JAVA_HOME没有配置。但事实上是配置了的。如果去每台机手动启动,都可以成功。原因在于ansible 去执行shell 的时候,有些命令是在/bin 目录下去找。所以还需要添加一些软连接到 /bin 目录下。
ln -s /usr/local/java/bin/jar /bin/jar ln -s /usr/local/java/bin/java /bin/java ln -s /usr/local/java/bin/javac /bin/javac ln -s /usr/local/java/bin/javah /bin/javah ln -s /usr/local/java/bin/javadoc /bin/javadoc
当然这些操作也是通过ansible去操作完成的。不可能每台机都去单独操作.
创建通用 role
用类似创建zookeeper角色的方式, 在 roles 目录下创建 common 目录,并在 common 目录下创建 需要的文件夹:
mkdir -p {tasks,handlers,files,templates,vars}
结构如下:
[root@bigdata111 roles]# tree ./common/ ./common/ ├── files ├── handlers ├── tasks ├── templates └── vars
在tasks 目录下 创建 main.yml 文件,测试环境的java安装在 /usr/local/java 目录下, 如果是其他目录,下面的命令需要自己修改路径.
- name: lnjar shell: "ln -s /usr/local/java/bin/jar /bin/jar" - name: lnjava shell: "ln -s /usr/local/java/bin/java /bin/java" - name: lnjavah shell: "ln -s /usr/local/java/bin/javah /bin/javah" - name: lnjavac shell: "ln -s /usr/local/java/bin/jar /bin/javac" - name: lnjavadoc shell: "ln -s /usr/local/java/bin/jar /bin/javadoc"
修改 zookeeper playbook
文件:/etc/ansible/roles/zookeeper.yml
- hosts: zookeeper remote_user: root roles: - common - zookeeper tags: zookeeper
再次执行 ansible-playbook roles/zookeeper.yml
再次执行 ansible-playbook roles/zookeeper.yml 部署zookeeper集群,并启动集群, 发现成功部署,并启动了zookeeper.
[root@bigdata111 ansible]# ansible-playbook roles/zookeeper.yml PLAY [zookeeper] *************************************************************** TASK [Gathering Facts] ********************************************************* ok: [192.168.222.116] ok: [192.168.222.114] ok: [192.168.222.115] TASK [common : lnjar] ********************************************************** [WARNING]: Consider using the file module with state=link rather than running 'ln'. If you need to use command because file is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message. changed: [192.168.222.116] changed: [192.168.222.114] changed: [192.168.222.115] TASK [common : lnjava] ********************************************************* changed: [192.168.222.115] changed: [192.168.222.116] changed: [192.168.222.114] TASK [common : lnjavah] ******************************************************** changed: [192.168.222.116] changed: [192.168.222.114] changed: [192.168.222.115] TASK [common : lnjavac] ******************************************************** changed: [192.168.222.114] changed: [192.168.222.115] changed: [192.168.222.116] TASK [common : lnjavadoc] ****************************************************** changed: [192.168.222.114] changed: [192.168.222.116] changed: [192.168.222.115] TASK [zookeeper : copy and unzip zookeeper] ************************************ ok: [192.168.222.116] ok: [192.168.222.115] ok: [192.168.222.114] TASK [zookeeper : create zookeeper data folder] ******************************** ok: [192.168.222.116] ok: [192.168.222.114] ok: [192.168.222.115] TASK [zookeeper : copy zookeeper config] *************************************** ok: [192.168.222.116] => (item={u'dest': u'/opt/apache-zookeeper-3.5.8-bin/conf/zoo.cfg', u'src': u'/etc/ansible/roles/zookeeper/files/zoo.cfg', u'mode': u'0755'}) ok: [192.168.222.114] => (item={u'dest': u'/opt/apache-zookeeper-3.5.8-bin/conf/zoo.cfg', u'src': u'/etc/ansible/roles/zookeeper/files/zoo.cfg', u'mode': u'0755'}) ok: [192.168.222.115] => (item={u'dest': u'/opt/apache-zookeeper-3.5.8-bin/conf/zoo.cfg', u'src': u'/etc/ansible/roles/zookeeper/files/zoo.cfg', u'mode': u'0755'}) TASK [zookeeper : Create zookeeper id] ***************************************** changed: [192.168.222.116] changed: [192.168.222.115] changed: [192.168.222.114] TASK [zookeeper : set env] ***************************************************** ok: [192.168.222.114] => (item={u'value': u'export ZOOKEEPER_HOME=/opt/apache-zookeeper-3.5.8-bin'}) ok: [192.168.222.115] => (item={u'value': u'export ZOOKEEPER_HOME=/opt/apache-zookeeper-3.5.8-bin'}) ok: [192.168.222.116] => (item={u'value': u'export ZOOKEEPER_HOME=/opt/apache-zookeeper-3.5.8-bin'}) ok: [192.168.222.114] => (item={u'value': u'export PATH=$ZOOKEEPER_HOME/bin:$PATH'}) ok: [192.168.222.116] => (item={u'value': u'export PATH=$ZOOKEEPER_HOME/bin:$PATH'}) ok: [192.168.222.115] => (item={u'value': u'export PATH=$ZOOKEEPER_HOME/bin:$PATH'}) TASK [zookeeper : chmod bin] *************************************************** ok: [192.168.222.114] ok: [192.168.222.115] ok: [192.168.222.116] TASK [zookeeper : enforce env] ************************************************* changed: [192.168.222.116] changed: [192.168.222.114] changed: [192.168.222.115] RUNNING HANDLER [zookeeper : restart zookeeper handler] ************************ changed: [192.168.222.116] changed: [192.168.222.115] changed: [192.168.222.114] PLAY RECAP ********************************************************************* 192.168.222.114 : ok=14 changed=8 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.222.115 : ok=14 changed=8 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.222.116 : ok=14 changed=8 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
查看zookeeper集群是否启动
可以用ansible 命令查看zookeeper 是否在集群上启动,也可以在集群的机器上手动执行 jps 命令,查看是否有QuorumPeerMain 进程.
[root@bigdata115 ~]# jps 8128 Jps 7965 QuorumPeerMain
到此为止,用 ansible 部署 zookeeper 集群就完成了。
注意事项
由于zookeeper用到 几个默认端口,可能需要打开防火墙配置, iptables中配置.
-A INPUT -m state --state NEW -m tcp -p tcp --dport 2181 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 2888 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 3888 -j ACCEPT
总结
先准备好zookeeper包
用role 方式编写 ansible-playbook 配置文件
2.1 按 role 模式创建好文件夹
2.2 编辑好ansible hosts 文件, 配置好要安装集群的机器, 自己先做好 ssh 免密码登陆。如果没做SSH 免密登陆,则需要配置登陆用户和密码.
2.3 准备资源文件
2.4 编写task
2.5 如果有handler,则编写handler, 否则可以不需要,根据业务情况,自己分析.
如果需要启动zookeeper,则在需要的地方加入handler.
3.1 如果ansible启动不了zookeeper, 检查 java 相关的软连接是否添加.
From:一号门
Previous:Hadoop FileSystem 获取目录所占磁盘空间大小
COMMENTS