036.集群網路-K8S網路模型及Linux基礎網路

来源:https://www.cnblogs.com/itzgr/archive/2020/03/22/12544350.html
-Advertisement-
Play Games

一 Kubernetes網路模型概述 1.1 Kubernetes網路模型 Kubernetes網路模型設計的一個基礎原則是:每個Pod都擁有一個獨立的IP地址,並假定所有Pod都在一個可以直接連通的、扁平的網路空間中。所以不管它們是否運行在同一個Node(宿主機)中,都要求它們可以直接通過對方的I ...


一 Kubernetes網路模型概述

1.1 Kubernetes網路模型

Kubernetes網路模型設計的一個基礎原則是:每個Pod都擁有一個獨立的IP地址,並假定所有Pod都在一個可以直接連通的、扁平的網路空間中。所以不管它們是否運行在同一個Node(宿主機)中,都要求它們可以直接通過對方的IP進行訪問。設計這個原則的原因是,用戶不需要額外考慮如何建立Pod之間的連接,也不需要考慮如何將容器埠映射到主機埠等問題。 實際上,在Kubernetes的集群里,IP是以Pod為單位進行分配的。一個Pod內部的所有容器共用一個網路堆棧(相當於一個網路命名空間,它們的IP地址、網路設備、配置等都是共用的)。按照這個網路原則抽象出來的為每個Pod都設置一個IP地址的模型也被稱作IP-per-Pod模型。 由於Kubernetes的網路模型假設Pod之間訪問時使用的是對方Pod的實際地址,所以一個Pod內部的應用程式看到的自己的IP地址和埠與集群內其他Pod看到的一樣。它們都是Pod實際分配的IP地址。將IP地址和埠在Pod內部和外部都保持一致,也就不需要使用NAT來進行地址轉換了。 Kubernetes的網路之所以這麼設計,主要原因就是可以相容過去的應用。當然,我們使用Linux命令“ipaddrshow”也能看到這些地址,和程式看到的沒有什麼區別。所以這種IP-per-Pod的方案很好地利用了現有的各種功能變數名稱解析和發現機制。 為每個Pod都設置一個IP地址的模型還有另外一層含義,那就是同一個Pod內的不同容器會共用同一個網路命名空間,也就是同一個Linux網路協議棧。這就意味著同一個Pod內的容器可以通過localhost來連接對方的埠。這種關係和同一個VM內的進程之間的關係是一樣的,看起來Pod內容器之間的隔離性減小了,而且Pod內不同容器之間的埠是共用的,就沒有所謂的私有埠的概念了。如果應用必須要使用一些特定的埠範圍,那麼也可以為這些應用單獨創建一些Pod。反之,對那些沒有特殊需要的應用,由於Pod內的容器是共用部分資源的,所以可以通過共用資源互相通信,這顯然更加容易和高效。針對這些應用,雖然損失了可接受範圍內的部分隔離性,卻也是值得的。 IP-per-Pod模式和Docker原生的通過動態埠映射方式實現的多節點訪問模式有如下差別:
  • 主要區別是後者的動態埠映射會引入埠管理的複雜性,而且訪問者看到的IP地址和埠與服務提供者實際綁定的不同(因為NAT的緣故,它們都被映射成新的地址或埠了),這也會引起應用配置的複雜化。
  • 同時,標準的DNS等名字解析服務也不適用了,甚至服務註冊和發現機制都比較複雜,因為在埠映射情況下,服務自身很難知道自己對外暴露的真實的服務IP和埠,外部應用也無法通過服務所在容器的私有IP地址和埠來訪問服務。
總的來說,IP-per-Pod模型是一個簡單的相容性較好的模型。從該模型的網路的埠分配、功能變數名稱解析、服務發現、負載均衡、應用配置和遷移等角度來看,Pod都能夠被看作一臺獨立的虛擬機或物理機。 按照這個網路抽象原則,Kubernetes對網路有如下要求。
  1. 所有容器都可以在不用NAT的方式下同別的容器通信。
  2. 所有節點都可以在不用NAT的方式下同所有容器通信,反之亦然。
  3. 容器的地址和別人看到的地址是同一個地址。
這些基本要求意味著並不是只要兩台機器都運行Docker,Kubernetes就可以工作了。具體的集群網路實現必須滿足上述基本要求,原生的Docker網路目前還不能很好地支持這些要求。 實際上,這些對網路模型的要求並沒有降低整個網路系統的複雜度。如果程式原來在VM上運行,而那些VM擁有獨立IP,並且它們之間可以直接透明地通信,那麼Kubernetes的網路模型就和VM使用的網路模型一樣。所以使用這種模型可以很容易地將已有的應用程式從VM或者物理機遷移到容器上。 當然,谷歌設計Kubernetes的一個主要運行基礎就是其公有雲GCE,GCE預設支持這些網路要求。另外,常見的其他公有雲服務商如亞馬遜等,其公有雲環境也支持這些網路要求。 由於部署私有雲的場景也非常普遍,所以在私有雲中運行Kubernetes+Docker集群之前,需要自己搭建出符合Kubernetes要求的網路環境。有很多開源組件可以幫助我們打通Docker容器和容器之間的網路,實現滿足Kubernetes要求的網路模型。當然,每種方案都有適合的場景,需要根據自己的實際需要進行選擇。 提示:Kubernetes的網路依賴於Docker,Docker的網路又離不開Linux操作系統內核特性的支持。

二 Docker網路基礎

Docker本身的技術依賴於近年來Linux內核虛擬化技術的發展,所以Docker對Linux內核的特性有很強的依賴。Docker通常使用到的與Linux網路有關的主要技術有:網路命名空間(Network Namespace)、Veth設備對、網橋、ipatables和路由。

2.1 網路命名空間

為了支持網路協議棧的多個實例,Linux在網路棧中引入了網路命名空間,這些獨立的協議棧被隔離到不同的命名空間中。 處於不同命名空間中的網路棧是完全隔離的,彼此之間無法通信。通過對網路資源的隔離,就能在一個宿主機上虛擬多個不同的網路環境。Docker正是利用了網路的命名空間特性,實現了不同容器之間的網路隔離。在Linux的網路命名空間中可以有自己獨立的路由表及獨立的iptables設置來提供包轉發、NAT及IP包過濾等功能。 為了隔離出獨立的協議棧,需要納入命名空間的元素有進程、套接字、網路設備等。進程創建的套接字必須屬於某個命名空間,套接字的操作也必須在命名空間中進行。同樣,網路設備也必須屬於某個命名空間。因為網路設備屬於公共資源,所以可以通過修改屬性實現在命名空間之間移動。
  • 網路命名空間的實現
Linux的網路協議棧相對複雜,為了支持獨立的協議棧,相關的這些全局變數都必須被修改為協議棧私有。最好的辦法就是讓這些全局變數成為一個Net Namespace變數的成員,然後為協議棧的函數調用加入一個Namespace參數。這就是Linux實現網路命名空間的核心。 同時,為了保證對已經開發的應用程式及內核代碼的相容性,內核代碼隱式地使用了命名空間中的變數。程式如果沒有對命名空間有特殊需求,就不需要編寫額外的代碼,網路命名空間對應用程式而言是透明的。 在建立了新的網路命名空間,並將某個進程關聯到這個網路命名空間後,就出現了類似於下圖所示的內核數據結構,所有網站棧變數都被放入了網路命名空間的數據結構中。這個網路命名空間是其進程組私有的,和其他進程組不衝突。 clipboard 在新生成的私有命名空間中只有迴環設備(名為“lo”且是停止狀態),其他設備預設都不存在,若需要其他設備,則要手工建立。 從網路角度,每個namespace提供了一份獨立的網路協議棧(網路設備介面、IPV4、IPV6、IP路由、防火牆規則、sockets等)。一個設備(Linux Device)只能位於一個namespace中,不同namespace中的設備可以利用veth pair進行橋接。 clipboard namespace可實現隔離的資源:
資源 含義
uts_ns UTS為Unix Timessharing System的簡稱,包含記憶體名稱、腳本、版本、底層體繫結構等信息。
ipc_ns 所有與進程通信(IPC)有關的信心。
nmt_ns 當前裝載的文件系統。
pid_ns 有關進程ID的信息。
user_ns 資源配額的信息。
net_ns 網路信息。
Docker容器中的各類網路棧設備都是Docker Daemon在啟動時自動創建和配置的。 所有的網路設備(物理的或虛擬介面、橋等在內核里都叫作NetDevice)都只能屬於一個命名空間。 註意,物理設備(連接實際硬體的設備)通常只能關聯到root這個命名空間中。虛擬的網路設備(虛擬的乙太網介面或者虛擬網口對)則可以被創建並關聯到一個給定的命名空間中,而且可以在這些命名空間之間移動。 同時,由於網路命名空間代表的是一個獨立的協議棧,所以它們之間是相互隔離的,彼此無法通信,在協議棧內部都看不到對方。 若需要打破這種限制,讓處於不同命名空間的網路相互通信,甚至和外部的網路進行通信,則需要應用Veth設備對。Veth設備對的一個重要作用就是打通互相看不到的協議棧之間的壁壘,類似一個通道,一端連著這個網路命名空間的協議棧,一端連著另一個網路命名空間的協議棧。所以如果想在兩個命名空間之間通信,就必須有一個Veth設備對。
  • 網路命名空間操作
如下命令需要使用root用戶執行,同時需要iproute軟體包提供相關命令。
  1 [root@k8smaster01 ~]# ip netns add mytestns			#創建命名空間
  2 [root@k8smaster01 ~]# ip netns exec mytestns <command>	#進入命名空間bash
  3 [root@k8smaster01 ~]# ip netns exec mytestns bash		#進入命名空間bash
  4 [root@k8smaster01 ~]# exit					#退出命名空間
  5 [root@k8smaster01 ~]# ip link set <device> netns mytestns	#轉移設備
註意:因為一個設備只能屬於一個命名空間,所以轉移後在這個命名空間中就看不到這個設備了。在設備裡面有一個重要的屬性:NETIF_F_ETNS_LOCAL,如果這個屬性為on,就不能被轉移到其他命名空間中。Veth設備屬於可以轉移的設備,而很多其他設備如lo設備、vxlan設備、ppp設備、bridge設備等都是不可以轉移的。

2.2 Veth設備對

引入Veth設備對是為了在不同的網路命名空間之間通信,利用它可以直接將兩個網路命名空間連接起來。由於要連接兩個網路命名空間,所以Veth設備都是成對出現的,很像一對乙太網卡,並且中間有一根直連的網線。通常將其中一端稱為另一端的peer。 在Veth設備的一端發送數據時,它會將數據直接發送到另一端,並觸發另一端的接收操作。Veth設備對的示意圖如下: 1575105169
  • veth pair操作
  1 [root@k8smaster01 ~]# ip link add veth0 type veth peer name veth1	#創建veth設備對
  2 [root@k8smaster01 ~]# ip link show | grep veth			#當前查看veth
  3 [root@k8smaster01 ~]# ip netns add ns0
  4 [root@k8smaster01 ~]# ip netns add ns1				#創建命名空間
  5 [root@k8smaster01 ~]# ip link set veth0 netns ns0
  6 [root@k8smaster01 ~]# ip link set veth1 netns ns1			#veth移入命名空間
  7 [root@k8smaster01 ~]# ip netns exec ns0 ip link show		#進入命名空間查看veth
  8 [root@k8smaster01 ~]# ip netns exec ns0 ip addr add local 192.168.10.1/24 dev veth0
  9 [root@k8smaster01 ~]# ip netns exec ns1 ip addr add local 192.168.10.2/24 dev veth1	#設置對應的IP
 10 [root@k8smaster01 ~]# ip netns exec ns0 ifconfig veth0 up
 11 [root@k8smaster01 ~]# ip netns exec ns1 ifconfig veth1 up		#開啟設備
 12 [root@k8smaster01 ~]# ip netns exec ns0 ping 192.168.10.2		#連通性測試
clipboard 提示:在Docker內部,Veth設備對也是連通容器與宿主機的主要網路設備。
  1 [root@k8smaster01 ~]# ip netns exec ns0 ethtool -S veth0
  2 NIC statistics:
  3      peer_ifindex: 9
  4 [root@k8smaster01 ~]# ip netns exec ns1 ip link | grep 9
clipboard

2.3 網橋

Linux可以支持多個不同的網路,它們之間能夠相互通信,可通過網橋將這些網路連接起來並實現各網路中主機的相互通信。 網橋是一個二層的虛擬網路設備,把若幹個網路介面“連接”起來,以使得網路介面之間的報文能夠互相轉發。網橋能夠解析收發的報文,讀取目標MAC地址的信息,和自己記錄的MAC表結合,來決策報文的轉發目標網路介面。 為了實現轉發功能,網橋學習源MAC地址(二層網橋轉發的依據就是MAC地址)。在轉發報文時,網橋只需要向特定的網口進行轉發,來避免不必要的網路交互。如果接受到未學習到的地址,就無法知道這個報文應該向哪個網路介面轉發,就將報文廣播給所有的網路介面(報文來源的網路介面除外)。 在實際的網路中,網路拓撲若出現改變,如設備被移動到另一個埠上,卻沒有發送任何數據,網橋設備就無法感知到這個變化,網橋還是向原來的埠轉發數據包,在這種情況下數據就會丟失。所以網橋還要對學習到的MAC地址表加上超時時間(預設為5min)。如果網橋收到了對應埠MAC地址回發的包,則重置超時時間,否則過了超時時間後,就認為設備已經不在那個埠上了,它就會重新廣播發送。 對於多網卡、多虛擬的設備,Linux的網橋提供了在這些設備之間互相轉發數據的二層設備。Linux內核支持網口的橋接(目前只支持乙太網介面)。但是與單純的交換機不同,交換機只是一個二層設備,對於接收到的報文,要麼轉發,要麼丟棄。運行著Linux內核的機器本身就是一臺主機,有可能是網路報文的目的地,其收到的報文除了轉發和丟棄,還可能被送到網路協議棧的上層(網路層),從而被自己(這台主機本身的協議棧)消化,所以既可以把網橋看作一個二層設備,也可以把它看作一個三層設備。
  • Linux網橋的實現
Linux內核是通過一個虛擬的網橋設備(Net Device)來實現橋接的。這個虛擬設備可以綁定若幹個乙太網介面設備,從而將它們橋接起來。如下圖所示,這種Net Device網橋和普通的設備不同,最明顯的一個特性是還可以有一個IP地址。 clipboard 如上圖所示,網橋設備br0綁定了eth0和eth1。對於網路協議棧的上層來說,只看得到br0就行。因為橋接是在數據鏈路層實現的,上層不需要關心橋接的細節,所以協議棧上層需要發送的報文被送到br0,網橋設備的處理代碼判斷報文該被轉發到eth0還是eth1,或者兩者皆轉發;反之,從eth0或從eth1接收到的報文被提交給網橋的處理代碼,在這裡會判斷報文應該被轉發、丟棄還是被提交到協議棧上層。而有時eth0、eth1也可能會作為報文的源地址或目的地址,直接參与報文的發送與接收,從而繞過網橋。
  • 網橋的常用操作命令
Docker自動完成了對網橋的創建和維護。 新增一個網橋設備: [root@k8smaster01 ~]# brctl #查看brctl模塊 clipboard 提示:可通過# yum -y install bridge-utils安裝brctl。 為網橋增加網口,在Linux中,一個網口其實就是一個物理網卡。 clipboard
  1 [root@k8smaster01 ~]# ip link add tap1 type veth peer name tap1_peer
  2 [root@k8smaster01 ~]# ip link add tap2 type veth peer name tap2_peer
  3 [root@k8smaster01 ~]# ip link add tap3 type veth peer name tap3_peer
  4 [root@k8smaster01 ~]# ip link add tap4 type veth peer name tap4_peer
  5 #創建veth pair
  6 [root@k8smaster01 ~]# ip netns add ns1
  7 [root@k8smaster01 ~]# ip netns add ns2
  8 [root@k8smaster01 ~]# ip netns add ns3
  9 [root@k8smaster01 ~]# ip netns add ns4
 10 #創建namespace
 11 [root@k8smaster01 ~]# ip link set tap1 netns ns1
 12 [root@k8smaster01 ~]# ip link set tap2 netns ns2
 13 [root@k8smaster01 ~]# ip link set tap3 netns ns3
 14 [root@k8smaster01 ~]# ip link set tap4 netns ns4
 15 #tap和namespace關聯
 16 [root@k8smaster01 ~]# brctl addbr br1		#創建橋
 17 [root@k8smaster01 ~]# brctl addif br1 tap1_peer
 18 [root@k8smaster01 ~]# brctl addif br1 tap2_peer
 19 [root@k8smaster01 ~]# brctl addif br1 tap3_peer
 20 [root@k8smaster01 ~]# brctl addif br1 tap4_peer
 21 #把相應的tap添加至bright中
 22 [root@k8smaster01 ~]# ip netns exec ns1 ip addr add local 192.168.20.1/24 dev tap1
 23 [root@k8smaster01 ~]# ip netns exec ns2 ip addr add local 192.168.20.2/24 dev tap2
 24 [root@k8smaster01 ~]# ip netns exec ns3 ip addr add local 192.168.20.3/24 dev tap3
 25 [root@k8smaster01 ~]# ip netns exec ns4 ip addr add local 192.168.20.4/24 dev tap4
 26 #配置相應IP地址
 27 [root@k8smaster01 ~]# ip link set br1 up
 28 [root@k8smaster01 ~]# ip link set tap1_peer up
 29 [root@k8smaster01 ~]# ip link set tap2_peer up
 30 [root@k8smaster01 ~]# ip link set tap3_peer up
 31 [root@k8smaster01 ~]# ip link set tap4_peer up
 32 [root@k8smaster01 ~]# ip netns exec ns1 ip link set tap1 up
 33 [root@k8smaster01 ~]# ip netns exec ns2 ip link set tap2 up
 34 [root@k8smaster01 ~]# ip netns exec ns3 ip link set tap3 up
 35 [root@k8smaster01 ~]# ip netns exec ns4 ip link set tap4 up
 36 #將bright和tap設置為up
 37 [root@k8smaster01 ~]# ip netns exec ns1 ping 192.168.20.2		#互ping
clipboard 提示:若物理網卡作為網橋的一個網口,則此物理網卡將在鏈路層工作(是一個純鏈路層設備),就不再需要IP地址了,可以取消物理網卡的IP,給網橋配置一個IP地址。

2.4 iptables和Netfilter

Linux提供了一套機制來為用戶實現自定義的數據包處理過程。在Linux網路協議棧中有一組回調函數掛接點,通過這些掛接點掛接的鉤子函數可以在Linux網路棧處理數據包的過程中對數據包進行一些操作,例如過濾、修改、丟棄等。 整個掛接點技術叫作Netfilter和iptables。Netfilter負責在內核中執行各種掛接的規則,運行在內核模式中;而iptables是在用戶模式下運行的進程,負責協助和維護內核中Netfilter的各種規則表。二者互相配合來實現整個Linux網路協議棧中靈活的數據包處理機制。
  • iptables規則
iptables內置三張表:filter、nat和mangle。
  • filter:實現防火牆功能;
  • nat:實現NAT功能;
  • mangle:實現流量整形。
iptables三張表,或三條鏈(chain),也是三種策略(policy)。這類策略,由不同規則(rule)串聯而成。 提示:更多iptables知識參考:https://wiki.archlinux.org/index.php/Iptables_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)。 規則示例:iptables - A INPUT - i ethO -p icmp -j ACCEPT 解釋:允許所有從 ethO 埠進入且協議是 ICMP 的報文可以接受(可以進入下一個流程)。 規則的本質是對進入的IP報文進行說明,如:符合什麼樣的條件(比如本條命令的條件是“允許所有從eth0埠進入且協議是 ICPM 的報文”)、做什麼樣的處理(比如本條命令的處理是“接受”,可以進入下一個流程)。 查看系統中已有規則的方法如下。
  • iptables-save: 按照命令的方式列印iptables的內容。
  • iptables-vnL: 以另一種格式顯示Netfilter表的內容。
  • Netfilter規則
iptables可以定義多種策略/規則,所有規則最終會傳遞到內核netfilter模塊,netfilter模塊會根據這些規則做相應的處理。 netfilter的處理方式是:從報文進入本機( linux host 或 vm)的那一刻起,到報文離開本機的那一刻止,中間這段時間(或者是發自本機的報文,從報文準備發送的那一刻,到報文離開本機的那一刻止,中間這段時間),netfilter 會在ABCDE時刻點插入處理模塊,這些處理模塊根據相應的策略/規則對報文進行處理。 對於 nat 、 filter 、 mangle 三張表也可以這麼理解:僅僅是為了達到不同的目的(功能)而實現的三個模塊而已 。 Netfilter可以掛接的規則點有5個,如下圖所示: clipboard 在這些時刻點中,iptables三張表(模塊)並不是所有的時刻都全部進行處理。在同一個時刻點,也可以有多個模塊進行處理,對於不同模塊誰先處理,誰後處理,可參考如下順序。 clipboard 解釋:
  1. PREROUTING:報文進入網路介面尚未進入路由之前的時刻;
  2. INPUT:路由判斷是本機接收的報文,準備從內核空間進入到用戶空間的時刻;
  3. FORWARD:路由判斷不是本機接收的報文,需要路由轉發,路由轉發的那個時刻;
  4. OUTPUT:本機報文需要發出去 經過路由判斷選擇好埠以後,準備發送的那一刻 ;
  5. POSTROUTING:FORWARD/OUTPUT 已經完成,報文即將出網路介面的那一刻 。
三張表所能對應的時刻點如下:
表名 時刻點
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 我們經常會遇到新裝機器或者用別人的linux機器的時候找不到某個命令出自哪個軟體包而不知道如何安裝的情況,用如下命令可以解決 yum provides TARGET 舉例說明: 這裡因為我已經安裝了,所以提示了我文件位置(安裝了找不到也可以這樣找) 最重要的是如這行 說明是這個redhat lsb ...
  • 1.網卡文件位置 centos網卡配置文件一般位於:/etc/sysconfig/network scripts/ 文件名一般為:ifcfg eno或者ifcfg eth0類似的文件,可以先用ip addr 命令或者是ifconfig命令查看網卡信息 如果是新機器沒有配置文件一般也會有ifcfg l ...
  • 一 Kubernetes網路實現 1.1 Kubernetes網路優勢 在實際的業務場景中,業務組件之間的關係十分複雜,微服務的理念更是讓應用部署的粒度更加細小和靈活。為了支持業務應用組件的通信,Kubernetes網路的設計主要致力於解決以下問題。 容器到容器之間的直接通信。 抽象的Pod到Pod ...
  • 一 Docker網路 1.1 Docker網路類型 標準的Docker支持以下4類網路模式: host模式:使用--net=host指定。 container模式:使用--net=container:NAME_or_ID指定。 none模式:使用--net=none指定。 bridge模式:使用-- ...
  • 工作中我們會遇到安裝軟體需要知道linux是什麼發行版本,話不多話上乾貨(按照我認為常用排序) 1. lsb_release a 名詞解釋:LSB (Linux Standard Base) 2. cat /etc/issue 3. cat /proc/version 4. uname a 查看版本 ...
  • Nginx 介紹 Nginx 是一個高性能的 Web 伺服器,從 2001 年發展至今,由於 Nginx 對硬體和操作系統內核特性的深度挖掘,使得在保持高併發的同時還能夠保持高吞吐量。Nginx 還採用了模塊設計,有大量的第三方模塊可以擴展 Nginx 的功能,因此 Nginx 的場景非常豐富,同時 ...
  • 記下來!以後別忘了 我把自己的小筆記本重裝了下系統 一、linux裝機 centos8 1、U盤啟動 2、進入安裝引導頁 3、按下鍵盤TAB鍵將最下麵的vmlinuz initrd=initrd.img inst.stage2=hd:LABEL=CentOS\x207\x20x86_64 rd.li ...
  • arm裸機,linux開發,編譯器,編譯環境答疑解惑 前言: 最近一直在跟著正點原子的i.mx6ull視頻學習,打算研究一下嵌入式linux的開發,主要是道聽途說單片機開發未來薪資不高,想著反正單片機學的也就半吊子,何不趁此時各大廠商(某點,某火,某山)紛紛推出免費視頻,開始進行價格戰的時候,從中漁 ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...