k8s二進制安裝與部署

目錄

一、實驗目的

二、實驗環境

三、實驗步驟

3.1 操作系統初始化配置

3.2 部署 docker引擎

3.3 部署 etcd 集群

3.3.1 在 master01 節點上操作 ? ? ?? ??? ??? ??? ?

?3.3.2 在 node01 節點上操作

3.3.3 在 node02 節點上操作

3.4 部署 Master 組件

3.4.1 在 master01 節點上操作

?3.5 部署 Worker Node 組件

3.5.1 在所有 node 節點上操作

3.5.2 在 node01 節點上操作

3.6 部署 CNI 網絡組件

3.6.1 部署 flannel

?3.6.2 部署 Calico

3.7 部署 CoreDNS

3.7.1 在所有 node 節點上操作

3.7.2 在 master01 節點上操作

3.8 master02 節點部署

3.9 負載均衡部署

3.9.1 在lb01、lb02節點上操作

3.9.2 在master01 節點上操作

3.10 部署 Dashboard

3.10.1 在所有node節點上操作

3.10.2?在 master01 節點上操作


一、實驗目的

二進制搭建 Kubernetes v1.20 ? ?

二、實驗環境

主機名IP地址服務
k8s集群master01192.168.10.80kube-apiserver kube-controller-manager kube-scheduler etcd
k8s集群master02192.168.10.20kube-apiserver kube-controller-manager kube-scheduler etcd
k8s集群node01192.168.10.18?kubelet kube-proxy docker?
k8s集群node02192.168.10.19kubelet kube-proxy docker?
etcd集群節點1192.168.10.80etcd
etcd集群節點2192.168.10.18etcd
etcd集群節點3192.168.10.19etcd
負載均衡(master)192.168.10.21nginx+keepalive
負載均衡(backup)192.168.10.22nginx+keepalive
虛擬IP地址192.168.10.100/

三、實驗步驟

3.1 操作系統初始化配置

1、關閉防火墻

systemctl stop firewalld
systemctl disable firewalld
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X

2、關閉selinux

setenforce 0
sed -i 's/enforcing/disabled/' /etc/selinux/config

3、關閉swap

swapoff -a

4、根據規劃設置主機名

hostnamectl set-hostname master01
hostnamectl set-hostname node01
hostnamectl set-hostname node02

5、在master添加hosts

cat >> /etc/hosts << EOF
192.168.10.80 master01
192.168.10.20 master02
192.168.10.18 node01
192.168.10.19 node02
EOF

6、調整內核參數

cat > /etc/sysctl.d/k8s.conf << EOF

7、開啟網橋模式,可將網橋的流量傳遞給iptables鏈

net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1

8、關閉ipv6協議

net.ipv6.conf.all.disable_ipv6=1
net.ipv4.ip_forward=1
EOFsysctl --system

9、時間同步

yum install ntpdate -y
ntpdate time.windows.com

3.2 部署 docker引擎

1、所有 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

2、啟動docker并設置開機自啟

systemctl start docker.service
systemctl enable docker.service?

3.3 部署 etcd 集群

etcd是CoreOS團隊于2013年6月發起的開源項目,它的目標是構建一個高可用的分布式鍵值(key-value)數據庫。etcd內部采用raft協議作為一致性算法,etcd是go語言編寫的。

etcd 作為服務發現系統,有以下的特點:
簡單:安裝配置簡單,而且提供了HTTP API進行交互,使用也很簡單
安全:支持SSL證書驗證
快速:單實例支持每秒2k+讀操作
可靠:采用raft算法,實現分布式系統數據的可用性和一致性

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 證書,它支持簽三種類型的證書:
1、client 證書,服務端連接客戶端時攜帶的證書,用于客戶端驗證服務端身份,如 kube-apiserver 訪問 etcd;
2、server 證書,客戶端連接服務端時攜帶的證書,用于服務端驗證客戶端身份,如 etcd 對外提供服務;
3、peer 證書,相互之間連接時使用的證書,如 etcd 節點之間進行驗證和通信。
這里全部都使用同一套證書認證。

3.3.1 在 master01 節點上操作 ? ? ?? ??? ??? ??? ?

1、準備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*

------------------------------------------------------------------------------------------
cfssl:證書簽發的工具命令
cfssljson:將 cfssl 生成的證書(json格式)變為文件承載式證書
cfssl-certinfo:驗證證書的信息
cfssl-certinfo -cert <證書名稱>?? ??? ??? ?#查看證書的信息
------------------------------------------------------------------------------------------

2、生成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/
./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-v3.4.9-linux-amd64.tar.gz 到 /opt/k8s 目錄中,啟動etcd服務
https://github.com/etcd-io/etcd/releases/download/v3.4.9/etcd-v3.4.9-linux-amd64.tar.gzcd /opt/k8s/
tar zxvf etcd-v3.4.9-linux-amd64.tar.gz
ls etcd-v3.4.9-linux-amd64
Documentation ?etcd ?etcdctl ?README-etcdctl.md ?README.md ?READMEv2-etcdctl.md
------------------------------------------------------------------------------------------
etcd就是etcd 服務的啟動命令,后面可跟各種啟動參數
etcdctl主要為etcd 服務提供了命令行操作
------------------------------------------------------------------------------------------#創建用于存放 etcd 配置文件,命令文件,證書的目錄
mkdir -p /opt/etcd/{cfg,bin,ssl}cd /opt/k8s/etcd-v3.4.9-linux-amd64/
mv etcd etcdctl /opt/etcd/bin/
cp /opt/k8s/etcd-cert/*.pem /opt/etcd/ssl/cd /opt/k8s/
./etcd.sh etcd01 192.168.10.80 etcd02=https://192.168.10.18:2380,etcd03=https://192.168.10.19:2380
#進入卡住狀態等待其他節點加入,這里需要三臺etcd服務同時啟動,如果只啟動其中一臺后,服務會卡在那里,直到集群中所有etcd節點都已啟動,可忽略這個情況#可另外打開一個窗口查看etcd進程是否正常
ps -ef | grep etcd#把etcd相關證書文件、命令文件和服務管理文件全部拷貝到另外兩個etcd集群節點
scp -r /opt/etcd/ root@192.168.10.18:/opt/
scp -r /opt/etcd/ root@192.168.10.19:/opt/
scp /usr/lib/systemd/system/etcd.service root@192.168.10.18:/usr/lib/systemd/system/
scp /usr/lib/systemd/system/etcd.service root@192.168.10.19:/usr/lib/systemd/system/

3.3.2 在 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.10.18:2380"?? ??? ??? ?#修改
ETCD_LISTEN_CLIENT_URLS="https://192.168.10.18:2379"?? ??? ?#修改#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.10.18:2380"?? ??? ?#修改
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.10.18:2379"?? ??? ??? ??? ?#修改
ETCD_INITIAL_CLUSTER="etcd01=https://192.168.10.80:2380,etcd02=https://192.168.10.18:2380,etcd03=https://192.168.10.19:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"#啟動etcd服務
systemctl start etcd
systemctl enable etcd ? ? ##systemctl enable --now etcd
systemctl在enable、disable、mask子命令里面增加了--now選項,可以激活同時啟動服務,激活同時停止服務等。systemctl status etcd

3.3.3 在 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.10.19:2380"?? ??? ??? ?#修改
ETCD_LISTEN_CLIENT_URLS="https://192.168.10.19:2379"?? ??? ?#修改#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.10.19:2380"?? ??? ?#修改
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.10.19:2379"?? ??? ??? ??? ?#修改
ETCD_INITIAL_CLUSTER="etcd01=https://192.168.10.80:2380,etcd02=https://192.168.10.18:2380,etcd03=https://192.168.10.19: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 --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.10.80:2379,https://192.168.10.18:2379,https://192.168.10.19:2379" endpoint health --write-out=tableETCDCTL_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.10.80:2379,https://192.168.10.18:2379,https://192.168.10.19:2379" endpoint status --write-out=table------------------------------------------------------------------------------------------
--cert-file:識別HTTPS端使用SSL證書文件
--key-file:使用此SSL密鑰文件標識HTTPS客戶端
--ca-file:使用此CA證書驗證啟用https的服務器的證書
--endpoints:集群中以逗號分隔的機器地址列表
cluster-health:檢查etcd集群的運行狀況
------------------------------------------------------------------------------------------#查看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.10.80:2379,https://192.168.10.18:2379,https://192.168.10.19:2379" --write-out=table member list

master組件簽發證書

3.4 部署 Master 組件

3.4.1 在 master01 節點上操作

#上傳 master.zip 和 k8s-cert.sh 到 /opt/k8s 目錄中,解壓 master.zip 壓縮包
cd /opt/k8s/
unzip master.zip
chmod +x *.sh#創建kubernetes工作目錄
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/
./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證書、apiserver相關證書和私鑰到 kubernetes工作目錄的 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二進制文件。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.shcat /opt/kubernetes/cfg/token.csv#二進制文件、token、證書都準備好后,開啟 apiserver 服務
cd /opt/k8s/
./apiserver.sh 192.168.10.80 https://192.168.10.80:2379,https://192.168.10.18:2379,https://192.168.10.19:2379#檢查進程是否啟動成功
ps aux | grep kube-apiservernetstat -natp | grep 6443 ? #安全端口6443用于接收HTTPS請求,用于基于Token文件或客戶端證書等認證#啟動 scheduler 服務
cd /opt/k8s/
./scheduler.sh
ps aux | grep kube-scheduler#啟動 controller-manager 服務
./controller-manager.sh
ps aux | grep kube-controller-manager#生成kubectl連接集群的kubeconfig文件
./admin.sh#通過kubectl工具查看當前集群組件狀態
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


3.5 部署 Worker Node 組件

3.5.1 在所有 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.10.18:/opt/kubernetes/bin/
scp kubelet kube-proxy root@192.168.10.19:/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/kubeconfigcd /opt/k8s/kubeconfig
chmod +x kubeconfig.sh
./kubeconfig.sh 192.168.10.80 /opt/k8s/k8s-cert/#把配置文件 bootstrap.kubeconfig、kube-proxy.kubeconfig 拷貝到 node 節點
scp bootstrap.kubeconfig kube-proxy.kubeconfig root@192.168.10.18:/opt/kubernetes/cfg/
scp bootstrap.kubeconfig kube-proxy.kubeconfig root@192.168.10.19:/opt/kubernetes/cfg/#RBAC授權,使用戶 kubelet-bootstrap 能夠有權限發起 CSR 請求證書
kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap若執行失敗,可先給kubectl綁定默認cluster-admin管理員集群角色,授權集群操作權限
kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous

------------------------------------------------------------------------------------------
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 生成一個證書,以后的訪問都是用證書做認證了。
------------------------------------------------------------------------------------------

3.5.2 在 node01 節點上操作

#啟動 kubelet 服務
cd /opt/
./kubelet.sh 192.168.10.18
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
192.168.10.18 ? NotReady ? <none> ? 108s ? v1.20.11//在 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.10.18
ps aux | grep kube-proxy

3.6 部署 CNI 網絡組件

3.6.1 部署 flannel

K8S 中 Pod 網絡通信:
●Pod 內容器與容器之間的通信
在同一個 Pod 內的容器(Pod 內的容器是不會跨宿主機的)共享同一個網絡命名空間,相當于它們在同一臺機器上一樣,可以用 localhost 地址訪問彼此的端口。●同一個 Node 內 Pod 之間的通信
每個 Pod 都有一個真實的全局 IP 地址,同一個 Node 內的不同 Pod 之間可以直接采用對方 Pod 的 IP 地址進行通信,Pod1 與 Pod2 都是通過 Veth 連接到同一個 docker0/cni0 網橋,網段相同,所以它們之間可以直接通信。●不同 Node 上 Pod 之間的通信
Pod 地址與 docker0 在同一網段,docker0 網段與宿主機網卡是兩個不同的網段,且不同 Node 之間的通信只能通過宿主機的物理網卡進行。
要想實現不同 Node 上 Pod 之間的通信,就必須想辦法通過主機的物理網卡 IP 地址進行尋址和通信。因此要滿足兩個條件:Pod 的 IP 不能沖突;將 Pod 的 IP 和所在的 Node 的 IP 關聯起來,通過這個關聯讓不同 Node 上 Pod 之間直接通過內網 IP 地址通信。Overlay Network:
疊加網絡,在二層或者三層基礎網絡上疊加的一種虛擬網絡技術模式,該網絡中的主機通過虛擬鏈路隧道連接起來。
通過Overlay技術(可以理解成隧道技術),在原始報文外再包一層四層協議(UDP協議),通過主機網絡進行路由轉發。這種方式性能有一定損耗,主要體現在對原始報文的修改。目前Overlay主要采用VXLAN。VXLAN:
將源數據包封裝到UDP中,并使用基礎網絡的IP/MAC作為外層報文頭進行封裝,然后在以太網上傳輸,到達目的地后由隧道端點解封裝并將數據發送給目標地址。Flannel:
Flannel 的功能是讓集群中的不同節點主機創建的 Docker 容器都具有全集群唯一的虛擬 IP 地址。
Flannel 是 Overlay 網絡的一種,也是將 TCP 源數據包封裝在另一種網絡包里面進行路由轉發和通信,目前支持 UDP、VXLAN、Host-gw 3種數據轉發方式。#Flannel UDP 模式的工作原理:
數據從主機 A 上 Pod 的源容器中發出后,經由所在主機的 docker0/cni0 網絡接口轉發到 flannel0 接口,flanneld 服務監聽在 flannel0 虛擬網卡的另外一端。
Flannel 通過 Etcd 服務維護了一張節點間的路由表。源主機 A 的 flanneld 服務將原本的數據內容封裝到 UDP 報文中, 根據自己的路由表通過物理網卡投遞給目的節點主機 B 的 flanneld 服務,數據到達以后被解包,然后直接進入目的節點的 flannel0 接口, 之后被轉發到目的主機的 docker0/cni0 網橋,最后就像本機容器通信一樣由 docker0/cni0 轉發到目標容器。#ETCD 之 Flannel 提供說明:
存儲管理Flannel可分配的IP地址段資源
監控 ETCD 中每個 Pod 的實際地址,并在內存中建立維護 Pod 節點路由表由于 UDP 模式是在用戶態做轉發,會多一次報文隧道封裝,因此性能上會比在內核態做轉發的 VXLAN 模式差。#VXLAN 模式:
VXLAN 模式使用比較簡單,flannel 會在各節點生成一個 flannel.1 的 VXLAN 網卡(VTEP設備,負責 VXLAN 封裝和解封裝)。
VXLAN 模式下作是由內核進行的。flannel 不轉發數據,僅動態設置 ARP 表和 MAC 表項。
UDP 模式的 flannel0 網卡是三層轉發,使用 flannel0 時在物理網絡之上構建三層網絡,屬于 ip in udp ;VXLAN封包與解包的工 模式是二層實現,overlay 是數據幀,屬于 mac in udp 。#Flannel VXLAN 模式跨主機的工作原理:
1、數據幀從主機 A 上 Pod 的源容器中發出后,經由所在主機的 docker0/cni0 網絡接口轉發到 flannel.1 接口
2、flannel.1 收到數據幀后添加 VXLAN 頭部,封裝在 UDP 報文中
3、主機 A 通過物理網卡發送封包到主機 B 的物理網卡中
4、主機 B 的物理網卡再通過 VXLAN 默認端口 4789 轉發到 flannel.1 接口進行解封裝
5、解封裝以后,內核將數據幀發送到 cni0,最后由 cni0 發送到橋接到此接口的容器 B 中。
//在所有節點上操作
#上傳 cni-plugins-linux-amd64-v0.8.6.tgz 和 flannel.tar 到 /opt 目錄中
cd /opt/
docker load -i flannel.tarmkdir /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 ? ? ? ? ?7skubectl get nodes
NAME ? ? ? ? ? ?STATUS ? ROLES ? ?AGE ? VERSION
192.168.10.18 ? Ready ? ?<none> ? 81m ? v1.20.11


3.6.2 部署 Calico

#k8s 組網方案對比:
●flannel方案
需要在每個節點上把發向容器的數據包進行封裝后,再用隧道將封裝后的數據包發送到運行著目標Pod的node節點上。目標node節點再負責去掉封裝,將去除封裝的數據包發送到目標Pod上。數據通信性能則大受影響。●calico方案
Calico不使用隧道或NAT來實現轉發,而是把Host當作Internet中的路由器,使用BGP同步路由,并使用iptables來做安全訪問策略,完成跨Host轉發。
采用直接路由的方式,這種方式性能損耗最低,不需要修改報文數據,但是如果網絡比較復雜場景下,路由表會很復雜,對運維同事提出了較高的要求。#Calico 主要由三個部分組成:
Calico CNI插件:主要負責與kubernetes對接,供kubelet調用使用。
Felix:負責維護宿主機上的路由規則、FIB轉發信息庫等。
BIRD:負責分發路由規則,類似路由器。
Confd:配置管理組件。#Calico 工作原理:
Calico 是通過路由表來維護每個 pod 的通信。Calico 的 CNI 插件會為每個容器設置一個 veth pair 設備, 然后把另一端接入到宿主機網絡空間,由于沒有網橋,CNI 插件還需要在宿主機上為每個容器的 veth pair 設備配置一條路由規則, 用于接收傳入的 IP 包。
有了這樣的 veth pair 設備以后,容器發出的 IP 包就會通過 veth pair 設備到達宿主機,然后宿主機根據路由規則的下一跳地址, 發送給正確的網關,然后到達目標宿主機,再到達目標容器。
這些路由規則都是 Felix 維護配置的,而路由信息則是 Calico BIRD 組件基于 BGP 分發而來。
calico 實際上是將集群里所有的節點都當做邊界路由器來處理,他們一起組成了一個全互聯的網絡,彼此之間通過 BGP 交換路由, 這些節點我們叫做 BGP Peer。目前比較常用的CNI網絡組件是flannel和calico,flannel的功能比較簡單,不具備復雜的網絡策略配置能力,calico是比較出色的網絡管理插件,但具備復雜網絡配置能力的同時,往往意味著本身的配置比較復雜,所以相對而言,比較小而簡單的集群使用flannel,考慮到日后擴容,未來網絡可能需要加入更多設備,配置更多網絡策略,則使用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_CIDRvalue: "10.244.0.0/16" ? ? ? ?#Calico 默認使用的網段為 192.168.0.0/16kubectl apply -f calico.yamlkubectl 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---------- node02 節點部署 ----------
//在 node01 節點上操作
cd /opt/
scp kubelet.sh proxy.sh root@192.168.10.19:/opt/
scp -r /opt/cni root@192.168.10.19:/opt///在 node02 節點上操作
#啟動kubelet服務
cd /opt/
chmod +x kubelet.sh
./kubelet.sh 192.168.10.19//在 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_CJDcpVsmdvnh81y0kubectl 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.10.19#查看群集中的節點狀態
kubectl get nodes

3.7 部署 CoreDNS

CoreDNS:可以為集群中的 service 資源創建一個域名 與 IP 的對應關系解析

3.7.1 在所有 node 節點上操作

#上傳 coredns.tar 到 /opt 目錄中
cd /opt
docker load -i coredns.tar

3.7.2 在 master01 節點上操作

#上傳 coredns.yaml 文件到 /opt/k8s 目錄中,部署 CoreDNS?
cd /opt/k8s
kubectl apply -f coredns.yamlkubectl get pods -n kube-system?
NAME ? ? ? ? ? ? ? ? ? ? ? ? ?READY ? STATUS ? ?RESTARTS ? AGE
coredns-5ffbfd976d-j6shb ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ?32s#DNS 解析測試
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.localName: ? ? ?kubernetes
Address 1: 10.0.0.1 kubernetes.default.svc.cluster.local

注:
如果出現以下報錯
[root@master01 k8s]# kubectl run -it ?--image=busybox:1.28.4 sh
If you don't see a command prompt, try pressing enter.
Error attaching, falling back to logs: unable to upgrade connection: Forbidden (user=system:anonymous, verb=create, resource=nodes, subresource=proxy)
Error from server (Forbidden): Forbidden (user=system:anonymous, verb=get, resource=nodes, subresource=proxy) ( pods/log sh)

需要添加 rbac的權限 ?直接使用kubectl綁定 ?clusteradmin 管理員集群角色 ?授權操作權限

[root@master01 k8s]# kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous
clusterrolebinding.rbac.authorization.k8s.io/cluster-system-anonymous created

3.8 master02 節點部署

//從 master01 節點上拷貝證書文件、各master組件的配置文件和服務管理文件到 master02 節點
scp -r /opt/etcd/ root@192.168.10.20:/opt/
scp -r /opt/kubernetes/ root@192.168.10.20:/opt
scp -r /root/.kube root@192.168.10.20:/root
scp /usr/lib/systemd/system/{kube-apiserver,kube-controller-manager,kube-scheduler}.service root@192.168.10.20:/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.10.80:2379,https://192.168.10.18:2379,https://192.168.10.19:2379 \
--bind-address=192.168.10.20 \?? ??? ??? ??? ?#修改
--secure-port=6443 \
--advertise-address=192.168.10.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名
//此時在master02節點查到的node節點狀態僅是從etcd查詢到的信息,而此時node節點實際上并未與master02節點建立通信連接,因此需要使用一個VIP把node節點與master節點都關聯起來

3.9 負載均衡部署

配置load balancer集群雙機熱備負載均衡(nginx實現負載均衡,keepalived實現雙機熱備)

3.9.1 在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.10.80:6443;server 192.168.10.20: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.10.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
ip a?? ??? ??? ??? ?#查看VIP是否生成//修改node節點上的bootstrap.kubeconfig,kubelet.kubeconfig配置文件為VIP
cd /opt/kubernetes/cfg/
vim bootstrap.kubeconfig?
server: https://192.168.10.100:6443vim kubelet.kubeconfig
server: https://192.168.10.100:6443vim kube-proxy.kubeconfig
server: https://192.168.10.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 ? ? ?84739/nginx: master?
tcp ? ? ? ?0 ? ? ?0 0.0.0.0:80 ? ? ? ? ? ? ?0.0.0.0:* ? ? ? ? ? ? ? LISTEN ? ? ?84739/nginx: master?
tcp ? ? ? ?0 ? ? ?0 192.168.10.21:60382 ? ? 192.168.10.20:6443 ? ? ?ESTABLISHED 84741/nginx: worker?
tcp ? ? ? ?0 ? ? ?0 192.168.10.100:6443 ? ? 192.168.10.18:41650 ? ? ESTABLISHED 84741/nginx: worker?
tcp ? ? ? ?0 ? ? ?0 192.168.10.100:6443 ? ? 192.168.10.19:49726 ? ? ESTABLISHED 84741/nginx: worker?
tcp ? ? ? ?0 ? ? ?0 192.168.10.21:35234 ? ? 192.168.10.80:6443 ? ? ?ESTABLISHED 84741/nginx: worker?
tcp ? ? ? ?0 ? ? ?0 192.168.10.100:6443 ? ? 192.168.10.18:41648 ? ? ESTABLISHED 84741/nginx: worker?
tcp ? ? ? ?0 ? ? ?0 192.168.10.100:6443 ? ? 192.168.10.19:49728 ? ? ESTABLISHED 84742/nginx: worker?
tcp ? ? ? ?0 ? ? ?0 192.168.10.100:6443 ? ? 192.168.10.18:41646 ? ? ESTABLISHED 84741/nginx: worker?
tcp ? ? ? ?0 ? ? ?0 192.168.10.21:32786 ? ? 192.168.10.20:6443 ? ? ?ESTABLISHED 84741/nginx: worker?
tcp ? ? ? ?0 ? ? ?0 192.168.10.100:6443 ? ? 192.168.10.18:41656 ? ? ESTABLISHED 84741/nginx: worker?
tcp ? ? ? ?0 ? ? ?0 192.168.10.21:60378 ? ? 192.168.10.20:6443 ? ? ?ESTABLISHED 84741/nginx: worker?
tcp ? ? ? ?0 ? ? ?0 192.168.10.21:32794 ? ? 192.168.10.20:6443 ? ? ?ESTABLISHED 84741/nginx: worker?
tcp ? ? ? ?0 ? ? ?0 192.168.10.100:6443 ? ? 192.168.10.19:49724 ? ? ESTABLISHED 84741/nginx: worker?
tcp ? ? ? ?0 ? ? ?0 192.168.10.21:35886 ? ? 192.168.10.80:6443 ? ? ?ESTABLISHED 84741/nginx: worker?
tcp ? ? ? ?0 ? ? ?0 192.168.10.100:6443 ? ? 192.168.10.19:51372 ? ? ESTABLISHED 84742/nginx: worker?
tcp ? ? ? ?0 ? ? ?0 192.168.10.100:6443 ? ? 192.168.10.19:49722 ? ? ESTABLISHED 84741/nginx: worker?
tcp ? ? ? ?0 ? ? ?0 192.168.10.100:6443 ? ? 192.168.10.19:49702 ? ? ESTABLISHED 84741/nginx: worker


3.9.2 在master01 節點上操作

//測試創建pod
kubectl run nginx --image=nginx//查看Pod的狀態信息
kubectl get pods
NAME ? ? ? ? ? ? ? ? ? ?READY ? STATUS ? ?RESTARTS ? AGE
nginx                   1/1     Running   0          4h12m? #創建完成,運行中kubectl get pods -o wide
NAME ? ? ? ? ? ? ? ? ? ?READY ? STATUS ? ?RESTARTS ? AGE ? IP ? ? ? ? ? ?NODE ? ? ? ? ? ?NOMINATED NODE
nginx   1/1     Running   0          4h12m   10.244.1.3   192.168.10.19   <none>           <none>//READY為1/1,表示這個Pod中有1個容器//在對應網段的node節點上操作,可以直接使用瀏覽器或者curl命令訪問
curl 10.244.1.3//這時在master01節點上查看nginx日志
kubectl logs nginx


3.10 部署 Dashboard

Dashboard 介紹
儀表板是基于Web的Kubernetes用戶界面。您可以使用儀表板將容器化應用程序部署到Kubernetes集群,對容器化應用程序進行故障排除,并管理集群本身及其伴隨資源。您可以使用儀表板來概述群集上運行的應用程序,以及創建或修改單個Kubernetes資源(例如deployment,job,daemonset等)。例如,您可以使用部署向導擴展部署,啟動滾動更新,重新啟動Pod或部署新應用程序。儀表板還提供有關群集中Kubernetes資源狀態以及可能發生的任何錯誤的信息。

3.10.1 在所有node節點上操作

在所有node節點上上傳以下壓縮包

3.10.2?在 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://NodeIP:30001

實驗完成!?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/15217.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/15217.shtml
英文地址,請注明出處:http://en.pswp.cn/web/15217.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Softing工業推出新品edgeGate:一款用于工業邊緣和云應用的硬件網關

2024年4月17日&#xff08;哈爾&#xff09;&#xff0c;Softing工業自動化在2024年漢諾威工業博覽會上首次展示了新品edgeGate。該產品是一個無需維護的硬件物聯網網關解決方案&#xff0c;可將生產數據從PLC和數控機床控制器傳輸至工業邊緣及物聯網云平臺。 &#xff08;edge…

MiniMax Golang2輪面試,期望薪資25K

一面 1、自我介紹 2、簡單介紹一下你們成立了這個finance的財務中臺之后&#xff0c;整體的服務架構是怎么樣的嗎&#xff1f; 3、就你提到的預算池項目&#xff0c;展開說說背景&#xff0c;以及解決了怎么樣的問題&#xff1f; 4、為什么采用針對T-1訂單的異步計算方案&a…

jmeter線程組(下篇)

線程組 線程組作為JMeter測試計劃的核心組件之一&#xff0c;對于模擬并發用戶的行為至關重要。線程組元件是整個測試計劃的入口&#xff0c;所有的取樣器和控制器必須放置在線程組下。 可以將線程組視為一個虛擬用戶池&#xff0c;其中每個線程可被理解為一個虛擬用戶&#x…

(Java面試題分享)萬里長征-03-搜狐

萬里長征-03-搜狐 ? 以下內容基于GPT-4o模型 問題 1.LeetCode103 二叉樹的鋸齒形層序遍歷 103. 二叉樹的鋸齒形層序遍歷 - 力扣&#xff08;LeetCode&#xff09; 2.LeetCode5 最長回文子串 5. 最長回文子串 - 力扣&#xff08;LeetCode&#xff09; 3.Kafka為何那么快 …

java如何創建Class對象?

請思考一個問題&#xff1a;如果你想在java程序運行時獲得某個類的信息&#xff0c;你會怎么辦&#xff1f; 首先要獲得該類的Class對象&#xff0c;然后才可以通過Class類中的方法來獲得與該Class對象相對應的類的信息。 有3種方法來獲得類的Class對象&#xff1a; 1.用Cla…

【數據結構與算法 | 基礎篇】[棧專題]力扣20,150

1. 力扣20 : 有效的符號 (1). 題 給定一個只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判斷字符串是否有效。 有效字符串需滿足&#xff1a; 左括號必須用相同類型的右括號閉合。左括號必須以正確的順序閉合。每個…

初學者都能掌握的操作符(中)

&#xff08;1&#xff09;位操作符&#xff08;& | ^&#xff09; &&#xff1a;&#xff08;按二進制位“與”&#xff09; 也就是兩個數的每一位二進制數按照 “與” 的算法&#xff0c;如下&#xff1a; int a 3 ,b 5 ; c a & b; 我們首先寫出a和b的二進…

退格(刪除)鍵

題目描述 用 來表示退格鍵&#xff0c;遇到 來表示退格鍵&#xff0c;遇到 來表示退格鍵&#xff0c;遇到就刪除上一位字符&#xff08;如果有&#xff09; 在鍵盤上從左到右一次輸入一串字符串&#xff0c;請輸出最終字符的個數。注&#xff1a;退格鍵不會出現在最終的剩余字…

5.23.12 計算機視覺的 Inception 架構

1. 介紹 分類性能的提升往往會轉化為各種應用領域中顯著的質量提升&#xff0c;深度卷積架構的架構改進可用于提高大多數其他計算機視覺任務的性能&#xff0c;這些任務越來越依賴于高質量的學習視覺特征。在 AlexNet 功能無法與手工設計、制作的解決方案競爭的情況下&#xf…

如何評價劉強東說“業績不好的人不是我兄弟”

在近日的一次京東管理層會議上&#xff0c;創始人劉強東以不容置疑的口吻表明了對公司文化的堅定態度&#xff1a;“凡是長期業績不好&#xff0c;從來不拼搏的人&#xff0c;不是我的兄弟。”這句話不僅是對那些工作表現不佳的員工的直接警告&#xff0c;也透露出京東在追求業…

three.js能實現啥效果?看過來,這里都是它的菜(08)

在Three.js中實現旋轉動畫的原理是通過修改對象的旋轉屬性來實現的&#xff0c;通常使用渲染循環&#xff08;render loop&#xff09;來更新對象的旋轉狀態&#xff0c;從而實現動畫效果。 具體的原理包括以下幾個步驟&#xff1a; 創建對象&#xff1a;首先創建一個需要旋轉…

AIGC-風格遷移-style Injection in Diffusion-CVPR2024HighLight-論文精度

Style Injection in Diffusion: A Training-free Approach for Adapting Large-scale Diffusion Models for Style Transfer-CVPR2024HighLight 代碼&#xff1a;https://github.com/jiwoogit/StyleID 論文&#xff1a;https://jiwoogit.github.io/StyleID_site/ 為了解決風格遷…

python3.12虛擬環境下ModuleNotFoundError: No module named ‘distutils‘的解決辦法

python3.12下面venv虛擬環境&#xff0c;安裝pwntools&#xff0c;運行Ropgadget提示&#xff1a;ModuleNotFoundError: No module named distutils’的解決辦法 (py3xt) :~/py3/bin$ ROPgadget Traceback (most recent call last):File "/home/a24/py3xt/bin/ROPgadget…

你真的會使用Vue3的onMounted鉤子函數嗎?Vue3中onMounted的用法詳解

目錄 一、onMounted的前世今生 1.1、onMounted是什么 1.2、onMounted在vue2中的前身 1.2.1、vue2中的onMounted 1.2.2、Vue2與Vue3的onMounted對比 1.3、vue3中onMounted的用法 1.3.1、基礎用法 1.3.2、順序執行異步操作 1.3.3、并行執行多個異步操作 1.3.4、執行一次…

Rust腐蝕怎么用服務器一鍵開服聯機教程

1、進入控制面板 首次登陸需要點擊下方重置密碼&#xff0c;如何再點擊登錄面板&#xff0c;點擊后會跳轉到登錄頁面&#xff0c;輸入用戶名和密碼登錄即可 2、設置游戲端口 由于腐蝕的設置需要三個端口&#xff0c;它們用于游戲端口&#xff08;必須為首選端口&#xff09;&a…

jenkins 部署golang 應用到k8s與測試環境

1.宿主機安裝jenkins 不要用docker 為什么&#xff1a;docker jenkins你只有jenkins&#xff0c; 你想做golang編譯的情況&#xff0c;它的鏡像里面缺少go環境。 而宿主機安裝的情況&#xff0c;jenkins是可以通過環境變量修改來訪問宿主機里面安裝的內容。 2.插件 // docke…

FFMPEG 解碼過程初步學習

1. 視頻文件解碼過程 解碼過程 步驟如下&#xff1a; 視頻文件&#xff08;封裝格式&#xff0c;MP4/FLV/AVI 等&#xff09;獲取視頻格式信息等解復用為Stream 流&#xff0c; 準備解碼用的Codec將Stream 流 使用解碼器解為Raw 格式針 1.1 音視頻格式填充&#xff1a; int…

找不到msvcr110.dll無法繼續執行代碼的原因分析及解決方法

在計算機使用過程中&#xff0c;我們經常會遇到一些錯誤提示&#xff0c;其中之一就是找不到msvcr110.dll文件。這個錯誤通常發生在運行某些程序或游戲時&#xff0c;系統無法找到所需的動態鏈接庫文件。為了解決這個問題&#xff0c;下面我將介紹5種常見的解決方法。 一&#…

Vue3實現上傳照片以及回顯

Vue3實現上傳照片以及回顯 一、安裝Element Plus二、案例1、基本示例 三、進階案例1、代碼2、代碼解釋1、上傳接口展示2、查詢接口展示組件屬性 3、效果展示 一、安裝Element Plus 使用 Element Plus 組件庫來實現上傳照片和回顯同樣很簡單&#xff0c;你可以按照以下步驟進行…

用棧實現隊列(C語言)

目錄 題目題目分析 代碼棧的實現結構體。棧的初始化棧的銷毀 入棧刪除查找頂部數據判空 答案結構體初始化插入數據刪除數據獲取隊列開頭元素判空銷毀棧 題目 題目分析 鏈接: 題目 請你僅使用兩個棧實現先入先出隊列。隊列應當支持一般隊列支持的所有操作&#xff08;push、po…