什麼是k8s

•Kubernetes介紹

1.背景介紹

  雲計算飛速發展

    - IaaS

    - PaaS

    - SaaS

  Docker技術突飛猛進

    - 一次構建,到處運行

    - 容器的快速輕量

    - 完整的生態環境

2.什麼是kubernetes

  首先,他是一個全新的基於容器技術的分佈式架構領先方案。Kubernetes(k8s)是Google開源的容器集羣管理系統(谷歌內部:Borg)。在Docker技術的基礎上,爲容器化的應用提供部署運行、資源調度、服務發現和動態伸縮等一系列完整功能,提高了大規模容器集羣管理的便捷性。

  Kubernetes是一個完備的分佈式系統支撐平臺,具有完備的集羣管理能力,多擴多層次的安全防護和准入機制、多租戶應用支撐能力、透明的服務註冊和發現機制、內建智能負載均衡器、強大的故障發現和自我修復能力、服務滾動升級和在線擴容能力、可擴展的資源自動調度機制以及多粒度的資源配額管理能力。同時Kubernetes提供完善的管理工具,涵蓋了包括開發、部署測試、運維監控在內的各個環節。

Kubernetes中,Service是分佈式集羣架構的核心,一個Service對象擁有如下關鍵特徵:

  • 擁有一個唯一指定的名字
  • 擁有一個虛擬IP(Cluster IP、Service IP、或VIP)和端口號
  • 能夠體統某種遠程服務能力
  • 被映射到了提供這種服務能力的一組容器應用上

  Service的服務進程目前都是基於Socket通信方式對外提供服務,比如Redis、Memcache、MySQL、Web Server,或者是實現了某個具體業務的一個特定的TCP Server進程,雖然一個Service通常由多個相關的服務進程來提供服務,每個服務進程都有一個獨立的Endpoint(IP+Port)訪問點,但Kubernetes能夠讓我們通過服務連接到指定的Service上。有了Kubernetes內奸的透明負載均衡和故障恢復機制,不管後端有多少服務進程,也不管某個服務進程是否會由於發生故障而重新部署到其他機器,都不會影響我們隊服務的正常調用,更重要的是這個Service本身一旦創建就不會發生變化,意味着在Kubernetes集羣中,我們不用爲了服務的IP地址的變化問題而頭疼了。

  容器提供了強大的隔離功能,所有有必要把爲Service提供服務的這組進程放入容器中進行隔離。爲此,Kubernetes設計了Pod對象,將每個服務進程包裝到相對應的Pod中,使其成爲Pod中運行的一個容器。爲了建立Service與Pod間的關聯管理,Kubernetes給每個Pod貼上一個標籤Label,比如運行MySQL的Pod貼上name=mysql標籤,給運行PHP的Pod貼上name=php標籤,然後給相應的Service定義標籤選擇器Label Selector,這樣就能巧妙的解決了Service於Pod的關聯問題。

  在集羣管理方面,Kubernetes將集羣中的機器劃分爲一個Master節點和一羣工作節點Node,其中,在Master節點運行着集羣管理相關的一組進程kube-apiserver、kube-controller-manager和kube-scheduler,這些進程實現了整個集羣的資源管理、Pod調度、彈性伸縮、安全控制、系統監控和糾錯等管理能力,並且都是全自動完成的。Node作爲集羣中的工作節點,運行真正的應用程序,在Node上Kubernetes管理的最小運行單元是Pod。Node上運行着Kubernetes的kubelet、kube-proxy服務進程,這些服務進程負責Pod的創建、啓動、監控、重啓、銷燬以及實現軟件模式的負載均衡器。

  在Kubernetes集羣中,它解決了傳統IT系統中服務擴容和升級的兩大難題。你只需爲需要擴容的Service關聯的Pod創建一個Replication Controller簡稱(RC),則該Service的擴容及後續的升級等問題將迎刃而解。在一個RC定義文件中包括以下3個關鍵信息。

  • 目標Pod的定義
  • 目標Pod需要運行的副本數量(Replicas)
  • 要監控的目標Pod標籤(Label)

  在創建好RC後,Kubernetes會通過RC中定義的的Label篩選出對應Pod實例並實時監控其狀態和數量,如果實例數量少於定義的副本數量,則會根據RC中定義的Pod模板來創建一個新的Pod,然後將新Pod調度到合適的Node上啓動運行,知道Pod實例的數量達到預定目標,這個過程完全是自動化。

  架構資料領取地址:895244712

 Kubernetes優勢:

    - 容器編排

    - 輕量級

    - 開源

    - 彈性伸縮

    - 負載均衡

•Kubernetes的核心概念

1.Master

  k8s集羣的管理節點,負責管理集羣,提供集羣的資源數據訪問入口。擁有Etcd存儲服務(可選),運行Api Server進程,Controller Manager服務進程及Scheduler服務進程,關聯工作節點Node。Kubernetes API server提供HTTP Rest接口的關鍵服務進程,是Kubernetes裏所有資源的增、刪、改、查等操作的唯一入口。也是集羣控制的入口進程;Kubernetes Controller Manager是Kubernetes所有資源對象的自動化控制中心;Kubernetes Schedule是負責資源調度(Pod調度)的進程

 

2.Node

  Node是Kubernetes集羣架構中運行Pod的服務節點(亦叫agent或minion)。Node是Kubernetes集羣操作的單元,用來承載被分配Pod的運行,是Pod運行的宿主機。關聯Master管理節點,擁有名稱和IP、系統資源信息。運行docker eninge服務,守護進程kunelet及負載均衡器kube-proxy.

  • 每個Node節點都運行着以下一組關鍵進程
  • kubelet:負責對Pod對於的容器的創建、啓停等任務
  • kube-proxy:實現Kubernetes Service的通信與負載均衡機制的重要組件
  • Docker Engine(Docker):Docker引擎,負責本機容器的創建和管理工作

  Node節點可以在運行期間動態增加到Kubernetes集羣中,默認情況下,kubelet會想master註冊自己,這也是Kubernetes推薦的Node管理方式,kubelet進程會定時向Master彙報自身情報,如操作系統、Docker版本、CPU和內存,以及有哪些Pod在運行等等,這樣Master可以獲知每個Node節點的資源使用情況,冰實現高效均衡的資源調度策略。、

 

3.Pod

  運行於Node節點上,若干相關容器的組合。Pod內包含的容器運行在同一宿主機上,使用相同的網絡命名空間、IP地址和端口,能夠通過localhost進行通。Pod是Kurbernetes進行創建、調度和管理的最小單位,它提供了比容器更高層次的抽象,使得部署和管理更加靈活。一個Pod可以包含一個容器或者多個相關容器。

  Pod其實有兩種類型:普通Pod和靜態Pod,後者比較特殊,它並不存在Kubernetes的etcd存儲中,而是存放在某個具體的Node上的一個具體文件中,並且只在此Node上啓動。普通Pod一旦被創建,就會被放入etcd存儲中,隨後會被Kubernetes Master調度到摸個具體的Node上進行綁定,隨後該Pod被對應的Node上的kubelet進程實例化成一組相關的Docker容器冰啓動起來,在。在默認情況下,當Pod裏的某個容器停止時,Kubernetes會自動檢測到這個問起並且重啓這個Pod(重啓Pod裏的所有容器),如果Pod所在的Node宕機,則會將這個Node上的所有Pod重新調度到其他節點上。

架構資料領取地址:895244712

4.Replication Controller

  Replication Controller用來管理Pod的副本,保證集羣中存在指定數量的Pod副本。集羣中副本的數量大於指定數量,則會停止指定數量之外的多餘容器數量,反之,則會啓動少於指定數量個數的容器,保證數量不變。Replication Controller是實現彈性伸縮、動態擴容和滾動升級的核心。

 

5.Service

  Service定義了Pod的邏輯集合和訪問該集合的策略,是真實服務的抽象。Service提供了一個統一的服務訪問入口以及服務代理和發現機制,關聯多個相同Label的Pod,用戶不需要了解後臺Pod是如何運行。

外部系統訪問Service的問題

  首先需要弄明白Kubernetes的三種IP這個問題

    Node IP:Node節點的IP地址

    Pod IP: Pod的IP地址

    Cluster IP:Service的IP地址

  首先,Node IP是Kubernetes集羣中節點的物理網卡IP地址,所有屬於這個網絡的服務器之間都能通過這個網絡直接通信。這也表明Kubernetes集羣之外的節點訪問Kubernetes集羣之內的某個節點或者TCP/IP服務的時候,必須通過Node IP進行通信

  其次,Pod IP是每個Pod的IP地址,他是Docker Engine根據docker0網橋的IP地址段進行分配的,通常是一個虛擬的二層網絡。

  最後Cluster IP是一個虛擬的IP,但更像是一個僞造的IP網絡,原因有以下幾點

  • Cluster IP僅僅作用於Kubernetes Service這個對象,並由Kubernetes管理和分配P地址
  • Cluster IP無法被ping,他沒有一個“實體網絡對象”來響應
  • Cluster IP只能結合Service Port組成一個具體的通信端口,單獨的Cluster IP不具備通信的基礎,並且他們屬於Kubernetes集羣這樣一個封閉的空間。

Kubernetes集羣之內,Node IP網、Pod IP網於Cluster IP網之間的通信,採用的是Kubernetes自己設計的一種編程方式的特殊路由規則。

 

6.Label

 Kubernetes中的任意API對象都是通過Label進行標識,Label的實質是一系列的Key/Value鍵值對,其中key於value由用戶自己指定。Label可以附加在各種資源對象上,如Node、Pod、Service、RC等,一個資源對象可以定義任意數量的Label,同一個Label也可以被添加到任意數量的資源對象上去。Label是Replication Controller和Service運行的基礎,二者通過Label來進行關聯Node上運行的Pod。

我們可以通過給指定的資源對象捆綁一個或者多個不同的Label來實現多維度的資源分組管理功能,以便於靈活、方便的進行資源分配、調度、配置等管理工作。

一些常用的Label如下:

  • 版本標籤:"release":"stable","release":"canary"......
  • 環境標籤:"environment":"dev","environment":"qa","environment":"production"
  • 架構標籤:"tier":"frontend","tier":"backend","tier":"middleware"
  • 分區標籤:"partition":"customerA","partition":"customerB"
  • 質量管控標籤:"track":"daily","track":"weekly"

  Label相當於我們熟悉的標籤,給某個資源對象定義一個Label就相當於給它大了一個標籤,隨後可以通過Label Selector(標籤選擇器)查詢和篩選擁有某些Label的資源對象,Kubernetes通過這種方式實現了類似SQL的簡單又通用的對象查詢機制。

架構資料領取地址:895244712

  Label Selector在Kubernetes中重要使用場景如下:

    •   kube-Controller進程通過資源對象RC上定義Label Selector來篩選要監控的Pod副本的數量,從而實現副本數量始終符合預期設定的全自動控制流程
    •   kube-proxy進程通過Service的Label Selector來選擇對應的Pod,自動建立起每個Service島對應Pod的請求轉發路由表,從而實現Service的智能負載均衡
    •   通過對某些Node定義特定的Label,並且在Pod定義文件中使用Nodeselector這種標籤調度策略,kuber-scheduler進程可以實現Pod”定向調度“的特性

 

•Kubernetes架構和組件

 

  - 服務分組,小集羣,多集羣

  - 服務分組,大集羣,單集羣

架構資料領取地址:895244712

Kubernetes 組件:

  Kubernetes Master控制組件,調度管理整個系統(集羣),包含如下組件:

  1.Kubernetes API Server

    作爲Kubernetes系統的入口,其封裝了核心對象的增刪改查操作,以RESTful API接口方式提供給外部客戶和內部組件調用。維護的REST對象持久化到Etcd中存儲。

  2.Kubernetes Scheduler

    爲新建立的Pod進行節點(node)選擇(即分配機器),負責集羣的資源調度。組件抽離,可以方便替換成其他調度器。

  3.Kubernetes Controller

    負責執行各種控制器,目前已經提供了很多控制器來保證Kubernetes的正常運行。

  4. Replication Controller

    管理維護Replication Controller,關聯Replication Controller和Pod,保證Replication Controller定義的副本數量與實際運行Pod數量一致。

  5. Node Controller

    管理維護Node,定期檢查Node的健康狀態,標識出(失效|未失效)的Node節點。

  6. Namespace Controller

    管理維護Namespace,定期清理無效的Namespace,包括Namesapce下的API對象,比如Pod、Service等。

  7. Service Controller

    管理維護Service,提供負載以及服務代理。

  8.EndPoints Controller

    管理維護Endpoints,關聯Service和Pod,創建Endpoints爲Service的後端,當Pod發生變化時,實時更新Endpoints。

  9. Service Account Controller

    管理維護Service Account,爲每個Namespace創建默認的Service Account,同時爲Service Account創建Service Account Secret。

  10. Persistent Volume Controller

    管理維護Persistent Volume和Persistent Volume Claim,爲新的Persistent Volume Claim分配Persistent Volume進行綁定,爲釋放的Persistent Volume執行清理回收。

  11. Daemon Set Controller

    管理維護Daemon Set,負責創建Daemon Pod,保證指定的Node上正常的運行Daemon Pod。

  12. Deployment Controller

    管理維護Deployment,關聯Deployment和Replication Controller,保證運行指定數量的Pod。當Deployment更新時,控制實現Replication Controller和 Pod的更新。

  13.Job Controller

    管理維護Job,爲Jod創建一次性任務Pod,保證完成Job指定完成的任務數目

  14. Pod Autoscaler Controller

    實現Pod的自動伸縮,定時獲取監控數據,進行策略匹配,當滿足條件時執行Pod的伸縮動作。

 

 Kubernetes Node運行節點,運行管理業務容器,包含如下組件:

  1.Kubelet

    負責管控容器,Kubelet會從Kubernetes API Server接收Pod的創建請求,啓動和停止容器,監控容器運行狀態並彙報給Kubernetes API Server。

  2.Kubernetes Proxy

    負責爲Pod創建代理服務,Kubernetes Proxy會從Kubernetes API Server獲取所有的Service信息,並根據Service的信息創建代理服務,實現Service到Pod的請求路由和轉發,從而實現Kubernetes層級的虛擬轉發網絡。

  3.Docker

    Node上需要運行容器服務

 

•如何搭建k8s 

     轉載自:
     作者:CodeSheep
     鏈接:https://www.jianshu.com/p/7d1fb03b8925

 

環境準備

 

    目前只是使用了2臺機器:2臺百度雲的雲服務器,如果需要增加多個節點,根據文件的節點機器,自行添加即可!

 

    matser:106.12.34.183

 

    node1:106.12.34.229

 

 

先設置master節點和所有slave節點的主機名

 

master上執行:

hostnamectl --static set-hostname  k8s-master

slave上執行:

hostnamectl --static set-hostname  k8s-node-1

修改master和slave上的hosts

在master和slave的/etc/hosts文件中均加入以下內容:

106.12.34.183   k8s-master
106.12.34.183   etcd
106.12.34.183   registry
192.12.34.229   k8s-node-1

關閉master和slave上的防火牆

systemctl disable firewalld.service
systemctl stop firewalld.service

部署Master節點

master節點需要安裝以下組件:

  • etcd
  • flannel
  • docker
  • kubernets

下面按順序闡述

1. etcd安裝

  • 安裝命令:yum install etcd -y
  • 編輯etcd的默認配置文件/etc/etcd/etcd.conf
# [member]
ETCD_NAME=master
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
#ETCD_WAL_DIR=""
#ETCD_SNAPSHOT_COUNT="10000"
#ETCD_HEARTBEAT_INTERVAL="100"
#ETCD_ELECTION_TIMEOUT="1000"
#ETCD_LISTEN_PEER_URLS="http://localhost:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379,http://0.0.0.0:4001"
#ETCD_MAX_SNAPSHOTS="5"
#ETCD_MAX_WALS="5"
#ETCD_CORS=""
#
#[cluster]
#ETCD_INITIAL_ADVERTISE_PEER_URLS="http://localhost:2380"
# if you use different ETCD_NAME (e.g. test), set ETCD_INITIAL_CLUSTER value for this name, i.e. "test=http://..."
#ETCD_INITIAL_CLUSTER="default=http://localhost:2380"
#ETCD_INITIAL_CLUSTER_STATE="new"
#ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_ADVERTISE_CLIENT_URLS="http://etcd:2379,http://etcd:4001"
#ETCD_DISCOVERY=""
#ETCD_DISCOVERY_SRV=""
#ETCD_DISCOVERY_FALLBACK="proxy"
#ETCD_DISCOVERY_PROXY=""
#ETCD_STRICT_RECONFIG_CHECK="false"
#ETCD_AUTO_COMPACTION_RETENTION="0"
#ETCD_ENABLE_V2="true"
#
#[proxy]
#ETCD_PROXY="off"
#ETCD_PROXY_FAILURE_WAIT="5000"
#ETCD_PROXY_REFRESH_INTERVAL="30000"
#ETCD_PROXY_DIAL_TIMEOUT="1000"
#ETCD_PROXY_WRITE_TIMEOUT="5000"
#ETCD_PROXY_READ_TIMEOUT="0"
#
#[security]
#ETCD_CERT_FILE=""
#ETCD_KEY_FILE=""
#ETCD_CLIENT_CERT_AUTH="false"
#ETCD_TRUSTED_CA_FILE=""
#ETCD_AUTO_TLS="false"
#ETCD_PEER_CERT_FILE=""
#ETCD_PEER_KEY_FILE=""
#ETCD_PEER_CLIENT_CERT_AUTH="false"
#ETCD_PEER_TRUSTED_CA_FILE=""
#ETCD_PEER_AUTO_TLS="false"
#
#[logging]
#ETCD_DEBUG="false"
# examples for -log-package-levels etcdserver=WARNING,security=DEBUG
#ETCD_LOG_PACKAGE_LEVELS=""
#
#[profiling]
#ETCD_ENABLE_PPROF="false"
#ETCD_METRICS="basic"
#
#[auth]
#ETCD_AUTH_TOKEN="simple"
  • 啓動etcd並驗證

首先啓動etcd服務

systemctl start etcd // 啓動etcd服務

再獲取etcd的健康指標看看:

etcdctl -C http://etcd:2379 cluster-health
etcdctl -C http://etcd:4001 cluster-health

查看etcd集羣健康度

2. flannel安裝

  • 安裝命令:yum install flannel
  • 配置flannel:/etc/sysconfig/flanneld
# Flanneld configuration options  
 
# etcd url location.  Point this to the server where etcd runs
FLANNEL_ETCD_ENDPOINTS="http://etcd:2379"
 
# etcd config key.  This is the configuration key that flannel queries
# For address range assignment
FLANNEL_ETCD_PREFIX="/atomic.io/network"
 
# Any additional options that you want to pass
#FLANNEL_OPTIONS=""
  • 配置etcd中關於flannel的key
etcdctl mk /atomic.io/network/config '{ "Network": "10.0.0.0/16" }'

配置etcd中關於flannel的key

  • 啓動flannel並設置開機自啓
systemctl start flanneld.service
systemctl enable flanneld.service

3. docker安裝

該部分網上教程太多了,主要步驟如下

  • 安裝命令:yum install docker -y
  • 開啓docker服務:service docker start
  • 設置docker開啓自啓動:chkconfig docker on

4. kubernets安裝

k8s的安裝命令很簡單,執行:

yum install kubernetes

但k8s需要配置的東西比較多,正如第一節“環境介紹”中提及的,畢竟master上需要運行以下組件:

  • kube-apiserver
  • kube-scheduler
  • kube-controller-manager

下面詳細闡述:

  • 配置/etc/kubernetes/apiserver文件
###
# kubernetes system config
#
# The following values are used to configure the kube-apiserver
#
 
# The address on the local server to listen to.
KUBE_API_ADDRESS="--address=0.0.0.0"
 
# The port on the local server to listen on.
KUBE_API_PORT="--port=8080"
 
# Port minions listen on
KUBELET_PORT="--kubelet-port=10250"
 
# Comma separated list of nodes in the etcd cluster
KUBE_ETCD_SERVERS="--etcd-servers=http://etcd:2379"
 
# Address range to use for services
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"
 
# default admission control policies
# KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota"
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"
 
# Add your own!
KUBE_API_ARGS=""
  • 配置/etc/kubernetes/config文件
###
# kubernetes system config
#
# The following values are used to configure various aspects of all
# kubernetes services, including
#
#   kube-apiserver.service
#   kube-controller-manager.service
#   kube-scheduler.service
#   kubelet.service
#   kube-proxy.service
# logging to stderr means we get it in the systemd journal
KUBE_LOGTOSTDERR="--logtostderr=true"
 
# journal message level, 0 is debug
KUBE_LOG_LEVEL="--v=0"
 
# Should this cluster be allowed to run privileged docker containers
KUBE_ALLOW_PRIV="--allow-privileged=false"
 
# How the controller-manager, scheduler, and proxy find the apiserver
KUBE_MASTER="--master=http://k8s-master:8080"
  • 啓動k8s各個組件
systemctl start kube-apiserver.service
systemctl start kube-controller-manager.service
systemctl start kube-scheduler.service
  • 設置k8s各組件開機啓動
systemctl enable kube-apiserver.service
systemctl enable kube-controller-manager.service
systemctl enable kube-scheduler.service

部署Slave節點

slave節點需要安裝以下組件:

  • flannel
  • docker
  • kubernetes

下面按順序闡述:

1. flannel安裝

  • 安裝命令:yum install flannel
  • 配置flannel:/etc/sysconfig/flanneld
# Flanneld configuration options  
 
# etcd url location.  Point this to the server where etcd runs
FLANNEL_ETCD_ENDPOINTS="http://etcd:2379"
 
# etcd config key.  This is the configuration key that flannel queries
# For address range assignment
FLANNEL_ETCD_PREFIX="/atomic.io/network"
 
# Any additional options that you want to pass
#FLANNEL_OPTIONS=""
  • 啓動flannel並設置開機自啓
systemctl start flanneld.service
systemctl enable flanneld.service

2. docker安裝

參考前文master節點上部署docker過程,此處不再贅述

3. kubernetes安裝

安裝命令:yum install kubernetes

不同於master節點,slave節點上需要運行kubernetes的如下組件:

  • kubelet
  • kubernets-proxy

下面詳細闡述要配置的東西:

  • 配置/etc/kubernetes/config
###
# kubernetes system config
#
# The following values are used to configure various aspects of all
# kubernetes services, including
#
#   kube-apiserver.service
#   kube-controller-manager.service
#   kube-scheduler.service
#   kubelet.service
#   kube-proxy.service
# logging to stderr means we get it in the systemd journal
KUBE_LOGTOSTDERR="--logtostderr=true"
 
# journal message level, 0 is debug
KUBE_LOG_LEVEL="--v=0"
 
# Should this cluster be allowed to run privileged docker containers
KUBE_ALLOW_PRIV="--allow-privileged=false"
 
# How the controller-manager, scheduler, and proxy find the apiserver
KUBE_MASTER="--master=http://k8s-master:8080"
  • 配置/etc/kubernetes/kubelet
###
# kubernetes kubelet (minion) config
 
# The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces)
KUBELET_ADDRESS="--address=0.0.0.0"
 
# The port for the info server to serve on
# KUBELET_PORT="--port=10250"
 
# You may leave this blank to use the actual hostname
KUBELET_HOSTNAME="--hostname-override=k8s-node-1"
 
# location of the api-server
KUBELET_API_SERVER="--api-servers=http://k8s-master:8080"
 
# pod infrastructure container
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"
 
# Add your own!
KUBELET_ARGS=""
  • 啓動kube服務
systemctl start kubelet.service
systemctl start kube-proxy.service
  • 設置k8s組件開機自啓
systemctl enable kubelet.service
systemctl enable kube-proxy.service

至此爲止,k8s集羣的搭建過程就完成了,下面來驗證一下集羣是否搭建成功了

驗證集羣狀態

  • 查看端點信息:kubectl get endpoints

端點信息

  • 查看集羣信息:kubectl cluster-info

集羣信息

  • 獲取集羣中的節點狀態: kubectl get nodes

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章