優(yōu)勢+工具+實(shí)踐=DevOps&Docker的企業(yè)級落地

Markdown

識(shí)別二維碼報(bào)名活動(dòng)

8月19日,來自微軟、數(shù)人云、京東、當(dāng)當(dāng)網(wǎng)的四位IT老兵,《一起吹響Container+集結(jié)號》,看Serverless、DevOps、微服務(wù)、CI/CD、分布式調(diào)度任務(wù)等技術(shù),在各個(gè)場景中與Container發(fā)生的碰撞與交互。

數(shù)人云:DevOps&Docker已經(jīng)逐步完成布道階段,在越來越多的場景中應(yīng)用并且獲得顯著的效果,本文將闡述了兩者結(jié)合在一起的優(yōu)勢以及相關(guān)實(shí)踐。

Docker通過模塊化、平臺(tái)獨(dú)立性、高效資源利用和快速安裝,顛覆了原有的應(yīng)用部署交付等方法,幫助DevOps更好地落地,兩者結(jié)合的優(yōu)勢有:

  • 快速交付
  • 實(shí)時(shí)更新應(yīng)用
  • 版本可靠
  • 提高質(zhì)量
  • 敏捷環(huán)境

什么是DevOps

敏捷開發(fā)基于適應(yīng)性應(yīng)用開發(fā)、持續(xù)改進(jìn)、持續(xù)交付,因此DevOps的目標(biāo)是在應(yīng)用交付的各個(gè)團(tuán)隊(duì)之間建立協(xié)作,并使應(yīng)用交付過程自動(dòng)化,從而不斷地測試、部署和監(jiān)控新發(fā)布的版本。

DevOps將開發(fā)和運(yùn)維協(xié)調(diào)在一起,尋求自動(dòng)化過程以保證應(yīng)用的質(zhì)量,通過DevOps模式,Docker可以構(gòu)建從GitHub代碼倉庫到應(yīng)用部署的一個(gè)持續(xù)交付的通道,從GitHub代碼倉庫到應(yīng)用部署。

DevOps如何結(jié)合Docker

Docker容器通過鏡像運(yùn)行,可以在本地或者存儲(chǔ)庫(如Docker Hub)上使用,假設(shè)作為一個(gè)用例,MySQL數(shù)據(jù)庫或其他數(shù)據(jù)庫提供的新版本經(jīng)常使用小BUG或補(bǔ)丁進(jìn)行修復(fù),如何在沒有延遲的情況下為終端用戶提供新版本?

Docker鏡像與代碼存儲(chǔ)庫相關(guān)聯(lián)——一個(gè)GitHub代碼倉庫或其他一些存儲(chǔ)庫,如AWS coUNK mit,若開發(fā)人員從GitHub代碼倉庫構(gòu)建Docker鏡像,并使其在Docker Hub到最終用戶,如果最終用戶將Docker鏡像部署為容器,那么會(huì)有以下幾個(gè)單獨(dú)運(yùn)行的階段:

1)將GitHub代碼倉庫構(gòu)建到Docker鏡像中(使用Docker構(gòu)建命令)

2)測試Docker鏡像(使用Docker run命令)

3)上傳Docker鏡像到Docker
Hub(使用Docker推送命令)

4)終端用戶下載Docker鏡像(使用Docker pull命令)

5)終端用戶運(yùn)行一個(gè)Docker容器(使用Docker run命令)

6)終端用戶部署一個(gè)應(yīng)用(如,使用AWS彈性Beanstalk)

7)終端用戶監(jiān)控應(yīng)用

Markdown

當(dāng)新的MySQL數(shù)據(jù)庫在短時(shí)間內(nèi)(可能僅僅一天),出現(xiàn)新的BUG,需要將過程重復(fù)。

但DevOps模式可以用于Docker鏡像從GitHub到部署,且不需要用戶或管理員進(jìn)行干預(yù)。

DevOps的設(shè)計(jì)模式

DevOps的設(shè)計(jì)模式以持續(xù)集成、持續(xù)測試、持續(xù)交付和持續(xù)部署為中心,自動(dòng)化、協(xié)作和持續(xù)監(jiān)控是DevOps中使用的一些其他設(shè)計(jì)模式。

【持續(xù)集成】

持續(xù)集成是不斷地將源代碼集成到一個(gè)新的構(gòu)建或發(fā)布的過程,源代碼可以在本地存儲(chǔ)中,也可以在GitHub或AWS CodeCommit中。

【持續(xù)測試】

連續(xù)測試新的構(gòu)建或發(fā)布即持續(xù)測試,Jenkins之類的工具為持續(xù)測試提供了幾個(gè)特性:在Jenkins的每個(gè)階段都有用戶去輸入,它提供了一些插件,如Docker構(gòu)建步驟插件,分別測試每個(gè)Docker應(yīng)用階段:運(yùn)行容器、上傳鏡像、停止容器。

【持續(xù)交付】

持續(xù)交付為終端用戶提供新的構(gòu)建,以便在生產(chǎn)中部署,對于Docker應(yīng)用,持續(xù)交付包括在Docker Hub或Amazon EC2容器等存儲(chǔ)庫中提供Docker鏡像的每個(gè)新版本/標(biāo)記。

【持續(xù)部署】

持續(xù)部署是不斷地部署Docker鏡像的最新版本,每當(dāng)一個(gè)Docker鏡像的新版本/標(biāo)簽可用時(shí),Docker鏡像就會(huì)被部署到生產(chǎn)環(huán)境中,Kubernetes 容器管理器已經(jīng)提供了一些功能,如滾動(dòng)更新,無需中斷即可將Docker鏡像升級到最新的服務(wù),Jenkins滾動(dòng)更新是自動(dòng)化的,當(dāng)Docker鏡像的新版本/標(biāo)簽可用時(shí),就會(huì)不斷更新。

【持續(xù)監(jiān)控】

持續(xù)監(jiān)控可以監(jiān)控正在運(yùn)行應(yīng)用的過程,類似于Sematext可以監(jiān)控Docker應(yīng)用,部署Sematext Docker代理來監(jiān)控Kubernetes的集群指標(biāo)并收集日志。

【自動(dòng)化】

對于Docker應(yīng)用,可以自動(dòng)安裝一些如Kubernetes這種非常復(fù)雜的工具,在其1.4版本中包含了名為Kubeadm的新工具,可以在Ubuntu和CentOS上自動(dòng)安裝Kubernetes上,但CoreOS上不支持Kubeadm工具。

【協(xié)作】

協(xié)作涉及到跨團(tuán)隊(duì)的工作和資源共享,如不同的開發(fā)團(tuán)隊(duì)可以在GitHub庫中開發(fā)Docker鏡像的不同版本代碼,所有的Docker鏡像標(biāo)簽都被構(gòu)建并不斷上傳至Docker Hub,Jenkins提供了許多分支渠道項(xiàng)目,用于從GitHub存儲(chǔ)庫等存儲(chǔ)庫的多個(gè)分支中構(gòu)建代碼。

DevOps的工具

Jenkins

Markdown

Jenkins是一種常用的自動(dòng)化和持續(xù)交付工具,可用于不斷地構(gòu)建、測試和交付Docker鏡像,Jenkins提供了幾個(gè)可以與Docker一起使用的插件,如Docker插件,Docker構(gòu)建步驟插件,Amazon EC2插件。

  • 使用Amazon EC2插件,可以使用云配置為Jenkins的代理服務(wù)器動(dòng)態(tài)提供實(shí)例。
  • Docker插件可以用來配置云,在Docker容器中運(yùn)行Jenkins項(xiàng)目。
  • Docker構(gòu)建步驟插件用于測試Docker鏡像的各個(gè)階段:構(gòu)建鏡像、運(yùn)行容器、將鏡像Push到 Docker Hub停止并刪除Docker。

CodeCommit & CodeBuild & Elastic Beanstalk

Markdown

AWS提供了一些DevOps工具:

CodeCommit是一個(gè)類似于GitHub的版本控制服務(wù),用來存儲(chǔ)和管理源代碼文件,AWS CodeBuild用于構(gòu)建和測試代碼的DevOps工具,需要構(gòu)建的代碼可以從GitHub或coUNK mit持續(xù)集成,從CodeBuild中輸出的Docker鏡像可以上傳到Docker Hub,也可以在構(gòu)建完成時(shí)上傳到Amazon EC2容器注冊中心。

CodeBuild提供持續(xù)且自動(dòng)化的過程用于構(gòu)建、測試、交付階段。

Elastic Beanstalk用于在云端部署和擴(kuò)展Docker應(yīng)用,提供了自動(dòng)容量供應(yīng)、負(fù)載均衡、容縮和監(jiān)控,Beanstalk應(yīng)用和環(huán)境可以從一個(gè)打包為ZIP文件的Dockerfile創(chuàng)建,該文件包含其他應(yīng)用資源,或僅僅來自一個(gè)未打包的Dockerfile,或可以在Dockerrun.aws中制定Docker應(yīng)用的配置,包括Docker鏡像和環(huán)境變量。Json文件是Dockerrun.aws的例子,列出了多個(gè)容器的配置,其中一個(gè)用于MySQL數(shù)據(jù)庫,另一個(gè)用戶Nginx服務(wù)器:

{
  "AWSEBDockerrunVersion": 2,
  "volumes": [
    {
      "name": "mysql-app",
      "host": {
        "sourcePath": "/var/app/current/mysql-app"
      }
    },
    {
      "name": "nginx-proxy-conf",
      "host": {
        "sourcePath": "/var/app/current/proxy/conf.d"
      }
    }
  ],
  "containerDefinitions": [
    {
      "name": "mysql-app",
      "image": "mysql",
      "environment": [
        {
            "name": "MYSQL_ROOT_PASSWORD",
            "value": "mysql"
        },
        {
            "name": "MYSQL_ALLOW_EMPTY_PASSWORD",
            "value": "yes"
        },
        {
            "name": "MYSQL_DATABASE",
            "value": "mysqldb"
        },
        {
            "name": "MYSQL_PASSWORD",
            "value": "mysql"
        }
    ],
      "essential": true,
      "memory": 128,
      "mountPoints": [
        {
          "sourceVolume": "mysql-app",
          "containerPath": "/var/mysql",
          "readOnly": true
        }
      ]
    },
    {
      "name": "nginx-proxy",
      "image": "nginx",
      "essential": true,
      "memory": 128,
      "portMappings": [
        {
          "hostPort": 80,
          "containerPort": 80
        }
      ],
      "links": [
        "mysql-app"
      ],
      "mountPoints": [
        {
          "sourceVolume": "mysql-app",
          "containerPath": "/var/mysql",
          "readOnly": true
        },
        {
          "sourceVolume": "nginx-proxy-conf",
          "containerPath": "/etc/nginx/conf.d",
          "readOnly": true
        }
      ]
    }
  ]
}

Beanstalk應(yīng)用程序部署的監(jiān)控:


Markdown

DevOps&Docker的實(shí)踐

Docker Datacenter提供讓企業(yè)更容易建立內(nèi)部CaaS環(huán)境,有助于企業(yè)應(yīng)用交付。

Docker Datacenter(DDC)為企業(yè)提供了一種方法:可以讓開發(fā)者輕松地部署應(yīng)用,而不必?fù)?dān)心從開發(fā)到生產(chǎn)的過程中產(chǎn)生的問題。

CaaS平臺(tái)提供容器和集群編排,通過為DDC構(gòu)建云端模板,開發(fā)者和IT操作人員可以將Dockerzed應(yīng)用遷移到云端。

DDC包括Docker Universal Control Plane(UCP)、The Docker Trusted Registry (DTR) , 和The Commercially Supported (CS) Docker Engine 。

Markdown

The Universal Control Plane

UCP是集群管理解決方案,可以安裝在本地或虛擬私有云上,UCP公開了標(biāo)準(zhǔn)的Docker API,可以繼續(xù)使用已知的工具管理集群,如仍然可以使用docker info 命令來查看集群的狀態(tài):

Containers: 15
Images: 10
ServerVersion: swarm/1.1.3
Role: primary
Strategy: spread
Filters: health, port, dependency, affinity, constraint
Nodes: 2
 ucp: <UCP_IP>:<PORT>
   └ Status: Healthy
   └ Containers: 20
 ucp-replica: <UCP_REPLICA>:<PORT>
   └ Status: Healthy
   └ Containers: 10

使用Docker UCP,仍然可以管理基礎(chǔ)設(shè)施的節(jié)點(diǎn):應(yīng)用、容器、網(wǎng)絡(luò)、鏡像等,Docker UCP有內(nèi)置身份驗(yàn)證機(jī)制,支持LDAP和Active Directory及基于角色的訪問控制(RBAC),確保只有授權(quán)用戶能夠訪問并對集群進(jìn)行更改。

Markdown

UCP是一個(gè)容器化的應(yīng)用,允許管理一組同一Docker集群的節(jié)點(diǎn),UCP的核心組件是名為UCP代理的全局調(diào)度服務(wù),運(yùn)行后將使用其他CUP組件部署容器。

The Docker Trusted Registry

安全性是開發(fā)者在企業(yè)采用Docker所面臨的最大挑戰(zhàn)之一,認(rèn)識(shí)到這一挑戰(zhàn)以及企業(yè)需要繼續(xù)在整個(gè)網(wǎng)絡(luò)中簡化安全性,Docker引入了Docker Trusted Registry(DTR)。

DTR使用的身份驗(yàn)證機(jī)制和Docker UCP相同將其內(nèi)置,還支持RBAC,允許在必要時(shí)實(shí)現(xiàn)個(gè)性化的訪問控制策略。

部署Docker Datacenter

運(yùn)行DDC主要有兩種選擇:部署整個(gè)堆棧,包括UCP和DTR在AWS上生成模板,或在Linux服務(wù)器上手動(dòng)操作,在本案例中,將使用Docker CaaS(容器作為服務(wù))提供的第二個(gè)選擇。

CaaS選項(xiàng)基本上是一個(gè)托管的SaaS解決方案,Docker引擎、UCP和DTR由Docker操作,容器節(jié)在服務(wù)器上運(yùn)行,本文將鏈接到AWS環(huán)境作為案例,但其實(shí)也可以在本地環(huán)境中運(yùn)行。

在AWS上部署節(jié)點(diǎn)集群

登錄到您的DDC賬戶(可以注冊試用Docer Datacenter版本)并在左側(cè)菜單中尋找云設(shè)置選項(xiàng),如下圖所示,包含可以鏈接的支持公有云應(yīng)用列表,用于創(chuàng)建和托管節(jié)點(diǎn),可用Docker Datacenter進(jìn)行管理。

Markdown

選擇AWS作為提供商,單擊Plug-and-Play圖表后,會(huì)出現(xiàn)對話框,需要進(jìn)入Role Delegation ARN(請參閱:https://docs.docker.com/docker-cloud/infrastructure/link-aws/

節(jié)點(diǎn)集群設(shè)置

鏈接到AWS環(huán)境后,進(jìn)行基礎(chǔ)設(shè)施設(shè)置,如下圖所示:

Markdown

點(diǎn)擊創(chuàng)建后,將被重定向到配置頁面——會(huì)被要求輸入集群的配置參數(shù):

Markdown

集群名稱沒有限制,也適用于標(biāo)簽字段,允許提供關(guān)于想要?jiǎng)?chuàng)建集群的額外描述。

建議列表也隨后出現(xiàn),作為提供者,必須選擇與自身賬戶鏈接的那個(gè),字段本身只需要一個(gè)選擇,而且不局限于創(chuàng)建托管在不同提供者的節(jié)點(diǎn)集群。

繼續(xù)選擇AWS區(qū)域和網(wǎng)絡(luò)(VPC),如果將VPC默認(rèn)設(shè)置為“Auto”那么所有的集群節(jié)點(diǎn)都將部署在一個(gè)新的自動(dòng)創(chuàng)建的VPC中。

Type/Size字段用于配置每個(gè)節(jié)點(diǎn)的CPU和RAM數(shù)量,IAM角色可以不受影響,并保存默認(rèn)值“None”剩下要配置的最后兩個(gè)字段是磁盤大小和節(jié)點(diǎn)數(shù)量,本文中,設(shè)置了10G的磁盤空間并創(chuàng)建了3個(gè)節(jié)點(diǎn)。

Markdown

點(diǎn)擊啟動(dòng)節(jié)點(diǎn)集群后,將重定向到節(jié)點(diǎn)集群概覽界面,可以跟蹤集群的狀態(tài),成功部署節(jié)點(diǎn)集群,部署的狀態(tài)就會(huì)出現(xiàn)在節(jié)點(diǎn)集群的名稱下。

再次點(diǎn)擊啟動(dòng)節(jié)點(diǎn)集群,能看到云提供商發(fā)生更改,因?yàn)橐呀?jīng)與Docker Datacenter相連,所有創(chuàng)建的節(jié)點(diǎn)都將在那里托管,可以在云平臺(tái)上用支持的方式進(jìn)行監(jiān)控。(參見Logz.io Docker日志收集器用于集中監(jiān)控Docker環(huán)境的方法:https://logz.io/blog/logz-io-docker-log-collector/

跨節(jié)點(diǎn)集群部署服務(wù)

接下來會(huì)詳細(xì)介紹如何跨節(jié)點(diǎn)集群部署服務(wù),本文中將使用Nginx:

Markdown

點(diǎn)擊左側(cè)菜單欄中的“服務(wù)”,將顯示主視圖的服務(wù)面板,而后點(diǎn)擊右上角的“Create”按鈕,將被重定向到部署獲取權(quán)鏡像的方式。

除了Jumpstart部分和公共鏡像,還有一部分可以定義自己的存儲(chǔ)庫,從中提取鏡像,這里將使用公開可用的鏡像。

Markdown

在搜索Docker Hub區(qū)域內(nèi)的文本框中輸入“Nginx”Enter后將看到與之匹配的可用鏡像列表,選擇第一項(xiàng)。

單擊列表項(xiàng)中的“Select”按鈕后,將重定向到Settings頁面,部署策略對以下事情非常重要:

  • 跨節(jié)點(diǎn)之間的負(fù)載均衡
  • 當(dāng)容器崩潰時(shí)的選項(xiàng):自動(dòng)重啟和自動(dòng)銷毀
  • 終止容器時(shí)的策略(此操作實(shí)際在終止時(shí)會(huì)破壞所有數(shù)據(jù))
  • 自動(dòng)重新部署選項(xiàng):當(dāng)新鏡像被推送或構(gòu)建時(shí)自動(dòng)重新部署服務(wù)
Markdown

為其他面板與端口添加運(yùn)行命令、內(nèi)存限制和CPU有關(guān)限制,本文實(shí)例中保留默認(rèn)值即可。

而后是Ports部分,可以在這里選擇發(fā)布哪些端口,并對外部公開(以及哪些不公開),本案例中使用的是80和443。

Markdown

接下來配置環(huán)境變量、和其他服務(wù)的鏈接,如把API作為單獨(dú)的服務(wù)部署,NGINX服務(wù)器將請求重定向到API服務(wù)時(shí),這些鏈接是有用的。

完成后,可以點(diǎn)擊“創(chuàng)建和部署“按鈕,將會(huì)重定向到服務(wù)概覽頁面,可以看到部署狀態(tài),前面步驟中輸入的配置概述、容器、鏈接、環(huán)境變量,以及用于訪問NGINX服務(wù)器的DSN節(jié)點(diǎn)等等。

Markdown

如果單擊節(jié)點(diǎn)中提供的鏈接,則會(huì)看到Nginx歡迎頁面。
如前所述,除了連接AWS賬戶外,還支持內(nèi)部節(jié)點(diǎn),但都需要安裝支持的操作系統(tǒng),單擊“在節(jié)點(diǎn)集群中自帶節(jié)點(diǎn)”按鈕,并在服務(wù)器中鍵入命令(在模式窗口內(nèi)提供),并在數(shù)據(jù)中心內(nèi)執(zhí)行類似節(jié)點(diǎn)的操作。

Markdown

原文作者:
Deepak Vohra、Daniel Berman

原文鏈接:
http://logz.io/blog/docker-datacenter
https://www.toadworld.com/platforms/mysql/b/weblog/archive/2017/01/17/devops-for-docker-a-trend-for-2017

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,656評論 3 419
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,855評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,254評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,473評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,014評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,833評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,016評論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,273評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,730評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,006評論 2 374

推薦閱讀更多精彩內(nèi)容