企業運維實踐-還不會部署高可用的kubernetes集群?使用kubeadm方式安裝高可用k8s集群v1.23.7
關注「WeiyiGeek」公眾號
設為「特別關注」每天帶你玩轉網絡安全運維、應用開發、物聯網IOT學習!
希望各位看友【關注、點贊、評論、收藏、投幣】,助力每一個夢想。
文章目錄:
0x00 前言簡述
0x01 環境準備
- 主機規劃
- 軟件版本
- 網絡規劃
0x02 安裝部署
- 1.準備基礎主機環境配置
- 2.負載均衡管理ipvsadm工具安裝與內核加載
- 3.高可用HAProxy與Keepalived軟件安裝配置
- 4.容器運行時containerd.io安裝配置
- 5.安裝源配置與初始化集群配置準備
- 6.使用kubeadm安裝部署K8S集群
- 7.部署配置 Calico 網絡插件
0x03 集群輔助插件部署
- 1.集群中基於nfs的provisioner的動態持卷環境部署
- 2.集群中安裝metrics-server獲取客戶端資源監控指標
- 3.集群管理原生UI工具kubernetes-dashboard安裝部署
- 4.集群管理K9S客戶端工具安裝使用
- 5.集群服務Service七層負載均衡ingress環境搭建部署
溫馨提示:若文章中有圖片顯示不全,可訪問我的博客【 //blog.weiyigeek.top 】繼續瀏覽該篇文章。
0x00 前言簡述
描述: 在我博客以及前面的文章之中講解Kubernetes相關集群環境的搭建說明, 隨着K8S及其相關組件的迭代, 與讀者當前接觸的版本有所不同,在上一章中我們一起實踐了【使用二進制方式進行安裝部署高可用的K8S集群V1.23.6】(//blog.weiyigeek.top/2022/5-7-654.html) , 所以本章將實踐使用kubeadm方式部署搭建高可用的kubernetes集群V1.23.7,此處仍然按照ubuntu 20.04系統以及haproxy、keepalive、containerd、etcd、kubeadm、kubectl 等相關工具插件【最新或者穩定的版本】進行實踐,這裡不再對k8s等相關基礎知識做介紹,如有新入門的童鞋,請訪問如下【博客文章】(//blog.weiyigeek.top/tags/k8s/) 或者【B站專欄】(//www.bilibili.com/read/readlist/rl520875?spm_id_from=333.999.0.0) 按照順序學習。
Kubernetes 簡述
Kubernetes (後續簡稱k8s)是 Google(2014年6月) 開源的一個容器編排引擎,使用Go語言開發,它支持自動化部署、大規模可伸縮、以及雲平台中多個主機上的容器化應用進行管理。其目標是讓部署容器化的應用更加簡單並且高效,提供了資源調度、部署管理、服務發現、擴容縮容、狀態 監控、維護等一整套功能, 努力成為跨主機集群的自動化部署、自動化擴展以及運行應用程序容器的平台,它支持一些列CNCF畢業項目,包括 Containerd、calico 等 。
擴展文章:
1.使用二進制方式部署v1.23.6的K8S集群實踐(上)【 //mp.weixin.qq.com/s/sYpHENyehAnGOQQakYzhUA 】
2.使用二進制方式部署v1.23.6的K8S集群實踐(下)【 //mp.weixin.qq.com/s/-ksiNJG6v4q47ez7_H3uYQ 】
本章完整原文地址:
0x01 環境準備
主機規劃
溫馨提示: 同樣此處使用的是 Ubuntu 20.04 操作系統, 該系統已做安全加固和內核優化符合等保2.0要求【SecOpsDev/Ubuntu-InitializeSecurity.sh at master · WeiyiGeek/SecOpsDev (github.com)】, 如你的Linux未進行相應配置環境可能與讀者有些許差異, 如需要進行(windows server、Ubuntu、CentOS)安全加固請參照如下加固腳本進行加固, 請大家瘋狂的 star 。
加固腳本地址:【 //github.com/WeiyiGeek/SecOpsDev/blob/master/OS-操作系統/Linux/Ubuntu/Ubuntu-InitializeSecurity.sh 】
主機地址 | 主機名稱 | 主機配置 | 主機角色 | 軟件組件 |
---|---|---|---|---|
10.20.176.212 | devtest-master-212 | 8C/16G | 控制節點 | |
10.20.176.213 | devtest-master-213 | 8C/16G | 控制節點 | |
10.20.176.214 | devtest-master-214 | 8C/32G | 控制節點 | |
10.20.176.215 | devtest-work-215 | 8C/16G | 工作節點 | |
10.20.176.211 | slbvip.k8s.devtest | – | 虛擬VIP | 虛擬網卡地址 |
軟件版本
操作系統
- 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數據庫
- 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
網絡插件&輔助軟件
- calico – v3.22
- coredns – v1.9.1
- kubernetes-dashboard – v2.5.1
- k9s – v0.25.18
網絡規劃
子網 Subnet | 網段 | 備註 |
---|---|---|
nodeSubnet | 10.20.176.0/24 | 宿主機節點子網 |
ServiceSubnet | 10.96.0.0/16 | SVC 子網 |
PodSubnet | 10.66.0.0/16 | POD 子網 |
0x02 安裝部署
1.準備基礎主機環境配置
步驟 01.【所有主機】主機名設置按照上述主機規划進行設置。
# 例如, 在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.【所有主機】將規劃中的主機名稱與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.驗證每個節點上IP、MAC 地址和 product_uuid 的唯一性,保證其能相互正常通信
# 使用命令 ip link 或 ifconfig -a 來獲取網絡接口的 MAC 地址
ifconfig -a
# 使用命令 查看 product_uuid 校驗
sudo cat /sys/class/dmi/id/product_uuid
步驟 04.【所有主機】系統時間同步與時區設置
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.【所有主機】禁用系統交換分區
swapoff -a && sed -i 's|^/swap.img|#/swap.ing|g' /etc/fstab
# 驗證交換分區是否被禁用
free | grep "Swap:"
步驟 06.【所有主機】系統內核參數調整
# 禁用 swap 分區
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
# 允許轉發
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.【所有主機】禁用系統防火牆
ufw disable && systemctl disable ufw && systemctl stop ufw
2.負載均衡管理ipvsadm工具安裝與內核加載
步驟 01.安裝ipvs模塊以及負載均衡相關依賴。
# 查看可用版本
sudo apt-cache madison ipvsadm
# ipvsadm | 1:1.31-1 | //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.將模塊加載到內核中(開機自動設置-需要重啟機器生效)
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內核中。
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
# 權限設置、並加載到系統之中
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軟件安裝配置
描述: 由於是測試學習環境, 此處我未專門準備兩台HA服務器, 而是直接採用master節點機器,如果是正式環境建議獨立出來。
步驟 01.【Master節點機器】安裝下載 haproxy (HA代理健康檢測) 與 keepalived (虛擬路由協議-主從)。
# 查看可用版本
sudo apt-cache madison haproxy keepalived
# haproxy | 2.0.13-2ubuntu0.5 | //mirrors.aliyun.com/ubuntu focal-security/main amd64 Packages
# keepalived | 1:2.0.19-2ubuntu0.2 | //mirrors.aliyun.com/ubuntu focal-updates/main amd64 Packages
# 安裝
sudo apt -y install haproxy keepalived
# 鎖定版本
apt-mark hold haproxy keepalived
步驟 02.【Master節點機器】進行 HAProxy 配置,其配置目錄為 /etc/haproxy/
,所有節點配置是一致的。
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: //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節點在一起所以不能使用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 節點的默認 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節點機器】進行 KeepAlived 相關配置 ,其配置目錄為 /etc/haproxy/
# 創建配置目錄,分別在各個master節點執行。
mkdir -vp /etc/keepalived
# __ROLE__ 角色: MASTER 或者 BACKUP
# __NETINTERFACE__ 宿主機物理網卡名稱 例如我的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 主機上執行)
# 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 主機上執行)
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 主機上執行)
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
溫馨提示: 注意上述的健康檢查是關閉注釋了的,你需要將K8S集群建立完成後再開啟。
track_script {
chk_apiserver
}
步驟 04.【Master節點機器】進行配置 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節點機器】啟動 haproxy 、keepalived 相關服務及測試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 主機中發現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
# 此時,發現VIP已經飄到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節點上安裝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 //download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 4.通過搜索指紋的最後8個字符進行密鑰驗證
sudo apt-key fingerprint 0EBFCD88
# 5.設置穩定存儲庫
sudo add-apt-repository \
"deb [arch=amd64] //download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
# 6.安裝特定版本在repo中列出可用的版本
sudo apt-cache madison containerd.io
# containerd.io | 1.6.6-1 | //download.docker.com/linux/ubuntu focal/stable amd64 Packages
# containerd.io | 1.6.4-1 | //download.docker.com/linux/ubuntu focal/stable amd64 Packages
# containerd.io | 1.5.11-1 | //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.下載安裝後在【所有節點】進行containerd 配置,此處將創建並修改 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 = ["//05f073ad3c0010ea0f4bc00b7105ec20.mirror.swr.myhuaweicloud.com","//xlx9erfu.mirror.aliyuncs.com","//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 = ["//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 = ["//gcr.mirrors.ustc.edu.cn/google-containers/","//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 = ["//quay.mirrors.ustc.edu.cn"]' /etc/containerd/config.toml
步驟 03.修改配置後【所有節點】重載containerd服務並查看相關服務及其版本。
# 配置重載與服務重啟
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: //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.【所有節點】Kubernetes 安裝源配置及其kubelet、kubeadm、kubectl工具下載安裝
# (1) gpg 簽名下載導入
curl //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 //mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
apt update
# 其它方式:
# (2) 設置穩定存儲庫
# sudo add-apt-repository "deb //mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main"
# (3) K8S可用版本,此處可以看見最新的是 1.24.1 , 由於博主實踐的K8S是為開發測試環境所搭建,則此處選擇 1.23.7 版本。
apt-cache madison kubelet | more
kubelet | 1.24.1-00 | //mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages
kubelet | 1.24.0-00 | //mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages
kubelet | 1.23.7-00 | //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.【所有節點】重載systemd守護進程並將 kubelet 設置成開機啟動
systemctl daemon-reload
systemctl restart containerd.service
systemctl enable kubelet && systemctl start kubelet
步驟 03.【devtest-master-212】為了節約拉取實踐我們可以在某一台master節點上先拉取所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版本依賴的相關鏡像
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.導入到各個節點後我們可以通過如下命令查看導入的鏡像列表信息。
# 方式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 節點】生成K8S初始化yaml配置文件,並根據實際情況進行編輯。
$ 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 # 關鍵點: 當前節點地址
bindPort: 6443 # 關鍵點: API端口默認即可
nodeRegistration:
criSocket: /run/containerd/containerd.sock # 關鍵點: 指定containerd為運行時
imagePullPolicy: IfNotPresent
name: devtest-master-212 # 關鍵點: 當前節點名稱
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
apiServer:
certSANs: # 關鍵點: 證書中心包含的SANs列表一般包含VIP與各節點的主機名稱
- 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 # 關鍵點: 集群所需鏡像倉庫源加快拉取
kind: ClusterConfiguration
kubernetesVersion: v1.23.7 # 關鍵點: K8S集群版本此處與我們提前下載的鏡像版本必須一致否則將會重新拉取指定K8S集群所需鏡像。
controlPlaneEndpoint: slbvip.k8s.devtest:16443 # 關鍵點: 高可用VIP地址的域名與haproxy代理端口。
networking:
dnsDomain: cluster.test # 關鍵點: 集群dns根域默認cluster.local
serviceSubnet: 10.96.0.0/12 # 關鍵點: services 服務子網段
podSubnet: 10.66.0.0/16 # 關鍵點: pod 服務子網段
scheduler: {}
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs # 關鍵點: 啟用IPVS支持
ipvs:
excludeCIDRs:
- 10.66.66.2/32 # 關鍵點: 排出指定IP
EOF
步驟 02.【devtest-master-212 節點】準備好初始化yaml清單後, 通過 kubeadm init 命令進行集群的初始化,並將日誌輸入到kubeadm-init.log。
kubeadm init --config=kubeadm-init-cluster.yaml --v=5 | tee kubeadm-init.log
# --config 指定yaml配置文件
# --v 指定日誌等級 debug
# 當執行後出現如下提示表明節點初始化安裝成功,可以按照指定提示進行執行。
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:
//kubernetes.io/docs/concepts/cluster-administration/addons/
# 【控制節點加入命令】
# 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
# 【工作節點加入命令】
# 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】節點中/etc/kubernetes/
目錄中的如下文件進行複製打包,並通過http協議將其分享給其它機器進行下載
# 將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
# 在其它【節點】進入到/tmp/執行如下命令進行下載
cd /tmp/ && wget 10.20.176.212:8080/pki.tar.gz
tar -zxvf /tmp/pki.tar.gz -C /etc/kubernetes/
# 查看解壓後的複製到/etc/kubernetes/目錄中的文件相關結構。
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】節點中執行如下 kubeadm join 命令添加新的 Master 節點到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】節點中執行如下 kubeadm join 命令添加新的 Work 節點到K8S集群中, 加入成功後如下圖所示:
kubeadm join slbvip.k8s.devtest:16443 \
--token devtes.httpweiyigeektop \
--discovery-token-ca-cert-hash sha256:4e5b3acb1d821bbd3976355f7b12b1daaa44e1fc38cbdfb2f86f4078d9507f22 \
--cri-socket /run/containerd/containerd.sock
步驟 06.全部加入到集群後我們可以通過如下命令進行查看添加的節點以及其節點角色設置,最終執行結果如下圖所示。
# 集群節點查看
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
# 集群節點角色設置,此處將devtest-work-215節點的ROLES設置為 work。
root@devtest-master-212:~$ kubectl label node devtest-work-215 node-role.kubernetes.io/work=
# node/devtest-work-215 labeled
步驟 07.查看集群信息、集群組件、以及集群中所有Pod進行查看, 執行結果如下
root@devtest-master-212:~# kubectl cluster-info
Kubernetes control plane is running at //slbvip.k8s.devtest:16443
CoreDNS is running at //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.然後我們為kubectl添加命令自動補齊不全功能,執行如下代碼即可。
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驗證集群環境, 並通過curl進行訪問,但是此時你會發現只有在【devtest-work-215】主機上才能訪問該nginx,而其它節點訪問時會報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 //10.22.0.5
curl: (28) Failed to connect to 10.22.0.5 port 80: Connection timed out
溫馨提示: 這是由於我們沒有為集群配置網絡插件,而常用的網絡插件是flannel、calico(下面將會以此為例
)以及當下cilium。
步驟 11.特別注意此處為了能在後續演示中將Pod應用調度到Master節點上,此時我們需要分別去除控制節點的污點。
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 網絡插件
描述: 在節點加入到集群時有時你會發現其節點狀態為 NotReady, 以及前面部署Pod無法被其它節點機器進行代理轉發訪問,所以部署calico插件可以讓Pod與集群正常通信。
步驟 01.在【devtest-master-212】節點上拉取最新版本的 calico 當前最新版本為 v3.22, 官方項目地址 (//github.com/projectcalico/calico)
# 拉取 calico 部署清單
wget //docs.projectcalico.org/v3.22/manifests/calico.yaml
步驟 02.修改 calico.yaml 文件的中如下 K/V, 即 Pod 獲取IP地址的地址池, 從網絡規劃中我們設置為 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.執行 kubectl apply 命令部署 calico 到集群之中。
kubectl apply -f calico.yaml
# configmap/calico-config created
# ....
# poddisruptionbudget.policy/calico-kube-controllers created
步驟 04.查看calico網絡插件在各節點上部署結果,狀態為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 再重新創建一個Pod應用,並在非【devtest-work-215 】節點上進行訪問測試
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集群部署完畢,在下節中將實踐演示在集群中安裝 Metrics Server 、kubernetes-dashboard、nfs-provisioner、ingress 等安裝實踐。
0x03 集群輔助插件部署
1.集群中基於nfs的provisioner的動態持卷環境部署
描述: 在K8S集群中我們常常會使用動態持久卷對應用數據進行持久化保存,例如應用配置、依賴插件、應用數據以及應用訪問日誌等,所以動態持久卷的重要性不言而喻,此小節將講解如何搭建以及nfs存儲服務以及使用kubernetes-sigs
提供的[nfs-subdir-external-provisioner] (//github.com/kubernetes-sigs/nfs-subdir-external-provisioner)項目針對已存在的 nfs 服務器進行 provisioner 部署。
Q: 什麼是nfs-subdir-external-provisioner?
NFS subdir external provisioner 是一個自動配置器,它使用您現有的和已配置的 NFS 服務器來支持通過 Persistent Volume Claims 動態配置 Kubernetes Persistent Volumes。
持久卷配置為 ${namespace}-${pvcName}-${pvName}。
溫馨提示:在進行此環境搭建時,請注意您必須已經有配置好的 NFS 服務器,為了保持與早期部署文件的向後兼容性,NFS Client Provisioner 的命名在部署 YAML 中保留為 nfs-storage-provisioner。
項目地址: //github.com/kubernetes-sigs/nfs-subdir-external-provisioner
步驟 01.我在一台Ubuntu 20.04主機上配置 NFS 存儲服務器(IP地址為10.20.176.102),如果你已有存儲服務器提供的NFS服務器則可以略過此步驟,其它操作系統安裝部署請看出我的這篇博客文章[NFS網絡文件系統基礎配置與使用] (//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
# [根據需求配置] 設置允許連接的ip, Example Allow 192.168.1.0/24 to be Accessed on Network
$ nano /etc/hosts.allow
portmap: 192.168.1.0/24
# [根據需求配置] idmapd 配置, 此處配置端口為40000
$ nano /etc/default/nfs-common
NEED_IDMAPD=YES
STATDOPTS="--port 40000"
# [根據需求配置] 內核服務配置,此處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.創建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防火牆規則配置 (PS: 通過rpcinfo命令可以查看 NFS 相關的端口)
ufw allow 111,2049,40000,40001/tcp
ufw reload
步驟 02.【所有節點】在客戶端嘗試掛載搭建的NFS服務器,並分別在節點機器掛載到/storage/nfs
目錄中
# 查看 NFS 掛載目錄
showmount -e 127.0.0.1
# Export list for 127.0.0.1:
# /app/storage/nfs *
# 掛載 NFS 服務器到指定節點目錄的/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
# 如果不使用了則可執行如下命令進行卸載掛載點
umount /storage/nfs
步驟 03.helm3 部署工具快速安裝
# helm3 安裝
$ wget //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 //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 //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域名下國內可能無法拉取,此處我已經拉取到阿里雲鏡像倉庫中registry.cn-hangzhou.aliyuncs.com/weiyigeek/nfs-subdir-external-provisioner:v4.0.2
,如果你需要自行拉取請參考此篇使用Aliyun容器鏡像服務對海外鏡像倉庫中鏡像進行拉取構建 ()
步驟 05.查看部署的nfs-storage動態持久卷以及其pod狀態
$ 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動態卷執行如下命令即可。
$ helm3 uninstall nfs-storage
release "nfs-storage" uninstalled
至此,基於NFS的provisioner 動態持久卷的安裝部署到此結束。
溫馨提示: 如果需要部署多個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 # 關鍵點(提供者不能一樣)
name: nfs-local
# 例如,此處創建兩個nfs動態卷即nfs-local與nfs-dev。
helm3 install nfs-local nfs-subdir-external-provisioner/
helm3 install nfs-dev nfs-subdir-external-provisioner-dev/
# helm 部署結果查看
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獲取客戶端資源監控指標
描述: 通常在集群安裝完成後,我們需要對其設置網絡、持久卷存儲等插件, 除此之外我們還需安裝metrics-server以便於獲取Node與Pod相關資源消耗等信息,否則你在執行kubectl top
命令時會提示error: Metrics API not available
, 所以本小節將針對Metrics-server的安裝進行講解。
項目地址: //github.com/kubernetes-sigs/metrics-server
Q: 什麼是metrics-server?
Metrics Server 是 Kubernetes 內置自動縮放管道的可擴展、高效的容器資源指標來源。
Metrics Server 從 Kubelets 收集資源指標,並通過 Metrics API 在 Kubernetes apiserver 中公開它們,供 Horizontal Pod Autoscaler 和 Vertical Pod Autoscaler 使用。
簡單的說: Metrics Server 是集群解析監控數據的聚合器,安裝後用戶可以通過標準的API(/apis/metrics.k8s.io)來訪問監控數據,此處值得注意的是Metrics-Server並非kube-apiserver的一部分,而是通過Aggregator這種插件機制,在獨立部署的情況下同kube-apiserver一起統一對外服務的,當進行api請求時kube-aggregator統一接口會分析訪問api具體的類型,幫我們負載到具體的api上。
溫馨提示: 我們可以通過 kubectl top
命令來訪問 Metrics API 獲取資源監控相關數據。
溫馨提示: 注意 Metrics API 只可以查詢當前度量數據,並不保存歷史數據。
安裝使用
步驟 01.Metrics Server 可以直接從 YAML 清單安裝,也可以通過官方 Helm 圖表安裝。
# (1) 下載 YAML 清單
wget //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) 由於其鏡像國內無法訪問此處我們採用阿里雲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 狀態為 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 \"//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 \"//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 簽發證書的導致訪問各節點資源時報錯。
-
解決辦法: 啟用 TLS BootStrap 證書籤發
# 1.分別在 Master 與 Node 節點中啟用TLS BootStrap 證書籤發,在 kubelet 的 yaml 配置中追加入如下K/V.
# 方式1.Kubeadm 搭建的集群
$ vim /var/lib/kubelet/config.yaml
...
serverTLSBootstrap: true
# 方式2.二進制搭建的集群(注意此路徑根據你的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.最後分別重啟各個節點kubelet服務即可
systemctl daemon-reload && systemctl restart kubelet.service
# 3.查看節點的證書籤發請求
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.同意簽發所有節點的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.部署清單狀態查看
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.查看各個節點以及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。它允許用戶管理集群中運行的應用程序並對其進行故障排除,以及管理集群本身。
項目地址: //github.com/kubernetes/dashboard/
步驟 01.從Github中拉取dashboard部署資源清單,當前最新版本v2.6.0 【2022年6月22日 16:46:37】
# 下載資源清單並部署 dashboard
$ wget -L //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 //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相關資源是否正常。
$ 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權限集,而要想使用dashboard操作集群中的資源,通常我們還需要自定義創建kubernetes-dashboard管理員角色。
權限控制參考地址: //github.com/kubernetes/dashboard/blob/master/docs/user/access-control/README.md
# 創建後最小權限的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 的服務帳戶授予管理員權限 (Admin privileges), 而在生產環境中通常不建議如此操作, 而是指定一個或者多個名稱空間下的資源進行操作。
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 創建的 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節點加上31443,例如此處//10.20.176.212:31443/#/workloads?namespace=default
。
4.集群管理K9S客戶端工具安裝使用
描述: k9s 是用於管理 Kubernetes 集群的 CLI, K9s 提供了一個終端 UI 來與您的 Kubernetes 集群進行交互。通過封裝 kubectl 功能 k9s 持續監視 Kubernetes 的變化並提供後續命令來與您觀察到的資源進行交互,直白的說就是k9s可以讓開發者快速查看並解決運行 Kubernetes 時的日常問題。
官網地址: //k9scli.io/
參考地址: //github.com/derailed/k9s
此處,以安裝二進制包為例進行實踐。
# 1. 利用 wget 命令 -c 短點續傳和 -b 後台下載
wget -b -c //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集群管理工具實踐嘗試] (//blog.weiyigeek.top/2022/1-1-582.html)
5.集群服務Service七層負載均衡ingress環境搭建部署
Q: 什麼是Ingress?
A: Ingress 是管理對集群中服務的提供外部訪問的 API 對象,Ingress 控制器負責實現 Ingress,通常使用負載均衡器,但它也可以配置邊緣路由器或其他前端來幫助處理流量,它可以將來自集群外部的 HTTP 和 HTTPS 路由轉發到集群內部的 Service 中。
Ingress 只是一個統稱,其由 Ingress 和 Ingress Controller 兩部分組成。
- Ingress 用作將原來需要手動配置的規則抽象成一個 Ingress 對象,使用 YAML 格式的文件來創建和管理。
- Ingress Controller 用作通過與 Kubernetes API 交互,動態的去感知集群中 Ingress 規則變化。
使用 Ingress 控制器可以輕鬆實現外部URL訪問集群內部服務、負載均衡、代理轉發、支持配置SSL/TLS並提供基於名稱的虛擬主機,值得注意的是 Ingress 不會暴露任意端口或協議,通過使用 Service.Type=NodePort
或 Service.Type=LoadBalancer
類型的服務向向 Internet 公開 HTTP 和 HTTPS 的訪問服務
Q: 常用 Ingress 控制器有那些?
其中ingress controller目前主要有兩種基於nginx服務的ingress controller (四層或者七層)和基於traefik的ingress controller(目前支持http和https協議),其它更多適用於Kubernetes的ingress控制器可以參考地址[//kubernetes.io/zh/docs/concepts/services-networking/ingress-controllers/#其他控制器]
- ingress-Nginx : 用於 Nginx Kubernetes Ingress 控制器能夠與 NGINX Web 服務器(作為代理)一起使用 (推薦)
- ingress-Traefik :由 Traefik Kubernetes Ingress 提供程序是一個用於 Traefik 代理的Ingress控制器。
- ingress-istio : Istio Ingress 是一個基於Istio的Ingress控制器。
溫馨提示: 理想情況下所有 Ingress 控制器都應符合參考規範。實際上各種 Ingress 控制器的操作略有不同,請參考相應Ingress的控制器官方文檔。
如下圖所示的一個簡單的示例,客戶端請求訪問外部URL地址, Ingress 將其所有流量發送到一個Service中, 後端 Pod 提供服務端響應通過路由進行返回給客戶端。
溫馨提示: 基於nginx服務的ingress controller根據不同的開發公司,又分為k8s社區的ingres-nginx和nginx公司的nginx-ingress,在此根據github上的活躍度和關注人數,我們選擇的是k8s社區的ingres-nginx。
- k8s社區提供的ingress,github地址如下://github.com/kubernetes/ingress-nginx
- nginx社區提供的ingress,github地址如下://github.com/nginxinc/kubernetes-ingress
Q: K8S社區提供 Ingress 規則有哪些?
- host : 虛擬主機名稱, 主機名通配符主機可以是精確匹配(例如”foo.bar.com”)或通配符(例如「 *.foo.com」)
- paths : URL訪問路徑。
- pathType : Ingress 中的每個路徑都需要有對應的路徑類型(Path Type)
- backend : 是 Service 文檔中所述的服務和端口名稱的組合與規則的 host 和 path 匹配的對 Ingress 的 HTTP(和 HTTPS )請求將發送到列出的 backend, 一般情況可以單獨為路徑設置Backend以及未匹配的url默認訪問的後端defaultBackend。
Ingress 中的每個路徑都需要有對應的路徑類型(Path Type),未明確設置 pathType 的路徑無法通過合法性檢查,當前支持的路徑類型有三種:
- Exact:精確匹配 URL 路徑,且區分大小寫。
- Prefix:基於以
/
分隔的URL路徑前綴匹配, 且區分大小寫,並且對路徑中的元素逐個完成。 - ImplementationSpecific:此路徑類型匹配方法取決於 IngressClass, 具體實現可以將其作為單獨的 pathType 處理或者與 Prefix 、 Exact 類型作相同處理。
說明: 如果路徑的最後一個元素是請求路徑中最後一個元素的子字符串,則不會匹配 (例如:/foo/bar 匹配 /foo/bar/baz, 但不匹配 /foo/barbaz)。
溫馨提示: defaultBackend 通常在 Ingress 控制器中配置,以服務與規範中的路徑不匹配的任何請求。
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中結合捕獲組一起使用。
- path: /svc(/|$)(.*)
backend:
service:
name: web1-service
port:
number: 80
pathType: ImplementationSpecific
EOF
Q: Nginx Ingress Controller與K8S集群版本對應關係
參考地址: //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†
快速安裝配置
環境依賴說明: Chart version 4.x.x and above: Kubernetes v1.19+
步驟 01.如果您有 Helm,則可以使用以下命令部署入口控制器:
helm3 repo add ingress-nginx //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 模板參數配置
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
溫馨提示: 上面在不需進行可用參數配置時可採用一條命令搞定(注意提前拉取相關鏡像)
helm3 upgrade --install ingress-nginx ingress-nginx \
--repo //kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace
溫馨提示: 使用如下更新helm圖表部署的應用以更新修改為國內鏡像源。
$ 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 名稱後續才能使用。
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 //$NODE_IP:$HTTP_NODE_PORT to access your application via HTTP."
echo "Visit //$NODE_IP:$HTTPS_NODE_PORT to access your application via HTTPS."
# 嘗試訪問 ingress - nginx
$ curl -I --insecure //devtest-master-212:30080
$ curl -I --insecure //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.優化ingress Pod內核參數以及擴容Pod到每個節點之上, 更多優化可以參考 [//blog.weiyigeek.top/2020/5-28-588.html#0x07-Kubernetes中ingress-nginx優化配置]
# 編輯 ingress-nginx-controller資源清單添加一個 initContainers 進行內核參數初始化
$ 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 副本為節點數量 (注意此處已去除master節點污點)
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>
本章完整原文地址:
- 還不會部署高可用的kubernetes集群?企業DevOps實踐之使用kubeadm方式安裝高可用k8s集群v1.23.7-//mp.weixin.qq.com/s/v_kO8o8mWOYc38kot86g6Q
- 21-kubernetes進階之kubeadm方式安裝高可用k8s集群
本文至此完畢,更多技術文章,盡情期待下一章節!
歡迎各位志同道合的朋友一起學習交流,如文章有誤請在下方留下您寶貴的經驗知識!
更多文章來源於【WeiyiGeek Blog 個人博客 – 為了能到遠方,腳下的每一步都不能少 】
個人主頁: 【 //weiyigeek.top】
博客地址: 【 //blog.weiyigeek.top 】
專欄書寫不易,如果您覺得這個專欄還不錯的,請給這篇專欄 【點個贊、投個幣、收個藏、關個注,轉個發,留個言】(人間六大情),這將對我的肯定,謝謝!。
-
echo “【點個贊】,動動你那粗壯的拇指或者芊芊玉手,親!”
-
printf(“%s”, “【投個幣】,萬水千山總是情,投個硬幣行不行,親!”)
-
fmt.Printf(“【收個藏】,閱後即焚不吃灰,親!”)
-
console.info(“【轉個發】,讓更多的志同道合的朋友一起學習交流,親!”)
-
System.out.println(“【關個注】,後續瀏覽查看不迷路喲,親!”)
-
cout << “【留個言】,文章寫得好不好、有沒有錯誤,一定要留言喲,親! ” << endl;
更多網絡安全、系統運維、應用開發、物聯網開發、網絡工程、全棧文章,盡在【個人博客 – //blog.weiyigeek.top】站點,謝謝支持!