k8s中的通信模式

1、pod内部之间容器与容器之间的通信,在同一个pod 中的容器共享资源和网络,使用同一个网络命名空间,可以直接通信的

2、同一个node节点之内,不同pod之间的通信,每个pod都有一个全局的真实的IP地址,同一个node直接的不同pod可以直接使用对方pod的IP地址通信

pod1和pod2是通过docker0的网桥来进行通信

3、不同node节点的上的pod之间如何进行通信?

cni的插件

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

flannel插件:功能就是让集群之中不同节点的docker容器具有全集群唯一的虚拟IP地址

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

flannel支持的数据转发方式

1、UDP模式,默认模式,应用转发,配置简单,但是性能最差

2、vlan,基于内核转发,也是最常用的网络类型(一般都是小集群)

3、host-gw(性能最好,但是配置麻烦)

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

node都会有一个flannel的虚拟网卡

k8s nodeport 多个pod 负载均衡 k8s实现负载均衡_kubernetes

vxlan:使用的就是overlay的虚拟隧道通信技术,二层+三层的模式

upd基于应用层,用户态

vxlan:flannel提供路由表,内核封装解封装

k8s nodeport 多个pod 负载均衡 k8s实现负载均衡_负载均衡_02

在 node01 节点上操作
#上传 cni-plugins-linux-amd64-v0.8.6.tgz 和 flannel.tar 到 /opt 目录中
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

//在 master01 节点上操作
#上传 kube-flannel.yml 文件到 /opt/k8s 目录中,部署 CNI 网络
cd /opt/k8s
kubectl apply -f kube-flannel.yml 

kubectl get pods -n kube-system
NAME                    READY   STATUS    RESTARTS   AGE
kube-flannel-ds-hjtc7   1/1     Running   0          7s

kubectl get nodes
NAME            STATUS   ROLES    AGE   VERSION
192.168.80.11   Ready    <none>   81m   v1.20.11

flannel:每个发向容器的数据包进行封装,vxlan通过vtep打包数据,由内核封装成数据包----转发目标的node节点---到了目标node节点,还有一个解封装的过程,再发送目标pod,性能是有一定影响的

Calico插件

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

BGP模式的特点:交换路由信息的外部网关协议,可以连接不同的node节点,node节点可能不是一个网段,BGP实现可靠的,最佳的,而且是动态的路由选择,自动识别相邻的路由设备

calico不使用overlay,也不需要交换,直接通过虚拟路由实现,每台虚拟路由都通过BGP

核心组件

felix:也是运行在主机中的一个个pod,一个进程,k8s daemont set 会在每个node节点部署相同的pod,后台的运行方式

负载宿主机上插入路由规则,维护calico需要的网络设备,网络接口管理,监听,路由等等

BGP client:bird BGP的客户端,专门负责在集群中分发在集群中分发路由规则的信息,每一个节点都会有一个BGP client

BGP协议广播方式通知其他节点的,分发路由的规则,实现网络互通

etcd 报讯路由信息,负责网络元数据的一致性,保证网络状态的一致和准确

calico的工作原理

路由表来维护每个pod之间的通信,创建好pod之后,添加一个设备cali veth pair设备

虚拟网卡:veth pair 是一对设备,虚拟的以太网设备

一头连接在容器的网络命名空间eth0

另一头连接宿主机的网络命名空间 cali

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

veth设备,容器发出的IP地址通过veth pair设备到宿主机,宿主机根据路由规则的下一跳,发送到网关(目标宿主机)

数据包到达目标宿主机,veth pair设备,目标宿主机噎死根据路由规则,下一跳地址,转发到目标容器

ipip模式:会生成一个tunnel,数据包都在tunnel内部打包,封装:宿主机ip 容器内部的IP地址

部署calico
在 master01 节点上操作
#上传 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
  
kubectl apply -f calico.yaml

kubectl get pods -n kube-system
NAME                                       READY   STATUS    RESTARTS   AGE
calico-kube-controllers-659bd7879c-4h8vk   1/1     Running   0          58s
calico-node-nsm6b                          1/1     Running   0          58s
calico-node-tdt8v                          1/1     Running   0          58s

#等 Calico Pod 都 Running,节点也会准备就绪
kubectl get nodes

在 node01 节点上操作
cd /opt/
scp kubelet.sh proxy.sh root@192.168.233.93:/opt/
scp kubelet.sh proxy.sh root@192.168.233.94:/opt/
scp -r /opt/cni root@192.168.233.93:/opt/
scp -r /opt/cni root@192.168.233.94:/opt/
//在 node02 节点上操作
#启动kubelet服务
cd /opt/
chmod +x kubelet.sh
./kubelet.sh 192.168.233.94

//在 master01 节点上操作
kubectl get csr
NAME                                                   AGE  SIGNERNAME                                    REQUESTOR           CONDITION
node-csr-BbqEh6LvhD4R6YdDUeEPthkb6T_CJDcpVsmdvnh81y0   10s  kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending
node-csr-duiobEzQ0R93HsULoS9NT9JaQylMmid_nBF3Ei3NtFE   85m  kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Approved,Issued

#通过 CSR 请求
kubectl certificate approve node-csr-BbqEh6LvhD4R6YdDUeEPthkb6T_CJDcpVsmdvnh81y0

kubectl get csr
NAME                                                   AGE  SIGNERNAME                                    REQUESTOR           CONDITION
node-csr-BbqEh6LvhD4R6YdDUeEPthkb6T_CJDcpVsmdvnh81y0   23s  kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Approved,Issued
node-csr-duiobEzQ0R93HsULoS9NT9JaQylMmid_nBF3Ei3NtFE   85m  kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Approved,Issued

#加载 ipvs 模块
for i in $(ls /usr/lib/modules/$(uname -r)/kernel/net/netfilter/ipvs|grep -o "^[^.]*");do echo $i; /sbin/modinfo -F filename $i >/dev/null 2>&1 && /sbin/modprobe $i;done

#使用proxy.sh脚本启动proxy服务
cd /opt/
chmod +x proxy.sh
./proxy.sh 192.168.233.94

#查看群集中的节点状态
kubectl get nodes
coredns

可以集群当中的service资源创建一个域名和ip进行对应解析的关系

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

部署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 
NAME                          READY   STATUS    RESTARTS   AGE
coredns-5ffbfd976d-j6shb      1/1     Running   0          32s

#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
部署msater02
从 master01 节点上拷贝证书文件、各master组件的配置文件和服务管理文件到 master02 节点
scp -r /opt/etcd/ root@20.0.0.71:/opt/
scp -r /opt/kubernetes/ root@20.0.0.71:/opt
scp -r /root/.kube root@20.0.0.71:/root
scp /usr/lib/systemd/system/{kube-apiserver,kube-controller-manager,kube-scheduler}.service root@20.0.0.71:/usr/lib/systemd/system/

//修改配置文件kube-apiserver中的IP
vim /opt/kubernetes/cfg/kube-apiserver

KUBE_APISERVER_OPTS="--logtostderr=false  \
--v=2 \
--log-dir=/opt/kubernetes/logs \
--etcd-servers=https://20.0.0.70:2379,https://20.0.0.72:2379,https://20.0.0.73:2379 \
--bind-address=20.0.0.71 \
--secure-port=6443 \
--advertise-address=20.0.0.71 \
--allow-privileged=true \
--service-cluster-ip-range=10.0.0.0/24 \
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \
--authorization-mode=RBAC,Node \
--enable-bootstrap-token-auth=true \
--token-auth-file=/opt/kubernetes/cfg/token.csv \
--service-node-port-range=30000-50000 \
--kubelet-client-certificate=/opt/kubernetes/ssl/apiserver.pem \
--kubelet-client-key=/opt/kubernetes/ssl/apiserver-key.pem \
--tls-cert-file=/opt/kubernetes/ssl/apiserver.pem  \
--tls-private-key-file=/opt/kubernetes/ssl/apiserver-key.pem \
--client-ca-file=/opt/kubernetes/ssl/ca.pem \
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \
--service-account-issuer=api \
--service-account-signing-key-file=/opt/kubernetes/ssl/apiserver-key.pem \
--etcd-cafile=/opt/etcd/ssl/ca.pem \
--etcd-certfile=/opt/etcd/ssl/server.pem \
--etcd-keyfile=/opt/etcd/ssl/server-key.pem \
--requestheader-client-ca-file=/opt/kubernetes/ssl/ca.pem \
--proxy-client-cert-file=/opt/kubernetes/ssl/apiserver.pem \
--proxy-client-key-file=/opt/kubernetes/ssl/apiserver-key.pem \
--requestheader-allowed-names=kubernetes \
--requestheader-extra-headers-prefix=X-Remote-Extra- \
--requestheader-group-headers=X-Remote-Group \
--requestheader-username-headers=X-Remote-User \
--enable-aggregator-routing=true \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/opt/kubernetes/logs/k8s-audit.log"

......

//在 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节点都关联起来
负载均衡部署
配置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
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 20.0.0.70:6443;
        server 20.0.0.71:6443;
    }
    server {
        listen 6443;
        proxy_pass k8s-apiserver;
    }
}

检查配置文件语法
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
   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"
    interval 5
}
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
    }
}

从
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_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"
    interval 5
}
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状态检查脚本 
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 addr				#查看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

tcp        0      0 0.0.0.0:6443            0.0.0.0:*               LISTEN      4141/nginx: master  
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      4141/nginx: master  
tcp        0      0 20.0.0.74:43860         20.0.0.71:6443          ESTABLISHED 4142/nginx: worker  
tcp        0      0 20.0.0.100:6443         20.0.0.73:47114         ESTABLISHED 4142/nginx: worker  
tcp        0      0 20.0.0.74:43848         20.0.0.71:6443          ESTABLISHED 4142/nginx: worker  
tcp        0      0 20.0.0.100:6443         20.0.0.72:50436         ESTABLISHED 4142/nginx: worker  
tcp        0      0 20.0.0.100:6443         20.0.0.72:50444         ESTABLISHED 4143/nginx: worker  
tcp        0      0 20.0.0.100:6443         20.0.0.72:50474         ESTABLISHED 4143/nginx: worker  
tcp        0      0 20.0.0.74:43870         20.0.0.71:6443          ESTABLISHED 4143/nginx: worker  
tcp        0      0 20.0.0.74:52370         20.0.0.70:6443          ESTABLISHED 4142/nginx: worker  
tcp        0      0 20.0.0.100:6443         20.0.0.72:50446         ESTABLISHED 4142/nginx: worker  
tcp        0      0 20.0.0.100:6443         20.0.0.72:50420         ESTABLISHED 4143/nginx: worker  
tcp        0      0 20.0.0.100:6443         20.0.0.73:47112         ESTABLISHED 4142/nginx: worker  
tcp        0      0 20.0.0.74:43842         20.0.0.71:6443          ESTABLISHED 4143/nginx: worker  
tcp        0      0 20.0.0.100:6443         20.0.0.72:50438         ESTABLISHED 4142/nginx: worker  
tcp        0      0 20.0.0.100:6443         20.0.0.73:47090         ESTABLISHED 4142/nginx: worker  
tcp        0      0 20.0.0.100:6443         20.0.0.72:50448         ESTABLISHED 4143/nginx: worker  
tcp        0      0 20.0.0.74:43838         20.0.0.71:6443          ESTABLISHED 4142/nginx: worker  
tcp        0      0 20.0.0.74:43862         20.0.0.71:6443          ESTABLISHED 4143/nginx: worker  
tcp        0      0 20.0.0.74:52372         20.0.0.70:6443          ESTABLISHED 4143/nginx: worker  
tcp        0      0 20.0.0.74:52380         20.0.0.70:6443          ESTABLISHED 4142/nginx: worker  
tcp        0      0 20.0.0.74:43852         20.0.0.71:6443          ESTABLISHED 4142/nginx: worker  
tcp        0      0 20.0.0.74:52394         20.0.0.70:6443          ESTABLISHED 4143/nginx: worker  
tcp        0      0 20.0.0.100:6443         20.0.0.73:47128         ESTABLISHED 4143/nginx: worker  
tcp        0      0 20.0.0.100:6443         20.0.0.73:47116         ESTABLISHED 4143/nginx: worker  
tcp        0      0 20.0.0.74:52358         20.0.0.70:6443          ESTABLISHED 4143/nginx: worker  
tcp        0      0 20.0.0.74:52384         20.0.0.70:6443          ESTABLISHED 4142/nginx: worker  
tcp        0      0 20.0.0.100:6443         20.0.0.73:47108         ESTABLISHED 4142/nginx: worker  
tcp        0      0 20.0.0.100:6443         20.0.0.73:47106         ESTABLISHED 4142/nginx: worker  
tcp        0      0 20.0.0.74:52362         20.0.0.70:6443          ESTABLISHED 4142/nginx: worker
 部署 Dashboard 
在 master01 节点上操作
#上传 recommended.yaml 文件到 /opt/k8s 目录中
cd /opt/k8s
vim recommended.yaml
#默认Dashboard只能集群内部访问,修改Service为NodePort类型,暴露到外部:
kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 30001     #添加
  type: NodePort          #添加
  selector:
    k8s-app: kubernetes-dashboard

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.72:30001/#/login

k8s nodeport 多个pod 负载均衡 k8s实现负载均衡_负载均衡_03