K8S系列一:概念入門

在這里插入圖片描述

寫在前面

本文組織方式:

  1. K8S的架構、作用和目的。需要首先對K8S整體有所了解。
    K8S是什么?
    為什么是K8S?
    K8S怎么做?

  2. K8S的重要概念,即K8S的API對象。要學習和使用K8S必須知道和掌握的幾個對象。
    Pod 實例
    Volume 數據卷
    Container 容器
    Deployment 和 ReplicaSet
    Service和Ingress
    namespace 命名空間
    其他

I. K8S概覽

1.1 K8S是什么?

K8S是Kubernetes的全稱,官方稱其是:

Kubernetes is an open source system for managing containerized applications across multiple hosts. It provides basic mechanisms for deployment, maintenance, and scaling of applications.
用于自動部署、擴展和管理“容器化(containerized)應用程序”的開源系統。

翻譯成大白話就是:“K8S是負責自動化運維管理多個Docker程序的集群”。 那么問題來了:Docker運行可方便了,為什么要用K8S,它有什么優勢?
插一句題外話:

  • 為什么Kubernetes要叫Kubernetes呢?維基百科已經交代了(老美對星際是真的癡迷):
    Kubernetes(在希臘語意為“舵手”或“駕駛員”)由Joe Beda、Brendan Burns和Craig
    McLuckie創立,并由其他谷歌工程師,包括Brian Grant和Tim Hockin等進行加盟創作,并由谷歌在2014年首次對外宣布
    。該系統的開發和設計都深受谷歌的Borg系統的影響,其許多頂級貢獻者之前也是Borg系統的開發者。在谷歌內部,Kubernetes的原始代號曾經是Seven,即星際迷航中的Borg(博格人)。Kubernetes標識中舵輪有七個輪輻就是對該項目代號的致意。
  • 為什么Kubernetes的縮寫是K8S呢?我個人贊同Why Kubernetes is Abbreviated
    k8s中說的觀點“嘛,寫全稱也太累了吧,不如整個縮寫”。其實只保留首位字符,用具體數字來替代省略的字符個數的做法,還是比較常見的。

1.2 為什么是K8S?

試想下傳統的后端部署辦法:把程序包(包括可執行二進制文件、配置文件等)放到服務器上,接著運行啟動腳本把程序跑起來,同時啟動守護腳本定期檢查程序運行狀態、必要的話重新拉起程序。

有問題嗎?顯然有!最大的一個問題在于:如果服務的請求量上來,已部署的服務響應不過來怎么辦? 傳統的做法往往是,如果請求量、內存、CPU超過閾值做了告警,運維馬上再加幾臺服務器,部署好服務之后,接入負載均衡來分擔已有服務的壓力。

問題出現了:從監控告警到部署服務,中間需要人力介入!那么,有沒有辦法自動完成服務的部署、更新、卸載和擴容、縮容呢?

這,就是K8S要做的事情:自動化運維管理Docker(容器化)程序。

1.3 K8S怎么做?

我們已經知道了K8S的核心功能:自動化運維管理多個容器化程序。那么K8S怎么做到的呢?這里,我們從宏觀架構上來學習K8S的設計思想。首先看下圖,圖片來自文章Components of Kubernetes Architecture:
在這里插入圖片描述
K8S是屬于主從設備模型(Master-Slave架構),即有Master節點負責核心的調度、管理和運維,Slave節點則在執行用戶的程序。但是在K8S中,主節點一般被稱為Master Node或者Head Node(本文采用Master Node稱呼方式),而從節點則被稱為Worker Node或者Node(本文采用Worker Node稱呼方式)。

要注意一點:Master Node和Worker Node是分別安裝了K8S的Master和Woker組件的實體服務器,每個Node都對應了一臺實體服務器(雖然Master Node可以和其中一個Worker Node安裝在同一臺服務器,但是建議Master Node單獨部署),所有Master Node和Worker Node組成了K8S集群,同一個集群可能存在多個Master Node和Worker Node。

首先來看Master Node都有哪些組件:

  • API Server。K8S的請求入口服務。API Server負責接收K8S所有請求(來自UI界面或者CLI命令行工具),然后,API
    Server根據用戶的具體請求,去通知其他組件干活。
  • Scheduler。K8S所有Worker Node的調度器。當用戶要部署服務時,Scheduler會選擇最合適的Worker Node(服務器)來部署。
  • Controller Manager。K8S所有Worker Node的監控器。Controller Manager有很多具體的Controller,在文章Components of Kubernetes Architecture中提到的有Node Controller、Service Controller、Volume Controller等。Controller負責監控和調整在Worker Node上部署的服務的狀態,比如用戶要求A服務部署2個副本,那么當其中一個服務掛了的時候,Controller會馬上調整,讓Scheduler再選擇一個Worker Node重新部署服務。
  • etcd。K8S的存儲服務。etcd存儲了K8S的關鍵配置和用戶配置,K8S中僅API Server才具備讀寫權限,其他組件必須通過API
    Server的接口才能讀寫數據(見Kubernetes Works Like an Operating System)。

接著來看Worker Node的組件,筆者更贊同HOW DO APPLICATIONS RUN ON KUBERNETES文章中提到的組件介紹:

  • Kubelet。Worker Node的監視器,以及與Master Node的通訊器。Kubelet是Master
    Node安插在Worker Node上的“眼線”,它會定期向Worker
    Node匯報自己Node上運行的服務的狀態,并接受來自Master Node的指示采取調整措施。
  • Kube-Proxy。K8S的網絡代理。私以為稱呼為Network-Proxy可能更適合?Kube-Proxy負責Node在K8S的網絡通訊、以及對外部網絡流量的負載均衡。
  • Container Runtime。Worker Node的運行環境。即安裝了容器化所需的軟件環境確保容器化程序能夠跑起來,比如Docker Engine。大白話就是幫忙裝好了Docker運行環境。
  • Logging Layer。K8S的監控狀態收集器。私以為稱呼為Monitor可能更合適?Logging
    Layer負責采集Node上所有服務的CPU、內存、磁盤、網絡等監控項信息。
  • Add-Ons。K8S管理運維Worker Node的插件組件。有些文章認為Worker
    Node只有三大組件,不包含Add-On,但筆者認為K8S系統提供了Add-On機制,讓用戶可以擴展更多定制化功能,是很不錯的亮點。

總結來看,K8S的Master Node具備:請求入口管理(API Server),Worker Node調度(Scheduler),監控和自動調節(Controller Manager),以及存儲功能(etcd);而K8S的Worker Node具備:狀態和監控收集(Kubelet),網絡和負載均衡(Kube-Proxy)、保障容器化運行環境(Container Runtime)、以及定制化功能(Add-Ons)

II. K8S重要概念

2.1 Pod實例

官方對于Pod的解釋是:

Pod是可以在 Kubernetes 中創建和管理的、最小的可部署的計算單元。

這樣的解釋還是很難讓人明白究竟Pod是什么,但是對于K8S而言,Pod可以說是所有對象中最重要的概念了!因此,我們必須首先清楚地知道“Pod是什么”,再去了解其他的對象。

從官方給出的定義,聯想下“最小的xxx單元”,是不是可以想到本科在學校里學習“進程”的時候,教科書上有一段類似的描述:資源分配的最小單位;還有”線程“的描述是:CPU調度的最小單位。什么意思呢?”最小xx單位“要么就是事物的衡量標準單位,要么就是資源的閉包、集合。前者比如長度米、時間秒;后者比如一個”進程“是存儲和計算的閉包,一個”線程“是CPU資源(包括寄存器、ALU等)的閉包。

同樣的,Pod就是K8S中一個服務的閉包。這么說的好像還是有點玄乎,更加云里霧里了。簡單來說,Pod可以被理解成一群可以共享網絡、存儲和計算資源的容器化服務的集合。再打個形象的比喻,在同一個Pod里的幾個Docker服務/程序,好像被部署在同一臺機器上,可以通過localhost互相訪問,并且可以共用Pod里的存儲資源(這里是指Docker可以掛載Pod內的數據卷,數據卷的概念,后文會詳細講述,暫時理解為“需要手動mount的磁盤”)。筆者總結Pod如下圖,可以看到:同一個Pod之間的Container可以通過localhost互相訪問,并且可以掛載Pod內所有的數據卷;但是不同的Pod之間的Container不能用localhost訪問,也不能掛載其他Pod的數據卷
在這里插入圖片描述

對Pod有直觀的認識之后,接著來看K8S中Pod究竟長什么樣子,具體包括哪些資源?

K8S中所有的對象都通過yaml來表示,筆者從官方網站摘錄了一個最簡單的Pod的yaml:

apiVersion: v1
kind: Pod
metadata:name: memory-demonamespace: mem-example
spec:containers:- name: memory-demo-ctrimage: polinux/stressresources:limits:memory: "200Mi"requests:memory: "100Mi"command: ["stress"]args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]volumeMounts:- name: redis-storagemountPath: /data/redisvolumes:- name: redis-storageemptyDir: {}

看不懂不必慌張,且耐心聽下面的解釋:

  • apiVersion記錄K8S的API Server版本,現在看到的都是v1,用戶不用管。
  • kind記錄該yaml的對象,比如這是一份Pod的yaml配置文件,那么值內容就是Pod。
  • metadata記錄了Pod自身的元數據,比如這個Pod的名字、這個Pod屬于哪個namespace(命名空間的概念,后文會詳述,暫時理解為“同一個命名空間內的對象互相可見”)。
  • spec記錄了Pod內部所有的資源的詳細信息,看懂這個很重要:
  • containers記錄了Pod內的容器信息,containers包括了:name容器名,image容器的鏡像地址,resources容器需要的CPU、內存、GPU等資源,command容器的入口命令,args容器的入口參數,volumeMounts容器要掛載的Pod數據卷等。可以看到,上述這些信息都是啟動容器的必要和必需的信息。
  • volumes記錄了Pod內的數據卷信息,后文會詳細介紹Pod的數據卷。

2.2 Volume 數據卷

K8S支持很多類型的volume數據卷掛載,具體請參見K8S卷。前文就“如何理解volume”提到:“需要手動mount的磁盤”,此外,有一點可以幫助理解:數據卷volume是Pod內部的磁盤資源。

其實,單單就Volume來說,不難理解。但是上面還看到了volumeMounts,這倆是什么關系呢?

volume是K8S的對象,對應一個實體的數據卷;而volumeMounts只是container的掛載點,對應container的其中一個參數。但是,volumeMounts依賴于volume,只有當Pod內有volume資源的時候,該Pod內部的container才可能有volumeMounts。

2.3 Container 容器

本文中提到的鏡像Image、容器Container,都指代了Pod下的一個container。關于K8S中的容器,在2.1Pod章節都已經交代了,這里無非再啰嗦一句:一個Pod內可以有多個容器container

在Pod中,容器也有分類,對這個感興趣的同學歡迎自行資料:

  • 標準容器 Application Container
  • 初始化容器 Init Container
  • 邊車容器 Sidecar Container
  • 臨時容器 Ephemeral Container

一般來說,我們部署的大多是標準容器( Application Container)

2.4 Deployment 和 ReplicaSet(簡稱RS)

除了Pod之外,K8S中最常聽到的另一個對象就是Deployment了。那么,什么是Deployment呢?官方給出了一個要命的解釋:

一個 Deployment 控制器為 Pods 和 ReplicaSets 提供聲明式的更新能力。 你負責描述 Deployment 中的
目標狀態,而 Deployment 控制器以受控速率更改實際狀態, 使其變為期望狀態。你可以定義 Deployment 以創建新的
ReplicaSet,或刪除現有 Deployment,并通過新的 Deployment 收養其資源。

翻譯一下:Deployment的作用是管理和控制Pod和ReplicaSet,管控它們運行在用戶期望的狀態中。哎,打個形象的比喻,Deployment就是包工頭,主要負責監督底下的工人Pod干活,確保每時每刻有用戶要求數量的Pod在工作。如果一旦發現某個工人Pod不行了,就趕緊新拉一個Pod過來替換它。

新的問題又來了:那什么是ReplicaSets呢?

ReplicaSet 的目的是維護一組在任何時候都處于運行狀態的 Pod 副本的穩定集合。 因此,它通常用來保證給定數量的、完全相同的
Pod 的可用性。

再來翻譯下:ReplicaSet的作用就是管理和控制Pod,管控他們好好干活。但是,ReplicaSet受控于Deployment。形象來說,ReplicaSet就是總包工頭手下的小包工頭

筆者總結得到下面這幅圖,希望能幫助理解:
在這里插入圖片描述
新的問題又來了:如果都是為了管控Pod好好干活,為什么要設置Deployment和ReplicaSet兩個層級呢,直接讓Deployment來管理不可以嗎?

回答:不清楚,但是私以為是因為先有ReplicaSet,但是使用中發現ReplicaSet不夠滿足要求,于是又整了一個Deployment(有清楚Deployment和ReplicaSet聯系和區別的小伙伴歡迎留言啊)。

但是,從K8S使用者角度來看,用戶會直接操作Deployment部署服務,而當Deployment被部署的時候,K8S會自動生成要求的ReplicaSet和Pod。在K8S官方文檔中也指出用戶只需要關心Deployment而不操心ReplicaSet:

This actually means that you may never need to manipulate ReplicaSet
objects: use a Deployment instead, and define your application in the
spec section.
這實際上意味著您可能永遠不需要操作ReplicaSet對象:直接使用Deployments并在規范部分定義應用程序。

補充說明:在K8S中還有一個對象 — ReplicationController(簡稱RC),官方文檔對它的定義是:

ReplicationController 確保在任何時候都有特定數量的 Pod 副本處于運行狀態。
換句話說,ReplicationController 確保一個 Pod 或一組同類的 Pod 總是可用的。

怎么樣,和ReplicaSet是不是很相近?在Deployments, ReplicaSets, and pods教程中說“ReplicationController是ReplicaSet的前身”,官方也推薦用Deployment取代ReplicationController來部署服務。

2.5 Service和Ingress

吐槽下K8S的概念/對象/資源是真的多啊!前文介紹的Deployment、ReplicationController和ReplicaSet主要管控Pod程序服務;那么,Service和Ingress則負責管控Pod網絡服務

我們先來看看官方文檔中Service的定義:

將運行在一組 Pods 上的應用程序公開為網絡服務的抽象方法。 使用 Kubernetes,您無需修改應用程序即可使用不熟悉的服務發現機制。
Kubernetes 為 Pods 提供自己的 IP 地址,并為一組 Pod 提供相同的 DNS 名, 并且可以在它們之間進行負載均衡。

翻譯下:K8S中的服務(Service)并不是我們常說的“服務”的含義,而更像是網關層,是若干個Pod的流量入口、流量均衡器。
那么,為什么要Service呢?

私以為在這一點上,官方文檔講解地非常清楚:

Kubernetes Pod 是有生命周期的。 它們可以被創建,而且銷毀之后不會再啟動。 如果您使用 Deployment
來運行您的應用程序,則它可以動態創建和銷毀 Pod。 每個 Pod 都有自己的 IP 地址,但是在 Deployment
中,在同一時刻運行的 Pod 集合可能與稍后運行該應用程序的 Pod 集合不同。 這導致了一個問題: 如果一組
Pod(稱為“后端”)為群集內的其他 Pod(稱為“前端”)提供功能, 那么前端如何找出并跟蹤要連接的 IP
地址,以便前端可以使用工作量的后端部分?

補充說明:K8S集群的網絡管理和拓撲也有特別的設計,以后會專門出一章節來詳細介紹K8S中的網絡。這里需要清楚一點:K8S集群內的每一個Pod都有自己的IP(是不是很類似一個Pod就是一臺服務器,然而事實上是多個Pod存在于一臺服務器上,只不過是K8S做了網絡隔離),在K8S集群內部還有DNS等網絡服務(一個K8S集群就如同管理了多區域的服務器,可以做復雜的網絡拓撲)。

此外,筆者推薦k8s外網如何訪問業務應用對于Service的介紹,不過對于新手而言,推薦閱讀前半部分對于service的介紹即可,后半部分就太復雜了。我這里做了簡單的總結:

Service是K8S服務的核心,屏蔽了服務細節,統一對外暴露服務接口,真正做到了“微服務”。舉個例子,我們的一個服務A,部署了3個備份,也就是3個Pod;對于用戶來說,只需要關注一個Service的入口就可以,而不需要操心究竟應該請求哪一個Pod。優勢非常明顯:一方面外部用戶不需要感知因為Pod上服務的意外崩潰、K8S重新拉起Pod而造成的IP變更,外部用戶也不需要感知因升級、變更服務帶來的Pod替換而造成的IP變化,另一方面,Service還可以做流量負載均衡

但是,Service主要負責K8S集群內部的網絡拓撲。那么集群外部怎么訪問集群內部呢?這個時候就需要Ingress了,官方文檔中的解釋是:

Ingress 是對集群中服務的外部訪問進行管理的 API 對象,典型的訪問方式是 HTTP。 Ingress 可以提供負載均衡、SSL
終結和基于名稱的虛擬托管。

翻譯一下:Ingress是整個K8S集群的接入層,復雜集群內外通訊。

最后,筆者把Ingress和Service的關系繪制網絡拓撲關系圖如下,希望對理解這兩個概念有所幫助:
在這里插入圖片描述

2.6 namespace 命名空間

和前文介紹的所有的概念都不一樣,namespace跟Pod沒有直接關系,而是K8S另一個維度的對象。或者說,前文提到的概念都是為了服務Pod的,而namespace則是為了服務整個K8S集群的。

那么,namespace是什么呢?

上官方文檔定義:

Kubernetes 支持多個虛擬集群,它們底層依賴于同一個物理集群。 這些虛擬集群被稱為名字空間。

翻譯一下:namespace是為了把一個K8S集群劃分為若干個資源不可共享的虛擬集群而誕生的。

也就是說,可以通過在K8S集群內創建namespace來分隔資源和對象。比如我有2個業務A和B,那么我可以創建ns-a和ns-b分別部署業務A和B的服務,如在ns-a中部署了一個deployment,名字是hello,返回用戶的是“hello a”;在ns-b中也部署了一個deployment,名字恰巧也是hello,返回用戶的是“hello b”(要知道,在同一個namespace下deployment不能同名;但是不同namespace之間沒有影響)。前文提到的所有對象,都是在namespace下的;當然,也有一些對象是不隸屬于namespace的,而是在K8S集群內全局可見的,官方文檔提到的可以通過命令來查看,具體命令的使用辦法,筆者會出后續的實戰文章來介紹,先貼下命令:

# 位于名字空間中的資源
kubectl api-resources --namespaced=true
?
# 不在名字空間中的資源
kubectl api-resources --namespaced=false

不在namespace下的對象有:
在這里插入圖片描述
在namespace下的對象有(部分):
在這里插入圖片描述

2.7 其他

K8S的對象實在太多了,2.1-2.6介紹的是在實際使用K8S部署服務最常見的。其他的還有Job、CronJob等等,在對K8S有了比較清楚的認知之后,再去學習更多的K8S對象,不是難事。

寫在后面

本文是K8S系列文章第一篇,希望能夠幫助對K8S不了解的新手快速了解K8S。如果文章中有紕漏,非常歡迎留言或者私信指出;有理解錯誤的地方,更是歡迎留言或者私信告知。

筆者一邊寫文章,一邊查閱和整理K8S資料,過程中越發感覺K8S架構的完備、設計的精妙,是值得深入研究的,K8S大受歡迎是有道理的!再次感嘆下。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/38638.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/38638.shtml
英文地址,請注明出處:http://en.pswp.cn/news/38638.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

php錯誤類型與處理

1 語法編譯錯誤,少了分號,這是系統觸發的錯誤,不需要我們去管。 2 錯誤類型有四種:error致命錯誤,代碼不會往下運行;warning:提醒錯誤,會往下運行,但是會有意想不到的結果…

【C++學習】STL容器——stack和queue

目錄 一、stack的介紹和使用 1.1 stack的介紹 1.2 stack的使用 1.3 stack的模擬實現 二、queue的介紹和使用 2.1 queue的介紹 2.2 queue的使用 2.3 queue的模擬實現 三、priority_queue的介紹和使用 3.1 priority_queue的介紹和使用 3.2 priority_queue的使用 3.4 p…

JVM---理解jvm之對象已死怎么判斷?

目錄 引用計數算法 什么是引用 可達性分析算法(用的最多的) 引用計數算法 定義:在對象中添加一個引用計數器,每當有一個地方引用它時,計數器值就加一;當引用失效時,計數器值就減一&#xff1…

國內外醫療器械政策法規網站集合

隨著醫療技術的不斷發展,醫療器械在現代醫療中扮演著重要的角色。為了確保醫療器械的安全性、有效性和質量,各國紛紛制定了一系列的政策法規來監管醫療器械的研發、生產、銷售和使用。這些政策法規的制定和實施對于保障公眾健康、促進醫療器械產業的健康…

docker--------介紹、常用命令,國內源配置

1 docker 國內源配置 # 鏡像:一堆文件 -目前從遠程倉庫下載的:https://hub.docker.com/ -鏡像有很多人提供:官方提供,第三方提供 -鏡像--》更新--》Tag不同版本 -centos:latest 最新 -docker pull 能找到…

舊版本docker未及時更新,導致更新/etc/docker/daemon.json配置文件出現docker重啟失敗

一、背景 安裝完docker和containerd之后,嘗試重啟docker的時候,報錯如下: systemctl restart dockerJob for docker.service failed because the control process exited with error code. See “systemctl status docker.service” and “…

學習ts(一)數據類型(基礎類型和任意類型)

運行 起步安裝 npm install typescript -g 運行tsc index.ts生成對應的js文件,然后使用node index.js執行js文件 為了方便運行還可以安裝插件,ts-node index.ts運行即可 npm i ts-node -g npm init -y npm i types/node -D基本數據類型 // 1.字符…

探索不同類型的代理服務器 (代理 IP、socks5 代理)及其在網絡安全與爬蟲中的應用

1. 代理服務器簡介 代理服務器是一臺充當中間人的服務器,它在客戶端與目標服務器之間傳遞網絡請求。代理服務器在不同層級上可以執行不同的任務,包括緩存、過濾、負載均衡和隱藏客戶端真實IP地址等。在網絡安全和爬蟲領域,代理服務器具有重要…

ARM(匯編指令)

.global _start _start:/*mov r0,#0x5mov r1,#0x6 bl LoopLoop:cmp r0,r1beq stopsubhi r0,r0,r1subcc r1,r1,r0mov pc,lr*/ mov r0,#0x1mov r1,#0x0mov r2,#0x64bl Loop Loop:cmp r0,r2bhi stopadd r1,r1,r0add r0,r0,#0x01mov pc,lr stop:B stop.end

現有的vue3+ts+vite項目集成electron

效果圖 什么時Electron Electron是使用JavaScript,HTML和CSS構建跨平臺的桌面應用程序框架。 Electron兼容Mac、Windows和Linux,可以構建出三個平臺的應用程序。 現有的vue3項目集成Electron 安裝依賴 原來有一個vue3+ts+vite+pnpm的項目,其中sub-modules是子項目,web是…

Monge矩陣

Monge矩陣 對一個m*n的實數矩陣A&#xff0c;如果對所有i&#xff0c;j&#xff0c;k和l&#xff0c;1≤ i<k ≤ m和1≤ j<l ≤ n&#xff0c;有 A[i,j]A[k,l] ≤ A[i,l]A[k,j] 那么&#xff0c;此矩陣A為Monge矩陣。 換句話說&#xff0c;每當我們從矩陣中挑…

全面梳理Python下的NLP 庫

一、說明 Python 對自然語言處理庫有豐富的支持。從文本處理、標記化文本并確定其引理開始&#xff0c;到句法分析、解析文本并分配句法角色&#xff0c;再到語義處理&#xff0c;例如識別命名實體、情感分析和文檔分類&#xff0c;一切都由至少一個庫提供。那么&#xff0c;你…

地理數據的雙重呈現:GIS與數據可視化

前一篇文章帶大家了解了GIS與三維GIS的關系&#xff0c;本文就GIS話題帶大家一起探討一下GIS和數據可視化之間的關系。 GIS&#xff08;地理信息系統&#xff09;和數據可視化在地理信息科學領域扮演著重要的角色&#xff0c;它們之間密切相關且相互增強。GIS是一種用于采集、…

歐拉函數和最大公約數

分析&#xff1a;如果兩個數的最大公約數是一個質數p&#xff0c;那么這兩個數都除以p&#xff0c;得到的兩個數的最大公約數一定是1. 反證法&#xff1a;如果得到的兩個數的最大公約數不是1&#xff0c;那么把此時的最大公約數乘以上邊的最大公約數&#xff0c;得到的一定比上…

文件操作 和 IO

目錄 ?編輯一、認識文件 1、文件路徑 2、其它知識 二、Java 中操作文件 三、文件內容的讀寫 1、Reader 2、InputStream 3、輸出 一、認識文件 文件是在硬盤上存儲數據的一種方式&#xff0c;操作系統幫我們把硬盤的一些細節都封裝起來了 我們只需要了解文件相關的一些…

【前端 | CSS】滾動到底部加載,滾動監聽、懶加載

背景 在日常開發過程中&#xff0c;我們會遇到圖片懶加載的功能&#xff0c;基本原理是&#xff0c;滾動條滾動到底部后再次獲取數據進行渲染。 那怎么判斷滾動條是否滾動到底部呢&#xff1f;滾動條滾動到底部觸發時間的時機和方法又該怎樣定義&#xff1f; 針對以上問題我…

數據集成革新:去中心化微服務集群的無限潛能

在當今數據密集型的業務環境下&#xff0c;傳統的集中式架構已經難以滿足高可用性和高并發性的要求。而去中心化微服務集群則通過分散式的架構&#xff0c;將系統劃分為多個小型的、獨立部署的微服務單元&#xff0c;每個微服務負責特定的業務功能&#xff0c;實現了系統的高度…

centos系統kubeadm安裝K8S_v1.27.x容器使用docker(K8S_v1.24版本以后依然使用docker容器管理)

kubeadm安裝K8S_v1.27.x容器使用docker 按照需要的文檔點擊這里下載 一.環境部署 1.1基礎環境配置 主機IP 主機名規劃 192.168.186.128 k8s-master01 192.168.186.129 k8s-node01 192.168.186.130 k8s-node02 1.2修改機器名稱 #永久修改主機名 hostnamectl set-hostname …

docker搭建opengrok環境

引言&#xff1a; 由于這幾天開始 http://aospxref.com/ 網站沒法用了。用習慣了opengrok的方式看AOSP的源碼&#xff0c;其他的在線查看源碼的網站用起來都不是很理想。所以考慮搭建一個環境。 首先網上看了下opengrok的環境搭建的方式&#xff0c;最終還是采用docker的方…

【JS 一個數組隨機選取x個元素】

可以使用Math.random()方法&#xff0c;結合循環和splice()方法來實現&#xff1a; let arr [1,2,3,4,5,6,7,8,9]; let randomArr [];for(let i 0; i < 4; i) {let randomIndex Math.floor(Math.random() * arr.length);let randomNum arr.splice(randomIndex, 1)[0];…