Skip to content

2 Kubernetes-网络+集群部署

Kubernetes 的网络模型,假定了所有 Pod ,都在一个**可以直接连通的扁平的网络空间**中
这在 GCE(Google Compute Engine)里面是现成的网络模型
而在私有云里搭建 Kubernetes 集群,就不能假定这个网络已经存在了,需要借助插件搭建(Flannel、calico等)

一、Flannel-UDP 网络插件

core公司制作

1)让每个物理机的每个容器:

1.全集群每一个 pod 有唯一的地址
                ETCD、flanneld 申请分配保证唯一性
2. pod 间能互相通讯
                跨物理机:UDP 数据报文的二次封装
                同物理机:通过当前节点的网桥实现转发(二层网络)
                pod 中不同容器间通讯:本地回环接口(lo)

2)flannel 工作原理:

1、flanneld 通过 apiserver 连接 etcd ,申请网段
2、一个数据包中有完整的数据体,在对其进行二次封装
3、使用 UDP 发送数据包,而不是TCP
                原因:TCP慢启动、内网中数据包丢失可能性小

image-20230110202251672

1、flannel 中,跨物理机通讯过程:

UDP 数据报文的二次封装

2、同一个物理机之间,不同 pod 之间通讯

通过当前节点的网桥实现转发(二层网络)

image-20230110205348065

3、pod 中不同容器间通讯

本地回环接口(lo)

image-20230110205537319

3)flannel 优缺点:

优点:逻辑清晰简单、排错简单

缺点:数据报文需要在用户空间、内核空间中多次拷贝(代价较高、延迟较高)

image-20230110210213483

二、calico 网络插件

思科制作的

​ 纯三层的网络设备,没有复用 docker 的 docker0 网络,而是自己实现

​ calico 网络不对数据包进行额外封装,不需要 NAT 和端口映射

1)calico 工作原理

image-20230110210732884

2)calico工作模式

1、BGP:边界网关协议(纯路由协议技术)
2、IPIP:Linux 内核中的隧道技术
                将各个 node 的路由之间做一个 tunnel ,再把网络连接起来
                ipv4 的报文上再封装一个 ipv4(三层网络的二次封装)

image-20230110211144728

ip tunnel 模式介绍:

[root@localhost ~]# ip tunnel help
Usage: ip tunnel { add | change | del | show | prl | 6rd } [ NAME ]
          [ mode { ipip | gre | sit | isatap | vti } ] [ remote ADDR ] [ local ADDR ]

#ip tunnel 模式介绍:
                ipip            #在ipv4的报文上,再封装一个ipv4报文
                gre             #可以实现,UDP与TCP相互封装
                sit             #用ipv4报文,封装ipv6报文
                isatap          #主要用于ipv6数据包封装
                vti             #虚拟隧道接口




#ip tunnel 模式详细介绍:

- ipip:即 IPv4 in IPv4,在 IPv4 报文的基础上再封装一个 IPv4 报文。
- gre:即通用路由封装(Generic Routing Encapsulation),定义了在任意一种网络层协议上封装其他任意一种网络层协议的机制,IPv4 和 IPv6 都适用。
- sit:和 ipip 类似,不同的是 sit 是用 IPv4 报文封装 IPv6 报文,即 IPv6 over IPv4。
- isatap:即站内自动隧道寻址协议(Intra-Site Automatic Tunnel Addressing Protocol),和 sit 类似,也是用于 IPv6 的隧道封装。
- vti:即虚拟隧道接口(Virtual Tunnel Interface),是 cisco 提出的一种 IPsec 隧道技术。

3)IPIP 模式实验

calico 网络插件的 IPIP 模式

实验拓扑图:

image-20230110221823449

image-20230110222018150

1、C7-1 C7-2 关闭多余的网卡,仅保留仅主机网卡

[root@localhost ~]# yum -y install tcpdump
[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens34 
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens34 |grep ONBOOT
ONBOOT=no
[root@localhost ~]# systemctl restart network

2、C7-1 C7-2 临时开启路由转发

$ echo 1 > /proc/sys/net/ipv4/ip_forward

3、开启 ipip 模块,添加 tun 设备

# 两台机器均开启 ipip 模块
$ modprobe ipip
$ lsmod | grep ipip

# 第一台机器创建 tun 设备
$ ip tunnel add tun1 mode ipip remote 192.168.20.202 local 192.168.20.201
$ ip addr add 10.10.100.10 peer 10.10.200.10 dev tun1
$ ip link set tun1 up

# 第二台机器创建 tun 设备
$ ip tunnel add tun1 mode ipip remote 192.168.20.201 local 192.168.20.202
$ ip addr add 10.10.200.10 peer 10.10.100.10 dev tun1
$ ip link set tun1 up

4、抓包测试

​ TUN 与 TAP 是操作系统内核中的虚拟网络设备,AP 等同于一个以太网设备,它操作第二层数据包如以太网数据帧。TUN 模拟了网络层设备,操作第三层数据包比如 IP 数据封包

# hsot1 tun1 虚拟网卡抓包
        #抓取 tun1 进入的数据包,-w持久化保存
$ tcpdump -i tun1 -w tun1.pcap
$ ping 10.10.200.10 -c 1


# host1 ens33 网卡抓包
$ tcpdump -i ens33 -w tun2.pcap
$ ping 10.10.200.10 -c 1

导出抓包保存的文件,用工具分析

tun1.pcap文件分析:

image-20230110225925388

tun2.pcap文件分析:

image-20230110230502691

4)总结

1、calico 网络的 IPIP 模式:

1.全集群每一个 pod 有唯一的地址:
        ETCD、calico 申请分配保证唯一性
2.pod间通讯:
        pod 内部不同容器间通讯:lo
        pod 间通讯:
            同物理机:本机路由表
                自己添加一对设备(一端放入pod中,一端放入物理空间 cali.c2 网卡)通过 gw 指向自己 pod 的 cali.c2 网卡
                    跨物理机:本机路由表
                           IPIP LInux kernel (隧道技术、点对点传输)
Ⅰ 同物理机间 pod 的通讯:

image-20230110231137894

Ⅱ 跨物理机间 pod 的通讯

image-20230110231244296

2、优缺点:

​ 优点:采用 Linux 内核原生功能,稳定、可靠、效率高

​ 缺点:当前排错比较困难

三、最终网络模型

Kubernetes 内部网络结构图:

image-20230110232518678

四、Kubernetes 集群部署

两种安装方式:

​ 1)容器化安装

​ 2)二进制安装:

​ 安装详细步骤:https://cloudmessage.top/archives/k8s-install-1220

1)容器化安装:kubeadm(将所有组件,以容器方式运行)
            优点:
                搭建相对简单
                具备自愈性
            缺点:
                不易理解安装原理
                证书有效期只有一年   解决:
                                    修改k8s源码
                                    每隔一年更新一次集群
                镜像存放在 GCR (谷歌仓库),国内不可访问

2)二进制安装:k8s组件以 systemd 管理为进程
            优点:
                更便于理解和观察组件之间的调用关系
            缺点:
                无自愈性
                搭建复杂(工作半年以后,可以再来理解性安装)

1)虚拟机准备:

环境拓扑图:

image-20230110233340700

1、安装 ikuai 路由

安装 ikuai 路由.md

详细步骤请点击👉 安装 ikuai 路由-详细步骤

2、各个虚拟机设置

Ⅰ 三个节点设置
                 CPU         MEM        磁盘
1个master        >=2个核心    >=4G       100G
2个worker        >=1个核心    >=2G       100G

注意:初始化集群时,只用一张网卡

Ⅱ 关闭多余的网卡,仅留一张网卡
[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens34 
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens34 |grep ONBOOT
ONBOOT=no
[root@localhost ~]# systemctl restart network
Ⅲ 再第一块网卡中只想网关为 ikuai ,写入DNS
[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33 
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens33 | egrep "IPADDR|NETMASK|GATEWAY|DNS"
IPADDR=192.168.20.201
NETMASK=255.255.255.0
GATEWAY=192.168.20.199
DNS1=114.114.114.114
DNS2=8.8.8.8
[root@localhost ~]# systemctl restart network
Ⅳ 测试访问
[root@localhost ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.20.199  0.0.0.0         UG    100    0        0 ens33
192.168.20.0    0.0.0.0         255.255.255.0   U     100    0        0 ens33
[root@localhost ~]# ping www.baidu.com
PING www.a.shifen.com (220.181.38.149) 56(84) bytes of data.
64 bytes from 220.181.38.149 (220.181.38.149): icmp_seq=1 ttl=127 time=7.26 ms
64 bytes from 220.181.38.149 (220.181.38.149): icmp_seq=2 ttl=127 time=5.07 ms
64 bytes from 220.181.38.149 (220.181.38.149): icmp_seq=3 ttl=127 time=6.89 ms
64 bytes from 220.181.38.149 (220.181.38.149): icmp_seq=4 ttl=127 time=7.17 ms
64 bytes from 220.181.38.149 (220.181.38.149): icmp_seq=5 ttl=127 time=6.03 ms
^C
--- www.a.shifen.com ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4008ms
rtt min/avg/max/mdev = 5.078/6.489/7.266/0.829 ms

ikuai 路由中有显示:

image-20230111003505420

2)环境准备(所有节点)

1、设置系统主机名,以及hosts解析

#主机名设置
#C7-1
[root@localhost ~]# hostnamectl set-hostname k8s-master01

#C7-2
[root@localhost ~]# hostnamectl set-hostname k8s-node01

#C7-3
[root@localhost ~]# hostnamectl set-hostname k8s-node02


#所有主机的hosts解析
[root@localhost ~]# vim /etc/hosts
[root@localhost ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.20.201  k8s-master01    m1
192.168.20.202  k8s-node01  n1
192.168.20.203  k8s-node02  n2

192.168.20.200  harbor.yq.com

2、安装依赖包

yum install -y conntrack ntpdate ntp ipvsadm ipset  iptables curl sysstat libseccomp wget  vim net-tools git

3、设置防火墙为 Iptables 并设置空规则

systemctl  stop firewalld  &&  systemctl  disable firewalld
yum -y install iptables-services  &&  systemctl  start iptables  &&  systemctl  enable iptables  &&  iptables -F  &&  service iptables save

4、关闭 SELINUX

swapoff -a && sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
setenforce 0 && sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config

5、设置内核参数

cat > kubernetes.conf <<EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0 # 禁止使用 swap 空间,只有当系统 OOM 时才允许使用它
vm.overcommit_memory=1 # 不检查物理内存是否够用
vm.panic_on_oom=0 # 开启 OOM  
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF
cp kubernetes.conf  /etc/sysctl.d/kubernetes.conf
sysctl -p /etc/sysctl.d/kubernetes.conf

6、调整系统时区,搭建时间同步服务器

1、所有节点设置时区
$ timedatectl set-timezone Asia/Shanghai

2、配置时间同步服务器
#master设置chronyd服务端
[root@localhost ~]# vim /etc/chrony.conf 
[root@localhost ~]# cat /etc/chrony.conf | egrep "^server|^allow|^local"
server ntp1.aliyun.com iburst
server ntp2.aliyun.com iburst
server ntp3.aliyun.com iburst
allow 192.168.20.0/24
local stratum 10
[root@localhost ~]# systemctl enable chronyd --now
[root@localhost ~]# systemctl restart chronyd


#node1配置chronyd客户端
[root@localhost ~]# vim /etc/chrony.conf 
[root@localhost ~]# cat /etc/chrony.conf | grep "^server"
server 192.168.20.201 iburst
[root@localhost ~]# systemctl restart chronyd


#node2配置chronyd客户端
[root@localhost ~]# vim /etc/chrony.conf 
[root@localhost ~]# cat /etc/chrony.conf | grep "^server"
server 192.168.20.201 iburst
[root@localhost ~]# systemctl restart chronyd


3、设置定时任务,确保chronyd时刻同步
(由于虚拟机中没有 bios 硬件,让时间一直运行)
[root@localhost ~]# crontab -e
no crontab for root - using an empty one
crontab: installing new crontab
[root@localhost ~]# crontab -l
*/5 * * * * systemctl restart chronyd
[root@localhost ~]# systemctl enable crond --now
[root@localhost ~]# systemctl restart crond

7、关闭系统不需要的服务

systemctl stop postfix && systemctl disable postfix

8、设置日志持久化

mkdir /var/log/journal # 持久化保存日志的目录
mkdir /etc/systemd/journald.conf.d
cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF
[Journal]
# 持久化保存到磁盘
Storage=persistent

# 压缩历史日志
Compress=yes

SyncIntervalSec=5m
RateLimitInterval=30s
RateLimitBurst=1000

# 最大占用空间 10G
SystemMaxUse=10G

# 单日志文件最大 200M
SystemMaxFileSize=200M

# 日志保存时间 2 周
MaxRetentionSec=2week

# 不将日志转发到 syslog
ForwardToSyslog=no
EOF
systemctl restart systemd-journald

9、升级内核为4.4,设置默认启动启动

向每一个节点中上传 kernel-lt 的rpm包:

image-20230111005807708

#安装
$ yum -y install kernel-lt-4.4*
#设置4.4内核默认启动
[root@localhost ~]# cat /boot/grub2/grub.cfg |grep 4.4
[root@localhost ~]# grub2-set-default 'CentOS Linux (4.4.222-1.el7.elrepo.x86_64) 7 (Core)'

10、重启,关机做快照

reboot

3)Kubernetes 集群环境部署

1、kube-proxy 开启 ipvs 的前提条件

所有节点设置:

modprobe br_netfilter

cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF

chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4

2、安装docker

所有节点设置:

yum install -y yum-utils

yum-config-manager \
  --add-repo \
  http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

yum install -y docker-ce

## 创建 /etc/docker 目录
mkdir /etc/docker

# 配置 daemon.        centos7  CGROUP systemd
cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "insecure-registries": ["harbor.yq.com"],
  "registry-mirrors": ["https://kfp63jaj.mirror.aliyuncs.com"]
}
EOF

# 重启docker服务
systemctl  enable docker && reboot

3、关闭 Network manager

避免后续的 calico 插件的 ipip 模式的限制

所有节点设置:

systemctl disable NetworkManager
systemctl stop NetworkManager

4、安装 kubeadm

所有节点设置:

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

yum -y  install  kubeadm-1.15.1 kubectl-1.15.1 kubelet-1.15.1
systemctl enable kubelet.service

5、导入kubeadm基础镜像

Ⅰ 上传压缩包到master中

image-20230111013355903

Ⅱ 将kubeadm基础镜像发送给其他节点
[root@k8s-master01 ~]# tar -xf kubeadm-basic.images.tar.gz

[root@k8s-master01 ~]# scp -r kubeadm-basic.images root@n1:/root/

[root@k8s-master01 ~]# scp -r kubeadm-basic.images root@n2:/root/
Ⅲ 在每一个节点中导入kubeadm基础镜像
[root@k8s-master01 ~]# dockertools load -l kubeadm-basic.images/
[root@k8s-node01 ~]# dockertools load -l kubeadm-basic.images/
[root@k8s-node02 ~]# dockertools load -l kubeadm-basic.images/


#此处也可以写一个脚本[root@k8s-master01 ~]# vim load.sh
[root@k8s-master01 ~]# cat load.sh
#!/bin/bash

ls /root/kubeadm-basic.images > /var/images.cache

for i in $(cat /var/images.cache)
do
    echo "$i loading............."
    docker load -i /root/kubeadm-basic.images/$i
done

rm -rf /var/images.cache
[root@k8s-master01 ~]# chmod a+x load.sh 
[root@k8s-master01 ~]# ./load.sh 
导入
[root@k8s-master01 ~]# vim load.sh
[root@k8s-master01 ~]# cat load.sh
#!/bin/bash

ls /root/kubeadm-basic.images > /var/images.cache

for i in $(cat /var/images.cache)
do
    echo "$i loading............."
    docker load -i /root/kubeadm-basic.images/$i
done

rm -rf /var/images.cache
[root@k8s-master01 ~]# chmod a+x load.sh 
[root@k8s-master01 ~]# ./load.sh 

5、初始化主节点(master中设置)

生成kubeadm-config.yaml文件,并修改:

​ masterip: advertiseAddress: 192.168.20.201

​ 版本: kubernetesVersion: v1.15.1

​ pod所在网段: podSubnet: "172.100.0.0/16"

​ 指定kubeproxy负载方案:强制用ipvs模式

[root@k8s-master01 ~]# kubeadm config print init-defaults > kubeadm-config.yaml

[root@k8s-master01 ~]# vim kubeadm-config.yaml

[root@k8s-master01 ~]# tail -n 6 kubeadm-config.yaml 
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
featureGates:
  SupportIPVSProxyMode: true
mode: ipvs

[root@k8s-master01 ~]# cat kubeadm-config.yaml | egrep "Address|kubernetesVersion|podSubnet"
  advertiseAddress: 192.168.20.201
kubernetesVersion: v1.15.1
  podSubnet: "172.100.0.0/16"

6、初始化集群

注意:每个节点初始化集群前,检查镜像是否导入、是否只有一张网卡

#master01初始化集群
kubeadm init --config=kubeadm-config.yaml --experimental-upload-certs | tee kubeadm-init.log
#根据master01初始化集群后的提示设置,配置master01环境
  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config



#根据master01初始化集群后的提示设置,将node01、node02加入kubeadm
#node1
kubeadm join 192.168.20.201:6443 --token abcdef.0123456789abcdef \
    --discovery-token-ca-cert-hash sha256:72c857b02befe38ba6db1f1bd61b77d3b65e55d16b7284f400c53d1ce51601bb

#node2
kubeadm join 192.168.20.201:6443 --token abcdef.0123456789abcdef \
    --discovery-token-ca-cert-hash sha256:72c857b02befe38ba6db1f1bd61b77d3b65e55d16b7284f400c53d1ce51601bb

7、部署 calico 网络

Ⅰ 上传calico镜像,并导入

image-20230111020212836

#master01   解压,导入calico镜像,并发送给其他节点
[root@k8s-master01 ~]# tar -xf calico-k8s-1.15.1.tar.gz 
[root@k8s-master01 ~]# cd calico-k8s-1.15.1
[root@k8s-master01 calico-k8s-1.15.1]# docker load -i calico-cni-3.3.7.tar 
[root@k8s-master01 calico-k8s-1.15.1]# docker load -i calico-node-3.3.7.tar
[root@k8s-master01 calico-k8s-1.15.1]# scp *.tar root@n1:/root/
[root@k8s-master01 calico-k8s-1.15.1]# scp *.tar root@n2:/root/


#node01 导入calico镜像
[root@k8s-node01 ~]# docker load -i calico-cni-3.3.7.tar
[root@k8s-node01 ~]# docker load -i calico-node-3.3.7.tar


#node02 导入calico镜像
[root@k8s-node02 ~]# docker load -i calico-cni-3.3.7.tar
[root@k8s-node02 ~]# docker load -i calico-node-3.3.7.tar
Ⅱ master01中根据资源清单文件,部署calico网络
[root@k8s-master01 calico-k8s-1.15.1]# kubectl create -f rbac-kdd.yaml 

[root@k8s-master01 calico-k8s-1.15.1]# kubectl create -f calico.yaml 

8、测试

[root@k8s-master01 calico-k8s-1.15.1]# kubectl get node
NAME           STATUS   ROLES    AGE   VERSION
k8s-master01   Ready    master   14m   v1.15.1
k8s-node01     Ready    <none>   10m   v1.15.1
k8s-node02     Ready    <none>   10m   v1.15.1

9、整理资源、做快照

[root@k8s-master01 ~]# mkdir -p /usr/local/kubernetes/install
[root@k8s-master01 ~]# mv kubeadm-config.yaml kubeadm-init.log /usr/local/kubernetes/install/
[root@k8s-master01 ~]# mkdir /usr/local/kubernetes/cni
[root@k8s-master01 ~]# mv calico-k8s-1.15.1 /usr/local/kubernetes/cni/

[root@k8s-master01 ~]# rm -rf /root/*