2017年8月3日木曜日

VagrantとAmbari blueprintでhiveの1ノードクラスタを作成する

以下のVagrantfileで、mysql, Ambari Server, Hiveなどがインストールされた1ノードクラスタを構築できます。

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "bento/centos-7.3"
  config.vm.hostname = "min-hive"
  config.vm.provider :virtualbox do |vbox|
     vbox.name = "min-hive"
     vbox.cpus = 4
     vbox.memory = 12288 
     vbox.customize ["modifyvm", :id, "--nicpromisc2","allow-all"]
  end
  # private network
  config.vm.network "private_network", ip: "192.168.55.20", :netmask => "255.255.255.0"
  # bridge netwrok
  config.vm.network "public_network", ip: "192.168.1.20", :netmask => "255.255.255.0"
  config.vm.network "forwarded_port", guest:22, host:10022, id:"ssh"
  config.vm.provision "shell", inline: <<-SHELL
# firewalld無効化
systemctl stop firewalld
systemctl disable firewalld

# mysqlインストール
sudo yum -y remove mariadb-libs
yum -y localinstall http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm
yum -y install mysql mysql-devel mysql-server mysql-utilities
sudo systemctl enable mysqld.service
sudo systemctl start mysqld.service

# パスワードの変更とユーザの作成、DB作成
chkconfig mysqld on
service mysqld start
export MYSQL_ROOTPWD='Root123#'
export MYSQL_PWD=`cat /var/log/mysqld.log | awk '/temporary password/ {print $NF}'`
mysql -uroot --connect-expired-password -e "SET PASSWORD = PASSWORD('$MYSQL_ROOTPWD');"
export MYSQL_PWD=$MYSQL_ROOTPWD
export MYSQL_ROOTPWD='root'
mysql -uroot --connect-expired-password -e "UNINSTALL PLUGIN validate_password;"
mysql -uroot --connect-expired-password -e "SET PASSWORD = PASSWORD('$MYSQL_ROOTPWD');"
export MYSQL_PWD=$MYSQL_ROOTPWD
mysql -uroot --connect-expired-password -e "CREATE DATABASE ambari DEFAULT CHARACTER SET utf8;"
mysql -uroot --connect-expired-password -e "CREATE USER ambari@localhost IDENTIFIED BY 'bigdata';"
mysql -uroot --connect-expired-password -e "GRANT ALL PRIVILEGES ON ambari.* TO 'ambari'@'%' IDENTIFIED BY 'bigdata';"

mysql -uroot --connect-expired-password -e "CREATE DATABASE hive DEFAULT CHARACTER SET utf8;"
mysql -uroot --connect-expired-password -e "CREATE USER hive@localhost IDENTIFIED BY 'hive';"
mysql -uroot --connect-expired-password -e "GRANT ALL PRIVILEGES ON hive.* TO 'hive'@'%' IDENTIFIED BY 'hive';"

sudo systemctl stop mysqld.service
sudo cp /vagrant/my.cnf /etc
ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock
sudo systemctl start mysqld.service

# JDBCドライバーのインストール
yum -y install mysql-connector-java

# ---------
cd /etc/yum.repos.d/
wget http://public-repo-1.hortonworks.com/ambari/centos7/2.x/updates/2.5.1.0/ambari.repo
yum -y install ambari-server ambari-agent


# AMBARI-20532
echo '' >> /etc/ambari-server/conf/ambari.properties
echo 'server.jdbc.database=mysql' >> /etc/ambari-server/conf/ambari.properties
echo 'server.jdbc.database_name=ambari' >> /etc/ambari-server/conf/ambari.properties
echo 'server.jdbc.user.name=ambari' >> /etc/ambari-server/conf/ambari.properties
echo 'server.jdbc.user.password=/etc/ambari-server/conf/password.dat' >> /etc/ambari-server/conf/ambari.properties
echo 'server.jdbc.driver=/usr/share/java/mysql-connector-java.jar' >> /etc/ambari-server/conf/ambari.properties
echo 'custom.jdbc.name=mysql-connector-java.jar' >> /etc/ambari-server/conf/ambari.properties
echo 'server.jdbc.hostname=localhost' >> /etc/ambari-server/conf/ambari.properties
echo 'server.jdbc.port=3306' >> /etc/ambari-server/conf/ambari.properties
ambari-server setup -s --jdbc-db=mysql --jdbc-driver=/usr/share/java/mysql-connector-java.jar -v
ambari-server setup --silent

mysql -u ambari -pbigdata ambari < /var/lib/ambari-server/resources/Ambari-DDL-MySQL-CREATE.sql

ambari-server start
ambari-agent start

# blueprintで1ノードクラスタを構築
curl -H "X-Requested-By: ambari" -X POST -u admin:admin http://localhost:8080/api/v1/blueprints/min-hive -d @/vagrant/cluster_configuration.json

curl -H "X-Requested-By: ambari" -X POST -u admin:admin http://localhost:8080/api/v1/clusters/min-hive -d @/vagrant/hostmapping.json
sleep 30

# 完了まで待機
Progress=`curl -s --user admin:admin -X GET http://localhost:8080/api/v1/clusters/min-hive/requests/1 | grep progress_percent | awk '{print $3}' | cut -d . -f 1`
while [[ `echo $Progress | grep -v 100` ]]; do
  Progress=`curl -s --user admin:admin -X GET http://localhost:8080/api/v1/clusters/min-hive/requests/1 | grep progress_percent | awk '{print $3}' | cut -d . -f 1`
  echo " Progress: $Progress%"
  sleep 30
done

# adminユーザのディレクトリを作成
sudo -u hdfs /usr/bin/hdfs dfs -mkdir /user/admin
sudo -u hdfs /usr/bin/hdfs dfs -chown admin /user/admin

# ユーザ追加
useradd test
echo test | passwd test --stdin

sudo -u hdfs /usr/bin/hdfs dfs -mkdir /user/test
sudo -u hdfs /usr/bin/hdfs dfs -chown test /user/test

SHELL
end
cluster_configuration.json

{
  "configurations" : [
    {
      "hive-site": {
        "hive.support.concurrency": "true",
        "hive.txn.manager": "org.apache.hadoop.hive.ql.lockmgr.DbTxnManager",
        "hive.compactor.initiator.on": "true",
        "hive.compactor.worker.threads": "5",
        "javax.jdo.option.ConnectionDriverName": "com.mysql.jdbc.Driver",
        "javax.jdo.option.ConnectionPassword": "hive",
        "javax.jdo.option.ConnectionURL": "jdbc:mysql://localhost/hive",
        "javax.jdo.option.ConnectionUserName": "hive"
      }
    },
    {
      "hive-env": {
        "hive_ambari_database": "MySQL",
        "hive_database": "Existing MySQL Database",
        "hive_database_type": "mysql",
        "hive_database_name": "hive"
      }
    },
    {
      "core-site": {
        "properties" : {
          "hadoop.proxyuser.root.groups" : "*",
          "hadoop.proxyuser.root.hosts" : "*"
        }
      }
    }
  ],
  "host_groups" : [
    {
      "name" : "host_group_1",
      "components" : [
        {
          "name" : "NAMENODE"
        },
        {
          "name" : "SECONDARY_NAMENODE"
        },
        {
          "name" : "DATANODE"
        },
        {
          "name" : "HDFS_CLIENT"
        },
        {
          "name" : "RESOURCEMANAGER"
        },
        {
          "name" : "NODEMANAGER"
        },
        {
          "name" : "YARN_CLIENT"
        },
        {
          "name" : "HISTORYSERVER"
        },
        {
          "name" : "APP_TIMELINE_SERVER"
        },
        {
          "name" : "ZOOKEEPER_SERVER"
        },
        {
          "name" : "ZOOKEEPER_CLIENT"
        },
        {
          "name" : "METRICS_MONITOR"
        },
        {
          "name" : "TEZ_CLIENT"
        },
        {
          "name" : "HIVE_SERVER"
        },
        {
          "name" : "HIVE_METASTORE"
        },
        {
          "name" : "METRICS_COLLECTOR"
        },
        {
          "name" : "WEBHCAT_SERVER"
        }
      ],
      "cardinality" : "1"
    }
  ],
  "settings" : [{
     "recovery_settings" : [{
       "recovery_enabled" : "true"
    }]
  }],
  "Blueprints" : {
    "blueprint_name" : "min-hive",
    "stack_name" : "HDP",
    "stack_version" : "2.6"
  }
}
hostmapping.json

{
  "blueprint" : "min-hive",
  "default_password" : "admin",
  "provision_action" : "INSTALL_AND_START",
  "host_groups" :[
    {
      "name" : "host_group_1",
      "hosts" : [
        {
          "fqdn" : "min-hive"
        }
      ]
    }
  ]
}
my.cnf

[client]
port            = 3306
socket          = /var/lib/mysql/mysql.sock
default-character-set=utf8

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
bind-address = 0.0.0.0
port            = 3306
key_buffer_size = 256M
max_allowed_packet = 16M
table_open_cache = 16
innodb_buffer_pool_size = 512M
innodb_log_file_size = 32M
sort_buffer_size = 8M
read_buffer_size = 8M
read_rnd_buffer_size = 8M
join_buffer_size = 8M
thread_stack = 4M
character-set-server=utf8
lower_case_table_names = 1
innodb_lock_wait_timeout=120
skip-innodb-doublewrite

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

○関連情報
Vagrantを使用してkerberos化した1ノードクラスタのhive環境を構築する

・Ambariに関する他の記事はこちらを参照してください。

2016年11月27日日曜日

pythonとhdfsパッケージを使用してHDFSを操作する

pythonでHDFSを操作するのに、hdfsパッケージが使用できます。以下の様にpipでインストールできます。

pip install hdfs

また、Dockerでhdfsパッケージを使用できるコンテナを作成するには、以下のDockerfileを使用します。

Dokcerfile
FROM ubuntu:16.04

RUN locale-gen ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LC_ALL ja_JP.UTF-8

RUN apt-get update \
  && apt-get -y install python-pip \
  && pip install hdfs

CMD "/bin/bash"
・コンテナのビルド
docker build -t ub1604hdfs .
・コンテナに入る場合(変更は破棄される)
docker run -v `pwd`/dat:/dat --add-host hdfsserver:192.168.1.10 --rm -it ub1604hdfs

Ambariを使用している場合、 接続先は HDFS > Configs > Advanced > Advanced hdfs-site と辿って、dfs.namenode.http-addressを確認します

ファイルの列挙は以下のコードのようにlistメソッドを使用します。
from hdfs import InsecureClient

url = "http://hdfsserver:50070"
client = InsecureClient(url, user="hdfs")

for filename in client.list("/"):
  print(filename)
ローカルファイルをHDFSにアップロードするには、以下のコードのようにuploadメソッドを使用します。
from hdfs import InsecureClient

url = "http://hdfsserver:50070"
client = InsecureClient(url, user="hdfs")

hdfs_path = "/tmp"
local_path = "./test.txt"
client.upload(hdfs_path, local_path)
HDFS上のファイルを読み込むには、以下のコードのようにreadメソッドを使用します。
from hdfs import InsecureClient

url = "http://hdfsserver:50070"
client = InsecureClient(url, user="hdfs")

hdfs_path = "/tmp/test.txt"
with client.read(hdfs_path) as reader:
  print(reader.read())
HDFSのファイルをローカルにダウンロードするには、downloadメソッドを使用します。
from hdfs import InsecureClient

url = "http://hdfsserver:50070"
client = InsecureClient(url, user="hdfs")

hdfs_path = "/tmp/test.txt"
local_path = "/dat/download.txt"
client.download(hdfs_path, local_path)
HDFS上のファイルを削除するには、deleteメソッドを使用できます。
from hdfs import InsecureClient

url = "http://hdfsserver:50070"
client = InsecureClient(url, user="hdfs")

hdfs_path = "/tmp/test.txt"
client.delete(hdfs_path, recursive=True)

2016年10月23日日曜日

pysmbでディレクトリを作成する

pysmbでディレクトリを作成するには、以下のコードのようにSMBConnectionのcreateDirectoryを使用します。
import datetime
import platform
from smb.SMBConnection import SMBConnection

user = "test1"
password = "test1password"
host = "testserver"
shared_folder = "share"
conn = SMBConnection(user, password, platform.uname()[1], host, use_ntlm_v2 = True)
conn.connect(host, 139)

today = datetime.date.today()
todaystr = today.strftime("%Y%m%d")
conn.createDirectory(shared_folder, "foo/" + todaystr)

conn.close()

・pysmbのインストール
pip install pysmb

pysmbでIPアドレスからNetBIOS名を取得する

pysmbでIPアドレスからNetBIOS名を取得するには、以下のコードのようにNetBIOSクラスのqueryIPForNameを使用します。

from nmb.NetBIOS import NetBIOS
import sys

remote_ip = "192.168.1.10"
srv_name=""
timeout=10 # 10 sec
bios = NetBIOS()
srv_name = bios.queryIPForName(remote_ip, timeout=timeout)
bios.close()
if srv_name is None:
  print(remote_ip + " is not found.")
else:
  print(srv_name[0] + " is found.")

・pysmbのインストール
pip install pysmb

2016年8月16日火曜日

flaskでhello worldを行うDockerコンテナを作成する

flaskでhello worldを行うDockerコンテナを作成するには、以下のDockerfileを使用します。

使用するDockerfile
FROM ubuntu:16.04

RUN locale-gen ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:en
ENV LC_ALL ja_JP.UTF-8

RUN apt-get update \
  && apt-get -y install python-pip \
  && pip install --upgrade Flask

CMD "/bin/bash"

以下のコマンドでコンテナの作成を行う。
docker build -t ub1604flask .

以下のコマンドでコンテナの実行を行う。
docker run -v `pwd`/dat:/dat -p 5000:5000 --rm -it ub1604flask python /dat/app.py

dat/app.py
from flask import Flask
app = Flask(__name__)

@app.route("/")
def index():
    return "Hello World!"

if __name__ == "__main__":
    app.run(host='0.0.0.0')

ブラウザからはホストのIPアドレス:5000でアクセスする。

2016年8月14日日曜日

pyvboxで実行している仮想マシン名を列挙する

pyvboxで実行している仮想マシン名を列挙するには、以下のコードのようにstateを使用します。

import virtualbox

for vm in virtualbox.VirtualBox().machines:
  if vm.state == virtualbox.pool.MachineState.first_online or vm.state == virtualbox.pool.MachineState.last_online:
    print vm.name

2016年5月25日水曜日

Vagrantを使用してCentOS7上でGnome DesktopとXRDPがインストールされた仮想マシン(CentOS7)を作成する

Vagrantを使用してCentOS7上でGnome DesktopとXRDPがインストールされた仮想マシンを作成するには、以下のVagrantfileを使用します。

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "centos/7"
  config.vm.hostname = "centos7gui"
  config.vm.network :public_network, ip:"192.168.1.11"
  config.vm.synced_folder ".", "/home/vagrant/sync", disabled: true
  config.vm.synced_folder ".", "/vagrant", type: "virtualbox"
  config.vm.provider :virtualbox do |vbox|
     vbox.name = "centos7gui"
     vbox.gui = true
  end
  config.vm.provision "shell", inline: <<-SHELL
yum -y install wget

# GUIに関連するパッケージをインストール
sudo yum -y groupinstall "Server with GUI"
# 不要なダイアログを表示されないようにする
sudo sh -c "echo 'X-GNOME-Autostart-enabled=false' >> /etc/xdg/autostart/gnome-welcome-tour.desktop"
sudo sh -c "echo 'X-GNOME-Autostart-enabled=false' >> /etc/xdg/autostart/gnome-software-service.desktop"
sudo sh -c "echo 'X-GNOME-Autostart-enabled=false' >> /etc/xdg/autostart/gnome-settings-daemon.desktop"
sudo systemctl disable initial-setup-graphical.service
sudo systemctl disable initial-setup-text.service

sudo systemctl set-default graphical.target

# 日本語のロケールを設定
sudo yum -y install ibus-kkc vlgothic-*
localectl set-locale LANG=ja_JP.UTF-8

# XRDPをインストールして、リモートデスクトップでログインできるようにする。
sudo yum -y install epel-release
sudo yum -y install xrdp
sudo yum -y install tigervnc-server

sudo chcon -t bin_t /usr/sbin/xrdp
sudo chcon -t bin_t /usr/sbin/xrdp-sesman
sudo sed -i "s/max_bpp=32/max_bpp=24/" /etc/xrdp/xrdp.ini 
systemctl start xrdp.service
systemctl enable xrdp.service


telinit 5
SHELL

end