成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

K8s和云原生愛橫情仇

云計算 云原生
Johnny Boursiquot: 大家好,歡迎收聽 Go Time。這是一個多元化的討論節目,邀請特別嘉賓一起探討 Go 語言及其相關領域的各種話題,包括云基礎設施、分布式系統、微服務、無服務器架構,今天特別要討論的是非常流行且開源的容器編排平臺 Kubernetes。

Johnny[2] 和 Mat[3] 與 Kris Nova[4] 和 Joe Beda[5] 一起探討了 Kubernetes 和云原生。他們討論了 Kubernetes 推動的“云原生”應用的興起、使用 Kubernetes 的合適場合、運行如此大型的開源項目所面臨的挑戰、Kubernetes 的可擴展性以及 Kubernetes 如何融入更大的云原生世界。

過程中為符合中文慣用表達有適當刪改, 版權歸原作者所有.

圖片圖片

Johnny Boursiquot: 大家好,歡迎收聽 Go Time。這是一個多元化的討論節目,邀請特別嘉賓一起探討 Go 語言及其相關領域的各種話題,包括云基礎設施、分布式系統、微服務、無服務器架構,今天特別要討論的是非常流行且開源的容器編排平臺 Kubernetes。

我是 Johnny Boursiquot,今天和我一起的嘉賓陣容非常強大,正如 Mat Ryer 常說的那樣。今天我們請到了 Mat 本人,還有另外兩位對 Kubernetes 非常了解的嘉賓。請歡迎 Joe Beda,前 Heptio(譯者注: 現已被VMware收購) 的 CTO,現在是 VMware 的一員;以及 Kris Nova,一位杰出的作者,同時也是 Kubernetes 的全能專家。大家好!

Joe Beda: 大家好,大家好!

Kris Nova: 嗨!

Johnny Boursiquot: 大家好!

Mat Ryer: 很高興今天能請到你們上節目。這將是一次非常有趣的討論……我知道很多聽眾對 Kubernetes 很了解,或者至少我認為他們很了解 Kubernetes,但我想我們還是需要先統一一下基本概念。這是我們節目中經常做的事情---讓那些剛接觸 Go 的人、剛加入社區的人和那些已經深入了解 Kubernetes 背后有大量 Go 代碼的人都能有所收獲。

讓我們從基本問題開始,先弄清楚什么是容器編排,Kubernetes 在這個體系中扮演什么角色。

Joe Beda: Nova,你想先來解釋一下,還是我先來做一個簡短的 "什么是 Kubernetes" 五分鐘快速介紹?

Kris Nova: 我想聽你先做五分鐘的 Kubernetes 介紹,然后我可以再補充。

Joe Beda: 好的,你可以指出我哪里講錯了。

Kris Nova: [笑]

Joe Beda: 假設大家對容器有一定的基礎了解---為了統一認識,容器的基本概念是將一個程序及其所有依賴項打包成一個東西,并使你可以在不同的機器上以可預測的方式運行它。所以這實際上是關于程序的可移植性。我認為 Go 語言開發者已經很幸運了,因為 Go 是靜態鏈接的,你可以把一個 Go 二進制文件拿到任何地方運行……但如果你試試用 Ruby 應用、PHP 應用、Python 應用或 Node.js 應用來做這件事,就會發現并不是所有的東西都像 Go 一樣自包含。因此,將這些東西打包成容器是一個很好的選擇。 (譯者注: "Go 是靜態鏈接"這種說法實際是不準確的)

顯然,Docker 讓容器變得非常易用且易于訪問,但最早的 Docker 只在單機上運行,而我們在 Google 構建類似系統的經驗表明,當你開始考慮跨多臺機器的容器可移植性時,事情變得更有趣。

因此,Kubernetes 的作用就是,你告訴它你想運行什么---"我想運行這個容器鏡像的十個副本",鏡像就是那個東西---然后它決定在何處運行這些東西,并確保它們一直在運行。

然后你會遇到一系列其他問題---網絡應該如何配置,存儲應該如何處理,容器如何互相發現,如何管理指向這些容器的負載均衡器等。所以,Kubernetes 解決了分配程序到計算機后衍生出的許多問題。

從編排的角度來看,這就是 Kubernetes 的作用。與此同時,我們實際上構建了一個通用的分布式系統內核,不僅可以描述如何運行容器,還可以描述你想運行哪些容器,如何升級它們,而且我們還使其具有可擴展性,這也是目前 Kubernetes 生態系統中許多有趣的地方。

Kris Nova: 對,然后我想補充一下---你說得非常棒,一如既往……我唯一想強調的是,在過去四五年中,我們構建 API 的重要性。正如你所說,Joe,它有點像分布式系統的內核,但真正的價值在于我們終于能夠在整個行業中標準化。我們第一次看到大家聚集在一起,以相同的方式定義他們的應用程序、網絡和存儲……這是云原生生態系統中一個非常強大的原語。

Johnny Boursiquot: 對,關于這個云原生術語……

Joe Beda: 如果你愿意,我可以為你定義一下……

Johnny Boursiquot: 請說。

Joe Beda: 好的,我想很多人都會對云原生的定義有所不同……Nova 也寫了一本關于這個的書,她可能是專家,但既然現在是我在說話,我就先講完……[笑] 抱歉,Nova。 在我看來,云的本質就是運行在別人的基礎設施上;它是 API 驅動的,自助服務的,并且具有彈性。因此,從開發者的角度來看,云通常意味著不需要與銷售人員溝通的一種服務。你可以直接使用信用卡進行操作并開始使用。這非常強大。

我認為你還可以將這種 API 驅動的自助服務應用到企業內部,雖然可能是另一個部門在提供服務……但如果做得好,應用開發者仍然擁有自助的體驗。對我來說,云原生是指工具、文化和流程,用來充分利用這種能力。

如何真正利用這種 API 驅動的自助服務,并將其反饋到軟件構建的過程中。你是如何定義的,Nova?

Kris Nova: 再次強調,你又搶了我所有的好句子。你對云的定義確實很好,作為一種一等原語。不過當我想到云原生時,我認為云是一回事,但原生(native)是另一回事,而這往往被忽視了……也就是在第一天,當你走到白板前,打開終端,或者在你寫代碼的地方,設計系統的地方---在第一天就考慮到它是在云上運行的。所以現在我們看到很多應用程序的遷移,或者將現有的遺留應用程序移到云上……在我看來,這只是將遺留系統移到云上運行,并不是真正的云原生應用程序。云原生是從一開始就以云為中心來設計應用程序。

Mat Ryer: 那么這個項目是如何開始的呢?Joe,它是從你在 Google 的工作中產生的嗎?然后這個開源項目就由此衍生出來了嗎?

Joe Beda: 我最初啟動了 Google Compute Engine,這是一個在 Google 上運行虛擬機的奇怪項目,因為幾乎沒有人使用虛擬機……而這個項目的作用其實是建立 GCP 的基礎設施云。你看看任何主要的云平臺,虛擬機都是其基礎服務之一,其他所有東西都是基于它構建的。

在 Google 內部,幾乎沒人用虛擬機,因為他們使用了一個叫做 Borg 的系統。它有點像 Kubernetes;容器的概念,打包成鏡像的方式---這些東西都有些不同……但總體的理念是一樣的:你描述你的程序,然后有一個系統來調度和運行它。這個理念在 Google 內部已經驗證了十年。因此,我們了解了這種方式對開發者的好處以及它所能帶來的效率。

所以我們當時的處境是這樣的---我們有幾件事想通過 Kubernetes 來做。首先是改變游戲規則,因為我們在與其他云平臺競爭。像 Amazon 這樣的公司已經占據了市場的主導地位,因此我們可以直接在虛擬機方面與它們競爭,或者我們可以嘗試讓開發者以不同的方式編寫程序,以充分發揮 Google 云的優勢。

其次,我們希望將內部員工開發與外部客戶開發的方式逐漸統一起來,這樣內部員工使用的系統體驗會與外部客戶的體驗更接近(如果不是完全相同的話)。

我們也知道,如果沒有開源,這些東西就不會產生影響。從一開始我們就認為開源是絕對必要的,并且我們真正承諾要做到開放---從第一天起,我們就說“你可以在 Amazon 上運行這個”,這讓很多人感到驚訝……我們還做了其他一些事情,比如引入了很多來自 Red Hat 的優秀人才。Red Hat 是我們早期的一個重要合作伙伴,幫助擴展了 Kubernetes 的應用場景和思維方式……所以這就是事情的開始。

Mat Ryer: 這是一個非常有趣的故事。這個問題本身也非常有趣……我以前是 App Engine 的用戶,雖然從外面看不太清楚內部是如何運作的,但我現在能看到使用 App Engine 與之前的差異,我只能想象在底層發生了什么變化……估計和 Kubernetes 和容器有關。因為從 App Engine 的角度來看,部署現在感覺更加自然。是這樣的嗎?這個項目發生了類似的事情嗎?

Joe Beda: 我認為 App Engine 本身也經歷了演變,我不想替那個團隊發言……但 GCE 和 App Engine 之間總是有點緊張關系,我認為這種緊張關系也適用于 Kubernetes 和 App Engine。

上周我在 SpringOne[6] 平臺會議上做了一個演講(譯者注: 是VMWare組織的一個Spring開發者、應用程序架構師的社區Conf),我談到了一點關于基礎設施即服務(IaaS)和平臺即服務(PaaS)之間的哲學差異。基礎設施即服務基本上是一組構建塊,是一組樂高積木,可以用來構建各種不同的東西。這不僅適用于虛擬機,我認為 Kubernetes 也仍然屬于這種工具箱級別的東西……而平臺即服務則更像是一個框架,其中有一些推薦的模式,如果你不遵循這些模式,那么使用起來就會更加困難,甚至無法完成你想做的事情。雖然這種方式通常效率很高,但有時也會帶來限制。

我認為我們期待的是進入一個兩者之間的界限不那么明顯的世界,這兩種解決問題的方式可以更好地結合起來。

Johnny Boursiquot: 在我腦海中,我試圖想象在組織中,誰的角色會負責這個問題?基本上,我應該把 Kubernetes 看作是一個用于部署應用程序的工具,還是一個用于構建部署平臺的工具?它是一個平臺構建器,還是一個實際的平臺?

Joe Beda: 我認為---我也很想聽聽 Nova 的看法……但我認為目前 Kubernetes 大致有三類用戶。我們發現有平臺團隊,我認為最具前瞻性的組織會將平臺視為一種內部產品。如何提供一個平臺,讓他們能夠擴展,向內部團隊提供更多的服務選項,并在某種程度上提供類似于云的體驗,但在更大的組織限制范圍內。這是在企業中我們常常看到的情況。

然后是應用程序運營者和開發者,應用程序運營者在 Kubernetes 之上運行應用……有時人們也會同時扮演這兩種角色,就像 DevOps 的方式一樣。

我還認為,平臺運營者通常會選擇使用 Kubernetes 的原始形式,但他們也會利用擴展性和其他系統,構建出一種推薦的使用 Kubernetes 的方式,這樣會更容易使用……隨著時間的推移,這種推薦的體驗會越來越像 PaaS,開發者可以直接上手,完成工作;運維的角色會減少很多繁瑣的工作,開發者的體驗會更像“我寫代碼,我發布,它就能運行”的方式。

Kris Nova: 補充一下---我們在《云原生基礎設施》這本書中也談到了這個問題---我認為還有第四類角色。我認為書中提到的“基礎設施工程師”就是這個角色。實際上,這些人就像 Joe 和我一樣,負責在幕后編寫管理基礎設施的軟件。這些人是 Kubernetes 的貢獻者,編寫operator軟件的人,編寫準入控制器實現的人……我認為這是一個非常新的工程角色,直到我們開始擁有一個 Joe 喜歡稱為“平臺之平臺”的東西之前,我們還沒有看到過這種角色。

Johnny Boursiquot: 順著這個思路---這讓我想起了我之前在 Twitter 上看到的一些內容---這些角色對經驗的要求非常高,因此很難讓一個初級開發者加入這些團隊并有效地做出貢獻。進入這些角色的門檻是否太高了?我看到很多招聘廣告,要求非常多,“你需要這個經驗,你需要那個經驗……”從我的角度來看,似乎進入這些角色的門檻非常高……從你的經驗來看,這是事實嗎?

Kris Nova: 我的看法是,這取決于你的團隊有多成熟。如果我們已經有基礎設施工程師和平臺團隊到位,并且已經有系統可以構建應用程序鏡像并推送到生產環境,那么進入的門檻會比較低。這只需要你選擇一種你擅長的語言編寫應用程序,然后讓現有系統處理剩下的事情。

但是,建立這些系統是一個完全不同的故事,這就是我們看到的高進入門檻的地方,尤其是當人們必須回答“我們如何開始為構建流水線的各個階段以及推送到生產環境實施解決方案?”時。

Joe Beda: 是的,這里的確有很多東西需要學習。如果我們把 Kubernetes 稱為一個分布式系統內核,那么那些擴展它的人、深入研究它的人---在某種程度上,他們就是內核工程師。而要成為一個 Linux 內核的專家,深入了解 Linux 內核的方方面面并不容易,對吧?

我的一個觀察是,雖然這些東西是新的,但如果我們看看 AWS,它的服務菜單也不容易理解。需要掌握的內容很多,要真正熟練使用 AWS 需要花費幾個月的時間。這也是他們推出 Lightsail 的原因。(譯者注: AWS推出的一項基于云端的輕量級計算服務,旨在使用戶能夠輕松快速地建立虛擬專用服務器(VPS),提供簡便、經濟實惠的云計算解決方案)  我認為,對于任何高級云系統來說,都會有這樣一條學習曲線。

我還認為,我們看到的現象是,學習 Linux 的曲線也是如此,但它已經成為了行業中的一種共享知識,大家一起學習,隨著時間的推移,它逐漸成為了行業中的背景噪聲。我認為云計算也是如此,熟悉 Amazon (的云服務) 某種程度上也已經幾乎成為了默認要求,成為了背景噪聲……我認為如果 Kubernetes 繼續保持它的增長軌跡,并成為一種更普遍的底層技術,那么熟悉或至少具備 Kubernetes 的工作知識將成為我們行業中默認的技能之一。

Mat Ryer:  說到開源團隊,這個項目最初是如何開始的?我想它和大多數項目一樣,應該有一個較小的范圍吧?我不確定。它是如何演變的?有什么驚喜,或者你看到的有趣的事情是什么?

Kris Nova: 對我來說,最有趣的事情之一就是讓 Kubernetes 運行起來……Joe 寫了一本關于這個的書。但我注意到,無論是在開源社區還是在商業企業中,從零開始運行 Kubernetes 對很多人來說一直是一個難點(譯者注: 結合語境,把a high point of friction翻譯為 “難點”)。回頭看,這也是我最初被 Kubernetes 吸引的原因之一,我對我們已經走了這么遠感到驚訝,但我們在這方面仍然沒有一個非常好的解決方案。

我認為我們正在取得進展,比如 Cluster API 項目[7]Kubeadm 工具[8],但即便如此,我認為關于如何從零開始運行 Kubernetes,至今仍有很多問題需要解答。

Joe Beda: 是的,我覺得這也是我最驚訝的地方。早期在 Kubernetes 項目中,我寫了很多 Bash 腳本,用于在 GCP 和其他環境中部署 Kubernetes---這些腳本并沒有很好地適應時間的變化……[笑] 我甚至寫了一種方法來在 Bash 中導出堆棧跟蹤;對此我既感到害怕又有點自豪。所以我們并沒有真正重視集群本身的生命周期管理,包括運行它的環境類型、如何構建能夠跨所有這些環境擴展的部署系統……因為在主要的公共云提供商上啟動一個集群,和在裸機上,或者用樹莓派啟動集群,是完全不同的體驗。

我認為 Kubernetes 的一個優勢在于它的可擴展性---從零售商在每個商店中使用它, 像 Chick-fil-A 就是一個例子(譯者注: Chick-fil-A是一家總部位于美國喬治亞州的美式連鎖快餐店,以雞肉三明治為主要特色),他們用 Kubernetes 來管理店內系統,比如售貨點系統、數字標牌等),到像 CERN(譯者注: 歐洲核子研究組織) 的粒子加速器這樣的大型設施,他們基本上是用它來做數據分析。所以這種可擴展性非常強大,但這也意味著你在管理生命周期時會遇到不同的挑戰,而我們在項目早期顯然低估了這種復雜性。

Johnny Boursiquot: 在行業會議上,你可能聽到有人說“我們要用 Kubernetes 來實現跨云部署。這將成為我們在所有云之上的基礎,這樣我們就有自由在不同云之間切換,甚至同時使用多個云。”你認為這是明智之舉嗎?企業和開發團隊應該在這一高層構建,而不充分利用任何一個云的特定優勢嗎?

Joe Beda: 我的看法是,對于很多公司來說,多云戰略是有意義的。首先,如果你是一家初創公司,你的首要任務是證明自己對世界有價值,而不是破產---無論如何,盡一切辦法證明你的價值主張是正確的。但是對于更成熟的公司來說,這更多的是風險管理問題。這些公司認為依賴單一供應商有風險,如果有辦法降低這種風險,那就值得嘗試,而 Kubernetes 是實現這一目標的技術之一。

另外,它還能很好地分離操作角色。你可以有專門的團隊來管理 Kubernetes,無論是在 X、Y 或 Z 基礎設施上運行 Kubernetes,還是使用某些服務來處理其中的一部分工作。最終你會在應用層面上獲得一定的通用性。

當然,我們可能無法屏蔽底層平臺的每一個細節,有時你需要利用底層平臺的一些特定特性。但如果我們可以減少那些不必要的差異,就能讓應用團隊的技能更具可移植性,甚至讓應用程序本身更加可移植。

另外,我們看到的一點是,這種做法可以在企業和其供應商之間形成杠桿作用。比如你是亞馬遜的一個大客戶,正在談折扣……[笑] 如果你完全依賴某些原生服務,你的議價能力就會減弱,除非你有可信的“遷移”威脅。也就是說,你可以對他們說:“我們可以在兩個月內從基礎設施 A 遷移到 B。” 這時,你和供應商之間的談判就會更加平衡。

Kris Nova: 接著 Joe 剛才的話題,我覺得在跨云定義應用、網絡、存儲等抽象層次時,我們經歷了一段非常有趣的思維過程。例如,當我們在設計 Cluster API 時,無論你多么通用化,總會遇到某些特定于云的配置。因此,這是一項艱巨的任務,首先要搞清楚哪些是通用部分,然后盡量減少為特定云設計的配置量。

如果你看看我們在 Cluster API 中如何使用 provider config,你會發現我們開始為特定云的部分進行版本管理,同時仍然保持一個通用的配置超集。這是基于我們在設計 Kops[9](譯者注: Kops(Kubernetes Operations)是一個用于管理和部署 Kubernetes 集群的工具。它主要用于在云環境中(如 AWS、GCE 和其他云提供商)創建、管理和維護 Kubernetes 集群) 和 Kubicorn[10] (譯者注: Kubicorn 是一個用于管理和部署 Kubernetes 集群的開源工具。它的目標是提供一種簡單而靈活的方式來創建和管理 Kubernetes 集群,特別是在云環境中. 項目幾乎不維護了)時學到的經驗教訓,我們試圖讓它盡可能通用……但最終我們發現無法完全做到通用化。

因此,如果你有機會讀我的書,我們會談到如何有效地使用軟件來管理 Kubernetes 集群的生命周期。而 Kubernetes 最根本的原則之一就是聲明式的本質。換句話說,你定義了目標或期望的狀態,然后我們會隨著時間推移去協調那個狀態。Cluster API 只是在遵循這個原理,并將其應用到基礎設施管理上。

你首先聲明 Kubernetes 集群的樣子,然后我們會去協調并使其成真。這在管理集群生命周期時很有幫助,因為如果我們想對集群進行變更、擴展、升級或進行某種方式的調整,我們都在遵循相同的聲明式原則,背后會有某種機制自動執行這些操作。

Joe Beda: 我會這么說:我們基本上是在用 Kubernetes 已經在大規模環境中驗證過的模式來管理 Kubernetes 本身。

Johnny Boursiquot: 這很有道理。

Mat Ryer: 聽起來像《盜夢空間》啊。 [笑]

Joe Beda: 是的,Cluster API 項目的標志是一堆疊起來的海龜,因為這就是“海龜疊疊樂”的概念。(譯者注: 一款流行的益智類游戲,通常以小海龜為主題, 游戲的主要目標是通過疊放海龜來形成穩定的結構,玩家需要運用一定的策略和技巧來完成任務)

Mat Ryer: 哈哈,沒錯。

Johnny Boursiquot: [笑] 真有趣。我們來自 GoTime FM Slack 頻道的一個問題……對于正在收聽的朋友們---是的,我們錄制時會實時接受問題,這是你們的機會。有人在頻道里問道:“Kubicorn 還活著嗎?還是已經被 Kubeadm 和 Kops 取代了?”

Kris Nova: 這是一個好問題。我知道有些人---包括我自己---時不時還會用 Kubicorn。我認為它從未打算成為可用于企業級規模管理 Kubernetes 集群的生產就緒工具。我覺得它是一次很好的思維練習,可能我從中獲得的最大價值是它是第一個基于 Kubeadm 構建的開源 Kubernetes 管理工具……而這一點至今依然存在。如果你看看 Kubicorn 的工作原理,它現在相對靜態,因為我們可以在運行時直接使用由上游推送的最新 Kubeadm 版本。所以我認為,Kubicorn 只是一個自動化使用 Kubeadm 而不是管理集群的工具。

通過 Kubicorn、Kops 和 Kubeadm,我們學到了很多東西,而 Cluster API 是將這些經驗教訓整合起來的很好的體現。所以,雖然它不再有所增長,但我不會說它已經完全消亡了。

Mat Ryer: 有趣的是,我注意到我們已經提到了幾次這個主題---我對此非常感興趣,就是這些理念和項目必須不斷演進。你談到了低估了向不同目標部署的復雜性,而這是一個很好的例子。如果在一開始就認識到這些復雜性,可能你根本不會開始這些項目,然而這些項目最終卻變得如此龐大、強大且功能齊全。所以這個理念是說,你不能在真空中設計這些東西。你必須先構建它,讓它被使用,進入現實世界,軟件才能變得更好、更成熟。你同意這一點嗎?

Joe Beda: 是的,我覺得---有幾點要說……我認為我們在開始時確實對 Kubernetes 的增長方向有一個相對清晰的愿景,這是基于我們在 Borg 上的經驗。但確實有些地方我們一開始簡化了,只為了啟動項目。你需要先開始做這些事情。

隨著項目的成長,我們也擴展了范圍。大約三、三年半前,我們意識到,隨著 Kubernetes 添加的功能越來越多……首先,我們無法跟上所有人的想法;其次,我們可能會犯錯,因此我們需要一種實驗機制。所以我們開始在 Kubernetes 中創建可擴展性機制,我覺得這真的將 Kubernetes 從一個僅用于容器編排的工具,轉變為真正的---當我們從技術上談論平臺時,它確實是平臺的基礎。通過這樣做,它讓我們能夠保持 Kubernetes 的范圍適當。

Kubernetes 生態系統中的很多事情并不屬于 Kubernetes 項目本身,我認為這是其成功的一個重要部分---能夠讓一個繁榮的生態系統蓬勃發展,在 Kubernetes 之上做有趣的事情,而不需要與核心 Kubernetes 開發者打交道。這極大地推動了項目和整個生態系統的發展。現在所有關于如何在 Kubernetes 之上部署應用程序并提供分布式管理的討論,正是圍繞這一點展開的。

Mat Ryer: 你剛才談到這個問題---那么 Kubernetes 是如何實現可擴展的?有哪些擴展方式呢?

Joe Beda:  Kubernetes 有一堆內置對象,你可以向它發出請求。例如,你可以說“我想要一個 pod”,它本質上是一個容器組,Kubernetes 會負責選擇運行它的機器,然后啟動它。你還可以說“我想要一個副本集”,這意味著“我想要這個特定模板的多個副本,我需要十個。”Kubernetes 會確保你有十個副本。接著你還可以說“我想要一個部署對象,這是一個版本管理的方式。”所以你可以進行版本升級等操作。我們為 Kubernetes 構建了一層又一層的對象系統。

最核心的擴展性功能是所謂的 自定義資源定義(CRDs)。它允許你在 Kubernetes 中創建新的對象,擴展 Kubernetes 的模式,以便你可以將自己的東西引入。如果你不喜歡 Kubernetes 中的部署方式,因為它無法按照你想要的方式進行藍綠部署,你可以編寫一個與部署對象類似的對象,稱之為藍綠部署,它可以實現你想要的邏輯。

這實際上是擴展了 Kubernetes 的模式,然后運行一段代碼,執行之前 Nova 提到的協調循環,這是 Kubernetes 實現分布式系統的核心。

令人興奮的是,大家不僅將這一模式應用于更領域特定的問題上。例如,你可以管理 MySQL 實例或 Kafka 實例的部署,而不僅僅是應用程序的部署。我們開始看到大家將操作知識轉化為代碼,并在 Kubernetes 上運行這些代碼。這樣你就可以用 Kubernetes 來創建一個類似 Amazon RDS 的系統,既可以描述你想要的東西,也可以實現如何運行這個 RDS 類似系統的邏輯。

同時我們還看到人們將這種控制模式應用到其他領域,不僅僅是運行 Kubernetes 上的東西,還可以用于配置硬件負載均衡器、在特定云中配置服務等。我還聽說有人在企業內部創建了一個自定義資源定義,用于描述團隊及其成員……一旦你定義了這個,它就會自動為你創建 Bitbucket 倉庫、Slack 頻道,并設置 CI/CD 系統,所有這些都是基于你聲明的團隊文檔。這就是 Kubernetes 賦予我們的分布式系統內核的強大力量,它為 Kubernetes 注入了第二波活力。

Kris Nova: 當我和 Kubernetes 新手交談時,試圖向他們解釋 Joe 剛才提到的 CRD 的強大之處,我通常會先定義 CRD 中的兩個重要元素,這在 Kubernetes 的每個對象中都能看到:一個是 spec,它是你想要的定義;另一個是 status,它是對象當前的實時狀態。正是因為我們同時擁有這兩者,協調這一原理才能發揮作用,這也是我們能夠構建復雜的協調循環、控制器和運算符的原因,無論我們想要做什么,作為軟件工程師都可以做到這一點。我認為很多人沒有意識到 Kubernetes 在定義這些運算符和控制器時賦予我們的強大能力和智慧。

Johnny Boursiquot: 嗯,我想他們現在肯定會關注這個了……[笑]

Joe Beda: 我會說的是,編寫這些控制器實際上比應該的要難……這是目前的一個活躍探索領域,人們正在研究如何讓 Kubernetes 更易于使用,也更容易編程。我們還有很長的路要走,才能讓這些東西更加可消費,更容易使用。

我想推薦一本書。這不是我的書,也不是 Kris 的書,而是由 Stefan Schimanski 和 Michael Hausenblas 編寫的《Programming Kubernetes》[11]。我手里有一本……如果你想了解如何使用 Go 編寫 Kubernetes 代碼并開始做一些 CRD 和控制器循環的開發,這是一本很好的入門書。這是一本 O'Reilly 出版的書。

Mat Ryer: 謝謝。

Johnny Boursiquot: 很棒。

Kris Nova: 是的,我覺得還需要指出的是,這個領域也有很多工具。我們從一個原型開始,有一個名為 operator framework[12] 的解決方案,它來自 Red Hat 和 Core OS 的開發者。我們還有一個開源的上游項目 Kubebuilder[13]……所以我們正在尋找構建控制器和運算符的框架,但這仍然是一個不斷迭代和完善的過程,我們還沒有完全到達目標。

Joe Beda: 說到 Go,我認為現在 Go 是編寫這些東西的首選語言……所以,這就是了。 [笑聲]

Mat Ryer: 是的,我本來想問這個問題……如果你看 github.com/kubernetes/kubernetes 倉庫,我猜這是 Kubernetes 的主代碼庫……

Joe Beda: 我們叫它 KK。 [笑] Kubernetes/Kubernetes。

Mat Ryer: 好的!我們不會再嵌套了。

Joe Beda: 哈哈。 [笑聲]

Mat Ryer: 我注意到在語言構成中,超過 90% 是 Go。那為什么一開始 Kubernetes 選擇了 Go 作為開發語言呢?

Joe Beda: 嗯,我想剩下的 10% 大概是 Bash,那都是我的錯,抱歉…… [笑聲] 我們選擇 Go 的第一個原因是 Docker 是其中一個關鍵因素,而 Docker 當時也是現在也是用 Go 編寫的。這對我們有很大的影響。我實際上堅持使用 Go,因為另一位創始人 Brendan Burns 的最初 Kubernetes 原型是用 Java 編寫的。我們同時也受到了 Mesosphere 的影響,它是一個較早的系統;Mesosphere 也使用了一些不同的擴展和編程理念,但本質上它是一個龐大的 C++ 代碼庫。

(譯者注: 現在該公司叫D2iQ,Mesos背后的公司,可參考 曾經 Mesos 背后的公司,如今在干嘛?[14])

因此,我在考慮“我們是要像 Mesos 那樣做 C++ 嗎?還是要像 Apache Hadoop 那樣用 Java?又或者我們要看看社區、代碼質量以及 Docker 生態系統中的互動性?”我認為 Go 是一個很好的選擇,它既足夠系統級別,又不像 C++ 那么難以接近,同時比 C++ 更加高效。因為要找到新的貢獻者,并讓他們在一個龐大的 C++ 代碼庫中快速上手,這非常困難。盡管有人批評 Kubernetes 是“Java 開發者用 Go 寫的”,但我覺得 Go 作為一個易于接近的系統級語言,最終是 Kubernetes 的正確選擇。

Kris Nova: 如果你對那些批評 Kubernetes 是基于面向對象的 Go 系統感興趣,我去年在 FOSDEM 上做了一場演講,叫《You Can't Have a Cluster \[BLEEP\] Without a Cluster》[15]。在那次演講中我提到了許多 Go 編程語言中的反模式,這些模式可能源自傳統的面向對象思維。不想太多批評你和 Brendan,Joe……

Joe Beda:  是的,你知道,社區發展得太快了,很多人加入項目時并不了解 Go……這在一定程度上推動了 Go 的發展,但也意味著他們可能是有經驗的程序員,但不一定擅長 Go……所以這就是我們看到的結果。我敢打賭,很多代碼庫看起來都很相似,基于相同的動態。

Kris Nova: 但它是一個成功的模式,對我們而言是有效的。再次回到那個隨時間演變的教訓,我們是如何走到今天的,并不是一開始就決定要以這種方式構建系統的。真的很有趣。

Johnny Boursiquot: 讓我真正感受到 Kubernetes 價值的一個方面是,它最初的討論總是圍繞著“我們在虛擬機之上進行容器編排,Kubernetes 為你提供了這種抽象,賦予你 pod 這個概念。”因此,你可以更高層次地處理部署,而不必直接處理虛擬機。那么現在“無服務器”---我做了個引號---已經成為一種趨勢,盡管我們都知道這更多是個市場術語,但支持 Kubernetes 上的無服務器確實是件事,對吧?通過 virtual-kubelet 項目[16],這變得可能。

從這個角度來看,你認為 Kubernetes 是否會成為下一代部署模式的平臺?從虛擬機到容器,再到函數即服務……無論下一步是什么,Kubernetes 是否有能力通過其擴展性來應對?

Joe Beda: 我希望如此,但我無法預測未來……首先我們要認識到,作為開發者和工程師,我們總有一種“唯一正確的方式”的心態。所以我們看到新技術時,它們很吸引人,大家都為之興奮……但實際上,隨著時間的推移,我們只會增加技術層面,而不會移除舊的東西。比如主機業務對 IBM 來說仍是一個增長業務。所以虛擬機不會很快消失。

我認為我們可以把它視為一個光譜,并為不同的場景提供合適的工具。沒有哪種應用程序是完全無服務器的、容器化的或虛擬機的。你可以說,“我會用函數即服務平臺來處理大部分工作,但我有一個需要用容器的機器學習模型,此外,我可能還需要運行一個遺留的單體架構。”這可以是一個應用程序使用的多種技術組合。我覺得這就是我們更常見的場景,新技術不會完全取代舊的東西。希望 Kubernetes 能夠足夠靈活,成為下一代技術的良好起點。

Mat Ryer: 是的,Jon Calhoun曾告訴我,很多人會把Kubernetes的代碼庫當作模式和示例的參考。他提到了一些編寫代碼時需要不同思維方式的地方......顯然,這里面有很多好的示例,Jon也說這些是被廣泛使用的。那么,關于代碼組織是否還有其他具體的地方呢?

Jon提到的其中一件事是Kubernetes必須迅速演變,你無法從一開始就設計出一個干凈、完美的設計;每個人的代碼都會自然演變,我認為這本身就是一個很好的教訓。那么,關于代碼結構或者這個項目,或者Go開發者從Kubernetes代碼庫中可以汲取到的東西,還有什么值得注意的嗎?

Kris Nova: 我認為Kubernetes代碼庫在我看來,可能是使用Go接口的最佳示例之一。 特別是當你在看Go中一些不太常規的原則時,比如組合(composition)和嵌入(embedding),我們在使用ObjectMeta時做得很好,ObjectMeta[17]嵌入在每個Kubernetes對象中。這是一個很好的例子,展示了我們如何定義通用部分,然后將它們分享給包含其他特定部分的對象中。

所以我認為這多少暗示了面向對象(OO)風格的思維模式,但這些是Go的一級特性,而我認為Kubernetes在巧妙利用這些特性方面做得非常出色。

Joe Beda: 我是看到了問題......[笑聲] 我認為Kubernetes經歷了從一個單一代碼庫到嘗試拆分的過程......現在它算是半拆分狀態,我甚至不想描述當前的狀態,這個拆分的過程是痛苦的。所以我認為這里可能有一些值得汲取的教訓,比如單一代碼庫的利與弊。

不過,我認為我們做對的一件事是,我們希望Kubernetes成為一個結構良好的分布式系統。所以我們并沒有一開始就創建一個單一的二進制文件,而是將不同的功能拆分成不同的二進制文件,并讓它們通過基本上所有人都能訪問的相同API進行通信。

所以從結構上看,創建多個可以通過網絡通信的二進制文件,并堅持沒有私有接口的原則---這是一個值得汲取的教訓。也許這不完全是Go的事情,但當你開始構建分布式系統時,創建正確的機制來幫助保持架構的整潔度是非常重要的。

Mat Ryer: 我猜,你們也是在不斷自我驗證的過程中?

Kris Nova: 是的,完全正確。我們完全是在使用自己的客戶端。如果你查看Go中的官方客戶端,看看人們如何構建與Kubernetes交互的Go程序,它實際上就是我們在Kubernetes內部使用的相同的源代碼。所以我們實際上是在運行我們建議大家用來解決自己問題的代碼......我認為這是一個非常好的模式。

Mat Ryer: 是的,我同意這個觀點。即便是它被頻繁使用的事實,你也能發現其中的任何問題......但是我們在Machine Box也注意到了一些其他有趣的副作用,Machine Box也是類似的情況---我們使用SDK,我們有一個用于Machine Box API的Go SDK,并在我們的集成測試中使用它。所以我們盡可能多地將測試整合到一起,以同時測試盡可能多的內容。但它確實提供了一定的穩定性,這真的很有趣。

Johnny Boursiquot: John在頻道里問到,Kubernetes作為一個開源項目,是否迫使你們在代碼結構、組織方式和包管理上走上一條特定的道路......如果這是一個私有代碼庫或私有項目,你們會做得不同嗎?

Joe Beda: 從代碼結構上講,我不認為我們會有很大的不同。我確實認為,社區的擴展和代碼是共同演變的,這是一個有趣的現象。隨著項目的增長,我們需要有方法來管理誰負責、誰決定功能、如何推動項目前進......我認為Kubernetes現在所使用的是我們稱之為開放治理的模式,基本上是由一群公開的人員決定項目的未來,而不是由某個公司控制。我認為在代碼結構的某些地方,我們確實看到了這種演變。

Kubernetes的可擴展性機制確實適合這種開源的“讓事情變得廣泛”的模式......如果沒有開源的角度,我們可能不會在可擴展性上投入這么多。

我覺得我們幾乎“打破”了GitHub項目的規模和工作流......Kubernetes社區開發了一個叫Prow的系統,基本上是GitHub的自動化工具。幾乎沒有人真正擁有Kubernetes GitHub組織的管理員權限。相反,一切都是通過/test、/approve或/lgtm命令來完成的,然后Prow機器人會處理這些內容。所以我們能夠在此基礎上構建一個更豐富的所有權模型和權限模型。這些東西都是用Go編寫的。但這不是代碼本身的問題,而是社區和代碼處理流程的一部分。

Kris Nova: 關于Kubernetes的快速迭代速度,有很多值得一提的地方。我們已經提到過幾次,作為一個開源項目,它的進展非常迅速,我認為這可以從Kubernetes K/K代碼庫中反映出來,看看我們在其中有多少二進制文件,以及我們引入了多少依賴項。雖然我不想在Go Time節目中提起依賴管理問題......但我認為它發展得很快,因此我們看到了代碼庫呈現出一種獨特的形態,這在其他情況下可能不會出現。

Johnny Boursiquot: 說到治理和公司對項目的影響,每當一個流行的開源項目---或者說支持這些項目的組織---被收購時,總會有一種膝跳反應式的擔憂,人們會想,“哦,看來我們的項目完了。現在我們將開始看到對某一家公司有利的東西,而對其他公司不利。”從外界來看,Kubernetes似乎沒有受到Heptio被VMware收購的影響......但我也很好奇,從你的角度來看,自從收購以來,有沒有哪些優勢對Kubernetes有益?

Joe Beda: 我首先要說的是,Heptio確實為Kubernetes做出了貢獻,但我們并不是最大的貢獻者。我認為我們可能在公司規模上做得超出預期,但我們參與的池子非常大。

我認為我的聯合創始人在Google時做得很好的一件事就是啟動了云原生計算基金會(CNCF),并把大家聚集在一起。我的聯合創始人Craig McLuckie是Heptio的共同創始人。這最終成為了一個中立的廠商平臺,用來托管Kubernetes。CNCF和Linux基金會有它們的優缺點......這是另一個可以在喝酒時討論的話題。但總的來說,讓這個項目不被任何一個公司擁有,是項目成功的關鍵之一,也讓它能夠繼續發展,無論是Heptio還是其他任何公司。

至于Heptio加入VMware的事情,我認為我們能夠激活VMware內部的很多人,帶更多的人進入社區,真正開始彌補我們通過客戶視角看到的一些空白。我們確實非常注重確保我們為項目投入的比從中獲取的更多。

Kris Nova: 回到之前關于治理的討論,我認為Kubernetes是第一個成功完成CNCF畢業流程的項目,設定了基調和參考架構。如果你看像Joe提到的Prow工具,它現在已經是一個開源工具,你可以引入它進行使用。你會看到CNCF生態系統中很多項目都在使用它。我們在本地的Falco項目中也在使用它,我知道還有很多其他項目也在使用它。同樣,我們要感謝Kubernetes,因為它是第一個通過CNCF畢業流程的項目,設定了很多后續流程的標準。

Johnny Boursiquot: 非常酷。隨著時間的推移,我很好奇接下來Kubernetes的重大步驟或改進是什么?你們認為代碼庫會變得更加穩定,還是還有很多大塊的功能需要完成,以使平臺更加完善?

Kris Nova: 我有個答案,當然我有些偏見。如果你看看我們作為社區已經解決的問題---我們已經解決了存儲問題,并迭代了幾次;我們也完成了網絡問題,完成了計算問題,甚至包括我們如何定義應用程序以及如何管理狀態的方式都已經有了進展......但如果你看看安全問題,目前還沒有一個好的解決方案。我認為這是Kubernetes需要解決的最后一個領域。

關于在Kubernetes中運行應用程序并保持其安全,甚至是保持整個Kubernetes集群的安全,有很多已知的問題。所以在我看來,這是在生態系統中存在的一個比較大的問題,正如Joe之前提到的那樣。

Joe Beda: 需要澄清的是,這些問題是可以解決的。我認為只是目前還不夠簡單或直觀,或者說沒有達到一鍵式的便捷程度。我認為在安全性方面,隨著時間的推移,Kubernetes將成為安全最佳實踐的標桿,因為你能獲得大量關于運行程序、它們如何運行、是誰決定運行這些程序、誰采取了哪些操作的數據。這些數據在傳統的DevOps環境中往往是看不到的。但我認為我們看到了這種潛力;不過我們還沒有完全實現這一點。所以我完全同意Kris的看法。

我們在Kubernetes核心項目中經常談論的一件事情是,讓Kubernetes變得“無趣”。好的基礎設施應該是無趣的。我記得Brad Fitzpatrick曾經在談論某個Go的版本發布時說,“這個Go版本沒有什么特別的地方,這其實是一件好事。”Go從那時起變得更有趣了,但曾經有一個時期,Go本身非常穩定,以至于發布說明只是“我們改進了垃圾回收器,并提高了性能,但從用戶的角度來看,幾乎沒有什么變化。”

我們也希望Kubernetes能夠到達這個階段,核心部分非常無趣,所有有趣的事情都發生在核心之外。我認為我們正在朝這個方向前進。所以我覺得這對我們來說是一個好地方,能夠讓生態系統中的事情變得更有趣,而不是核心項目本身。

Kris Nova:  我第一次聽到有人用“無趣”來形容軟件的時候,好像是Rob Pike在Go剛推出時的某個早期演講中提到的。

Mat Ryer: 是的。我有個快速問題,如果我寫k8s……

Joe Beda: 哈哈哈!

Mat Ryer: ……我是讓自己難堪了嗎?這是“潮”還是“不潮”啊?我不確定,這還流行嗎,還是……

Joe Beda: 還流行啊。

Mat Ryer: 還流行啊。

Joe Beda: 對于那些不清楚的人來說---這就像我們寫國際化或本地化一樣,i...

Johnny Boursiquot: i18n...

Joe Beda: i18n,類似的東西。或者Andreessen Horowitz的a16z……[笑聲] 這是同樣的邏輯,k和s之間有8個字母。但我們還有一個優勢,那就是你可以把它叫做“kates”。因此很多人在讀它時,不叫Kube或Kubernetes,而是叫kates。我不知道是誰開始這么叫的......這既酷,因為它是一個簡寫,但它也增加了Kubernetes世界的新手學習的難度,因為又多了一個術語。人們會想,“好吧,我知道Kubernetes,但我看到k8s......這到底是怎么回事啊?!”

Mat Ryer: 是的。

Kris Nova: 我喜歡它的原因是,它讓我在Twitter上談論Kubernetes時可以最少化字符數。

Johnny Boursiquot: 這確實有幫助。說到更多術語......是“kube cuttle”,還是“kube control”?[笑聲]

Joe Beda: “Queue Beck tall”!

Johnny Boursiquot: [笑聲]

Joe Beda: 這就像是I/O控制,你是說“I/O控制”還是“eye octal”(ioctl)?我們經常在這些發音上爭論不休。我們在Heptio有一位員工,現在在VMware---她堅持把Kubernetes錯誤發音成Kapernikes(Copernicus) [笑聲] 這成了我們團隊的一個游戲,看看誰能找到最糟糕的發音。

Johnny Boursiquot: 太棒了。

Mat Ryer: 最后一個問題,Nova......K/K代碼庫有85,000多個提交記錄。你最喜歡哪個?可以直接給個簡短的哈希值。

Kris Nova: 我最喜歡的提交記錄......讓我們稱之為Joe的提交吧。Joe是第一個在開源代碼庫中提交代碼的人,如果沒有他的提交,我想我們現在都不會在這里。

Mat Ryer: 這是個好答案。

Johnny Boursiquot: 答案揭曉。

Joe Beda: 我必須反駁一下......在我們把代碼庫移到GitHub之前,我們其實有一個內部代碼庫。我只是做了一些清理工作,準備發布代碼......[笑聲] 所以我不能說那都是我寫的代碼。我只是負責在我們準備發布時整理了代碼。

Mat Ryer: 我認為GitHub的歷史不會騙人,它在法庭上也是可以接受的證據。

Johnny Boursiquot: [笑聲] 你知道你可以修改那個歷史記錄,對吧?我只是說一下。

Mat Ryer: 真的可以嗎?

Johnny Boursiquot: [笑聲] 好吧。我覺得這是我參與過的最有趣的一期節目之一,因為我對基礎設施充滿了熱情,作為一個SRE,知道無趣的技術才是我們想要的讓我感到安心......因為當我值班時,我不希望有有趣的事情發生,所以......[笑聲] 知道項目的方向真是太棒了,今天能有你們來節目真是太好了。

Joe,你經常主持TGI Kubernetes直播,我們經常看你偶爾遇到點小麻煩,但大多數時候你都能順利完成任務,還有社區的幫助......

Joe Beda: 是的,我想我們已經做了90多期了。我們每周五都會直播......Nova在她還在Heptio工作時也主持了很多期。我知道她現在也在計劃在Twitch上做一些自己的直播。

Johnny Boursiquot: 嗯,期待你的直播,Nova。

Kris Nova: 是的,我們已經做了第一次直播,正在努力完善。我想我們會更多地聚焦于Kubernetes和其他容器編排,拓寬一些話題范圍......當然,我們是一家安全公司,所以肯定會有很多安全相關的討論。

Mat Ryer: 太好了,我們也很期待觀看......

Kris Nova: 是的,我想“觀看”是個合適的詞。

Mat Ryer: 謝謝你。 [笑聲] 我只是確認一下。

Johnny Boursiquot: 等待確認......[笑聲]

Joe Beda: 有趣的是,YouTube/Twitch的直播和播客有著不同的感覺,我認為它們的消費方式也不一樣......所以看到不同的媒介找到自己的方式很有趣。

Kris Nova: 是的,當你開始直播時,總有那么一瞬間,你會意識到自己已經在一個小房間里,一個人對著空氣說了30分鐘......[笑聲] 很容易陷入這種自說自話的狀態。

Johnny Boursiquot: 太棒了。非常感謝你們來參加我們的節目,感謝所有現場收聽的聽眾,感謝你們在頻道里提問。如果你們之后再聽到這期節目,希望你們也會喜歡。

Reference

[1] Kubernetes and Cloud Native: https://changelog.com/gotime/105

[2] Johnny: https://github.com/jboursiquot

[3] Mat: https://github.com/matryer

[4] Kris Nova: https://github.com/krisnova

[5] Joe Beda: https://github.com/jbeda

[6] SpringOne: https://springone.io/

[7] Cluster API 項目: https://github.com/kubernetes-sigs/cluster-api

[8] Kubeadm 工具: https://github.com/kubernetes/kubeadm

[9] Kops: https://github.com/kubernetes/kops

[10] Kubicorn: https://github.com/kubicorn/kubicorn

[11] 《Programming Kubernetes》: https://book.douban.com/subject/33393681/

[12] operator framework: https://github.com/operator-framework

[13] Kubebuilder: https://github.com/kubernetes-sigs/kubebuilder

[14] 曾經 Mesos 背后的公司,如今在干嘛?: https://2d2d.io/s1/mesos/

[15] 《You Can't Have a Cluster [BLEEP] Without a Cluster》: https://www.youtube.com/watch?v=CLVIbCs2VJY

[16] virtual-kubelet 項目: https://github.com/virtual-kubelet/virtual-kubelet

[17] ObjectMeta: https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/common-definitions/object-meta/

責任編輯:武曉燕 來源: 旅途散記
相關推薦

2023-03-06 07:19:50

2021-04-25 10:26:58

云計算云原生

2023-03-03 07:54:21

2022-04-07 10:17:18

云原生服務器優化

2025-01-03 08:08:56

2022-11-08 08:55:31

2023-03-07 07:56:37

Sqoopk8s底層

2022-10-14 07:42:50

LuceneHTTPWeb

2024-06-12 13:21:06

2023-02-08 07:55:33

K8sHPA服務器

2021-08-13 07:00:41

云原生k8sspringboot

2021-08-26 07:20:05

云原生K8sSpringboot

2022-07-18 18:48:32

Kubernetes云原生

2022-11-06 21:31:11

云原生Sentinel集群模式

2023-03-01 07:42:12

HBase編排部署數據

2024-06-06 09:19:09

2024-06-21 09:28:05

2024-06-18 13:22:42

Nginx云原生Kubernetes

2023-02-01 07:46:51

k8s云原生巧妙用法

2020-12-22 07:42:05

云原生開源項目k8s
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: av喷水| 亚洲经典一区 | 日韩在线观看一区二区三区 | 日日噜噜噜夜夜爽爽狠狠视频97 | 日韩在线视频一区二区三区 | 免费小视频在线观看 | 亚洲天堂一区 | 91电影在线播放 | 看片91| 欧美福利视频 | 亚洲欧美综合精品久久成人 | 日本一本在线 | 日韩在线一区二区三区 | 亚洲性视频在线 | 国产精品久久久一区二区三区 | 四虎成人av| 伊人国产精品 | 国产福利网站 | 国产在线网站 | 国产视频综合 | 91精品国产色综合久久 | 一级在线观看 | 五月天婷婷丁香 | 久久中文字幕一区 | 精品99爱视频在线观看 | 亚洲第一免费播放区 | 欧美中文一区 | 超碰在线免费公开 | 在线日韩在线 | 亚洲精品在线播放 | 日本久久精品视频 | 一区在线播放 | 久久机热| 一级毛片免费 | 久久777| 成人精品 | 久久男女视频 | 久久精品99国产精品 | 久色视频在线观看 | 97久久超碰| 国产一伦一伦一伦 |