一、雲時代的運維
本文是我和李堯老師一起實驗。李堯是紅帽高級培訓講師,目前負責紅帽中國區員工內部技術培訓與認證。
物理機時代的運維,由於設備數量較少,運維人員的壓力不大,工作之餘還能喝點小酒,狀態是這樣的:
上了虛擬機後,作業系統數量增加十倍,運維人員嚴陣以待,但仍能抵擋,狀態是這樣的:
上了Openstack後,作業系統數量再度增加,並且需要做異構環境維護,運維人員有點蒙圈,狀態是這樣的:
公有雲開始使用,員需要對物理機、虛擬機、Openstack、公有雲的一體化運維,運維人員的狀態徹底崩潰,狀態是這樣的:
那麼,有沒有一種運維手段和工具,幫助客戶解決這個問題呢?請看本文如何通過Ansible管理公有雲。
二、Ansible都能管什麼雲?
Ansible都能管什麼雲?不是一個兩個,很是很多很多,但最有名的幾個是:
AWS、Azure、Google、Openstack、VMware(虛擬化)
(http://docs.ansible.com/ansible/latest/modules/list_of_cloud_modules.html)
事實上,Anisble的管理功能是全棧的:從底層硬體到頂層雲租戶中的應用。
三、Ansible如何連接雲
Ansible連接虛擬機中的OS,可以通過ssh、winRM。但如果想對雲做配置管理,則需要對應的連接代理,對應連接代理名稱:
Ansible管理Openstack,用的是shade方式(https://pypi.org/project/shade/)
簡單而言,shade是一種客戶端連接Openstack的方式,它調用的是Openstack的API。
在Ansible Server上,如果要配置對Openstack的連接,則需要配置(~/.config/openstack下)clouds.yaml文件,具體內容在後面實驗會詳細解釋。
Ansible管理AWS,用的boto的代理連接AWS的IAM組件。
在一個Ansible server上,如果要配置對AWS的連接,需要配置兩個文件:
/etc/boto.cfg
~/.aws/credentials
~/.boto
需要配置的變量如下:
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_SECURITY_TOKEN
AWS_PROFILE
四、Ansible連上雲可以可以調用的組件
雲平臺提供給Anible的可以調用的模塊,先看一下AWS的,內容很豐富:
aws_acm_facts - Retrieve certificate facts from AWS Certificate Manager service
aws_api_gateway - Manage AWS API Gateway APIs
aws_application_scaling_policy - Manage Application Auto Scaling Scaling Policies
aws_az_facts - Gather facts about availability zones in AWS.
aws_batch_compute_environment - Manage AWS Batch Compute Environments
aws_batch_job_definition - Manage AWS Batch Job Definitions
aws_batch_job_queue - Manage AWS Batch Job Queues
aws_direct_connect_connection - Creates, deletes, modifies a DirectConnect connection
aws_direct_connect_gateway - Manage AWS Direct Connect Gateway.
aws_direct_connect_link_aggregation_group - Manage Direct Connect LAG bundles.
aws_direct_connect_virtual_interface - Manage Direct Connect virtual interfaces.
aws_elasticbeanstalk_app - create, update, and delete an elastic beanstalk application
aws_kms - Perform various KMS management tasks.
aws_kms_facts - Gather facts about AWS KMS keys
aws_region_facts - Gather facts about AWS regions.
aws_s3 - manage objects in S3.
aws_s3_bucket_facts - Lists S3 buckets in AWS
aws_s3_cors - Manage CORS for S3 buckets in AWS
aws_ses_identity - Manages SES email and domain identity
aws_ssm_parameter_store - Manage key-value pairs in aws parameter store.
aws_waf_condition - create and delete WAF Conditions
aws_waf_facts - Retrieve facts for WAF ACLs, Rule , Conditions and Filters.
aws_waf_rule - create and delete WAF Rules
aws_waf_web_acl - create and delete WAF Web ACLs
cloudformation - Create or delete an AWS CloudFormation stack
cloudformation_facts - Obtain facts about an AWS CloudFormation stack
cloudfront_distribution - create, update and delete aws cloudfront distributions.
cloudfront_facts - Obtain facts about an AWS CloudFront distribution
cloudfront_invalidation - create invalidations for aws cloudfront distributions
cloudfront_origin_access_identity - create, update and delete origin access identities for a cloudfront distribution.
cloudtrail - manage CloudTrail create, delete, update
cloudwatchevent_rule - Manage CloudWatch Event rules and targets
cloudwatchlogs_log_group - create or delete log_group in CloudWatchLogs
cloudwatchlogs_log_group_facts - get facts about log_group in CloudWatchLogs
data_pipeline - Create and manage AWS Datapipelines
dynamodb_table - Create, update or delete AWS Dynamo DB tables.
dynamodb_ttl - set TTL for a given DynamoDB table.
ec2 - create, terminate, start or stop an instance in ec2
ec2_ami - create or destroy an image in ec2
ec2_ami_copy - copies AMI between AWS regions, return new image id
ec2_ami_facts - Gather facts about ec2 AMIs
ec2_ami_find - Searches for AMIs to obtain the AMI ID and other information (D)
ec2_ami_search - Retrieve AWS AMI information for a given operating system. (D)
ec2_asg - Create or delete AWS Autoscaling Groups
ec2_asg_facts - Gather facts about ec2 Auto Scaling Groups (ASGs) in AWS
ec2_asg_lifecycle_hook - Create, delete or update AWS ASG Lifecycle Hooks.
ec2_customer_gateway - Manage an AWS customer gateway
ec2_customer_gateway_facts - Gather facts about customer gateways in AWS
ec2_eip - manages EC2 elastic IP (EIP) addresses.
ec2_elb - De-registers or registers instances from EC2 ELBs
ec2_elb_facts - Gather facts about EC2 Elastic Load Balancers in AWS
ec2_elb_lb - Creates or destroys Amazon ELB.
ec2_eni - Create and optionally attach an Elastic Network Interface (ENI) to an instance
ec2_eni_facts - Gather facts about ec2 ENI interfaces in AWS
ec2_group - maintain an ec2 VPC security group.
ec2_group_facts - Gather facts about ec2 security groups in AWS.
ec2_instance - Create & manage EC2 instances
ec2_instance_facts - Gather facts about ec2 instances in AWS
ec2_key - create or delete an ec2 key pair
ec2_lc - Create or delete AWS Autoscaling Launch Configurations
ec2_lc_facts - Gather facts about AWS Autoscaling Launch Configurations
ec2_lc_find - Find AWS Autoscaling Launch Configurations
ec2_metadata_facts - Gathers facts (instance metadata) about remote hosts within ec2
ec2_metric_alarm - Create/update or delete AWS Cloudwatch 『metric alarms』
ec2_placement_group - Create or delete an EC2 Placement Group
ec2_placement_group_facts - List EC2 Placement Group(s) details
ec2_remote_facts - Gather facts about ec2 instances in AWS (D)
ec2_scaling_policy - Create or delete AWS scaling policies for Autoscaling groups
ec2_snapshot - creates a snapshot from an existing volume
ec2_snapshot_copy - copies an EC2 snapshot and returns the new Snapshot ID.
ec2_snapshot_facts - Gather facts about ec2 volume snapshots in AWS
ec2_tag - create and remove tag(s) to ec2 resources.
ec2_vol - create and attach a volume, return volume id and device map
ec2_vol_facts - Gather facts about ec2 volumes in AWS
ec2_vpc - configure AWS virtual private clouds (D)
ec2_vpc_dhcp_option - Manages DHCP Options, and can ensure the DHCP options for the given VPC match what’s requested
ec2_vpc_dhcp_option_facts - Gather facts about dhcp options sets in AWS
ec2_vpc_egress_igw - Manage an AWS VPC Egress Only Internet gateway
ec2_vpc_endpoint - Create and delete AWS VPC Endpoints.
ec2_vpc_endpoint_facts - Retrieves AWS VPC endpoints details using AWS methods.
ec2_vpc_igw - Manage an AWS VPC Internet gateway
ec2_vpc_igw_facts - Gather facts about internet gateways in AWS
ec2_vpc_nacl - create and delete Network ACLs.
ec2_vpc_nacl_facts - Gather facts about Network ACLs in an AWS VPC
ec2_vpc_nat_gateway - Manage AWS VPC NAT Gateways.
ec2_vpc_nat_gateway_facts - Retrieves AWS VPC Managed Nat Gateway details using AWS methods.
ec2_vpc_net - Configure AWS virtual private clouds
ec2_vpc_net_facts - Gather facts about ec2 VPCs in AWS
ec2_vpc_peer - create, delete, accept, and reject VPC peering connections between two VPCs.
ec2_vpc_peering_facts - Retrieves AWS VPC Peering details using AWS methods.
ec2_vpc_route_table - Manage route tables for AWS virtual private clouds
ec2_vpc_route_table_facts - Gather facts about ec2 VPC route tables in AWS
ec2_vpc_subnet - Manage subnets in AWS virtual private clouds
ec2_vpc_subnet_facts - Gather facts about ec2 VPC subnets in AWS
ec2_vpc_vgw - Create and delete AWS VPN Virtual Gateways.
ec2_vpc_vgw_facts - Gather facts about virtual gateways in AWS
ec2_vpc_vpn - Create, modify, and delete EC2 VPN connections.
ec2_win_password - gets the default administrator password for ec2 windows instances
ecs_attribute - manage ecs attributes
ecs_cluster - create or terminate ecs clusters
ecs_ecr - Manage Elastic Container Registry repositories
ecs_service - create, terminate, start or stop a service in ecs
ecs_service_facts - list or describe services in ecs
ecs_task - run, start or stop a task in ecs
ecs_taskdefinition - register a task definition in ecs
ecs_taskdefinition_facts - describe a task definition in ecs
efs - create and maintain EFS file systems
efs_facts - Get information about Amazon EFS file systems
elasticache - Manage cache clusters in Amazon Elasticache.
elasticache_facts - Retrieve facts for AWS Elasticache clusters
elasticache_parameter_group - Manage cache security groups in Amazon Elasticache.
elasticache_snapshot - Manage cache snapshots in Amazon Elasticache.
elasticache_subnet_group - manage Elasticache subnet groups
elb_application_lb - Manage an Application load balancer
elb_application_lb_facts - Gather facts about application ELBs in AWS
elb_classic_lb - Creates or destroys Amazon ELB.
elb_classic_lb_facts - Gather facts about EC2 Elastic Load Balancers in AWS
elb_instance - De-registers or registers instances from EC2 ELBs
elb_target - Manage a target in a target group
elb_target_group - Manage a target group for an Application or Network load balancer
elb_target_group_facts - Gather facts about ELB target groups in AWS
execute_lambda - Execute an AWS Lambda function
iam - Manage IAM users, groups, roles and keys
iam_cert - Manage server certificates for use on ELBs and CloudFront
iam_group - Manage AWS IAM groups
iam_managed_policy - Manage User Managed IAM policies
iam_mfa_device_facts - List the MFA (Multi-Factor Authentication) devices registered for a user
iam_policy - Manage IAM policies for users, groups, and roles
iam_role - Manage AWS IAM roles
iam_role_facts - Gather information on IAM roles
iam_server_certificate_facts - Retrieve the facts of a server certificate
iam_user - Manage AWS IAM users
kinesis_stream - Manage a Kinesis Stream.
lambda - Manage AWS Lambda functions
lambda_alias - Creates, updates or deletes AWS Lambda function aliases.
lambda_event - Creates, updates or deletes AWS Lambda function event mappings.
lambda_facts - Gathers AWS Lambda function details as Ansible facts
lambda_policy - Creates, updates or deletes AWS Lambda policy statements.
lightsail - Create or delete a virtual machine instance in AWS Lightsail
rds - create, delete, or modify an Amazon rds instance
rds_param_group - manage RDS parameter groups
rds_subnet_group - manage RDS database subnet groups
redshift - create, delete, or modify an Amazon Redshift instance
redshift_facts - Gather facts about Redshift cluster(s)
redshift_subnet_group - manage Redshift cluster subnet groups
route53 - add or delete entries in Amazons Route53 DNS service
route53_facts - Retrieves route53 details using AWS methods
route53_health_check - add or delete health-checks in Amazons Route53 DNS service
route53_zone - add or delete Route53 zones
s3_bucket - Manage S3 buckets in AWS, Ceph, Walrus and FakeS3
s3_lifecycle - Manage s3 bucket lifecycle rules in AWS
s3_logging - Manage logging facility of an s3 bucket in AWS
s3_sync - Efficiently upload multiple files to S3
s3_website - Configure an s3 bucket as a website
sns - Send Amazon Simple Notification Service (SNS) messages
sns_topic - Manages AWS SNS topics and subscriptions
sqs_queue - Creates or deletes AWS SQS queues.
sts_assume_role - Assume a role using AWS Security Token Service and obtain temporary credentials
sts_session_token - Obtain a session token from the AWS Security Token Service
管理Openstack的模塊:
os_auth - Retrieve an auth token
os_client_config - Get OpenStack Client config
os_flavor_facts - Retrieve facts about one or more flavors
os_floating_ip - Add/Remove floating IP from an instance
os_group - Manage OpenStack Identity Groups
os_image - Add/Delete images from OpenStack Cloud
os_image_facts - Retrieve facts about an image within OpenStack.
os_ironic - Create/Delete Bare Metal Resources from OpenStack
os_ironic_inspect - Explicitly triggers baremetal node introspection in ironic.
os_ironic_node - Activate/Deactivate Bare Metal Resources from OpenStack
os_keypair - Add/Delete a keypair from OpenStack
os_keystone_domain - Manage OpenStack Identity Domains
os_keystone_domain_facts - Retrieve facts about one or more OpenStack domains
os_keystone_endpoint - Manage OpenStack Identity service endpoints
os_keystone_role - Manage OpenStack Identity Roles
os_keystone_service - Manage OpenStack Identity services
os_network - Creates/removes networks from OpenStack
os_networks_facts - Retrieve facts about one or more OpenStack networks.
os_nova_flavor - Manage OpenStack compute flavors
os_nova_host_aggregate - Manage OpenStack host aggregates
os_object - Create or Delete objects and containers from OpenStack
os_port - Add/Update/Delete ports from an OpenStack cloud.
os_port_facts - Retrieve facts about ports within OpenStack.
os_project - Manage OpenStack Projects
os_project_access - Manage OpenStack compute flavors acceess
os_project_facts - Retrieve facts about one or more OpenStack projects
os_quota - Manage OpenStack Quotas
os_recordset - Manage OpenStack DNS recordsets
os_router - Create or delete routers from OpenStack
os_security_group - Add/Delete security groups from an OpenStack cloud.
os_security_group_rule - Add/Delete rule from an existing security group
os_server - Create/Delete Compute Instances from OpenStack
os_server_action - Perform actions on Compute Instances from OpenStack
os_server_facts - Retrieve facts about one or more compute instances
os_server_group - Manage OpenStack server groups
os_server_volume - Attach/Detach Volumes from OpenStack VM’s
os_stack - Add/Remove Heat Stack
os_subnet - Add/Remove subnet to an OpenStack network
os_subnets_facts - Retrieve facts about one or more OpenStack subnets.
os_user - Manage OpenStack Identity Users
os_user_facts - Retrieve facts about one or more OpenStack users
os_user_group - Associate OpenStack Identity users and groups
os_user_role - Associate OpenStack Identity users and roles
os_volume - Create/Delete Cinder Volumes
os_zone - Manage OpenStack DNS zones
五、Ansible如何獲取雲主機的inventory
Inventory即清單。記錄的是Ansible要執行任務的主機列表。
在物理機環境中,主機IP比較少,可以放到靜態配置文件中:
然後在執行playbook的時候,通過-i參數指定inventory文件。
但是,在雲環境中,由於虛擬機數量很多,而且IP位址經常發生變化,通過靜態清單的方式一來工作量巨大,二來很難保證實時更新,這就需要使用動態方式獲取inventory。這個inventory如何獲取的?
獲取動態清單有兩種方法:
1.通過python編寫動態清單腳本
2.通過ansible的gather_facts和add_host獲取。
第一種方法
我們需要針對不同的雲,編寫不同的動態inventory腳本。
很難???有點。
還好,在github上有大量的範例可供參考和修改。記住,這就是開源的好處!
(https://github.com/ansible/ansible/tree/devel/contrib/inventory)
我們以aws舉例。相關的兩個文件是:ec2.ini和ec2.py。
ec2.ini是配置文件,定義了你要aws環境的配置變量,如:
而ec2.py是獲取動態信息的執行腳本。我們看其中一段內容,它表示執行這個腳本,從aws上獲取如下信息並返回:
When run against a specific host, this script returns the following variables:
- ec2_ami_launch_index
- ec2_architecture
- ec2_association
- ec2_attachTime
- ec2_attachment
- ec2_attachmentId
- ec2_block_devices
- ec2_client_token
- ec2_deleteOnTermination
- ec2_description
- ec2_deviceIndex
- ec2_dns_name
- ec2_eventsSet
- ec2_group_name
- ec2_hypervisor
- ec2_id
- ec2_image_id
- ec2_instanceState
- ec2_instance_type
- ec2_ipOwnerId
- ec2_ip_address
- ec2_item
- ec2_kernel
- ec2_key_name
- ec2_launch_time
- ec2_monitored
- ec2_monitoring
- ec2_networkInterfaceId
- ec2_ownerId
- ec2_persistent
- ec2_placement
- ec2_platform
- ec2_previous_state
- ec2_private_dns_name
- ec2_private_ip_address
- ec2_publicIp
- ec2_public_dns_name
- ec2_ramdisk
- ec2_reason
- ec2_region
- ec2_requester_id
- ec2_root_device_name
- ec2_root_device_type
- ec2_security_group_ids
- ec2_security_group_names
- ec2_shutdown_state
- ec2_sourceDestCheck
- ec2_spot_instance_request_id
- ec2_state
- ec2_state_code
- ec2_state_reason
- ec2_status
- ec2_subnet_id
- ec2_tenancy
- ec2_virtualization_type
- ec2_vpc_id
而通過動態清單的方式獲取的信息,不僅可以被inventory使用,還可以被module使用。
第二種方法
1.信息收集(本地方式是gather_facts,openstack通過os_server_facts模塊實現)
2.add_hosts將收集到的信息推送到內存清單;add_hosts是ansible的一個模塊。
(http://docs.ansible.com/ansible/latest/modules/add_host_module.html?highlight=add_host)
add_hosts的作用:add a host (and alternatively a group) to the ansible-playbook in-memory inventory.
社區有對應的用例:
信息收集和add_hosts需要一起用,才能在內存中添加動態清單。
我們舉個例子:
在這個playbook中,先通過gather_facts收集信息。然後add_host獲取ipv4.address:
而這個playbook獲取到的信息(我在實驗中通過ansible setup輸出),要獲取的信息就是192.168.88.128的IP信息,它的key是
ansible_default_ipv4.address,層級目錄可以在下圖中看到:
我們看一下playbook的執行結果,和預期相同:
至於在雲中獲取動態清單的方法選擇,AWS中建議使用python方式(因為ansible的模塊可以調用aws的tag);在Openstack中,建議使用gather_facts和add_hosts,ansible很難簡單調用openstack的tag。
八、實驗展示Ansible對Openstack的管理
Ansible管理的Openstack環境拓撲如下:
在上圖中,laptop是自己的筆記本電腦,JumpBox是堡壘機,用於管理Openstack,上面將會被部署Openstack client和Ansible等。
從筆記本到堡壘機,堡壘機到Openstack實例的通訊如下圖:
Openstack的節點:
控制節點:
OpenStack controller host: ctrl.example.com
計算節點:
OpenStack infrastructure:
Compute node 00: comp00.example.com
Compute node 01: comp01.example.com
網絡節點
Network node 00: net00.example.com
Network node 01: net01.example.com
Network node 02: net02.example.com
堡壘機上安裝openstack的client:
將keystonerc_admin從管理節點拷貝。
查看計算節點:
九、配置堡壘機
在堡壘機上獲取openstack的公鑰,然後倒入本地認證:
在堡壘機上安裝必要的軟體:
安裝shade:
配置堡壘機的clouds.yaml文件,以便堡壘機可以通過shade library與Openstack連接:
接下來,編寫 rhel-guest鏡像加載的playbook,這個後面會用到執行playbook:
執行playbook:
驗證是否可以獲取openstack的token:
驗證是否可以獲取openstack的用戶列表:
截至到目前,堡壘機與Openstack的通訊沒有問題。
九、通過Ansible為Openstack一鍵部署多實例應用
在本實驗中,我們將通過一個大的playbook,進行Openstack的多個配置,配置內容如下:
1.網絡配置
public network和一個private network,以及rivate network 和internal physical network之間的路由器。
2.創建Key Pairs
3.創建 customer flavor
4.創建四個應用(四個虛擬機實例上)Application 1、Application 2、Database、Front End
5.ocp——facts role收集信息
git clone https://github.com/prakhar1985/good_example
我們看這個playbook的主任務:
在上圖中,我們可以很清楚地看到,playbook做的事情是在堡壘機上執行playbook,調用9個role,先調用4個roles做如下組件的配置:
osp-network、osp-keypair、osp-security group、osp-flavor
由於篇幅有限,我們只看osp-network的role:
[root@workstation-1c79 tasks]# cat main.yml
- os_network:
cloud: ospcloud
state: present
name: ext_network
external: true
- os_subnet:
cloud: ospcloud
state: present
network_name: ext_network
name: external_subnet
cidr: 10.10.10.0/24
dns_nameservers:
- 8.8.8.7
- 8.8.8.8
host_routes:
- destination: 0.0.0.0/0
nexthop: 10.10.10.0
- destination: 192.168.0.0/24
nexthop: 192.168.0.0
- os_network:
cloud: ospcloud
state: present
name: int_network
external: false
register: internal
tags:
- tested
- os_subnet:
cloud: ospcloud
state: present
network_name: int_network
name: int_subnet
cidr: 20.20.20.0/24
dns_nameservers:
- 8.8.8.7
- 8.8.8.8
host_routes:
- destination: 0.0.0.0/0
nexthop: 192.168.0.0
- destination: 192.168.0.0/24
nexthop: 192.168.0.0
- os_router:
cloud: ospcloud
state: present
name: router1
network: ext_network
external_fixed_ips:
- subnet: external_subnet
interfaces:
- int_subnet
上面的role就是按照之前我們的定義,創建兩個openstack網絡和一個router。
執行完四個role以後,就完成了對Openstack如下組件的配置:osp-network、osp-keypair、osp-security group、osp-flavor。
然後site.yml再調用另外幾個role做: Create frontend instance、Create App1 server、Create App2 server、Create DB server的操作。
我們執行site.yaml,查看輸出結果。
首先,playbook會按照對role的調用,依次創建網絡、創建key pair、創建安全組
接下來,創建flavor:
至此,基本配置的四個role已經執行完畢。
接下來,部署前端應用。
部署app1實例:
給app1實例增加浮動IP:
創建app2實例:
給app2實例增加浮動IP
創建db實例:
給db實例增加浮動IP:
最後,通過add host收集清單,添加到動態清單中:
最終playbook執行成功:
登錄Openstack,查看部署好的實例:
九、通過Ansible在Openstack利用動態清單部署三層應用
(https://github.com/tonykay/good-ansible)
這個playbook的目錄結構如下:
我們看一下主任務:main.yml
---這個yaml做的事情,第一步,調用osp-facts這個role獲取動態清單。我們查看一下這個role:
這個role是使用os_server_facts和Add host獲取動態清單(如果沒有收集動態清單,則使用靜態清單的變量定義)。
獲取變量的key是:public_v4、metadata.group、metadata.deployment_name,而result.ansible_facts.openstack_servers是循環前綴。
獲取完動態心以後,繼續執行roles:配置load-balancer tier、app tier、 database tier。然後,這三個大的任務,分別調用寫好的roles。
執行playbook:
$ ansible-playbook main.yml -i inventory/hosts --ask-vault-pass
執行playbook後,第一步是調用role osp-facts收集信息,然後以變量方式注入到roles變量中:
例如public_v4信息:
具體的安裝步驟較長,這裡不再贅述。實際上就是將幾個組件安裝到Openstack實例中。
十、有了Ansible,你的運維也可以很帥
通過Ansible對物理機、虛擬機、私有雲、公有雲的一體化運維,運維人員的壓力不僅可以減小,還可以很拉風,狀態是這樣的:
而不再是這樣的:
魏新宇
"大魏分享"運營者、紅帽資深解決方案架構師
專注開源雲計算、容器及自動化運維在金融行業的推廣
擁有紅帽RHCE/RHCA、VMware VCP-DCV、VCP-DT、VCP-Network、VCP-Cloud、ITIL V3、Cobit5、C-STAR、AIX、HPUX等相關認證。
文章打賞隨意(轉發和讚賞都是對作者原創的鼓勵):
更多精彩內容,歡迎繼續關注大魏分享: