K8s9(2-1) k8s中的通信机制, kube-proxy的ipvs模式 ,无头服务,LoadBalancer,ExternalName,外部公有 ip(externalIPs)

1.K8s中的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。

k8s间的通信方式:

k8s通过CNI接口接入其他插件来实现网络通讯。目前比较流行的插件有flannel, calico等。

CNI插件存放位置: cat /etc/cni/net.d/10-flannel.conflist

插件使用的解决方案如下:

虚拟网桥,虚拟网卡,多个容器共用一一个虛拟网卡进行通信。
多路复用: MacVLAN,多个容器共用- -个物理网卡进行通信。
硬件交换: SR-LOV, 一个物理网卡可以虚拟出多个接口,这个性能最好。

容器间通信:同一个pod内的多个容器间的通信,通过Io即可实现;

pod之间的通信:

同一节点的pod之间通过cni网桥转发数据包。
不同节点的pod之间的通信需要网络插件支持。

pod和service通信:通过 iptables 或 ipvs 实现通信,ipvs取代不了iptables,因为ipvs只能做负载均衡,而做不了nat转换。

pod和外网通信:iptables的MASQUERADE

Service与集群外部客户端的通信: Ingress、 NodePort、 Loadbalancer

2.kube-proxy的ipvs模式:

默认情况下:kube-proxy使用的是iptables模式,如果宿主机有大量的pod会浪费cpu来频繁更新iptables策略;

因此,使用ipvs模式下的service可以使k8s支持更多量级的pod;

开启kube-proxy的ipvs模式:
yum install -y ipvsadm 所有节点安装
kubectl edit cm kube-proxy -n kube-system 修改IPVS模式 mode: “ipvs”
kubectl get pod -n kube-system |grep kube-proxy | awk '{system(“kubectl delete pod “$1” -n kube-system”)}'更新kube-proxy pod

安装ipvsadm,更改mode; 由于更改了模式,因此更新kube-proxy pod 最简单的就是删除让其重建;
等删除完成之后可以使用ipvsadm -ln 查看其中策略,可以看见service中的10.96.0.1和10.98.153.70在策略中使用rr调度;
在这里插入图片描述

同时:IPVS模式下,kube-proxy会在service创建后,在宿主机上添加一个虚拟网卡: kube-ipvs0,并分配service IP。
在这里插入图片描述

使用ipvs模式下创建的pod都会在 kube-ipvs0,中分配到对应的service IP;

# demo.yml 
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  selector:
    app: myapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo2
spec:
  replicas: 4
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v2


3.无头服务(Headless Services):

Headless Service “无头服务” 。 Headless Service不需要分配一个VIP,而是直接以DNS记录的方式解析出被代理 Pod的IP地址。
域名格式:$ (servicename).$(namespace).svc.cluster.local

yum install -y bind-utils.x86_64安装解析工具( dig )

[root@server11~]$ vim service.yml 
[root@server11~]$ cat service.yml 
kind: Service
apiVersion: v1
metadata:
  name: myservice
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: myapp
  clusterIP: None
[root@server11~]$ kubectl apply -f service.yml 
service/myservice created
[root@server11~]$ kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   7d11h
myservice    ClusterIP   None         <none>        80/TCP    10s
[root@server11~]$ kubectl describe svc myservice 
Name:              myservice
Namespace:         default
Labels:            <none>
Annotations:       Selector:  app=myapp
Type:              ClusterIP
IP:                None
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.47:80,10.244.1.48:80,10.244.2.70:80
Session Affinity:  None
Events:            <none>

[root@server11~]$ kubectl -n kube-system describe svc kube-dns 
Name:              kube-dns
Namespace:         kube-system
Labels:            k8s-app=kube-dns
                   kubernetes.io/cluster-service=true
                   kubernetes.io/name=KubeDNS
Annotations:       prometheus.io/port: 9153
                   prometheus.io/scrape: true
Selector:          k8s-app=kube-dns
Type:              ClusterIP
IP:                10.96.0.10
Port:              dns  53/UDP
TargetPort:        53/UDP
Endpoints:         10.244.0.10:53,10.244.0.11:53
Port:              dns-tcp  53/TCP
TargetPort:        53/TCP
Endpoints:         10.244.0.10:53,10.244.0.11:53
Port:              metrics  9153/TCP
TargetPort:        9153/TCP
Endpoints:         10.244.0.10:9153,10.244.0.11:9153
Session Affinity:  None
Events:            <none>

[root@server11~]$ dig myservice.default.svc.cluster.local @10.96.0.10
; <<>> DiG 9.9.4-RedHat-9.9.4-72.el7 <<>> myservice.default.svc.cluster.local @10.96.0.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19011
;; 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.70
myservice.default.svc.cluster.local. 30 IN A 10.244.1.48
myservice.default.svc.cluster.local. 30 IN A 10.244.1.47
;; Query time: 0 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Fri Jun 26 15:01:23 CST 2020
;; MSG SIZE  rcvd: 217

[root@server11~]$ dig myservice.default.svc.cluster.local @10.244.0.11
; <<>> DiG 9.9.4-RedHat-9.9.4-72.el7 <<>> myservice.default.svc.cluster.local @10.244.0.11
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16525
;; 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.1.48
myservice.default.svc.cluster.local. 30 IN A 10.244.2.70
myservice.default.svc.cluster.local. 30 IN A 10.244.1.47
;; Query time: 0 msec
;; SERVER: 10.244.0.11#53(10.244.0.11)
;; WHEN: Fri Jun 26 15:02:57 CST 2020
;; MSG SIZE  rcvd: 217

无头服务在Pod滚动更新后,依然可以解析:因为在service中的地址也会改变:

[root@server11~]$ kubectl delete pod --all
pod "deployment-example-67764dd8bd-p5qnr" deleted
pod "deployment-example-67764dd8bd-pvkc6" deleted
pod "deployment-example-67764dd8bd-smr7c" deleted
[root@server11~]$ kubectl get pod -o wide
NAME                                  READY   STATUS    RESTARTS   AGE   IP            NODE      NOMINATED NODE   READINESS GATES
deployment-example-67764dd8bd-6pwdw   1/1     Running   0          7s    10.244.2.74   server3   <none>           <none>
deployment-example-67764dd8bd-jl7nl   1/1     Running   0          7s    10.244.1.49   server2   <none>           <none>
deployment-example-67764dd8bd-zvd28   1/1     Running   0          7s    10.244.2.73   server3   <none>           <none>
[root@server11~]$ dig myservice.default.svc.cluster.local @10.244.0.11
; <<>> DiG 9.9.4-RedHat-9.9.4-72.el7 <<>> myservice.default.svc.cluster.local @10.244.0.11
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48989
;; 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.1.49
myservice.default.svc.cluster.local. 30 IN A 10.244.2.73
myservice.default.svc.cluster.local. 30 IN A 10.244.2.74
;; Query time: 0 msec
;; SERVER: 10.244.0.11#53(10.244.0.11)
;; WHEN: Fri Jun 26 15:14:37 CST 2020
;; MSG SIZE  rcvd: 217

4.LoadBalancer方式(可外部访问):

从外部访问 Service 的第二种方式,适用于公有云上的 Kubernetes 服务。这时候,你可以指定一个 LoadBalancer 类型的 Service。
在service提交后,Kubernetes就会调用 CloudProvider 在公有云上创建一个负载均衡服务,并且把被代理的 Pod 的 IP地址配置给负载均衡服务做后端。

LoadBalancer示例:本例没有云主机,所以状态为 pending

编写资源清单:type类型为LoadBalancer,注意大小写

cat service.yml 
kind: Service
apiVersion: v1
metadata:
  name: myservice
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: myapp
  type: LoadBalancer

执行,查 看:

kubectl apply -f service.yml 
service/myservice created
[root@server11~]$ kubectl get svc 
NAME         TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1        <none>        443/TCP        7d11h
myservice    LoadBalancer   10.104.173.144   `<pending>`     80:32646/TCP   5s

5.ExternalName方式(可外部访问):

适用于集群内部容器访问外部资源

通过返回 CNAME 和对应值,可以将服务映射到 externalName 字段的内容

编写资源清单:type类型为ExternalName,定义外部域名:

cat service.yml 
kind: Service
apiVersion: v1
metadata:
  name: myservice
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: myapp
  type:  ExternalName  
  externalName: www.baidu.com

执行资源清单,查看结果:

kubectl apply -f service.yml 
service/myservice created
[root@server11~]$ kubectl get svc 
NAME         TYPE           CLUSTER-IP   EXTERNAL-IP     PORT(S)   AGE
kubernetes   ClusterIP      10.96.0.1    <none>          443/TCP   7d11h
myservice    ExternalName   <none>       www.baidu.com   80/TCP    4s
[root@server11~]$ dig myservice.default.svc.cluster.local @10.244.0.11
; <<>> DiG 9.9.4-RedHat-9.9.4-72.el7 <<>> myservice.default.svc.cluster.local @10.244.0.11
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 44555
;; flags: qr aa rd; QUERY: 1, ANSWER: 4, 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 CNAME www.baidu.com.
www.baidu.com.  30 IN CNAME www.a.shifen.com.
www.a.shifen.com. 30 IN A 61.135.169.121
www.a.shifen.com. 30 IN A 61.135.169.125
;; Query time: 75 msec
;; SERVER: 10.244.0.11#53(10.244.0.11)
;; WHEN: Fri Jun 26 15:28:43 CST 2020
;; MSG SIZE  rcvd: 233


6.引入外部共有 ip(externalIPs)

添加外部公共ip后,可以直接通过公开的ip地址3访问pod:

cat service.yml 
kind: Service
apiVersion: v1
metadata:
  name: myservice
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: myapp
  externalIPs: 
  - 172.25.1.100
[root@server11~]$ kubectl apply -f service.yml 
service/myservice created
[kub@server1 mainfest]$ kubectl get svc 
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP    PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1        <none>         443/TCP   7d11h
myservice    ClusterIP   10.105.122.218   172.25.1.100   80/TCP    4s
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值