k8s的网络类型

部署 CNI 网络组件

部署 flannel

K8S 中 Pod 网络通信:

Pod 内容器与容器之间的通信

在同一个 Pod 内的容器(Pod 内的容器是不会跨宿主机的)共享同一个网络命名空间,
相当于它们在同一台机器上一样,可以用 localhost 地址访问彼此的端口。

同一个 Node 内 Pod 之间的通信

每个 Pod 都有一个真实的全局 IP 地址,同一个 Node 内的不同 Pod 之间可以直接采用对方 Pod 的 IP 地址进行通信,
Pod1 与 Pod2 都是通过 Veth 连接到同一个 docker0/cni0 网桥,网段相同,所以它们之间可以直接通信。

不同 Node 上 Pod 之间的通信

cni插件:cni在k8s中是一个标准接口,在容器运行时调用网络插件,配置容器网络。负责设置容器的网络命名空间,IP地址。路由等等一系列的参数。

flanne插件:功能就是让集群之间不同节点的docker容器具有全集群为一个虚拟ip地址。

Overlay Network

overlay网络,在底层物理网络的基础之上,创建一个逻辑的网络层,二层+三层的集合,二次是物理网络,三层是逻辑网络。
overlay网络也是一种网络虚拟化的技术。

flannel支持的数据转发方式:
(每个node都会有一个flannel的虚拟网卡)
1、UDP模式

默认模式,应用转发,配置简单,但是性能最差。默认就是UDP(一般不用)

UDP:基于应用转发,flannel提供路由表,fannel分装数据包,解封装。

UDP基于应用层。走用户态

UDP模式使用的网卡是flannel.0

UDP模式的数据流向:

封装过程:

1、pod将数据通过 docker 0 网桥将数据转发的flannel.0网卡

2、node节点上都会有一个flannel的虚拟网卡负责封装和解封装。

     flannel.0网卡:封装数据包。通过自身flannel插件的路由表转发。

3、转发到部署在k8s上的pod  flanneld上。

解封装过程:

1、将包转发到目的node上,由flanneld解去数据包的第一层封装,后转发到flannel.0网卡。

2、flannel.0网卡将第二层解封装,转发到docker0。

3、docker0的网桥根据解析出来的目的地址,把数据流量转发到指定的容器内部。

在封装和解封装之后,信息会保存在etcd中。下次转发,可以直接请求etcd。

封装两层(由外到内)

第一层    封装真实主机的信息        源IP地址和目的IP地址

第二层     封装容器内的信息           内部容器的源IP和容器的目的IP地址。使用的是UDP协议

讲解可用

#Flannel UDP 模式的工作原理:
数据从主机 A 上 Pod 的源容器中发出后,经由所在主机的 docker0/cni0 网络接口转发到 flannel0 接口,
flanneld 服务监听在 flannel0 虚拟网卡的另外一端。
Flannel 通过 Etcd 服务维护了一张节点间的路由表。源主机 A 的 flanneld 服务将原本的数据内容封装到 
UDP 报文中, 根据自己的路由表通过物理网卡投递给目的节点主机 B 的 flanneld 服务,数据到达以后被解包,
然后直接进入目的节点的 flannel0 接口, 之后被转发到目的主机的 docker0/cni0 网桥,
最后就像本机容器通信一样由 docker0/cni0 转发到目标容器。

#ETCD 之 Flannel 提供说明:
存储管理Flannel可分配的IP地址段资源
监控 ETCD 中每个 Pod 的实际地址,并在内存中建立维护 Pod 节点路由表

由于 UDP 模式是在用户态做转发,会多一次报文隧道封装,因此性能上会比在内核态做转发的 VXLAN 模式差。  

2、vxlan模式

基于内核转发,适用于小集群(常用),使用的overlay的虚拟隧道通信技术(二层+三层的模式)

工作原理

根据VNI(flannel提供)+IP地址找到目标节点的通信地址

flannel提供路由表,内核实现封装和解封装,vxlan使用的网卡是flannel1.1网卡。

vxlan模式的数据流向:

封装过程:

       pod基于 docker 0 的网桥将数据传输至flannel.1网卡。会生成一个VTEP虚拟网络隧道,通过VTEP来实现据封装由网卡将发送至对方的网卡。通过隧道模式转发

注:

VTEP:virul tunel endpoint 虚拟网络隧道

源IP地址和目的IP地址还会生成vni。类似于vlanid。这些vni对应的是内部容器的源ip和目的ip。这些信息也会保存到etcd中。

解封装过程:

       数据发送到对方的网卡,由对方内核解封装数据包。并传递给flannel.1网卡,通过数据包内的目的vni地址,依次向下传递通过 docker 0 找到指定pod内容器的IP地址。

注:

封装过程类似于三层交换机

这里的flannel就需要负责识别对应的VNI的IP地址即可

这些信息也会保存到etcd中

讲解可用

#Flannel VXLAN 模式跨主机的工作原理:
1、数据帧从主机 A 上 Pod 的源容器中发出后,经由所在主机的 docker0/cni0 网络接口转发到 flannel.1 接口
2、flannel.1 收到数据帧后添加 VXLAN 头部,封装在 UDP 报文中
3、主机 A 通过物理网卡发送封包到主机 B 的物理网卡中
4、主机 B 的物理网卡再通过 VXLAN 默认端口 4789 转发到 flannel.1 接口进行解封装
5、解封装以后,内核将数据帧发送到 cni0,最后由 cni0 发送到桥接到此接口的容器 B 中。
3、host-gw

性能最好,但配置麻烦。

部署 CNI 网络组件安装flannel

在 node01 节点上操作
上传 cni-plugins-linux-amd64-v0.8.6.tgz 和 flannel.tar 到 /opt 目录中
在主节点上传入flannel的yml文件
cd /opt/
docker load -i flannel.tar
 
mkdir -p /opt/cni/bin
tar zxvf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin
#解压插件源码包放到指定的目录中。
node02节点上相同操作
 
在 master01 节点上操作上传入flannel的yml文件 部署 CNI 网络
cd /opt/k8s
kubectl apply -f kube-flannel.yml
#自动拉起pod节点
 
kubectl get pods -n kube-system
#查看是否拉起成功
kubectl get -o wide pods -n kube-system
#查看node使用的IP地址是什么


Calico插件

定义及特点

采用直接路由的方式。BGP路由。不需要修改报文,统一直接通过路由表转发。路由表会很复杂。对运行维护的要求比较高。

BGP模式的特点:交换路由信息的外部网关协议,可以连接不同的node节点。这些node节点可能不是一个网段。BGP实现可靠的(安全)、最佳的(选择最佳路径)、动态的路由选择(自动识别、自动选择)。自动识别相邻的路由设备(自动识别需要手动配置)。

calico不使用重叠网络,也不需要交换,直接通过虚拟路由实现。每一台虚拟路由都通过BGP转发到不同的节点。

核心组件:

felix:也是运行在主机上的一个pod,一个进程,k8s的daemonset的方式部署的pod。
daemontset 会在每个node节点部署相同的pod.后台的运行方式。
负责维护宿主机上插入路由的规则,维护calico需要的网络设备。网络接口管理,监听,路由等等。
BGP Client:bird BGP的客户端,专门负责在集群中分发路由规则的信息,每一个节点都会由一个BGP Client。
BGP协议广播方式通知其他节点的,分发路由规则,实现网络互通
ETCD:保存路由信息,负责网络元数据的一致性,保证网络状态的一致和准确。

Calico 工作原理:

通过路由表进行不同节点的pod之间的通信。一旦创建好pod后,veth pair路由设备会添加一个网卡设备cali

虚拟网卡:veth pair设备是一对设备,虚拟的以太网设备,一头连接容器的网络命名空间eth0,另一头连接宿主机的网络命名空间cali

依靠veth pair设备进行IP地址分配,veth pair连接容器的部分给容器分配一个IP地址,这个IP地址是唯一标识,宿主机也会被veth pair分配一个Calico网络的内部IP地址,这个IP地址和其他节点上的容器进行通信。

Calico模式的数据流向:

在ipip模式中,会生成一个tunnel隧道,所有的数据包封装都在tunnel中完成,封装的信息有:宿主机的IP地址,容器内部的IP地址。

部署 CNI 网络组件安装calico

在 master01 节点上操作上传 calico.yaml 文件到 /opt/k8s 目录中,部署 CNI 网络
cd /opt/k8s
vim calico.yaml
-----3878行-----
修改里面定义 Pod 的网络(CALICO_IPV4POOL_CIDR),需与前面 kube-controller-manager 配置文件指定的 cluster-cidr 网段一样
    - name: CALICO_IPV4POOL_CIDR
      value: "10.244.0.0/16"        
#Calico 默认使用的网段为 192.168.0.0/16
 
kubectl apply -f calico.yaml
#执行部署calico的yaml文件
kubectl get pods -n kube-system
#查看节点是否部署成功
#有一个总控制网络负责控制两个节点网络
kubectl get nodes
 
kubectl create deployment nginx1 --image=nginx:1.22 --replicas=3
#每创建一个pod就会生成一个calico网卡
ip route
#可以查看路由表

靠路由规则和路由条目转发。但是路由表数量太多,反而会影响转发效率。可以手动删除pod,它会自动清空路由表和路由条目。

总结【背】

常用的网络插件有两个flannel和calico

flannel配置简单,功能简单,基于overlay叠加网络实现,在物理层的网络再封装一个虚拟网络

vxlan是虚拟三层网络,最常用,基于vni+ip进行转发,flannel提供路由表,内核封装和解封装,但封装和解封装对数据传输的性能会有影响,同时不具备网络策略配置的能力,这个能力基于UDP协议,默认网段是10.244.0.0/16

udp是默认模式,一般在测试环境中用

host-gw不用

calico功能强大,基于路由表进行转发,没有封装和解封装的过程,对性能影响较小,具备网络策略配置的能力,但是每生成一个pod就会生成一个路由表,维护起来比较复杂,降低转发效率

模式:ipip模式、BGP模式

BGP模式是通过维护IP路由表的前缀来实现目标主机的可达性

对比IPIP模式,BGP模式没有隧道,BGP模式下,pod的数据包直接通过网卡发送到目标主机

ipip模式有隧道,在隧道中进行数据包的封装 ipv4 in ipv4

简单的小集群,使用flannel,考虑到以后扩容以及配置网络策略,可以使用calico


 

总结【背】在k8s中常用的网络插件有flannel和calico两种

flannel插件

flannel:配置简单。功能简单。基于overlay叠加网络实现。在物理层的网络封装一个虚拟的网络。

vxlan是虚拟三层网络。

UDP是默认模式一般不用。

flannel使用最多的就是vxlan模式。它是通过vni+ip进行转发,flannel提供路由表,由内核封装和解封装。

由于封装和解封装的过程。对数据传输的性能会有影响。同时不具备网络策略配置的能力。

host-gw配置太过于复杂。

calico插件

calico:功能强大,基于路由表转发。没有封装和解封装的过程。具备网络策略和配置能力。但是路由表维护起来比较复杂。

calico有两种模式:ipip、BGP

BGP:通过为ip路由表的前缀来实现目标主机的可达性。对比ipip模式,BGP模式没有隧道。BGP模式下,pod的数据包直接通过网卡,发送到目的地。

ipip的隧道:隧道进行数据包的封装。外层是宿主机的IP----内部是容器的IP

如果是简单的小集群使用flannel即可。

如果考虑到扩容、配置网络策略建议使用calico。

我们公司集群比较小使用flannel插件使用vxlan模式,但是calico我也知道。

部署 CoreDNS

CoreDNS:可以为集群中的 service 资源创建一个域名与 IP 的对应关系解析。

service是对外提供访问的地址。现在加入DNS机制之后,可以直接访问服务名。

service发现是k8s中的一个重要机制,其基本功能为:在集群内通过服务名对服务进行访问,
即需要完成从服务名到ClusterIP的解析。

k8s主要有两种service发现机制:环境变量和DNS。没有DNS服务的时候,k8s会采用环境变量的形式,但一旦有多个service,环境变量会变复杂,为解决该问题,我们使用DNS服务。

CoreDNS 是一个用于 Kubernetes 集群的灵活的 DNS 服务器。它为集群中的服务资源提供域名解析,使得可以通过域名来访问 Kubernetes 集群中的服务。

CoreDNS的作用

CoreDNS 可以为这些 Cluster IP 分配域名,并提供 DNS 解析服务。通过 CoreDNS,你可以通过服务名称来访问服务,而不必使用具体的 Cluster IP 地址。这对于在集群中进行服务发现和通信非常有用。

部署 CoreDNS
在所有 node 节点上操作
上传 coredns.tar 到 /opt 目录
cd /opt
docker load -i coredns.tar
 
在 master01 节点上操作
上传 coredns.yaml 文件到 /opt/k8s 目录中,部署 CoreDNS 
cd /opt/k8s
kubectl apply -f coredns.yaml
#一件拉起执行配置文件
kubectl get pods -n kube-system
 
kubectl run -it --rm dns-test --image=busybox:1.28.4 sh
#--rm:一旦退出容器就会被销毁
nslookup kubernetes
exit

部署多节点master02

开始master02 节点部署
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -x
#清空iptables的所有策略
master01、node01、node02关闭swap交换分区
swapoff -a
#关闭swap交换分区
#k8s在涉及时,为了提升性能,默认不使用swap交换分区,k8s在初始化的时候会自动检测swap
开始给主机改名
hostnamectl set-hostname master02
cat >> /etc/hosts << EOF
20.0.0.32 master01
20.0.0.33 master02
20.0.0.34 node01
20.0.0.35 node02
EOF
每台主机都加入映射
 
优化参数:
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv6.conf.all.disable_ipv6=1
net.ipv4.ip_forward=1
EOF
systemctl --system
#让配置文件生效
 
进行时间同步:
yum install ntpdate -y ntpdate ntp.aliyun.com 
 
从 master01 节点上拷贝证书文件、各master组件的配置文件和服务管理文件到 master02 节点
scp -r /opt/etcd/ root@20.0.0.33:/opt/
scp -r /opt/kubernetes/ root@20.0.0.33:/opt
scp -r /root/.kube root@20.0.0.33:/root
scp /usr/lib/systemd/system/{kube-apiserver,kube-controller-manager,kube-scheduler}.service root@20.0.0.33:/usr/lib/systemd/system/
 
修改配置文件kube-apiserver中的IP
vim /opt/kubernetes/cfg/kube-apiserver
----修改第五行和第七行----
#改成本机的IP地址20.0.0.33
 
开启组件:
systemctl start kube-apiserver.service
systemctl enable kube-apiserver.service
#开启apiserver
systemctl start kube-controller-manager.service
systemctl enable kube-controller-manager.service
#开启运行管理器
systemctl start kube-scheduler.service
systemctl enable kube-scheduler.service
#开启资源调度组件
 
查看node节点状态:
ln -s /opt/kubernetes/bin/* /usr/local/bin/
#创建软连接让系统可以识别
kubectl get nodes
kubectl get nodes -o wide
此时node节点并没有和master02并没有真正建立通信。是etcd里存储的信息。

负载均衡部署

//配置load balancer集群双机热备负载均衡(nginx实现负载均衡,keepalived实现双机热备)
##### 在lb01、lb02节点上操作 ##### 
//配置nginx的官方在线yum源,配置本地nginx的yum源

cat > /etc/yum.repos.d/nginx.repo << 'EOF'
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
EOF


yum install nginx -y

//修改nginx配置文件,配置四层反向代理负载均衡,指定k8s群集2台master的节点ip和6443端口

vim /etc/nginx/nginx.conf
events {
    worker_connections  1024;
}

#添加

stream {
    log_format  main  '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent';
#日志记录格式    
#$remote_addr: 客户端的 IP 地址。
#$upstream_addr: 上游服务器的地址。
#[$time_local]: 访问时间,使用本地时间。
#$status: HTTP 响应状态码。
#$upstream_bytes_sent: 从上游服务器发送到客户端的字节数。
    
    access_log  /var/log/nginx/k8s-access.log  main;

    upstream k8s-apiserver {
        server 192.168.10.10:6443;
        server 192.168.10.20:6443;
    }
    server {
        listen 6443;
        proxy_pass k8s-apiserver;
    }
}

http {
......

//检查配置文件语法

nginx -t   

//启动nginx服务,查看已监听6443端口

systemctl start nginx
systemctl enable nginx
netstat -natp | grep nginx 

//部署keepalived服务

yum install keepalived -y

//修改keepalived配置文件
vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
   # 接收邮件地址
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   # 邮件发送地址
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id NGINX_MASTER    #lb01节点的为 NGINX_MASTER,lb02节点的为 NGINX_BACKUP
   #vrrp_strict  #注释掉
}

#添加一个周期性执行的脚本
vrrp_script check_nginx {
    script "/etc/nginx/check_nginx.sh"    #指定检查nginx存活的脚本路径
}

vrrp_instance VI_1 {
    state MASTER            #lb01节点的为 MASTER,lb02节点的为 BACKUP
    interface ens33            #指定网卡名称 ens33
    virtual_router_id 51    #指定vrid,两个节点要一致
    priority 100            #lb01节点的为 100,lb02节点的为 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.10.100/24    #指定 VIP
    }
    track_script {
        check_nginx            #指定vrrp_script配置的脚本
    }
}

//创建nginx状态检查脚本 

vim /etc/nginx/check_nginx.sh

#!/bin/bash                                                        
/usr/bin/curl -I http://localhost &>/dev/null    
if [ $? -ne 0 ];then                                            
#    /etc/init.d/keepalived stop
    systemctl stop keepalived
fi 
chmod +x /etc/nginx/check_nginx.sh

//启动keepalived服务(一定要先启动了nginx服务,再启动keepalived服务)

systemctl start keepalived
systemctl enable keepalived
ip a                #查看VIP是否生成

//修改node节点上的bootstrap.kubeconfig,kubelet.kubeconfig配置文件为VIP

cd /opt/kubernetes/cfg/
vim bootstrap.kubeconfig 
server: https://192.168.233.100:6443
                      
vim kubelet.kubeconfig
server: https://192.168.233.100:6443
                        
vim kube-proxy.kubeconfig
server: https://192.168.233.100:6443

//重启kubelet和kube-proxy服务

systemctl restart kubelet.service 
systemctl restart kube-proxy.service

//在 lb01 上查看 nginx 和 node 、 master 节点的连接状态

netstat -natp | grep nginx


部署 Dashboard

Dashboard 介绍
仪表板是基于Web的Kubernetes用户界面。您可以使用仪表板将容器化应用程序部署到Kubernetes集群,
对容器化应用程序进行故障排除,并管理集群本身及其伴随资源。
您可以使用仪表板来概述群集上运行的应用程序,以及创建或修改单个Kubernetes资源
(例如deployment,job,daemonset等)。例如,您可以使用部署向导扩展部署,启动滚动更新,
重新启动Pod或部署新应用程序。仪表板还提供有关群集中Kubernetes资源状态以及可能发生的任何错误的信息。

//在 master01 节点上操作
#上传 recommended.yaml 文件到 /opt/k8s 目录中
 

cd /opt/k8s
recommended.yaml
#默认Dashboard只能集群内部访问,修改Service为NodePort类型,暴露到外部

kubectl apply -f recommended.yaml

#创建service account并绑定默认cluster-admin管理员集群角色

kubectl create serviceaccount dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin

#获取token值

kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

#使用输出的token登录Dashboard
https://192.168.10.30:30001

https://192.168.10.40:30001


 

  • 38
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值