K8s Scheduler(4-2)

理解resource limit 會(huì)如何影響pod 調(diào)度

  • Kubernetes 提供request 和 limit 兩種方式設(shè)置容器資源。

  • 為了提高資源利用率,k8s調(diào)度時(shí)根據(jù)pod 的request值計(jì)算調(diào)度策略筋蓖,從而實(shí)現(xiàn)節(jié)點(diǎn)資源超賣。

  • k8s根據(jù)limit限制pod使用資源殖演,當(dāng)內(nèi)存超過(guò)limit時(shí)會(huì)觸發(fā)oom假栓。 且限制pod的cpu 不允許超過(guò)limit。

  • 根據(jù)pod的 request和limit点晴,k8s會(huì)為pod 計(jì)算服務(wù)質(zhì)量偏形,并分為Guaranteed(requests和limits顯示設(shè)置且相等或者只設(shè)置了limits,那么requests也會(huì)與之相等), Burstable(limits和requests顯示設(shè)置不相等), BestEffort 這3級(jí)觉鼻。當(dāng)節(jié)點(diǎn)資源不足時(shí)俊扭,發(fā)生驅(qū)逐或者oom時(shí), Guaranteed 級(jí)別的pod 優(yōu)先保護(hù)坠陈, Burstable 節(jié)點(diǎn)次之(request越大萨惑,使用資源量越少 保護(hù)級(jí)別越高), BestEffort 最先被驅(qū)逐仇矾。

  • Kubernetes提供了RequestQuota和LimitRange 用于設(shè)置namespace 內(nèi)pod 的資源范圍 和 規(guī)挠拱總量。 RequestQuota 用于設(shè)置各種類型對(duì)象的數(shù)量贮匕, cpu和內(nèi)存的總量姐仅。 LimitRange 用于設(shè)置pod或者容器 request和limit 的默認(rèn)值,最大最小值刻盐, 以及超賣比例(limit / request)掏膏。

  • 對(duì)于一些重要的線上應(yīng)用,我們應(yīng)該合理設(shè)置limit和request敦锌,limit和request 設(shè)置一致馒疹,資源不足時(shí)k8s會(huì)優(yōu)先保證這些pod正常運(yùn)行。

  • 為了提高資源利用率乙墙。 對(duì)一些非核心颖变,并且資源不長(zhǎng)期占用的應(yīng)用生均,可以適當(dāng)減少pod的request,這樣pod在調(diào)度時(shí)可以被分配到資源不是十分充裕的節(jié)點(diǎn)腥刹,提高使用率马胧。但是當(dāng)節(jié)點(diǎn)的資源不足時(shí),也會(huì)優(yōu)先被驅(qū)逐或被oom kill衔峰。

不使用調(diào)度器漓雅, 手動(dòng)調(diào)度一個(gè)pod

使用static pod可以實(shí)現(xiàn)手動(dòng)調(diào)度一個(gè)pod。

static pod的特點(diǎn)總結(jié)如下:

  1. 不通過(guò)apiserver watch朽色, 由本機(jī)的kubelet進(jìn)程執(zhí)行watch邻吞,并拉起
  2. 只在本機(jī)進(jìn)行調(diào)度
  3. 沒(méi)有健康檢查
  4. 不被controller manager調(diào)度
  5. 因?yàn)閍piserver里有pod的鏡像信息, 通過(guò)apiserver還是可以看到pod的信息
如何創(chuàng)建葫男?

方法一: kubelet啟動(dòng)時(shí)要指定參數(shù)kubelet --pod-manifest-path=<the directory>抱冷,這里的the directory要放置static pod的編排文件的目錄。 把static pod的編排文件放到此目錄下梢褐, kubelet可以監(jiān)聽(tīng)到變化旺遮, 并根據(jù)編排文件創(chuàng)建pod。

方法二: 指定--manifest-url=<URL>盈咳, kubelet會(huì)從這個(gè)URL下載編排文件耿眉, 并創(chuàng)建pod

如何刪除?

當(dāng)我們直接用kubectl的命令kubectl delete pod刪除一個(gè)靜態(tài)pod時(shí)鱼响, 我們會(huì)發(fā)現(xiàn)static pod過(guò)一段時(shí)間又會(huì)被kubelet拉起鸣剪。

要完全刪除一個(gè)static pod, 可以移除把該static pod的編排文件丈积, 從--pod-manifest-path=<the directory>所指定的目錄里移除即可筐骇。

使用場(chǎng)景?

因?yàn)閟tatic pod有一個(gè)特性是我們的應(yīng)用的docker 容器被刪除江滨,或者pod被kubectl誤刪了之后铛纬, static pod還能被kubelet進(jìn)程拉起。通過(guò)這種方式保證了應(yīng)用的可用性唬滑。 有點(diǎn)相當(dāng)于systemd的功能告唆, 但比systemd好的一點(diǎn)是, static pod的鏡像信息會(huì)在apiserver中注冊(cè)晶密。 這樣的話擒悬, 我們就可以統(tǒng)一對(duì)部署信息進(jìn)行可視化管理。 另外static調(diào)度了的是容器惹挟, 無(wú)需拷貝二進(jìn)制文件到主機(jī)上茄螃, 應(yīng)用封裝在鏡像里也保證了環(huán)境的一致性缝驳, 無(wú)論是應(yīng)用的編排文件還是應(yīng)用的鏡像都方便進(jìn)行版本管理和分發(fā)连锯。

實(shí)際生產(chǎn)中归苍, static pod可以用來(lái)部署kubernetes的kube-proxy, kube-scheduler, kube-controller-manager, kube-apiserver等進(jìn)程。

當(dāng)我們要部署一個(gè)有狀態(tài)的應(yīng)用运怖, 有幾種方式:

  1. 使用statefulset
  2. 給主機(jī)打上label拼弃,只允許主機(jī)在這幾臺(tái)主機(jī)上調(diào)度
  3. 通過(guò)掛載ceph盤來(lái)存儲(chǔ)有狀態(tài)數(shù)據(jù)(要求master和node節(jié)點(diǎn)上都要安裝rbd工具)
  4. 使用static pod ,但是這種方式適合那些無(wú)滾動(dòng)升級(jí)需求摇展, 無(wú)擴(kuò)縮容需求吻氧,不頻繁進(jìn)行升級(jí)的應(yīng)用

常用的優(yōu)選算法介紹:

least_requested分值計(jì)算方式 (cpu((capacity-sum(requested))10/capacity) + memory((capacity-sum(requested))10/capacity))/2
其cpu和menmory分值各占一半。
balanced_resource_allocation是選用cpu和內(nèi)存使用最為接近的節(jié)點(diǎn)咏连,基于least_requested分值的計(jì)算結(jié)果判定盯孙。

那么schedule里的policy是啥樣子的呢:

{
"kind" : "Policy",
"apiVersion" : "v1",
"predicates" : [
    {"name" : "PodFitsPorts"},
    {"name" : "PodFitsResources"},
    {"name" : "NoDiskConflict"},
    {"name" : "MatchNodeSelector"},
    {"name" : "HostName"}
    ],
"priorities" : [
    {"name" : "LeastRequestedPriority", "weight" : 1},
    {"name" : "BalancedResourceAllocation", "weight" : 1},
    {"name" : "ServiceSpreadingPriority", "weight" : 1},
    {"name" : "EqualPriority", "weight" : 1}
    ]
}

*** 4. controller的區(qū)別 ***

controller manager作為集群內(nèi)部的管理控制中心,負(fù)責(zé)集群內(nèi)的Node祟滴,Pod副本振惰,服務(wù)端點(diǎn)(endpoint),命名空間(namespace)等的管理垄懂,當(dāng)某個(gè)Node意外宕機(jī)骑晶,CM會(huì)及時(shí)發(fā)現(xiàn)此故障并執(zhí)行自動(dòng)化修復(fù)流程,確保集群始終處于預(yù)期的工作狀態(tài)草慧。

controller management包括:replication controller桶蛔,node controller,rescourseQuota controller漫谷,namespaces controller仔雷,serviceAccount controller,token controller舔示,service tontroller和endpoint controller朽寞。CM是這些controller的核心管理者。

Replication Controller

RC的作用是確保在任何時(shí)候集群中一個(gè)RC所關(guān)聯(lián)的Pod副本數(shù)量保持預(yù)設(shè)值斩郎。

最好不用越過(guò)RC而直接創(chuàng)建Pod脑融,因?yàn)橥ㄟ^(guò)RC管理Pod副本,實(shí)現(xiàn)自動(dòng)創(chuàng)建缩宜,補(bǔ)足肘迎,替換,刪除Pod副本锻煌,提供系統(tǒng)的容災(zāi)能力妓布。

總結(jié)一下RC的職責(zé):

1.確保當(dāng)前集群中有且僅有N個(gè)Pod實(shí)例

2.通過(guò)調(diào)整RC中yaml文件的spec.replicas屬性值來(lái)實(shí)現(xiàn)系統(tǒng)擴(kuò)容或縮容

3.通過(guò)改變RC中的Pod模板來(lái)實(shí)現(xiàn)系統(tǒng)的滾動(dòng)升級(jí)。

再總結(jié)一下RC的典型使用場(chǎng)景宋梧,如下

1.重新調(diào)度

2.彈性伸縮

3.滾動(dòng)更新

Node controller

kubelet進(jìn)程在啟動(dòng)時(shí)通過(guò)API server注冊(cè)自身節(jié)點(diǎn)信息匣沼,并定時(shí)向API server匯報(bào)狀態(tài)信息,API server更新這些信息到etcd中捂龄。

Node controller通過(guò)API server定時(shí)獲取Node的相關(guān)信息释涛,實(shí)現(xiàn)管理和監(jiān)控Node加叁。

endpoint controller 和service controller

endpoint表示了一個(gè)service對(duì)應(yīng)的所有pod副本的訪問(wèn)地址,而endpoint controller就是負(fù)責(zé)生成和維護(hù)所有endpoint對(duì)象的控制器唇撬。負(fù)責(zé)監(jiān)聽(tīng)service和對(duì)應(yīng)的Pod副本的變化它匕,若service被刪除,則刪除與該service同名的endpoint對(duì)象窖认,若檢測(cè)到新的service創(chuàng)建或修改豫柬,則先根據(jù)該service獲取相應(yīng)的pod列表,然后創(chuàng)建或更新service對(duì)應(yīng)的endpoint對(duì)象扑浸。

那么endpoint對(duì)象如何使用呢埠胖。答案是在每個(gè)node上的kube-proxy進(jìn)程子檀,該進(jìn)程獲得每個(gè)service的endpoint,實(shí)現(xiàn)service的負(fù)載均衡功能。

Namespace controller

用戶通過(guò)API server可以創(chuàng)建新的Namespace并保存在etcd中锤悄,namespace controller定時(shí)通過(guò)API server讀取這些namespace信息醋界,若namespace被刪除服鹅,則NC刪除該namespace下的RC混蔼,Pod等資源對(duì)象。

如果namespace controller觀察到namespace設(shè)置了刪除期限系奉,同時(shí)namespace的spec.finalizers域值為空檬贰,則NC將通過(guò)API server刪除該namespace資源。

ReplicaSet

ReplicaSet的目的是在任何時(shí)候都maintain一組穩(wěn)定的pod replicas缺亮,常用來(lái)確保指定數(shù)量的pod replica可用翁涤。ReplicaSet具有selector,replicas, podTemplate字段萌踱。通過(guò)pod的metadata.ownerReferences字段來(lái)關(guān)聯(lián)ReplicaSet和Pod葵礼。

注意:當(dāng)創(chuàng)建的pod的label符合ReplicaSet的selector,且該pod不屬于任何controller并鸵,則該pod會(huì)被自動(dòng)歸為該ReplicaSet擁有鸳粉,導(dǎo)致ReplicaSet下的pod不相同;同時(shí)园担,會(huì)影響ReplicaSet本身的replica pod的個(gè)數(shù)届谈。

建議使用Deployment來(lái)管理ReplicaSet,而不是直接使用弯汰,除非需要定制化的更新測(cè)例或不需要更新艰山。

因?yàn)閐eployment不僅具備了replicaSet的功能,同時(shí)還支持事件和狀態(tài)查看咏闪,回滾曙搬,版本記錄,對(duì)于每次升級(jí)可以暫停和啟動(dòng)。

Deployment

Deployment對(duì)Pod和ReplicaSet提供聲明式的更新纵装。在描述預(yù)期狀態(tài)后征讲,Deployment會(huì)以可控的頻率下使得實(shí)際狀態(tài)符合預(yù)期狀態(tài)。

默認(rèn)情況下搂擦,Deployment保證最多25%的pod不可靠稳诚,pod數(shù)量最多超出25%哗脖。

StatefulSets

StatefulSets主要用來(lái)管理有狀態(tài)的app瀑踢。跟Deployment一樣,StatefulSet用來(lái)管理Pod才避,但不同的是橱夭,StatefulSets中的每個(gè)pod都維護(hù)一個(gè)嚴(yán)格的identifier并在reschedule時(shí)不變。

StatefulSet具有以下特點(diǎn):

  • Stable, unique network identifiers.
  • Stable, persistent storage.
  • Ordered, graceful deployment and scaling.
  • Ordered, automated rolling updates.

限制:

  • Pod的storage要么基于請(qǐng)求的storage class由PersistentVolume Provisioner設(shè)置桑逝,要么由admin提前設(shè)置好棘劣;
  • 刪除或scale down StatefulSet將不會(huì)刪除相關(guān)的volumes,用于保證數(shù)據(jù)安全楞遏;
  • StatefulSets目前需要?jiǎng)?chuàng)建headless service來(lái)負(fù)責(zé)pod的netework identity茬暇,用戶負(fù)責(zé)創(chuàng)建該headless service;
  • StatefulSet刪除后不保證pod結(jié)束寡喝,pod會(huì)按順序gracefully的結(jié)束糙俗;
  • 當(dāng)使用默認(rèn)的Pod Management Policy(OrderedReady)作為rollupdate policy,可能需要人工干預(yù)來(lái)走出broken state预鬓。
  • StatefulSet上部署和擴(kuò)展的規(guī)則:創(chuàng)建pod的順序由0到N巧骚,刪除的順序正好相反;擴(kuò)展時(shí)格二,前面的pod必須是Running和Ready狀態(tài)劈彪,刪除時(shí),后續(xù)pod必須是terminated顶猜。

K8S 1.7之后沧奴,指定.spec.updateStrategy來(lái)設(shè)置更新策略,當(dāng).spec.updateStrategy.type為OnDelete時(shí)长窄,在pod template改動(dòng)后將不會(huì)自動(dòng)更新Pods扼仲;為RollingUpdate,默認(rèn)策略抄淑,將自動(dòng)更新pod屠凶。RollingUpdate更新策略可以設(shè)置partition,通過(guò)設(shè)置字段 .spec.updateStrategy.rollingUpdate.partition來(lái)實(shí)現(xiàn)肆资,當(dāng)pod template更新后矗愧,只有ordinal大于等于partition的pod才會(huì)更新,小于partition的pod不更新。當(dāng).spec.replicas小于partition唉韭,所有pod不更新夜涕。

Job

Job創(chuàng)建一個(gè)或多個(gè)pod并確保指定數(shù)量的pod成功終止。當(dāng)指定數(shù)量的pod成功終止后属愤,job結(jié)束女器。場(chǎng)景:當(dāng)創(chuàng)建的pod不能完成時(shí),job會(huì)創(chuàng)建新的pod來(lái)完成任務(wù)住诸。

下面是Job的示例驾胆。

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  backoffLimit:6
  activeDeadlineSeconds: 100 #
  ttlSecondsAfterFinished: 100 
  template:
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4

restartPolicy只允許Never或OnFailure。

通過(guò)設(shè)置.spec.completions和.spec.parallelism屬性來(lái)完成不同的任務(wù)贱呐,前者表示成功完成的任務(wù)數(shù)量丧诺,后者表示并行任務(wù)數(shù)量,默認(rèn)都為1.當(dāng).spec.parallelism設(shè)置為0時(shí)奄薇,job將被暫停驳阎。

通過(guò).spec.backoffLimit來(lái)設(shè)置pod失敗后的重試次數(shù),默認(rèn)為6馁蒂,重試的delay時(shí)間指數(shù)式增長(zhǎng)呵晚,最長(zhǎng)6分鐘。

當(dāng)Job complete沫屡,將不會(huì)創(chuàng)建pod饵隙,old pod也不會(huì)被刪除,這樣可以查看log谁鳍。同時(shí)癞季,Job也存在,這樣可以查看status倘潜”疗猓可以通過(guò)kubectl delete來(lái)人工刪除。

Job終止可能因?yàn)槭〈螖?shù)超過(guò).spec.backoffLimit涮因,或者因?yàn)閖ob的運(yùn)行時(shí)間炒超過(guò)設(shè)置的.spec.activeDeadlineSeconds废睦。當(dāng)Job的運(yùn)行時(shí)間超過(guò)activeDeadlineSeconds,所有運(yùn)行的pod被終止养泡,Job狀態(tài)變?yōu)镕ailed嗜湃,reason: DeadlineExceeded。

-Cron Job

終止的Job不被回收會(huì)浪費(fèi)資源澜掩,可以使用cron job來(lái)管理job并清理job购披。

Cron Job創(chuàng)建基于時(shí)間調(diào)度的job,時(shí)區(qū)為master node的時(shí)區(qū)肩榕。當(dāng)Cron job大于100次沒(méi)有被調(diào)度刚陡,將不會(huì)調(diào)度job并打印error信息。Cron job只負(fù)責(zé)創(chuàng)建符合schedule的job,而job負(fù)責(zé)pod的管理筐乳。

activeDeadlineSeconds

通過(guò)指定job存活時(shí)間歌殃,來(lái)結(jié)束一個(gè)job。當(dāng)job運(yùn)行時(shí)間達(dá)到activeDeadlineSeconds指定的時(shí)間后蝙云,job會(huì)停止由它啟動(dòng)的所有任務(wù)(如:pod)氓皱,并設(shè)置job的狀態(tài)為failed, reason: DeadlineExceeded

TTL Controller提供了一種機(jī)制來(lái)限制resource object執(zhí)行完存活的時(shí)間,目前只處理Job勃刨。

ttlSecondsAfterFinished

使用場(chǎng)景:默認(rèn)情況下波材,job異常或者成功結(jié)束后朵你,包括job啟動(dòng)的任務(wù)(pod)各聘,都不會(huì)被清理掉揣非,因?yàn)槟憧梢砸罁?jù)保存的job和pod抡医,查看狀態(tài)、日志早敬,以及調(diào)試等忌傻。這些用戶可以手動(dòng)刪除,用戶手動(dòng)刪除job搞监,job controller會(huì)級(jí)聯(lián)刪除對(duì)應(yīng)的pod水孩。

除了手動(dòng)刪除,通過(guò)指定參數(shù)ttlSecondsAfterFinished也可以實(shí)現(xiàn)自動(dòng)刪除job琐驴,以及級(jí)聯(lián)的資源俘种,如:pod。如果設(shè)置為0绝淡,job會(huì)被立即刪除宙刘。如果不指定,job則不會(huì)被刪除牢酵。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末悬包,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子馍乙,更是在濱河造成了極大的恐慌布近,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丝格,死亡現(xiàn)場(chǎng)離奇詭異撑瞧,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)显蝌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門预伺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事扭屁∷闾福” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵料滥,是天一觀的道長(zhǎng)然眼。 經(jīng)常有香客問(wèn)我,道長(zhǎng)葵腹,這世上最難降的妖魔是什么高每? 我笑而不...
    開(kāi)封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮践宴,結(jié)果婚禮上鲸匿,老公的妹妹穿的比我還像新娘。我一直安慰自己阻肩,他們只是感情好带欢,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著烤惊,像睡著了一般乔煞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上柒室,一...
    開(kāi)封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天渡贾,我揣著相機(jī)與錄音,去河邊找鬼雄右。 笑死空骚,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的擂仍。 我是一名探鬼主播囤屹,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼防楷!你這毒婦竟也來(lái)了牺丙?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤复局,失蹤者是張志新(化名)和其女友劉穎冲簿,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體亿昏,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡峦剔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了角钩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吝沫。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡呻澜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出惨险,到底是詐尸還是另有隱情羹幸,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布辫愉,位于F島的核電站栅受,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏恭朗。R本人自食惡果不足惜屏镊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望痰腮。 院中可真熱鬧而芥,春花似錦、人聲如沸膀值。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)虫腋。三九已至骄酗,卻和暖如春稀余,著一層夾襖步出監(jiān)牢的瞬間悦冀,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工睛琳, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盒蟆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓师骗,卻偏偏與公主長(zhǎng)得像历等,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子辟癌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345