關(guān)注「WeiyiGeek」每天帶你玩轉(zhuǎn)網(wǎng)絡安全運維志群、應用開發(fā)着绷、物聯(lián)網(wǎng)IOT學習!
希望各位看友【關(guān)注、點贊、評論帖渠、收藏即硼、投幣】子漩,助力每一個夢想豫喧。
文章目錄:
0x00 前言簡述
0x01 環(huán)境準備
- 主機規(guī)劃
- 軟件版本
- 網(wǎng)絡規(guī)劃
0x02 安裝部署
- 1.準備基礎主機環(huán)境配置
- 2.負載均衡管理ipvsadm工具安裝與內(nèi)核加載
- 3.高可用HAProxy與Keepalived軟件安裝配置
- 4.容器運行時containerd.io安裝配置
- 5.安裝源配置與初始化集群配置準備
- 6.使用kubeadm安裝部署K8S集群
- 7.部署配置 Calico 網(wǎng)絡插件
0x03 集群輔助插件部署
- 1.集群中基于nfs的provisioner的動態(tài)持卷環(huán)境部署
- 2.集群中安裝metrics-server獲取客戶端資源監(jiān)控指標
- 3.集群管理原生UI工具kubernetes-dashboard安裝部署
- 4.集群管理K9S客戶端工具安裝使用
- 5.集群服務Service七層負載均衡ingress環(huán)境搭建部署
0x00 前言簡述
描述: 在我博客以及前面的文章之中講解Kubernetes相關(guān)集群環(huán)境的搭建說明, 隨著K8S及其相關(guān)組件的迭代, 與讀者當前接觸的版本有所不同,在上一章中我們一起實踐了【使用二進制方式進行安裝部署高可用的K8S集群V1.23.6】(https://blog.weiyigeek.top/2022/5-7-654.html) , 所以本章將實踐使用kubeadm方式部署搭建高可用的kubernetes集群V1.23.7讲衫,此處仍然按照ubuntu 20.04系統(tǒng)以及haproxy缕棵、keepalive、containerd涉兽、etcd招驴、kubeadm、kubectl 等相關(guān)工具插件【最新或者穩(wěn)定的版本】進行實踐枷畏,這里不再對k8s等相關(guān)基礎知識做介紹别厘,如有新入門的童鞋,請查看如下文章(https://blog.weiyigeek.top/tags/k8s/) 進行基礎掃盲拥诡。
Kubernetes 簡述
Kubernetes (后續(xù)簡稱k8s)是 Google(2014年6月) 開源的一個容器編排引擎触趴,使用Go語言開發(fā),它支持自動化部署渴肉、大規(guī)娜吲常可伸縮、以及云平臺中多個主機上的容器化應用進行管理仇祭。其目標是讓部署容器化的應用更加簡單并且高效披蕉,提供了資源調(diào)度、部署管理乌奇、服務發(fā)現(xiàn)没讲、擴容縮容、狀態(tài) 監(jiān)控礁苗、維護等一整套功能, 努力成為跨主機集群的自動化部署爬凑、自動化擴展以及運行應用程序容器的平臺,它支持一些列CNCF畢業(yè)項目寂屏,包括 Containerd贰谣、calico 等 。
0x01 環(huán)境準備
主機規(guī)劃
溫馨提示: 同樣此處使用的是 Ubuntu 20.04 操作系統(tǒng), 該系統(tǒng)已做安全加固和內(nèi)核優(yōu)化符合等保2.0要求【SecOpsDev/Ubuntu-InitializeSecurity.sh at master · WeiyiGeek/SecOpsDev (github.com)】, 如你的Linux未進行相應配置環(huán)境可能與讀者有些許差異, 如需要進行(windows server迁霎、Ubuntu吱抚、CentOS)安全加固請參照如下加固腳本進行加固, 請大家瘋狂的 star 。
主機地址 | 主機名稱 | 主機配置 | 主機角色 | 軟件組件 |
---|---|---|---|---|
10.20.176.212 | devtest-master-212 | 8C/16G | 控制節(jié)點 | |
10.20.176.213 | devtest-master-213 | 8C/16G | 控制節(jié)點 | |
10.20.176.214 | devtest-master-214 | 8C/32G | 控制節(jié)點 | |
10.20.176.215 | devtest-work-215 | 8C/16G | 工作節(jié)點 | |
10.20.176.211 | slbvip.k8s.devtest | - | 虛擬VIP | 虛擬網(wǎng)卡地址 |
軟件版本
操作系統(tǒng)
- Ubuntu 20.04 LTS - 5.4.0-92-generic
高可用軟件
- ipvsadm - 1:1.31-1
- haproxy - 2.0.13-2
- keepalived - 1:2.0.19-2
ETCD數(shù)據(jù)庫
- etcd - v3.5.4
容器運行時
- containerd.io - 1.6.6
Kubernetes
- kubeadm - v1.23.7
- kube-apiserver - v1.23.7
- kube-controller-manager - v1.23.7
- kubectl - v1.23.7
- kubelet - v1.23.7
- kube-proxy - v1.23.7
- kube-scheduler - v1.23.7
網(wǎng)絡插件&輔助軟件
- calico - v3.22
- coredns - v1.9.1
- kubernetes-dashboard - v2.5.1
- k9s - v0.25.18
網(wǎng)絡規(guī)劃
子網(wǎng) Subnet | 網(wǎng)段 | 備注 |
---|---|---|
nodeSubnet | 10.20.176.0/24 | 宿主機節(jié)點子網(wǎng) |
ServiceSubnet | 10.96.0.0/16 | SVC 子網(wǎng) |
PodSubnet | 10.66.0.0/16 | POD 子網(wǎng) |
0x02 安裝部署
1.準備基礎主機環(huán)境配置
步驟 01.【所有主機】主機名設置按照上述主機規(guī)劃進行設置考廉。
# 例如, 在10.20.176.212主機中運行秘豹。
hostnamectl set-hostname devtest-master-212
# 例如, 在10.20.176.213主機中運行。
hostnamectl set-hostname devtest-master-213
# 例如, 在10.20.176.214主機中運行昌粤。
hostnamectl set-hostname devtest-master-214
# 例如, 在10.10.107.215主機中運行既绕。
hostnamectl set-hostname devtest-work-215
步驟 02.【所有主機】將規(guī)劃中的主機名稱與IP地址進行硬解析啄刹。
sudo tee -a /etc/hosts <<'EOF'
10.20.176.211 slbvip.k8s.devtest
10.20.176.212 devtest-master-212
10.20.176.213 devtest-master-213
10.20.176.214 devtest-master-214
10.20.176.215 devtest-work-215
EOF
步驟 03.驗證每個節(jié)點上IP、MAC 地址和 product_uuid 的唯一性,保證其能相互正常通信
# 使用命令 ip link 或 ifconfig -a 來獲取網(wǎng)絡接口的 MAC 地址
ifconfig -a
# 使用命令 查看 product_uuid 校驗
sudo cat /sys/class/dmi/id/product_uuid
步驟 04.【所有主機】系統(tǒng)時間同步與時區(qū)設置
date -R
sudo ntpdate ntp.aliyun.com
sudo timedatectl set-timezone Asia/Shanghai
# 或者
# sudo dpkg-reconfigure tzdata
sudo timedatectl set-local-rtc 0
timedatectl
步驟 05.【所有主機】禁用系統(tǒng)交換分區(qū)
swapoff -a && sed -i 's|^/swap.img|#/swap.ing|g' /etc/fstab
# 驗證交換分區(qū)是否被禁用
free | grep "Swap:"
步驟 06.【所有主機】系統(tǒng)內(nèi)核參數(shù)調(diào)整
# 禁用 swap 分區(qū)
egrep -q "^(#)?vm.swappiness.*" /etc/sysctl.conf && sed -ri "s|^(#)?vm.swappiness.*|vm.swappiness = 0|g" /etc/sysctl.conf || echo "vm.swappiness = 0" >> /etc/sysctl.conf
# 允許轉(zhuǎn)發(fā)
egrep -q "^(#)?net.ipv4.ip_forward.*" /etc/sysctl.conf && sed -ri "s|^(#)?net.ipv4.ip_forward.*|net.ipv4.ip_forward = 1|g" /etc/sysctl.conf || echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
# - 允許 iptables 檢查橋接流量
egrep -q "^(#)?net.bridge.bridge-nf-call-iptables.*" /etc/sysctl.conf && sed -ri "s|^(#)?net.bridge.bridge-nf-call-iptables.*|net.bridge.bridge-nf-call-iptables = 1|g" /etc/sysctl.conf || echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf
egrep -q "^(#)?net.bridge.bridge-nf-call-ip6tables.*" /etc/sysctl.conf && sed -ri "s|^(#)?net.bridge.bridge-nf-call-ip6tables.*|net.bridge.bridge-nf-call-ip6tables = 1|g" /etc/sysctl.conf || echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf
步驟 07.【所有主機】禁用系統(tǒng)防火墻
ufw disable && systemctl disable ufw && systemctl stop ufw
2.負載均衡管理ipvsadm工具安裝與內(nèi)核加載
步驟 01.安裝ipvs模塊以及負載均衡相關(guān)依賴凄贩。
# 查看可用版本
sudo apt-cache madison ipvsadm
# ipvsadm | 1:1.31-1 | http://mirrors.aliyun.com/ubuntu focal/main amd64 Packages
# 安裝
sudo apt -y install ipvsadm ipset sysstat conntrack
# 鎖定版本
apt-mark hold ipvsadm
# ipvsadm set on hold.
步驟 02.將模塊加載到內(nèi)核中(開機自動設置-需要重啟機器生效)
tee /etc/modules-load.d/k8s-.conf <<'EOF'
# netfilter
br_netfilter
# containerd
overlay
# nf_conntrack
nf_conntrack
# ipvs
ip_vs
ip_vs_lc
ip_vs_lblc
ip_vs_lblcr
ip_vs_rr
ip_vs_wrr
ip_vs_sh
ip_vs_dh
ip_vs_fo
ip_vs_nq
ip_vs_sed
ip_vs_ftp
ip_tables
ip_set
ipt_set
ipt_rpfilter
ipt_REJECT
ipip
xt_set
EOF
步驟 03.手動加載模塊到Linux內(nèi)核中誓军。
mkdir -vp /etc/modules.d/
tee /etc/modules.d/k8s-ipvs.modules <<'EOF'
#!/bin/bash
# netfilter 模塊 允許 iptables 檢查橋接流量
modprobe -- br_netfilter
# containerd
modprobe -- overlay
# nf_conntrack
modprobe -- nf_conntrack
# ipvs
modprobe -- ip_vs
modprobe -- ip_vs_lc
modprobe -- ip_vs_lblc
modprobe -- ip_vs_lblcr
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- ip_vs_dh
modprobe -- ip_vs_fo
modprobe -- ip_vs_nq
modprobe -- ip_vs_sed
modprobe -- ip_vs_ftp
modprobe -- ip_tables
modprobe -- ip_set
modprobe -- ipt_set
modprobe -- ipt_rpfilter
modprobe -- ipt_REJECT
modprobe -- ipip
modprobe -- xt_set
EOF
# 權(quán)限設置、并加載到系統(tǒng)之中
chmod 755 /etc/modules.d/k8s-ipvs.modules && bash /etc/modules.d/k8s-ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack
# ip_vs_sh 16384 0
# ip_vs_wrr 16384 0
# ip_vs_rr 16384 0
# ip_vs 155648 6 ip_vs_rr,ip_vs_sh,ip_vs_wrr
# nf_conntrack 139264 1 ip_vs
# nf_defrag_ipv6 24576 2 nf_conntrack,ip_vs
# nf_defrag_ipv4 16384 1 nf_conntrack
# libcrc32c 16384 5 nf_conntrack,btrfs,xfs,raid456,ip_vs
sysctl --system
溫馨提示: 在 kernel 4.19 版本及以上將使用 nf_conntrack 模塊, 則在 4.18 版本以下則需使用nf_conntrack_ipv4 模塊疲扎。
3.高可用HAProxy與Keepalived軟件安裝配置
描述: 由于是測試學習環(huán)境, 此處我未專門準備兩臺HA服務器, 而是直接采用master節(jié)點機器昵时,如果是正式環(huán)境建議獨立出來。
步驟 01.【Master節(jié)點機器】安裝下載 haproxy (HA代理健康檢測) 與 keepalived (虛擬路由協(xié)議-主從)椒丧。
# 查看可用版本
sudo apt-cache madison haproxy keepalived
# haproxy | 2.0.13-2ubuntu0.5 | http://mirrors.aliyun.com/ubuntu focal-security/main amd64 Packages
# keepalived | 1:2.0.19-2ubuntu0.2 | http://mirrors.aliyun.com/ubuntu focal-updates/main amd64 Packages
# 安裝
sudo apt -y install haproxy keepalived
# 鎖定版本
apt-mark hold haproxy keepalived
步驟 02.【Master節(jié)點機器】進行 HAProxy 配置壹甥,其配置目錄為 /etc/haproxy/
,所有節(jié)點配置是一致的壶熏。
sudo cp /etc/haproxy/haproxy.cfg{,.bak}
tee /etc/haproxy/haproxy.cfg<<'EOF'
global
user haproxy
group haproxy
maxconn 2000
daemon
log /dev/log local0
log /dev/log local1 err
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
timeout http-request 15s
timeout http-keep-alive 15s
# errorfile 400 /etc/haproxy/errors/400.http
# errorfile 403 /etc/haproxy/errors/403.http
# errorfile 408 /etc/haproxy/errors/408.http
# errorfile 500 /etc/haproxy/errors/500.http
# errorfile 502 /etc/haproxy/errors/502.http
# errorfile 503 /etc/haproxy/errors/503.http
# errorfile 504 /etc/haproxy/errors/504.http
# 注意: 管理HAproxy (可選)
# frontend monitor-in
# bind *:33305
# mode http
# option httplog
# monitor-uri /monitor
# 注意: 基于四層代理, 1644 3為VIP的 ApiServer 控制平面端口, 由于是與master節(jié)點在一起所以不能使用6443端口.
frontend k8s-master
bind 0.0.0.0:16443
bind 127.0.0.1:16443
mode tcp
option tcplog
tcp-request inspect-delay 5s
default_backend k8s-master
# 注意: Master 節(jié)點的默認 Apiserver 是6443端口
backend k8s-master
mode tcp
option tcplog
option tcp-check
balance roundrobin
default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
server devtest-master-212 10.20.176.212:6443 check
server devtest-master-213 10.20.176.213:6443 check
server devtest-master-214 10.20.176.214:6443 check
EOF
步驟 03.【Master節(jié)點機器】進行 KeepAlived 相關(guān)配置 句柠,其配置目錄為 /etc/haproxy/
# 創(chuàng)建配置目錄,分別在各個master節(jié)點執(zhí)行棒假。
mkdir -vp /etc/keepalived
# __ROLE__ 角色: MASTER 或者 BACKUP
# __NETINTERFACE__ 宿主機物理網(wǎng)卡名稱 例如我的ens32
# __IP__ 宿主機物理IP地址
# __VIP__ 虛擬VIP地址
sudo tee /etc/keepalived/keepalived.conf <<'EOF'
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
script_user root
enable_script_security
}
vrrp_script chk_apiserver {
script "/etc/keepalived/check_apiserver.sh"
interval 5
weight -5
fall 2
rise 1
}
vrrp_instance VI_1 {
state __ROLE__
interface __NETINTERFACE__
mcast_src_ip __IP__
virtual_router_id 51
priority 101
advert_int 2
authentication {
auth_type PASS
auth_pass K8SHA_KA_AUTH
}
virtual_ipaddress {
__VIP__
}
# HA 健康檢查
# track_script {
# chk_apiserver
# }
}
EOF
# 此處將 devtest-master-212 配置為 Master (devtest-master-212 主機上執(zhí)行)
# devtest-master-212 10.20.176.212 => MASTER
sed -i -e 's#__ROLE__#MASTER#g' \
-e 's#__NETINTERFACE__#ens32#g' \
-e 's#__IP__#10.20.176.212#g' \
-e 's#__VIP__#10.20.176.211#g' /etc/keepalived/keepalived.conf
# devtest-master-213 10.20.176.213 => BACKUP (devtest-master-213 主機上執(zhí)行)
sed -i -e 's#__ROLE__#BACKUP#g' \
-e 's#__NETINTERFACE__#ens32#g' \
-e 's#__IP__#10.20.176.213#g' \
-e 's#__VIP__#10.20.176.211#g' /etc/keepalived/keepalived.conf
# devtest-master-214 10.20.176.214 => BACKUP (devtest-master-214 主機上執(zhí)行)
sed -i -e 's#__ROLE__#BACKUP#g' \
-e 's#__NETINTERFACE__#ens32#g' \
-e 's#__IP__#10.20.176.214#g' \
-e 's#__VIP__#10.20.176.211#g' /etc/keepalived/keepalived.conf
溫馨提示: 注意上述的健康檢查是關(guān)閉注釋了的溯职,你需要將K8S集群建立完成后再開啟。
track_script {
chk_apiserver
}
步驟 04.【Master節(jié)點機器】進行配置 KeepAlived 健康檢查文件淆衷。
sudo tee /etc/keepalived/check_apiserver.sh <<'EOF'
#!/bin/bash
err=0
for k in $(seq 1 3)
do
check_code=$(pgrep haproxy)
if [[ $check_code == "" ]]; then
err=$(expr $err + 1)
sleep 1
continue
else
err=0
break
fi
done
if [[ $err != "0" ]]; then
echo "systemctl stop keepalived"
/usr/bin/systemctl stop keepalived
exit 1
else
exit 0
fi
EOF
sudo chmod +x /etc/keepalived/check_apiserver.sh
步驟 05.【Master節(jié)點機器】啟動 haproxy 缸榄、keepalived 相關(guān)服務及測試VIP漂移。
# 重載 Systemd 設置 haproxy 祝拯、keepalived 開機自啟以及立即啟動
sudo systemctl daemon-reload
sudo systemctl enable --now haproxy && sudo systemctl enable --now keepalived
# Synchronizing state of haproxy.service with SysV service script with /lib/systemd/systemd-sysv-install.
# Executing: /lib/systemd/systemd-sysv-install enable haproxy
# Synchronizing state of keepalived.service with SysV service script with /lib/systemd/systemd-sysv-install.
# Executing: /lib/systemd/systemd-sysv-install enable keepalived
# 在 devtest-master-212 主機中發(fā)現(xiàn)vip地址在其主機上甚带。
root@devtest-master-212:~$ ip addr
# 2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
# link/ether 00:50:56:8a:57:69 brd ff:ff:ff:ff:ff:ff
# inet 10.20.176.212/24 brd 10.20.176.255 scope global ens32
# valid_lft forever preferred_lft forever
# inet 10.20.176.211/24 scope global ens32
# valid_lft forever preferred_lft forever
# inet6 fe80::250:56ff:fe8a:5769/64 scope link
# valid_lft forever preferred_lft forever
# 其它兩臺Master主機上通信驗證。
root@devtest-master-213:~$ ping 10.20.176.211
# PING 10.20.176.211 (10.20.176.211) 56(84) bytes of data.
# 64 bytes from 10.20.176.211: icmp_seq=1 ttl=64 time=0.161 ms
root@devtest-master-214:~$ ping 10.20.176.211
然后我們可以手動驗證VIP漂移,我們將該服務器上keepalived停止掉佳头。
root@devtest-master-212:~$ pgrep haproxy
# 6120
# 6121
root@devtest-master-212:~$ /usr/bin/systemctl stop keepalived
# 此時,發(fā)現(xiàn)VIP已經(jīng)飄到devtest-master-212主機中
root@devtest-master-215:~$ ip addr show ens32
# 2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
# link/ether 00:0c:29:93:28:61 brd ff:ff:ff:ff:ff:ff
# inet10.20.176.215/24 brd 10.10.107.255 scope global ens32
# valid_lft forever preferred_lft forever
# inet 10.20.176.211/32 scope global ens32
# valid_lft forever preferred_lft forever
至此鹰贵,HAProxy 與 Keepalived 配置就告一段落了。
4.容器運行時containerd.io安裝配置
步驟 01.分別在master與work節(jié)點上安裝containerd康嘉。
# 1.卸載舊版本
sudo apt-get remove docker docker-engine docker.io containerd runc
# 2.更新apt包索引并安裝包以允許apt在HTTPS上使用存儲庫
sudo apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
# 3.添加Docker官方GPG密鑰 # -fsSL
curl https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 4.通過搜索指紋的最后8個字符進行密鑰驗證
sudo apt-key fingerprint 0EBFCD88
# 5.設置穩(wěn)定存儲庫
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
# 6.安裝特定版本在repo中列出可用的版本
sudo apt-cache madison containerd.io
# containerd.io | 1.6.6-1 | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
# containerd.io | 1.6.4-1 | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
# containerd.io | 1.5.11-1 | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
# 7.使用第二列中的版本字符串安裝特定的版本碉输,例如: 1.6.6-1
sudo apt-get install containerd.io=1.6.6-1
# 離線安裝: apt install -y ./containerd.io_1.6.6-1_amd64.deb
步驟 02.下載安裝后在【所有節(jié)點】進行containerd 配置,此處將創(chuàng)建并修改 config.toml 文件.
# 為 containerd 生成默認配置
mkdir -vp /etc/containerd
containerd config default >/etc/containerd/config.toml
ls /etc/containerd/config.toml
# /etc/containerd/config.toml
# pause 鏡像源
sed -i "s#k8s.gcr.io/pause#registry.cn-hangzhou.aliyuncs.com/google_containers/pause#g" /etc/containerd/config.toml
# 使用 SystemdCgroup
sed -i 's#SystemdCgroup = false#SystemdCgroup = true#g' /etc/containerd/config.toml
# docker.io mirror
sed -i '/registry.mirrors]/a\ \ \ \ \ \ \ \ [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]' /etc/containerd/config.toml
sed -i '/registry.mirrors."docker.io"]/a\ \ \ \ \ \ \ \ \ \ endpoint = ["https://05f073ad3c0010ea0f4bc00b7105ec20.mirror.swr.myhuaweicloud.com","https://xlx9erfu.mirror.aliyuncs.com","https://docker.mirrors.ustc.edu.cn"]' /etc/containerd/config.toml
# gcr.io mirror
sed -i '/registry.mirrors]/a\ \ \ \ \ \ \ \ [plugins."io.containerd.grpc.v1.cri".registry.mirrors."gcr.io"]' /etc/containerd/config.toml
sed -i '/registry.mirrors."gcr.io"]/a\ \ \ \ \ \ \ \ \ \ endpoint = ["https://gcr.mirrors.ustc.edu.cn"]' /etc/containerd/config.toml
# k8s.gcr.io mirror
sed -i '/registry.mirrors]/a\ \ \ \ \ \ \ \ [plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]' /etc/containerd/config.toml
sed -i '/registry.mirrors."k8s.gcr.io"]/a\ \ \ \ \ \ \ \ \ \ endpoint = ["https://gcr.mirrors.ustc.edu.cn/google-containers/","https://registry.cn-hangzhou.aliyuncs.com/google_containers/"]' /etc/containerd/config.toml
# quay.io mirror
sed -i '/registry.mirrors]/a\ \ \ \ \ \ \ \ [plugins."io.containerd.grpc.v1.cri".registry.mirrors."quay.io"]' /etc/containerd/config.toml
sed -i '/registry.mirrors."quay.io"]/a\ \ \ \ \ \ \ \ \ \ endpoint = ["https://quay.mirrors.ustc.edu.cn"]' /etc/containerd/config.toml
步驟 03.修改配置后【所有節(jié)點】重載containerd服務并查看相關(guān)服務及其版本亭珍。
# 配置重載與服務重啟
systemctl daemon-reload && systemctl restart containerd.service
systemctl status -l containerd.service
# ● containerd.service - containerd container runtime
# Loaded: loaded (/lib/systemd/system/containerd.service; enabled; vendor preset: enabled)
# Active: active (running) since Thu 2022-06-16 05:22:50 UTC; 5 days ago
# Docs: https://containerd.io
# Main PID: 790 (containerd)
# Tasks: 51
# Memory: 76.3M
# CGroup: /system.slice/containerd.service
# ├─ 790 /usr/bin/containerd
# 客戶端版本查看
root@devtest-master-212:/var/cache/apt/archives# ctr version
# Client:
# Version: 1.6.6
# Revision: 10c12954828e7c7c9b6e0ea9b0c02b01407d3ae1
# Go version: go1.17.11
# Server:
# Version: 1.6.6
# Revision: 10c12954828e7c7c9b6e0ea9b0c02b01407d3ae1
# UUID: 71a28bbb-6ed6-408d-a873-e394d48b35d8
root@devtest-master-212:/var/cache/apt/archives# runc -v
# runc version 1.1.2
# commit: v1.1.2-0-ga916309
# spec: 1.0.2-dev
# go: go1.17.11
# libseccomp: 2.5.1
5.安裝源配置與初始化集群配置準備
步驟 01.【所有節(jié)點】Kubernetes 安裝源配置及其kubelet敷钾、kubeadm、kubectl工具下載安裝
# (1) gpg 簽名下載導入
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -
# (2) Kubernetes 安裝源
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
apt update
# 其它方式:
# (2) 設置穩(wěn)定存儲庫
# sudo add-apt-repository "deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main"
# (3) K8S可用版本,此處可以看見最新的是 1.24.1 , 由于博主實踐的K8S是為開發(fā)測試環(huán)境所搭建肄梨,則此處選擇 1.23.7 版本阻荒。
apt-cache madison kubelet | more
kubelet | 1.24.1-00 | https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages
kubelet | 1.24.0-00 | https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages
kubelet | 1.23.7-00 | https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages
# (4) 下載安裝指定版本的kubelet、kubeadm众羡、kubectl
K8S_VERSION="1.23.7-00"
sudo apt install kubelet=${K8S_VERSION} kubeadm=${K8S_VERSION} kubectl=${K8S_VERSION}
步驟 02.【所有節(jié)點】重載systemd守護進程并將 kubelet 設置成開機啟動
systemctl daemon-reload
systemctl restart containerd.service
systemctl enable kubelet && systemctl start kubelet
步驟 03.【devtest-master-212】為了節(jié)約拉取實踐我們可以在某一臺master節(jié)點上先拉取所K8S集群所需要的鏡像侨赡。
# 列出所需鏡像
kubeadm config images list --kubernetes-version=1.23.7
# k8s.gcr.io/kube-apiserver:v1.23.7
# k8s.gcr.io/kube-controller-manager:v1.23.7
# k8s.gcr.io/kube-scheduler:v1.23.7
# k8s.gcr.io/kube-proxy:v1.23.7
# k8s.gcr.io/pause:3.6
# k8s.gcr.io/etcd:3.5.1-0
# k8s.gcr.io/coredns/coredns:v1.8.6
# 使用阿里提供的鏡像源進行拉取v1.23.7版本依賴的相關(guān)鏡像
for i in $(kubeadm config images list --kubernetes-version=1.23.7 --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers -v 5);do
ctr -n k8s.io images pull ${i}
done
# registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.23.7
# registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.23.7
# registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.23.7
# registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.23.7
# registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6
# registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.1-0
# registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.6
# 從 container.io 中的鏡像導出本地
for images in $(ctr -n k8s.io i ls name~=registry.cn-hangzhou.aliyuncs.com/google_containers -q);do
temp_name=${images##*/}
tar_name=$(echo $temp_name | tr ':' '_')
echo "export ${images} >> $tar_name.tar"
ctr -n k8s.io images export ${tar_name}.tar ${images}
done
# 從本地導入鏡像到 container.io 中
for tarfile in $(ls);do
$ ctr images import --base-name foo/bar foobar.tar
ctr -n k8s.io images export ${tar_name}.tar ${images}
done
步驟 04.導入到各個節(jié)點后我們可以通過如下命令查看導入的鏡像列表信息。
# 方式1
ctr -n k8s.io i ls name~=registry.cn-hangzhou.aliyuncs.com/google_container
# 方式2
crictl images | grep "registry.cn-hangzhou.aliyuncs.com/google"
registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64 3.0 99e59f495ffaa 314kB
registry.cn-hangzhou.aliyuncs.com/google_containers/coredns v1.8.6 a4ca41631cc7a 13.6MB
registry.cn-hangzhou.aliyuncs.com/google_containers/etcd 3.5.1-0 25f8c7f3da61c 98.9MB
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver v1.23.7 03c169f383d97 32.6MB
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager v1.23.7 e34d4a6252edd 30.2MB
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy v1.23.7 b1aa05aa5100e 39.3MB
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler v1.23.7 ed0ccfa052ab4 15.1MB
registry.cn-hangzhou.aliyuncs.com/google_containers/pause 3.6 6270bb605e12e 302kB
6.使用kubeadm安裝部署K8S集群
步驟 01.【devtest-master-212 節(jié)點】生成K8S初始化yaml配置文件,并根據(jù)實際情況進行編輯羊壹。
$ kubeadm config print init-defaults > kubeadm-init-default.yaml
$ vim kubeadm-init-default.yaml
# 此處為v1.23.x 適用的集群初始化配置清單
tee kubeadm-init-cluster.yaml <<'EOF'
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: devtes.httpweiyigeektop
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 10.20.176.212 # 關(guān)鍵點: 當前節(jié)點地址
bindPort: 6443 # 關(guān)鍵點: API端口默認即可
nodeRegistration:
criSocket: /run/containerd/containerd.sock # 關(guān)鍵點: 指定containerd為運行時
imagePullPolicy: IfNotPresent
name: devtest-master-212 # 關(guān)鍵點: 當前節(jié)點名稱
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
apiServer:
certSANs: # 關(guān)鍵點: 證書中心包含的SANs列表一般包含VIP與各節(jié)點的主機名稱
- slbvip.k8s.devtest
- localhost
- devtest-master-212
- devtest-master-213
- devtest-master-214
- 10.20.176.211
- 10.20.176.212
- 10.20.176.213
- 10.20.176.214
- 10.66.66.2
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers # 關(guān)鍵點: 集群所需鏡像倉庫源加快拉取
kind: ClusterConfiguration
kubernetesVersion: v1.23.7 # 關(guān)鍵點: K8S集群版本此處與我們提前下載的鏡像版本必須一致否則將會重新拉取指定K8S集群所需鏡像蓖宦。
controlPlaneEndpoint: slbvip.k8s.devtest:16443 # 關(guān)鍵點: 高可用VIP地址的域名與haproxy代理端口。
networking:
dnsDomain: cluster.test # 關(guān)鍵點: 集群dns根域默認cluster.local
serviceSubnet: 10.96.0.0/12 # 關(guān)鍵點: services 服務子網(wǎng)段
podSubnet: 10.66.0.0/16 # 關(guān)鍵點: pod 服務子網(wǎng)段
scheduler: {}
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs # 關(guān)鍵點: 啟用IPVS支持
ipvs:
excludeCIDRs:
- 10.66.66.2/32 # 關(guān)鍵點: 排出指定IP
EOF
步驟 02.【devtest-master-212 節(jié)點】準備好初始化yaml清單后, 通過 kubeadm init 命令進行集群的初始化油猫,并將日志輸入到kubeadm-init.log稠茂。
kubeadm init --config=kubeadm-init-cluster.yaml --v=5 | tee kubeadm-init.log
# --config 指定yaml配置文件
# --v 指定日志等級 debug
# 當執(zhí)行后出現(xiàn)如下提示表明節(jié)點初始化安裝成功,可以按照指定提示進行執(zhí)行情妖。
Your Kubernetes control-plane has initialized successfully!
# To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
# You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
# 【控制節(jié)點加入命令】
# You can now join any number of control-plane nodes by copying certificate authorities and service account keys on each node and then running the following as root:
kubeadm join slbvip.k8s.devtest:16443 --token devtes.httpweiyigeektop \
--discovery-token-ca-cert-hash sha256:4e5b3acb1d821bbd3976355f7b12b1daaa44e1fc38cbdfb2f86f4078d9507f22 \
--control-plane
# 【工作節(jié)點加入命令】
# Then you can join any number of worker nodes by running the following on each as root:
kubeadm join slbvip.k8s.devtest:16443 --token devtes.httpweiyigeektop \
--discovery-token-ca-cert-hash sha256:4e5b3acb1d821bbd3976355f7b12b1daaa44e1fc38cbdfb2f86f4078d9507f22
步驟 03.將【devtest-master-212】節(jié)點中/etc/kubernetes/
目錄中的如下文件進行復制打包主慰,并通過http協(xié)議將其分享給其它機器進行下載
# 將ca證書拷貝到指定目錄
mkdir -vp /tmp/pki/etcd && cp /etc/kubernetes/pki/ca.* /etc/kubernetes/pki/sa.* /etc/kubernetes/pki/front-proxy-ca.* /tmp/pki
cp /etc/kubernetes/pki/etcd/ca.* /tmp/pki/etcd/
# 壓縮依賴依賴的ca證書目錄
tar -zcvf pki.tar.gz pki/
# 使用 python 搭建一個臨時 http 服務
python3 -m http.server 8080
# 在其它【節(jié)點】進入到/tmp/執(zhí)行如下命令進行下載
cd /tmp/ && wget 10.20.176.212:8080/pki.tar.gz
tar -zxvf /tmp/pki.tar.gz -C /etc/kubernetes/
# 查看解壓后的復制到/etc/kubernetes/目錄中的文件相關(guān)結(jié)構(gòu)。
tree /etc/kubernetes/
/etc/kubernetes/
└── pki
├── ca.crt
├── ca.key
├── etcd
│ ├── ca.crt
│ └── ca.key
├── front-proxy-ca.crt
├── front-proxy-ca.key
├── sa.key
└── sa.pub
2 directories, 8 files
步驟 04.在其余【master】節(jié)點中執(zhí)行如下 kubeadm join 命令添加新的 Master 節(jié)點到K8S集群控制面板中, 加入成功后如下圖所示:
kubeadm join slbvip.k8s.devtest:16443 \
--control-plane \
--token devtes.httpweiyigeektop \
--discovery-token-ca-cert-hash sha256:4e5b3acb1d821bbd3976355f7b12b1daaa44e1fc38cbdfb2f86f4078d9507f22 \
--cri-socket /run/containerd/containerd.sock
溫馨提示: 在v1.23.x
如果要使用containerd運行時必須--cri-socket
指定其運行時socket鲫售。
步驟 05.在其余【work】節(jié)點中執(zhí)行如下 kubeadm join 命令添加新的 Work 節(jié)點到K8S集群中, 加入成功后如下圖所示:
kubeadm join slbvip.k8s.devtest:16443 \
--token devtes.httpweiyigeektop \
--discovery-token-ca-cert-hash sha256:4e5b3acb1d821bbd3976355f7b12b1daaa44e1fc38cbdfb2f86f4078d9507f22 \
--cri-socket /run/containerd/containerd.sock
步驟 06.全部加入到集群后我們可以通過如下命令進行查看添加的節(jié)點以及其節(jié)點角色設置,最終執(zhí)行結(jié)果如下圖所示该肴。
# 集群節(jié)點查看
root@devtest-master-212:~$ kubectl get node
# NAME STATUS ROLES AGE VERSION
# devtest-master-212 Ready control-plane,master 15m v1.23.7
# devtest-master-213 Ready control-plane,master 5m19s v1.23.7
# devtest-master-214 Ready control-plane,master 2m7s v1.23.7
# devtest-work-215 Ready <none> 14m v1.23.7
# 集群節(jié)點角色設置情竹,此處將devtest-work-215節(jié)點的ROLES設置為 work。
root@devtest-master-212:~$ kubectl label node devtest-work-215 node-role.kubernetes.io/work=
# node/devtest-work-215 labeled
步驟 07.查看集群信息匀哄、集群組件秦效、以及集群中所有Pod進行查看, 執(zhí)行結(jié)果如下
root@devtest-master-212:~# kubectl cluster-info
Kubernetes control plane is running at https://slbvip.k8s.devtest:16443
CoreDNS is running at https://slbvip.k8s.devtest:16443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
root@devtest-master-212:~# 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","reason":""}
root@devtest-master-212:~# kubectl get pod -A
步驟 08.開啟所有【master】中keepalived的健康檢查,并重啟keepalived.service服務
vim /etc/keepalived/keepalived.conf
...
# 開啟 HA 健康檢查,例如
track_script {
chk_apiserver
}
systemctl restart keepalived.service
步驟 09.然后我們?yōu)閗ubectl添加命令自動補齊不全功能涎嚼,執(zhí)行如下代碼即可阱州。
apt install -y bash-completion
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
步驟 10.最后我們可以部署一個nginx的Pod驗證集群環(huán)境, 并通過curl進行訪問,但是此時你會發(fā)現(xiàn)只有在【devtest-work-215】主機上才能訪問該nginx法梯,而其它節(jié)點訪問時會報Connection timed out
, 其原因可看下面的溫馨提示苔货。
kubectl run nginx --image nginx:latest --port=80
pod/nginx created
kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 68s 10.22.0.5 devtest-work-215 <none> <none>
curl -I http://10.22.0.5
curl: (28) Failed to connect to 10.22.0.5 port 80: Connection timed out
溫馨提示: 這是由于我們沒有為集群配置網(wǎng)絡插件,而常用的網(wǎng)絡插件是flannel立哑、calico(下面將會以此為例
)以及當下cilium夜惭。
步驟 11.特別注意此處為了能在后續(xù)演示中將Pod應用調(diào)度到Master節(jié)點上,此時我們需要分別去除控制節(jié)點的污點。
kubectl taint node devtest-master-212 node-role.kubernetes.io/master=:NoSchedule-
# node/devtest-master-212 untainted
kubectl taint node devtest-master-213 node-role.kubernetes.io/master=:NoSchedule-
# node/devtest-master-213 untainted
kubectl taint node devtest-master-214 node-role.kubernetes.io/master=:NoSchedule-
# node/devtest-master-214 untainted
7.部署配置 Calico 網(wǎng)絡插件
描述: 在節(jié)點加入到集群時有時你會發(fā)現(xiàn)其節(jié)點狀態(tài)為 NotReady, 以及前面部署Pod無法被其它節(jié)點機器進行代理轉(zhuǎn)發(fā)訪問铛绰,所以部署calico插件可以讓Pod與集群正常通信诈茧。
步驟 01.在【devtest-master-212】節(jié)點上拉取最新版本的 calico 當前最新版本為 v3.22, 官方項目地址 (https://github.com/projectcalico/calico)
# 拉取 calico 部署清單
wget https://docs.projectcalico.org/v3.22/manifests/calico.yaml
步驟 02.修改 calico.yaml 文件的中如下 K/V, 即 Pod 獲取IP地址的地址池, 從網(wǎng)絡規(guī)劃中我們設置為 10.66.0.0/16
, 注意默認情況下如下字段是注釋的且默認地址池為192.168.0.0/16
。
$ vim calico.yaml
# The default IPv4 pool to create on startup if none exists. Pod IPs will be
# chosen from this range. Changing this value after installation will have
# no effect. This should fall within `--cluster-cidr`.
- name: CALICO_IPV4POOL_CIDR
value: "10.66.0.0/16"
步驟 03.執(zhí)行 kubectl apply 命令部署 calico 到集群之中捂掰。
kubectl apply -f calico.yaml
# configmap/calico-config created
# ....
# poddisruptionbudget.policy/calico-kube-controllers created
步驟 04.查看calico網(wǎng)絡插件在各節(jié)點上部署結(jié)果,狀態(tài)為Running表示部署成功敢会。
kubectl get pod -n kube-system -o wide| head -n 6
# NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
# calico-kube-controllers-6b77fff45-w29rq 1/1 Running 0 8m5s 10.66.35.65 devtest-master-214 <none> <none>
# calico-node-7gxdc 1/1 Running 0 8m5s 10.20.176.213 devtest-master-213 <none> <none>
# calico-node-tsk6w 1/1 Running 0 8m5s 10.20.176.212 devtest-master-212 <none> <none>
# calico-node-vnkhg 1/1 Running 0 8m5s 10.20.176.215 devtest-work-215 <none> <none>
# calico-node-xh2dw 1/1 Running 0 8m5s 10.20.176.214 devtest-master-214 <none> <none>
步驟 05.此時刪除 nginx 的 Pod 再重新創(chuàng)建一個Pod應用,并在非【devtest-work-215 】節(jié)點上進行訪問測試
root@devtest-master-212:/opt/init/k8s# kubectl run nginx --image=nginx:latest --port=80
# pod/nginx created
root@devtest-master-212:/opt/init/k8s# kubectl get pod nginx
# NAME READY STATUS RESTARTS AGE
# nginx 1/1 Running 0 10s
root@devtest-master-212:/opt/init/k8s# kubectl get pod nginx -o wide
# NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
# nginx 1/1 Running 0 13s 10.66.53.66 devtest-work-215 <none> <none>
root@devtest-master-212:/opt/init/k8s# curl -I 10.66.53.66
# HTTP/1.1 200 OK
# Server: nginx/1.21.5
# Date: Wed, 15 Jun 2022 11:39:48 GMT
# Content-Type: text/html
# Content-Length: 615
# Last-Modified: Tue, 28 Dec 2021 15:28:38 GMT
# Connection: keep-alive
# ETag: "61cb2d26-267"
# Accept-Ranges: bytes
至此这嚣,高可用的K8S集群部署完畢鸥昏,在下節(jié)中將實踐演示在集群中安裝 Metrics Server 、kubernetes-dashboard疤苹、nfs-provisioner互广、ingress 等安裝實踐。
0x03 集群輔助插件部署
1.集群中基于nfs的provisioner的動態(tài)持卷環(huán)境部署
描述: 在K8S集群中我們常常會使用動態(tài)持久卷對應用數(shù)據(jù)進行持久化保存,例如應用配置惫皱、依賴插件像樊、應用數(shù)據(jù)以及應用訪問日志等,所以動態(tài)持久卷的重要性不言而喻旅敷,此小節(jié)將講解如何搭建以及nfs存儲服務以及使用kubernetes-sigs
提供的[nfs-subdir-external-provisioner] (https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner)項目針對已存在的 nfs 服務器進行 provisioner 部署生棍。
Q: 什么是nfs-subdir-external-provisioner?
NFS subdir external provisioner 是一個自動配置器,它使用您現(xiàn)有的和已配置的 NFS 服務器來支持通過 Persistent Volume Claims 動態(tài)配置 Kubernetes Persistent Volumes媳谁。
持久卷配置為 ${namespace}-${pvcName}-${pvName}涂滴。
溫馨提示:在進行此環(huán)境搭建時,請注意您必須已經(jīng)有配置好的 NFS 服務器晴音,為了保持與早期部署文件的向后兼容性柔纵,NFS Client Provisioner 的命名在部署 YAML 中保留為 nfs-storage-provisioner。
項目地址: https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
步驟 01.我在一臺Ubuntu 20.04主機上配置 NFS 存儲服務器(IP地址為10.20.176.102)锤躁,如果你已有存儲服務器提供的NFS服務器則可以略過此步驟搁料,其它操作系統(tǒng)安裝部署請看出我的這篇博客文章[NFS網(wǎng)絡文件系統(tǒng)基礎配置與使用] (https://blog.weiyigeek.top/2019/5-16-104.html)
# Step1.Install Required Packages(Server)
$ apt-get update
$ apt-get install nfs-kernel-server rpcbind
# Step2.Configure NFS Server
# [根據(jù)需求配置] 設置允許連接的ip, Example Allow 192.168.1.0/24 to be Accessed on Network
$ nano /etc/hosts.allow
portmap: 192.168.1.0/24
# [根據(jù)需求配置] idmapd 配置, 此處配置端口為40000
$ nano /etc/default/nfs-common
NEED_IDMAPD=YES
STATDOPTS="--port 40000"
# [根據(jù)需求配置] 內(nèi)核服務配置,此處mountd服務端口為40001
$ nano /etc/default/nfs-kernel-server
RPCMOUNTDOPTS="--manage-gids --port 40001"
# NFS 服務器共享路徑配置
$ nano /etc/exports
# Example for NFSv2 and NFSv3:
# /srv/homes hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
# Example for NFSv4:
# /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check)
/app/storage/nfs *(rw,sync,no_root_squash,no_subtree_check)
# Step3.創(chuàng)建NFS配置需要共享的目錄
mkdir -vp /app/storage/nfs
# Step4.自啟動RPC服務于nfs共享服務
systemctl enable rpcbind nfs-server.service
systemctl start rpcbind nfs-server.service
# Step5.更新nfs配置文件 (nano /etc/exports)
exportfs -a
# Step6.Ubuntu防火墻規(guī)則配置 (PS: 通過rpcinfo命令可以查看 NFS 相關(guān)的端口)
ufw allow 111,2049,40000,40001/tcp
ufw reload
步驟 02.【所有節(jié)點】在客戶端嘗試掛載搭建的NFS服務器,并分別在節(jié)點機器掛載到/storage/nfs
目錄中
# 查看 NFS 掛載目錄
showmount -e 127.0.0.1
# Export list for 127.0.0.1:
# /app/storage/nfs *
# 掛載 NFS 服務器到指定節(jié)點目錄的/storage/nfs目錄
mkdir -vp /storage/nfs
# 臨時掛載
mount -t nfs 10.20.176.102:/app/storage/nfs /storage/nfs
# 永久掛載將掛載配置寫入到/etc/fstab中
tee -a /etc/fstab <<"EOF"
10.20.176.102:/app/storage/nfs /storage/nfs nfs defaults 0 0
EOF
mount -a
# 查看掛載信息
$ mount -l
$ df -Th | grep "/storage/nfs"
10.20.176.102:/app/storage/nfs nfs4 97G 11G 82G 12% /storage/nfs
# 如果不使用了則可執(zhí)行如下命令進行卸載掛載點
umount /storage/nfs
步驟 03.helm3 部署工具快速安裝
# helm3 安裝
$ wget https://get.helm.sh/helm-v3.9.0-linux-amd64.tar.gz && tar -zxf helm-v3.9.0-linux-amd64.tar.gz
$ tar -zxf helm-v3.9.0-linux-amd64.tar.gz
$ cp linux-amd64/helm /usr/local/bin/helm3
步驟 04.在Github中下載nfs-subdir-external-provisioner的release壓縮包或者使用helm3指定倉庫進行安裝系羞。
- 方式1.release 壓縮包
$ wget https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/releases/download/nfs-subdir-external-provisioner-4.0.16/nfs-subdir-external-provisioner-4.0.16.tgz
$ tar -zxvf nfs-subdir-external-provisioner-4.0.16.tgz
# 按照指定需求編輯如下values值
$ egrep -v '^$|#' values.yaml
replicaCount: 1
strategyType: Recreate
image:
repository: registry.cn-hangzhou.aliyuncs.com/weiyigeek/nfs-subdir-external-provisioner
tag: v4.0.2
pullPolicy: IfNotPresent
imagePullSecrets: []
nfs:
server: 10.20.176.102
path: /app/storage/nfs
mountOptions:
volumeName: nfs-subdir-external-provisioner-root
reclaimPolicy: Retain
storageClass:
create: true
provisionerName: cluster.local/nfs-storage-subdir-provisioner
defaultClass: false
name: nfs-storage
allowVolumeExpansion: true
reclaimPolicy: Delete
archiveOnDelete: true
onDelete:
pathPattern:
accessModes: ReadWriteOnce
annotations: {}
leaderElection:
enabled: true
rbac:
create: true
podSecurityPolicy:
enabled: false
podAnnotations: {}
podSecurityContext: {}
securityContext: {}
serviceAccount:
create: true
annotations: {}
name:
resources: {}
nodeSelector: {}
tolerations: []
affinity: {}
labels: {}
# 指定下載解壓目錄進行chat圖表安裝
$ helm3 install nfs-storage nfs-subdir-external-provisioner/
NAME: nfs-storage
LAST DEPLOYED: Mon Jun 20 15:41:50 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
- 方式2.helm3指定倉庫
$ helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
$ helm nfs-storage nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
--set nfs.server=10.20.176.102 \
--set nfs.path=/app/storage/nfs
# 更新
$ helm3 upgrade nfs-storage nfs-subdir-external-provisioner/
溫馨提示: 由于nfs-subdir-external-provisioner鏡像是k8s.gcr.io域名下國內(nèi)可能無法拉取郭计,此處我已經(jīng)拉取到阿里云鏡像倉庫中registry.cn-hangzhou.aliyuncs.com/weiyigeek/nfs-subdir-external-provisioner:v4.0.2
,如果你需要自行拉取請參考此篇使用Aliyun容器鏡像服務對海外鏡像倉庫中鏡像進行拉取構(gòu)建 ()
步驟 05.查看部署的nfs-storage動態(tài)持久卷以及其pod狀態(tài)
$ helm3 list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
nfs-storage default 1 2022-06-20 15:41:50.960642233 +0800 CST deployed nfs-subdir-external-provisioner-4.0.16 4.0.2
$ kubectl get storageclasses.storage.k8s.io
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
nfs-storage cluster.local/nfs-storage-subdir-provisioner Delete Immediate true 17s
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nfs-storage-nfs-subdir-external-provisioner-77f4d85f74-kljck 1/1 Running 0 33s
步驟 06.如想卸載helm3安裝的nfs-storage動態(tài)卷執(zhí)行如下命令即可椒振。
$ helm3 uninstall nfs-storage
release "nfs-storage" uninstalled
至此昭伸,基于NFS的provisioner 動態(tài)持久卷的安裝部署到此結(jié)束。
溫馨提示: 如果需要部署多個nfs持久卷, 則我們需要更改values.yaml中如下字段澎迎,并使用不同的名稱庐杨。
# values.yaml
nfs:
server: 10.20.176.102
path: /app/storage/nfs/pvc/local
volumeName: nfs-subdir-external-provisioner-local
....
storageClass:
....
provisionerName: cluster.local/nfs-local-subdir-provision # 關(guān)鍵點(提供者不能一樣)
name: nfs-local
# 例如,此處創(chuàng)建兩個nfs動態(tài)卷即nfs-local與nfs-dev。
helm3 install nfs-local nfs-subdir-external-provisioner/
helm3 install nfs-dev nfs-subdir-external-provisioner-dev/
# helm 部署結(jié)果查看
helm3 list
# NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
# nfs-dev default 1 2022-07-14 11:27:33.997601363 +0800 CST deployed nfs-subdir-external-provisioner-4.0.16 4.0.2
# nfs-local default 1 2022-07-14 11:28:02.49579496 +0800 CST deployed nfs-subdir-external-provisioner-4.0.16 4.0.2
# storageclasses 查看
kubectl get storageclasses.storage.k8s.io
# NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
# nfs-dev (default) cluster.local/nfs-dev-subdir-provisioner Delete Immediate true 4m36s
# nfs-local cluster.local/nfs-local-subdir-provisioner Delete Immediate true 4m8s
# nfs-subdir-external-provisioner pod 查看
kubectl get pod
# NAME READY STATUS RESTARTS AGE
# nfs-dev-nfs-subdir-external-provisioner-cf7684f8b-fzl9h 1/1 Running 0 5m4s
# nfs-local-nfs-subdir-external-provisioner-6f97d44bb8-424tk 1/1 Running 0 4m36s
正常情況下顯示出的日志信息:
$ kubectl logs -f nfs-dev-nfs-subdir-external-provisioner-cf7684f8b-fzl9h
# I0714 03:27:35.390909 1 leaderelection.go:242] attempting to acquire leader lease default/cluster.local-nfs-dev-subdir-provisioner...
# I0714 03:27:35.400777 1 leaderelection.go:252] successfully acquired lease default/cluster.local-nfs-dev-subdir-provisioner
# I0714 03:27:35.400856 1 event.go:278] Event(v1.ObjectReference{Kind:"Endpoints", Namespace:"default", Name:"cluster.local-nfs-dev-subdir-provisioner", UID:"34019115-d09e-433d-85d6-c254c5492ce5", APIVersion:"v1", ResourceVersion:"5510886", FieldPath:""}): type: 'Normal' reason: 'LeaderElection' nfs-dev-nfs-subdir-external-provisioner-cf7684f8b-fzl9h_b0aaa93a-f7fc-4931-b0cf-e04f42cefd9a became leader
# I0714 03:27:35.400943 1 controller.go:820] Starting provisioner controller cluster.local/nfs-dev-subdir-provisioner_nfs-dev-nfs-subdir-external-provisioner-cf7684f8b-fzl9h_b0aaa93a-f7fc-4931-b0cf-e04f42cefd9a!
# I0714 03:27:35.501130 1 controller.go:869] Started provisioner controller cluster.local/nfs-dev-subdir-provisioner_nfs-dev-nfs-subdir-external-provisioner-cf7684f8b-fzl9h_b0aaa93a-f7fc-4931-b0cf-e04f42cefd9a!
2.集群中安裝metrics-server獲取客戶端資源監(jiān)控指標
描述: 通常在集群安裝完成后,我們需要對其設置網(wǎng)絡嗡善、持久卷存儲等插件, 除此之外我們還需安裝metrics-server以便于獲取Node與Pod相關(guān)資源消耗等信息辑莫,否則你在執(zhí)行kubectl top
命令時會提示error: Metrics API not available
, 所以本小節(jié)將針對Metrics-server的安裝進行講解。
項目地址: https://github.com/kubernetes-sigs/metrics-server
Q: 什么是metrics-server?
Metrics Server 是 Kubernetes 內(nèi)置自動縮放管道的可擴展罩引、高效的容器資源指標來源各吨。
Metrics Server 從 Kubelets 收集資源指標,并通過 Metrics API 在 Kubernetes apiserver 中公開它們袁铐,供 Horizontal Pod Autoscaler 和 Vertical Pod Autoscaler 使用揭蜒。
簡單的說: Metrics Server 是集群解析監(jiān)控數(shù)據(jù)的聚合器,安裝后用戶可以通過標準的API(/apis/metrics.k8s.io)來訪問監(jiān)控數(shù)據(jù),此處值得注意的是Metrics-Server并非kube-apiserver的一部分,而是通過Aggregator這種插件機制,在獨立部署的情況下同kube-apiserver一起統(tǒng)一對外服務的剔桨,當進行api請求時kube-aggregator統(tǒng)一接口會分析訪問api具體的類型屉更,幫我們負載到具體的api上。
溫馨提示: 我們可以通過 kubectl top
命令來訪問 Metrics API 獲取資源監(jiān)控相關(guān)數(shù)據(jù)洒缀。
溫馨提示: 注意 Metrics API 只可以查詢當前度量數(shù)據(jù),并不保存歷史數(shù)據(jù)瑰谜。
安裝使用
步驟 01.Metrics Server 可以直接從 YAML 清單安裝欺冀,也可以通過官方 Helm 圖表安裝。
# (1) 下載 YAML 清單
wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml -O metrics-server.yaml
root@devtest-master-212:/opt/init/k8s# ls
calico.yaml kubeadm-init-cluster.yaml kubeadm-init.log metrics-server.yaml
# (2) 提前下載相應的鏡像加快部署
grep "image:" metrics-server.yaml
# image: k8s.gcr.io/metrics-server/metrics-server:v0.6.1
# (3) 由于其鏡像國內(nèi)無法訪問此處我們采用阿里云k8s.gcr.io鏡像源
sed -i 's#k8s.gcr.io/metrics-server#registry.cn-hangzhou.aliyuncs.com/google_containers#g' metrics-server.yaml
# (4) 部署資源清單
kubectl apply -f metrics-server.yaml
# serviceaccount/metrics-server created
......
# apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
步驟 02.不論是在二進制方式或kubeadm方式安裝k8s集群, 都在部署 metrics-server 資源清單后 Pod 狀態(tài)為 0/1 并報出annot validate certificate for 10.10.107.223 because it doesn't contain any IP SANs
錯誤問題解決萨脑。
- 錯誤信息:
$ kubectl describe pod -n kube-system metrics-server-6ffc8966f5-cf2qh
# Warning Unhealthy 8s (x17 over 2m27s) kubelet Readiness probe failed: HTTP probe failed with statuscode: 500
$ kubectl logs -f --tail 50 -n kube-system metrics-server-6ffc8966f5-cf2qh
# E0520 11:13:17.379944 1 scraper.go:140] "Failed to scrape node" err="Get \"https://10.10.107.226:10250/metrics/resource\": x509: cannot validate certificate for 10.10.107.226 because it doesn't contain any IP SANs" node="node-1"
# E0520 11:13:17.382948 1 scraper.go:140] "Failed to scrape node" err="Get \"https://10.10.107.223:10250/metrics/resource\": x509: cannot validate certificate for 10.10.107.223 because it doesn't contain any IP SANs" node="master-223"
問題原因: 由于 metrics-server 未獲得TLS Bootstrap 簽發(fā)證書的導致訪問各節(jié)點資源時報錯隐轩。
解決辦法: 啟用 TLS BootStrap 證書簽發(fā)
# 1.分別在 Master 與 Node 節(jié)點中啟用TLS BootStrap 證書簽發(fā),在 kubelet 的 yaml 配置中追加入如下K/V.
# 方式1.Kubeadm 搭建的集群
$ vim /var/lib/kubelet/config.yaml
...
serverTLSBootstrap: true
# 方式2.二進制搭建的集群(注意此路徑根據(jù)你的kubelet.service進行配置), 此處我們定義的路徑為 /etc/kubernetes/cfg/kubelet-config.yaml
# /var/lib/kubelet/config.yaml
$ tee -a /etc/kubernetes/cfg/kubelet-config.yaml <<'EOF'
serverTLSBootstrap: true
EOF
# kubeadm 安裝方式可以使用如下
tee -a /var/lib/kubelet/config.yaml <<'EOF'
serverTLSBootstrap: true
EOF
# 2.最后分別重啟各個節(jié)點kubelet服務即可
systemctl daemon-reload && systemctl restart kubelet.service
# 3.查看節(jié)點的證書簽發(fā)請求
kubectl get csr
# NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
# csr-6w6xp 7s kubernetes.io/kubelet-serving system:node:devtest-master-212 <none> Pending
# csr-bpqzl 5s kubernetes.io/kubelet-serving system:node:devtest-master-213 <none> Pending
# csr-gtksm 3s kubernetes.io/kubelet-serving system:node:devtest-work-215 <none> Pending
# csr-vzfs7 4s kubernetes.io/kubelet-serving system:node:devtest-master-214 <none> Pending
# 4.同意簽發(fā)所有節(jié)點的CSR請求
kubectl certificate approve $(kubectl get csr | grep -v NAME | grep "Pending" | cut -d " " -f 1)
# certificatesigningrequest.certificates.k8s.io/csr-6w6xp approved
# certificatesigningrequest.certificates.k8s.io/csr-bpqzl approved
# certificatesigningrequest.certificates.k8s.io/csr-gtksm approved
# certificatesigningrequest.certificates.k8s.io/csr-vzfs7 approved
步驟 03.Metrics Server 默認是安裝在kube-system名稱空間下渤早,我們可以查看其deployment职车、Pod運行以及SVC情況。
# 1.部署清單狀態(tài)查看
kubectl get deploy,pod,svc -n kube-system -l k8s-app=metrics-server
# NAME READY UP-TO-DATE AVAILABLE AGE
# deployment.apps/metrics-server 1/1 1 1 5h37m
# NAME READY STATUS RESTARTS AGE
# pod/metrics-server-6ffc8966f5-c4jvn 1/1 Running 0 14m
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# service/metrics-server ClusterIP 10.111.197.94 <none> 443/TCP 5h37m
# 2.注冊到K8S集群中的 metrics.k8s.io API 查看
kubectl get apiservices.apiregistration.k8s.io | grep "metrics"
# v1beta1.metrics.k8s.io kube-system/metrics-server True 14h
步驟 04.查看各個節(jié)點以及Pod的資源指標(CPU/MEM)
$ kubectl top node
# NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
# devtest-master-212 219m 2% 2793Mi 17%
# devtest-master-213 211m 2% 2417Mi 15%
# devtest-master-214 203m 1% 2467Mi 7%
# devtest-work-215 90m 1% 1601Mi 10%
# 默認名稱空間中Pod的資源信息
$ kubectl top pod
# NAME CPU(cores) MEMORY(bytes)
# nginx 0m 10Mi
3.集群管理原生UI工具kubernetes-dashboard安裝部署
描述:Kubernetes Dashboard是Kubernetes集群的通用鹊杖、基于web的UI悴灵。它允許用戶管理集群中運行的應用程序并對其進行故障排除,以及管理集群本身骂蓖。
項目地址: https://github.com/kubernetes/dashboard/
步驟 01.從Github中拉取dashboard部署資源清單积瞒,當前最新版本v2.6.0 【2022年6月22日 16:46:37】
# 下載資源清單并部署 dashboard
$ wget -L https://raw.githubusercontent.com/kubernetes/dashboard/v2.6.0/aio/deploy/recommended.yaml -O dashboard.yaml
$ kubectl apply -f dashboard.yaml
$ grep "image:" dashboard.yaml
# image: kubernetesui/dashboard:v2.6.0
# image: kubernetesui/metrics-scraper:v1.0.8
# 或者一條命令搞定部署
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.6.0/aio/deploy/recommended.yaml
# serviceaccount/kubernetes-dashboard created
......
# deployment.apps/dashboard-metrics-scraper created
步驟 02.使用kubectl get命令查看部署的dashboard相關(guān)資源是否正常。
$ kubectl get pod,svc -n kubernetes-dashboard
NAME READY STATUS RESTARTS AGE
dashboard-metrics-scraper-6f669b9c9b-vfmzp 1/1 Running 0 73m
kubernetes-dashboard-67b9478795-2gwmm 1/1 Running 0 73m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/dashboard-metrics-scraper ClusterIP 10.106.168.38 <none> 8000/TCP 73m
service/kubernetes-dashboard ClusterIP 10.106.191.197 <none> 443/TCP 73m
# 編輯 service/kubernetes-dashboard 服務將端口通過nodePort方式進行暴露為30443登下。
$ kubectl edit svc -n kubernetes-dashboard kubernetes-dashboard
# service/kubernetes-dashboard edited
apiVersion: v1
kind: Service
.....
spec:
.....
ports:
- port: 443
protocol: TCP
targetPort: 8443
nodePort: 31443 # 新增
selector:
k8s-app: kubernetes-dashboard
sessionAffinity: None
type: NodePort # 修改
步驟 03.默認儀表板部署包含運行所需的最小RBAC權(quán)限集赡鲜,而要想使用dashboard操作集群中的資源,通常我們還需要自定義創(chuàng)建kubernetes-dashboard管理員角色庐船。
權(quán)限控制參考地址: https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/README.md
# 創(chuàng)建后最小權(quán)限的Token(只能操作kubernetes-dashboard名稱空間下的資源)
kubectl get sa -n kubernetes-dashboard kubernetes-dashboard
kubectl describe secrets -n kubernetes-dashboard kubernetes-dashboard-token-jhdpb | grep '^token:'|awk '{print $2}'
Kubernetes Dashboard 支持幾種不同的用戶身份驗證方式:
- Authorization header
- Bearer Token (默認)
- Username/password
- Kubeconfig file (默認)
溫馨提示: 此處使用Bearer Token方式, 為了方便演示我們向 Dashboard 的服務帳戶授予管理員權(quán)限 (Admin privileges), 而在生產(chǎn)環(huán)境中通常不建議如此操作, 而是指定一個或者多個名稱空間下的資源進行操作。
tee rbac-dashboard-admin.yaml <<'EOF'
apiVersion: v1
kind: ServiceAccount
metadata:
name: dashboard-admin
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dashboard-admin
namespace: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: dashboard-admin
namespace: kubernetes-dashboard
EOF
kubectl apply -f rbac-dashboard-admin.yaml
# serviceaccount/dashboard-admin created
# clusterrolebinding.rbac.authorization.k8s.io/dashboard-admin created
# 或者 兩條命令搞定
# kubectl create serviceaccount -n devtest devtest-ns-admin
# kubectl create clusterrolebinding devtest-ns-admin --clusterrole=admin --serviceaccount=devtest:devtest-ns-admin
步驟 04.獲取 sa 創(chuàng)建的 dashboard-admin 用戶的 secrets 名稱并獲取認證 token 嘲更,用于上述搭建的dashboard 認證使用筐钟。
kubectl get sa -n kubernetes-dashboard dashboard-admin -o yaml | grep "\- name" | awk '{print $3}'
# dashboard-admin-token-crh7v
kubectl describe secrets -n kubernetes-dashboard dashboard-admin-token-crh7v | grep "^token:" | awk '{print $2}'
# 獲取到認證Token
步驟 05.利用上述 Token 進行登陸Kubernetes-dashboard的UI,其地址為node節(jié)點加上31443,例如此處https://10.20.176.212:31443/#/workloads?namespace=default
。
4.集群管理K9S客戶端工具安裝使用
描述: k9s 是用于管理 Kubernetes 集群的 CLI, K9s 提供了一個終端 UI 來與您的 Kubernetes 集群進行交互赋朦。通過封裝 kubectl 功能 k9s 持續(xù)監(jiān)視 Kubernetes 的變化并提供后續(xù)命令來與您觀察到的資源進行交互篓冲,直白的說就是k9s可以讓開發(fā)者快速查看并解決運行 Kubernetes 時的日常問題。
官網(wǎng)地址: https://k9scli.io/
參考地址: https://github.com/derailed/k9s
此處,以安裝二進制包為例進行實踐宠哄。
# 1. 利用 wget 命令 -c 短點續(xù)傳和 -b 后臺下載
wget -b -c https://github.com/derailed/k9s/releases/download/v0.25.18/k9s_Linux_x86_64.tar.gz
# 2.解壓并刪除多余文件
tar -zxf k9s_linux_x86_64.tar.gz
rm k9s_linux_x86_64.tar.gz LICENSE README.md
# 3.拷貝 kubernetes 控制配置文件到加目錄中
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
export KUBECONFIG=/etc/kubernetes/admin.conf
# 4.直接運行即可壹将,如果你對vim操作比較熟悉,那么恭喜你了你很快能上手k9s.
/stroage/nfs# ./k9s
# 5.退出k9s指令
:quit
更多使用技巧請參考: [K9s之K8s集群管理工具實踐嘗試] (https://blog.weiyigeek.top/2022/1-1-582.html)
5.集群服務Service七層負載均衡ingress環(huán)境搭建部署
Q: 什么是Ingress?
A: Ingress 是管理對集群中服務的提供外部訪問的 API 對象,Ingress 控制器負責實現(xiàn) Ingress毛嫉,通常使用負載均衡器诽俯,但它也可以配置邊緣路由器或其他前端來幫助處理流量,它可以將來自集群外部的 HTTP 和 HTTPS 路由轉(zhuǎn)發(fā)到集群內(nèi)部的 Service 中承粤。
Ingress 只是一個統(tǒng)稱暴区,其由 Ingress 和 Ingress Controller 兩部分組成。
- Ingress 用作將原來需要手動配置的規(guī)則抽象成一個 Ingress 對象辛臊,使用 YAML 格式的文件來創(chuàng)建和管理仙粱。
- Ingress Controller 用作通過與 Kubernetes API 交互,動態(tài)的去感知集群中 Ingress 規(guī)則變化彻舰。
使用 Ingress 控制器可以輕松實現(xiàn)外部URL訪問集群內(nèi)部服務伐割、負載均衡候味、代理轉(zhuǎn)發(fā)、支持配置SSL/TLS并提供基于名稱的虛擬主機隔心,值得注意的是 Ingress 不會暴露任意端口或協(xié)議白群,通過使用 Service.Type=NodePort
或 Service.Type=LoadBalancer
類型的服務向向 Internet 公開 HTTP 和 HTTPS 的訪問服務
Q: 常用 Ingress 控制器有那些?
其中ingress controller目前主要有兩種基于nginx服務的ingress controller (四層或者七層)和基于traefik的ingress controller(目前支持http和https協(xié)議),其它更多適用于Kubernetes的ingress控制器可以參考地址[https://kubernetes.io/zh/docs/concepts/services-networking/ingress-controllers/#%E5%85%B6%E4%BB%96%E6%8E%A7%E5%88%B6%E5%99%A8]
- ingress-Nginx : 用于 Nginx Kubernetes Ingress 控制器能夠與 NGINX Web 服務器(作為代理)一起使用 (推薦)
- ingress-Traefik :由 Traefik Kubernetes Ingress 提供程序是一個用于 Traefik 代理的Ingress控制器济炎。
- ingress-istio : Istio Ingress 是一個基于Istio的Ingress控制器川抡。
溫馨提示: 理想情況下所有 Ingress 控制器都應符合參考規(guī)范。實際上各種 Ingress 控制器的操作略有不同,請參考相應Ingress的控制器官方文檔须尚。
如下圖所示的一個簡單的示例崖堤,客戶端請求訪問外部URL地址, Ingress 將其所有流量發(fā)送到一個Service中, 后端 Pod 提供服務端響應通過路由進行返回給客戶端。
溫馨提示: 基于nginx服務的ingress controller根據(jù)不同的開發(fā)公司耐床,又分為k8s社區(qū)的ingres-nginx和nginx公司的nginx-ingress密幔,在此根據(jù)github上的活躍度和關(guān)注人數(shù),我們選擇的是k8s社區(qū)的ingres-nginx撩轰。
- k8s社區(qū)提供的ingress胯甩,github地址如下:https://github.com/kubernetes/ingress-nginx
- nginx社區(qū)提供的ingress,github地址如下:https://github.com/nginxinc/kubernetes-ingress
Q: K8S社區(qū)提供 Ingress 規(guī)則有哪些?
- host : 虛擬主機名稱, 主機名通配符主機可以是精確匹配(例如"foo.bar.com")或通配符(例如“ *.foo.com”)
- paths : URL訪問路徑堪嫂。
- pathType : Ingress 中的每個路徑都需要有對應的路徑類型(Path Type)
- backend : 是 Service 文檔中所述的服務和端口名稱的組合與規(guī)則的 host 和 path 匹配的對 Ingress 的 HTTP(和 HTTPS )請求將發(fā)送到列出的 backend, 一般情況可以單獨為路徑設置Backend以及未匹配的url默認訪問的后端defaultBackend偎箫。
Ingress 中的每個路徑都需要有對應的路徑類型(Path Type),未明確設置 pathType 的路徑無法通過合法性檢查皆串,當前支持的路徑類型有三種:
- Exact:精確匹配 URL 路徑淹办,且區(qū)分大小寫。
- Prefix:基于以
/
分隔的URL路徑前綴匹配, 且區(qū)分大小寫恶复,并且對路徑中的元素逐個完成怜森。 - ImplementationSpecific:此路徑類型匹配方法取決于 IngressClass, 具體實現(xiàn)可以將其作為單獨的 pathType 處理或者與 Prefix 、 Exact 類型作相同處理谤牡。
說明: 如果路徑的最后一個元素是請求路徑中最后一個元素的子字符串副硅,則不會匹配 (例如:/foo/bar 匹配 /foo/bar/baz, 但不匹配 /foo/barbaz)。
溫馨提示: defaultBackend 通常在 Ingress 控制器中配置翅萤,以服務與規(guī)范中的路徑不匹配的任何請求恐疲。
tee > test.yaml << 'EOF'
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
spec:
defaultBackend:
service:
name: test
port:
number: 80
EOF
kubectl apply -f
注意, 入口控制器和負載平衡器可能需要一兩分鐘才能分配 IP 地址。 在此之前套么,你通常會看到地址字段的值被設定為<pending>
流纹。
溫馨提示: ingress控制器資源清單在v1.19以及之后版本集群中寫法如下
cat <<-EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: foo.bar.com
namespace: default
annotations:
#URL重定向。
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: foo.bar.com
http:
paths:
# 在Ingress Controller的版本≥0.22.0之后违诗,path中需要使用正則表達式定義路徑漱凝,并在rewrite-target中結(jié)合捕獲組一起使用。
- path: /svc(/|$)(.*)
backend:
service:
name: web1-service
port:
number: 80
pathType: ImplementationSpecific
EOF
Q: Nginx Ingress Controller與K8S集群版本對應關(guān)系
參考地址: https://github.com/kubernetes/ingress-nginx#support-versions-table
Support Versions table
Ingress-NGINX version k8s supported version Alpine Version Nginx Version
v1.2.1 1.23, 1.22, 1.21, 1.20, 1.19 3.14.6 1.19.10?
快速安裝配置
環(huán)境依賴說明: Chart version 4.x.x and above: Kubernetes v1.19+
步驟 01.如果您有 Helm诸迟,則可以使用以下命令部署入口控制器:
helm3 repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm3 repo update
helm3 search repo ingress-nginx -l
# NAME CHART VERSION APP VERSION DESCRIPTION
# ingress-nginx/ingress-nginx 4.1.4 1.2.1 Ingress controller for Kubernetes using NGINX a...
# ingress-nginx/ingress-nginx 4.1.3 1.2.1 Ingress controller for Kubernetes using NGINX a...
# ingress-nginx Chart 模板參數(shù)配置
helm3 show values --version 4.1.4 ingress-nginx/ingress-nginx > values.yaml
# values.yaml 配置修改完畢后安裝 ingress-nginx
helm3 install ingress-nginx -f values.yaml --version 4.1.4 ingress-nginx/ingress-nginx --namespace ingress-nginx --create-namespace --debug
溫馨提示: 上面在不需進行可用參數(shù)配置時可采用一條命令搞定(注意提前拉取相關(guān)鏡像)
helm3 upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace
溫馨提示: 使用如下更新helm圖表部署的應用以更新修改為國內(nèi)鏡像源茸炒。
$ crictl pull registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.2.1
$ crictl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1
helm3 upgrade ingress-nginx --namespace ingress-nginx --version 4.1.4 -f values.yaml ingress-nginx/ingress-nginx --debug
步驟 02.查看ingress-nginx的部署情況愕乎,一些 pod 應該在 ingress-nginx 命名空間中啟動:
helm3 list -n ingress-nginx
# NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
# ingress-nginx ingress-nginx 1 2022-06-24 13:12:36.692931823 +0800 CST deployed ingress-nginx-4.1.4 1.2.1
helm3 history ingress-nginx -n ingress-nginx
# REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
# 1 Fri Jun 24 13:20:49 2022 deployed ingress-nginx-4.1.4 1.2.1 Install complete
# 等待 Pod 應用部署為正常
kubectl wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=120s
# pod/ingress-nginx-controller-7cfd586878-fkdb5 condition met
# 查看 ingress-nginx 的 Pod 與 SVC
kubectl get pod,svc -n ingress-nginx
# NAME READY STATUS RESTARTS AGE
# pod/ingress-ingress-nginx-admission-create-pjm6x 0/1 Completed 0 7m47s
# pod/ingress-nginx-controller-7cfd586878-fkdb5 1/1 Running 0 18m
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# service/ingress-nginx-controller NodePort 10.107.81.40 <none> 80:30080/TCP,443:30443/TCP 18m
# service/ingress-nginx-controller-admission ClusterIP 10.106.154.244 <none> 443/TCP 18m
# 查看 ingress 的 ingressclasses 名稱后續(xù)才能使用。
kubectl get ingressclasses.networking.k8s.io
NAME CONTROLLER PARAMETERS AGE
nginx k8s.io/ingress-nginx <none> 19m
步驟 03.針對搭建的 ingress-nginx 服務驗證, 此處訪問應該是NGINX標準404錯誤頁面,因為
# Get the application URL by running these commands:
export HTTP_NODE_PORT=30080
export HTTPS_NODE_PORT=30443
export NODE_IP=$(kubectl --namespace ingress-nginx get nodes -o jsonpath="{.items[0].status.addresses[1].address}")
echo "Visit http://$NODE_IP:$HTTP_NODE_PORT to access your application via HTTP."
echo "Visit https://$NODE_IP:$HTTPS_NODE_PORT to access your application via HTTPS."
# 嘗試訪問 ingress - nginx
$ curl -I --insecure http://devtest-master-212:30080
$ curl -I --insecure https://devtest-master-212:30443
# HTTP/2 404
# date: Fri, 24 Jun 2022 07:07:12 GMT
# content-type: text/html
# content-length: 146
# strict-transport-security: max-age=15724800; includeSubDomains
步驟 04.優(yōu)化ingress Pod內(nèi)核參數(shù)以及擴容Pod到每個節(jié)點之上, 更多優(yōu)化可以參考 [https://blog.weiyigeek.top/2020/5-28-588.html#0x07-Kubernetes%E4%B8%ADingress-nginx%E4%BC%98%E5%8C%96%E9%85%8D%E7%BD%AE]
# 編輯 ingress-nginx-controller資源清單添加一個 initContainers 進行內(nèi)核參數(shù)初始化
$ kubectl edit deployments.apps -n ingress-nginx ingress-nginx-controller
....
initContainers:
- command:
- sh
- -c
- |
mount -o remount rw /proc/sys
sysctl -w net.core.somaxconn=65535
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.ip_local_port_range="1024 65535"
sysctl -w fs.file-max=1048576
sysctl -w fs.inotify.max_user_instances=16384
sysctl -w fs.inotify.max_user_watches=524288
sysctl -w fs.inotify.max_queued_events=16384
image: alpine:3.10
imagePullPolicy: IfNotPresent
name: sysctl
resources: {}
securityContext:
privileged: true
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
....
# 擴容 ingress-nginx-controller 副本為節(jié)點數(shù)量 (注意此處已去除master節(jié)點污點)
kubectl scale deployment --replicas=4 -n ingress-nginx ingress-nginx-controller
# 查看 ingress-controller 的Pod
kubectl get pod -n ingress-nginx -l app.kubernetes.io/component=controller -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-controller-7f8cd9c4fc-6lqgw 1/1 Running 0 5m33s 10.66.55.65 devtest-master-213 <none> <none>
ingress-nginx-controller-7f8cd9c4fc-8svfj 1/1 Running 0 3m16s 10.66.53.79 devtest-work-215 <none> <none>
ingress-nginx-controller-7f8cd9c4fc-g75fz 1/1 Running 0 6m40s 10.66.237.129 devtest-master-212 <none> <none>
ingress-nginx-controller-7f8cd9c4fc-jl5qg 1/1 Running 0 5m33s 10.66.35.67 devtest-master-214 <none> <none>
擴展知識文章:
1.使用二進制方式部署v1.23.6的K8S集群實踐(上)【 https://mp.weixin.qq.com/s/sYpHENyehAnGOQQakYzhUA 】
2.使用二進制方式部署v1.23.6的K8S集群實踐(下)【 https://mp.weixin.qq.com/s/-ksiNJG6v4q47ez7_H3uYQ 】
本文至此完畢壁公,更多技術(shù)文章感论,盡情期待下一章節(jié)!
歡迎各位志同道合的朋友一起學習交流紊册,如文章有誤請在下方留下您寶貴的經(jīng)驗知識!
原文地址: 21-kubernetes進階之kubeadm方式安裝高可用k8s集群
更多文章來源于【WeiyiGeek Blog 個人博客 - 為了能到遠方比肄,腳下的每一步都不能少 】
個人主頁: 【 https://weiyigeek.top】
博客地址: 【 https://blog.weiyigeek.top 】
專欄書寫不易,如果您覺得這個專欄還不錯的囊陡,請給這篇專欄 【點個贊芳绩、投個幣、收個藏撞反、關(guān)個注妥色,轉(zhuǎn)個發(fā),留個言】(人間六大情)遏片,這將對我的肯定嘹害,謝謝!吮便。
echo "【點個贊】笔呀,動動你那粗壯的拇指或者芊芊玉手,親髓需!"
printf("%s", "【投個幣】凿可,萬水千山總是情,投個硬幣行不行授账,親!")
fmt.Printf("【收個藏】惨驶,閱后即焚不吃灰白热,親!")
console.info("【轉(zhuǎn)個發(fā)】粗卜,讓更多的志同道合的朋友一起學習交流屋确,親!")
System.out.println("【關(guān)個注】续扔,后續(xù)瀏覽查看不迷路喲攻臀,親!")
cout << "【留個言】纱昧,文章寫得好不好刨啸、有沒有錯誤,一定要留言喲识脆,親! " << endl;
更多網(wǎng)絡安全设联、系統(tǒng)運維善已、應用開發(fā)、物聯(lián)網(wǎng)開發(fā)离例、網(wǎng)絡工程换团、全棧文章,盡在博客 https://blog.weiyigeek.top 之中宫蛆,謝謝各位看友支持艘包!