Tag简述
Tag(标签),阿里云提供的一种标记资源的方式,对资源添加标签可以方便地对资源进行标记,从而方便的进行资源的批量管理,现在ECS可以使用Tag标记的资源主要有以下几种:实例、磁盘、镜像、快照、安全组。
Tag基础
每个Tag是由两个部分组成,Key和Value。Tag是很开放的配置,Tag的Key和Value可以取值几乎任意字符串。因此,Tag是一个可以方便对资源进行标记、分类的工具。
Tag使用限制
为了更合理使用,Tag在功能上有几个限制。
- 首先,一个资源上面已有的Tag不能超过10个,标签太多会导致标签本身难以管理
- 一个资源上Tag key不能相同,如果添加一个已有key的Tag,会使用新的Tag覆盖老的Tag
- 相同Tag相同类型的资源数量不建议超过500,相同Tag的资源数量太大,会弱化Tag的资源分类功能
Tag经典场景
标签划分
对于一般的资源管理需求,都是针对一个用户下数量较多的情况,当实例等数量较多时,对实例进行运维管理等操作就会变得比较困难,有时候甚至需要采取拆分账号的方式管理不同部门或者不同用途的资源。如果采用Tag进行资源的分类管理,会大大简化这个问题。
首先,我们可以针对实例的使用场景进行分类,在一般的开发场景中,机器一般有多个分类:开发测试环境、打包环境、生产环境等。这些机器的运维管理是绝对隔绝的,因此要在Tag上对其进行区分,在开发测试机器上,可以增加标签(增加方式详见下一节)key为env、value为test;在生产机器上,可以增加标签key为env、value为product。形成如下图的机器分类。
之后再考虑按照使用人员进行的资源分类。对于资源保有多的,一个人进行资源的全部管理也是很困难的,所以需要进行基于人员的资源划分,我们可以在资源上,增加表示部门的标签,代表这些资源隶属于不同的部门。在增加了部门分类之后,机器分类如图:
权限控制
只使用标签的资源分类,只能做到对资源进行标记、划分,无法进行实质的资源管控隔离,如果需要做到资源真正的使用者隔离,就需要同时结合RAM实现。
简单介绍下RAM,每个阿里云账号都可以创建多个子账号,这些子账号可以被授权管理阿里云账号的某些资源,这个授权操作是阿里云账号来管理的,相关文档见:https://help.aliyun.com/product/28625.html
我们这里就是使用子账号结合标签对资源进行不同分类的隔离,我们为每个部门创建一个管理员(子账号),即dep manager,然后授权每个子账号只能操作带有自己部门标签的资源。这样我们就把实例资源完全分给两个部门进行管理,同时,实例上也带有相关环境的标识。
使用Tag的方式
接下来,详细描述下上述操作的具体步骤。
API操作
从API操作资源可以更清晰看到资源的变化过程,因此推荐使用API进行资源操作,相关文档在这里:https://help.aliyun.com/product/52507.html
对于接下来的操作,只需要安装python SDK,需要安装的包如下(ECS外的操作如RAM等通过控制台操作)
aliyun-python-sdk-core
aliyun-python-sdk-ecs
添加标签 页面操作
添加标签,需要的参数主要是资源id、资源类型、标签,注意region不要填错。下面是为资源添加标签的代码示例,一次调用最多可添加5个标签。
# common codes, 下次不再添加
# coding=utf-8
import logging
from aliyunsdkcore import client
from aliyunsdkcore.acs_exception.exceptions import ServerException, ClientException
from aliyunsdkecs.request.v20140526.AddTagsRequest import AddTagsRequest
clint = client.AcsClient('AK', 'SK', 'cn-qingdao') # region 按实际填写
logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S')
def _get_response(request):
try:
ret = clint.do_action_with_exception(request)
logging.info(ret)
except ServerException, e:
logging.error(e)
except ClientException, e:
logging.error(e)
# common codes end
def add_tag(resource_id, resource_type, tag1, tag2):
request = AddTagsRequest()
request.set_ResourceId(resource_id)
request.set_ResourceType(resource_type)
request.set_Tag1Key(tag1.get('key'))
request.set_Tag1Value(tag1.get('value'))
request.set_Tag2Key(tag2.get('key'))
request.set_Tag2Value(tag2.get('value'))
_get_response(request)
if __name__ == '__main__':
add_tag('i-xxxxx', 'instance', {'key':'env', 'value':'test'}, {'key':'depart', 'value':'dep1'})
以上示例可以给instance(实例)i-xxxxx添加两个标签,两个标签分别为 env:test 和 depart:dep1 。如果添加Tag时value填写错误,可以改正value之后再调用一次AddTags来“覆盖”一次同key的标签。
查询标签页面操作
查询标签,可以根据资源查询资源上的标签,也可以不填写资源,查询用户名下所有标签。下面是查询一个资源下标签的代码示例
from aliyunsdkecs.request.v20140526.DescribeTagsRequest import DescribeTagsRequest
def describe_tag(resource_id, resource_type):
request = DescribeTagsRequest()
request.set_ResourceId(resource_id)
request.set_ResourceType(resource_type)
_get_response(request)
if __name__ == '__main__':
describe_tag('i-xxxxx', 'instance')
删除标签页面操作
删除标签,删除指定资源的标签,本接口现在必须指定资源,可以不指定Tag value,表示删除所有Tag key为某个值的资源上的标签。
from aliyunsdkecs.request.v20140526.RemoveTagsRequest import RemoveTagsRequest
def remove_tag(resource_id, resource_type, tag):
request = RemoveTagsRequest()
request.set_ResourceId(resource_id)
request.set_ResourceType(resource_type)
request.set_Tag1Key(tag.get('key'))
request.set_Tag1Value(tag.get('value'))
_get_response(request)
if __name__ == '__main__':
remove_tag('i-xxxx', 'instance', {'key':'env', 'value':'test'})
创建资源自带标签页面操作
上述的操作都是针对于已有资源的Tag添加,为了保证标签流程的闭环,在创建资源的时候也是支持标签添加的,在资源的创建接口都是支持直接带Tag的创建,例如创建实例接口:
from aliyunsdkecs.request.v20140526.RunInstancesRequest import RunInstancesRequest
def remove_tag(resource_id, resource_type, tag):
request = RunInstancesRequest()
...
request.set_Tags({'Key':'env', 'Value':'test'})
_get_response(request)
这样创建出来的实例将会天然带有env:test标签。
控制台操作
添加标签送我学习API
在控制台添加标签,可以直接在实例列表的"更多"选项中选择编辑标签,在弹出框中新建标签即可。
查询标签送我学习API
标签在实例列表中或者实例详情页中就可以看到。
删除标签送我学习API
与添加标签一样,删除标签也在编辑标签的弹出窗口中操作,选择已有的标签删除掉即可。
创建资源自带标签送我学习API
现在的新版buy页面天然支持实例分组(Tag)功能,在新版buy页面需要先填写完前两步中的必填项。
在第四步的分组配置中,可以添加此次创建资源的标签
在最后确认订单阶段,可以确认标签的选择。
基于Tag的权限控制
我们涉及到的权限控制都指的是在子账号情况下对子账号的访问进行控制,首先需要在RAM控制台创建子账号(用户),然后给子用户授予权限,这个子用户将只有操作、查询授权规则相关的权限。
对于标签权限,授权语法如下:
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*",
"Condition": {
"StringEquals": {
"ecs:tag/depart": "dep1"
}
}
}
]
}
授权了如上权限的子用户,就只能操作带有depart:dep1标签的资源,注意,在查询时,这个授权不能作为过滤条件,在这个子账号查询实例的时候,必须带有Tag.1.Key=depart Tag.1.Value=dep1的过滤条件才允许查询。
对于使用Tag授权的资源,对不同类型的API有不同的限制表现,具体的限制如下:
操作类接口
对于操作类接口(如StartInstance),是针对某一个资源的操作,子账号是否有权限完全依赖这个实例是否带有指定的标签。
如果实例上带有授权语句中所有规定的标签,则允许子账号操作。
查询类接口
对于查询类操作,由于所有的鉴权行为都是前置行为(即判断结果只区分是否通过,而不会判断一个集合中有哪些通过),所以不会对结果集合进行“有权限过滤”。使用了标签鉴权的子账号,必须在查询中带有指定有权限的标签进行查询,才能查到有权限的实例。
创建类接口
对于创建类接口,鉴权时会判断接口中使用的所有资源是不是有权限,同时,也会判断创建出来的资源是否有权限。因此,对于带有标签授权的子账号,创建实例的时候,创建调用也必须带有相关Tag,否则子用户没有权限创建。