主頁 >  其他 > 運維實戰 kubernetes(k8s) 之 service

運維實戰 kubernetes(k8s) 之 service

2021-06-18 14:31:46 其他

@[TOC]( 運維實戰 kubernetes(k8s) 之 service )

1. service 介紹

  • Service可以看作是一組提供相同服務的Pod對外的訪問介面,借助Service,應用可以方便地實作服務發現和負載均衡,
  • service默認只支持4層負載均衡能力,沒有7層功能,(可以通過Ingress實作)
  • service的型別:
    ClusterIP:默認值,k8s系統給service自動分配的虛擬IP,只能在集群內部訪問,
    NodePort:將Service通過指定的Node上的埠暴露給外部,訪問任意一個NodeIP:nodePort都將路由到ClusterIP,
    LoadBalancer:在 NodePort 的基礎上,借助 cloud provider 創建一個外部的負載均衡器,并將請求轉發到 :NodePort,此模式只能在云服務器上使用,
    ExternalName:將服務通過 DNS CNAME 記錄方式轉發到指定的域名(通過 spec.externlName 設定),
  • Service 是由 kube-proxy 組件,加上 iptables 來共同實作的.
  • kube-proxy 通過 iptables 處理 Service 的程序,需要在宿主機上設定相當多的 iptables 規則,如果宿主機有大量的Pod,不斷重繪iptables規則,會消耗大量的CPU資源,
  • IPVS模式的 service,可以使K8s集群支持更多量級的Pod,

先啟動倉庫,然后輸入變數,查看kubectl的狀態;

[root@server1 ~]# cd harbor/
[root@server1 harbor]# docker-compose start

[root@server2 ~]# export KUBECONFIG=/etc/kubernetes/admin.conf
[root@server2 ~]# kubectl get pod -n kube-system

2. 開啟 kube-proxy 的 ipvs 模式

要確保倉庫的存在;此處用的是本機的源;

[root@server2 k8s]# cd /etc/yum.repos.d/
[root@server2 yum.repos.d]# ls
docker.repo  dvd.repo  k8s.repo  redhat.repo
[root@server2 yum.repos.d]# vim k8s.repo 
[root@server2 yum.repos.d]# cat k8s.repo 
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=0	##將此處改為0,不啟用該源;使用本機的源來安裝
gpgcheck=0

每個結點安裝yum install -y ipvsadm 軟體;
安裝完成之后:

[root@server2 ~]# ipvsadm -l
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
[root@server2 ~]# ipvsadm -ln	
##查看 iptables 的規則,它是內核功能
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
[root@server2 ~]# lsmod | grep ip_vs
ip_vs_sh               12688  0 
ip_vs_wrr              12697  0 
ip_vs_rr               12600  0 
ip_vs                 145497  6 ip_vs_rr,ip_vs_sh,ip_vs_wrr
nf_conntrack          133095  10 ip_vs,nf_nat,nf_nat_ipv4,nf_nat_ipv6,xt_conntrack,nf_nat_masquerade_ipv4,nf_nat_masquerade_ipv6,nf_conntrack_netlink,nf_conntrack_ipv4,nf_conntrack_ipv6
libcrc32c              12644  4 xfs,ip_vs,nf_nat,nf_conntrack
[root@server2 ~]# kubectl -n kube-system get cm
	## 查看配置資訊
NAME                                 DATA   AGE
coredns                              1      25h
extension-apiserver-authentication   6      25h
kube-flannel-cfg                     2      24h
kube-proxy                           2      25h
kube-root-ca.crt                     1      25h
kubeadm-config                       2      25h
kubelet-config-1.21                  1      25h
[root@server2 ~]# kubectl -n kube-system edit cm kube-proxy 
##編輯配置資訊,指定使用 ipvs 的模式,不寫時默認用的是 iptables
configmap/kube-proxy edited

    ipvs:
      excludeCIDRs: null
      minSyncPeriod: 0s
      scheduler: ""
      strictARP: false
      syncPeriod: 0s
      tcpFinTimeout: 0s
      tcpTimeout: 0s
      udpTimeout: 0s
    kind: KubeProxyConfiguration
    metricsBindAddress: ""
    mode: "ipvs"
    
configmap/kube-proxy edited

修改完資訊之后,需要多載;由于當前的服務是由控制器所管理,此時只需洗掉之前的pod ,會再次讀取組態檔重新拉取pod;

kube-proxy 通過 linux 的 IPVS 模塊,以 rr 輪詢方式調度 service 的Pod,

[root@server2 ~]# kubectl -n kube-system get daemonsets.apps 
NAME              DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
kube-flannel-ds   3         3         3       3            3           <none>                   24h
kube-proxy        3         3         3       3            3           kubernetes.io/os=linux   25h
[root@server2 ~]# kubectl -n kube-system get pod | grep kube-proxy | awk '{system("kubectl -n kube-system delete pod "$1"")}'
pod "kube-proxy-866lg" deleted
pod "kube-proxy-hxgbt" deleted
pod "kube-proxy-jrc9z" deleted
[root@server2 ~]# ipvsadm -ln
##重啟之后,此時在每個結點上都可以看到 iptables 策略;其中10.96.0.10是 CLUSTER-IP 的地址;0.8 和 0.9 是 dns 所在 pod 的地址;
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.96.0.1:443 rr
  -> 172.25.25.2:6443             Masq    1      0          0         
TCP  10.96.0.10:53 rr
  -> 10.244.0.8:53                Masq    1      0          0         
  -> 10.244.0.9:53                Masq    1      0          0         
TCP  10.96.0.10:9153 rr		
  -> 10.244.0.8:9153              Masq    1      0          0         
  -> 10.244.0.9:9153              Masq    1      0          0         
UDP  10.96.0.10:53 rr
  -> 10.244.0.8:53                Masq    1      0          0         
  -> 10.244.0.9:53                Masq    1      0          0  

[root@server2 ~]# kubectl -n kube-system get svc
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   8d
[root@server2 ~]# kubectl -n kube-system get pod -o wide
NAME                              READY   STATUS    RESTARTS   AGE     IP            NODE      NOMINATED NODE   READINESS GATES
coredns-85ffb569d4-85kp7          1/1     Running   3          8d      10.244.0.9    server2   <none>           <none>
coredns-85ffb569d4-bd579          1/1     Running   3          8d      10.244.0.8    server2   <none>           <none>
etcd-server2                      1/1     Running   3          8d      172.25.25.2   server2   <none>           <none>
kube-apiserver-server2            1/1     Running   3          8d      172.25.25.2   server2   <none>           <none>
kube-controller-manager-server2   1/1     Running   3          8d      172.25.25.2   server2   <none>           <none>
kube-flannel-ds-f8qhr             1/1     Running   2          8d      172.25.25.4   server4   <none>           <none>
kube-flannel-ds-hvfwp             1/1     Running   2          8d      172.25.25.3   server3   <none>           <none>
kube-flannel-ds-mppbp             1/1     Running   3          8d      172.25.25.2   server2   <none>           <none>
kube-proxy-6f78h                  1/1     Running   0          4m10s   172.25.25.2   server2   <none>           <none>
kube-proxy-7jvkr                  1/1     Running   0          4m12s   172.25.25.4   server4   <none>           <none>
kube-proxy-9d5s7                  1/1     Running   0          4m5s    172.25.25.3   server3   <none>           <none>
kube-scheduler-server2            1/1     Running   3          8d      172.25.25.2   server2   <none>           <none>

IPVS 模式下,kube-proxy 會在 service 創建后,在宿主機上添加一個虛擬網卡:kube-ipvs0,并分配 service IP,

[root@server2 ~]# ip addr show kube-ipvs0 
10: kube-ipvs0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default 
    link/ether 52:54:5e:c0:51:56 brd ff:ff:ff:ff:ff:ff
    inet 10.96.0.10/32 scope global kube-ipvs0
       valid_lft forever preferred_lft forever
    inet 10.96.0.1/32 scope global kube-ipvs0
       valid_lft forever preferred_lft forever

新建一個來觀察效果:

[root@server2 k8s]# kubectl get all
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   8d
[root@server2 k8s]# ls
cronjob.yaml  daemonset.yaml  deployment.yaml  job.yaml  pod.yaml  rs.yaml  svc.yaml
[root@server2 k8s]# vim deployment.yaml 
[root@server2 k8s]# kubectl apply -f deployment.yaml 
deployment.apps/deployment-example created
[root@server2 k8s]# kubectl get pod
NAME                                  READY   STATUS    RESTARTS   AGE
deployment-example-5b768f7647-9wlvc   1/1     Running   0          4s
deployment-example-5b768f7647-j6bvs   1/1     Running   0          4s
deployment-example-5b768f7647-ntmk7   1/1     Running   0          4s
[root@server2 k8s]# kubectl get pod --show-labels 
NAME                                  READY   STATUS    RESTARTS   AGE   LABELS
deployment-example-5b768f7647-9wlvc   1/1     Running   0          52s   app=nginx,pod-template-hash=5b768f7647
deployment-example-5b768f7647-j6bvs   1/1     Running   0          52s   app=nginx,pod-template-hash=5b768f7647
deployment-example-5b768f7647-ntmk7   1/1     Running   0          52s   app=nginx,pod-template-hash=5b768f7647
[root@server2 k8s]# ipvsadm -ln
##此時雖然已經有了 pod 但是并沒有加進去,沒有 svc,
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.96.0.1:443 rr
  -> 172.25.25.2:6443             Masq    1      0          0         
TCP  10.96.0.10:53 rr
  -> 10.244.0.8:53                Masq    1      0          0         
  -> 10.244.0.9:53                Masq    1      0          0         
TCP  10.96.0.10:9153 rr
  -> 10.244.0.8:9153              Masq    1      0          0         
  -> 10.244.0.9:9153              Masq    1      0          0         
UDP  10.96.0.10:53 rr
  -> 10.244.0.8:53                Masq    1      0          0         
  -> 10.244.0.9:53                Masq    1      0          0         

將指令轉為 yaml 檔案;

[root@server2 k8s]# kubectl expose deployment deployment-example --port=80 --target-port=80
service/deployment-example exposed
[root@server2 k8s]# kubectl get svc
NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
deployment-example   ClusterIP   10.105.194.76   <none>        80/TCP    8s
kubernetes           ClusterIP   10.96.0.1       <none>        443/TCP   8d
[root@server2 k8s]# kubectl describe svc deployment-example
Name:              deployment-example
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.105.194.76
IPs:               10.105.194.76
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.26:80,10.244.2.33:80,10.244.2.34:80
Session Affinity:  None
Events:            <none>

[root@server2 k8s]# kubectl get svc deployment-example -o yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2021-06-12T13:30:52Z"
  name: deployment-example
  namespace: default
  resourceVersion: "60216"
  uid: 7729b22e-4e26-4e6e-afa1-7c4e0a37e019
spec:
  clusterIP: 10.105.194.76
  clusterIPs:
  - 10.105.194.76
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}
[root@server2 k8s]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.96.0.1:443 rr
  -> 172.25.25.2:6443             Masq    1      0          0         
TCP  10.96.0.10:53 rr
  -> 10.244.0.8:53                Masq    1      0          0         
  -> 10.244.0.9:53                Masq    1      0          0         
TCP  10.96.0.10:9153 rr
  -> 10.244.0.8:9153              Masq    1      0          0         
  -> 10.244.0.9:9153              Masq    1      0          0         
TCP  10.105.194.76:80 rr
##此時查看時,會有三個pod
  -> 10.244.1.26:80               Masq    1      0          0         
  -> 10.244.2.33:80               Masq    1      0          0         
  -> 10.244.2.34:80               Masq    1      0          0         
UDP  10.96.0.10:53 rr
  -> 10.244.0.8:53                Masq    1      0          0         
  -> 10.244.0.9:53                Masq    1      0          0     

此時測驗時,會負載均衡到后端的三個 pod 上

[root@server2 k8s]# curl 10.105.194.76
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@server2 k8s]# curl 10.105.194.76/hostname.html
deployment-example-5b768f7647-j6bvs
[root@server2 k8s]# curl 10.105.194.76/hostname.html
deployment-example-5b768f7647-9wlvc
[root@server2 k8s]# curl 10.105.194.76/hostname.html
deployment-example-5b768f7647-ntmk7
[root@server2 k8s]# ipvsadm -ln
測驗之后,可以用此命令查看調度的次數

當用命令kubectl delete svc deployment-example 將服務洗掉時,此時也就在 ipvs中看不到資訊,

除了上述用指令生成 yaml檔案的方法之外,還可以直接撰寫 yaml檔案;

[root@server2 k8s]# vim svc.yaml 
[root@server2 k8s]# cat svc.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  selector: 
    app: nginx

  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

[root@server2 k8s]# kubectl apply -f svc.yaml 
service/myservice created
[root@server2 k8s]# kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   8d
myservice    ClusterIP   10.104.41.30   <none>        80/TCP    5s
[root@server2 k8s]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.96.0.1:443 rr
  -> 172.25.25.2:6443             Masq    1      0          0         
TCP  10.96.0.10:53 rr
  -> 10.244.0.8:53                Masq    1      0          0         
  -> 10.244.0.9:53                Masq    1      0          0         
TCP  10.96.0.10:9153 rr
  -> 10.244.0.8:9153              Masq    1      0          0         
  -> 10.244.0.9:9153              Masq    1      0          0         
TCP  10.104.41.30:80 rr
  -> 10.244.1.26:80               Masq    1      0          0         
  -> 10.244.2.33:80               Masq    1      0          0         
  -> 10.244.2.34:80               Masq    1      0          0         
UDP  10.96.0.10:53 rr
  -> 10.244.0.8:53                Masq    1      0          0         
  -> 10.244.0.9:53                Masq    1      0          0         

3. 創建 service:(NodePort方式)

為了從外部訪問 service 的第一種方式,用 NodePort 的方式會系結節點的埠,供外部來訪問,
以上的方式都是 ClusterIP 的方式,此時修改一下格式:

[root@server2 k8s]# vim svc.yaml 
[root@server2 k8s]# cat svc.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  selector: 
    app: nginx
  type: NodePort
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

[root@server2 k8s]# kubectl apply -f svc.yaml 
service/myservice created
[root@server2 k8s]# kubectl get svc	
##此時會將埠暴露出來,外部在訪問時需要指定埠來訪問
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        8d
myservice    NodePort    10.100.227.116   <none>        80:32204/TCP   6s

在書寫 yaml 檔案時,可以用命令來獲得幫助 kubectl explain service.spec等后面跟得資訊都可以查看幫助,


4. DNS 插件 Service

Kubernetes 提供了一個 DNS 插件 Service,
在集群內部直接用DNS記錄的方式訪問,而不需要一個VIP,

[root@server2 k8s]# yum install -y bind-utils.x86_64 
##安裝插件
[root@server2 k8s]# cat /etc/resolv.conf
nameserver 114.114.114.114
[root@server2 k8s]# cat svc.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  selector:
    app: nginx
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
[root@server2 k8s]# kubectl apply -f svc.yaml 
service/myservice created
[root@server2 k8s]#  dig -t A myservice.default.svc.cluster.local @10.96.0.10

; <<>> DiG 9.9.4-RedHat-9.9.4-72.el7 <<>> -t A myservice.default.svc.cluster.local @10.96.0.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4147
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;myservice.default.svc.cluster.local. IN	A

;; ANSWER SECTION:
myservice.default.svc.cluster.local. 30	IN A	10.108.31.117
##此時決議到的地址為 myservice上的地址
;; Query time: 0 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Sun Jun 13 21:13:34 CST 2021
;; MSG SIZE  rcvd: 115

[root@server2 k8s]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   9d
myservice    ClusterIP   10.108.31.117   <none>        80/TCP    10h
[root@server2 k8s]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.96.0.1:443 rr
  -> 172.25.25.2:6443             Masq    1      3          0         
TCP  10.96.0.10:53 rr
  -> 10.244.179.65:53             Masq    1      0          0         
  -> 10.244.179.66:53             Masq    1      0          0         
TCP  10.96.0.10:9153 rr
  -> 10.244.179.65:9153           Masq    1      0          0         
  -> 10.244.179.66:9153           Masq    1      0          0         
TCP  10.108.31.117:80 rr
  -> 10.244.1.31:80               Masq    1      0          0         
  -> 10.244.2.40:80               Masq    1      0          0         
  -> 10.244.2.41:80               Masq    1      0          0         
UDP  10.96.0.10:53 rr
  -> 10.244.179.65:53             Masq    1      0          1         
  -> 10.244.179.66:53             Masq    1      0          1  

以上創建的程序中,IP會隨著pod 而變化,但是域名并不會變化;在訪問時可以直接指定域名來訪問,此時也是負載均衡的,

[root@server2 k8s]# kubectl run demo --image=busyboxplus -it --restart=Never
If you don't see a command prompt, try pressing enter.
/ # cat /etc/resolv.conf 
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
/ # curl myservice
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
/ # curl myservice/hostname.html
deployment-example-5b768f7647-rkpgr
/ # 
/ # curl myservice/hostname.html
deployment-example-5b768f7647-czchr
/ # curl myservice/hostname.html
deployment-example-5b768f7647-brg9n
/ # curl myservice/hostname.html
deployment-example-5b768f7647-rkpgr
  • Headless Service “無頭服務”
    Headless Service不需要分配一個 VIP,而是直接以 DNS 記錄的方式決議出被代理 Pod 的IP地址,
    域名格式:$ (servicename).$(namespace).svc.cluster.local
[root@server2 k8s]# kubectl delete -f svc.yaml 
service "myservice" deleted
[root@server2 k8s]# vim svc.yaml 
[root@server2 k8s]# cat svc.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  selector:
    app: nginx
  type: ClusterIP
  clusterIP: None
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
[root@server2 k8s]# kubectl apply -f svc.yaml 
service/myservice created
[root@server2 k8s]# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   28h
myservice    ClusterIP   None         <none>        80/TCP    20s

此時看到的是沒有分配到的VIP,但是可以根據 DNS 記錄中的pod 的地址來訪問;

[root@server2 k8s]#  dig -t A myservice.default.svc.cluster.local @10.96.0.10

; <<>> DiG 9.9.4-RedHat-9.9.4-72.el7 <<>> -t A myservice.default.svc.cluster.local @10.96.0.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11968
;; flags: qr aa rd; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;myservice.default.svc.cluster.local. IN	A

;; ANSWER SECTION:
myservice.default.svc.cluster.local. 30	IN A	10.244.2.41
myservice.default.svc.cluster.local. 30	IN A	10.244.1.31
myservice.default.svc.cluster.local. 30	IN A	10.244.2.40

;; Query time: 0 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Sun Jun 13 21:24:28 CST 2021
;; MSG SIZE  rcvd: 217

[root@server2 k8s]# kubectl describe svc myservice 
Name:              myservice
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                None
IPs:               None
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.90:80,10.244.2.77:80,10.244.2.78:80
Session Affinity:  None
Events:            <none>

5. pod 滾動更新

以上無頭服務,在 pod 滾動更新之后,其 IP 的變化是隨著 pod 自動更新的;

[root@server2 k8s]# kubectl delete pod --all
pod "demo" deleted
pod "deployment-example-5b768f7647-brg9n" deleted
pod "deployment-example-5b768f7647-czchr" deleted
pod "deployment-example-5b768f7647-rkpgr" deleted
[root@server2 k8s]# kubectl get pod
NAME                                  READY   STATUS    RESTARTS   AGE
deployment-example-5b768f7647-2psc6   1/1     Running   0          21s
deployment-example-5b768f7647-cdfdk   1/1     Running   0          21s
deployment-example-5b768f7647-q76rp   1/1     Running   0          21s
[root@server2 k8s]# kubectl describe svc myservice 
Name:              myservice
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                None
IPs:               None
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.94:80,10.244.1.95:80,10.244.2.79:80
Session Affinity:  None
Events:            <none>

6. 創建 service: (LoadBalancer)

從外部訪問 Service 的第二種方式,適用于公有云上的 Kubernetes 服務,這時候,可以指定一個 LoadBalancer 型別的 Service,

[root@server2 k8s]# kubectl delete -f svc.yaml 
service "myservice" deleted
[root@server2 k8s]# vim svc.yaml 
[root@server2 k8s]# cat svc.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  selector:
    app: nginx
  type: LoadBalancer
  #clusterIP: None
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
[root@server2 k8s]# kubectl apply -f svc.yaml 
service/myservice created
[root@server2 k8s]# kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1       <none>        443/TCP        28h
myservice    LoadBalancer   10.99.186.132   <pending>     80:31894/TCP   37s

此時是在 nodeport的基礎之上,從云端來分配一個 IP;此處沒有云端時會一直處于 <pending> 的狀態,

  1. 當是云環境時會通過驅動去分配一個IP,供其訪問;
  2. 當前是裸金屬環境,那么分配IP 的動作由誰去做呢?

metallb
官網:https://metallb.universe.tf/installation/
設定ipvs模式:

[root@server2 k8s]# kubectl edit configmaps -n kube-system kube-proxy 
configmap/kube-proxy edited
     37       strictARP: true

     44     mode: "ipvs"
[root@server2 k8s]# kubectl -n kube-system get pod | grep kube-proxy | awk '{system("kubectl -n kube-system delete pod "$1"")}'
pod "kube-proxy-6f78h" deleted
pod "kube-proxy-7jvkr" deleted
pod "kube-proxy-9d5s7" deleted
##讓策略生效

部署:先下載資源清單,

[root@server2 k8s]# mkdir metallb
[root@server2 k8s]# cd metallb/
[root@server2 metallb]# wget https://raw.githubusercontent.com/metallb/metallb/v0.9.5/manifests/namespace.yaml
[root@server2 metallb]# cat namespace.yaml 
apiVersion: v1
kind: Namespace
metadata:
  name: metallb-system
  labels:
    app: metallb
[root@server2 metallb]# kubectl apply -f namespace.yaml 
namespace/metallb-system created
##創建 namespace
[root@server2 metallb]# wget https://raw.githubusercontent.com/metallb/metallb/v0.9.6/manifests/metallb.yaml

配置清單metallb.yaml 指定的鏡像需要提前下載,并將其上傳至私有倉庫;

[root@server1 ~]# docker pull metallb/speaker:v0.9.6
[root@server1 ~]# docker pull metallb/controller:v0.9.6
[root@server1 harbor]# docker tag metallb/speaker:v0.9.6 reg.westos.org/metallb/speaker:v0.9.6
[root@server1 harbor]# docker tag metallb/controller:v0.9.6 reg.westos.org/metallb/controller:v0.9.6
[root@server1 harbor]# docker push reg.westos.org/metallb/controller;
[root@server1 harbor]# docker push reg.westos.org/metallb/controller:v0.9.6 

上傳完之后,此處私有倉庫的地址和檔案中的一致,然后開始部署:

[root@server2 metallb]# kubectl apply -f metallb.yaml
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+

在第一次部署時,需要生成一個密鑰:

[root@server2 metallb]# kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"
secret/memberlist created
[root@server2 metallb]# kubectl -n metallb-system get all
NAME                              READY   STATUS    RESTARTS   AGE
pod/controller-64f86798cc-qgbsw   1/1     Running   0          2m59s
pod/speaker-f7vtr                 1/1     Running   0          2m59s
pod/speaker-jdqv4                 1/1     Running   0          2m59s
pod/speaker-t8675                 1/1     Running   0          2m59s
##在客戶端控制節點創建一個,在3個節點運行客戶端代理
NAME                     DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
daemonset.apps/speaker   3         3         3       3            3           kubernetes.io/os=linux   2m59s

NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/controller   1/1     1            1           2m59s

NAME                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/controller-64f86798cc   1         1         1       2m59s
[root@server2 metallb]# kubectl -n metallb-system get secrets 
NAME                     TYPE                                  DATA   AGE
controller-token-hk6k2   kubernetes.io/service-account-token   3      3m18s
default-token-22jtp      kubernetes.io/service-account-token   3      9m39s
memberlist               Opaque                                1      105s
speaker-token-phglk      kubernetes.io/service-account-token   3      3m18s

以上創建完成之后,編輯一個檔案:設定其分配IP的范圍,

[root@server2 metallb]# vim config.yaml
[root@server2 metallb]# cat config.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 172.25.25.100-172.25.25.200
[root@server2 metallb]# kubectl apply -f config.yaml 
configmap/config created
[root@server2 metallb]# kubectl -n metallb-system get cm
NAME               DATA   AGE
config             1      10s
kube-root-ca.crt   1      11m
[root@server2 metallb]# kubectl -n metallb-system describe cm config 
Name:         config
Namespace:    metallb-system
Labels:       <none>
Annotations:  <none>

Data
====
config:
----
address-pools:
- name: default
  protocol: layer2
  addresses:
  - 172.25.15.100-172.25.15.200

Events:  <none>

來測驗外部能否獲取VIP;

[root@server2 metallb]# cd ..
[root@server2 k8s]# vim svc.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  selector: 
    app: nginx
  #type: ClusterIP
  #type: NodePort
  #clusterIP: None
  type: LoadBalancer
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

[root@server2 k8s]# kubectl apply -f svc.yaml 
service/myservice unchanged
[root@server2 k8s]# kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1       <none>          443/TCP        29h
myservice    LoadBalancer   10.99.186.132   172.25.15.100   80:31894/TCP   29m

此時已經分配到了vip ,外部直接可以訪問:

[root@foundation15 ~]# curl 172.25.15.100
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@foundation15 ~]# curl 172.25.15.100/hostname.html
deployment-example-5b768f7647-cdfdk

7. 創建 service :(ExternalName)

從外部訪問的第三種方式叫做ExternalName,決議名稱,常用于外部控制,

[root@server2 k8s]# vim ex-svc.yaml
[root@server2 k8s]# cat ex-svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: ex-svc
spec:
  type:  ExternalName
  externalName: www.baidu.com
[root@server2 k8s]# kubectl apply -f ex-svc.yaml 
service/ex-svc created
[root@server2 k8s]# kubectl get svc
##此處沒有分配ip,用域名的方式可以訪問
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
ex-svc       ExternalName   <none>          www.baidu.com   <none>         10s
kubernetes   ClusterIP      10.96.0.1       <none>          443/TCP        29h
myservice    LoadBalancer   10.99.186.132   172.25.15.100   80:31894/TCP   33m
[root@server2 k8s]# kubectl describe svc ex-svc 
Name:              ex-svc
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          <none>
Type:              ExternalName
IP Families:       <none>
IP:                
IPs:               <none>
External Name:     www.baidu.com
Session Affinity:  None
Events:            <none>
[root@server2 k8s]# dig -t A ex-svc.default.svc.cluster.local @10.96.0.10


;; ANSWER SECTION:
ex-svc.default.svc.cluster.local. 30 IN	CNAME	www.baidu.com.
www.baidu.com.		30	IN	CNAME	www.a.shifen.com.
www.a.shifen.com.	30	IN	A	36.152.44.95
www.a.shifen.com.	30	IN	A	36.152.44.96

假設外部資源的域名發生變化:

[root@server2 k8s]# vim ex-svc.yaml 
[root@server2 k8s]# cat ex-svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: ex-svc
spec:
  type:  ExternalName
  externalName: www.westos.org
[root@server2 k8s]# kubectl apply -f ex-svc.yaml 
service/ex-svc configured
[root@server2 k8s]# kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE
ex-svc       ExternalName   <none>          www.westos.com   <none>         2m44s
kubernetes   ClusterIP      10.96.0.1       <none>           443/TCP        9d
myservice    LoadBalancer   10.99.186.132   172.25.25.100    80:31981/TCP   7m45s

[root@server2 k8s]# dig -t A ex-svc.default.svc.cluster.local @10.96.0.10

;; ANSWER SECTION:
ex-svc.default.svc.cluster.local. 30 IN	CNAME	www.westos.org.
www.westos.org.		30	IN	CNAME	applkdmhnt09730.pc-cname.xiaoe-tech.com.
applkdmhnt09730.pc-cname.xiaoe-tech.com. 30 IN A 118.25.119.100

可以發現即使外部域名發生變化,不變的是svc,集群內部可以將地址設定為 svc 的地址;將其做個映射就可以,不用做太大的變更,

以上的方式是分配地址,service 允許為其分配一個公有IP,

8. ingress

Kubernetes 里的 Ingress 服務是一種全域的、為了代理不同后端 Service 而設定的負載均衡服務,

Ingress由兩部分組成:Ingress controller 和 Ingress 服務,

Ingress Controller 會根據你定義的 Ingress 物件,提供對應的代理能力,業界常用的各種反向代理專案,比如 Nginx、HAProxy、Envoy、Traefik 等,都已經為Kubernetes 專門維護了對應的 Ingress Controller,

在這里插入圖片描述

8.1 ingress的配置

官網:https://kubernetes.github.io/ingress-nginx/

應用 ingress controller 定義檔案:

[root@server2 k8s]# mkdir ingress
[root@server2 k8s]# cd ingress/
[root@server2 ingress]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.47.0/deploy/static/provider/baremetal/deploy.yaml

根據檔案內容需要下載兩個鏡像;此處用直接下載好經過打包的鏡像上傳至私有倉庫,

[root@server1 ~]# docker load  -i  ingress-nginx-v0.46.0.tar
[root@server1 ~]# docker push reg.westos.org/ingress-nginx/controller:v0.46.0 
[root@server1 ~]# docker push  reg.westos.org/ingress-nginx/kube-webhook-certgen:v1.5.1 

然后修改檔案中的鏡像指向,并部署:

[root@server2 ingress]# vim deploy.yaml 

324           image: ingress-nginx/controller:v0.46.0

589           image: ingress-nginx/kube-webhook-certgen:v1.5.1

635           image: ingress-nginx/kube-webhook-certgen:v1.5.1
[root@server2 ingress]# kubectl apply -f deploy.yaml 

部署好 ingress之后,查看其相關一些資訊;可以看到有 NodePort是 供集外部可以訪問 和ClusterIP是集群內部訪問;

[root@server2 ingress]# kubectl -n ingress-nginx get all
NAME                                            READY   STATUS              RESTARTS   AGE
pod/ingress-nginx-admission-create-n49ww        0/1     Completed           0          10s
pod/ingress-nginx-admission-patch-mqmxq         0/1     Completed           1          10s
pod/ingress-nginx-controller-56c7fc94cb-dzvft   0/1     ContainerCreating   0          10s

NAME                                         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             NodePort    10.103.186.206   <none>        80:32594/TCP,443:32643/TCP   10s
service/ingress-nginx-controller-admission   ClusterIP   10.103.30.139    <none>        443/TCP                      10s

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/ingress-nginx-controller   0/1     1            0           10s

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/ingress-nginx-controller-56c7fc94cb   1         1         0       10s

NAME                                       COMPLETIONS   DURATION   AGE
job.batch/ingress-nginx-admission-create   1/1           4s         10s
job.batch/ingress-nginx-admission-patch    1/1           5s         10s
[root@server2 ingress]# kubectl -n ingress-nginx get pod
NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-n49ww        0/1     Completed   0          62s
ingress-nginx-admission-patch-mqmxq         0/1     Completed   1          62s
ingress-nginx-controller-56c7fc94cb-dzvft   1/1     Running     0          62s
[root@server2 ingress]# kubectl -n ingress-nginx describe svc ingress-nginx-controller
Name:                     ingress-nginx-controller
Namespace:                ingress-nginx
Labels:                   app.kubernetes.io/component=controller
                          app.kubernetes.io/instance=ingress-nginx
                          app.kubernetes.io/managed-by=Helm
                          app.kubernetes.io/name=ingress-nginx
                          app.kubernetes.io/version=0.47.0
                          helm.sh/chart=ingress-nginx-3.33.0
Annotations:              <none>
Selector:                 app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.103.186.206
IPs:                      10.103.186.206
Port:                     http  80/TCP
TargetPort:               http/TCP
NodePort:                 http  32594/TCP
Endpoints:                10.244.1.35:80
Port:                     https  443/TCP
TargetPort:               https/TCP
NodePort:                 https  32643/TCP
Endpoints:                10.244.1.35:443
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>
[root@server2 ingress]# kubectl -n ingress-nginx get svc
NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.103.186.206   <none>        80:32594/TCP,443:32643/TCP   107s
ingress-nginx-controller-admission   ClusterIP   10.103.30.139    <none>        443/TCP                      107s
[root@server2 ingress]# curl 10.103.186.206
##集群內此時并不能訪問到資訊,是因為還沒有定義 ingress
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

為了可以訪問,需要有可用的svc

[root@server2 k8s]# vim svc.yaml 
[root@server2 k8s]# cat svc.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  selector:
    app: nginx
  #type: LoadBalancer
  type: ClusterIP
  #clusterIP: None
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
[root@server2 k8s]# kubectl apply -f svc.yaml 
[root@server2 k8s]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   9d
myservice    ClusterIP   10.97.144.118   <none>        80/TCP    13s
[root@server2 k8s]# kubectl describe svc myservice 
##此時三個 pod 已經就緒
Name:              myservice

Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.94:80,10.244.1.95:80,10.244.2.79:80
Session Affinity:  None
Events:            <none>
[root@server2 k8s]# kubectl get pod
NAME                                  READY   STATUS    RESTARTS   AGE
deployment-example-5b768f7647-2psc6   1/1     Running   0          129m
deployment-example-5b768f7647-cdfdk   1/1     Running   0          129m
deployment-example-5b768f7647-q76rp   1/1     Running   0          129m

將后端的三個 pod 暴露出去,供外部可以訪問;當前的 ClusterIP不能讓外部訪問,此時需要用ingress來訪問;

[root@server2 ingress]# vim ingress.yaml
[root@server2 ingress]# cat ingress.yaml 
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-www1
spec:
  rules:
  - host: www1.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: myservice
          servicePort: 80
[root@server2 ingress]# kubectl apply -f ingress.yaml 
[root@server2 ingress]# kubectl get ingress
NAME           CLASS    HOSTS             ADDRESS   PORTS   AGE
ingress-www1   <none>   www1.westos.org             80      13s
[root@server2 ingress]# kubectl describe ingress ingress-www1 
Name:             ingress-www1
Namespace:        default
Address:          
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host             Path  Backends
  ----             ----  --------
  www1.westos.org  
                   /   myservice:80 (10.244.1.94:80,10.244.1.95:80,10.244.2.79:80)
Annotations:       <none>
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  Sync    26s   nginx-ingress-controller  Scheduled for sync

此時在訪問 www1.westos.org 時,會調度到后端的 pod 上;但是此時對于域名的訪問并不能被識別,需要做決議;將其決議到 nginx 的控制器上以NodePort來識別,訪問時必須加上埠號;

[root@westos ~]# tail -n 1 /etc/hosts
172.25.25.2   server2 www1.westos.org
[root@westos ~]# curl www1.westos.org
curl: (7) Failed to connect to www1.westos.org port 80: Connection refused
[root@westos ~]# curl www1.westos.org:32594
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@westos ~]# curl www1.westos.org:32594/hostname.html
deployment-example-5b768f7647-t769f
[root@westos ~]# curl www1.westos.org:32594/hostname.html
deployment-example-5b768f7647-rlvlw
[root@westos ~]# curl www1.westos.org:32594/hostname.html
deployment-example-5b768f7647-jv7kf

除了NodePort形式之外,還可以用LoadBalancer來分配外部 IP;

[root@server2 ingress]# kubectl -n ingress-nginx edit svc

     49     type: LoadBalancer
     50   status:
     51     loadBalancer: {}
service/ingress-nginx-controller edited
service/ingress-nginx-controller-admission skipped
[root@server2 ingress]# kubectl -n ingress-nginx get svc
NAME                                 TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.103.186.206   172.25.25.100   80:32594/TCP,443:32643/TCP   91m
ingress-nginx-controller-admission   ClusterIP      10.103.30.139    <none>          443/TCP  

可以看到分配到了一個外部 IP;此時在修改決議檔案,不能再決議到之前的 ip,當之前的主機掛掉之后,就不能訪問;但是指向分配的IP,便不存在該問題,訪問時不用加埠;

[root@westos ~]# vim /etc/hosts
[root@westos ~]# tail -n1 /etc/hosts
172.25.25.100   www1.westos.org
[root@westos ~]# ping -c1 -w1 www1.westos.org
PING www1.westos.org (172.25.25.100) 56(84) bytes of data.
64 bytes from www1.westos.org (172.25.25.100): icmp_seq=1 ttl=64 time=0.542 ms

--- www1.westos.org ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.542/0.542/0.542/0.000 ms
[root@westos ~]# curl www1.westos.org
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@westos ~]# curl www1.westos.org/hostname.html
deployment-example-5b768f7647-t769f
[root@westos ~]# curl www1.westos.org/hostname.html
deployment-example-5b768f7647-jv7kf
[root@westos ~]# curl www1.westos.org/hostname.html
deployment-example-5b768f7647-t769f

再添加來觀察效果:

[root@server2 ingress]# cp ../svc.yaml .
[root@server2 ingress]# vim svc.yaml 
[root@server2 ingress]# cat svc.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  selector:
    app: nginx
  #type: LoadBalancer
  type: ClusterIP
  #clusterIP: None
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    app: myapp
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
[root@server2 ingress]# kubectl apply -f svc.yaml 
service/myservice unchanged
service/nginx-svc created
[root@server2 ingress]# kubectl describe svc nginx-svc 
##此時沒有Endpoints控制器
Name:              nginx-svc
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=myapp
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.108.174.65
IPs:               10.108.174.65
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         <none>
Session Affinity:  None
Events:            <none>
[root@server2 ingress]# kubectl get pod --show-labels
##也沒有myapp的標簽
NAME                                  READY   STATUS    RESTARTS   AGE    LABELS
deployment-example-5b768f7647-2psc6   1/1     Running   0          144m   app=nginx,pod-template-hash=5b768f7647
deployment-example-5b768f7647-cdfdk   1/1     Running   0          144m   app=nginx,pod-template-hash=5b768f7647
deployment-example-5b768f7647-q76rp   1/1     Running   0          144m   app=nginx,pod-template-hash=5b768f7647

為其添加控制器和標簽:

[root@server2 ingress]# cp ../deployment.yaml .
[root@server2 ingress]# cat deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-www2
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v2
        livenessProbe:
          tcpSocket:
            port: 80
          initialDelaySeconds: 2
          periodSeconds: 3
          timeoutSeconds: 1
        readinessProbe:
          httpGet:
            path: /hostname.html
            port: 80
          initialDelaySeconds: 1
          periodSeconds: 3
          timeoutSeconds: 1
[root@server2 ingress]# kubectl apply -f deployment.yaml 
[root@server2 ingress]# kubectl get pod --show-labels 
##此時查看時就有了標簽,也有了pod 資訊
[root@server2 ingress]# kubectl describe svc nginx-svc 
Name:              nginx-svc
Namespace:         default

Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.97:80,10.244.1.98:80,10.244.2.83:80
Session Affinity:  None
Events:            <none>

此時編輯 ingress 添加一個頁面;此時是動態更新;

[root@server2 ingress]# vim ingress.yaml 
[root@server2 ingress]# cat ingress.yaml 
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-www1
spec:
  rules:
  - host: www1.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: myservice
          servicePort: 80
  - host: www2.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-svc
          servicePort: 80
[root@server2 ingress]# kubectl apply -f ingress.yaml 
[root@server2 ingress]# kubectl get ingress
NAME           CLASS    HOSTS                             ADDRESS         PORTS   AGE
ingress-www1   <none>   www1.westos.org,www2.westos.org   172.25.15.100   80      18m
[root@server2 ingress]# kubectl describe ingress ingress-www1 
Name:             ingress-www1
Namespace:        default
Address:          172.25.15.100
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host             Path  Backends
  ----             ----  --------
  www1.westos.org  
                   /   myservice:80 (10.244.1.94:80,10.244.1.95:80,10.244.2.79:80)
  www2.westos.org  
                   /   nginx-svc:80 (10.244.1.97:80,10.244.1.98:80,10.244.2.83:80)
Annotations:       <none>
Events:
  Type    Reason  Age                From                      Message
  ----    ------  ----               ----                      -------
  Normal  Sync    31s (x3 over 18m)  nginx-ingress-controller  Scheduled for sync

8.2 Ingress TLS 配置

要做加密之前首先來生成key:

[root@server2 ingress]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
Generating a 2048 bit RSA private key
..........................+++
...+++
writing new private key to 'tls.key'
-----
[root@server2 ingress]#  kubectl create secret tls tls-secret --key tls.key --cert tls.crt
secret/tls-secret created
##將生成的證書和key 存起來
[root@server2 ingress]# kubectl get secrets 
NAME                  TYPE                                  DATA   AGE
default-token-z4gbr   kubernetes.io/service-account-token   3      9d
tls-secret            kubernetes.io/tls                     2      9s

對網站www1.westos.org 進行加密:

[root@server2 ingress]# vim ingress.yaml 
[root@server2 ingress]# cat ingress.yaml 
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-www1
spec:
  tls:
  - hosts:
    - www1.westos.org
    secretName: tls-secret
  rules:
  - host: www1.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: myservice
          servicePort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-www1
spec:
  rules:
  - host: www2.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-svc
          servicePort: 80
[root@server2 ingress]# kubectl apply -f ingress.yaml 
[root@server2 ingress]# kubectl describe ingress
Name:             ingress-www1
Namespace:        default
Address:          172.25.25.3
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
  tls-secret terminates www1.westos.org
Rules:
  Host             Path  Backends
  ----             ----  --------
  www1.westos.org  
                   /   myservice:80 (10.244.1.34:80,10.244.2.42:80,10.244.2.43:80)
Annotations:       <none>
Events:
  Type    Reason  Age                From                      Message
  ----    ------  ----               ----                      -------
  Normal  Sync    13s (x2 over 13s)  nginx-ingress-controller  Scheduled for sync


Name:             ingress-www2
Namespace:        default
Address:          172.25.25.3
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host             Path  Backends
  ----             ----  --------
  www2.westos.org  
                   /   nginx-svc:80 (10.244.1.38:80,10.244.2.46:80,10.244.2.47:80)
Annotations:       <none>
Events:
  Type    Reason  Age                From                      Message
  ----    ------  ----               ----                      -------
  Normal  Sync    13s (x2 over 13s)  nginx-ingress-controller  Scheduled for sync
[root@server2 ingress]# kubectl get ingress
NAME           CLASS    HOSTS             ADDRESS       PORTS     AGE
ingress-www1   <none>   www1.westos.org   172.25.25.3   80, 443   47s
ingress-www2   <none>   www2.westos.org   172.25.25.3   80        47s

測驗:由于此時開啟了443,便會重定向到443,如果沒有開啟由于其是加密的便不能訪問;www2沒有做加密,直接回傳值,

[root@westos ~]# curl -I www1.westos.org
HTTP/1.1 308 Permanent Redirect
Date: Mon, 14 Jun 2021 03:32:05 GMT
Content-Type: text/html
Content-Length: 164
Connection: keep-alive
Location: https://www1.westos.org
[root@westos ~]# curl -I www2.westos.org
HTTP/1.1 200 OK
Date: Mon, 14 Jun 2021 03:55:54 GMT
Content-Type: text/html
Content-Length: 65
Connection: keep-alive
Last-Modified: Sun, 25 Feb 2018 06:04:32 GMT
ETag: "5a9251f0-41"
Accept-Ranges: bytes

8.3 Ingress 認證配置

[root@server2 ingress]# yum install -y httpd-tools
[root@server2 ingress]# htpasswd -c auth admin
New password: 
Re-type new password: 
Adding password for user admin
[root@server2 ingress]# htpasswd auth zxk
New password: 
Re-type new password: 
Adding password for user zxk
[root@server2 ingress]# cat auth 
admin:$apr1$NAtpYX/0$bqGqb.8Vo7DqDCoILmUpv1
zxk:$apr1$zuNeydPF$nbL1qU65BmtgMMp9DGeAg0
[root@server2 ingress]# kubectl create secret generic basic-auth --from-file=auth
secret/basic-auth created
[root@server2 ingress]# kubectl get secrets 
NAME                  TYPE                                  DATA   AGE
basic-auth            Opaque                                1      4m13s
default-token-z4gbr   kubernetes.io/service-account-token   3      10d
tls-secret            kubernetes.io/tls                     2      42m

編輯檔案來器用認證:

[root@server2 ingress]# cat ingress.yaml 
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-www1
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - westps'
spec:
  tls:
  - hosts:
    - www1.westos.org
    secretName: tls-secret
  rules:
  - host: www1.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: myservice
          servicePort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-www2
spec:
  rules:
  - host: www2.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-svc
          servicePort: 80
[root@server2 ingress]# kubectl apply -f ingress.yaml 

在這里插入圖片描述

8.4 Ingress地址重寫

  1. 當訪問www2.westos.org時直接改寫為www2.westos.org/hostname.html
[root@server2 ingress]# cat ingress.yaml 
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-www1
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - westps'
spec:
  tls:
  - hosts:
    - www1.westos.org
    secretName: tls-secret
  rules:
  - host: www1.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: myservice
          servicePort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-www2
  annotations:		##當訪問www2.westos.org時直接改寫為www2.westos.org/hostname.html
    nginx.ingress.kubernetes.io/app-root: /hostname.html
spec:
  rules:
  - host: www2.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-svc
          servicePort: 80
[root@server2 ingress]# kubectl apply -f ingress.yaml 
Warning: networking.k8s.io/v1beta1 Ingress is deprecated in v1.19+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
ingress.networking.k8s.io/ingress-www1 configured
ingress.networking.k8s.io/ingress-www2 configured
  1. 路徑重寫
[root@server2 ingress]# vim ingress-rewrite.yaml
[root@server2 ingress]# cat ingress-rewrite.yaml 
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: ingress-rewrite
  namespace: default
spec:
  rules:
  - host: rewrite.westos.org
    http:
      paths:
      - backend:
          serviceName: nginx-svc
          servicePort: 80
        path: /westos(/|$)(.*)
[root@server2 ingress]# kubectl apply -f ingress.yaml 
Warning: networking.k8s.io/v1beta1 Ingress is deprecated in v1.19+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
ingress.networking.k8s.io/ingress-www1 configured
ingress.networking.k8s.io/ingress-www2 configured
[root@server2 ingress]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   10d
myservice    ClusterIP   10.97.144.118   <none>        80/TCP    136m
nginx-svc    ClusterIP   10.108.174.65   <none>        80/TCP    85m

外部訪問策略是,先來訪問 ingress 中的 svc開啟的pod 去 調度后端的 svc

測驗:

[root@westos ~]# curl -I rewrite.westos.org/westos
HTTP/1.1 200 OK
Date: Mon, 14 Jun 2021 04:38:52 GMT
Content-Type: text/html
Content-Length: 65
Connection: keep-alive
Last-Modified: Sun, 25 Feb 2018 06:04:32 GMT
ETag: "5a9251f0-41"
Accept-Ranges: bytes

[root@westos ~]# curl -I rewrite.westos.org/westos/hostname.html
HTTP/1.1 200 OK
Date: Mon, 14 Jun 2021 04:39:03 GMT
Content-Type: text/html
Content-Length: 32
Connection: keep-alive
Last-Modified: Mon, 14 Jun 2021 03:11:07 GMT
ETag: "60c6c8cb-20"
Accept-Ranges: bytes

[root@westos ~]# curl -I rewrite.westos.org/westos/test.html
HTTP/1.1 404 Not Found
Date: Mon, 14 Jun 2021 04:39:11 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
[root@westos ~]# curl  rewrite.westos.org/westos/
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@westos ~]# curl  rewrite.westos.org/westos/hostname.html
deployment-www2-6bb947d8b-tnlhf
[root@westos ~]# curl  rewrite.westos.org/westos/hostname.html
deployment-www2-6bb947d8b-9cbfp

常用的一些引數含義:
在這里插入圖片描述

9. 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)

9.1 flannel 網路

  1. 通信結構
    前面用到的都是 flannel,Flannel vxlan 模式跨主機通信原理:

在這里插入圖片描述

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

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

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

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

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

  • 通信原理
    當容器發送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網橋,最后到達目標容器,

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

配置flannel:

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

     30       "Backend": {
     31         "Type": "host-gw"
     32       }
configmap/kube-flannel-cfg edited
[root@server2 ~]# kubectl -n kube-system get pod | grep kube-flannel | awk '{system("kubectl -n kube-system delete pod "$1"")}'
[root@server2 ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.25.25.250   0.0.0.0         UG    0      0        0 eth0
10.244.0.0      0.0.0.0         255.255.255.0   U     0      0        0 cni0
10.244.1.0      172.25.25.3     255.255.255.0   UG    0      0        0 eth0
10.244.2.0      172.25.25.4     255.255.255.0   UG    0      0        0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
172.25.25.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0

當訪問本地網路時直接走cni,1網段走eth0的172.25.25.3; 2 網段直接走eth0到172.25.25.4
在所有結點上會生成主機網關;此模式的前提是所有節點在一個 vlan中,

修改配置資訊:

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

     27   net-conf.json: |
     28     {
     29       "Network": "10.244.0.0/16",
     30       "Backend": {
     31         "Type": "vxlan"
     32         "Directrouting": true
     33       }

表示再一個網段中使用的是 host-gw的模式,不在一個網段使用的是vxlan

9.2 calico網路插件

官網:https://docs.projectcalico.org/getting-started/kubernetes/self-managed-onprem/onpremises

  • calico簡介:
    flannel實作的是網路通信,calico的特性是在pod之間的隔離,
    通過BGP路由,但大規模端點的拓撲計算和收斂往往需要一定的時間和計算資源,
    純三層的轉發,中間沒有任何的NAT和overlay,轉發效率最好,
    Calico 僅依賴三層路由可達,Calico 較少的依賴性使它能適配所有 VM、Container、白盒或者混合環境場景,

安裝calico:在安裝之前先清理之前插件的資訊,避免兩個之間沖突;

[root@server2 ~]# kubectl delete -f kube-flannel.yml 
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
podsecuritypolicy.policy "psp.flannel.unprivileged" deleted
clusterrole.rbac.authorization.k8s.io "flannel" deleted
clusterrolebinding.rbac.authorization.k8s.io "flannel" deleted
serviceaccount "flannel" deleted
configmap "kube-flannel-cfg" deleted
daemonset.apps "kube-flannel-ds" deleted
[root@server2 ~]# kubectl -n kube-system get pod
NAME                              READY   STATUS    RESTARTS   AGE
coredns-85ffb569d4-85kp7          1/1     Running   4          9d
coredns-85ffb569d4-bd579          1/1     Running   4          9d
etcd-server2                      1/1     Running   4          9d
kube-apiserver-server2            1/1     Running   4          9d
kube-controller-manager-server2   1/1     Running   4          9d
kube-proxy-6f78h                  1/1     Running   1          17h
kube-proxy-7jvkr                  1/1     Running   1          17h
kube-proxy-9d5s7                  1/1     Running   1          17h
kube-scheduler-server2            1/1     Running   4          9d
##在所有節點做個清理的動作;
[root@server2 ~]# cd /etc/cni/net.d/
[root@server2 net.d]# ls
10-flannel.conflist
[root@server2 net.d]# mv 10-flannel.conflist  /mnt/

用命令 arp -an 查看主機的 mac地址.

  1. 部署 calico 插件
    使用 calico插件:
[root@server2 ~]# mkdir calico/
[root@server2 calico]# wget https://docs.projectcalico.org/manifests/calico.yaml
[root@server2 calico]# vim calico.yaml 

根據檔案內容,來下載所需的鏡像放入私有軟體倉庫中;

[root@server1 ~]# docker pull docker.io/calico/cni:v3.19.1
[root@server1 ~]# docker pull docker.io/calico/pod2daemon-flexvol:v3.19.1
[root@server1 ~]# docker pull docker.io/calico/node:v3.19.1
[root@server1 ~]# docker pull docker.io/calico/kube-controllers:v3.19.1
[root@server1 ~]# docker images | grep calico
calico/node                                  v3.19.1                          c4d75af7e098        3 weeks ago         168MB
calico/pod2daemon-flexvol                    v3.19.1                          5660150975fb        3 weeks ago         21.7MB
calico/cni                                   v3.19.1                          5749e8b276f9        3 weeks ago         146MB
calico/kube-controllers                      v3.19.1                          5d3d5ddc8605        3 weeks ago         60.6MB
[root@server1 ~]# docker images | grep calico | awk '{system("docker tag "$1":"$2" reg.westos.org/"$1":"$2"")}'
##修該標簽
[root@server1 ~]# docker images | grep reg.westos.org\/calico | awk '{system("docker push "$1":"$2"")}'
##上傳

然后編輯檔案將鏡像路徑更改過來,然后在修改內容,
IPIP作業模式:適用于互相訪問的pod不在同一個網段中,跨網段訪問的場景,
BGP作業模式:適用于互相訪問的pod在同一個網段,適用于大型網路,

[root@server2 calico]# vim calico.yaml 

3657             - name: CALICO_IPV4POOL_IPIP
3658               value: "off"

3683             - name: CALICO_IPV4POOL_CIDR
3684               value: "10.244.0.0/16"

此時在應用清單檔案之后,會看到calico的插件資訊;

[root@server2 calico]# kubectl apply -f calico.yaml 
[root@server2 calico]# kubectl get pod -n kube-system 
NAME                                      READY   STATUS    RESTARTS   AGE
calico-kube-controllers-784b4f4c9-c9w6c   1/1     Running   0          41s
calico-node-4rn49                         1/1     Running   0          41s
calico-node-6nmvk                         1/1     Running   0          41s
calico-node-9st7d                         1/1     Running   0          41s
coredns-85ffb569d4-85kp7                  1/1     Running   4          9d
coredns-85ffb569d4-bd579                  1/1     Running   4          9d
etcd-server2                              1/1     Running   4          9d
kube-apiserver-server2                    1/1     Running   4          9d
kube-controller-manager-server2           1/1     Running   4          9d
kube-proxy-6f78h                          1/1     Running   1          17h
kube-proxy-7jvkr                          1/1     Running   1          17h
kube-proxy-9d5s7                          1/1     Running   1          17h
kube-scheduler-server2                    1/1     Running   4          9d
[root@server2 calico]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.25.25.250   0.0.0.0         UG    0      0        0 eth0
10.244.0.0      0.0.0.0         255.255.255.0   U     0      0        0 cni0
10.244.1.0      172.25.25.3     255.255.255.255 UGH   0      0        0 eth0
10.244.1.0      10.244.1.0      255.255.255.0   UG    0      0        0 flannel.1
10.244.2.0      172.25.25.4     255.255.255.255 UGH   0      0        0 eth0
10.244.2.0      10.244.2.0      255.255.255.0   UG    0      0        0 flannel.1
169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
172.25.25.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0
  1. calico 網路架構

Felix:監聽ECTD中心的存盤獲取事件,用戶創建pod后,Felix負責將其網卡、IP、MAC都設定好,然后在內核的路由表里面寫一條,注明這個IP應該到這張網卡,同樣如果用戶制定了隔離策略,Felix同樣會將該策略創建到ACL中,以實作隔離,

BIRD:一個標準的路由程式,它會從內核里面獲取哪一些IP的路由發生了變化,然后通過標準BGP的路由協議擴散到整個其他的宿主機上,讓外界都知道這個IP在這里,路由的時候到這里來,

在這里插入圖片描述

  1. 網路策略

NetworkPolicy策略模型:控制某個 namespace 下的 pod 網路出入站規則;
官網:https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/

  1. 限制訪問指定服務
[root@server2 ingress]# vim ingress.yaml 
##洗掉里面的認策略,用于測驗
[root@server2 ingress]# kubectl apply -f ingress.yaml 

[root@server2 k8s]# vim deployment.yaml 
[root@server2 k8s]# cat deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-example
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: myapp:v1
[root@server2 k8s]# kubectl apply -f deployment.yaml 
deployment.apps/deployment-example created
[root@server2 k8s]# kubectl get pod --show-labels 
NAME                                  READY   STATUS    RESTARTS   AGE     LABELS
demo                                  1/1     Running   1          7m27s   run=demo
deployment-example-6456d7c676-4d52s   1/1     Running   0          20s     app=nginx,pod-template-hash=6456d7c676
deployment-example-6456d7c676-b8wcl   1/1     Running   0          20s     app=nginx,pod-template-hash=6456d7c676
deployment-example-6456d7c676-bf67v   1/1     Running   0          20s     app=nginx,pod-template-hash=6456d7c676
[root@server2 k8s]# kubectl get pod -o wide
NAME                                  READY   STATUS    RESTARTS   AGE     IP               NODE      NOMINATED NODE   READINESS GATES
demo                                  1/1     Running   1          7m59s   10.244.22.0      server4   <none>           <none>
deployment-example-6456d7c676-4d52s   1/1     Running   0          52s     10.244.22.2      server4   <none>           <none>
deployment-example-6456d7c676-b8wcl   1/1     Running   0          52s     10.244.141.192   server3   <none>           <none>
deployment-example-6456d7c676-bf67v   1/1     Running   0          52s     10.244.22.1      server4   <none>           <none>

注:此處不能用之前flunnel創建的pod 來測驗.

[root@server2 calico]# vim policy.yaml 
[root@server2 calico]# cat policy.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-nginx
spec:
  podSelector:
    matchLabels:
      app: nginx
[root@server2 calico]# kubectl apply -f policy.yaml 
networkpolicy.networking.k8s.io/deny-nginx created
[root@server2 calico]# kubectl get networkpolicies.
NAME         POD-SELECTOR   AGE
deny-nginx   app=nginx      3m24s
[root@server2 calico]# kubectl describe networkpolicies. deny-nginx 
Name:         deny-nginx
Namespace:    default
Created on:   2021-06-14 15:44:05 +0800 CST
Labels:       <none>
Annotations:  <none>
Spec:
  PodSelector:     app=nginx
  Allowing ingress traffic:
    <none> (Selected pods are isolated for ingress connectivity)
  Not affecting egress traffic
  Policy Types: Ingress

此時在測驗時標簽為nginx的被限制;

[root@server2 calico]# curl 10.244.22.0
^C
[root@server2 calico]# 
[root@server2 calico]# kubectl run web --image=nginx
pod/web created
[root@server2 calico]# kubectl get pod --show-labels 
NAME                                  READY   STATUS    RESTARTS   AGE    LABELS
deployment-example-6456d7c676-4d52s   1/1     Running   0          6m5s   app=nginx,pod-template-hash=6456d7c676
deployment-example-6456d7c676-b8wcl   1/1     Running   0          6m5s   app=nginx,pod-template-hash=6456d7c676
deployment-example-6456d7c676-bf67v   1/1     Running   0          6m5s   app=nginx,pod-template-hash=6456d7c676
web                                   1/1     Running   0          11s    run=web
[root@server2 calico]# kubectl get pod -o wide
NAME                                  READY   STATUS    RESTARTS   AGE     IP               NODE      NOMINATED NODE   READINESS GATES
deployment-example-6456d7c676-4d52s   1/1     Running   0          6m27s   10.244.22.2      server4   <none>           <none>
deployment-example-6456d7c676-b8wcl   1/1     Running   0          6m27s   10.244.141.192   server3   <none>           <none>
deployment-example-6456d7c676-bf67v   1/1     Running   0          6m27s   10.244.22.1      server4   <none>           <none>
web                                   1/1     Running   0          33s     10.244.22.3      server4   <none>           <none>
[root@server2 calico]# curl 10.244.22.3
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
  1. 允許指定pod訪問服務:
[root@server2 calico]# vim policy.yaml 
[root@server2 calico]# cat policy.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-nginx
spec:
  podSelector:
    matchLabels:
      app: nginx
---
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: access-demo
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:
  - from:
      - podSelector:
          matchLabels:
            run: demo
[root@server2 calico]# kubectl apply -f policy.yaml 
networkpolicy.networking.k8s.io/deny-nginx unchanged
networkpolicy.networking.k8s.io/access-demo created
[root@server2 calico]# curl 10.244.141.192
^C
[root@server2 calico]# kubectl run demo --image=busyboxplus -it
If you don't see a command prompt, try pressing enter.
/ # curl 10.244.141.192
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
/ # 

當前只有run: demo才能訪問 nginx 服務,其他默認還是被拒絕訪問,

  1. 禁止 namespace 中所有 Pod 之間的相互訪問
[root@server2 calico]# cat policy.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-nginx
spec:
  podSelector:
    matchLabels:
      app: nginx
---
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: access-demo
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:
  - from:
      - podSelector:
          matchLabels:
            run: demo

---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: default
spec:
  podSelector: {}
[root@server2 calico]# kubectl apply -f policy.yaml 
networkpolicy.networking.k8s.io/deny-nginx unchanged
networkpolicy.networking.k8s.io/access-demo unchanged
networkpolicy.networking.k8s.io/default-deny created
[root@server2 calico]# kubectl get networkpolicies.
NAME           POD-SELECTOR   AGE
access-demo    app=nginx      5m19s
default-deny   <none>         16s
deny-nginx     app=nginx      13m
[root@server2 calico]# kubectl create namespace demo
namespace/demo created
[root@server2 calico]# kubectl get ns
NAME              STATUS   AGE
default           Active   10d
demo              Active   6s
ingress-nginx     Active   6h50m
kube-node-lease   Active   10d
kube-public       Active   10d
kube-system       Active   10d
metallb-system    Active   18h
[root@server2 calico]# kubectl run demo --image=busyboxplus -it -n demo
If you don't see a command prompt, try pressing enter.
/ # curl 10.244.141.192
^C
/ # 10.244.22.3

[root@server2 calico]# kubectl delete -f policy.yaml 
networkpolicy.networking.k8s.io "deny-nginx" deleted
networkpolicy.networking.k8s.io "access-demo" deleted
networkpolicy.networking.k8s.io "default-deny" deleted

[root@server2 calico]# kubectl -n demo attach demo -it
If you don't see a command prompt, try pressing enter.
/ # curl 10.244.22.3
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

  1. 禁止其他 namespace 訪問服務
    策略之間可能會有干擾,刪掉之前的策略在來做實驗
[root@server2 calico]# kubectl delete -f policy.yaml 
networkpolicy.networking.k8s.io "deny-nginx" deleted
networkpolicy.networking.k8s.io "access-demo" deleted
networkpolicy.networking.k8s.io "default-deny" deleted
[root@server2 calico]# vim policy2.yaml 
[root@server2 calico]# cat policy2.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: deny-namespace
spec:
  podSelector:
    matchLabels:
  ingress:
  - from:
    - podSelector: {}
[root@server2 calico]# kubectl apply -f policy2.yaml 
networkpolicy.networking.k8s.io/deny-namespace created
[root@server2 calico]# kubectl -n demo attach demo -it
If you don't see a command prompt, try pressing enter.

此時不能訪問,

  1. 只允許指定namespace訪問服務
[root@server2 calico]# vim policy2.yaml
[root@server2 calico]# cat policy2.yaml 
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: deny-namespace
spec:
  podSelector:
    matchLabels:
  ingress:
  - from:
    - podSelector: {}

---
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: access-namespace
spec:
  podSelector:
    matchLabels:
      run: web
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          role: prod

[root@server2 calico]# kubectl label namespaces demo role=prod
namespace/demo labeled

[root@server2 calico]# kubectl apply -f policy2.yaml 
networkpolicy.networking.k8s.io/deny-namespace configured
networkpolicy.networking.k8s.io/access-namespace created

[root@server2 calico]# kubectl get pod -o wide
NAME                                  READY   STATUS    RESTARTS   AGE   IP               NODE      NOMINATED NODE   READINESS GATES
deployment-example-6456d7c676-4d52s   1/1     Running   0          39m   10.244.22.2      server4   <none>           <none>
deployment-example-6456d7c676-b8wcl   1/1     Running   0          39m   10.244.141.192   server3   <none>           <none>
deployment-example-6456d7c676-bf67v   1/1     Running   0          39m   10.244.22.1      server4   <none>           <none>
web                                   1/1     Running   0          33m   10.244.22.3      server4   <none>           <none>
[root@server2 calico]# kubectl get pod --show-labels 
NAME                                  READY   STATUS    RESTARTS   AGE   LABELS
deployment-example-6456d7c676-4d52s   1/1     Running   0          39m   app=nginx,pod-template-hash=6456d7c676
deployment-example-6456d7c676-b8wcl   1/1     Running   0          39m   app=nginx,pod-template-hash=6456d7c676
deployment-example-6456d7c676-bf67v   1/1     Running   0          39m   app=nginx,pod-template-hash=6456d7c676
web                                   1/1     Running   0          33m   run=web

[root@server2 calico]# kubectl -n demo attach demo -it
If you don't see a command prompt, try pressing enter.
/ # curl 10.244.22.2
^C
/ # curl 10.244.22.3
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
/ # 
  1. 允許外網訪問服務
[root@server2 calico]# cat policy2.yaml 
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: deny-namespace
spec:
  podSelector:
    matchLabels:
  ingress:
  - from:
    - podSelector: {}

---
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: access-namespace
spec:
  podSelector:
    matchLabels:
      run: web
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          role: prod

---
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: web-allow-external
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:
  - ports:
    - port: 80
    from: []
[root@server2 calico]# kubectl apply -f policy2.yaml 
networkpolicy.networking.k8s.io/deny-namespace configured
networkpolicy.networking.k8s.io/access-namespace unchanged
networkpolicy.networking.k8s.io/web-allow-external created
[root@westos ~]# curl www1.westos.org/hostname.html
deployment-example-6456d7c676-4d52s
[root@westos ~]# curl www1.westos.org/hostname.html
deployment-example-6456d7c676-b8wcl

更多的策略資訊看官網介紹:https://docs.projectcalico.org/getting-started/kubernetes/self-managed-onprem/onpremises

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/288086.html

標籤:其他

上一篇:平面中判斷線段與矩形是否相交

下一篇:net-tools工具集的netstat逐漸被ss屬于的ipoute工具集取代

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more