节点部署完成之后,节点的状态都是Notready,所以要部署k8s网络:
k8s的网络类型:
k8s中的通信模式:
- pod内部之间容器与容器之间的通信。
在同一个pod中的容器共享资源和网络,使用同一个网络命名空间,可以直接通信的
- 同一个node节点之内,不同pod之间的通信
每个pod都有一个全局的真实的IP地址,同一个node直接的不同pod可以直接使用对方的pod的IP地址进行通信。
Pod1和pod2是通过docker的网桥来进行通信的
-
不同node节点的上的pod之间如何进行通信?
Cni插件:cni是一个标准接口,用于容器运行时调用网络插件,配置容器网络,负责设置容器的网络命名空间,IP地址,路由等等参数
Flanne插件:功能就是让集群之中不同节点的docker容器具有全集群唯一的虚拟IP地址,他是一个overlay网络,在底层物理网络的基础之上,创建一个逻辑的网络层,二层+三层的集合,二层是物理网络,三层是逻辑上的网络层,overlay网络也是一种网络虚拟化的技术
Flannel支持的数据转发方式:
- UDP模式,默认模式,应用转发,配置简单,但是性能最差
- Vxlan模式,基于内核转发,也是最常用的网络类型(小集群都使用这个模式)
- Host-gw(性能最好,但是配置麻烦,了解即可)
UDP模式(用的较少):基于应用转发,是由flannel来提供路由表,flannel封装数据包,解封装
每个node节点都会有一个flannel的虚拟网卡
数据流向图:
Vxlan模式:使用的就是overlay的虚拟隧道通信技术,是一个二层+三层的模式
而UDP是基于应用层,用户态
Vxlan:flannel提供路由表,内核封装解封装
Flannel1.1接口,用的就是vxlan
Vxlan的工作模式图:简单来说就是说vni+ip地址
vim /etc/profile
source <(kubectl completion bash)
source /etc/profile
Node1,node2
将flannel.tar拖入
docker load -i flannel.tar
mkdir -p /opt/cni/bin
将cni-plugins-linux-amd64-v0.8.6.tgz拖入
tar -xf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin/
Node2同样的操作
Master01
拖入kube-flannel.yml
kubectl apply -f kube-flannel.yml
查看(多刷新几次,需要等待时间)
kubectl get pod -n kube-system
kubectl get pod -o wide -n kube-system
Ifconfig查看
Node1,node2
网络已部署完成
kubectl get nodes
第二个网络插件calico插件:
Flannel:每个发向容器的数据包进行封装,vxlan通过vtep打包数据,由内核封装数据包-----》转发到目标的node节点。到了目标node节点后,还有一个解封装的过程,再发送到目标pod,性能是有一定影响的
Calico:它是采用直接路由的方式,他的性能是最好的,也就是BGP路由,不需要修改报文,统一直接通过路由表转发,路由表会很复杂,运行维护的要求比较高
BGP模式的特点:交换路由信息外部网关协议,可以连接不同的node节点,node节点可能不是一个网段,BGP会自动寻址,自动选择可靠的,最佳的,动态的路由选择,自动识别相邻的路由设备
Calico不能使用overlay,也不需要交换,直接通过虚拟路由实现,每一台虚拟路由都通过BGP转发
核心组件:
Felix:也是运行在主机上的一个个pod,一个进程,k8s daemonset的方式部署的pod
Daemont set会在每个node节点部署相同的pod,后台的运行方式
负责在宿主机上插入路由规则,维护calico需要的网络设备,网络接口的管理,监听,路由转发等等
BGP Client: bird BGP的客户端,专门负责在集群当中转发路由规则的信息,每一个节点都会有一个BGP Client
BGP协议广播的方式通知其他节点的,分发路由的规则,实现网络互通
ETCD:报错路由信息,负责网络元数据的一致性,元数据就是保证网络状态的一致性和准确
Calico的工作原理:
路由表来维护每个pod之间的通信,一旦创建好pod之后,会添加一个设备cali 也试试veth pair设备,比如说虚拟网卡:veth pair是一对设备,虚拟的以太网设备,一头连接在容器的网络命名空间,另一头连接网络宿主机的网络命名空间,名字叫做cali
这个设备的作用:IP地址的分配,veth pair连接容器的部分给容器分配一个IP地址,这个IP地址是一个唯一的标识,宿主机也会被这个veth pair分配一个calico网络的内部IP地址,和其他节点上的容器进行通信
Veth设备,容器发出的IP地址通过veth pair设备到宿主机,宿主机就根据路由规则的下一跳地址发送到网关(目标宿主机)
数据包到达目标宿主机,veth pair设备,目标宿主机也是根据路由规则,下一跳地址,转发到目标容器
原理图:
Ipip模式:会生成一个tunnel,数据包都在tunnel内部打包,封装:宿主机IP 容器内部得分IP地址
实验部分:
#上传 calico.yaml 文件到 /opt/k8s 目录中,部署 CNI 网络
cd /opt/k8s
vim calico.yaml
#修改里面定义 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
搜索
改为:
运行yml文件
kubectl apply -f calico.yaml
kubectl get pods -n kube-system
多刷新几下#等 Calico Pod 都 Running,节点也会准备就绪
kubectl get pods -n kube-system
ifconfig 查看node1 node2
已完成
kubectl create deployment nginx1 --image=nginx:1.22 --replicas=3
kubectl get pod
创建完成
kubectl get pods -n kube-system
查看详细信息
kubectl get pod -o wide
ip route
再次演示
kubectl create deployment httpd --image=nginx:1.22 --replicas=3
kubectl get pod
kubectl delete deployments httpd
添加http后就会生成一个路由条目
总结:
Flannel和calico:
Flannel:配置简单,功能简单,基于overlay叠加网络实现,在物理层的网络上再封装一个虚拟的网络,
vxlan是虚拟三层网络,UDP模式是默认不用的,常用的就是vxlan模式,IP进行转发,Fannel提供路由表,内核封装和解封装
host-gw也是不用的,由于封装和解封装的过程,对数据传输可能会有影响,没有网络策略配置的能力UDP(协议)默认网段:10.244.0.0/16
Calicao:功能强大
,基于路由表进行转发,没有封装和解封装的过程,具备网络策略的配置能力,但是路由表维护起来复杂
模式:ipip BGP
BGP:通过为IP路由表的前缀来实现目标主机的可达性
对比ipip模式,BGP模式没有隧道,BGP模式下,pod的数据包直接通过网卡发送到目的地
Ipip的隧道:在隧道进行数据包的封装IP---ipv4
简单的小集群:使用flannel
如果也会要扩容,那配置的网络策略:calico
Coredns:
可以集群当中的service资源创建一个域名和IP进行对应解析的关系。
Service是对外提供访问的一个地址,现在我们加入DNS机制之后,可以直接访问他的服务名
kubectl get pod
kubectl expose deployment nginx1 --port=30000 --target-port=80 --name=nginx-server
kubectl get svc
//在所有 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
#DNS 解析测试
kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous
kubectl run -it --rm dns-test --image=busybox:1.28.4 sh
If you don't see a command prompt, try pressing enter.
/ # nslookup kubernetes
Server: 10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local
Name: kubernetes
Address 1: 10.0.0.1 kubernetes.default.svc.cluster.local
exit
kubectl edit svc nginx-server
kubectl get svc
部署多节点,部署master2:
映射(全部,除了两台nginx)
20.0.0.71 master01
20.0.0.72 node01
20.0.0.73 node02
20.0.0.74 master02
内核优化
vim /etc/sysctl.d/k8s.conf
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
sysctl --system
时间同步
yum install ntpdate -y
ntpdate ntp.aliyun.com
//从 master01 节点上拷贝证书文件、各master组件的配置文件和服务管理文件到 master02 节点
scp -r /opt/etcd/ root@20.0.0.74:/opt/
scp -r /opt/kubernetes/ root@20.0.0.74:/opt
scp -r /root/.kube root@20.0.0.74:/root
scp /usr/lib/systemd/system/{kube-apiserver,kube-controller-manager,kube-scheduler}.service root@20.0.0.73:/usr/lib/systemd/system/
Master02:
//修改配置文件kube-apiserver中的IP
vim /opt/kubernetes/cfg/kube-apiserver
KUBE_APISERVER_OPTS="--logtostderr=true \
--v=4 \
--etcd-servers=https://192.168.233.91:2379,https://192.168.233.93:2379,https://192.168.233.94:2379 \
--bind-address=192.168.233.92 \ #修改
--secure-port=6443 \
--advertise-address=192.168.233.92 \ #修改
......
//在 master02 节点上启动各服务并设置开机自启
systemctl start kube-apiserver.service
systemctl enable kube-apiserver.service
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 #-o=wide:输出额外信息;对于Pod,将输出Pod所在的Node名
//此时在master02节点查到的node节点状态仅是从etcd查询到的信息,
而此时node节点实际上并未与master02节点建立通信连接,因此需要使用一个VIP把node节点与master节点都关联起来
软连接
完成
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.233.91:6443;
server 192.168.233.92:6443;
}
server {
listen 6443;
proxy_pass k8s-apiserver;
}
}
http {
......
另一边的nginx同样的操作
//检查配置文件语法
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.233.100/24 #指定 VIP
}
track_script {
check_nginx #指定vrrp_script配置的脚本
}
}
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
vrrp_skip_check_adv_addr
# vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script check_nginx {
script "/etc/nginx/check_nginx.sh"
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
20.0.0.100/24
}
track_script {
check_nginx
}
}
设置时间
//创建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是否生成
同样的配置从(稍稍微修改)
! 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_BACKUP
vrrp_skip_check_adv_addr
# vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script check_nginx {
script "/etc/nginx/check_nginx.sh"
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
20.0.0.100/24
}
track_script {
check_nginx
}
}
先起nginx,再起keepalived
测试主恢复之后,要先启动nginx在启动keepalived
systemctl start nginx
systemctl restart keepalived.service
Node1,2
//修改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
重启
//在 lb01 上查看 nginx 和 node 、 master 节点的连接状态
netstat -natp | grep nginx
测试
从节点查看
//测试创建pod
kubectl run nginx --image=nginx
//查看Pod的状态信息
kubectl get pods
kubectl get pods -o wide
//在对应网段的node节点上操作,可以直接使用浏览器或者curl命令访问
curl 172.17.36.2
kubectl exec -it nginx bash
//这时在master01节点上查看nginx日志
kubectl logs nginx-dbddb74b8-nf9sk
Dashboard:
仪表盘,就是kubenetes的可视化界面,在这个可视化界面上,可以对k8s集群化管理
//在 master01 节点上操作
#上传 recommended.yaml 文件到 /opt/k8s 目录中
cd /opt/k8s
vim 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://20.0.0.73:30001