当前位置: 首页 > news >正文

2、k8s 二进制安装(详细)

k8s 二进制安装

      • IP规划
      • 初始化
      • 部署 etcd 集群
        • 在 etcd01 节点上操作
          • 准备cfssl证书生成工具,加权
          • 生成etcd证书
          • 上传etcd软件包
          • 启动 etcd 服务
      • 部署 Master 组件
      • 部署 Worker Node 组件
        • node 节点安装 docker
        • 部署组件
      • 部署 CNI 网络组件
        • 部署 flannel
          • 简介
          • 部署
        • 部署 Calico
          • 简介
          • 部署
      • 部署 CoreDNS
      • master02 节点部署
      • 负载均衡部署
      • 部署 Dashboard

IP规划

主机名IP
master01192.168.110.10
master01192.168.110.40
node01192.168.110.20
node02192.168.110.30
etcd01/lb01192.168.110.50
etcd02/lb02192.168.110.60
etcd03192.168.110.70

初始化

#关闭防火墙和核心防护
systemctl stop firewalld
systemctl disable firewalld
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
setenforce 0
sed -i 's/enforcing/disabled/' /etc/selinux/config#设置主机名
hostnamectl set-hostname master01
su#在master添加hosts
cat >> /etc/hosts << EOF
192.168.110.10 master01
192.168.110.40 master02
192.168.110.20 node01
192.168.110.30 node02
192.168.110.50 etcd01
192.168.110.60 etcd02
192.168.110.70 etcd03
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
EOFsysctl --system#时间同步
yum install ntpdate -y
ntpdate time.windows.com

部署 etcd 集群

etcd是一个分布式键值存储系统,用于在分布式系统中保存配置信息、元数据以及关键的共享状态。它是一个开源项目,最初由CoreOS开发并维护,现在由CNCF托管。etcd的设计目标是提供可靠的分布式存储,以支持分布式系统的一致性和高可用性。
etcd 目前默认使用2379端口提供HTTP API服务, 2380端口和peer通信(这两个端口已经被IANA(互联网数字分配机构)官方预留给etcd)。 即etcd默认使用2379端口对外为客户端提供通讯,使用端口2380来进行服务器间内部通讯。
etcd 在生产环境中一般推荐集群方式部署。由于etcd 的leader选举机制,要求至少为3台或以上的奇数台。

在 etcd01 节点上操作
准备cfssl证书生成工具,加权
#方法一,下载
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -O /usr/local/bin/cfssl
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -O /usr/local/bin/cfssljson
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -O /usr/local/bin/cfssl-certinfo
chmod +x /usr/local/bin/cfssl*#方法二,上传已有压缩包 etcd.zip 到 /root
unzip etcd.zip
cd etcd/cfssl/
mv cfssl* /usr/local/bin/
chmod +x /usr/local/bin/cfssl*
生成etcd证书
#创建工作目录
mkdir /opt/k8s#上传 etcd-cert.sh 和 etcd.sh 到 /opt/k8s/ 目录中
cd ~/etcd/
mv etcd-cert.sh  etcd.sh /opt/k8s
cd /opt/k8s
chmod +x etcd-cert.sh etcd.sh#创建用于生成CA证书、etcd 服务器证书以及私钥的目录
mkdir /opt/k8s/etcd-cert
mv etcd-cert.sh etcd-cert/
cd /opt/k8s/etcd-cert/
./etcd-cert.sh#生成的证书
ls
ca-config.json  ca-csr.json  ca.pem        server.csr       server-key.pem
ca.csr          ca-key.pem   etcd-cert.sh  server-csr.json  server.pem
上传etcd软件包
#上传 etcd-v3.4.26-linux-amd64.tar.gz 到 /opt/k8s 目录中
tar -xf etcd-v3.4.26-linux-amd64.tar.gz
cd /opt/k8sls etcd-v3.4.26-linux-amd64
Documentation  etcd  etcdctl  README-etcdctl.md  README.md  READMEv2-etcdctl.md
启动 etcd 服务
#创建用于存放 etcd 配置文件,命令文件,证书的目录
mkdir -p /opt/etcd/{cfg,bin,ssl}cd etcd-v3.4.26-linux-amd64
mv etcd etcdctl /opt/etcd/bin/
cp /opt/k8s/etcd-cert/*.pem /opt/etcd/ssl/#进入卡住状态等待其他节点加入,这里需要三台etcd服务同时启动,如果只启动其中一台后,服务会卡在那里,直到集群中所有etcd节点都已启动,可忽略这个情况
cd /opt/k8s/
./etcd.sh etcd01 192.168.110.50 etcd02=https://192.168.110.60:2380,etcd03=https://192.168.110.70:2380#可另外打开一个窗口查看etcd进程是否正常
ps -ef | grep etcd

把etcd相关证书文件、命令文件和服务管理文件全部拷贝到另外两个etcd集群节点

scp -r /opt/etcd/ root@192.168.110.60:/opt/
scp -r /opt/etcd/ root@192.168.110.70:/opt/
scp /usr/lib/systemd/system/etcd.service root@192.168.110.60:/usr/lib/systemd/system/
scp /usr/lib/systemd/system/etcd.service root@192.168.110.70:/usr/lib/systemd/system/

etcd02 节点上操作

vim /opt/etcd/cfg/etcd
#[Member]
ETCD_NAME="etcd02"											#修改
ETCD_DATA_DIR="/var/lib/etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.110.60:2380"			#修改
ETCD_LISTEN_CLIENT_URLS="https://192.168.110.60:2379"		#修改#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.110.60:2380"		#修改
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.110.60:2379"				#修改
ETCD_INITIAL_CLUSTER="etcd01=https://192.168.110.50:2380,etcd02=https://192.168.110.60:2380,etcd03=https://192.168.110.70:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"#启动etcd服务
systemctl start etcd
systemctl enable etcd
systemctl status etcd#检查etcd群集状态
ETCDCTL_API=3 /opt/etcd/bin/etcdctl --endpoints="https://192.168.110.50:2379,https://192.168.110.60:2379,https://192.168.110.70:2379" --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem  endpoint health --write-out=table#查看当前的 leader
ETCDCTL_API=3 /opt/etcd/bin/etcdctl --endpoints="https://192.168.110.50:2379,https://192.168.110.60:2379,https://192.168.110.60:2379" --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem  endpoint status --write-out=table

etcd03 节点操作同 etcd02

部署 Master 组件

安装 apiserver 服务,controller-manager 服务,scheduler 服务和kubectl 工具

在 etcd01 上操作

#将 cfssl 工具传到master01
scp /usr/local/bin/cfssl* 192.168.110.10:/usr/local/bin/

在 master01 上操作

#创建 /opt/k8s/ 目录上传 master.zip 并解压
mkdir /opt/k8s/
cd /opt/k8s/
unzip master.zip
chmod +x *.sh[root@master01 k8s]# ls
admin.sh  apiserver.sh  controller-manager.sh  master.zip  scheduler.sh#创建kubernetes工作目录
mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}#创建用于生成CA证书、相关组件的证书和私钥的目录,上传 k8s-cert.sh
mkdir /opt/k8s/k8s-cert
mv /opt/k8s/k8s-cert.sh /opt/k8s/k8s-cert
cd /opt/k8s/k8s-cert/
./k8s-cert.sh[root@master01 k8s-cert]# ls *pem
admin-key.pem  apiserver-key.pem  ca-key.pem  kube-proxy-key.pem
admin.pem      apiserver.pem      ca.pem      kube-proxy.pem#复制CA证书、apiserver相关证书和私钥到 kubernetes工作目录的 ssl 子目录中
cp ca*pem apiserver*pem /opt/kubernetes/ssl/#上传 kubernetes-server-linux-amd64.tar.gz 到 /opt/k8s/ 目录中,解压 kubernetes 压缩包
cd /opt/k8s/
tar zxvf kubernetes-server-linux-amd64.tar.gz#复制master组件的关键命令文件到 kubernetes工作目录的 bin 子目录中
cd /opt/k8s/kubernetes/server/bin
cp kube-apiserver kubectl kube-controller-manager kube-scheduler /opt/kubernetes/bin/
ln -s /opt/kubernetes/bin/* /usr/local/bin/#创建 bootstrap token 认证文件,apiserver 启动时会调用,然后就相当于在集群内创建了一个这个用户,接下来就可以用 RBAC 给他授权
cd /opt/k8s/
vim token.sh
#!/bin/bash
#获取随机数前16个字节内容,以十六进制格式输出,并删除其中空格
BOOTSTRAP_TOKEN=$(head -c 16 /dev/urandom | od -An -t x | tr -d ' ')
#生成 token.csv 文件,按照 Token序列号,用户名,UID,用户组 的格式生成
cat > /opt/kubernetes/cfg/token.csv <<EOF
${BOOTSTRAP_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOFchmod +x token.sh
./token.sh
cat /opt/kubernetes/cfg/token.csv#在 master01 节点
mkdir /opt/etcd/ssl/ -p
#在 etcd 节点
cd /opt/etcd/ssl/
scp * 192.168.110.10:`pwd`
#在 master01 节点
[root@master01 k8s]# ls  /opt/etcd/ssl/
ca-key.pem  ca.pem  server-key.pem  server.pem
#二进制文件、token、证书都准备好后,开启 apiserver 服务(修改 apiserver.sh 脚本里 ip)
cd /opt/k8s/
./apiserver.sh 192.168.110.10 https://192.168.110.50:2379,https://192.168.110.60:2379,https://192.168.110.70:2379
#检查进程是否启动成功
ps aux | grep kube-apiserver
netstat -natp | grep 6443   #安全端口6443用于接收HTTPS请求,用于基于Token文件或客户端证书等认证#启动 scheduler 服务(修改 KUBE_APISERVER 的IP)
cd /opt/k8s/
./scheduler.sh
ps aux | grep kube-scheduler#启动 controller-manager 服务(修改 KUBE_APISERVER 的IP)
./controller-manager.sh
ps aux | grep kube-controller-manager#生成kubectl连接集群的kubeconfig文件(修改 KUBE_APISERVER 的IP)
./admin.sh#通过kubectl工具查看当前集群组件状态
kubectl get cs
#查看版本信息
kubectl version
#查看当前的 leader
kubectl -n kube-system get leases kube-scheduler
kubectl -n kube-system get leases kube-controller-manager

部署 Worker Node 组件

安装kubelet,kube-proxy 和 docker

node 节点安装 docker
yum install -y yum-utils device-mapper-persistent-data lvm2 
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 
yum install -y docker-ce docker-ce-cli containerd.iomkdir /etc/docker
cat > /etc/docker/daemon.json <<EOF
{"registry-mirrors": ["https://docker.m.daocloud.io", "https://docker.1panel.live"],"exec-opts": ["native.cgroupdriver=systemd"],"log-driver": "json-file","log-opts": {"max-size": "1g", "max-file": "3"}
}
EOFsystemctl start docker.service
systemctl enable docker.service docker info | grep "Cgroup Driver"
部署组件
#创建kubernetes工作目录
mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}#上传 node.zip 到 /opt 目录中,解压 node.zip 压缩包,获得kubelet.sh、proxy.sh
cd /opt/
unzip node.zip
chmod +x kubelet.sh proxy.sh#在 master01 节点上操作
#把 kubelet、kube-proxy 拷贝到 node 节点
cd /opt/k8s/kubernetes/server/bin
scp kubelet kube-proxy root@192.168.110.20:/opt/kubernetes/bin/
scp kubelet kube-proxy root@192.168.110.30:/opt/kubernetes/bin/
#上传kubeconfig.sh文件到/opt/k8s/kubeconfig目录中,生成kubelet初次加入集群引导kubeconfig文件和kube-proxy.kubeconfig文件
#kubeconfig 文件包含集群参数(CA 证书、API Server 地址),客户端参数(上面生成的证书和私钥),集群 context 上下文参数(集群名称、用户名)。Kubenetes 组件(如 kubelet、kube-proxy)通过启动时指定不同的 kubeconfig 文件可以切换到不同的集群,连接到 apiserver。
mkdir /opt/k8s/kubeconfig 
cd /opt/k8s/kubeconfig
chmod +x kubeconfig.sh
./kubeconfig.sh 192.168.110.10 /opt/k8s/k8s-cert/
#把配置文件 bootstrap.kubeconfig、kube-proxy.kubeconfig 拷贝到 node 节点
scp bootstrap.kubeconfig kube-proxy.kubeconfig root@192.168.110.20:/opt/kubernetes/cfg/
scp bootstrap.kubeconfig kube-proxy.kubeconfig root@192.168.110.30:/opt/kubernetes/cfg/
#RBAC授权,使用户 kubelet-bootstrap 能够有权限发起 CSR 请求证书
kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap
#自动批准 CSR 请求
kubectl create clusterrolebinding node-autoapprove-bootstrap --clusterrole=system:certificates.k8s.io:certificatesigningrequests:nodeclient --user=kubelet-bootstrap 
kubectl create clusterrolebinding node-autoapprove-certificate-rotation --clusterrole=system:certificates.k8s.io:certificatesigningrequests:selfnodeclient --user=kubelet-bootstrap#在 node01 节点上操作
#启动 kubelet 服务
cd /opt/
./kubelet.sh 192.168.110.20
ps aux | grep kubelet
//在 master01 节点上操作,通过 CSR 请求
#检查到 node01 节点的 kubelet 发起的 CSR 请求,Pending 表示等待集群给该节点签发证书
kubectl get csr
[root@master01 kubeconfig]# kubectl get csr
NAME                                                   AGE   SIGNERNAME                                    REQUESTOR           CONDITION
node-csr-HD7lIMBUCLneSmDmaoDwXpe_FWJ75FylZ1iWGR69o2s   65s   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Approved,Issued
#通过 CSR 请求
kubectl certificate approve node-csr-HD7lIMBUCLneSmDmaoDwXpe_FWJ75FylZ1iWGR69o2s
#Approved,Issued 表示已授权 CSR 请求并签发证书
kubectl get csr
NAME                                                   AGE  SIGNERNAME                                    REQUESTOR           CONDITION
node-csr-duiobEzQ0R93HsULoS9NT9JaQylMmid_nBF3Ei3NtFE   2m5s kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Approved,Issued
#查看节点,由于网络插件还没有部署,节点会没有准备就绪 NotReady
[root@master01 kubeconfig]# kubectl get node
NAME             STATUS     ROLES    AGE   VERSION
192.168.110.20   NotReady   <none>   97m   v1.20.15//在 node01 节点上操作
#加载 ip_vs 模块
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服务
cd /opt/
./proxy.sh 192.168.110.20
ps aux | grep kube-proxy

在 node02 节点操作同 node01

部署 CNI 网络组件

部署 flannel
简介

Flannel 的功能是让集群中的不同节点主机创建的 Docker 容器都具有全集群唯一的虚拟 IP 地址。
Flannel 是 Overlay 网络的一种,也是将 TCP 源数据包封装在另一种网络包里面进行路由转发和通信,目前支持 UDP、VXLAN、Host-gw 3种数据转发方式。

Flannel UDP 模式的工作原理:
1、数据从主机A 上 Pod 的源容器中发出后,经由所在主机的 cni0 网桥转发到 flannel0 接口,flanneld 服务监听在 flannel0 接口的另外一端。
2、发送给 flannel0 接口的 IP 包信息将被 flanneld 进程接收,flanneld 进程接收 IP 包后在原有的基础上进行 UDP 封包
3、Flannel 通过 etcd 服务维护了一张节点间的路由表。目标容器所在宿主机的 IP 地址,flanneld 通过查询 etcd 很容易就能得到
4、flanneld 将封装好的 UDP 报文通过节点网络发往在主机B 监听 8285 端口的 flanneld 进程
5、运行在主机B 上的 flanneld 将 UDP 报文解包后得到原始 IP 包,内核通过查询本机路由表将该 IP 包转发给 cni0 网桥
6、cni0 网桥将 IP 包转发给连接在网桥上的目标Pod。至此整个流程结束。回程报文将按照上面的数据流原路返回

由于在 UDP 模式下 flanneld 进行网络的封包和解包工作,而 VXLAN 模式下封包解包的工作由内核完成,因此性能上 UDP 模式会比在内核态做转发的 VXLAN 模式差。

VXLAN 模式是 Flannel 默认和推荐的模式,flannel 会为每个节点分配一个 24 位子网,并在每个节点上创建两张虚机网卡:cni0 和 flannel.1 。 cni0 是一个网桥设备,类似于 docker0 ,节点上所有的 Pod 都通过 veth pair 的形式与 cni0 相连。 flannel.1 则是一个 VXLAN 类型的设备,充当 VTEP 设备(VXLAN Tunnel Endpoint)的角色,实现对 VXLAN 报文的封包解包。
在 VXLAN 模式下,flanneld 启动时先确保 VXLAN 设备已存在,如果不存在则创建,存在则跳过。并将 VTEP 设备的信息上报到 etcd 中,当 flannel 网络有新节点加入并向 etcd 注册时, 会在其它节点添加路由规则。
UDP 模式的 flannel0 网卡是三层转发,使用 flannel0 是在物理网络之上构建三层网络,属于 ip in udp ;VXLAN 模式是二层实现,overlay 是数据帧,属于 mac in udp 。

Flannel VXLAN 模式跨主机的工作原理:
1、数据包从主机 A 上 Pod 的源容器中发出后,经由所在主机的 cni0 网络接口转发到 flannel.1 设备
2、flannel.1 收到数据包后,在内核态为数据包添加以太网头部(目的 MAC 地址为目的 flannel.1 设备的 MAC 地址)和 VXLAN 头部,再将此数据帧进行 UDP 封装
3、flannel.1 通过查询本机的 FDB 转发数据库获取目的 flannel.1 设备对应的宿主机 IP 地址
4、通过节点网络将 UDP 报文发往在主机B 监听 8472 端口的 flannel.1 设备,并在内核态进行解封装,获取原始数据包
5、根据解包后得到的原始数据包中的目的IP,flannel.1 将数据包发送给 cni0,最后由 cni0 发送给连接在此接口上的PodB

部署
#在 node01 节点上操作
#上传 cni-plugins-linux-amd64-v1.3.0.tgz 和 flannel镜像文件 到 /opt 目录中
cd /opt/
unzip flannel-v0.21.5.zip
docker load -i flannel.tar
docker load -i flannel-cni-plugin.tarmkdir -p /opt/cni/bin
tar zxvf cni-plugins-linux-amd64-v1.3.0.tgz -C /opt/cni/bin#在 master01 节点上操作
#上传 kube-flannel.yml 文件到 /opt/k8s 目录中,部署 CNI 网络
#在 node01 节点上
scp kube-flannel.yml 192.168.110.10:/opt/k8s
#在 master01 节点
cd /opt/k8s
kubectl apply -f kube-flannel.yml 
kubectl get pods -n kube-flannel
kubectl get nodes[root@master01 k8s]# kubectl get pods -n kube-flannel
NAME                    READY   STATUS    RESTARTS   AGE
kube-flannel-ds-m86br   1/1     Running   0          31s
kube-flannel-ds-qkjw9   1/1     Running   0          31s
[root@master01 k8s]# kubectl get nodes
NAME             STATUS   ROLES    AGE    VERSION
192.168.110.20   Ready    <none>   132m   v1.20.15
192.168.110.30   Ready    <none>   22m    v1.20.15#在node上查看flannel.1的端口
ip -d a show flannel.1   
#通过路由信息,看到发送到对端网段的数据包都会经过 flannel.1发出,网关ip也是对端vtep设备的ip地址
route -n                         
#由于flannel.1 通过路由信息已经知道对端vtep的ip地址,通过查询本地arp缓存表,得到目的vtep的mac地址
ip neigh show dev flannel.1    
#flannel.1可以通过查询本机的FDB表获取目的节点主机的ip  
bridge fdb show flannel.1    [root@node01 opt]# ip -d a show flannel.1
8: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default link/ether 9e:33:61:e2:14:9e brd ff:ff:ff:ff:ff:ff promiscuity 0 vxlan id 1 local 192.168.110.20 dev ens33 srcport 0 0 dstport 8472 nolearning ageing 300 noudpcsum noudp6zerocsumtx noudp6zerocsumrx numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 inet 10.244.0.0/32 scope global flannel.1valid_lft forever preferred_lft forever
[root@node01 opt]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.110.2   0.0.0.0         UG    100    0        0 ens33
10.244.1.0      10.244.1.0      255.255.255.0   UG    0      0        0 flannel.1
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.110.0   0.0.0.0         255.255.255.0   U     100    0        0 ens33
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0
[root@node01 opt]# ip neigh show dev flannel.1
10.244.1.0 lladdr 62:c5:6f:ed:55:96 PERMANENT
[root@node01 opt]# bridge fdb show flannel.1
01:00:5e:00:00:01 dev ens33 self permanent
01:00:5e:00:00:fb dev ens33 self permanent
33:33:00:00:00:01 dev ens33 self permanent
01:00:5e:00:00:01 dev virbr0 self permanent
01:00:5e:00:00:fb dev virbr0 self permanent
52:54:00:9c:44:78 dev virbr0-nic master virbr0 permanent
52:54:00:9c:44:78 dev virbr0-nic vlan 1 master virbr0 permanent
33:33:00:00:00:01 dev docker0 self permanent
01:00:5e:00:00:01 dev docker0 self permanent
01:00:5e:00:00:fb dev docker0 self permanent
02:42:1e:24:eb:65 dev docker0 vlan 1 master docker0 permanent
02:42:1e:24:eb:65 dev docker0 master docker0 permanent
33:33:00:00:00:01 dev dummy0 self permanent
33:33:00:00:00:01 dev kube-ipvs0 self permanent
62:c5:6f:ed:55:96 dev flannel.1 dst 192.168.110.30 self permanent
部署 Calico
简介

Calico不使用隧道或NAT来实现转发,而是把每个操作系统的协议栈认为是一个路由器,然后把所有的容器认为是连在这个路由器上的网络终端,在路由器之间跑标准的路由协议——BGP的协议,然后让它们自己去学习这个网络拓扑该如何转发。
它不使用 cni0 网桥,而是通过路由规则把数据包直接发送到目标节点的网卡,所以性能高。

Calico 的模式:
1、IPIP 模式:在原有 IP 报文中封装一个新的 IP 报文,新的 IP 报文中将源地址 IP 和目的地址 IP 都修改为对端宿主机 IP。Calico 默认使用 IPIP 的模式。
2、BGP 模式:将节点做为虚拟路由器通过 BGP 路由协议来实现集群内容器之间的网络访问。
3、cross-subnet(ipip-bgp混合模式):IPIP 模式和 BGP 模式都有对应的局限性,对于一些主机跨子网而又无法使网络设备使用 BGP 的场景可以使用 cross-subnet 模式,实现同子网机器使用 BGP 模式,跨子网机器使用 IPIP 模式。

Calico 工作原理:
IPIP 模式:
Calico 会将容器的 IP 数据包经过 veth pair 设备发送到 tunl0 设备,并被内核的 IPIP 驱动直接封装到宿主机网络的 IP 数据包中,新封装的 IP 数据包再根据 Felix 维护的路由规则发送给目标节点,目标节点通过 IPIP 驱动解包得到原始容器 IP 数据包,然后根据路由规则经过 veth pair 设备送达到目标容器。

BGP 模式:
Calico 是通过路由表来维护每个 Pod 的通信。Calico 的 CNI 插件会为每个容器设置一个 veth pair 设备, 然后把另一端接入到宿主机网络空间,由于没有网桥,CNI 插件还需要在宿主机上为每个容器的 veth pair 设备配置一条路由规则, 用于接收传入的 IP 包。
有了这样的 veth pair 设备以后,容器发出的 IP 包就会通过 veth pair 设备到达宿主机,然后根据容器要访问的IP和宿主机的路由规则,找到下一跳要到达的宿主机 IP。 流量到达下一跳的宿主机后,根据当前宿主机上的路由规则,直接到达对端容器的 veth pair 插在宿主机的一端,最终进入容器。
这些路由规则都是 Felix 维护配置的,而路由信息则是 Calico BIRD 组件基于 BGP 分发而来。
Calico 实际上是将集群里所有的节点都当做边界路由器来处理,他们一起组成了一个全互联的网络,彼此之间通过 BGP 交换路由, 这些节点我们叫做 BGP Peer。

相比IPIP模式,BGP模式下不需要tunl0设备参与报文传输,报文直接通过物理网卡(比如ens33)转发到目标机器上,不会进行二次IP报文的封装,因此从性能上来看,BGP是占优势的。但是由于没有二次封包,BGP模式只能在同一个子网内使用,无法跨网段使用。

部署

在 master01 节点

#上传 calico.yaml 文件到 /opt/k8s 目录中,部署 Calico
#下载地址:curl https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml
cd /opt/k8s
vim calico.yaml#修改里面定义 Pod 的网络(CALICO_IPV4POOL_CIDR),需与前面 kube-controller-manager 配置文件指定的 cluster-cidr 网段一样- name: CALICO_IPV4POOL_CIDRvalue: "10.244.0.0/16"        #Calico 默认使用的网段为 192.168.0.0/16kubectl apply -f calico.yaml
kubectl get pods -n kube-system#等 Calico Pod 都 Running,节点也会准备就绪
kubectl get nodes[root@master01 k8s]# kubectl get pods -n kube-system
NAME                                       READY   STATUS    RESTARTS   AGE
calico-kube-controllers-659bd7879c-khr55   1/1     Running   0          5m6s
calico-node-rf8lf                          1/1     Running   0          5m6s
calico-node-rw5qp                          1/1     Running   0          5m6s
[root@master01 k8s]# kubectl get nodes
NAME             STATUS   ROLES    AGE    VERSION
192.168.110.20   Ready    <none>   147m   v1.20.15
192.168.110.30   Ready    <none>   37m    v1.20.15[root@node02 opt]# ip route
default via 192.168.110.2 dev ens33 proto static metric 100 
10.244.0.0 via 192.168.110.20 dev tunl0 proto bird onlink 
10.244.0.0/24 via 10.244.0.0 dev flannel.1 onlink 
unreachable 10.244.1.0/24 proto bird 
10.244.60.64/26 via 192.168.110.20 dev tunl0 proto bird onlink 
blackhole 10.244.193.64/26 proto bird 
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 
192.168.110.0/24 dev ens33 proto kernel scope link src 192.168.110.30 metric 100 
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1#修改calico的网络模式IPIP变为BGP
kubectl edit ds calico-node -n kube-system
......- name: CALICO_IPV4POOL_IPIPvalue: "Never"                     #设置为Never时为BGP模式,设置为Always时为IPIP模式,设置为Cross-SubNet时为混合模式- name: IP_AUTODETECTION_METHOD      #添加下面两行value: "interface=ens33"           #指定calico使用的网卡kubectl edit ippool ipipMode: Never         #把ipipMode从Always修改成为Never使用BGP模式时,查看IP会发现tunl0没有IP地址了;查看route会发现不再使用tunl0了,而是直接通过物理网卡转发。
ip addr
ip route[root@node01 opt]# ip route
default via 192.168.110.2 dev ens33 proto static metric 100 
10.244.0.0/24 dev cni0 proto kernel scope link src 10.244.0.1 
10.244.1.0 via 192.168.110.30 dev ens33 proto bird 
10.244.1.0/24 via 10.244.1.0 dev flannel.1 onlink 
blackhole 10.244.60.64/26 proto bird 
10.244.193.64/26 via 192.168.110.30 dev ens33 proto bird 
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 
192.168.110.0/24 dev ens33 proto kernel scope link src 192.168.110.20 metric 100 
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1

部署 CoreDNS

CoreDNS:CoreDNS 是 Kubernetes 的默认 DNS 实现。可以为 K8S 集群内的 Pod 提供 DNS 服务。
使用 CoreDNS 可以为集群中的 service 资源创建一个资源名称 与 ClusterIP 的对应关系解析,从而避免将 service 的 ClusterIP 地址硬编码到应用程序代码中。

#在所有 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 [root@master01 k8s]# kubectl get pods -n kube-system 
NAME                                       READY   STATUS    RESTARTS   AGE
calico-kube-controllers-659bd7879c-khr55   1/1     Running   0          30m
calico-node-5lk72                          1/1     Running   0          10m
calico-node-rddmg                          1/1     Running   0          10m
coredns-7f8c5c6967-l2tpc                   1/1     Running   0 #DNS 解析测试
kubectl run -it --rm dns-test --image=busybox:1.28.4 sh[root@master01 k8s]# kubectl run -it --rm dns-test1 --image=busybox sh
If you don't see a command prompt, try pressing enter.
/ # nslookup kubernetes.default.svc.cluster.local.
Server:		10.0.0.2
Address:	10.0.0.2:53Name:	kubernetes.default.svc.cluster.local
Address: 10.0.0.1#若执行失败,可先给kubectl绑定默认cluster-admin管理员集群角色,授权集群操作权限
kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous

master02 节点部署

#从 master01 节点上拷贝证书文件、各master组件的配置文件和服务管理文件到 master02 节点
scp -r /opt/etcd/ root@192.168.110.40:/opt/
scp -r /opt/kubernetes/ root@192.168.110.40:/opt
scp -r /root/.kube root@192.168.110.40:/root
scp /usr/lib/systemd/system/{kube-apiserver,kube-controller-manager,kube-scheduler}.service root@192.168.110.40:/usr/lib/systemd/system/#修改配置文件kube-apiserver中的IP
vim /opt/kubernetes/cfg/kube-apiserver
KUBE_APISERVER_OPTS="--logtostderr=true \
--v=4 \
--etcd-servers=https://192.168.80.10:2379,https://192.168.80.11:2379,https://192.168.80.12:2379 \
--bind-address=192.168.80.20 \				#修改
--secure-port=6443 \
--advertise-address=192.168.80.20 \			#修改
......//在 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名[root@localhost ~]# kubectl get nodes
NAME             STATUS   ROLES    AGE     VERSION
192.168.110.20   Ready    <none>   3h38m   v1.20.15
192.168.110.30   Ready    <none>   108m    v1.20.15
[root@localhost ~]# kubectl get nodes -o wide
NAME             STATUS   ROLES    AGE     VERSION    INTERNAL-IP      EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION          CONTAINER-RUNTIME
192.168.110.20   Ready    <none>   3h38m   v1.20.15   192.168.110.20   <none>        CentOS Linux 7 (Core)   3.10.0-957.el7.x86_64   docker://26.1.4
192.168.110.30   Ready    <none>   108m    v1.20.15   192.168.110.30   <none>        CentOS Linux 7 (Core)   3.10.0-957.el7.x86_64   docker://26.1.4

此时在master02节点查到的node节点状态仅是从etcd查询到的信息,而此时node节点实际上并未与master02节点建立通信连接,因此需要使用一个VIP把node节点与master节点都关联起来

负载均衡部署

配置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
EOFyum 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';access_log  /var/log/nginx/k8s-access.log  main;upstream k8s-apiserver {server 192.168.110.10:6443;server 192.168.110.40: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 keepalivedglobal_defs {# 接收邮件地址notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}# 邮件发送地址notification_email_from Alexandre.Cassen@firewall.locsmtp_server 127.0.0.1smtp_connect_timeout 30router_id NGINX_MASTER	#lb01节点的为 NGINX_MASTER,lb02节点的为 NGINX_BACKUP
}#添加一个周期性执行的脚本
vrrp_script check_nginx {script "/etc/nginx/check_nginx.sh"	#指定检查nginx存活的脚本路径
}vrrp_instance VI_1 {state MASTER			#lb01节点的为 MASTER,lb02节点的为 BACKUPinterface ens33			#指定网卡名称 ens33virtual_router_id 51	#指定vrid,两个节点要一致priority 100			#lb01节点的为 100,lb02节点的为 90advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.80.100/24	#指定 VIP}track_script {check_nginx			#指定vrrp_script配置的脚本}
}#创建nginx状态检查脚本 
vim /etc/nginx/check_nginx.sh
#!/bin/bash
#egrep -cv "grep|$$" 用于过滤掉包含grep 或者 $$ 表示的当前Shell进程ID,即脚本运行的当前进程ID号
count=$(ps -ef | grep nginx | egrep -cv "grep|$$")if [ "$count" -eq 0 ];thensystemctl stop keepalived
fichmod +x /etc/nginx/check_nginx.sh#启动keepalived服务(一定要先启动了nginx服务,再启动keepalived服务)
systemctl start keepalived
systemctl enable keepalived
#lb01上查看VIP是否生成
ip a		[root@etcd01 k8s-cert]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000link/ether 00:0c:29:ef:81:c3 brd ff:ff:ff:ff:ff:ffinet 192.168.110.50/24 brd 192.168.110.255 scope global noprefixroute ens33valid_lft forever preferred_lft foreverinet6 fe80::8c65:44b1:be2a:c9f5/64 scope link noprefixroute valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000link/ether 52:54:00:75:aa:99 brd ff:ff:ff:ff:ff:ffinet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000link/ether 52:54:00:75:aa:99 brd ff:ff:ff:ff:ff:ff#修改node节点上的bootstrap.kubeconfig,kubelet.kubeconfig配置文件为VIP
cd /opt/kubernetes/cfg/
vim bootstrap.kubeconfig 
server: https://192.168.80.100:6443vim kubelet.kubeconfig
server: https://192.168.80.100:6443vim kube-proxy.kubeconfig
server: https://192.168.80.100:6443#重启kubelet和kube-proxy服务
systemctl restart kubelet.service 
systemctl restart kube-proxy.service#在 lb01 上查看 nginx 和 node 、 master 节点的连接状态
netstat -natp | grep nginx[root@etcd01 ~]# netstat -natp | grep nginx
tcp        0      0 0.0.0.0:6443            0.0.0.0:*               LISTEN      9036/nginx: master  
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      9036/nginx: master  
tcp        0      0 192.168.110.50:55238    192.168.110.40:6443     ESTABLISHED 9042/nginx: worker  
tcp        0      0 192.168.110.50:57196    192.168.110.10:6443     ESTABLISHED 9041/nginx: worker  
tcp        0      0 192.168.110.100:6443    192.168.110.20:40392    ESTABLISHED 9042/nginx: worker  
tcp        0      0 192.168.110.100:6443    192.168.110.20:40374    ESTABLISHED 9041/nginx: worker  
tcp        0      0 192.168.110.100:6443    192.168.110.30:41828    ESTABLISHED 9042/nginx: worker  
tcp        0      0 192.168.110.100:6443    192.168.110.30:41824    ESTABLISHED 9043/nginx: worker  
tcp        0      0 192.168.110.100:6443    192.168.110.30:41818    ESTABLISHED 9041/nginx: worker  
tcp        0      0 192.168.110.50:55226    192.168.110.40:6443     ESTABLISHED 9041/nginx: worker  
tcp        0      0 192.168.110.100:6443    192.168.110.30:41820    ESTABLISHED 9043/nginx: worker  
tcp        0      0 192.168.110.100:6443    192.168.110.20:40368    ESTABLISHED 9043/nginx: worker  
tcp        0      0 192.168.110.100:6443    192.168.110.30:41834    ESTABLISHED 9043/nginx: worker  
tcp        0      0 192.168.110.100:6443    192.168.110.30:41822    ESTABLISHED 9042/nginx: worker  
tcp        0      0 192.168.110.50:57254    192.168.110.10:6443     ESTABLISHED 9043/nginx: worker  
tcp        0      0 192.168.110.100:6443    192.168.110.20:40358    ESTABLISHED 9042/nginx: worker  
tcp        0      0 192.168.110.50:55218    192.168.110.40:6443     ESTABLISHED 9043/nginx: worker  
tcp        0      0 192.168.110.100:6443    192.168.110.20:40336    ESTABLISHED 9043/nginx: worker  
tcp        0      0 192.168.110.50:57238    192.168.110.10:6443     ESTABLISHED 9044/nginx: worker  
tcp        0      0 192.168.110.50:57206    192.168.110.10:6443     ESTABLISHED 9043/nginx: worker  
tcp        0      0 192.168.110.50:57198    192.168.110.10:6443     ESTABLISHED 9043/nginx: worker  
tcp        0      0 192.168.110.100:6443    192.168.110.30:41826    ESTABLISHED 9043/nginx: worker  
tcp        0      0 192.168.110.100:6443    192.168.110.20:40394    ESTABLISHED 9044/nginx: worker  
tcp        0      0 192.168.110.50:55274    192.168.110.40:6443     ESTABLISHED 9042/nginx: worker  
tcp        0      0 192.168.110.50:57360    192.168.110.10:6443     ESTABLISHED 9042/nginx: worker  
tcp        0      0 192.168.110.50:57236    192.168.110.10:6443     ESTABLISHED 9042/nginx: worker  
tcp        0      0 192.168.110.100:6443    192.168.110.20:40522    ESTABLISHED 9042/nginx: worker  
tcp        0      0 192.168.110.50:57218    192.168.110.10:6443     ESTABLISHED 9042/nginx: worker  
tcp        0      0 192.168.110.50:55258    192.168.110.40:6443     ESTABLISHED 9043/nginx: worker  
tcp        0      0 192.168.110.50:55372    192.168.110.40:6443     ESTABLISHED 9043/nginx: worker
#如果有问题检查防火墙核心防护

在 master01 节点上进行检测

#测试创建pod
kubectl run nginx --image=nginx//查看Pod的状态信息
kubectl get pods[root@master01 opt]# kubectl get pods
NAME       READY   STATUS    RESTARTS   AGE
nginx      1/1     Running   0          7skubectl get pods -o wide[root@master01 opt]# kubectl get pods -o wide
NAME       READY   STATUS    RESTARTS   AGE    IP             NODE             NOMINATED NODE   READINESS GATES
nginx      1/1     Running   0          70s    10.244.60.72   192.168.110.20   <none>           <none>
#READY为1/1,表示这个Pod中有1个容器#在对应网段的node节点上操作,可以直接使用浏览器或者curl命令访问
curl 172.17.36.2[root@node01 logs]# curl 10.244.60.72
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
... ...
<p><em>Thank you for using nginx.</em></p>
</body>
</html>#这时在master01节点上查看nginx日志
kubectl logs nginx[root@master01 opt]# kubectl logs nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
... ...
2025/02/10 08:51:22 [notice] 1#1: start worker process 31
2025/02/10 08:51:22 [notice] 1#1: start worker process 32
192.168.110.20 - - [10/Feb/2025:08:54:15 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"若执行失败,可先给kubectl绑定默认cluster-admin管理员集群角色,授权集群操作权限
kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous

部署 Dashboard

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

#在 master01 节点上操作
#上传 recommended.yaml 文件到 /opt/k8s 目录中
cd /opt/k8s
vim recommended.yaml
#默认Dashboard只能集群内部访问,修改Service为NodePort类型,暴露到外部:
kind: Service
apiVersion: v1
metadata:labels:k8s-app: kubernetes-dashboardname: kubernetes-dashboardnamespace: kubernetes-dashboard
spec:ports:- port: 443targetPort: 8443nodePort: 30001     #添加type: NodePort          #添加selector:k8s-app: kubernetes-dashboardkubectl 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
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')#使用输出的token登录Dashboard
https://192.168.110.20:30001 或者 https://192.168.110.30:30001

在这里插入图片描述

在这里插入图片描述

相关文章:

2、k8s 二进制安装(详细)

k8s 二进制安装 IP规划初始化部署 etcd 集群在 etcd01 节点上操作准备cfssl证书生成工具&#xff0c;加权生成etcd证书上传etcd软件包启动 etcd 服务 部署 Master 组件部署 Worker Node 组件node 节点安装 docker部署组件 部署 CNI 网络组件部署 flannel简介部署 部署 Calico简…...

02、QLExpress从入门到放弃,相关API和文档

QLExpress从入门到放弃,相关API和文档 一、属性开关 public class ExpressRunner {private boolean isTrace;private boolean isShortCircuit;private boolean isPrecise; }/*** 是否需要高精度计算*/ private boolean isPrecise false;高精度计算在会计财务中非常重要&…...

在 Visual Studio Code 与微信开发者工具中调试使用 emscripten 基于 C 生成的 WASM 代码

最近在尝试将一些 C/C、Lua 项目挪到 Web 上跑, 接触到了 emscripten. 这里会介绍下在 Visual Studio Code 与微信开发者工具中调试使用 emscripten 基于 C 生成的 WASM 代码 (WebAssembly) 的一些方法. Emscripten 与 WebAssebmly WebAssembly 是一种新的编码方式, 可以在现代…...

计算机毕业设计——Springboot的社区维修平台旅游管理

&#x1f4d8; 博主小档案&#xff1a; 花花&#xff0c;一名来自世界500强的资深程序猿&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 花花在深度学习任务中展现出卓越的能力&#xff0c;包括但不限于java、python等技术。近年来&#xff0c;花花更…...

Oracle常见语法

一、求交集 SELECT column1, column2 FROM table1 INTERSECT SELECT column1, column2 FROM table2;INTERSECT 操作符是 Oracle 和一些其他数据库&#xff08;如 PostgreSQL 和 SQL Server&#xff09;特有的集合操作符&#xff0c;在 MySQL 中并不直接支持。MYSQL同效果代码&a…...

[2025年最新]2024.3版本idea无法安装插件问题解决

背景 随着大模型的持续发展&#xff0c;特别年前年后deepseek的优异表现&#xff0c;编程过程中&#xff0c;需要解决ai来辅助编程&#xff0c;因此需要安装一些大模型插件 问题描述 在线安装插件的时候会遇到以下问题&#xff1a; 1.数据一直在加载&#xff0c;加载的很满 2.点…...

说一下 jvm 有哪些垃圾回收器?

JVM 垃圾回收器对比表 垃圾回收器类型工作方式回收方式停顿时间适用场景优点缺点常见问题常见配置Serial GC串行单线程&#xff0c;STW年轻代&#xff1a;复制算法 老年代&#xff1a;标记-整理长小内存、单核CPU&#xff0c;如桌面应用或嵌入式设备简单高效&#xff0c;适用于…...

【Linux】--- 进程间的通信

【Linux】--- 进程间的通信 一、进程间通信的介绍1、进程间通信的概念2、进程间通信的目的3、 进程间通信的本质/前提4、进程间通信的分类 二、管道1、什么是管道2、匿名管道&#xff08;1&#xff09;匿名管道的原理&#xff08;2&#xff09;pipe函数&#xff08;3&#xff0…...

GlusterFS 深度洞察:从架构原理到案例实践的全面解读(上)

文章目录 一.GlusterFS简介二.GlusterFS原理架构三.适用场景四.Glusterfs与其他存储产品对比五.部署GlusterFS集群六. 使用heketi将glusterfs接入k8s作为后端存储 一.GlusterFS简介 GlusterFS是一个免费的开源分布式文件系统&#xff0c;具有无中心节点、堆栈式设计、全局统一…...

实现限制同一个账号最多只能在3个客户端(有电脑、手机等)登录(附关键源码)

如上图&#xff0c;我的百度网盘已登录设备列表&#xff0c;有一个手机&#xff0c;2个windows客户端。手机设备有型号、最后登录时间、IP等。windows客户端信息有最后登录时间、操作系统类型、IP地址等。这些具体是如何实现的&#xff1f;下面分别给出android APP中采集手机信…...

C#综合知识点面试集锦

在.NET Core 框架的面试中,可能会涉及基础概念、核心组件、依赖注入、性能优化等多方面的知识点,以下为你详细介绍: 基础概念 .NET Core 概述 定义与特点:解释 .NET Core 是一个跨平台、开源、模块化且高性能的通用开发框架,能在 Windows、Linux、macOS 等操作系统上运行…...

宝珀(Blancpain):机械制表的三项重大创新(中英双语)

宝珀&#xff08;Blancpain&#xff09;&#xff1a;机械制表的创新先驱 本文灵感来源&#xff1a; 瑞士钟表业决定逆流而上&#xff0c;杀出一条生路&#xff0c;宝珀更是坚定地宣称“我们永远只做机械表”&#xff0c;它拒绝了石英技术。制表师们在提高腕表的技艺和品质、实…...

稠密架构和稀疏架构

稠密架构和稀疏架构 flyfish 稠密架构 参数使用方面&#xff1a;稠密架构中的大部分参数在每次计算时都会被使用。也就是说&#xff0c;对于输入的每一个样本&#xff0c;模型的所有或大部分参数都会参与到计算过程中。计算特点&#xff1a;计算密集&#xff0c;需要对大量的…...

SpringCloud - Gateway 网关

前言 该博客为Sentinel学习笔记&#xff0c;主要目的是为了帮助后期快速复习使用 学习视频&#xff1a;7小快速通关SpringCloud 辅助文档&#xff1a;SpringCloud快速通关 源码地址&#xff1a;cloud-demo 一、简介 官网&#xff1a;https://spring.io/projects/spring-clou…...

【如何掌握CSP-J 信奥赛中的排序算法】

要掌握CSP-J信奥赛中的排序算法&#xff0c;需要系统学习基础排序算法的原理、实现和应用场景。以下是分阶段的学习路径和建议&#xff1a; 一、必掌握的排序算法清单 CSP-J阶段需重点掌握以下算法&#xff08;按考察频率排序&#xff09;&#xff1a; 冒泡排序&#xff08;B…...

3. CSS中@scope

说说你对 CSS 中scope 的了解 <style>/* scope规则 */scope (#app) {.box {width: 100px;height: 100px;background-color: red;}} </style> <div id"app"><div class"box"></div> </div>CSS 中的scope 是一个相对较新…...

基于雷达和摄像头的无人机轨迹识别与激光照射控制研究

标题:基于雷达和摄像头的无人机轨迹识别与激光照射控制研究 内容:1.摘要 摘要&#xff1a;本文研究了基于雷达和摄像头的无人机轨迹识别与激光照射控制。通过对雷达和摄像头数据的融合处理&#xff0c;实现了对无人机轨迹的精确识别。同时&#xff0c;利用激光照射技术对无人机…...

Response 和 Request 介绍

怀旧网个人博客网站地址&#xff1a;怀旧网&#xff0c;博客详情&#xff1a;Response 和 Request 介绍 1、HttpServletResponse 1、简单分类 2、文件下载 通过Response下载文件数据 放一个文件到resources目录 编写下载文件Servlet文件 public class FileDownServlet exten…...

读 DeepSeek-R1 论文笔记

DeepSeek-R1&#xff1a;通过强化学习激发大语言模型的推理能力 DeepSeek-AI 摘要 我们推出第一代推理模型DeepSeek-R1-Zero和DeepSeek-R1。DeepSeek-R1-Zero作为无需监督微调(SFT)预训练阶段、直接通过大规模强化学习(RL)训练的基础模型&#xff0c;展现出卓越的推理能力。…...

【算法-动态规划】、魔法卷轴: 两次清零机会整个数组最大累加和

【算法-动态规划】、魔法卷轴: 两次清零机会整个数组最大累加和 文章目录 一、dp1.1 题意理解1.2 整体思路1.3 具体思路1.4 代码 二、多语言解法 一、dp 1.1 题意理解 nums 数组, 有正负0, 使用最多两次魔法卷轴, 希望使数组整体的累加和尽可能大. 求尽可能大的累加和 其实就…...

蓝桥杯C语言组:分治问题研究

蓝桥杯C语言组分治问题研究 摘要 本文针对蓝桥杯C语言组中的分治问题展开深入研究&#xff0c;详细介绍了分治算法的原理、实现方法及其在解决复杂问题中的应用。通过对经典例题的分析与代码实现&#xff0c;展示了分治算法在提高编程效率和解决实际问题中的重要作用&#xff…...

npm介绍(Node Package Manager)(JavaScript生态中最流行的包管理工具,主要用于Node.js项目的依赖管理)

文章目录 **核心功能****常用命令****关键文件****npm vs 其他工具****最佳实践**官方资源 npm&#xff08;Node Package Manager&#xff09;是 JavaScript 生态中最流行的包管理工具&#xff0c;主要用于 Node.js 项目的依赖管理。以下是核心要点&#xff1a; 核心功能 依赖管…...

小白零基础如何搭建CNN

1.卷积层 在PyTorch中针对卷积操作的对象和使用的场景不同&#xff0c;如有1维卷积、2维卷积、 3维卷积与转置卷积&#xff08;可以简单理解为卷积操作的逆操作&#xff09;&#xff0c;但它们的使用方法比较相似&#xff0c;都可以从torch.nn模块中调用&#xff0c;需要调用的…...

【分布式架构理论3】分布式调用(1):负载均衡

文章目录 零、三种不同的负载均衡一、常见行业负载均衡方案1. 电商与互联网服务2. 金融与支付系统3. 云计算与分布式存储 二、负载均衡策略概述1. 无状态负载均衡&#xff08;强调公平性&#xff09;2. 有状态的负载均衡&#xff08;强调正确性&#xff09; 三、 总结 零、三种…...

QT 5.15.2 开发地图ArcGIS 100.15.6(ArcGIS Runtime SDK for Qt)

QT 5.15.2ArcGIS下载 Downloads | ArcGIS Runtime API for Qt | Esri Developer ArcGIS安装&#xff08;略&#xff09;参考 Display a map | ArcGIS Maps SDK for Qt | Esri Developer QT新建工程 步骤1 步骤2 步骤3 步骤4&#xff08;选择Topographic不需要KEY) 步骤5&a…...

细读 React | React Router 路由切换原理

2022 北京冬奥会开幕式 此前一直在疑惑&#xff0c;明明 pushState()、replaceState() 不触发 popstate 事件&#xff0c;可为什么 React Router 还能挂载对应路由的组件呢&#xff1f; 翻了一下 history.js 源码&#xff0c;终于知道原因了。 源码 假设项目路由设计如下&#…...

kubernetes学习-Helm 包管理器(十二)

一、Helm解释 Helm&#xff1a;Kubernetes 的软件包管理器 Helm 被誉为查找、分享及使用 Kubernetes 软件组件的最佳途径。作为 Kubernetes 包的管理工具&#xff0c;Helm 专注于管理名为 chart 的软件包。以下是 Helm 所具备的核心功能&#xff1a; 创建新 chart&#xff1…...

PbootCMS最新代码注入漏洞(CNVD-2025-01710、CVE-2024-12789)

PbootCMS是一套高效、简洁、 强悍的可免费商用的CMS源码&#xff0c;使用PHPMySQL开发&#xff0c;能够满足各类企业网站开发建设的需要。 国家信息安全漏洞共享平台于2025-01-14公布该程序存在代码注入漏洞。 漏洞编号&#xff1a;CNVD-2025-01710、CVE-2024-12789 影响产品…...

网络安全与AI:数字经济发展双引擎

在2025年年初&#xff0c;一场科技攻防战引发了全球关注。国产人工智能DeepSeek的爆火&#xff0c;伴随着大规模的网络攻击事件&#xff0c;将网络安全的重要性推上了风口浪尖。 在此背景下&#xff0c;我们计划探讨网络安全与人工智能如何为数字经济发展提供强大动力。网络安…...

【DeepSeek × Postman】请求回复

新建一个集合 在 Postman 中创建一个测试集合 DeepSeek API Test&#xff0c;并创建一个关联的测试环境 DeepSeek API Env&#xff0c;同时定义两个变量 base_url 和 api_key 的步骤如下&#xff1a; 1. 创建测试集合 DeepSeek API Test 打开 Postman。点击左侧导航栏中的 Co…...

如何将网站提交百度收录完整SEO教程

百度收录是中文网站获取流量的重要渠道。本文以我的网站&#xff0c;www.mnxz.fun&#xff08;当然现在没啥流量&#xff09; 为例&#xff0c;详细讲解从提交收录到自动化维护的全流程。 一、百度收录提交方法 1. 验证网站所有权 1、登录百度搜索资源平台 2、选择「用户中心…...

【unity实战】实现摄像机跟随效果

考虑到每个人基础可能不一样,且并不是所有人都有同时做2D、3D开发的需求,所以我把 【零基础入门unity游戏开发】 分为成了C#篇、unity通用篇、unity3D篇、unity2D篇。 【C#篇】:主要讲解C#的基础语法,包括变量、数据类型、运算符、流程控制、面向对象等,适合没有编程基础的…...

使用Hexo部署NexT主体网站

一.使用git提交文件 参考&#xff1a; 从零开始搭建个人博客&#xff08;超详细&#xff09; - 知乎 致谢&#xff01; 第一种&#xff1a;本地没有 git 仓库 直接将远程仓库 clone 到本地&#xff1b;将文件添加并 commit 到本地仓库&#xff1b;将本地仓库的内容push到远程仓…...

使用 AlexNet 实现图片分类 | PyTorch 深度学习实战

前一篇文章&#xff0c;CNN 卷积神经网络处理图片任务 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 本篇文章内容来自于 强化学习必修课&#xff1a;引领人工智能新时代【梗直哥瞿炜】 使用 AlexNet 实现图片分类…...

ES6 Proxy 用法总结以及 Object.defineProperty用法区别

Proxy 是 ES6 引入的一种强大的拦截机制&#xff0c;用于定义对象的基本操作&#xff08;如读取、赋值、删除等&#xff09;的自定义行为。相较于 Object.defineProperty&#xff0c;Proxy 提供了更灵活、全面的拦截能力。 1. Proxy 语法 const proxy new Proxy(target, hand…...

初次体验Tauri和Sycamore (2)

原创作者&#xff1a;庄晓立&#xff08;LIIGO&#xff09; 原创时间&#xff1a;2025年2月8日&#xff08;首次发布时间&#xff09; 原创链接&#xff1a;https://blog.csdn.net/liigo/article/details/145520637 版权所有&#xff0c;转载请注明出处。 关键词&#xff1a;Sy…...

Qt - 地图相关 —— 2、Qt调用百度在线地图功能示例全集,包含线路规划、地铁线路查询等(附源码)

效果:由于录制软件导致exe显示不正常,实际运行没有任何问题。 作者其他相关文章链接:           Qt - 地图相关 —— 1、加载百度在线地图(附源码)...

ffmpeg基本用法

一、用法 ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}... 说明&#xff1a; global options&#xff1a;全局选项&#xff0c;应用于整个 FFmpeg 进程&#xff0c;它们通常不受输入或输出部分的限制。 infile options&#xff1a;输入选…...

redis底层数据结构——链表

文章目录 定义内部实现总结 定义 链表提供了高效的节点重排能力&#xff0c;以及顺序性的节点访间方式&#xff0c;并且可以通过增删节点来灵活地调整链表的长度。 作为一种常用数据结构&#xff0c;链表内置在很多高级的编程语言里面&#xff0c;因为Redis使用的C语言并没有…...

Repo命令使用

repo 命令与 git 类似&#xff0c;但它主要用于管理多个 Git 仓库的操作。以下是等效的 repo 命令&#xff1a; 1. 获取新仓库代码 克隆仓库 repo init -u <manifest_url> -b <branch_name> repo sync repo init&#xff1a;初始化 repo&#xff0c;指定远程清单…...

React 高级教程

使用 React 高级组件(HOC)实现的完整项目示例,包含权限控制、数据加载状态处理、性能优化等常见高级功能。创建一个简单的博客系统: // 项目结构: src/ |-- components/ | |-- ArticleList.jsx | |-- Article.jsx | |-- Header.jsx | |-- LoginForm.jsx | |-- U…...

Linux: ASoC 声卡硬件参数的设置过程简析

文章目录 1. 前言2. ASoC 声卡设备硬件参数2.1 将 DAI、Machine 平台的硬件参数添加到声卡2.2 打开 PCM 流时将声卡硬件参数配置到 PCM 流2.3 应用程序对 PCM 流参数进行修改调整 1. 前言 限于作者能力水平&#xff0c;本文可能存在谬误&#xff0c;因此而给读者带来的损失&am…...

网络基础知识与配置

目录 网络基础知识 &#xff08;一&#xff09;网络的概念 &#xff08;二&#xff09;网络协议 &#xff08;三&#xff09;网络拓扑结构 &#xff08;四&#xff09;IP地址和子网掩码 显示和配置网络接口 &#xff08;一&#xff09;在Windows系统中 &#xff08;二&a…...

【STM32】ADC|多通道ADC采集

本次实现的是ADC实现数字信号与模拟信号的转化&#xff0c;数字信号时不连续的&#xff0c;模拟信号是连续的。 1.ADC转化的原理 模拟-数字转换技术使用的是逐次逼近法&#xff0c;使用二分比较的方法来确定电压值 当单片机对应的参考电压为3.3v时&#xff0c;0~ 3.3v(模拟信…...

centos 7 关于引用stdatomic.h的问题

问题&#xff1a;/tmp/tmp4usxmdso/main.c:6:23: fatal error: stdatomic.h: No such file or directory #include <stdatomic.h> 解决步骤&#xff1a; 1.这个错误是因为缺少C编译器的标准原子操作头文件 stdatomic.h。在Linux系统中&#xff0c;我们需要安装开发工具…...

用语言模型探索语音风格空间:无需情感标签的情 感TTS

用语言模型探索语音风格空间&#xff1a;无需情感标签的情感TTS 原文&#xff1a;Exploring speech style spaces with language models: Emotional TTS without emotion labels 今天我们要说的是 一种无需情感标签的情感TTS。提出了一个基于FastSpeech2的E-TTS框架&#xff0…...

将Excel中的图片保存下载并导出

目录 效果演示 注意事项 核心代码 有需要将excel中的图片解析出来保存到本地的小伙子们看过来&#xff01;&#xff01;&#xff01; 效果演示 注意事项 仅支持xlsx格式&#xff1a;此方法适用于Office 2007及以上版本的.xlsx文件&#xff0c;旧版.xls格式无法使用。 图片名…...

2.11日学习总结

题目一 &#xff1a; AC代码 #include <stdio.h> #include <stdlib.h>// 定义长整型 typedef long long ll;// 定义求最大值和最小值的宏函数 #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b))// 定义数组和变量 ll…...

安川伺服控制器MP系列优势特点及行业应用

在工业自动化领域&#xff0c;运动控制器的性能直接决定了设备的精度、效率和可靠性。作为全球领先的运动控制品牌&#xff0c;安川电机伺服控制器凭借其卓越的技术优势和广泛的应用场景&#xff0c;正在为智能制造注入强劲动力&#xff01; MP3100&#xff1a;主板型运动控制…...

【腾讯地图】录入经纬度功能 - 支持地图选点

目录 效果展示代码引入地图服务地址弹框中输入框 - 支持手动输入经纬度/地图选点按钮地图选点弹框组件 当前文章 - 地图功能与 https://blog.csdn.net/m0_53562074/article/details/143677335 功能类似 效果展示 代码 引入地图服务地址 public/index.html <!-- 互联网地图…...