【k8s集群应用】Kubernetes部署安装-二进制部署实例
文章目录
- Kubernetes 部署方式
- 常见的K8S安装部署方式
- Kubeadm与二进制部署的区别
- Kubernetes部署安装
- 环境配置
- Kubernetes集群初始化配置(实验环境)
- 一、操作系统初始化配置
- 二、部署Docker引擎
- etcd 集群搭建
- 配置 etcd 集群
- Kubernetes Master 组件部署
- 准备工作
- 创建目录
- 复制证书
- 解压 Kubernetes 二进制文件
- 创建 Bootstrap Token
- 启动 Master 组件
- 生成 Kubeconfig 文件
- 验证集群状态
- Kubernetes Worker Node 部署
- 在所有 Node 节点上执行的操作
- 在 Master 节点(master01)上执行的操作
- 在 node01 节点上操作
- 启动 kubelet 服务
- 在 master01 节点上操作,通过 CSR 请求
- 在 node01 节点上操作
- 加载 ip_vs 模块
- 启动proxy服务
- 部署 CNI 网络组件
- 在 node01 节点上操作
- 上传 cni-plugins-linux-amd64-v1.3.0.tgz 和 flannel镜像文件 到 /opt 目录中
- 在 master01 节点上操作
- 上传 kube-flannel.yml 文件到 /opt/k8s 目录中,部署 CNI 网络
- 部署 Calico(在 master01 节点操作)
- 部署 Calico
- 查看node状态
- 修改calico的网络模式
- node02 节点部署
- 在 node01 节点上操作
- 在 node02 节点上操作
- 在 master01 节点上操作
- 通过 CSR 请求
- 在 node02 节点上操作
- 加载 ipvs 模块
- 使用proxy.sh脚本启动proxy服务
- 查看群集中的节点状态
- 部署 CoreDNS
- CoreDNS
- 部署CoreDNS
- 在所有 node 节点上操作
- 在 master01 节点上操作
- DNS 解析测试
- 故障排除
Kubernetes 部署方式
常见的K8S安装部署方式
- Minikube
- 用途:用于本地快速运行一个单节点微型K8S,适合学习、预览K8S特性。
- 部署地址:https://kubernetes.io/docs/setup/minikube
- Kubeadm
- 用途:提供
kubeadm init和kubeadm join命令,用于快速部署K8S集群,相对简单。 - 文档地址:https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/
- 用途:提供
- 二进制安装部署
- 用途:生产首选,从官方下载发行版的二进制包,手动部署每个组件和自签TLS证书,组成K8S集群。
- 下载地址:https://github.com/kubernetes/kubernetes/releases
- 备注:虽然手动部署较麻烦,但期间可以学习很多工作原理,也利于后期维护。
总结:
- Minikube:适合本地学习和预览K8S特性。
- Kubeadm:部署简单,适合快速搭建K8S集群,但管理难度较大,故障恢复速度较慢。
- 二进制部署:部署复杂,但管理方便,集群伸展性能好,稳定性高,适合生产环境。
Kubeadm与二进制部署的区别
- 二进制部署
- 部署难度:难
- 管理方便性:方便
- 集群伸展性能:好
- 稳定性:集群规模到达一定规模(几百个节点、上万个Pod)时,二进制部署的稳定性高于kubeadm。
- 故障恢复:宿主机起来后,进程也会自动起来,恢复速度快。
- Kubeadm部署
- 部署难度:简单
- 管理方便性:难
- 部署方式:以容器管理容器的方式部署组件及服务。
- 故障恢复:恢复速度比二进制慢,因为需要先启动宿主机,再启动进程,最后启动容器,集群才能恢复。
Kubernetes部署安装
环境配置
| 节点名称 | IP地址 | 托管服务/组件 |
|---|---|---|
| k8s集群master01 | 20.0.0.10 | kube-apiserver, kube-controller-manager, kube-scheduler, etcd |
| k8s集群master02 | 20.0.0.66 | (备用master) |
| k8s集群node01 | 20.0.0.58 | kubelet, kube-proxy, docker, etcd |
| k8s集群node02 | 20.0.0.59 | kubelet, kube-proxy, docker, etcd |
| etcd集群节点1 | 20.0.0.10 | etcd |
| etcd集群节点2 | 20.0.0.58 | etcd |
| etcd集群节点3 | 20.0.0.59 | etcd |
Kubernetes集群初始化配置(实验环境)
一、操作系统初始化配置
-
关闭防火墙
- 停止并禁用
firewalld服务。 - 清除所有iptables规则。
systemctl stop firewalld systemctl disable firewalld iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X - 停止并禁用
-
关闭SELinux
- 临时关闭SELinux。
- 永久修改
/etc/selinux/config文件,将SELinux设置为disabled。
setenforce 0 sed -i 's/enforcing/disabled/' /etc/selinux/config -
关闭Swap
- 临时关闭Swap。
- 永久禁用Swap,修改
/etc/fstab文件,注释掉Swap相关行。
swapoff -a sed -ri 's/.*swap.*/#&/' /etc/fstab -
设置主机名
- 根据规划,使用
hostnamectl命令设置各节点的主机名。
hostnamectl set-hostname [主机名] - 根据规划,使用
-
添加Hosts
- 在
master节点上,编辑/etc/hosts文件,添加集群内其他节点的IP和主机名映射。
cat >> /etc/hosts << EOF 20.0.0.10 master01 20.0.0.58 node01 20.0.0.59 node02 EOF - 在
-
调整内核参数
- 创建
/etc/sysctl.d/k8s.conf文件,添加必要的内核参数配置。 - 应用配置。
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 sysctl --system - 创建
-
时间同步
- 安装
ntpdate工具。 - 使用
ntpdate同步时间。
yum install ntpdate -y ntpdate time.windows.com - 安装
二、部署Docker引擎
-
安装依赖
- 在所有
node节点上,安装yum-utils、device-mapper-persistent-data和lvm2。
yum install -y yum-utils device-mapper-persistent-data lvm2 - 在所有
-
添加Docker仓库
- 使用
yum-config-manager添加Docker的官方仓库。
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo - 使用
-
安装Docker
- 安装Docker CE、Docker CE CLI和
containerd.io。
yum install -y docker-ce docker-ce-cli containerd.io - 安装Docker CE、Docker CE CLI和
-
配置Docker
- 创建
/etc/docker目录。 - 在
/etc/docker/daemon.json文件中添加Docker的配置,包括镜像加速器、Cgroup Driver等。
mkdir /etc/docker cat > /etc/docker/daemon.json <<EOF {"registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com", "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"} } EOF - 创建
-
启动并启用Docker服务
- 启动Docker服务。
- 设置Docker服务开机自启。
systemctl start docker.service systemctl enable docker.service -
验证Docker配置
- 使用
docker info命令检查Cgroup Driver是否配置正确。
docker info | grep "Cgroup Driver" Cgroup Driver: systemd - 使用
------------------------------ 部署 etcd 集群 ------------------------------
etcd是一个分布式键值存储系统,用于在分布式系统中保存配置信息、元数据以及关键的共享状态。它是一个开源项目,最初由CoreOS开发并维护,现在由CNCF托管。etcd的设计目标是提供可靠的分布式存储,以支持分布式系统的一致性和高可用性。
关键特性:
- 分布式存储:etcd的数据存储是分布式的,可以跨多个节点进行分布,确保高可用性和可扩展性。
- 强致性:etcd提供强一致性的保证,确保在集群中的所有节点都能看到相同的数据视图。
- 轻量级:etcd采用轻量级的Raft一致性算法,以确保集群中的节点之间达成一致,同时保持相对较低的性能开销。
- API支持:etcd提供简单而强大的HTTP+JSON API,使得开发人员可以轻松地与其进行交互,并集成到各种应用和工具中。
- Watch机制:etcd支持Watch机制,允许客户端监视特定键的变化,并在数据发生变更时得到通知。
- 安全性:etcd支持SSL/TLS加密,以保障数据在传输过程中的安全性,并提供基于角色的访问控制。
应用场景:
- 配置管理: etcd常用于存储应用程序和系统的配置信息,允许动态地更新配置而无需重启应用。
- 服务发现: etcd可以用作服务发现的后端存储,帮助服务在动态环境中找到彼此。
- 分布式锁: 通过etcd的分布式锁机制,可以实现分布式系统中的协同工作和资源同步。
- 集群协调: etcd在构建分布式系统中,作为集群协调的关键组件,确保系统的一致性和稳定性。
总体而言,etcd在云原生应用和分布式系统中发挥着重要作用,提供了可靠的分布式存储和协调服务,为应用程序提供一致性、可靠性和高可用性的基础设施支持。
etcd 目前默认使用2379端口提供HTTP API服务, 2380端口和peer通信(这两个端口已经被IANA(互联网数字分配机构)官方预留给etcd)。 即etcd默认使用2379端口对外为客户端提供通讯,使用端口2380来进行服务器间内部通讯。
etcd 在生产环境中一般推荐集群方式部署。由于etcd 的leader选举机制,要求至少为3台或以上的奇数台。
---------- 准备签发证书环境 ----------
CFSSL 是 CloudFlare 公司开源的一款 PKI/TLS 工具。 CFSSL 包含一个命令行工具和一个用于签名、验证和捆绑 TLS 证书的 HTTP API 服务。使用Go语言编写。
CFSSL 使用配置文件生成证书,因此自签之前,需要生成它识别的 json 格式的配置文件,CFSSL 提供了方便的命令行生成配置文件。
CFSSL 用来为 etcd 提供 TLS 证书,它支持签三种类型的证书:
- client 证书,服务端连接客户端时携带的证书,用于客户端验证服务端身份,如 kube-apiserver 访问 etcd;
- server 证书,客户端连接服务端时携带的证书,用于服务端验证客户端身份,如 etcd 对外提供服务;
- peer 证书,相互之间连接时使用的证书,如 etcd 节点之间进行验证和通信。
这里全部都使用同一套证书认证。
etcd 集群搭建
- 安装 cfssl 工具
- 下载并安装
cfssl、cfssljson和cfssl-certinfo工具。
链接可能失效,此处自己上传的文件进行实验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 证书
- 创建目录并上传脚本。
mkdir /opt/k8s cd /opt/k8s/ chmod +x etcd-cert.sh etcd.sh vim /opt/k8s/etcd-cert.sh # 修改 etcd 中集群的 IP 地址 mkdir /opt/k8s/etcd-cert mv etcd-cert.sh etcd-cert/ cd /opt/k8s/etcd-cert/ ./etcd-cert.sh # 生成 CA 证书、etcd 服务器证书及私钥 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
cd /opt/k8s/ wget https://github.com/etcd-io/etcd/releases/download/v3.4.26/etcd-v3.4.26-linux-amd64.tar.gz tar zxvf etcd-v3.4.26-linux-amd64.tar.gz
配置 etcd 集群
- 创建必要目录
mkdir -p /opt/etcd/{cfg,bin,ssl} cd /opt/k8s/etcd-v3.4.26-linux-amd64/ mv etcd etcdctl /opt/etcd/bin/ cp /opt/k8s/etcd-cert/*.pem /opt/etcd/ssl/ - 启动 etcd 服务
- 在
master01节点上启动 etcd 并等待其他节点加入。
进入卡住状态等待其他节点加入,这里需要三台etcd服务同时启动,如果只启动其中一台后,服务会卡在那里,直到集群中所有etcd节点都已启动,可忽略这个情况cd /opt/k8s/ ./etcd.sh etcd01 20.0.0.10 etcd02=https://20.0.0.58:2380,etcd03=https://20.0.0.59:2380- 可另外打开一个窗口查看etcd进程是否正常
ps -ef | grep etcd - 在
- 拷贝配置文件到集群节点中
- 把etcd相关证书文件、命令文件和服务管理文件全部拷贝到另外两个etcd集群节点
scp -r /opt/etcd/ root@20.0.0.58:/opt/ scp -r /opt/etcd/ root@20.0.0.59:/opt/ scp /usr/lib/systemd/system/etcd.service root@20.0.0.58:/usr/lib/systemd/system/ scp /usr/lib/systemd/system/etcd.service root@20.0.0.59:/usr/lib/systemd/system/ - 配置其他节点
- 在
node01和node02节点上修改/opt/etcd/cfg/etcd配置文件。
vim /opt/etcd/cfg/etcd #[Member] ETCD_NAME="etcd02" #修改 ETCD_DATA_DIR="/var/lib/etcd" ETCD_LISTEN_PEER_URLS="https://20.0.0.58:2380" #修改 ETCD_LISTEN_CLIENT_URLS="https://20.0.0.58:2379" #修改#[Clustering] ETCD_INITIAL_ADVERTISE_PEER_URLS="https://20.0.0.58:2380" #修改 ETCD_ADVERTISE_CLIENT_URLS="https://20.0.0.58:2379" #修改 ETCD_INITIAL_CLUSTER="etcd01=https://20.0.0.10:2380,etcd02=https://20.0.0.58:2380,etcd03=https://20.0.0.59: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://20.0.0.10:2379,https://20.0.0.58:2379,https://20.0.0.59: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://20.0.0.10:2379,https://20.0.0.58:2379,https://20.0.0.59: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
- –cacert :使用此CA证书验证启用https的服务器的证书
- –key :使用此TLS密钥文件标识HTTPS客户端
- –cert :使用此TLS证书文件标识HTTPS客户端
- –endpoints:集群中以逗号分隔的机器地址列表
- cluster-health:检查etcd集群的运行状况
Kubernetes Master 组件部署
准备工作
- 上传文件到 /opt/k8s 目录
- 上传
master.zip和k8s-cert.sh到/opt/k8s。 - 上传
kubernetes-server-linux-amd64.tar.gz到/opt/k8s。
- 上传
注:此处用的是自己的master.zip压缩包里有事先准备好的脚本文件资源等并不适用所有情况,适度参考。
2. 解压和权限设置
- 解压
master.zip并赋予脚本执行权限。cd /opt/k8s/ unzip master.zip chmod +x *.sh
创建目录
- 创建 Kubernetes 工作目录
mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs} - 创建证书目录
mkdir /opt/k8s/k8s-cert mv /opt/k8s/k8s-cert.sh /opt/k8s/k8s-cert cd /opt/k8s/k8s-cert/ ./k8s-cert.sh#生成ca证书、相关组件的证书和私钥 - 查看生成的证书
大致得到如下结果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 证书和 API Server 相关证书及私钥复制到
ssl目录。cp ca*pem apiserver*pem /opt/kubernetes/ssl/
#上传 kubernetes-server-linux-amd64.tar.gz 到 /opt/k8s/ 目录中,解压 kubernetes 压缩包
#下载地址:https://github.com/kubernetes/kubernetes/blob/release-1.20/CHANGELOG/CHANGELOG-1.20.md
#注:打开链接你会发现里面有很多包,下载一个server包就够了,包含了Master和Worker Node二进制文件。
解压 Kubernetes 二进制文件
-
解压 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
- 创建并运行 token.sh 脚本
cd /opt/k8s/ vim token.sh #!/bin/bash #获取随机数前16个字节内容,以十六进制格式输出,并删除其中空格 BOOTSTRAP_TOKEN=$(head -c 16 /dev/urandom | od -An -t x | tr -d ' ') 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
启动 Master 组件
- 启动 API Server
- 需要先准备好
apiserver.sh脚本,传入参数如 etcd 集群地址。
cd /opt/k8s/ ./apiserver.sh 20.0.0.10 https://20.0.0.10:2379,https://20.0.0.58:2379,https://20.0.0.59:2379 # 检查 API Server 是否启动成功 ps aux | grep kube-apiserver netstat -natp | grep 6443 - 需要先准备好
- 启动 Scheduler
cd /opt/k8s/ ./scheduler.sh ps aux | grep kube-scheduler
注意脚本中的IP地址是否正确
- 启动 Controller Manager
./controller-manager.sh
注意脚本中的IP地址是否正确
生成 Kubeconfig 文件
- 生成
kubectl连接集群的kubeconfig文件,并运行admin.sh脚本。./admin.sh
注意脚本中的IP地址是否正确
验证集群状态
- 查看集群组件状态
kubectl get cs
输出大致如下:
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
scheduler Healthy ok
etcd-2 Healthy {"health":"true"}
etcd-1 Healthy {"health":"true"}
etcd-0 Healthy {"health":"true"}
-
查看版本信息
kubectl version -
查看当前 leader
kubectl -n kube-system get leases kube-scheduler kubectl -n kube-system get leases kube-controller-manager
Kubernetes Worker Node 部署
在所有 Node 节点上执行的操作
-
创建 Kubernetes 工作目录
- 创建必要的目录结构用于存放 Kubernetes 组件的二进制文件、配置文件、证书和日志。
mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}
- 创建必要的目录结构用于存放 Kubernetes 组件的二进制文件、配置文件、证书和日志。
-
上传并解压 node.zip
- 将包含
kubelet.sh和proxy.sh脚本的node.zip文件上传到/opt目录。 - 解压
node.zip并赋予脚本执行权限。cd /opt/ unzip node.zip chmod +x kubelet.sh proxy.sh
- 将包含
在 Master 节点(master01)上执行的操作
-
拷贝 kubelet 和 kube-proxy 到 Node 节点
- 将
kubelet和kube-proxy二进制文件从 Master 节点的/opt/k8s/kubernetes/server/bin目录拷贝到各个 Node 节点的/opt/kubernetes/bin/目录。cd /opt/k8s/kubernetes/server/bin scp kubelet kube-proxy root@20.0.0.58:/opt/kubernetes/bin/ scp kubelet kube-proxy root@20.0.0.59:/opt/kubernetes/bin/
- 将
-
生成 kubeconfig 文件
- 创建
/opt/k8s/kubeconfig目录,上传kubeconfig.sh脚本并赋予执行权限。 - 执行
kubeconfig.sh脚本生成bootstrap.kubeconfig和kube-proxy.kubeconfig文件。这些文件包含连接到 API Server 所需的证书和配置信息。mkdir /opt/k8s/kubeconfigcd /opt/k8s/kubeconfig chmod +x kubeconfig.sh ./kubeconfig.sh 20.0.0.10 /opt/k8s/k8s-cert/
- 创建
-
拷贝 kubeconfig 文件到 Node 节点
- 将生成的
bootstrap.kubeconfig和kube-proxy.kubeconfig文件拷贝到各个 Node 节点的/opt/kubernetes/cfg/目录。scp bootstrap.kubeconfig kube-proxy.kubeconfig root@20.0.0.58:/opt/kubernetes/cfg/ scp bootstrap.kubeconfig kube-proxy.kubeconfig root@20.0.0.59:/opt/kubernetes/cfg/
- 将生成的
-
RBAC 授权和自动批准 CSR 请求
- 创建 RBAC 绑定,使用户
kubelet-bootstrap能够发起 CSR 请求并自动批准这些请求。kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap 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
- 创建 RBAC 绑定,使用户
kubelet 采用 TLS Bootstrapping 机制,自动完成到 kube-apiserver 的注册,在 node 节点量较大或者后期自动扩容时非常有用。
Master apiserver 启用 TLS 认证后,node 节点 kubelet 组件想要加入集群,必须使用CA签发的有效证书才能与 apiserver 通信,当 node 节点很多时,签署证书是一件很繁琐的事情。因此 Kubernetes 引入了 TLS bootstraping 机制来自动颁发客户端证书,kubelet 会以一个低权限用户自动向 apiserver 申请证书,kubelet 的证书由 apiserver 动态签署。
kubelet 首次启动通过加载 bootstrap.kubeconfig 中的用户 Token 和 apiserver CA 证书发起首次 CSR 请求,这个 Token 被预先内置在 apiserver 节点的 token.csv 中,其身份为 kubelet-bootstrap 用户和 system:kubelet-bootstrap 用户组;想要首次 CSR 请求能成功(即不会被 apiserver 401 拒绝),则需要先创建一个 ClusterRoleBinding,将 kubelet-bootstrap 用户和 system:node-bootstrapper 内置 ClusterRole 绑定(通过 kubectl get clusterroles 可查询),使其能够发起 CSR 认证请求。
TLS bootstrapping 时的证书实际是由 kube-controller-manager 组件来签署的,也就是说证书有效期是 kube-controller-manager 组件控制的;kube-controller-manager 组件提供了一个 --experimental-cluster-signing-duration 参数来设置签署的证书有效时间;默认为 8760h0m0s,将其改为 87600h0m0s,即 10 年后再进行 TLS bootstrapping 签署证书即可。
也就是说 kubelet 首次访问 API Server 时,是使用 token 做认证,通过后,Controller Manager 会为 kubelet 生成一个证书,以后的访问都是用证书做认证了。
在 node01 节点上操作
启动 kubelet 服务
cd /opt/
./kubelet.sh 20.0.0.58
ps aux | grep kubelet
在 master01 节点上操作,通过 CSR 请求
- 检查到 node01 节点的 kubelet 发起的 CSR 请求,Pending 表示等待集群给该节点签发证书
kubectl get csr
#输出大致如下
NAME AGE SIGNERNAME REQUESTOR CONDITION
node-csr-duiobEzQ0R93HsULoS9NT9JaQylMmid_nBF3Ei3NtFE 12s kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending
- 通过 CSR 请求
kubectl certificate approve node-csr-duiobEzQ0R93HsULoS9NT9JaQylMmid_nBF3Ei3NtFE
- 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
kubectl get node
NAME STATUS ROLES AGE VERSION
20.0.0.58 NotReady <none> 108s 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 20.0.0.58
ps aux | grep kube-proxy
部署 CNI 网络组件
在 node01 节点上操作
上传 cni-plugins-linux-amd64-v1.3.0.tgz 和 flannel镜像文件 到 /opt 目录中
cd /opt/
docker load -i flannel.tar
docker load -i flannel-cni-plugin.tar
mkdir -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 网络
cd /opt/k8s
kubectl apply -f kube-flannel.yml
kubectl get pods -n kube-flannel
NAME READY STATUS RESTARTS AGE
kube-flannel-ds-hjtc7 1/1 Running 0 7s
kubectl get nodes
NAME STATUS ROLES AGE VERSION
20.0.0.58 Ready <none> 81m v1.20.15
ip -d a show flannel.1 #在node上查看flannel.1的端口
route -n #通过路由信息,看到发送到对端网段的数据包都会经过 flannel.1发出,网关ip也是对端vtep设备的ip地址
ip neigh show dev flannel.1 #由于flannel.1 通过路由信息已经知道对端vtep的ip地址,通过查询本地arp缓存表,得到目的vtep的mac地址
bridge fdb show flannel.1 #flannel.1可以通过查询本机的FDB表获取目的节点主机的ip
部署 Calico(在 master01 节点操作)
curl:https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml
部署 Calico
上传 calico.yaml 文件到 /opt/k8s 目录中
vim冒号模式下/CALICO_IPV4POOL_CIDR找
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/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
查看node状态
等 Calico Pod 都 Running,节点也会准备就绪
kubectl get nodes
修改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
node02 节点部署
在 node01 节点上操作
cd /opt/
scp kubelet.sh proxy.sh root@20.0.0.59:/opt/
scp -r /opt/cni root@20.0.0.59:/opt/
在 node02 节点上操作
启动kubelet服务
cd /opt/
chmod +x kubelet.sh
./kubelet.sh 20.0.0.59
在 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
在 node02 节点上操作
加载 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 20.0.0.59
查看群集中的节点状态
kubectl get nodes
部署 CoreDNS
CoreDNS
- CoreDNS 是 Kubernetes 的默认 DNS 实现。
- 为 Kubernetes 集群内的 Pod 提供 DNS 服务。
- 通过创建 service 资源名称与 ClusterIP 的对应关系解析,避免将 service 的 ClusterIP 地址硬编码到应用程序代码中。
部署CoreDNS
在所有 node 节点上操作
- 上传
coredns.tar到/opt目录中。 - 使用 Docker 加载 CoreDNS 镜像:
cd /opt docker load -i coredns.tar
在 master01 节点上操作
- 上传
coredns.yaml文件到/opt/k8s目录中。 - 使用 kubectl 部署 CoreDNS:
cd /opt/k8s kubectl apply -f coredns.yaml - 检查 CoreDNS Pod 的状态:
示例输出:kubectl get pods -n kube-systemNAME READY STATUS RESTARTS AGE coredns-5ffbfd976d-j6shb 1/1 Running 0 32s
DNS 解析测试
- 使用 busybox 镜像运行一个临时 Pod 进行 DNS 解析测试:
kubectl run -it --rm dns-test --image=busybox:1.28.4 sh - 在 busybox Pod 中执行
nslookup命令:/ # 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
故障排除
-
如果 DNS 解析测试失败,可以尝试给
kubectl绑定默认cluster-admin管理员集群角色,授权集群操作权限:kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous -
确保所有 node 节点上已经加载了 CoreDNS 的 Docker 镜像。
-
部署 CoreDNS 的配置文件
coredns.yaml需要正确配置,确保 CoreDNS 能够正确解析 Kubernetes 集群内的服务。 -
在进行 DNS 解析测试时,确保 CoreDNS Pod 已经处于 Running 状态。
相关文章:
【k8s集群应用】Kubernetes部署安装-二进制部署实例
文章目录 Kubernetes 部署方式常见的K8S安装部署方式Kubeadm与二进制部署的区别 Kubernetes部署安装环境配置Kubernetes集群初始化配置(实验环境)一、操作系统初始化配置二、部署Docker引擎 etcd 集群搭建配置 etcd 集群 Kubernetes Master 组件部署准备…...
js常见代码输出问题之promise,await,变量提升以及闭包(包括例子以及详细解析)
这里写目录标题 异步事件循环宏任务微任务1. 执行顺序2. 分类 Promise代码输出1. promise.then执行时机2. 宏任务微任务的多轮次3. .then .catch会返回新的promise4. 返回任意一个非 promise 的值都会被包裹成 promise 对象5. .then .catch 的值不能是promise本身6. 值透传7. .…...
遗传算法与深度学习实战(27)——进化卷积神经网络
遗传算法与深度学习实战(27)——进化卷积神经网络 0. 前言1. 自定义交叉算子2. 自定义突变操作符3. 进化卷积神经网络小结系列链接 0. 前言 DEAP toolbox 中提供的标准遗传操作符对于自定义的网络架构基因序列来说是不够的。这是因为任何标准的交叉算子…...
【Vue3】前端使用 FFmpeg.wasm 完成用户视频录制,并对视频进行压缩处理
强烈推荐这篇博客!非常全面的一篇文章,本文是对该博客的简要概括和补充,在不同技术栈中提供一种可行思路,可先阅读该篇文章再阅读本篇: FFmpeg——在Vue项目中使用FFmpeg(安装、配置、使用、SharedArrayBu…...
基础算法——前缀和
由于比赛基本都是采用Dev-C所以,算法篇基本都是采用Dev-C来解释(版本5.11,c11) 首先介绍一下前缀和算法 给定一个数组,有q次询问,每次询问: 两个整数l,r,求出数组 l 到 r的结果 遇…...
spring实例化对象的几种方式(使用XML配置文件)
前言 Spring框架作为一个轻量级的控制反转(IoC)容器,为开发者提供了多种对象实例化的策略。通过这些策略,开发者可以更加灵活地控制对象的生命周期和依赖关系。无论是通过XML配置、注解配置还是Java配置,Spring都能…...
【二叉树】力扣 129.求根节点到叶子节点数字之和
一、题目 二、思路 每找到一个非空节点,之前路径上的所有节点的数量级都要增加1个单位。例如,当前节点为3,之前的节点路径为1 -> 2,presum 1 * 10 2 12,现在路径变为了 1 -> 2 -> 3,sum pres…...
深度学习物体检测之YOLOV5源码解读
V5比前面版本偏工程化,项目化,更贴合实战 一.V5版本项目配置 (1)整体项目概述 首先github直接查找yolov5,下载下来即可。在训练时,数据是怎么处理的?网络模型架构是怎么设计的(如各层的设计)?yolov5要求是大于python3.8与大于等…...
音频数据采样入门详解 - 给Python初学者的简单解释
音频数据采样入门详解 - 给Python初学者的简单解释 声音是如何变成数字的?什么是采样率?为什么要懂这个?Python小例子总结 大家好!今天我们来聊一个有趣的话题:音频数据是如何在计算机中处理的。让我用最简单的方式来解…...
Unity类银河战士恶魔城学习总结(P179 Enemy Archer 弓箭手)
教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/ 本章节实现了敌人弓箭手的制作 Enemy_Archer.cs 核心功能 状态机管理敌人的行为 定义了多个状态对象(如 idleState、moveState、attackState 等),通过状态机管理敌人的…...
SpringCloud集成sleuth和zipkin实现微服务链路追踪
文章目录 前言技术积累spring cloud sleuth介绍zipkin介绍Zipkin与Sleuth的协作 SpringCloud多模块搭建Zipkin Server部署docker pull 镜像启动zipkin server SpringCloud 接入 Sleuth 与 Zipkinpom引入依赖 (springboot2.6)appilication.yml配置修改增加测试链路代码 调用微服…...
Python随机抽取Excel数据并在处理后整合为一个文件
本文介绍基于Python语言,针对一个文件夹下大量的Excel表格文件,基于其中每一个文件,随机从其中选取一部分数据,并将全部文件中随机获取的数据合并为一个新的Excel表格文件的方法。 首先,我们来明确一下本文的具体需求。…...
Linux+Docker onlyoffice 启用 HTTPS 端口支持
文章目录 一、需求二、配置2.1 创建容器2.2 进入容器2.3 生成私钥和证书 2.4 测试访问 一、需求 上篇文章介绍了如何搭建一个 onlyoffice 在线预览服务,但是我们实际场景调用该服务的网站是协议是 https 的 ,但是 onlyoffice 服务还没做配置,…...
在 Visual Studio Code 中编译、调试和执行 Makefile 工程 llama2.c
在 Visual Studio Code 中编译、调试和执行 Makefile 工程 llama2.c 1. Installing the extension (在 Visual Studio Code 中安装插件)1.1. Extensions for Visual Studio Code1.2. C/C1.2.1. Pre-requisites 1.3. Makefile Tools 2. Configuring your project (配置项目)2.1.…...
python中math模块常用函数
文章目录 math模块简介各种三角函数反三角函数取整函数欧几里得距离绝对值最大公约数开根号幂阶乘函数 math模块简介 math模块是python标准库的一部分,提供了对于浮点数相关的数学运算,下面是常用的一些function 各种三角函数反三角函数 math.cos、ma…...
优化 Vue 3 开发体验:配置 Vite 使用 WebStorm 作为 Vue DevTools 的默认编辑器
优化 Vue 3 开发体验:配置 Vite 使用 WebStorm 替代 VS Code 作为 Vue DevTools 的默认编辑器 在 Vue 3 项目开发中,合理配置开发工具可以大大提升我们的工作效率。本文将介绍如何配置 Vite,使其在使用 Vue DevTools 时将默认编辑器从 VS Co…...
【C语言练习(9)—有一个正整数,求是几位数然后逆序打印】
C语言练习(9) 文章目录 C语言练习(9)前言题目题目解析结果总结 前言 主要到整数的取余(%)和整数的取商(/),判断语句if…else if …else的使用 题目 给一个不多于3位的正整数,要求:一、求它是几位数&…...
热敏打印机的控制
首次接触热敏打印机,本来没有特别之处,花了大概十天时间完成一款猫学王热敏打印机,给到客户体验后,客户反馈说打字看起来不明显,打印照片有条纹,所以引起了我对于他的关注,几点不足之处需要优化…...
【closerAI ComfyUI】电商赋能,AI模特套图生产,各种姿势自定义,高度保持人物服饰场景一致性,摆拍街拍专用
closerAIGCcloserAI,一个深入探索前沿人工智能与AIGC领域的资讯平台,我们旨在让AIGC渗入我们的工作与生活中,让我们一起探索AIGC的无限可能性!aigc.douyoubuy.cn 【closerAI ComfyUI】电商赋能,AI模特套图生产,各种姿势自定义,高度保持人物服饰场景一致性,摆拍街拍专用…...
ARM学习(36)静态扫描规则学习以及工具使用
笔者来学习了解一下静态扫描以及其规则,并且亲身是实践一下对arm 架构的代码进行扫描。 1、静态扫描认识 静态扫描:对代码源文件按照一定的规则进行扫描,来发现一些潜在的问题或者风险,因为不涉及代码运行,所以其一般只是发现一些规范或则一些质量问题,当然这些可能存在潜…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
