Skip to content

Commit

Permalink
Update default region of huaweicloud provider to ap-southeast-3
Browse files Browse the repository at this point in the history
1. "ap-southeast-3" region is in Singapore, we can use more stable
and speed networking access to some resources.
2. Update server flavor and image to match the region.
3. Allocate and attach EIP to head node
4. Add workspace security group egress rule
5. Add workspace subnet DNS option
6. Add configurable workspace bandwidth option for EIP and NAT
7. Add fs.obs.endpoint in core-site.xml for HuaweiCloud provider

Related-with: oap-project#1011
  • Loading branch information
kiwik committed Mar 28, 2023
1 parent b2f92a0 commit 8b2f189
Show file tree
Hide file tree
Showing 20 changed files with 113 additions and 40 deletions.
2 changes: 1 addition & 1 deletion example/cluster/huaweicloud/example-obs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ workspace_name: example-workspace
# Cloud-provider specific configuration.
provider:
type: huaweicloud
region: cn-east-2
region: ap-southeast-3
use_managed_cloud_storage: False
storage:
# OBS configurations for storage
Expand Down
4 changes: 2 additions & 2 deletions example/cluster/huaweicloud/example-standard.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ workspace_name: example-workspace
# Cloud-provider specific configuration.
provider:
type: huaweicloud
region: cn-east-2
region: ap-southeast-3

auth:
ssh_user: ubuntu
ssh_user: root
# Set proxy if you are in corporation network. For example,
# ssh_proxy_command: "ncat --proxy-type socks5 --proxy your_proxy_host:your_proxy_port %h %p"

Expand Down
2 changes: 1 addition & 1 deletion example/cluster/huaweicloud/example-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ workspace_name: example-workspace
# Cloud-provider specific configuration.
provider:
type: huaweicloud
region: cn-east-2
region: ap-southeast-3
# Use allowed_ssh_sources to allow SSH access from your client machine
allowed_ssh_sources:
- 0.0.0.0/0
10 changes: 10 additions & 0 deletions python/cloudtik/core/_private/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2855,3 +2855,13 @@ def get_command_session_name(cmd: str, timestamp: int):
hasher.update(cmd.encode("utf-8"))
hasher.update(timestamp_str.encode("utf-8"))
return "cloudtik-" + hasher.hexdigest()


def get_workspace_nat_public_ip_bandwidth_conf(
workspace_config: Dict[str, Any]) -> int:
return workspace_config.get('provider', {}).get('public_ip_bandwidth', 20)


def get_cluster_node_public_ip_bandwidth_conf(
cluster_provider_config: Dict[str, Any]) -> int:
return cluster_provider_config.get('public_ip_bandwidth', 20)
5 changes: 5 additions & 0 deletions python/cloudtik/core/config-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,11 @@
"type": "boolean",
"description": "Whether to assign worker with the role to access cloud storage.",
"default": true
},
"public_ip_bandwidth": {
"type": "integer",
"description": "Bandwidth of public ip in MB for node.",
"default": 20
}
}
},
Expand Down
5 changes: 5 additions & 0 deletions python/cloudtik/core/workspace-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,11 @@
"type": "string"
},
"description": "The list of CIDR definitions for hosts allowing ssh connection. For example, 0.0.0.0/0 for all hosts."
},
"public_ip_bandwidth": {
"type": "integer",
"description": "Bandwidth of public ip in MB for NAT.",
"default": 20
}
}
}
Expand Down
29 changes: 21 additions & 8 deletions python/cloudtik/providers/_private/huaweicloud/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@

import requests
from huaweicloudsdkcore.exceptions.exceptions import ServiceResponseException
from huaweicloudsdkecs.v2 import ListFlavorsRequest, ListServersDetailsRequest, \
from huaweicloudsdkecs.v2 import ListFlavorsRequest, \
ListServersDetailsRequest, \
NovaCreateKeypairOption, \
NovaCreateKeypairRequest, \
NovaCreateKeypairRequestBody, \
Expand Down Expand Up @@ -54,7 +55,7 @@

from cloudtik.core._private.cli_logger import cf, cli_logger
from cloudtik.core._private.utils import check_cidr_conflict, \
is_managed_cloud_storage, \
get_workspace_nat_public_ip_bandwidth_conf, is_managed_cloud_storage, \
is_peering_firewall_allow_ssh_only, \
is_peering_firewall_allow_working_subnet, is_use_internal_ip, \
is_use_managed_cloud_storage, \
Expand All @@ -69,11 +70,10 @@
_make_ecs_client, _make_obs_client, \
_make_vpc_client, export_huaweicloud_obs_storage_config, flat_tags_map, \
get_huaweicloud_cloud_storage_uri, get_huaweicloud_obs_storage_config, \
get_huaweicloud_obs_storage_config_for_update, HWC_OBS_BUCKET, \
HWC_SERVER_STATUS_ACTIVE, make_ecs_client, \
make_eip_client, \
make_iam_client, \
make_nat_client, \
get_huaweicloud_obs_storage_config_for_update, \
HWC_OBS_BUCKET, HWC_SERVER_STATUS_ACTIVE, \
make_ecs_client, make_eip_client, \
make_iam_client, make_nat_client, \
make_obs_client, make_obs_client_aksk, make_vpc_client, tags_list_to_dict
from cloudtik.providers._private.utils import StorageTestingError

Expand Down Expand Up @@ -442,6 +442,15 @@ def _update_security_group_rules(config, sg, vpc, vpc_client):
protocol='tcp',
remote_ip_prefix=vpc.cidr)))
)
# Create egress rule
vpc_client.create_security_group_rule(
CreateSecurityGroupRuleRequest(
CreateSecurityGroupRuleRequestBody(
CreateSecurityGroupRuleOption(sg.id,
direction='egress',
remote_ip_prefix='0.0.0.0/0')))
)

# Create peering vpc rule
if is_use_peering_vpc(config) and \
is_peering_firewall_allow_working_subnet(config):
Expand Down Expand Up @@ -518,13 +527,14 @@ def _check_and_create_eip(config, workspace_name):
eip_client = make_eip_client(config) \

cli_logger.print("Creating elastic IP: {}...", _eip_name)
bandwidth = get_workspace_nat_public_ip_bandwidth_conf(config)
eip = eip_client.create_publicip(
CreatePublicipRequest(
CreatePublicipRequestBody(
# Dedicated bandwidth 5 Mbit
bandwidth=CreatePublicipBandwidthOption(name=_bw_name,
share_type='PER',
size=5),
size=bandwidth),
publicip=CreatePublicipOption(type='5_bgp',
alias=_eip_name)))
).publicip
Expand Down Expand Up @@ -633,6 +643,8 @@ def _check_and_create_subnets(vpc, vpc_client, workspace_name):
CreateSubnetRequestBody(
CreateSubnetOption(name=subnet_name,
cidr=_cidr,
primary_dns='114.114.114.114',
secondary_dns='8.8.8.8',
gateway_ip=_gateway_ip,
vpc_id=vpc.id)))
).subnet
Expand Down Expand Up @@ -1467,6 +1479,7 @@ def _configure_subnet_from_workspace(config):
node_config["nics"] = private_subnet_ids
else:
node_config["nics"] = public_subnet_ids
node_config["publicip"] = True
# worker nodes
else:
node_config["nics"] = private_subnet_ids
Expand Down
32 changes: 27 additions & 5 deletions python/cloudtik/providers/_private/huaweicloud/node_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@
CreatePostPaidServersRequestBody, DeleteServersRequest, \
DeleteServersRequestBody, \
ListServersDetailsRequest, \
PostPaidServer, PostPaidServerDataVolume, PostPaidServerExtendParam, \
PostPaidServer, PostPaidServerDataVolume, PostPaidServerEip, \
PostPaidServerEipBandwidth, PostPaidServerExtendParam, \
PostPaidServerNic, \
PostPaidServerRootVolume, \
PostPaidServerPublicip, PostPaidServerRootVolume, \
PostPaidServerSecurityGroup, PostPaidServerTag, ServerId, ServerTag

from cloudtik.core._private.cli_logger import cli_logger
from cloudtik.core._private.utils import \
get_cluster_node_public_ip_bandwidth_conf
from cloudtik.core.node_provider import NodeProvider
from cloudtik.core.tags import CLOUDTIK_TAG_CLUSTER_NAME, \
CLOUDTIK_TAG_NODE_NAME
Expand All @@ -23,7 +26,8 @@
from cloudtik.providers._private.huaweicloud.utils import _get_node_info, \
_get_node_private_and_public_ip, _make_ecs_client, \
flat_tags_map, get_default_huaweicloud_cloud_storage, \
get_huaweicloud_obs_storage_config, HWC_SERVER_STATUS_ACTIVE, \
get_huaweicloud_obs_storage_config, \
HWC_SERVER_STATUS_ACTIVE, \
HWC_SERVER_STATUS_NON_TERMINATED, HWC_SERVER_TAG_STR_FORMAT, \
tags_list_to_dict
from cloudtik.providers._private.utils import validate_config_dict
Expand Down Expand Up @@ -157,6 +161,18 @@ def create_node(self, node_config: Dict[str, Any], tags: Dict[str, str],
nics = _node_config.pop('nics')
_node_config['nics'] = [PostPaidServerNic(subnet_id=nic['subnet_id'])
for nic in nics]
publicip = _node_config.pop('publicip')
if publicip:
bandwidth = get_cluster_node_public_ip_bandwidth_conf(
self.provider_config)
_node_config['publicip'] = PostPaidServerPublicip(
eip=PostPaidServerEip(
iptype='5_bgp',
bandwidth=PostPaidServerEipBandwidth(sharetype='PER',
size=bandwidth)
),
delete_on_termination=True
)
sgs = _node_config.pop('security_groups')
_node_config['security_groups'] = [
PostPaidServerSecurityGroup(id=sg['id']) for sg in sgs]
Expand Down Expand Up @@ -236,12 +252,18 @@ def node_tags(self, node_id: str) -> Dict[str, str]:

def external_ip(self, node_id: str) -> str:
node = self._get_cached_node(node_id)
private_ip, public_ip = _get_node_private_and_public_ip(node)
_, public_ip = _get_node_private_and_public_ip(node)
if not public_ip:
node = self._get_node(node_id)
_, public_ip = _get_node_private_and_public_ip(node)
return public_ip

def internal_ip(self, node_id: str) -> str:
node = self._get_cached_node(node_id)
private_ip, public_ip = _get_node_private_and_public_ip(node)
private_ip, _ = _get_node_private_and_public_ip(node)
if not private_ip:
node = self._get_node(node_id)
private_ip, _ = _get_node_private_and_public_ip(node)
return private_ip

def terminate_node(self, node_id: str) -> Optional[Dict[str, Any]]:
Expand Down
25 changes: 19 additions & 6 deletions python/cloudtik/providers/_private/huaweicloud/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
import os
from functools import lru_cache
from typing import Any, Dict, List
import os

from huaweicloudsdkcore.auth.credentials import BasicCredentials, \
GlobalCredentials
Expand All @@ -19,10 +19,11 @@
from obs import ObsClient

from cloudtik.core._private.constants import \
CLOUDTIK_DEFAULT_CLOUD_STORAGE_URI, env_bool
CLOUDTIK_DEFAULT_CLOUD_STORAGE_URI, env_bool, env_integer
from cloudtik.core._private.utils import get_storage_config_for_update

OBS_SERVICES_URL = 'https://obs.myhuaweicloud.com'
OBS_SERVICES_URL = 'https://obs.{location}.myhuaweicloud.com'
OBS_SERVICES_DEFAULT_URL = 'https://obs.myhuaweicloud.com'
HWC_OBS_BUCKET = "obs.bucket"
HWC_SERVER_TAG_STR_FORMAT = '{}={}'
HWC_SERVER_STATUS_ACTIVE = 'ACTIVE'
Expand Down Expand Up @@ -93,15 +94,16 @@ def _client_cache(region: str = None, ak: str = None, sk: str = None) -> Dict[
import certifi
_ssl_verify = certifi.where()

_server = get_huaweicloud_obs_storage_endpoint(region)
if ak and sk:
obs_client = ObsClient(access_key_id=ak, secret_access_key=sk,
server=OBS_SERVICES_URL, ssl_verify=_ssl_verify,
server=_server, ssl_verify=_ssl_verify,
region=region)
else:
# Enable OBSClient (ENV, ECS) security provider policy chain, see
# https://support.huaweicloud.com/sdk-python-devg-obs/obs_22_0601.html
obs_client = ObsClient(security_provider_policy='OBS_DEFAULT',
server=OBS_SERVICES_URL, ssl_verify=_ssl_verify,
server=_server, ssl_verify=_ssl_verify,
region=region)
client_map['obs'] = obs_client

Expand Down Expand Up @@ -185,6 +187,13 @@ def get_huaweicloud_obs_storage_config(provider_config: Dict[str, Any]):
return None


def get_huaweicloud_obs_storage_endpoint(region: str = None) -> str:
if region:
return OBS_SERVICES_URL.format(location=region)
else:
return OBS_SERVICES_DEFAULT_URL


def get_huaweicloud_obs_storage_config_for_update(
provider_config: Dict[str, Any]):
storage_config = get_storage_config_for_update(provider_config)
Expand All @@ -204,6 +213,10 @@ def export_huaweicloud_obs_storage_config(provider_config,
if obs_bucket:
config_dict["HUAWEICLOUD_OBS_BUCKET"] = obs_bucket

obs_endpoint = get_huaweicloud_obs_storage_endpoint(
provider_config.get("region"))
config_dict["HUAWEICLOUD_OBS_ENDPOINT"] = obs_endpoint

obs_access_key = cloud_storage.get("obs.access.key")
if obs_access_key:
config_dict["HUAWEICLOUD_OBS_ACCESS_KEY"] = obs_access_key
Expand Down Expand Up @@ -251,7 +264,7 @@ def tags_list_to_dict(tags: list) -> Dict[str, str]:


def _get_node_private_and_public_ip(node) -> List[str]:
private_ip = public_ip = ''
private_ip = public_ip = None
for _, addrs in node.addresses.items():
for addr in addrs:
if addr.os_ext_ip_stype == 'fixed' and not private_ip:
Expand Down
12 changes: 6 additions & 6 deletions python/cloudtik/providers/huaweicloud/defaults.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ from: defaults
# Cloud-provider specific configuration.
provider:
type: huaweicloud
region: cn-east-2
region: ap-southeast-3
# Whether to use managed cloud storage of workspace.
use_managed_cloud_storage: True

# How we will authenticate with newly launched nodes.
auth:
ssh_user: ubuntu
ssh_user: root
# By default, we create a new private keypair, but you can also use your own.
# If you do so, make sure to also set "KeyName" in the head and worker node
# configurations below.
Expand All @@ -26,8 +26,8 @@ available_node_types:
resources: {}
# Provider-specific config for this node type, e.g. instance flavor.
node_config:
image_ref: d4f60377-bb01-4a27-b119-c6de54fd4042
flavor_ref: ai1.xlarge.4
image_ref: 019b09ea-b960-46cd-abd8-306529e5eaa0
flavor_ref: ai1s.xlarge.4
# key_name: key_pair_name
root_volume:
volumetype: SSD
Expand All @@ -41,8 +41,8 @@ available_node_types:
resources: {}
# Provider-specific config for this node type, e.g. instance flavor.
node_config:
image_ref: d4f60377-bb01-4a27-b119-c6de54fd4042
flavor_ref: ai1.xlarge.4
image_ref: 019b09ea-b960-46cd-abd8-306529e5eaa0
flavor_ref: ai1s.xlarge.4
# key_name: key_pair_name
root_volume:
volumetype: SSD
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ from: workspace-defaults
# Cloud-provider specific configuration.
provider:
type: huaweicloud
region: cn-east-2
region: ap-southeast-3
# Decide whether to require public IP for head node.
# When setting to False, Head node will require a public IP.
# Default to False
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
<name>fs.obs.impl</name>
<value>org.apache.hadoop.fs.obs.OBSFileSystem</value>
</property>
<property>
<name>fs.obs.endpoint</name>
<value>{%fs.obs.endpoint.property%}</value>
</property>
{%fs.obs.security.provider.property%}
{%hadoop.credential.property%}
<property>
Expand Down
1 change: 1 addition & 0 deletions python/cloudtik/runtime/spark/scripts/configure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ function update_config_for_aliyun() {
function update_config_for_huaweicloud() {
fs_default_dir="obs://${HUAWEICLOUD_OBS_BUCKET}"
sed -i "s!{%fs.default.name%}!${fs_default_dir}!g" `grep "{%fs.default.name%}" -rl ./`
sed -i "s!{%fs.obs.endpoint.property%}!${HUAWEICLOUD_OBS_ENDPOINT}!g" `grep "{%fs.obs.endpoint.property%}" -rl ./`

update_cloud_storage_credential_config

Expand Down
2 changes: 1 addition & 1 deletion python/cloudtik/templates/huaweicloud/large.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ provider:
available_node_types:
head.default:
node_config:
flavor_ref: ai1.4xlarge.4
flavor_ref: ai1s.4xlarge.4
root_volume:
volumetype: SSD
size: 100
Expand Down
4 changes: 2 additions & 2 deletions python/cloudtik/templates/huaweicloud/medium.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ provider:
available_node_types:
head.default:
node_config:
flavor_ref: ai1.4xlarge.4
flavor_ref: ai1s.4xlarge.4
root_volume:
volumetype: SSD
size: 100
worker.default:
node_config:
flavor_ref: ai1.8xlarge.4
flavor_ref: ai1s.8xlarge.4
root_volume:
volumetype: SSD
size: 100
Expand Down
2 changes: 1 addition & 1 deletion python/cloudtik/templates/huaweicloud/small-highmem.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ provider:
available_node_types:
worker.default:
node_config:
flavor_ref: m6.xlarge.8
flavor_ref: ai1s.2xlarge.4
Loading

0 comments on commit 8b2f189

Please sign in to comment.