banner
云野阁

云野阁

闲云野鹤,八方逍遥

k8s知識梳理--進階

網路#

Kubernetes - 網路模型原則

在不使用網路地址轉換 (NAT) 的情況下,集群中的 Pod 能夠與任意其他 Pod 進行通信

在不使用網路地址轉換 (NAT) 的情況下,在集群節點上運行的程序能與同一節點上的任何 Pod 進行通信

每個 Pod 都有自己的 IP 地址 (IP-per-Pod),並且任意其他 Pod 都可以通過相同的這個地址訪問它

藉助 CNI 標準,Kubernetes 可以實現容器網路問題的解決。通過插件化的方式來整合各種網路插件,實現集群內部網終相互通信,只要實現 CNI 標準中定義的核心介面操作 (ADD, 將容器添加到網路;DEL,從網路中刪除一個容器;CHECK, 檢查容器的網路是否符合預期等)。CNI 插件通常聚焦在容器到容器的網路通信。

CNI 的介面並不是指 HTTP,gRPC 這種介面,CNI 介面是指對可執行程序的調用 (exec) 可執行程序,Kubernetes 節點默認的 CNI 插件路徑為 /opt/cni/bin

CNI 通過 JSON 格式的配置文件來描述網路配置,當需要設置容器網路時,由容器運行時負責執行 CNI 插件,並通過 CNI 插件的標準輸入 (stdin) 來傳遞配置文件信息,通過標準輸出 (stdout) 接收插件的執行結果。從網路插件功能可以分為五類:

  • Main 插件,創建具體網路設備 (bridge: 網橋設備,連接 container 和 host;ipvlan: 為容器增加 ipvlan 網卡;loopback設備;macvlan: 為容器創建一個 MAC 地址;ptp: 創建一對 VethPair;vlan: 分配一個 vlan 設備;host-device: 將已存在的設備移入容器內)
  • IPAM 插件:負責分配 IP 地址 (dhcp: 容器向 DHCP 伺服器發起請求,給 Pod 發放或回收 IP 地址;host-local: 使用預先配置的 IP 地址段來進行分配;static: 為容器分配一個靜態 IPv4/IPv6 地址主要用於 debug)
  • META 插件:其他功能的插件 (tuning: 通過 sysctl 調整網路設備參數;portmap: 通過 iptables 配置端口映射;bandwidth: 使用 Token Bucket Filter 來限流;sbr: 為網卡設置 source based routing;firewall:通過 iptables 給容器網路的進出流量進行限制)
  • Windows 插件:專門用於 Windows 平台的 CNI 插件 (win-bridge 與 win-overlay 網路插件)
  • 第三方網路插件:第三方開源的網路插件眾多,每個組件都有各自的優點及適應的場景,難以形成統一的標準組件,常用有 Flannel、Calico、Cilium、OVN 網路插件
提供商網路模型路由分發網路策略網格外部數據存儲加密Ingress/Egress 策略
Canal封裝(VXLAN)k8s API
Flannel封裝(VXLAN)k8s API
Calico封裝(VXLAN, IPIP)或未封裝Etcd 和 k8s API
Weave封裝
Cilium封裝(VXLAN)Etcd 和 k8s API
  • 網路模型:封裝或未封裝。
  • 路由分發:一種外部網關協議,用於在互聯網上交換路由和可達性信息。BGP 可以幫助進行跨集群 Pod 之間的網路。此功能對於未封裝的 CNI 網路插件是必須的,並且通常由 BGP 完成。如果你想構建跨網段拆分的集群,路由分發是一個很好的功能。
  • 網路策略:Kubernetes 提供了強制執行規則的功能,這些規則決定了哪些 service 可以使用網路策略進行相互通信。這是從 Kubernetes1.7 起穩定的功能,可以與某些網路插件一起使用。
  • 網格:允許在不同的 Kubernetes 集群間進行 service 之間的網路通信。
  • 外部數據存儲:具有此功能的 CNI 網路插件需要一個外部數據存儲來存儲數據。
  • 加密:允許加密和安全的網路控制和數據平面。
  • Ingress/Egress 策略:允許你管理 Kubernetes 和非 Kubernetes 通信的路由控制。

Calico 是一個純三層的虛擬網路,它沒有復用 docker 的 docker0 網橋,而是自己實現的,calico 網路不對數據包進行額外封裝,不需要 NAT 和端口映射

Calico 架構

Felix

  • 管理網路介面編寫路由
  • 編寫 ACL
  • 報告狀態

bird (BGP Client)

BGP Client 將通過 BGP 協議廣播告訴剩餘 calico 節點,從而實現網路互通

confd

通過監聽 etcd 以了解 BGP 配置和全局默認值的更改。Confd 根據 ETCD 數據的更新,動態生成 BGP 配置文件文件更改時 confd 觸發 BGP 重新加載

1

Calico 網路模式 --VXLAN

什麼是 VXLAN?

  • VXLAN,即 Virtual Extensible LAN (虛擬可擴展局域網),是 Linux 本身支持的一種網路虛擬化技術。VXLAN 可以完全在內核態實現封裝和解封裝工作,從而通過 “隧道” 機制,構建出覆蓋網路 (Overlay Network)

  • 基於三層的” 二層 “通信,層即 vxlan 包封裝在 udp 數據包中,要求 udp 在 k8s 節點間三層可達;二層即 vxlan 封包的源 mac 地址和目的 mac 地址是自己的 vxlan 設備 mac 和對端 vxlan 設備 mac 實現通信。

2

數據包封包:封包,在 vxlan 設備上將 pod 發來的數據包源、目的 mac 替換為本機 vxlan 網卡和對端節點 vxlan 網卡的 mac。外層 udp 目的 ip 地址根據路由和對端 vxlan 的 mac fdb 表獲取

優勢:只要 k8s 節點間三層互通,可以跨網段,對主機網關路由沒有特殊要求。各個 node 節點通過 vxlan 設備實現基於三層的” 二層” 互通,三層即 vxlan 包封裝在 udp 數據包中,要求 udp 在 k8s 節點間三層可達;二層即 vxlan 封包的源 mac 地址和目的 mac 地址是自己的 vxlan 設備 mac 和對端 vxlan 設備 mac

缺點:需要進行 vxlan 的數據包封包和解包會存在一定的性能損耗

Calico 配置開啟 VXLAN

#Enable IPIP
-name:CALICO_IPV4POOL_IPIP
-value:"Never"
#Enable or Disable VXLAN on the default IP pool.
-name:CALICO_IPV4POOL_VXLAN
-value:"Always"
#Enable or Disable VXLAN on the default IPv6 IP pool.
-name:CALICO_IPV6POOL_VXLAN
-value:"Always"

#calico_backend:"bird"
calico_backend:"vxlan"

#注釋存活探測和就緒探測
#--bird-live
#--bird-ready

Calico 網路模式 --IPIP

Linux 原生內核支持

IPIP 隧道的工作原理是將源主機的 IP 數據包封裝在一個新的 IP 數據包中,新的 IP 數據包的目的地址是隧道的另一端。在隧道的另一端,接收方將解封裝原始 IP 數據包,並將其傳遞到目標主機。IPIP 隧道可以在不同的網路之間建立連接,例如在 IPV4 網路和 IPV6 網路之間建立連接。

數據包封包:封包,在 tunl0 設備上將 pod 發來的數據包的 mac 層去掉,留下 ip 層封包。
外層數據包目的 ip 地址根據路由得到。
優點:只要 k8s 節點間三層互通,可以跨網段,對主機網關路由沒有特殊要求。
缺點:需要進行 IPIP 的數據包封包和解包會存在一定的性能損耗

Calico 配置開啟 IPIP

#Enable IPIP
-name:CALICO_IPV4POOL_IPIP
-value:"Always"
#Enable or Disable VXLAN on the default IP pool.
-name:CALICO_IPV4POOL_VXLAN
-value:"Never"
#Enable or Disable VXLAN on the default IPv6 IP pool.
-name:CALICO_IPV6POOL_VXLAN
-value:"Never"

Calico 網路模式 --BGP

邊界網關協議 (Border Gateway Protocol,.BGP) 是互聯網上一個核心的去中心化自治路由協議。它通過維護 IP 路由表或‘前綴 ' 表來實現自治系統 (AS) 之間的可達性,屬於量路由協議。BGP 不使用傳統的內部網關協議 (IGP) 的指標,而使用基於路徑、網路策略或規則集來決定路由。因此,它更適合被稱為矢量性協議,而不是路由協議。BGP,通俗的講就是講接入到機房的多條線路(如電信、聯通,移動等)融合為一體,實現多線單 IP,BGP 機房的優點:伺服器只需要設置一個 IP 地址,最佳訪問路由是由網路上的骨幹路由器根據路由跳數與其它技術指標來確定的,不會佔用伺服器的任何系統。

數據包封包:不需要進行數據包封包

優點:不用封包解包,通過 BGP 協議可實現 pod 網路在主機間的三層可達

缺點:跨網段時,配置較為複雜網路要求較高,主機網關路由也需要充當 BGP Speaker。

Calico 配置開啟 BGP

#Enable IPIP
-name:CALICO_IPV4POOL_IPIP
-value:"Off"
#Enable or Disable VXLAN on the default IP pool.
-name:CALICO_IPV4POOL_VXLAN
-value:"Never"
#Enable or Disable VXLAN on the default IPv6 IP pool.
-name:CALICO_IPV6POOL_VXLAN
-value:"Never"

Service#

在 Kubernetes 集群中,每個 Node 運行一個kube-proxy進程。kube-proxy負責為 Service 實現了一種 VIP (虛擬 IP) 的形式。

在 Kubernetes v1.0 版本,代理完全在 userspace。在 Kubernetes v1.1 版本,新增了 iptables 代理,但並不是默認的運行模式。從 Kubernetes v1.2 起,默認就是 iptables 代理。在 Kubernetes v1.8.0-beta.0 中,添加了 ipvs 代理。

userspace

kube-proxy:

  • 監聽 APISERVER 將 Service 的變化修改本地的 iptables 規則
  • 代理當前節點的 pod 用戶請求

3

Iptables

kube-proxy:

  • 監聽 APISERVER 將 Service 的變化修改本地的 iptables 規則

相對於 userspace 方式,kube-proxy 功能解耦壓力更小

4

ipvs

kube-proxy:

  • 監聽 APISERVER 將 Service 的變化修改本地的 ipvs 規則

5

Secret#

Kubernetes 通過僅僅將 Secret 分發到需要訪問 Secret 的 Pod 所在的機器節點來保障其安全性。Secret 只會存儲在節點的內存中,永不寫入物理存儲,這樣從節點刪除 secret 時就不需要擦除磁碟數據。

從 Kubernetes1.7 版本開始,etcd 會以加密形式存儲 Secret,這在一定程度上保證了 Secret 安全性。

Secret 類型

6

Downward API#

Downward API 是 Kubernetes 中的一個功能,它允許容器在運行時從 Kubernetes API 伺服器獲取有關它們自身的信息。這些信息可以作為容器內部的環境變量或文件注入到容器中,以便容器可以獲取有關其運行環境的各種信息,如 Pod 名稱、命名空間、標籤等

  • 提供容器元數據
  • 動態配置
  • 與 Kubernetes 環境集成

HELM#

Helm 是官方提供的類似於 YUM 的包管理器,是部署環境的流程封裝。Helm 有兩個重要的概念:chart 和 release

  • Chart:是創建一個應用的信息集合,包括各種 Kubernetes 對象的配置模板、參數定義、依賴關係、文檔說明等。chart 是應用部署的自包含邏輯單元。可以將 chart 想像成 apt、yum 中的軟體安裝包
  • Release:是 chart 的運行實例,代表了一個正在運行的應用。當 chart 被安裝到 Kubernetes 集群,就生成一個 release。chart 能夠多次安裝到同一集群,每次安裝都是一個 release。
  • Helm cli:helm 客戶端組件,負責和 kubernetes apiserver 通信
  • Repository:用於發布和存儲 Chart 的倉庫

下載安裝#

下載 Helm

wget https://get.helm.sh/helm-v3.18.4-linux-amd64.tar.gz
tar -zxvf helm-v3.18.4-linux-amd64.tar.gz
cp -a linux-amd64/helm /usr/local/bin/
chmod a+x /usr/local/bin/helm
helm version

添加 chart 倉庫國內源

helm repo add bitnami https://helm-charts.itboon.top/bitnami --force-update
helm repo update
#搜索倉庫內容
helm search repo bitnami

安裝 chart 示例#

#查看apache包配置
helm show values bitnami/apache
#安裝apache
helm install bitnami/apache --generate-name
#查看
helm list -n default
kubectl get svc
kubectl get pod

#查看chart基本信息
helm show chart bitnami/apache
#查看chart所有信息
helm show all bitnami/apache

#刪除版本
helm uninstall apache-1753181984
#保留歷史版本
helm uninstall apache-1753181984 --keep-history

#查看該版本的信息
helm status apache-1753182488

擴展

#在當前倉庫中搜索wordpress的chart包
helm search repo wordpress
#在官方倉庫中搜索wordpress的chart包
helm search hub wordpress

#安裝apache並指定名稱為apache-1753234488
helm install apache-1753234488 bitnami/apache 

安裝自定義 chart

#查看apache包配置
helm show values bitnami/apache

#創建yaml文件,添加要修改的參數
vi apache.yml
service:
  type: NodePort

#覆蓋配置參數,並安裝apache
helm install -f apache.yml bitnami/apache --generate-name

除了使用 yaml 文件覆蓋外,還可以使用--set:通過命令行的方式對指定項進行覆蓋。如果同時使用兩種方式,則--set中的值會被合併到--values中,但是--set中的值優先級更高,在--set中覆蓋的內容會被保存在 ConfigMap 中。可以通過helm get values <release-name>來查看指定 release 中--set設置的值。也可以通過運行helm upgrade並指定--reset-values字段來清除--set中設置的值。

--set的格式和限制

--set選項使用 0 或多個 name/value 對。最簡單的用法類似於:--set name=value, 等價於如下 YAML 格式:

name:value

多個值使用逗號分割,因此--set a=b,c=d的 YAML 表示是:

a: b
c: d

支持更複雜的表達式。例如,--set outer.inner=value被轉換成了:

outer:
  inner: value

列表使用花括號 ({}) 來表示,例如,--set name={a,b,c}被轉換成了:

name:
  -a
  -b
  -c

某些 name/key 可以設置為 null 或者空數組,例如--set name=[],a=null

name: []
a: null

升級和回滾#

helm upgrade執行最小侵入式升級,只更新上次發布以來發生更改的內容。

#helm upgrade -f yaml文件 版本名 chart包
helm upgrade -f apache.yml apache-1753183272 bitnami/apache

版本回滾

#查看存在的版本
#helm history 版本名
helm history apache-1753183272
#執行回滾
#helm rollback 版本名 版本號
helm rollback apache-1753183272 1

創建自定義 chart 包#

#創建chart包
helm create test
#刪除不需要的文件
#在templates中創建yaml資源清單
vi nodePort.yaml
############################
apiVersion: v1
kind: Service
metadata:
  name: myapp-test-202401110926-svc
  labels:
    app: myapp-test
spec:
  type: NodePort
  selector:
    app: myapp-test
  ports:
    - name: "80-80"
      protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 31111
############################
vi deplyment.yaml
############################
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-test-202401110926-deploy
  labels:
    app: myapp-test
spec:
  replicas: 5
  selector:
    matchLabels:
      app: myapp-test
  template:
    metadata:
      labels:
        app: myapp-test
    spec:
      containers:
        - name: myapp
          image: wangyanglinux/myapp:v1.0
############################
#發布部署
helm install test test/

完整示例

vi templates/NOTES.txt
############################
1. 這是一個測試的 myapp chart
2. myapp release 名字:myapp-test-{{ now | date "20060102030405" }}-deploy
3. service 名字:myapp-test-{{ now | date "20060102030405" }}-svc
############################
vi templates/deplyment.yaml
############################
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-test-{{ now | date "20060102030405" }}-deploy
  labels:
    app: myapp-test
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: myapp-test
  template:
    metadata:
      labels:
        app: myapp-test
    spec:
      containers:
        - name: myapp
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"

############################
vi templates/service.yaml
############################
apiVersion: v1
kind: Service
metadata:
  name: myapp-test-{{ now | date "20060102030405" }}-svc
  labels:
    app: myapp-test
spec:
  type: {{ .Values.service.type | quote }}
  selector:
    app: myapp-test
  ports:
    - name: "80-80"
      protocol: TCP
      port: 80
      targetPort: 80
      {{- if eq .Values.service.type "NodePort" }}
      nodePort: {{ .Values.service.nodePort }}
      {{- end }}
############################
#與templates目錄同一級
vi values.yaml
############################
replicaCount: 5
image:
  repository: wangyanglinux/myapp
  tag: "v1.0"  

service:
  type: NodePort
  nodePort: 32321  
############################

二進制高可用 Kubernetes 集群部署#

前言#

通過 5 台伺服器使用二進制方式部署採用三主兩從的高可用 Kubernetes 集群。

集群架構#

(1)基礎環境

操作系統:Rocky Linux release 10.0

軟體:Kubernetes-1.33.4、docker-28.3.3

(2)環境準備

主機名IP集群及組件角色
k8s-master01192.168.0.111master,api-server,control manager,scheduler,etcd,
kubelet,kube-proxy,nginx
k8s-master02192.168.0.112master,api-server,control manager,scheduler,etcd,
kubelet,kube-proxy,nginx
k8s-master03192.168.0.113master,api-server,control manager,scheduler,etcd,
kubelet,kube-proxy,nginx
k8s-node01192.168.0.114worker,kubelet,kube-proxy,nginx
k8s-node02192.168.0.115worker,kubelet,kube-proxy,nginx

環境初始化#

(1)更換系統軟體源,下載依賴軟體

sed -e 's|^mirrorlist=|#mirrorlist=|g' \
    -e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g' \
    -i.bak \
    /etc/yum.repos.d/[Rr]ocky*.repo

dnf makecache
#下載依賴軟體
yum install -y wget openssl gcc gcc-c++ zlib-devel openssl-devel make redhat-rpm-config

(2)重命名 hostname

hostnamectl set-hostname k8s-master01 && bash
hostnamectl set-hostname k8s-master02 && bash
hostnamectl set-hostname k8s-node01 && bash
hostnamectl set-hostname k8s-node02 && bash
hostnamectl set-hostname k8s-node03 && bash

(3)系統環境修改

#關閉firewalld防火牆
systemctl stop firewalld
systemctl disable firewalld
firewall-cmd --state

#安裝iptables
yum install -y iptables-services
systemctl start iptables
iptables -F
systemctl enable iptables

# selinux永久關閉
setenforce 0
 sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config
cat /etc/selinux/config

# swap永久關閉
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab
cat /etc/fstab

# 設置時區
timedatectl set-timezone Asia/Shanghai
date

# 添加hosts
cat >> /etc/hosts << EOF
192.168.0.111 k8s-master01
192.168.0.112 k8s-master02
192.168.0.113 k8s-master03
192.168.0.114 k8s-node01
192.168.0.115 k8s-node02
EOF
#查看
cat /etc/hosts

(4)安裝 ipvs

# 安裝ipvs
yum -y install ipvsadm sysstat conntrack libseccomp

# 開啟路由轉發
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
sysctl -p

#ipvs加載模組
cat >> /etc/modules-load.d/ipvs.conf <<EOF
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
ip_tables
ip_set
xt_set
ipt_set
ipt_rpfilter
ipt_REJECT
ipip
EOF

systemctl restart systemd-modules-load.service

lsmod | grep -e ip_vs -e nf_conntrack

(5)排除 calico 網卡被 NetworkManager 所管理

# 排除 calico 網卡被 NetworkManager 所管理
cat > /etc/NetworkManager/conf.d/calico.conf << EOF 
[keyfile]
unmanaged-devices=interface-name:cali*;interface-name:tunl*
EOF

systemctl restart NetworkManager

(6)配置時間同步伺服器

#修改k8s-master01上的chrony配置文件
sed -i -e 's/2\.rocky\.pool\.ntp\.org/ntp.aliyun.com/g' -e 's/#allow 192\.168\.0\.0\/16/allow 192.168.0.0\/24/g' -e 's/#local stratum 10/local stratum 10/g' /etc/chrony.conf

#修改k8s-master02上的chrony配置文件
sed -i -e 's/2\.rocky\.pool\.ntp\.org/ntp.aliyun.com/g' -e 's/#allow 192\.168\.0\.0\/16/allow 192.168.0.0\/24/g' -e 's/#local stratum 10/local stratum 11/g' /etc/chrony.conf

#修改k8s-master03上的chrony配置文件
sed -i -e 's/2\.rocky\.pool\.ntp\.org/ntp.aliyun.com/g' -e 's/#allow 192\.168\.0\.0\/16/allow 192.168.0.0\/24/g' -e 's/#local stratum 10/local stratum 12/g' /etc/chrony.conf

#修改k8s-node01、k8s-node02、k8s-node03上的chrony配置文件
sed -i 's/^pool 2\.rocky\.pool\.ntp\.org iburst$/pool 192.168.0.111 iburst\
pool 192.168.0.112 iburst\
pool 192.168.0.113 iburst/g' /etc/chrony.conf

#重啟chronyd
systemctl restart chronyd

#驗證
chronyc sources -v

(7)設置進程可打開的最大文件數

# 配置 ulimit
ulimit -SHn 65535

cat >> /etc/security/limits.conf << EOF
* soft nofile 655360
* hard nofile 131072
* soft nproc 655350
* hard nproc 655350
* soft memlock unlimited
* hard memlock unlimitedd
EOF

(8)修改內核參數

cat <<EOF > /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
fs.may_detach_mounts = 1
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.netfilter.nf_conntrack_max=2310720
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl =15
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 327680
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.ip_conntrack_max = 65536
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_timestamps = 0
net.core.somaxconn = 16384
net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0
net.ipv6.conf.lo.disable_ipv6 = 0
net.ipv6.conf.all.forwarding = 1
EOF

sysctl --system

安裝 docker#

(1)使用腳本安裝 docker

bash <(curl -sSL https://linuxmirrors.cn/docker.sh)

(2)Docker 配置修改

cat >/etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "registry-mirrors": [
   "http://hub-mirror.c.163.com",
   "https://hub.rat.dev",
   "https://docker.mirrors.ustc.edu.cn",
   "https://docker.1panel.live",
   "https://docker.m.daocloud.io",
   "https://docker.1ms.run"
  ],
  "max-concurrent-downloads": 10,
  "log-driver": "json-file",
  "log-level": "warn",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
    },
  "data-root": "/data/dockerData"
}
EOF

systemctl daemon-reload
systemctl restart docker

安裝 cri-dockerd#

(1)下載安裝 cri-dockerd

wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.18/cri-dockerd-0.3.18.amd64.tgz

tar xvf cri-dockerd-*.amd64.tgz 
cp -r cri-dockerd/*  /usr/bin/
chmod +x /usr/bin/cri-dockerd

(2)添加 cri-docker 服務配置文件

cat >  /usr/lib/systemd/system/cri-docker.service <<EOF
[Unit]
Description=CRI Interface for Docker Application Container Engine
Documentation=https://docs.mirantis.com
After=network-online.target firewalld.service docker.service
Wants=network-online.target
Requires=cri-docker.socket

[Service]
Type=notify
ExecStart=/usr/bin/cri-dockerd --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.10
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
StartLimitBurst=3
StartLimitInterval=60s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
Delegate=yes
KillMode=process

[Install]
WantedBy=multi-user.target
EOF

(3)添加 cri-docker 的 socket 配置文件

cat > /usr/lib/systemd/system/cri-docker.socket <<EOF
[Unit]
Description=CRI Docker Socket for the API
PartOf=cri-docker.service

[Socket]
ListenStream=%t/cri-dockerd.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker

[Install]
WantedBy=sockets.target
EOF

(4)啟動 cri-dockerd,使得配置生效

systemctl daemon-reload
systemctl enable --now cri-docker.service
systemctl status cri-docker.service

安裝 etcd 集群(master 節點)#

(1)下載 etcd 包並安裝

wget https://github.com/etcd-io/etcd/releases/download/v3.6.4/etcd-v3.6.4-linux-amd64.tar.gz

tar -xf etcd-*.tar.gz
mv etcd-*/etcd /usr/local/bin/ && mv etcd-*/etcdctl /usr/local/bin/
ls /usr/local/bin/
etcdctl version

安裝 Kubernetes 集群#

(1)下載 Kubernetes 二進制包並安裝

wget https://dl.k8s.io/v1.33.2/kubernetes-server-linux-amd64.tar.gz

#在master節點執行
tar -xf kubernetes-server-linux-amd64.tar.gz  --strip-components=3 -C /usr/local/bin kubernetes/server/bin/kube{let,ctl,-apiserver,-controller-manager,-scheduler,-proxy}
#在node節點執行
tar -xf kubernetes-server-linux-amd64.tar.gz  --strip-components=3 -C /usr/local/bin kubernetes/server/bin/kube{let,-proxy}

ls /usr/local/bin/
kubelet --version
# 所有節點執行,存放cni插件
mkdir -p /opt/cni/bin

生成相關證書(master 節點)#

安裝 cfssl 證書管理工具#

wget https://hub.gitmirror.com/https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssl-certinfo_1.6.5_linux_amd64 -O /usr/local/bin/cfssl-certinfo
wget https://hub.gitmirror.com/https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssljson_1.6.5_linux_amd64 -O /usr/local/bin/cfssljson
wget https://hub.gitmirror.com/https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssl_1.6.5_linux_amd64 -O /usr/local/bin/cfssl -O /usr/local/bin/cfssl

#添加可執行權限,查看版本
chmod +x /usr/local/bin/cfssl*
cfssl version

生成 ETCD 證書#

mkdir -p /etc/etcd/ssl && cd /etc/etcd/ssl

#創建生成證書的配置文件
cat > ca-config.json << EOF 
{
  "signing": {
    "default": {
      "expiry": "876000h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "876000h"
      }
    }
  }
}
EOF

#創建證書簽發請求文件
cat > etcd-ca-csr.json  << EOF 
{
  "CN": "etcd",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "etcd",
      "OU": "Etcd Security"
    }
  ],
  "ca": {
    "expiry": "876000h"
  }
}
EOF

簽發 ETCD 的 CA 證書和密鑰

cfssl gencert -initca etcd-ca-csr.json | cfssljson -bare /etc/etcd/ssl/etcd-ca

創建用於生成 ETCD 的服務端證書的配置文件

cat > etcd-csr.json << EOF 
{
  "CN": "etcd",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "etcd",
      "OU": "Etcd Security"
    }
  ]
}
EOF

簽發 ETCD 的服務端證書

cfssl gencert    -ca=/etc/etcd/ssl/etcd-ca.pem    -ca-key=/etc/etcd/ssl/etcd-ca-key.pem    -config=ca-config.json -hostname=127.0.0.1,k8s-master01,k8s-master02,k8s-master03,192.168.0.111,192.168.0.112,192.168.0.113  -profile=kubernetes    etcd-csr.json | cfssljson -bare /etc/etcd/ssl/etcd

生成 Kubernetes 證書#

mkdir -p /etc/kubernetes/pki && cd /etc/kubernetes/pki
#創建證書簽發請求文件
cat > ca-csr.json   << EOF 
{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "Kubernetes",
      "OU": "Kubernetes-manual"
    }
  ],
  "ca": {
    "expiry": "876000h"
  }
}
EOF

簽發 Kubernetes 的 CA 證書和密鑰

cfssl gencert -initca ca-csr.json | cfssljson -bare /etc/kubernetes/pki/ca

生成 ApiServer 證書#

#創建證書簽發請求文件
cat > apiserver-csr.json << EOF 
{
  "CN": "kube-apiserver",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "Kubernetes",
      "OU": "Kubernetes-manual"
    }
  ]
}
EOF

#創建生成證書的配置文件
cat > ca-config.json << EOF 
{
  "signing": {
    "default": {
      "expiry": "876000h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "876000h"
      }
    }
  }
}
EOF

簽發 ApiServer 的 CA 證書和密鑰

cfssl gencert   -ca=/etc/kubernetes/pki/ca.pem -ca-key=/etc/kubernetes/pki/ca-key.pem  -config=ca-config.json -hostname=10.96.0.1,127.0.0.1,kubernetes,kubernetes.default,kubernetes.default.svc,kubernetes.default.svc.cluster,kubernetes.default.svc.cluster.local,192.168.0.111,192.168.0.112,192.168.0.113,192.168.0.114,192.168.0.115,192.168.0.116,192.168.0.117,192.168.0.118,192.168.0.119,192.168.0.120  -profile=kubernetes   apiserver-csr.json | cfssljson -bare /etc/kubernetes/pki/apiserver

10.96.0.1 是 Kubernetes 的 service 的默認地址

kubernetes,kubernetes.default,kubernetes.default.svc,kubernetes.default.svc.cluster,kubernetes.default.svc.cluster.local 是 Kubernetes 的默認解析域名

生成 ApiServer 聚合證書#

#創建證書簽發請求文件
cat > front-proxy-ca-csr.json  << EOF 
{
  "CN": "kubernetes",
  "key": {
     "algo": "rsa",
     "size": 2048
  },
  "ca": {
    "expiry": "876000h"
  }
}
EOF

簽發 ApiServer 聚合證書和密鑰

cfssl gencert   -initca front-proxy-ca-csr.json | cfssljson -bare /etc/kubernetes/pki/front-proxy-ca 

生成 ApiServer 聚合證書的客戶端證書#

#創建證書簽發請求文件
cat > front-proxy-client-csr.json  << EOF 
{
  "CN": "front-proxy-client",
  "key": {
     "algo": "rsa",
     "size": 2048
  }
}
EOF

簽發 ApiServer 聚合證書的客戶端證書和密鑰

cfssl gencert  \
-ca=/etc/kubernetes/pki/front-proxy-ca.pem   \
-ca-key=/etc/kubernetes/pki/front-proxy-ca-key.pem   \
-config=ca-config.json   \
-profile=kubernetes   front-proxy-client-csr.json | cfssljson -bare /etc/kubernetes/pki/front-proxy-client

生成 controller-manager 證書#

#創建證書簽發請求文件
cat > manager-csr.json << EOF 
{
  "CN": "system:kube-controller-manager",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "system:kube-controller-manager",
      "OU": "Kubernetes-manual"
    }
  ]
}
EOF

簽發 controller-manager 證書和密鑰

cfssl gencert \
   -ca=/etc/kubernetes/pki/ca.pem \
   -ca-key=/etc/kubernetes/pki/ca-key.pem \
   -config=ca-config.json \
   -profile=kubernetes \
   manager-csr.json | cfssljson -bare /etc/kubernetes/pki/controller-manager

生成 controller-manager 專用的 kubeconfig 配置文件

kubectl config set-cluster kubernetes \
     --certificate-authority=/etc/kubernetes/pki/ca.pem \
     --embed-certs=true \
     --server=https://127.0.0.1:8443 \
     --kubeconfig=/etc/kubernetes/controller-manager.kubeconfig

kubectl config set-context system:kube-controller-manager@kubernetes \
    --cluster=kubernetes \
    --user=system:kube-controller-manager \
    --kubeconfig=/etc/kubernetes/controller-manager.kubeconfig

kubectl config set-credentials system:kube-controller-manager \
    --client-certificate=/etc/kubernetes/pki/controller-manager.pem \
    --client-key=/etc/kubernetes/pki/controller-manager-key.pem \
    --embed-certs=true \
    --kubeconfig=/etc/kubernetes/controller-manager.kubeconfig

kubectl config use-context system:kube-controller-manager@kubernetes \
     --kubeconfig=/etc/kubernetes/controller-manager.kubeconfig

生成 kube-scheduler 證書#

#創建證書簽發請求文件
cat > scheduler-csr.json << EOF 
{
  "CN": "system:kube-scheduler",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "system:kube-scheduler",
      "OU": "Kubernetes-manual"
    }
  ]
}
EOF

簽發 kube-scheduler 證書和密鑰

cfssl gencert \
   -ca=/etc/kubernetes/pki/ca.pem \
   -ca-key=/etc/kubernetes/pki/ca-key.pem \
   -config=ca-config.json \
   -profile=kubernetes \
   scheduler-csr.json | cfssljson -bare /etc/kubernetes/pki/scheduler

生成 kube-scheduler 專用的 kubeconfig 配置文件

kubectl config set-cluster kubernetes \
     --certificate-authority=/etc/kubernetes/pki/ca.pem \
     --embed-certs=true \
     --server=https://127.0.0.1:8443 \
     --kubeconfig=/etc/kubernetes/scheduler.kubeconfig

kubectl config set-credentials system:kube-scheduler \
     --client-certificate=/etc/kubernetes/pki/scheduler.pem \
     --client-key=/etc/kubernetes/pki/scheduler-key.pem \
     --embed-certs=true \
     --kubeconfig=/etc/kubernetes/scheduler.kubeconfig

kubectl config set-context system:kube-scheduler@kubernetes \
     --cluster=kubernetes \
     --user=system:kube-scheduler \
     --kubeconfig=/etc/kubernetes/scheduler.kubeconfig

kubectl config use-context system:kube-scheduler@kubernetes \
     --kubeconfig=/etc/kubernetes/scheduler.kubeconfig

生成 admin 證書#

#創建證書簽發請求文件
cat > admin-csr.json << EOF 
{
  "CN": "admin",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "system:masters",
      "OU": "Kubernetes-manual"
    }
  ]
}
EOF

簽發 admin 證書和密鑰

cfssl gencert \
   -ca=/etc/kubernetes/pki/ca.pem \
   -ca-key=/etc/kubernetes/pki/ca-key.pem \
   -config=ca-config.json \
   -profile=kubernetes \
   admin-csr.json | cfssljson -bare /etc/kubernetes/pki/admin

生成 admin 專用的 kubeconfig 配置文件

kubectl config set-cluster kubernetes     \
  --certificate-authority=/etc/kubernetes/pki/ca.pem     \
  --embed-certs=true     \
  --server=https://127.0.0.1:8443     \
  --kubeconfig=/etc/kubernetes/admin.kubeconfig

kubectl config set-credentials kubernetes-admin  \
  --client-certificate=/etc/kubernetes/pki/admin.pem     \
  --client-key=/etc/kubernetes/pki/admin-key.pem     \
  --embed-certs=true     \
  --kubeconfig=/etc/kubernetes/admin.kubeconfig

kubectl config set-context kubernetes-admin@kubernetes    \
  --cluster=kubernetes     \
  --user=kubernetes-admin     \
  --kubeconfig=/etc/kubernetes/admin.kubeconfig

kubectl config use-context kubernetes-admin@kubernetes  --kubeconfig=/etc/kubernetes/admin.kubeconfig

生成 kube-proxy 證書#

#創建證書簽發請求文件
cat > kube-proxy-csr.json  << EOF 
{
  "CN": "system:kube-proxy",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "system:kube-proxy",
      "OU": "Kubernetes-manual"
    }
  ]
}
EOF

簽發 kube-proxy 證書和密鑰

cfssl gencert \
   -ca=/etc/kubernetes/pki/ca.pem \
   -ca-key=/etc/kubernetes/pki/ca-key.pem \
   -config=ca-config.json \
   -profile=kubernetes \
   kube-proxy-csr.json | cfssljson -bare /etc/kubernetes/pki/kube-proxy

生成 kube-proxy 專用的 kubeconfig 配置文件

kubectl config set-cluster kubernetes     \
  --certificate-authority=/etc/kubernetes/pki/ca.pem     \
  --embed-certs=true     \
  --server=https://127.0.0.1:8443     \
  --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig

kubectl config set-credentials kube-proxy  \
  --client-certificate=/etc/kubernetes/pki/kube-proxy.pem     \
  --client-key=/etc/kubernetes/pki/kube-proxy-key.pem     \
  --embed-certs=true     \
  --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig

kubectl config set-context kube-proxy@kubernetes    \
  --cluster=kubernetes     \
  --user=kube-proxy     \
  --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig

kubectl config use-context kube-proxy@kubernetes  --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig

創建 ServiceAccount 加密密鑰#

openssl genrsa -out /etc/kubernetes/pki/sa.key 2048
openssl rsa -in /etc/kubernetes/pki/sa.key -pubout -out /etc/kubernetes/pki/sa.pub

添加組件配置,啟動服務#

ETCD 組件(master 節點)#

(1)k8s-master01 配置文件

cat > /etc/etcd/etcd.config.yml << EOF 
name: 'k8s-master01'
data-dir: /var/lib/etcd
wal-dir: /var/lib/etcd/wal
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 0
listen-peer-urls: 'https://192.168.0.111:2380'
listen-client-urls: 'https://192.168.0.111:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
cors:
initial-advertise-peer-urls: 'https://192.168.0.111:2380'
advertise-client-urls: 'https://192.168.0.111:2379'
discovery:
discovery-fallback: 'proxy'
discovery-proxy:
discovery-srv:
initial-cluster: 'k8s-master01=https://192.168.0.111:2380,k8s-master02=https://192.168.0.112:2380,k8s-master03=https://192.168.0.113:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-v2: true
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-transport-security:
  cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  client-cert-auth: true
  trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem'
  auto-tls: true
peer-transport-security:
  cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  peer-client-cert-auth: true
  trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem'
  auto-tls: true
debug: false
log-package-levels:
log-outputs: [default]
force-new-cluster: false
EOF

(2)k8s-master02 配置文件

cat > /etc/etcd/etcd.config.yml << EOF 
name: 'k8s-master02'
data-dir: /var/lib/etcd
wal-dir: /var/lib/etcd/wal
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 0
listen-peer-urls: 'https://192.168.0.112:2380'
listen-client-urls: 'https://192.168.0.112:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
cors:
initial-advertise-peer-urls: 'https://192.168.0.112:2380'
advertise-client-urls: 'https://192.168.0.112:2379'
discovery:
discovery-fallback: 'proxy'
discovery-proxy:
discovery-srv:
initial-cluster: 'k8s-master01=https://192.168.0.111:2380,k8s-master02=https://192.168.0.112:2380,k8s-master03=https://192.168.0.113:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-v2: true
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-transport-security:
  cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  client-cert-auth: true
  trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem'
  auto-tls: true
peer-transport-security:
  cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  peer-client-cert-auth: true
  trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem'
  auto-tls: true
debug: false
log-package-levels:
log-outputs: [default]
force-new-cluster: false
EOF

(3)k8s-master03 配置文件

cat > /etc/etcd/etcd.config.yml << EOF 
name: 'k8s-master03'
data-dir: /var/lib/etcd
wal-dir: /var/lib/etcd/wal
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 0
listen-peer-urls: 'https://192.168.0.113:2380'
listen-client-urls: 'https://192.168.0.113:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
cors:
initial-advertise-peer-urls: 'https://192.168.0.113:2380'
advertise-client-urls: 'https://192.168.0.113:2379'
discovery:
discovery-fallback: 'proxy'
discovery-proxy:
discovery-srv:
initial-cluster: 'k8s-master01=https://192.168.0.111:2380,k8s-master02=https://192.168.0.112:2380,k8s-master03=https://192.168.0.113:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-v2: true
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-transport-security:
  cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  client-cert-auth: true
  trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem'
  auto-tls: true
peer-transport-security:
  cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  peer-client-cert-auth: true
  trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem'
  auto-tls: true
debug: false
log-package-levels:
log-outputs: [default]
force-new-cluster: false
EOF

(4)創建 etcd 服務啟動配置文件

cat > /usr/lib/systemd/system/etcd.service << EOF

[Unit]
Description=Etcd Service
Documentation=https://coreos.com/etcd/docs/latest/
After=network.target

[Service]
Type=notify
ExecStart=/usr/local/bin/etcd --config-file=/etc/etcd/etcd.config.yml
Restart=on-failure
RestartSec=10
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
Alias=etcd3.service

EOF

(5)啟動 etcd 服務

mkdir -p /etc/kubernetes/pki/etcd
ln -s /etc/etcd/ssl/* /etc/kubernetes/pki/etcd/

systemctl daemon-reload
systemctl enable --now etcd.service
systemctl status etcd.service

(6)etcd 集群的健康狀態

export ETCDCTL_API=3
etcdctl --endpoints="192.168.0.111:2379,192.168.0.112:2379,192.168.0.113:2379" --cacert=/etc/kubernetes/pki/etcd/etcd-ca.pem --cert=/etc/kubernetes/pki/etcd/etcd.pem --key=/etc/kubernetes/pki/etcd/etcd-key.pem  endpoint status --write-out=table

+--------------------+------------------+---------+-----------------+---------+--------+-----------------------+-------+-----------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+
| ENDPOINT | ID | VERSION | STORAGE VERSION | DB SIZE | IN USE | PERCENTAGE NOT IN USE | QUOTA | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS | DOWNGRADE TARGET VERSION | DOWNGRADE ENABLED |
+--------------------+------------------+---------+-----------------+---------+--------+-----------------------+-------+-----------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+
| 192.168.0.111:2379 | 9c35553b47538310 | 3.6.4 | 3.6.0 | 20 kB | 16 kB | 20% | 0 B | true | false | 3 | 6 | 6 | | | false |
| 192.168.0.112:2379 | 545bae002651f913 | 3.6.4 | 3.6.0 | 20 kB | 16 kB | 20% | 0 B | false | false | 2 | 7 | 7 | | | false |
| 192.168.0.113:2379 | d7497b3a31d15f9e | 3.6.4 | 3.6.0 | 20 kB | 16 kB | 20% | 0 B | false | false | 2 | 7 | 7 | | | false |
+--------------------+------------------+---------+-----------------+---------+--------+-----------------------+-------+-----------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+

#將etcd相關防火牆策略保存,防止重啟後etcd服務無法啟動
service iptables save

如果出現重啟伺服器後,etcd 集群服務無法啟動的情況。清空防火牆規則,啟動 etcd 服務並保存策略即可。

安裝 Nginx 配置高可用#

(1)下載安裝 Nginx

wget https://nginx.org/download/nginx-1.28.0.tar.gz
tar xvf nginx-1.28.0.tar.gz
cd nginx-1.28.0
#編譯安裝,其中--with-stream為啟用四層代理
./configure --with-stream --without-http --without-http_uwsgi_module --without-http_scgi_module --without-http_fastcgi_module
make && make install 

(2)創建配置文件

cat > /usr/local/nginx/conf/kube-nginx.conf <<EOF
worker_processes 1;
events {
    worker_connections  1024;
}
stream {
    upstream backend {
    	least_conn;
        hash $remote_addr consistent;
        server 192.168.0.111:6443        max_fails=3 fail_timeout=30s;
        server 192.168.0.112:6443        max_fails=3 fail_timeout=30s;
        server 192.168.0.113:6443        max_fails=3 fail_timeout=30s;
    }
    server {
        listen 127.0.0.1:8443;
        proxy_connect_timeout 1s;
        proxy_pass backend;
    }
}
EOF

(6)添加 nignx 服務

cat > /etc/systemd/system/kube-nginx.service <<EOF
[Unit]
Description=kube-apiserver nginx proxy
After=network.target
After=network-online.target
Wants=network-online.target

[Service]
Type=forking
ExecStartPre=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/kube-nginx.conf -p /usr/local/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/kube-nginx.conf -p /usr/local/nginx
ExecReload=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/kube-nginx.conf -p /usr/local/nginx -s reload
PrivateTmp=true
Restart=always
RestartSec=5
StartLimitInterval=0
LimitNOFILE=65536
 
[Install]
WantedBy=multi-user.target
EOF

(7)啟動服務

systemctl daemon-reload
systemctl enable --now kube-nginx.service
systemctl status kube-nginx.service

ApiServer 組件#

#所有節點創建所需目錄
mkdir -p /etc/kubernetes/manifests/ /etc/systemd/system/kubelet.service.d /var/lib/kubelet /var/log/kubernetes

(1)k8s-master01 節點添加 apiserver 服務

cat > /usr/lib/systemd/system/kube-apiserver.service << EOF

[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/usr/local/bin/kube-apiserver \\
      --v=2  \\
      --allow-privileged=true  \\
      --bind-address=0.0.0.0  \\
      --secure-port=6443  \\
      --advertise-address=192.168.0.111 \\
      --service-cluster-ip-range=10.96.0.0/12,fd00:1111::/112  \\
      --service-node-port-range=30000-32767  \\
      --etcd-servers=https://192.168.0.111:2379,https://192.168.0.112:2379,https://192.168.0.113:2379 \\
      --etcd-cafile=/etc/etcd/ssl/etcd-ca.pem  \\
      --etcd-certfile=/etc/etcd/ssl/etcd.pem  \\
      --etcd-keyfile=/etc/etcd/ssl/etcd-key.pem  \\
      --client-ca-file=/etc/kubernetes/pki/ca.pem  \\
      --tls-cert-file=/etc/kubernetes/pki/apiserver.pem  \\
      --tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem  \\
      --kubelet-client-certificate=/etc/kubernetes/pki/apiserver.pem  \\
      --kubelet-client-key=/etc/kubernetes/pki/apiserver-key.pem  \\
      --service-account-key-file=/etc/kubernetes/pki/sa.pub  \\
      --service-account-signing-key-file=/etc/kubernetes/pki/sa.key  \\
      --service-account-issuer=https://kubernetes.default.svc.cluster.local \\
      --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname  \\
      --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota  \\
      --authorization-mode=Node,RBAC  \\
      --enable-bootstrap-token-auth=true  \\
      --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem  \\
      --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.pem  \\
      --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client-key.pem  \\
      --requestheader-allowed-names=aggregator  \\
      --requestheader-group-headers=X-Remote-Group  \\
      --requestheader-extra-headers-prefix=X-Remote-Extra-  \\
      --requestheader-username-headers=X-Remote-User \\
      --enable-aggregator-routing=true

Restart=on-failure
RestartSec=10s
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target

EOF

(2)k8s-master02 節點添加 apiserver 服務

cat > /usr/lib/systemd/system/kube-apiserver.service << EOF

[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/usr/local/bin/kube-apiserver \\
      --v=2  \\
      --allow-privileged=true  \\
      --bind-address=0.0.0.0  \\
      --secure-port=6443  \\
      --advertise-address=192.168.0.112 \\
      --service-cluster-ip-range=10.96.0.0/12,fd00:1111::/112  \\
      --service-node-port-range=30000-32767  \\
      --etcd-servers=https://192.168.0.111:2379,https://192.168.0.112:2379,https://192.168.0.113:2379 \\
      --etcd-cafile=/etc/etcd/ssl/etcd-ca.pem  \\
      --etcd-certfile=/etc/etcd/ssl/etcd.pem  \\
      --etcd-keyfile=/etc/etcd/ssl/etcd-key.pem  \\
      --client-ca-file=/etc/kubernetes/pki/ca.pem  \\
      --tls-cert-file=/etc/kubernetes/pki/apiserver.pem  \\
      --tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem  \\
      --kubelet-client-certificate=/etc/kubernetes/pki/apiserver.pem  \\
      --kubelet-client-key=/etc/kubernetes/pki/apiserver-key.pem  \\
      --service-account-key-file=/etc/kubernetes/pki/sa.pub  \\
      --service-account-signing-key-file=/etc/kubernetes/pki/sa.key  \\
      --service-account-issuer=https://kubernetes.default.svc.cluster.local \\
      --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname  \\
      --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota  \\
      --authorization-mode=Node,RBAC  \\
      --enable-bootstrap-token-auth=true  \\
      --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem  \\
      --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.pem  \\
      --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client-key.pem  \\
      --requestheader-allowed-names=aggregator  \\
      --requestheader-group-headers=X-Remote-Group  \\
      --requestheader-extra-headers-prefix=X-Remote-Extra-  \\
      --requestheader-username-headers=X-Remote-User \\
      --enable-aggregator-routing=true


Restart=on-failure
RestartSec=10s
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target

EOF

(3)k8s-master03 節點添加 apiserver 服務

cat > /usr/lib/systemd/system/kube-apiserver.service << EOF

[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/usr/local/bin/kube-apiserver \\
      --v=2  \\
      --allow-privileged=true  \\
      --bind-address=0.0.0.0  \\
      --secure-port=6443  \\
      --advertise-address=192.168.0.113 \\
      --service-cluster-ip-range=10.96.0
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。