作者:MeshCloud脉时云公有云架构师付光
一、背景
GCP中实例分配IP地址默认使用DHCP分配,DHCP的默认租约期为1个小时。当实例关机超过一个小时原分配的IP地址可能会被分配到其他的实例上。
为了使IP地址在实例的生命周期内不会改变,则需要修改此默认的分配规则。目前主要有三类:
- 升级临时IP为静态IP地址
- 延长DHCP默认的租约期
- 创建实例的时候指定使用的子网IP
二、三种方式的优缺点
1. 升级临时IP为静态IP地址
这种方式会将IP地址设置为静态IP,设置静态IP之后,IP有独立的生命周期。在实例选择了静态IP之后,此IP将伴随实例整个生命周期,即使实例的生命周期结束,静态IP地址依然存在,只有手动删除静态IP,IP才会被DHCP资源池回收。
在存在有自动扩缩容的项目中,此类方法会导致为使用的静态IP增多,逐渐耗尽资源池中的IP地址。
2. 延长DHCP默认的租约期
DHCP默认的租约期为1个小时,目前不支持修改(代码中有相关的配置项,只是没有开放出来让客户自定义)。
如果没有设置合适的租约期的话,延长默认的租约期也会导致和第一种类似的故障,耗尽资源池中的IP地址。
3. 创建实例的时候指定使用的子网IP
在创建实例的时候指定子网中未使用的IP地址,则此IP地址不会在实例关机时自动释放。只有当实例被删除时才会释放IP地址。
此方式增加了创建虚拟主机时的工作量,但是不用担心实例被删除时无法自动释放IP到资源池中。
三、配置方法
1. 升级临时IP为静态IP地址
# 获取主机IP信息
gcloud compute instances describe INSTANCE_NAME --zone ZONE | grep "networkIP"
# 创建静态IP地址
gcloud compute addresses create ADDRESS_NAME_1 [ADDRESS_NAME_2..] \
--addresses IP_ADDRESS_1,[IP_ADDRESS_2,..] \--region REGION \--subnet SUBNETWORK
# API方式创建静态IP地址
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION/addresses
{
"addressType": "INTERNAL",
"address": "IP_ADDRESS",
"name": "ADDRESS_NAME",
"subnetwork": "regions/REGION/subnetworks/SUBNETWORK"
}
# 获取所有主机的IP地址信息
gcloud compute instances list --format="value(name,networkInterfaces[].networkIP,networkInterfaces[].subnetwork)"
# 获取所有静态地址信息
gcloud compute addresses list --filter="addressType:INTERNAL AND purpose:GCE_ENDPOINT" --format="value(name,address,status)"
# 获取所有的静态地址IP地址信息
gcloud compute addresses list
# API方式获取所有的静态地址IP地址信息
GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION/addresses
GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/aggregated/addresses
# 删除指定的静态地址
gcloud compute addresses delete ADDRESS_NAME \
--region REGION
# API方式删除指定的静态地址
DELETE https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION/addresses/ADDRESS_NAME
DELETE https://compute.googleapis.com/compute/v1/projects/myproject/regions/us-west1/addresses/example-address-to-delete
#!/bin/bash
gcloud compute addresses list --format=json | jq -c '.[]' | while read line
do
echo $line | jq '.addressType'
echo $line | jq '.status'
echo "================================="
done
2. 创建实例的时候指定使用的子网IP
# 创建实例的时候指定IP地址
gcloud compute instances create VM_NAME
--private-network-ip IP_ADDRESS
# API方式创建实例时指定IP地址
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances
{
"name": "VM_NAME",
"machineType": "zones/us-central1-f/machineTypes/e2-micro",
"networkInterfaces": [{
"accessConfigs": [{
"type": "ONE_TO_ONE_NAT",
"name": "External NAT",
}],
"network": "global/networks/default",
"networkIP": "IP_ADDRESS"
}],
"disks": [{
"autoDelete": "true",
"boot": "true",
"type": "PERSISTENT",
"initializeParams": {
"sourceImage": "projects/debian-cloud/global/images/v20150818"
}
}]
}