目錄
一、環境準備
二 、etcd叢集
三、部署
準備工作
master節點部署
部署 docker 引擎
flannel網絡配置
在 master01 節點上操作
在所有 node 節點上操作
部署master元件
部署 Woker Node 元件
node02 節點部署
k8s叢集master1:192.168.0.12 kube-apiserver kube-controller-manager kube-scheduler etcd
k8s叢集node1: 192.168.0.14 kubelet kube-proxy docker flannel
k8s叢集node2: 192.168.0.15 kubelet kube-proxy docker flannel
etcd作為服務發現系統,有以下的特點:
• 簡單 安裝配置簡單,而且提供了HTTP API進行互動,使用也很簡單
• 安全: 支援SSL證書驗證
• 快速: 單執行個體支援每秒2k+讀操作
• 可靠: 采用raft算法實作分布式系統資料的可用性和一緻性
準備簽發證書環境
CFSSL是CloudFlare 公司開源的一款PKI/TLS工具。CESSL 包含一個指令行工具和一個用于簽名、驗證和捆綁TLS證書的HTTP API服務。使用Go語言編寫。
CFSSL使用配置檔案生成證書,是以自簽之前,需要生成它識别的json 格式的配置檔案,CFSSL 提供了友善的指令行生成配置檔案。
CFSSL用來為etcd提供TLS證書,它支援簽三種類型的證書:
1、client證書,服務端連接配接用戶端時攜帶的證書,用于用戶端驗證服務端身份,如kube-apiserver 通路etcd;
2、server證書,用戶端連接配接服務端時攜帶的證書,用于服務端驗證用戶端身份,如etcd對外提供服務:
3、peer證書,互相之間連接配接時使用的證書,如etcd節點之間進行驗證和通信。
這裡全部都使用同一套證書認證。
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
關閉selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config
關閉swap
swapoff -a
sed -ri 's/.swap./#&/' /etc/fstab
根據規劃設定主機名
hostnamectl set-hostname master01
hostnamectl set-hostname node01
hostnamectl set-hostname node02
在master添加hosts
cat >> /etc/hosts << EOF
192.168.0.12 master01
192.168.0.14 node01
192.168.0.15 node02
EOF
将橋接的IPv4流量傳遞到iptables的鍊
cat > /etc/syscl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables =1
sysctl --system
時間同步
yum install ntpdate -y
ntpdate time.windows.com
下載下傳證書制作工具
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -O /usr/local/bin/cfssl
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -O /usr/local/bin/cfssljson
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -O /usr/local/bin/cfssl-certinfo
或
curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o /usr/local/bin/cfssl
curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o /usr/local/bin/cfssljson
curl -L https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -o /usr/local/bin/cfssl-certinfo
chmod +x /usr/local/bin/cfssl*
cfssl: 證書簽發的工具指令
cfssljson: 将cfssl 生成的證書( json格式)變為檔案承載式證書
cfssl-certinfo:驗證證書的資訊
cfssl-certinfo -cert <證書名稱>
檢視證書的資訊
//建立k8s.工作目錄
mkdir /opt/k8s
cd /opt/k8s/
//上傳etcd-cert.sh 和etcd.sh 到/opt/k8s/ 目錄中
chmod +x etcd-cert.sh etcd. sh
修改etcd-cert.sh
建立用于生成CA憑證、etcd伺服器證書以及私鑰的目錄
mkdir /opt/k8s/etcd-cert
mv etcd-cert.sh etcd-cert/
cd /opt/k8s/etcd-cert/
./etcd-cert.sh
生成CA憑證、etcd伺服器證書以及私鑰
etcd二進制包位址: https://github.com/etcd-io/etcd/releases
上傳etcd-v3.3.10-1inux-amd64.tar.gz 到/opt/k8s/ 目錄中,解壓etcd 壓縮包
tar zxvf etcd-v3.3.10-linux-amd64.tar.gz
1s etcd-v3.3.10-linux-amd64
Documentation etcd etcdctl README-etcdctl.md README.md
READMEv2-etcdctl.md
etcd就是etcd服務的啟動指令,後面可跟各種啟動參數
etcdct1主要為etcd服務提供了指令行操作
建立用于存放etcd配置檔案,指令檔案,證書的目錄
mkdir -P /opt/etcd/{cfg,bin,ssl}
mv /opt/k8s/etcd-v3.3.10-linux- amd64/etcd /opt/k8s/etcd-v3.3.10-1inux-amd64/etcdct1 /opt/etcd/bin/
cp /opt/k8s/etcd-cert/*.pem /opt/etcd/ssl/
./etcd.sh etcd01 192.168.80.10 etcd02=https://192.168.80.11:2380,etcd03=https://192.168.80.12:2380
進入卡住狀态等待其他節點加入,這裡需要三台etcd服務同時啟動,如果隻啟動其中一台後,服務會卡在那裡,直到叢集中所有etcd節點都已啟動,可忽略這個情況
另外打開一個視窗檢視etcd程序是否正常
ps -ef | grep etcd
//把etcd相關證書檔案和指令檔案全部拷貝到另外兩個etcd叢集節點
scp -r /opt/etcd/ [email protected]:/opt/
scp -r /opt/etcd/ [email protected]:/opt/
//把etcd服務管理檔案拷貝到另外兩個etcd叢集節點
scp /usr/lib/systemd/system/etcd.service [email protected]:/usr/lib/systemd/system/
scp /usr/lib/systemd/system/etcd.service [email protected]:/usr/lib/systemd/system/
//在node2節點修改
//在node3節點修改
master01 節點上操作
ln -s /opt/etcd/bin/etcd* /usr/local/bin
//檢查etcd群集狀态
cd /opt/etcd/ssl
/opt/etcd/bin/etcdctl
--ca-file=ca.pem
--cert-file=server.pem
--key-file=server-key.pem
--endpoints="https://192.168.0.12:2379,https://192.168.0.14:2379,https://192.168.0.15:2379"
cluster-health
--cert-file:識别HTTPS端使用sSL證書檔案
--key-file: 使用此SSL密鑰檔案辨別HTTPS用戶端
-ca-file:使用此CA憑證驗證啟用https的伺服器的證書
--endpoints:叢集中以逗号分隔的機器位址清單
cluster-health:檢查etcd叢集的運作狀況
切換到etcd3版本檢視叢集節點狀态和成員清單
export ETCDCTL_API=3
v2和v3指令略有不同,etcd2 和etcd3也是不相容的,預設是v2版本
etcdctl --write-out=table endpoint status
etcdctl --write-out=table member list
export ETCDCTL_API=2
再切回v2版本
所有node節點部署docker引擎
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install -y docker-ce dqsker-ce-cli containerd.io
systenctl start docker.service
systemct1 enable docker.service
K8S中Pod網絡通信:
●Pod内容器與容器之間的通信
在同一個Pod内的容器(Pod内的容器是不會跨主控端的)共享同一個網絡指令空間,相當于它們在網一台機器上一樣,可以用localhost位址訪間彼此的端口
●同一個Node内Pod之間的通信
每個Pod 都有一個真實的全局IP位址,同一個Node 内的不同Pod之間可以直接采用對方Pod的IP 位址進行通信,Pod1 與Pod2都是通過veth連接配接到同一個docker0 網橋,網段相同,是以它們之間可以直接通信
●不同Node上Pod之間的通信
Pod位址與docker0 在同一網段,dockor0 網段與主控端網卡是兩個不同的網段,且不同Nodo之間的通信貝能通過主控端的實體網卡進行
要想實作不同Node 上Pod之間的通信,就必須想辦法通過主機的實體網卡IP位址進行尋址和通信。是以要滿足兩個條件: Pod 的IP不能沖突;将Pod的IP和所在的Node的IP關聯起來,通過這個關聯讓不同Node上Pod之間直接通過内網IP位址通信。
Overlay Network:
疊加網絡,在二層或者三層基礎網絡上疊加的一種虛拟網絡技術模式,該網絡中的主機通過虛拟鍊路隧道連接配接起來(類似于VPN)
VXLAN:
将源資料包封裝到UDP中,并使用基礎網絡的IP/MAC作為外層封包頭進行封裝,然後在以太網上傳輸,到達目的地後由隧道端點解封裝并将資料發送給目标位址
Flannel:
Flannel的功能是讓叢集中的不同節點主機建立的Docker容器都具有全叢集唯一的虛拟IP位址
Flannel是Overlay 網絡的一種,也是将TCP 源資料包封裝在另一種網絡 包裡而進行路由轉發和通信,目前己經支援UDP、VXLAN、host-GW 3種資料轉發方式
Flannel 工作原理:
資料從 node1 上的 Pod 源容器中發出後,經由所在主機的 docker0 虛拟網卡轉發到flannel.1 虛拟網卡;flanneld服務監聽在 flannel.1虛拟網卡的另外一端。
Flannel 通過 Etcd 服務維護了一張節點間的路由表。源主機 node01 的flanneld 服務将原本的資料内容封裝到 UDP 中後根據自己的路由表通過實體網卡投遞給目的節點 node02 的 flanneld 服務,資料到達以後被解包,然後直接進入目的節點的 flannel.1 虛拟網卡,之後被轉發到目的主機的 docker0 虛拟網卡,最後就像本機容器通信一樣由 docker0 轉發到目标容器。
ETCD之Flannel 提供說明:
存儲管理Flanne1可配置設定的IP位址段資源
監控 ETCD 中每個 Pod 的實際位址,并在記憶體中建立維護 Pod 節點路由表
添加 flannel 網路配置資訊,寫入配置設定的子網段到 etcd 中,供 flannel 使用
set /coreos.com/network/config '{"Network": "172.17.0.0/16","Backend": {"Type": "vxlan"}}'
//檢視寫入的資訊
--endpoints="https://192.168.0.12:2379,https://192.168.0.14:2379,https://192.168.0.16:2379"
get /coreos.com/network/config
字段解析
set
set /coreos.com/network/config 添加一條網絡配置記錄,這個配置将用于flannel配置設定給每個docker的虛拟IP位址段以及flannel使用轉發方式
get
get /coreos.com/network/config 擷取網絡配置記錄,後面不用再跟參數了
Network∶用于指定Flannel位址池
Backend∶用于指定資料包以什麼方式轉發,預設為udp模式,Backend為vxlan比起預設的udp性能相對好一些
上傳 flannel.sh 和 flannel-v0.10.0-linux-amd64.tar.gz 到/opt 目錄中,解壓 flannel 壓縮包
cd /opt
tar zxvf flannel-v0.10.0-linux-amd64.tar.gz
flanneld #flanneld為主要的執行檔案
mk-docker-opts.sh #mk-docker-opts.sh腳本用于生成Docker啟動網絡環境參數
README.md
建立kubernetes工作目錄
mkdir -p /opt/kubernetes/{cfg,bin,ssl}
mv mk-docker-opts.sh flanneld /opt/kubernetes/bin/ #将主要執行檔案和docker啟動參數移動到工作目錄中
啟動flanneld服務,開啟flannel網絡功能
chmod +x flannel.sh
./flannel.sh https://192.168.0.12:2379,https://192.168.0.14:2379,https://192.168.0.15:2379
flannel啟動後會生成一個docker網絡相關資訊配置檔案/run/flannel/subnet.env,包含了docker要使用flannel通訊的相關參數,子網段,空間等
cat /run/flannel/subnet.env
DOCKER_OPT_BIP="--bip=172.17.27.1/24"
DOCKER_OPT_IPMASQ="--ip-masq=false"
DOCKER_OPT_MTU="--mtu=1450"
DOCKER_NETWORK_OPTIONS=" --bip=172.17.27.1/24 --ip-masq=false --mtu=1450"
--bip∶指定 docker 啟動時的子網
--ip-masq∶ 設定 ipmasg=false 關閉 snat 僞裝政策
--mtu=1450∶mtu 要留出50位元組給外層的vxlan封包的額外開銷使用
進入docker啟動項中添加flannel定義的相關網路參數,并将flannel添加到啟動變量中
vim /usr/lib/systemd/system/docker.service
EnvironmentFile=/run/flannel/subnet.env
ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONS -H fd:// --containerd=/run/containerd/containerd.sock
systemctl daemon-reload 重載後重新開機服務
systemctl restart docker.service
ifconfig 重新開機後docker網段與自定義的flannel網段一緻
上傳master.zip 和k8s-cert.sh 到/opt/k8s 目錄中,解壓master.zip 壓縮包
unzip master.zip
apiserver.sh
scheduler.sh
controller-manager.sh
chmod +x * .sh
mkdir -P /opt/kubernetes/{cfg,bin,ss1}
建立用于生成CA憑證、相關元件的證書和私鑰的目錄
mkdir /opt/k8s/k8s-cert
mv /opt/k8s/k8s-cert.sh /opt/k8s/k8s-cert
cd /opt/k8s/k8s-cert/
vim k8s-cert.sh 修改IP位址
./k8s-cert.sh 生成CA憑證、相關元件的證書和私鑰
controller-manager 和 kube-scheduler 設定為隻調用目前機器的 apiserver, 使用127.0.0.1:8080 通信,是以不需要簽發證書
複制CA憑證、apiserver 相關證書和私鑰到kubernetes. 工作目錄的ssl子目錄中
cp capem apiserverpem /opt/kubernetes/ssl/
上傳kubernetes-server-linux-amd64.tar.gz 到/opt/k8s/ 目錄中,解壓kubernetes 壓縮包
tar zxvf kubernetes-server-linux-amd64.tar.gz
複制master元件的關鍵指令檔案到kubernetes. 工作目錄的bin子目錄中
cd /opt/k8s/kubernetes/server/bin
cp kube-apiserver kubectl kube-controller-manager kube-scheduler /opt/kubernetes/bin/
ln -s /opt/kubernetes/bin/* /usr/local/bin/
建立bootstrap token 認證檔案,apiserver 啟動時會調用,然後就相當于在叢集内建立了一個這個使用者,接下來就可以用RBAC給他授權
vim token.sh
!/bin/bash
擷取随機數前16個位元組内容,以十六進制格式輸出,并删除其中空格
BOOTSTRAP_TOKEN=$(head -c 16 /dev/urandom | od -An -t x | tr -d ' ')
生成token.csv 檔案,按照Token序列号,使用者名,UID,使用者組的格式生成
cat > /opt/kubernetes/cfg/token.csv <<EOF
${BOOTSTRAP_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
chmod +x token.sh
./token.sh
cat /opt/kubernetes/cfg/token.csv
二進制檔案、token、證書都準備好後,開啟 apiserver 服務
./apiserver.sh 192.168.0.12 https://192.168.0.12:2379,https://192.168.0.14:2379,https://192.168.0.15:2379
檢查程序是否啟動成功
ps aux | grep kube-apiserver
k8s通過kube- apiserver這 個程序提供服務,該程序運作在單個master節點上。預設有兩個端口6443和8080
安全端口6443用于接收HTTPS請求,用于基于Token檔案或用戶端證書等認證
netstat -natp | grep 6443
本地端口8080用于接收HTTP請求,非認證或授權的HTTP請求通過該端口通路APIServer
netstat -natp | grep 8080
檢視版本資訊(必須保證apiserver啟動正常,不然無法查詢到server的版本資訊)
kubectl version
啟動scheduler 服務
./scheduler.sh 127.0.0.1
ps aux | grep kube-scheduler
啟動controller-manager服務
./controller-manager.sh 127.0.0.1
檢視節點狀态
kubectl get componentstatuses #也可以 kubectl get cs
NAME STATUS MESSAGE ERROR
controller-manager
scheduler
etcd-2
etcd-1
etcd-0
把kubelet、 kube-proxy拷貝到node 節點
scp kubelet kube-proxy [email protected]:/opt/kubernetes/bin/
scp kubelet kube-proxy [email protected]:/opt/kubernetes/bin/
在 node01 節點上操作
上傳node.zip 到/opt 目錄中,解壓node.zip 壓縮包,獲得kubelet.sh、proxy.sh
cd /opt/
unzip node.zip
在master1節點上操作
建立用于生成kubelet的配置檔案的目錄
mkdir /opt/k8s/kubeconfig
上傳 kubeconfig.sh 檔案到/opt/k8s/kubeconfig 目錄中
kubeconfig.sh檔案包含叢集參數(CA 證書、API Server 位址),用戶端參數(上面生成的證書和私鑰),叢集context上下文參數(叢集名稱、使用者名)。Kubenetes 元件(如kubelet、 kube-proxy) 通過啟動時指定不同的kubeconfig檔案可以切換到不同的叢集,連接配接到apiserver
cd /opt/k8s/kubeconfig
chmod +x kubeconfig.sh
生成kubelet的配置檔案
./kubeconfig.sh 192.168.80.10 /opt/k8s/k8s-cert/
把配置檔案bootstrap.kubeconfig、kube-proxy.kubeconfig拷貝到node節點
scp bootstrap.kubeconfig kube-proxy.kubeconfig [email protected]:/opt/kubernetes/cfg/
scp bootstrap.kubeconfig kube-proxy.kubeconfig [email protected]:/opt/kubernetes/cfg/
RBAC授權,将預設使用者kubelet-bootatrap 與内置的ClusterRole system:node-bootatrapper 綁定到一起,使其能夠發起CSR請求
kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap
kubectl get clusterroles 檢視角色
kubelet采用TLS Bootstrapping 機制,自 動完成到kube -apiserver的注冊,在node節點量較大或者後期自動擴容時非常有用。
Master apiserver 啟用TLS 認證後,node 節點kubelet 元件想要加入叢集,必須使用CA簽發的有效證書才能與apiserver 通信,當node節點很多時,簽署證書是一件很繁瑣的事情。是以Kubernetes 引入了TLS bootstraping 機制來自動頒發用戶端證書,kubelet會以一個低權限使用者自動向apiserver 申請證書,kubelet 的證書由apiserver 動态簽署。
kubelet首次啟動通過加載bootstrap.kubeconfig中的使用者Token 和apiserver CA憑證發起首次CSR請求,這個Token被預先内置在apiserver 節點的token.csv 中,其身份為kubelet-bootstrap 使用者和system: kubelet- bootstrap使用者組:想要首次CSR請求能成功(即不會被apiserver 401拒絕),則需要先建立一個ClusterRoleBinding, 将kubelet-bootstrap 使用者和system:node - bootstrapper内置ClusterRole 綁定(通過kubectl get clusterroles 可查詢),使其能夠發起CSR認證請求。
TLS bootstrapping 時的證書實際是由kube-controller-manager元件來簽署的,也就是說證書有效期是kube-controller-manager元件控制的; kube-controller-manager 元件提供了一個--experimental-cluster-signing-duration參數來設定簽署的證書有效時間:預設為8760h0m0s, 将其改為87600h0m0s, 即10年後再進行TLS bootstrapping 簽署證書即可。
也就是說kubelet 首次通路API Server 時,是使用token 做認證,通過後,Controller Manager 會為kubelet生成一個證書,以後的通路都是用證書做認證了。
檢視角色:
kubectl get clusterroles | grep system:node-bootstrapper
檢視已授權的角色:
kubectl get clusterrolebinding
使用kubelet.sh腳本啟動kubelet服務
chmod +x kubelet.sh
./kubelet.sh 192.168.0.14
檢查kubelet服務啟動
ps aux | grep kubelet
此時還沒有生成證書
ls /opt/kubernetes/ssl/
檢查到node1 節點的kubelet 發起的CSR請求,Pending 表示等待叢集給該節點簽發證書.
kubectl get csr
通過CSR請求
kubectl certificate approve node-csr-NOI-9vufTLIqJgMWq4fHPNPHKbjCX1DGHptj7FqTa8A
檢視群集節點狀态,成功加入node1節點
kubectl get nodes
ls /opt/kubernetes/cfg/kubelet.kubeconfig
加載ip_vs子產品(預設使用iptables)
for i in $(ls /usr/lib/modules/$(uname -r)/kernel/net/netfilter/ipvs|grep -o "[.]*");do echo $i; /sbin/modinfo -F filename $i >/dev/null 2>&1 && /sbin/modprobe $i;done
使用proxy.sh腳本啟動proxy服務
chmod +x proxy.sh
./proxy.sh 192.168.0.14
systemctl status kube-proxy.service
在node1 節點上将kubelet.sh、 proxy.sh 檔案拷貝到node2 節點
scp kubelet.sh proxy.sh [email protected]:/opt/
./kubelet.sh 192.168.0.15
NAME
再次檢視CSR請求狀态,Approved, Issued表示已授權CSR請求并簽發證書
檢視群集節點狀态
NAME STATUS ROLES AGE VERSION
加載ip_vs子產品
./proxy.sh 192.168.0.15
kubectl create deployment nginx-test --image=nginx:1.14