一、service的简介
1.1Service可以看作是一组提供相同服务的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 设定)。

1.2外部主机访问节点

[root@server2 manifest]# kubectl apply -f service.yml 
[root@server2 manifest]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   5d18h
myservice    ClusterIP   10.102.194.46   <none>        80/TCP    3h8m
[root@server2 manifest]# kubectl apply -f pod2.yml 
deployment.apps/deployment-example created
[root@server2 manifest]# kubectl get pod
NAME                                  READY   STATUS    RESTARTS   AGE
deployment-example-67764dd8bd-6bkml   1/1     Running   0          3s
deployment-example-67764dd8bd-ffpxw   1/1     Running   0          3s
deployment-example-67764dd8bd-nprg7   1/1     Running   0          3s

在这里插入图片描述

更改myservice文件ClusterIP改为NodePort:将Service通过指定的Node上的端口暴露给外部,访问任意一个
[root@server2 manifest]# kubectl edit svc myservice   
service/myservice edited

在这里插入图片描述

暴露端口30580
[root@server2 manifest]# kubectl get svc 
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        5d18h
myservice    NodePort    10.102.194.46   <none>        80:30580/TCP   3h20m

在其他节点上查看
[root@server4 ~]# netstat -tnpl | grep 30580  
tcp        0      0 0.0.0.0:30580           0.0.0.0:*               LISTEN      17972/kube-proxy    

[root@server3 ~]# netstat -tnpl | grep 30580
tcp        0      0 0.0.0.0:30580           0.0.0.0:*               LISTEN      18045/kube-proxy    

在不属于集群的主机上访问

在这里插入图片描述
**二、Service 是由 kube-proxy 组件,加上 iptables 来共同实现的.
kube-proxy 通过 iptables 处理 Service 的过程,需要在宿主机上设置相当多的iptables 规则,如果宿主机有大量的Pod,不断刷新iptables规则,会消耗大量的CPU资源。

IPVS模式的service,可以使K8s集群支持更多量级的Pod。
 
开启kube-proxy的ipvs模式:
yum install -y ipvsadm //所有节点安装
root@server2 manifest]# kubectl edit cm kube-proxy -n kube-system //修改IPVS模式

在这里插入图片描述

更新kube-proxy pod。
mode: "ipvs" • $ kubectl get pod -n kube-system |grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}' 

在这里插入图片描述

在这里插入图片描述
在其他节点上创建这个VIP
kube-proxy通过linux的IPVS模块,以rr轮询方式调度service中的Pod
在这里插入图片描述

IPVS模式下,kube-proxy会在service创建后,在宿主机上添加一个虚拟网卡:
kube-ipvs0,并分配service IP

查卡每个节点都有:10.98.46.168  IP
[root@server2 manifest]# ip a | grep kube-ipvs0
9: kube-ipvs0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default 
    inet 10.96.0.1/32 brd 10.96.0.1 scope global kube-ipvs0
    inet 10.96.0.10/32 brd 10.96.0.10 scope global kube-ipvs0
    inet 10.98.46.168/32 brd 10.98.46.168 scope global kube-ipvs0
[root@server3 ~]# ip a | grep kube-ipvs0
58: kube-ipvs0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default 
    inet 10.96.0.10/32 brd 10.96.0.10 scope global kube-ipvs0
    inet 10.96.0.1/32 brd 10.96.0.1 scope global kube-ipvs0
    inet 10.98.46.168/32 brd 10.98.46.168 scope global kube-ipvs0
[root@server4 ~]# ip a | grep kube-ipvs0
41: kube-ipvs0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default 
    inet 10.96.0.1/32 brd 10.96.0.1 scope global kube-ipvs0
    inet 10.96.0.10/32 brd 10.96.0.10 scope global kube-ipvs0
    inet 10.98.46.168/32 brd 10.98.46.168 scope global kube-ipvs0

在这里插入图片描述
在这里插入图片描述
在server3上查看

在这里插入图片描述
三、Kubernetes 提供了一个 DNS 插件 Service
在这里插入图片描述

通过域名解析IP;也可以访问域名实现负载均衡(IP地址会变化,但是域名不会改变)
当重新创建pod后,VIP在其他节点都是实时同步的
在这里插入图片描述
四、Headless Service “无头服务”
• Headless Service不需要分配一个VIP,而是直接以DNS记录的方式解析出被代理
Pod的IP地址。

• 域名格式:$(servicename).$(namespace).svc.cluster.local

[root@server2 manifest]# yum install  -y bind-utils

在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

[root@server2 manifest]# cat service.yml 
kind: Service
apiVersion: v1
metadata:
  name: myservice
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: myapp
  clusterIP: None  不显示IP

在这里插入图片描述

[root@server2 manifest]# kubectl get svc -n kube-system
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   5d22h
10.96.0.10此地址是集群自动分配的servicer地址,此地址后面有两个pod如下图所示
使用dig命名也可以直接访问下面两个地址解析到容器地址——实现负载均衡

在这里插入图片描述

查看service后端的两个pod地址
[root@server2 manifest]# kubectl describe svc myservice 

在这里插入图片描述
实现负载均衡
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Pod滚动更新后,依然可以解析:

[root@server2 manifest]# vim pod2.yml

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
五、外部访问service的另外两种方式
5.1、 LoadBalancer 类型的 Service
从外部访问 Service 的第二种方式,适用于公有云上的 Kubernetes 服务。这
时候,你可以指定一个 LoadBalancer 类型的 Service。

[root@server2 manifest]# kubectl delete -f service.yml 
service "myservice" deleted
[root@server2 manifest]# cat  service.yml
kind: Service
apiVersion: v1
metadata:
  name: myservice
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: myapp
  type: LoadBalancer  指定一个 LoadBalancer 类型的 Service

[root@server2 manifest]# kubectl apply -f service.yml 
service/myservice created
[root@server2 manifest]# kubectl get svc myservice 
NAME        TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
myservice   LoadBalancer   10.104.101.0   <pending>     80:30509/TCP   16s

流程:用户——访问公有云上的slb——访问后端pod——访问(172.25.254.2/3/4:30509)都可以。
在service提交后,Kubernetes就会调用 CloudProvider 在公有云上为你创建一个负载均衡服务,并且把被代理的 Pod 的 IP地址配置给负载均衡服务做后端。

5.2从外部访问的第三种方式叫做ExternalName
集群内部的pod访问集群之外的资源

[root@server2 manifest]# 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  公司域名
  

使用dns地址解析
在这里插入图片描述
也可以使用后端pod的地址
在这里插入图片描述

更改公司名称
[root@server2 manifest]# 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.taobao.com  淘宝

在这里插入图片描述
5.3service允许为其分配一个公有IP。
外部主机访问pod

[root@server2 manifest]# vim service.yml 
kind: Service
apiVersion: v1
metadata:
  name: myservice
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: myapp
  externalIPs:
  - 172.25.254.100   自定义一个外网IP

[root@server2 manifest]# kubectl delete -f service.yml 
service "myservice" deleted
[root@server2 manifest]# kubectl apply -f service.yml 
service/myservice created
[root@server2 manifest]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP      PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>           443/TCP   6d
myservice    ClusterIP   10.100.32.158   172.25.254.100   80/TCP    9s

在这里插入图片描述
在这里插入图片描述

外部主机访问
[root@server1 ~]# curl 172.25.254.100
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

六、不同网段的pod容器跨主机访问
6.1Flannel vxlan模式跨主机通信原理
在这里插入图片描述
server2跨主机访问server3
在这里插入图片描述
子网分配信息存放位置

[root@server2 manifest]# cd /run/flannel/
[root@server2 flannel]# cat subnet.env 
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true

[root@server4 ~]# cat /run/flannel/subnet.env 
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.2.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true

[root@server3 ~]# cat /run/flannel/subnet.env 
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.1.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true


每个节点也都会启动一个服务

ps ax | grep flnneld
 55573 pts/0    R+     0:00 grep --color=auto flnneld

查看各个节点的MAC地址
在这里插入图片描述

网关10.244.1.0的MAC地址就是server2上flannel1的MAC地址
网关10.244.2.0的MAC地址就是server3上flannel1的MAC地址

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

        flannel包装:  搭载udp数据包到达server4
         源地址:server3:10.244.1.86-mac:f6:73:ec:b5:07:9a
         目的地:server4:10.244.2.61-mac:1e:0f:e8:fc:db:2a
eth0包装:
源地址:172.25.254.3:00:0c:29:ba:53:cb
目的地:172.25.254.4:00:0c:29:c6:f7:50

到达server4之后解封到达flannel1之后解封再到达cni0。
这样会影响性能导致访问速度不一致

6.2host-gw模式跨主机通信

[root@server2 manifest]# cat service.yml 
kind: Service
apiVersion: v1
metadata:
  name: myservice
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: myapp
  type: NodePort   更改类型
[root@server2 manifest]# cat pod2.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
  # Unique key of the Deployment instance
  name: deployment-example
spec:
  # 3 Pods should exist at all times.
  replicas: 4
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        # Apply this label to pods and default
        # the Deployment label selector to this value
        app: myapp
    spec:
      containers:
      - name: myapp
        # Run this image
        image: myapp:v1

在这里插入图片描述

[root@server2 manifest]# kubectl get svc  改为NodePort之后会有一个端口31891
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        6d2h
myservice    NodePort    10.110.8.176   <none>        80:31891/TCP   8m11s

更改通信模式为host-gw模式
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

查看通信原理:

10.244.1.0访问10.244.2.0:
通过ens33直接转发定向到server4主机IP上没有经过flannel封装
[root@server3 ~]# ip route 
default via 192.168.1.1 dev ens33 proto static metric 100 
10.244.0.0/24 via 172.25.254.2 dev ens33 
10.244.1.0/24 dev cni0 proto kernel scope link src 10.244.1.1   
10.244.2.0/24 via 172.25.254.4 dev ens33  
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 
172.25.254.0/24 dev ens33 proto kernel scope link src 172.25.254.3 metric 100 
192.168.1.0/24 dev ens33 proto kernel scope link src 192.168.1.33 metric 100 

[root@server4 ~]# ip route   同样的原理也是经过ens33网卡出去直接访问主机IP
default via 192.168.1.1 dev ens33 proto static metric 100 
10.244.0.0/24 via 172.25.254.2 dev ens33 
10.244.1.0/24 via 172.25.254.3 dev ens33 
10.244.2.0/24 dev cni0 proto kernel scope link src 10.244.2.1 
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 
172.25.254.0/24 dev ens33 proto kernel scope link src 172.25.254.4 metric 100 
192.168.1.0/24 dev ens33 proto kernel scope link src 192.168.1.44 metric 100 

注意:必须二层网络互相连通。大多数情况下二层网络是不通的,都是三层通信

外部主机访问测试
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
知识点补充:flannel不支持网络策略,只是支持通信。

6.3.1默认情况下vxlan没有打开直连路由,打开Vxlan的直连路由功能
当在同一个网段内使用直连路由,不同网段的使用隧道模式
编辑文件flannel
在这里插入图片描述

查看已经更改
[root@server2 manifest]# kubectl describe -n  kube-system cm kube-flannel-cfg 

在这里插入图片描述
在这里插入图片描述

[root@server2 manifest]# kubectl get pod
NAME                                  READY   STATUS    RESTARTS   AGE
deployment-example-7449b5b68f-55f7q   1/1     Running   0          5m51s
deployment-example-7449b5b68f-6g4fz   1/1     Running   0          5m51s
deployment-example-7449b5b68f-fszzl   1/1     Running   0          5m51s
deployment-example-7449b5b68f-vzrqq   1/1     Running   0          5m51s
[root@server2 manifest]# kubectl apply -f service.yml 
service/myservice created
[root@server2 manifest]# kubectl get svc myservice
NAME        TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
myservice   NodePort   10.99.43.52   <none>        80:32685/TCP   3s

外部主机测试访问
在这里插入图片描述
6.3.2使用caclio模式增加网略策略
获取文件:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#
在这里插入图片描述
在这里插入图片描述

 vim calico.yaml 

在文件中查找;下载相应软件包(一共四个),并上传至harbor仓库
在这里插入图片描述
默认情况下激活IPIP是基于IP的隧道,隧道可以忽略不同网段的限制。当前实验环境在同一个网段下可以不开启IPIP。

vim calico.yaml 

在这里插入图片描述
所有节点移走flannel配置文件
在这里插入图片描述

cni调用的指令文件
cni主要工作:把新建的容器添加到网络站上和删除。
在这里插入图片描述
运行caclio网络插件
在这里插入图片描述
在这里插入图片描述
使用的是daemonsets方式

[root@server2 ~]# kubectl get  daemonsets.apps -n kube-system
NAME          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
calico-node   3         3         0       3            0           kubernetes.io/os=linux   3m12s
kube-proxy    3         3         3       3            3           kubernetes.io/os=linux   18h

在这里插入图片描述
在这里插入图片描述
查看IPIP隧道模式被禁用

[root@server2 ~]# kubectl describe ippool  使用的是边界网关协议

在这里插入图片描述
创建service和pod
在这里插入图片描述
外部主机测试访问
在这里插入图片描述
6.3.2.1calico自定义IP及开启隧道模式

[root@server2 ~]# vim calico.yaml 

在这里插入图片描述

在这里插入图片描述

[root@server2 ~]# kubectl delete -f calico.yaml   删除
[root@server2 ~]# kubectl apply -f calico.yaml   新建

在节点上查看隧道模式已经开启
在这里插入图片描述
在这里插入图片描述
7.更改网络插件模式为host-gw模式

移走所有节点的calico文件
cd /etc/cni/net.d/
 ls
10-calico.conflist  calico-kubeconfig
 mv * /mnt/
vim kube-flannel.yml 

在这里插入图片描述

kubectl delete -f calico.yaml 
kubectl apply -f kube-flannel.yml
可以重启所有主机

在这里插入图片描述

Logo

开源、云原生的融合云平台

更多推荐