日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

k8s网络通信

發布時間:2024/9/3 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 k8s网络通信 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、通信模式

一 、k8s通過CNI接口接入其他插件來實現網絡通訊。目前比較流行的插件有flannel,calico等。
CNI插件存放位置:# cat /etc/cni/net.d/10-flannel.conflist
插件使用的解決方案如下:

  • 虛擬網橋,虛擬網卡,多個容器共用一個虛擬網卡進行通信。
  • 多路復用:MacVLAN,多個容器共用一個物理網卡進行通信。
  • 硬件交換:SR-LOV,一個物理網卡可以虛擬出多個接口,這個性能最好。

二、容器間通信:同一個pod內的多個容器間的通信,通過lo即可實現;

三、pod之間的通信:

  • 同一節點的pod之間通過cni網橋轉發數據包。
  • 不同節點的pod之間的通信需要網絡插件支持。

四、pod和service通信: 通過iptables或ipvs實現通信,ipvs取代不了iptables,因為ipvs只能做負載均衡,而做不了nat轉換。

五、pod和外網通信:iptables的MASQUERADE。

六、Service與集群外部客戶端的通信;(ingress、nodeport、loadbalancer)

二、service

1 k8s提供的dns服務插件

[root@server2 ~]# kubectl describe svc myservice

[root@server2 ~]# kubectl run demo1 --image=busyboxplus -it If you don't see a command prompt, try pressing enter. / # nslookup myservice / # curl myservice [root@server2 ~]# kubectl get service kube-dns --namespace=kube-system

[root@server2 ~]# dig myservice.default.svc.cluster.local. @10.96.0.10

2 Headless Service “無頭服務”

  • Headless Service不需要分配一個VIP,而是直接以DNS記錄的方式解析出被代理Pod的IP地址。
  • 域名格式:(servicename).(servicename).(servicename).(namespace).svc.cluster.local
[root@server2 ~]# vim demo.yml #clusterIP: None #無頭服務 --- apiVersion: v1 kind: Service metadata:name: myservice spec:selector:app: myappports:- protocol: TCPport: 80targetPort: 80clusterIP: None #無頭服務---apiVersion: apps/v1 kind: Deployment metadata:name: demo2 spec:replicas: 3selector:matchLabels:app: myapptemplate:metadata:labels:app: myappspec:containers:- name: myappimage: myapp:v2 [root@server2 ~]# kubectl apply -f demo.yml [root@server2 ~]# kubectl get svc

從下圖看到沒有分配固定ip,而是直接以DNS記錄的方式解析出被代理Pod的IP地址。

[root@server2 ~]# dig myservice.default.svc.cluster.local. @10.96.0.10


3 創建service(NodePort方式)

[root@server2 ~]# vim demo.yml --- apiVersion: v1 kind: Service metadata:name: myservice spec:selector:app: myappports:- protocol: TCPport: 80targetPort: 80#clusterIP: Nonetype: NodePort---apiVersion: apps/v1 kind: Deployment metadata:name: demo2 spec:replicas: 3selector:matchLabels:app: myapptemplate:metadata:labels:app: myappspec:containers:- name: myappimage: myapp:v2 [root@server2 ~]# kubectl delete -f demo.yml [root@server2 ~]# kubectl apply -f demo.yml [root@server2 ~]# kubectl get svc

在ip的基礎上又加了一個端口

4. LoadBalancer 類型的 Service

從外部訪問 Service 的第二種方式,適用于公有云上的 Kubernetes 服務。這時候,你可以指定一個 LoadBalancer 類型的 Service。
在service提交后,Kubernetes就會調用 CloudProvider 在公有云上為你創建一個負載均衡服務,并且把被代理的 Pod 的 IP地址配置給負載均衡服務做后端。

將剛才的demo.yml中的類型變成LoadBalancer即可
由于我們使用的不是共有云,所以暫時不能實現,EXTERNAL-IP顯示的是pending等待分配ip狀態

5 service允許為其分配一個公有IP

在ClusterIP的基礎上,給綁定了一個外部地址,在外部可以直接訪問

[root@server2 ~]# vim demo.yml externalIPs:- 172.25.1.10



在外部主機可以通過這個ip進行訪問

6 ExternalName

從外部訪問的第三種方式叫做ExternalName

[root@server2 ~]# vim my-service.yml apiVersion: v1 kind: Service metadata:name: my-service spec:type: ExternalNameexternalName: www.baidu.com


兩種驗證方式:

[root@server2 ~]# dig -t A my-service.default.svc.cluster.local. @10.96.0.10 #dig [root@server2 ~]# kubectl attach demo1 -it #進入交互測試


三、(pod間通信)Flannel 網絡

Flannel vxlan模式跨主機通信原理

(1)VXLAN,即Virtual Extensible LAN(虛擬可擴展局域網),是Linux本身支持的一網種網絡虛擬化技術。VXLAN可以完全在內核態實現封裝和解封裝工作,從而通過“隧道”機制,構建出覆蓋網絡(Overlay Network)。

(2)VTEP:VXLAN Tunnel End Point(虛擬隧道端點),在Flannel中 VNI的默認值是1,這也是為什么宿主機的VTEP設備都叫flannel.1的原因。

(3)Cni0: 網橋設備,每創建一個pod都會創建一對 veth pair。其中一端是pod中的eth0,另一端是Cni0網橋中的端口(網卡)。

(4)Flannel.1: TUN設備(虛擬網卡),用來進行 vxlan 報文的處理(封包和解包)。不同node之間的pod數據流量都從overlay設備以隧道的形式發送到對端。

(5)Flanneld:flannel在每個主機中運行flanneld作為agent,它會為所在主機從集群的網絡地址空間中,獲取一個小的網段subnet,本主機內所有容器的IP地址都將從中分配。同時Flanneld監聽K8s集群數據庫,為flannel.1設備提供封裝數據時必要的mac、ip等網絡數據信息。

flannel網絡原理

當容器發送IP包,通過veth pair 發往cni網橋,再路由到本機的flannel.1設備進行處理。
VTEP設備之間通過二層數據幀進行通信,源VTEP設備收到原始IP包后,在上面加上一個目的MAC地址,封裝成一個內部數據幀,發送給目的VTEP設備。
內部數據楨,并不能在宿主機的二層網絡傳輸,Linux內核還需要把它進一步封裝成為宿主機的一個普通的數據幀,承載著內部數據幀通過宿主機的eth0進行傳輸。
Linux會在內部數據幀前面,加上一個VXLAN頭,VXLAN頭里有一個重要的標志叫VNI,它是VTEP識別某個數據楨是不是應該歸自己處理的重要標識。
flannel.1設備只知道另一端flannel.1設備的MAC地址,卻不知道對應的宿主機地址是什么。在linux內核里面,網絡設備進行轉發的依據,來自FDB的轉發數據庫,這個flannel.1網橋對應的FDB信息,是由flanneld進程維護的。
linux內核在IP包前面再加上二層數據幀頭,把目標節點的MAC地址填進去,MAC地址從宿主機的ARP表獲取。
此時flannel.1設備就可以把這個數據幀從eth0發出去,再經過宿主機網絡來到目標節點的eth0設備。目標主機內核網絡棧會發現這個數據幀有VXLAN Header,并且VNI為1,Linux內核會對它進行拆包,拿到內部數據幀,根據VNI的值,交給本機flannel.1設備處理,flannel.1拆包,根據路由表發往cni網橋,最后到達目標容器。

[root@server2 ~]# kubectl get pod -n kube-system



相同主機之間的pod通過cni通信

在server3上要先知道目標主機(server4)eth0的IP和mac地址



arp -n 可以查看到有server4的ip信息。

flannel支持多種后端

Vxlan

  • vxlan //報文封裝,默認
  • Directrouting //直接路由,跨網段使用vxlan,同網段使用host-gw模式。
    host-gw://主機網關,性能好,但只能在二層網絡中,不支持跨網絡,如果有成千上萬的Pod,容易產生廣播風暴,不推薦
    UDP: //性能差,不推薦

host-gw主機網關

修改配置flannel:

[root@server2 ~]# kubectl -n kube-system edit cm kube-flannel-cfg


生效:

[root@server2 ~]# kubectl get pod -n kube-system |grep flannel | awk '{system("kubectl delete pod "$1" -n kube-system")}'


從下圖我們可以看出本地的話直接走cni,如果是1,0網段的直接走網關etho

vxlan

[root@server2 ~]# kubectl -n kube-system edit cm kube-flannel-cfg "Type": "vxlan","Directrouting": true [root@server2 ~]# kubectl get pod -n kube-system |grep flannel | awk '{system("kubectl delete pod "$1" -n kube-system")}'





并沒有經過flannel.1

四、Service與集群外部客戶端的通信(Ingress 服務)

  • 一種全局的、為了代理不同后端 Service 而設置的負載均衡服務,就是 Kubernetes 里的Ingress 服務。
  • Ingress由兩部分組成:Ingress controller和Ingress服務。
  • Ingress Controller 會根據你定義的 Ingress 對象,提供對應的代理能力。業界常用的各種反向代理項目,比如 Nginx、HAProxy、Envoy、Traefik 等,都已經為Kubernetes 專門維護了對應的 Ingress Controller。


官網:ingress-nginx
下載鏡像并上傳到本地倉庫,鏡像下載需要翻墻
所需的資源鏈接: yaml文件和鏡像 提取碼: nbvc

Ingress 服務部署:

[root@server1 ~]# docker load -i ingress-nginx.tar [root@server1 ~]# docker tag quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.33.0 reg.westos.org/library/nginx-ingress-controller:0.33.0 [root@server1 ~]# docker tag jettech/kube-webhook-certgen:v1.2.0 reg.westos.org/library/kube-webhook-certgen:v1.2.0 [root@server1 ~]# docker push reg.westos.org/library/nginx-ingress-controller:0.33.0 [root@server1 ~]# docker push reg.westos.org/library/kube-webhook-certgen:v1.2.0[root@server2 ~]# mkdir ingress-nginx/ [root@server2 ~]# cd ingress-nginx/ [root@server2 ingress-nginx]# kubectl apply -f deploy.yaml [root@server2 ingress-nginx]# kubectl get ns [root@server2 ingress-nginx]# kubectl get all -n ingress-nginx


創建Ingress服務

[root@server2 ~]# vim nginx.yml apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata:name: ingress-demo spec:rules:- host: www1.westos.orghttp:paths:- path: /backend:serviceName: myserviceservicePort: 80 [root@server2 ~]# kubectl apply -f nginx.yml


做好地址解析:


用DaemonSet結合nodeselector來部署ingress-controller到特定的node上,然后使用HostNetwork直接把該pod與宿主機node的網絡打通,直接使用宿主機的80/443端口就能訪問服務。

  • 優點是整個請求鏈路最簡單,性能相對NodePort模式更好。
  • 缺點是由于直接利用宿主機節點的網絡和端口,一個node只能部署一個ingress-controller pod。
    比較適合大并發的生產環境使用。

Ingress TLS 加密配置

生成證書: [root@server2 ingress-nginx]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc" 導入證書: [root@server2 ingress-nginx]# kubectl create secret tls tls-secret --key tls.key --cert tls.crt 查看證書: [root@server2 ingress-nginx]# kubectl get secrets


生效:

[root@server2 ingress-nginx]# vim tls.yml apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata:name: nginx-test spec:tls:- hosts:- www1.westos.orgsecretName: tls-secretrules:- host: www1.westos.orghttp:paths:- path: /backend:serviceName: myserviceservicePort: 80 [root@server2 ingress-nginx]# kubectl apply -f tls.yml [root@server2 ingress-nginx]# kubectl describe ingress nginx-test [root@server2 ingress-nginx]# kubectl get ingress



認證

[root@server2 ingress-nginx]# yum install httpd-tools.x86_64 -y [root@server2 ingress-nginx]# htpasswd -c auth sun [root@server2 ingress-nginx]# kubectl create secret generic basic-auth --from-file=auth

[root@server2 ingress-nginx]# vim tls.ymlannotations:nginx.ingress.kubernetes.io/auth-type: basicnginx.ingress.kubernetes.io/auth-secret: basic-auth [root@server2 ingress-nginx]# kubectl apply -f tls.yml [root@server2 ingress-nginx]# kubectl apply -f nginx.yml


Ingress地址重寫

vim tls.yml apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata:name: nginx-testannotations:nginx.ingress.kubernetes.io/rewrite-target: /$2 spec:rules:- host: www1.westos.orghttp:paths:- backend:serviceName: myserviceservicePort: 80path: /westos(/|$)(.*)kubectl apply -f tls.yml curl www1.westos.org == curl www1.westos.org/westos
  • annotations參數

總結

以上是生活随笔為你收集整理的k8s网络通信的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。