Как подключить том Cloud Block Storage к серверу OnMetal с помощью pyrax?

Я хочу автоматизировать подключение тома Cloud Block Storage к серверу OnMetal под управлением CentOS. 7, написав скрипт Python, использующий модуль Python pyrax. Вы знаете, как это сделать?


person Erik Sjölund    schedule 08.02.2016    source источник


Ответы (1)


Подключить том Cloud Block Storage к серверу OnMetal немного сложнее, чем к обычному виртуальному серверу Rackspace. Это вы заметите, когда попытаетесь подключить том Cloud Block Storage к серверу OnMetal в веб-интерфейсе Rackspace Cloud Control Panel, как вы видите этот текст:

Примечание. При присоединении томов к серверам OnMetal необходимо войти на сервер OnMetal, чтобы задать имя инициатора, обнаружить цели и затем подключиться к цели.

Таким образом, вы можете подключить том в веб-интерфейсе, но дополнительно вам необходимо войти на сервер OnMetal и выполнить несколько команд. Фактические команды можно скопировать и вставить из веб-интерфейса в терминал сервера OnMetal.

Также перед отсоединением нужно выполнить команду.

Но веб-интерфейс на самом деле не нужен. Это можно сделать с помощью модуля Python pyrax.

Сначала установите RPM-пакет iscsi-initiator-utils на сервер OnMetal.

[root@server-01 ~]# yum -y install iscsi-initiator-utils

Предполагая, что Volume_id и server_id известны, этот код Python сначала подключает том, а затем отсоединяет его. К сожалению, аргумент точки монтирования attach_to_instance() не работает для серверов OnMetal, поэтому нам нужно будет использовать команду lsblk -n -d до и после присоединения тома. Сравнивая выходные данные, мы затем выводим имя устройства, используемого для подключенного тома. (Часть для вывода имени устройства не учитывается в следующем коде Python).

#/usr/bin/python
# Disclaimer: Use the script at your own Risk!                                                                                                                                    
import json
import os
import paramiko
import pyrax

# Replace server_id and volume_id                                                                                                                                                                       
# to your settings                                                                                                                                                                                      
server_id = "cbdcb7e3-5231-40ad-bba6-45aaeabf0a8d"
volume_id = "35abb4ba-caee-4cae-ada3-a16f6fa2ab50"
# Just to demonstrate that the mount_point argument for                                                                                                                                                 
# attach_to_instance() is not working for OnMetal servers                                                                                                                                               
disk_device = "/dev/xvdd"

def run_ssh_commands(ssh_client, remote_commands):
    for remote_command in remote_commands:
        stdin, stdout, stderr = ssh_client.exec_command(remote_command)
        print("")
        print("command: " + remote_command)
        for line in stdout.read().splitlines():
            print(" stdout: " + line)
        exit_status = stdout.channel.recv_exit_status()
        if exit_status != 0:
            raise RuntimeError("The command :\n{}\n"
                               "exited with exit status: {}\n"
                               "stderr: {}".format(remote_command,
                                                   exit_status,
                                                   stderr.read()))

pyrax.set_setting("identity_type", "rackspace")
pyrax.set_default_region('IAD')
creds_file = os.path.expanduser("~/.rackspace_cloud_credentials")
pyrax.set_credential_file(creds_file)
server = pyrax.cloudservers.servers.get(server_id)
vol = pyrax.cloud_blockstorage.find(id = volume_id)
vol.attach_to_instance(server, mountpoint=disk_device)
pyrax.utils.wait_until(vol, "status", "in-use", interval=3, attempts=0,
                       verbose=True)

ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect(server.accessIPv4, username='root', allow_agent=True)

# The new metadata is only available if we get() the server once more                                                                                                                                   
server = pyrax.cloudservers.servers.get(server_id)

metadata = server.metadata["volumes_" + volume_id]
parsed_json = json.loads(metadata)
target_iqn = parsed_json["target_iqn"]
target_portal = parsed_json["target_portal"]
initiator_name = parsed_json["initiator_name"]

run_ssh_commands(ssh_client, [
    "lsblk -n -d",
    "echo InitiatorName={} > /etc/iscsi/initiatorname.iscsi".format(initiator_name),
    "iscsiadm -m discovery --type sendtargets --portal {}".format(target_portal),
    "iscsiadm -m node --targetname={} --portal {} --login".format(target_iqn, target_portal),
    "lsblk -n -d",
    "iscsiadm -m node --targetname={} --portal {} --logout".format(target_iqn, target_portal),
    "lsblk -n -d"
])

vol.detach()
pyrax.utils.wait_until(vol, "status", "available", interval=3, attempts=0,
                                    verbose=True)

Запуск кода Python выглядит так

user@ubuntu:~$ python attach.py 2> /dev/null
Current value of status: attaching (elapsed:  1.0 seconds)
Current value of status: in-use (elapsed:  4.9 seconds)

command: lsblk -n -d
 stdout: sda    8:0    0 29.8G  0 disk

command: echo InitiatorName=iqn.2008-10.org.openstack:a24b6f80-cf02-48fc-9a25-ccc3ed3fb918 > /etc/iscsi/initiatorname.iscsi

command: iscsiadm -m discovery --type sendtargets --portal 10.190.142.116:3260
 stdout: 10.190.142.116:3260,1 iqn.2010-11.com.rackspace:35abb4bb-caee-4c5e-ad53-a16f6f12ab50
 stdout: 10.69.193.1:3260,1 iqn.2010-11.com.rackspace:35abb4bb-caee-4c5e-ad53-a16f6f12ab50

command: iscsiadm -m node --targetname=iqn.2010-11.com.rackspace:35abb4bb-caee-4c5e-ad53-a16f6f12ab50 --portal 10.190.142.116:3260 --login
 stdout: Logging in to [iface: default, target: iqn.2010-11.com.rackspace:35abb4bb-caee-4c5e-ad53-a16f6f12ab50, portal: 10.190.142.116,3260] (multiple)
 stdout: Login to [iface: default, target: iqn.2010-11.com.rackspace:35abb4bb-caee-4c5e-ad53-a16f6f12ab50, portal: 10.190.142.116,3260] successful.

command: lsblk -n -d
 stdout: sda    8:0    0 29.8G  0 disk
 stdout: sdb    8:16   0   50G  0 disk

command: iscsiadm -m node --targetname=iqn.2010-11.com.rackspace:35abb4bb-caee-4c5e-ad53-a16f6f12ab50 --portal 10.190.142.116:3260 --logout
 stdout: Logging out of session [sid: 5, target: iqn.2010-11.com.rackspace:35abb4bb-caee-4c5e-ad53-a16f6f12ab50, portal: 10.190.142.116,3260]
 stdout: Logout of [sid: 5, target: iqn.2010-11.com.rackspace:35abb4bb-caee-4c5e-ad53-a16f6f12ab50, portal: 10.190.142.116,3260] successful.

command: lsblk -n -d
 stdout: sda    8:0    0 29.8G  0 disk
Current value of status: detaching (elapsed:  0.8 seconds)
Current value of status: available (elapsed:  4.7 seconds)
user@ubuntu:~$

Только одно дополнительное замечание:

Хотя это и не упоминается в официальной документации Rackspace.

https://support.rackspace.com/how-to/attach-a-cloud-block-storage-volume-to-an-onmetal-server/

в сообщении на форуме от 5 августа 2015 г. служба поддержки управляемой инфраструктуры Rackspace также рекомендует Бег

iscsiadm -m node -T $TARGET_IQN -p $TARGET_PORTAL --op update -n node.startup -v automatic

чтобы сделать соединение постоянным, чтобы он автоматически перезапускал сеанс iscsi при запуске.

Обновить

Что касается определения имени нового устройства: майор Хейден пишет в сообщение в блоге, которое

[root@server-01 ~]# ls /dev/disk/by-path/

может использоваться для поиска пути к новому устройству. Если вы хотите уважать любые символические ссылки, я думаю, это сработает.

[root@server-01 ~]# find -L /dev/disk/by-path -maxdepth 1 -mindepth 1 -exec realpath {} \;
person Erik Sjölund    schedule 08.02.2016