k8s二进制部署

news2024/12/25 18:30:04

目录

一、K8S常见的部署方式

1.1 K8S常见的部署方式

1.2 k8s部署 二进制与高可用的区别

二、Kubernetes二进制部署

2.1 Kubernetes二进制部署准备

① 服务器准备

② 签发证书环境准备

2.2 操作系统初始化配置

2.3 部署 etcd 集群

① 在 master01 节点上操作

② work node节点操作

③ master节点查看集群状态

④ work node 部署docker引擎

2.4 部署 Master 组件

① 在 master01 节点上操作

2.5 部署 Worker Node 组件

① 在所有 node 节点上操作

② 在 master01 节点上操作

③ 在 node01 节点启动kubelet 服务(node2同理)

④ master01 节点上操作,通过 CSR 请求

⑤ 在 node01 节点上操作(node2操作同理)

2.6 部署网络组件(部署 flannel)

① 在 node 节点上操作

② 在 master01 节点上操作


一、K8S常见的部署方式

1.1 K8S常见的部署方式

  • Minikube

    • Minikube是一个工具,可以在本地快速运行一个单节点微型K8S,仅用于学习、预览K8S的一些特性使用。
    • 部署地址:kubernetes.io/docs/setup/…
  • Kubeadm

    • Kubeadm也是一个工具,提供kubeadm init和kubeadm join,用于快速部署K8S集群,相对简单
    • 部署地址:kubernetes.io/docs/refere…
  • 二进制安装部署

  • 生产首选,从官方下载发行版的二进制包,手动部署每个组件和自签TLS证书,组成K8S集群,新手推荐。

    • 部署地址:github.com/kubernetes/…
  • Kubeadm降低部署门槛,但屏蔽了很多细节,遇到问题很难排查。如果想更容易可控,推荐使用二进制包部署Kubernetes集群,虽然手动部署麻烦点,期间可以学习很多工作原理,也利于后期维护。

1.2 k8s部署 二进制与高可用的区别

  • 二进制部署

    • 部署难,管理方便,集群伸展性能好
    • 更稳定,集群规模到达一定的规模(几百个节点、上万个Pod),二进制稳定性是要高于kubeadm部署
    • 遇到故障,宿主机起来了,进程也会起来
  • kubeadm部署

    • 部署简单,管理难
    • 是以一种容器管理容器的方式允许的组件及服务,故障恢复时间比二进制慢
    • 遇到故障,启动宿主机,再启动进程,最后去启动容器,集群才能恢复,速度比二进制慢

二、Kubernetes二进制部署

2.1 Kubernetes二进制部署准备

① 服务器准备

服务器IP地址安装工具
K8s集群master01(ectd节点1)192.168.226.12cfs证书生成工具(cfssl、cfssljson、cfssl-certinfo)、etcd证书生成工具
K8s集群node01(ectd节点2)192.168.226.16cfs证书生成工具(cfssl、cfssljson、cfssl-certinfo)、etcd证书生成工具、Flannel网络插件、docker容器引擎
K8s集群node02(ectd节点3)192.168.142.17cfs证书生成工具(cfssl、cfssljson、cfssl-certinfo)、etcd证书生成工具、Flannel网络插件、docker容器引擎

② 签发证书环境准备

  • CFSSL是CloudFlare 公司开源的一款PKI/TLS_ 工具。CFSSL 包含-一个命令行工具和-一个用于签名、验证和捆绑TLS证书的HTTP API服务。使用Go语言编写。

  • CFSSL用来为eted提供TLS证书,它支持签三种类型的证书:

    • client 证书,服务端连接客户端时携带的证书,用于客户端验证服务端身份,如kube-apiserver 访问eted:
    • server. 证书,客户端连接服务瑞时携带的证书,用于服务端验证客户端身份,如eted对外提供服务:
    • peer证书,相互之间连接时使用的证书,如etcd节点之间进行验证和通信。
  • 这里全部使用同一套证书认证

2.2 操作系统初始化配置

#关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X

#关闭selinux
setenforce 0
sed -i 's/enforcing/disabled/' /etc/selinux/config   
复制代码

#关闭swap
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab   

#根据规划设置主机名
hostnamectl set-hostname master01
hostnamectl set-hostname node01
hostnamectl set-hostname node02

#在master添加hosts,添加各个节点的映射关系
cat >> /etc/hosts << EOF
192.168.142.10 master01
192.168.142.40 node01
192.168.142.100 node02
EOF
复制代码

#调整内核参数
cat > /etc/sysctl.d/k8s.conf << EOF
#开启网桥模式,可将网桥的流量传递给iptables链
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
#关闭ipv6协议
net.ipv6.conf.all.disable_ipv6=1
net.ipv4.ip_forward=1
EOF
复制代码

sysctl --system  #将配置文件重新加载

#时间同步
yum install ntpdate -y
ntpdate time.windows.com
复制代码

2.3 部署 etcd 集群

① 在 master01 节点上操作

#准备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

由于某些网络源加载速度过慢,可以将事先准备好的几个工具放入/usr/local/bin/目录下方
chmod +x /usr/local/bin/cfssl*
复制代码

#生成Etcd证书
mkdir /opt/k8s
cd /opt/k8s/

#上传 etcd-cert.sh 和 etcd.sh 到 /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/ 
vim etcd-cert.sh   #修改生成证书脚本
复制代码

 

 

 

./etcd-cert.sh     #运行生成证书脚本

ls   #查看/opt/k8s/etcd-cert/下生成的证书文件(如下所示)
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-v3.4.9-linux-amd64.tar.gz 到 /opt/k8s 目录中,启动etcd服务
cd /opt/k8s/
tar zxvf etcd-v3.4.9-linux-amd64.tar.gz

mkdir -p /opt/etcd/{cfg,bin,ssl}      #创建存放etcd相关证书文件
cd /opt/k8s/etcd-v3.4.9-linux-amd64/  #进入etcd软件包目录中
mv etcd etcdctl /opt/etcd/bin/
cp /opt/k8s/etcd-cert/*.pem /opt/etcd/ssl/
复制代码

 

cd /opt/k8s/
./etcd.sh etcd01 192.168.142.10 etcd02=https://192.168.142.40:2380,etcd03=https://192.168.142.100:2380
复制代码

 

ps -ef | grep etcd

scp -r /opt/etcd/ root@192.168.142.40:/opt/
scp -r /opt/etcd/ root@192.168.142.100:/opt/
scp /usr/lib/systemd/system/etcd.service root@192.168.142.40:/usr/lib/systemd/system/
scp /usr/lib/systemd/system/etcd.service root@192.168.142.100:/usr/lib/systemd/system/
复制代码

② work node节点操作

//在 node01 节点上操作
vim /opt/etcd/cfg/etcd
#[Member]
ETCD_NAME="etcd02"	  #修改
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.142.40:2380"		#监听地址集群成员之间通信的端口号
ETCD_LISTEN_CLIENT_URLS="https://192.168.142.40:2379"	#监听地址对外通信的端口号

#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.142.40:2380"	#修改
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.142.40:2379"		#修改
ETCD_INITIAL_CLUSTER="etcd01=https://192.168.142.10:2380,etcd02=https://192.168.142.40:2380,etcd03=https://192.168.142.100:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"

systemctl start etcd
systemctl enable etcd
systemctl status etcd
复制代码

//在 node02 节点上操作
vim /opt/etcd/cfg/etcd
#[Member]
ETCD_NAME="etcd03"	#修改
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.142.100:2380"		#修改
ETCD_LISTEN_CLIENT_URLS="https://192.168.142.100:2379"		#修改

#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.142.100:2380"	#修改
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.142.100:2379"		#修改
ETCD_INITIAL_CLUSTER="etcd01=https://192.168.142.10:2380,etcd02=https://192.168.142.40:2380,etcd03=https://192.168.142.100:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"

systemctl start etcd
systemctl enable etcd
systemctl status etcd
复制代码

③ master节点查看集群状态

#检查etcd群集状态
ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.142.10:2379,https://192.168.142.40:2379,https://192.168.142.100:2379" endpoint health --write-out=table

ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.142.10:2379,https://192.168.142.40:2379,https://192.168.142.100:2379" --write-out=table member list
复制代码

④ work node 部署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.io

systemctl start docker.service
systemctl enable docker.service 
复制代码

2.4 部署 Master 组件

① 在 master01 节点上操作

#上传 master.zip 和 k8s-cert.sh 到 /opt/k8s 目录中,解压 master.zip 压缩包
cd /opt/k8s/
unzip master.zip
chmod +x *.sh

mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}

#创建用于生成CA证书、相关组件的证书和私钥的目录
mkdir /opt/k8s/k8s-cert
mv /opt/k8s/k8s-cert.sh /opt/k8s/k8s-cert
cd /opt/k8s/k8s-cert/
vim k8s-cert.sh    #修改生成脚本文件
   
复制代码

 

./k8s-cert.sh      #运行脚本

ls *pem    #查看/opt/k8s/k8s-cert/目录下生成的相关证书文件
admin-key.pem  apiserver-key.pem  ca-key.pem  kube-proxy-key.pem  
admin.pem      apiserver.pem      ca.pem      kube-proxy.pem
复制代码

 

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

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"
EOF

chmod +x token.sh
./token.sh

cat /opt/kubernetes/cfg/token.csv

cd /opt/k8s/
./apiserver.sh 192.168.142.10 https://192.168.142.10:2379,https://192.168.142.40:2379,https://192.168.142.100:2379

ps aux | grep kube-apiserver

netstat -natp | grep 6443   #安全端口6443用于接收HTTPS请求,用于基于Token文件或客户端证书等认证
复制代码

 

cd /opt/k8s/

#启动 scheduler 服务
vim scheduler.sh    #修改scheduler.sh脚本
./scheduler.sh      #运行脚本
ps aux | grep kube-scheduler
复制代码

#启动 controller-manager 服务
vim controller-manager.sh   #修改controller-manager.sh脚本
./controller-manager.sh     #运行脚本
ps aux | grep kube-controller-manager
复制代码

 

 

#生成kubectl连接集群的证书
vim admin.sh    #修改admin.sh脚本
./admin.sh      #运行脚本
复制代码

kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous   

#通过kubectl工具查看当前集群组件状态 (如下显示为etcd正常连接)
kubectl get cs

Warning: v1 ComponentStatus is deprecated in v1.19+
NAME                 STATUS    MESSAGE             ERROR
scheduler            Healthy   ok
controller-manager   Healthy   ok
etcd-0               Healthy   {"health":"true"}
etcd-2               Healthy   {"health":"true"}
etcd-1               Healthy   {"health":"true"}
复制代码

#查看版本信息
kubectl version
复制代码

 

2.5 部署 Worker Node 组件

① 在所有 node 节点上操作

#创建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.142.40:/opt/kubernetes/bin/
scp kubelet kube-proxy root@192.168.142.100:/opt/kubernetes/bin/

#上传 kubeconfig.sh 文件到 /opt/k8s/kubeconfig 目录中,生成 kubeconfig 的配置文件
mkdir /opt/k8s/kubeconfig

cd /opt/k8s/kubeconfig
chmod +x kubeconfig.sh
./kubeconfig.sh 192.168.142.10 /opt/k8s/k8s-cert/

scp bootstrap.kubeconfig kube-proxy.kubeconfig root@192.168.142.40:/opt/kubernetes/cfg/
scp bootstrap.kubeconfig kube-proxy.kubeconfig root@192.168.142.100:/opt/kubernetes/cfg/

#RBAC授权,使用户 kubelet-bootstrap 能够有权限发起 CSR 请求
kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap

复制代码

③ 在 node01 节点启动kubelet 服务(node2同理)

#node1节点操作
#启动 kubelet 服务
cd /opt/
./kubelet.sh 192.168.142.40    #脚本后面添加node1节点IP地址
ps aux | grep kubelet

#node2节点操作
#启动 kubelet 服务
cd /opt/
./kubelet.sh 192.168.142.100
ps aux | grep kubelet
复制代码

 

④ master01 节点上操作,通过 CSR 请求

#检查到 node01 节点的 kubelet 发起的 CSR 请求,Pending 表示等待集群给该节点签发证书
kubectl get csr
NAME                                                   AGE  SIGNERNAME                                    REQUESTOR           CONDITION
node-csr-DJECTTouRGlosit2jbP-flUjpW2xzxi5rcokcy1dqWs   49s   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending
复制代码

 

#通过 CSR 请求(下方命令要加上node节点的name字段
kubectl certificate approve node-csr-DJECTTouRGlosit2jbP-flUjpW2xzxi5rcokcy1dqWs
#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 nodes   #查看node节点的状态
NAME              STATUS     ROLES    AGE     VERSION
192.168.142.100   NotReady   <none>   4m39s   v1.20.11
192.168.142.40    NotReady   <none>   4m28s   v1.20.11
复制代码

⑤ 在 node01 节点上操作(node2操作同理)

#加载 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.142.40
ps aux | grep kube-proxy
复制代码

2.6 部署网络组件(部署 flannel)

① 在 node 节点上操作

#上传 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.142.40   Ready    <none>   81m   v1.20.11
复制代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/360120.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用Fabric.js实现贝塞尔曲线波浪特效

一、前言 本文是在此基础上收到启发然后进行的变化&#xff0c;当然&#xff0c;观看与否不会影响接下来的阅读体验。 二、实现思路 其实整个波浪动画其实可以看成&#xff1a;在相对坐标系静止的视角下&#xff0c;一个正弦函数在直角坐标系上匀速平移时我们所观察到的效果…

如何防止订单重复提交

如何防止订单重复提交前言什么是重复下单为什么会重复下单&#xff1f;如何处理重复下单&#xff1f;利用数据库实现幂等利用Redis防重前言 最近在做电商项目&#xff0c;整理一下解决方案并帮助自己巩固知识点&#xff0c;此方案是结合了目前的业务环境&#xff0c;若有更好的…

Linux进程概念讲解

1、进程的基本概念在给进程下定义之前&#xff0c;我们先了解一下进程&#xff1a;我们在编写完代码并运行起来时&#xff0c;在我们的磁盘中会形成一个可执行文件&#xff0c;当我们双击这个可执行文件时&#xff08;程序时&#xff09;&#xff0c;这个程序会加载到内存中&am…

中央计算平台「上车」加速

随着英伟达、高通宣布在2024年开始陆续交付中央计算平台&#xff0c;Tier1正在跨域联合&#xff0c;以寻求在新的行业周期获得先发优势。 本月初&#xff0c;韩国LG电子宣布与高通达成合作协议&#xff0c;在原有座舱计算平台基础上&#xff0c;进一步拓展至智能驾驶领域。而在…

Transformer架构理解

参考&#xff1a; 1. Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Łukasz Kaiser, and Illia Polosukhin. 2017. Attention is all you need. In Proceedings of the 31st International Conference on Neural Information Pr…

Java 语法糖详解

本文从 Java 编译原理角度&#xff0c;深入字节码及 class 文件&#xff0c;抽丝剥茧&#xff0c;了解 Java 中的语法糖原理及用法&#xff0c;帮助大家在学会如何使用 Java 语法糖的同时&#xff0c;了解这些语法糖背后的原理。 什么是语法糖&#xff1f; 语法糖&#xff08…

金三银四一口气拿下三个offer的软件测试面试宝典,面试必看

说说你们怎么做接口自动化测试的☆☆☆☆☆ 我们是使用pythonrequesunittest来搭建我们的做接口自动化测试框架&#xff0c;使用python语言来调用第三方的类库requests来根据我们接口方法get或者post来发送接口请求&#xff0c;接收响应回来的数据进行适当的格式转换&#xff…

Python+Requests+PyTest+Excel+Allure 接口自动化测试实战

--------UnitTest框架和PyTest框架的简单认识对比与项目实战-------- 定义&#xff1a; Unittest是Python标准库中自带的单元测试框架&#xff0c;Unittest有时候也被称为PyUnit&#xff0c;就像JUnit是Java语言的标准单元测试框架一样&#xff0c;Unittest则是Python语言的标…

Python爬虫进阶 - win和linux下selenium使用代理

目录 Windows selenium配置 下载地址 Chrome Chromedriver 版本对应关系 实践测试 操作元素 浏览器操作 获取元素信息 鼠标操作 实战demo selenium添加代理 Linux selenium配置 检查服务器环境 下载安装第三方库&#xff08;最简单版&#xff09; 实践测试 代码…

【2.20】动态规划 +项目 + 存储引擎

01背包问题 现有一容量为w的背包&#xff0c;有3个物品&#xff0c;每个物品重量不同&#xff0c;价值不同&#xff0c;问&#xff0c;怎样装才能价值最大化&#xff1f; 明确dp数组含义和下标含义&#xff1a;dp[j]表示当前背包的最大价值。j表示背包容量。递推公式&#xf…

【期末复习】例题说明Prim算法与Kruskal算法

点睛Prim与Kruskal算法是用来求图的最小生成树的算法。最小生成树有n个顶点&#xff0c;n-1条边&#xff0c;不能有回路。Prim算法Prim算法的特点是从个体到整体&#xff0c;随机选定一个顶点为起始点出发&#xff0c;然后找它的权值最小的边对应的另一个顶点&#xff0c;这两个…

IEEE学生会员注册

IEEE学生会员注册0、引言IEEE 会员介绍1、IEEE学生会员会费2、加入学生会员2.1、创建/登录 IEEE 账户2.2、填写/维护 个人基本信息2.3、填写/维护 基本教育信息3、选择一个你将要加入的协会或社团4、确认购物车5、付款5.1、付款详情信息页5.2、扫码付款并验证5.3、会员确认邮件…

【前端提效】-- VsCode 实用插件推荐

EditorConfig for VS Code ***** 作用&#xff1a;多人协同开发&#xff0c;规范缩进风格&#xff0c;缩进大小&#xff0c;tab长度以及字符集等&#xff0c;解决不同IDE的编码范设置&#xff0c;在这里配置&#xff08;.editorconfig&#xff09;的代码规范规则优先级高于编辑…

Object.defineproperty方法

Object.defineproperty 的作用就是直接在一个对象上定义一个新属性&#xff0c;或者修改一个已经存在的属性Object.defineproperty可以接收三个参数Object.defineproperty(obj, prop, desc)obj : 第一个参数就是要在哪个对象身上添加或者修改属性prop : 第二个参数就是添加或修…

Ansys Zemax | 如何在存在全内反射 (TIR) 的情况下应用散射

在本文中&#xff0c;我们将展示如何利用虚拟表面来对具有全内反射 (TIR) 的物体进行建模&#xff0c;同时保持其他独特的表面特性&#xff0c;例如粗糙的表面结构。 下载 联系工作人员获取附件 简介 在OpticStudio中&#xff0c;全内反射 (TIR) 在其他表面属性&#xff08…

计网物理层

第一章&#xff1a;物理层 1、物理层的主要作用&#xff1a; ①、在不同的传输媒体上传输比特流 ②、屏蔽各种传输媒体的差异&#xff0c;为上层的数据链路层提供服务&#xff0c;使得上层的数据链路层无需考虑传输媒体是什么 2、传输媒体的种类&#xff1a; ①、导引型传…

python环境配置

python环境配置一、ADB环境配置1、ADB下载路径:2、点击下载3、解压并放到本地磁盘4、配置ADB环境变量二、Python环境配置1、Python下载路径:2、点击下载(默认下载最新的)3、解压并放到本地磁盘4、配置Python环境变量5、配置pip环境变量三、Pycharm安装1、pycharm下载路径:2、点…

“数字乡民”疑云:助农?坑农?

1月2日&#xff0c;“深入实施数字乡村发展行动&#xff0c;推动数字化应用场景研发推广”写入了国务院《关于做好2023年全面推进乡村振兴重点工作的意见》中&#xff0c;2022年中央一号文件也要求“大力推进数字乡村建设&#xff0c;推进智慧农业发展”。 在这之前&#xff0…

ArrayList删除元素时导致的java.util.ConcurrentModificationException错误的分析及源码解读

1.前言 集合对于开发者来说都不陌生&#xff0c;可以说是我们日常开发中使用最频繁的对象之一&#xff0c;尤其是ArrayList&#xff0c;可是对于一些开发者并不真正了解它&#xff0c;只是使用习惯了&#xff0c;也就按照集合中基础的一些api使用了&#xff0c;但有时候却因为错…

MacBook IDEA 顶部菜单栏不显示问题

文章目录背景&#xff1a;当前显示方式一1. 快捷键&#xff1a;双击shift 搜索 idea.vmoptions3. 在idea.vmoptions文件末尾添加 -Dapple.laf.useScreenMenuBarfalse方式二1. 访达 > 应用程序 > idea 右键 显示包内容2. 进入到bin包位置的命令终端3. 编辑文件 vi idea.pr…