目錄
3.2、在Kubernetes中,service對象的4個特徵
5.2、設置master可以無密碼登錄所有節點的root賬戶
5.3、將可執行文件路徑/opt/k8s/bin添加到PATH變量中
5.14、設置rsyslog和systemd journal
5.17、檢查系統內核和模塊是否適合運行docker(僅適用於linux系統)
5.18、分發集羣環境變量定義腳本(擴容時不需要執行該步驟)
1.4、爲各節點創建和分發etcd systemd unit文件
2.5、分發flanneld systemd unit文件到所有節點
3.2.2.1 K8S集羣架構搭建及運行docker容器
1、Linux 操作系統原理
參考地址:https://product.pconline.com.cn/itbk/software/dnyw/1707/9626394.html
一個計算機系統是硬件、軟件的共生體,它們互相依賴、不可分割。
1.1、計算機硬件
是由外圍設備、處理器、內存、硬盤和其他電子設備組成的計算機發動機
1.2、操作系統
是控制硬件工作的,是用來和硬件打交道,爲用戶程序提供一個有限服務集的低級支撐軟件。
1.3、Linux操作系統
在Linux中操作系統被稱爲“內核”,也稱爲“核心”。
Linux內核的主要模塊(組件)分爲以下7部分:
存儲管理
CPU和進程管理
文件系統
設備管理和驅動
網絡通信
系統的初始化(引導)
系統調用
Linux內核被設計爲“單內核”(monolithic)結構
1.4、Linux系統的操作原理
1、一切都是文件
2、每個軟件都有確定的用途
2、K8S 集羣架構圖
1、etcd:一個高可用的K/V鍵值對存儲和服務發現系統
2、flannel:實現跨主機的容器網絡的通信
3、kube-apiserver:提供kubernetes集羣的API調用
4、kube-controller-manager:確保集羣服務
5、kube-scheduler:調度容器,分配到Node
6、kubelet:在Node節點上按照配置文件中定義的容器規格 啓動容器
7、kube-proxy:提供網絡代理服務
3、K8S 集羣部署架構
1個master + 2個node。存儲集羣etcd是單點集羣(真實環境不推薦此做法,需要集羣)。網絡使用的是flannel虛擬二次網絡。
3.1、Kubernetes的8個集羣管理能力
1、多層次的安全防護和准入機制
2、多租戶應用支撐能力
3、透明的服務註冊和服務發現機制
4、內建智能負載均衡器
5、強大的故障發現和自我修復能力
6、服務滾動升級和在線擴容能力
7、可擴展的資源自動調度機制
8、以及多粒度的資源管理能力
3.2、在Kubernetes中,service對象的4個特徵
1、擁有一個唯一指定的名字
eg:mysql-service
2、擁有一個虛擬IP和端口號
虛擬IP:Cluster IP、service IP、VIP
3、能夠提供某種遠程服務能力
4、被映射到提供這種服務能力的一組容器應用上
快速、在線體驗kubernetes的功能:https://kubernetes.io/docs/tutorials/kubernetes-basics/
K8s官方下載地址:https://github.com/kubernetes
本文以下所有操作命令都參考老師的文檔:E:\meWork\study\project\subject-3\subject-3-k8s\專題三-Kubernetes_學習文檔-N.docx
4、集羣環境配置說明
4.1、環境準備
節點 |
ip 地址 |
操作系統 |
master |
|
CentOS 7.8-x86_64 |
node1 |
|
CentOS 7.8-x86_64 |
node2 |
|
CentOS 7.8-x86_64 |
4.2、集羣詳情、組件版本
OS:CentOS Linux release 7.8.2003 (Core)
Kubernetes:1.12.3(最低的版本要求是1.6)
Docker:18.09.0-ce(建議使用 Docker CE)
Etcd:3.3.10
Flannel:v0.10.0 (vxlan或者host-gw 網絡)
TLS 認證通信 (所有組件,如 etcd、kubernetes master 和 node)
RBAC 授權
kubelet TLS BootStrapping
插件:Coredns、dashboard、heapster(influxdb、grafana)、Metrics-Server、EFK(elasticsearch、fluentd、kibana)
鏡像倉庫:docker registry、harbor
私有docker鏡像倉庫harbor(harbor提供離線安裝包,直接使用docker-compose啓動即可)
私有docker鏡像倉庫harbor的參官文檔:
安裝文檔:https://github.com/goharbor/harbor/blob/master/docs/install-config/installation-prereqs.md
配置 https訪問:https://github.com/goharbor/harbor/blob/master/docs/install-config/configure-https.md
4.3、環境說明
Master:192.168.0.32
Node:192.168.0.33、192.168.0.34
注意:192.168.0.32 這臺主機 master 和 node 複用。所有生成證書、執行 kubectl 命令的操作都在這臺節點上執行。一旦 node 加入到 kubernetes 集羣之後就不需要再登陸node節點了。
4.4、主要配置策略
kube-apiserver:
1、使用節點本地nginx4層透明代理實現高可用
2、關閉非安全端口8080和匿名訪問
3、在安全端口6443接收https請求
4、嚴格的認證和授權策略(x509、token、RBAC)
5、開啓bootstrap token認證,支持kubelet TLS bootstrapping
6、使用https訪問kubelet、etcd,加密通信
kube-controller-manager:
1、3節點高可用
2、關閉非安全端口,在安全端口10252接收https請求
3、使用kubeconfig訪問apiserver的安全端口
4、自動approve kubelet證書籤名請求(CSR),證書過期後自動輪轉
5、各controller使用自己的ServiceAccount訪問apiserver
kube-scheduler:
1、3節點高可用
2、使用kubeconfig訪問apiserver的安全端口
kubelet:
1、使用kubeadm動態創建bootstrap token,而不是在apiserver中靜態配置
2、使用TLS bootstrap機制自動生成client和server證書,過期後自動輪轉
3、在KubeletConfiguration類型的JSON文件配置主要參數
4、關閉只讀端口,在安全端口10250接收https請求,對請求進行認證和授權,拒絕匿名訪問和非授權訪問
5、使用kubeconfig訪問apiserver的安全端口
kube-proxy:
1、使用kubeconfig訪問apiserver的安全端口
2、在KubeProxyConfiguration類型的JSON文件配置主要參數
3、使用ipvs代理模式
集羣插件:
DNS:使用功能、性能更好的 coredns
Dashboard:支持登錄認證
Metric:heapster、metrics-server,使用https訪問kubelet安全端口
Log:Elasticsearch、Fluend、Kibana
Registry 鏡像庫:docker-registry、harbor
harbor私有鏡像倉庫:參考:https://github.com/goharbor/harbor
5、集羣環境搭建安裝(系統初始化和全局變量)
“5.3”到“5.17”的命令在master、node1、node2,3臺機器上都需要執行
5.1、設置主機名、添加docker賬戶
設置永久主機名稱,然後xshell重新連接,就可以看到名稱變成新的名稱了
1、將主機名改爲master:hostnamectl set-hostname master
2、爲支持DNS解析主機名稱,修改/etc/hosts文件:
cat >> /etc/hosts <<EOF
192.168.0.32 master master
192.168.0.33 node1 node1
192.168.0.34 node2 node2
EOF
3、添加docker賬戶:useradd -m docker
5.2、設置master可以無密碼登錄所有節點的root賬戶
1、創建一個rsa的密鑰:ssh-keygen -t rsa
2、將公鑰文件放到master的root賬戶下:ssh-copy-id root@master
3、將公鑰文件放到node1的root賬戶下:ssh-copy-id root@node1
4、將公鑰文件放到node2的root賬戶下:ssh-copy-id root@node2
5、遠程連接到node1上去:ssh root@node1
5.3、將可執行文件路徑/opt/k8s/bin添加到PATH變量中
後面會將k8s可執行組件的二進制文件,全部放到/opt/k8s/bin目錄下,以這個目錄作爲標準。
爲了執行命令時不用寫全路徑,需要將這個路添加到PATH變量中
1、添加環境變量:echo 'PATH=/opt/k8s/bin:$PATH' >>/root/.bashrc
2、查看是否添加成功:cat /root/.bashrc
5.4、安裝依賴包
在master、node1、node2都需要執行下面3個命令
1、安裝依賴包1:yum install -y epel-release
2、安裝依賴包2:yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget
3、安裝完畢後,檢查ip_vs是否正常:/usr/sbin/modprobe ip_vs
5.5、關閉防火牆
從“4.4、主要配置策略”可以知道需要用到很多端口,爲了方便(避免每一個端點都在防火牆中配置放行),避免少配置了端口,導致安裝失敗,所以需要關閉防火牆。
1、關閉防火牆:systemctl stop firewalld
2、取消防火牆的自啓動:systemctl disable firewalld
3、清除防火牆的規則策略1:iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat
清除防火牆的規則策略2:iptables -P FORWARD ACCEPT
5.6、關閉swap分區
如果開啓了swap分區,kubelet會啓動失敗。
1、關閉swap分區:swapoff -a
2、註釋/etc/fstab中swap的相應行:sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
5.7、關閉SELinux
SELinux是linux內核的保護,如果開啓SELinux,執行某些受保護的命令就會報錯:Permission denied
1、關閉SELinux的命令1:setenforce 0
2、關閉SELinux的命令2:sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
5.8、關閉dnsmasq(可選)
linux系統開啓了dnsmasq後(eg:GUI環境),將系統DNS Server設置爲 127.0.0.1,這會導致docker容器無法解析域名,需要關閉它:
systemctl stop dnsmasq
systemctl disable dnsmasq
5.9、加載內核模塊(可選)
如果是比較老的版本,就需要執行這個命令,新的版本就不用執行
modprobe ip_vs_rr
modprobe br_netfilter
5.10、優化內核參數
這一步如果執行有一些報錯不用理會,繼續往下執行。(因爲版本不一樣,參數值有可能也不一樣)
1、創建kubernetes.conf命令:
cat > kubernetes.conf <<EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0 # 禁止使用 swap 空間,只有當系統 OOM 時才允許使用它
vm.overcommit_memory=1 # 不檢查物理內存是否夠用
vm.panic_on_oom=0 # 開啓 OOM
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF
2、複製kubernetes.conf到/etc/sysctl.d下:cp kubernetes.conf /etc/sysctl.d/kubernetes.conf
3、是/etc/sysctl.d/kubernetes.conf文件生效:sysctl -p /etc/sysctl.d/kubernetes.conf
5.11、設置系統時區
#1、調整系統TimeZone
timedatectl set-timezone Asia/Shanghai
#2、將當前的UTC時間寫入硬件時鐘
timedatectl set-local-rtc 0
#3、重啓依賴於系統時間的服務
systemctl restart rsyslog
systemctl restart crond
5.12、更新系統時間(可選)
ntpdate cn.pool.ntp.org
5.13、關閉無關的服務
systemctl stop postfix && systemctl disable postfix
5.14、設置rsyslog和systemd journal
systemd的journald 記錄日誌的3個優勢:
1、可以記錄到內存或文件系統(默認記錄到內存,對應的位置爲/run/log/jounal)
2、可以限制佔用的磁盤空間、保證磁盤剩餘空間
3、可以限制日誌文件大小、保存的時間
由於journald默認將日誌轉發給rsyslog,這會導致:
1、日誌寫了多份
2、/var/log/messages中包含了太多無關日誌,不方便後續查看
3、同時也影響系統性能
因爲上面的問題,所以需要修改默認設置:
#1、持久化保存日誌的目錄
mkdir /var/log/journal
mkdir /etc/systemd/journald.conf.d
cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF
[Journal]
#2、持久化保存到磁盤
Storage=persistent
#3、壓縮歷史日誌
Compress=yes
SyncIntervalSec=5m
RateLimitInterval=30s
RateLimitBurst=1000
#4、最大佔用空間10G
SystemMaxUse=10G
#5、單日誌文件最大200M
SystemMaxFileSize=200M
#6、日誌保存時間2周
MaxRetentionSec=2week
#7、不將日誌轉發到syslog
ForwardToSyslog=no
EOF
systemctl restart systemd-journald
5.15、創建相關目錄
mkdir -p /opt/k8s/{bin,work} /opt/k8s/work/cert /etc/{kubernetes,etcd}/cert
5.16、升級內核、關閉 NUMA
系統內核是3.10以下版本需要才需要升級內核、關閉 NUMA
查看系統內核版本:uname -a
5.17、檢查系統內核和模塊是否適合運行docker(僅適用於linux系統)
1、下載check-config.sh文件:curl https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh > check-config.sh
我下載不了,直接用的老師給的check-config.sh文件,上傳到虛擬機中,直接執行bash ./check-config.sh命令,也可以
2、bash ./check-config.sh
5.18、分發集羣環境變量定義腳本(擴容時不需要執行該步驟)
3個節點收執行這個命令,便於直接拖拽文件到xshell,上傳到虛擬機對應目錄。文件拖拽上傳、下載的工具:
yum install -y lrzsz
後續的部署步驟將使用environment.sh文件中定義的全局環境變量;
老師提供的文件在:http://59.111.92.219/q1906-java/subject-3/blob/master/subject-3-k8s/environment.sh
下面的命令只在master節點執行
根據自己的機器情況修改文件內容,然後將文件複製到所有節點的/opt/k8s/bin目錄
export IFACE的就是IP配置文件的DEVICE值(查看網絡接口名稱):vim /etc/sysconfig/network-scripts/ifcfg-enp0s3
變成可執行文件:chmod +x environment.sh
讓環境變量文件生效:source environment.sh
讀取環境變量文件,然後分發到其他節點:
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp /opt/k8s/bin/environment.sh root@${node_ip}:/opt/k8s/bin/
ssh root@${node_ip} "chmod +x /opt/k8s/bin/*"
done
6、HTTPS網絡安全架構設計
6.1、對稱加密
“明文”通過“密鑰”加密成“密文”;拿到“密文”,需要通過“密鑰”解密成“明文”。
常見的對稱加密算法有:DES、3DES、AES、Blowfish、IDEA、RC5、RC6
6.2、非對稱加密
用“公鑰”對“明文”加密,用“私鑰”對“明文”解密。
常見的非對稱加密算法有:RSA、Elagmal、揹包算法、Rabin。
應用場景:SSH、HTTPS、TLS、電子證書、電子簽名、電子身份證......
6.3、數組證書
數字證書就是識別網站(服務器)
6.4、數組證書的4種格式
1、Java Keystore(JKS)格式
這是Java提供的密碼庫,通過Java Development Kit(JDK)工具包中的Keytool工具,生成Java Keystore(JKS)格式的證書文件。
使用這個格式的軟件有:Tomcat、Weblogic、JBoss
2、PEM、KEY、CRT格式
這是OpenSSl工具提供的密碼庫,生成PEM、KEY、CRT等格式的證書文件
使用這個格式的軟件有:Apache、Nginx
3、KDB格式
這是使用IBM產品自帶的iKeyman工具,生成KDB格式的證書文件。
使用這個格式的軟件是IBM的Web服務產品,eg:Websphere、IBM Http Server(IHS)
4、PFX格式
這是使用Windows自帶的證書庫生成PFX格式的證書
使用這個格式的服務有:微軟Windows Server中的Internet Information Services(IIS)服務
只有經過CA簽發後才能得到真正的證書,詳細瞭解數字證書:https://www.jianshu.com/p/42bf7c4d6ab8
6.5、4種數組證書格式相互轉換
6.6、SSL證書
SSL證書是數字證書的一種方式
SSL:Secure Socket Layer安全套接字協議,提供兩個安全服務:鑑別、保密
HTTPS就是HTTP的安全版,HTTP下加入SSL層
HTTPS協議主要作用:
1、建立一個信息安全通道,來保證數據傳輸的安全
2、確認網站的真實性
SSL/TLS:安全套接字協議(SSL)是Web瀏覽器與Web服務器之間安全交換信息的協議。
用於網站HTTPS化的SSL數字證書有3種類型:DV SSL(個人)、OV SSL(組織、企業)、EV SSL(大型企業、金融機構)
SSL證書的優勢:
1、簡單快捷
只需要申請一張證書,部署在服務器上,就可以在有效期內不用做其他操作
2、顯示直觀
部署SSL證書後,通過https訪問網站,能在地址欄或地址欄右側直接看到加密鎖標誌。
3、身份認證
能在證書信息裏看到網站所有者公司信息,進而確認網站的有效性和真實性。
6.7、Nginx集羣環境SSL證書部署
證書部署在Nginx上,在nginx.conf配置文件中加入如下配置:
7、集羣環境搭建安裝(創建 CA 證書和祕鑰)
爲確保安全,kubernetes系統各組件需要使用x509證書對通信進行加密和認證。
CA(Certificate Authority)是自簽名的根證書,用來簽名後續創建的其它證書。
本文檔使用CloudFlare的PKI工具集cfssl創建所有證書
cfssl的github地址:https://github.com/cloudflare/cfssl
7.1、安裝cfssl工具
進入work目錄:cd /opt/k8s/work
變成可執行文件:chmod +x /opt/k8s/bin/*
7.2、創建根證書(CA)
CA證書是集羣所有節點共享的,只需要創建一個CA證書,後續創建的所有證書都由它簽名。
第一步、創建配置文件CA配置文件:用於配置根證書的使用場景(profiles)和具體參數,後續在簽名其它證書時需要指定特定場景。
具體參數有:usage,過期時間、服務端認證、客戶端認證、加密等
signing:表示該證書可用於簽名其它證書,生成的ca.pem證書中CA=TRUE;
server auth:表示client可以用該該證書對server提供的證書進行驗證;
client auth:表示server可以用該該證書對client提供的證書進行驗證;
cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
EOF
第二步、創建證書籤名請求文件
CN:Common Name,kube-apiserver從證書中提取該字段作爲請求的用戶名(User Name),瀏覽器使用該字段驗證網站是否合法;
O:Organization,kube-apiserver從證書中提取該字段作爲請求用戶所屬的組(Group);
kube-apiserver將提取的User、Group作爲RBAC授權的用戶標識;
第三步、生成CA證書、私鑰
7.3、分發證書文件
將生成的CA證書、祕鑰文件、配置文件拷貝到所有節點的/etc/kubernetes/cert目錄下:
source /opt/k8s/bin/environment.sh # 導入 NODE_IPS 環境變量
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "mkdir -p /etc/kubernetes/cert"
scp ca*.pem ca-config.json root@${node_ip}:/etc/kubernetes/cert
done
8、集羣環境搭建安裝(部署kubectl命令行工具)
8.1、下載和分發kubectl命令行工具
將如下文件拖拽上傳到work目錄
8.2、創建admin證書、私鑰
kubectl是kubernetes集羣的命令行管理工具。
kubectl與apiserver https安全端口通信,apiserver對提供的證書進行認證和授權。
kubectl作爲集羣的管理工具,需要被授予最高權限。這裏創建具有最高權限的admin證書。
第一步、創建證書籤名請求
cat > admin-csr.json <<EOF
{
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "system:masters",
"OU": "study163"
}
]
}
EOF
system:masters:kube-apiserver收到該證書後,將請求的Group設置爲system:masters;
預定義的ClusterRoleBinding cluster-admin將Group system:masters與Role cluster-admin綁定,該Role授予所有API的權限;
該證書只會被kubectl當做client證書使用,所以hosts字段爲空;
第二步、生成證書和私鑰
cfssl gencert -ca=/opt/k8s/work/cert/ca.pem \
-ca-key=/opt/k8s/work/cert/ca-key.pem \
-config=/opt/k8s/work/cert/ca-config.json \
-profile=kubernetes admin-csr.json | cfssljson -bare admin
8.3、創建kubeconfig文件
kubeconfig爲kubectl的配置文件,包含訪問apiserver的所有信息,eg:apiserver地址、CA證書、自身使用的證書
命令如下:
source /opt/k8s/bin/environment.sh
# 設置集羣參數
kubectl config set-cluster kubernetes \
--certificate-authority=/opt/k8s/work/cert/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kubectl.kubeconfig
# 設置客戶端認證參數
kubectl config set-credentials admin \
--client-certificate=/opt/k8s/work/cert/admin.pem \
--client-key=/opt/k8s/work/cert/admin-key.pem \
--embed-certs=true \
--kubeconfig=kubectl.kubeconfig
# 設置上下文參數
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=admin \
--kubeconfig=kubectl.kubeconfig
# 設置默認上下文
kubectl config use-context kubernetes --kubeconfig=kubectl.kubeconfig
certificate-authority:驗證kube-apiserver證書的根證書;
client-certificate、--client-key:剛生成的admin證書、私鑰,連接kube-apiserver時使用;
embed-certs=true:將ca.pem和admin.pem證書內容嵌入到生成的kubectl.kubeconfig文件中(不加時,寫入的是證書文件路徑);
8.4、分發kubeconfig文件
分發到所有使用kubectl命令的節點:
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "mkdir -p ~/.kube"
scp kubectl.kubeconfig root@${node_ip}:~/.kube/config
done
3.2.2.2 K8S基於二進制集羣架構搭建1
1、部署etcd集羣
etcd是基於Raft的分佈式key-value存儲系統,常用於:服務發現、共享配置、併發控制(leader選舉、分佈式鎖)。
etcd集羣各節點的名稱和IP如下:
master:192.168.0.32
node1:192.168.0.33
node2:192.168.0.34
1.1、下載和分發etcd二進制文件
前面已經將etcd的包上傳到work目錄,不需要再下載了
分發二進制文件到集羣所有節點:
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp etcd-v3.3.10-linux-amd64/etcd* root@${node_ip}:/opt/k8s/bin
ssh root@${node_ip} "chmod +x /opt/k8s/bin/*"
done
1.2、創建etcd證書和私鑰
第一步、創建證書籤名請求
cd /opt/k8s/work/cert
cat > etcd-csr.json <<EOF
{
"CN": "etcd",
"hosts": [
"127.0.0.1",
"192.168.0.32",
"192.168.0.33",
"192.168.0.34"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "study163"
}
]
}
EOF
hosts:指定授權使用該證書的etcd節點IP或域名列表,這裏將etcd集羣的三個節點IP都列在其中
第二步、生成證書、私鑰
cfssl gencert -ca=/opt/k8s/work/cert/ca.pem \
-ca-key=/opt/k8s/work/cert/ca-key.pem \
-config=/opt/k8s/work/cert/ca-config.json \
-profile=kubernetes etcd-csr.json | cfssljson -bare etcd
第三步、分發生成的證書和私鑰到各etcd節點
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "mkdir -p /etc/etcd/cert"
scp etcd*.pem root@${node_ip}:/etc/etcd/cert/
done
1.3、創建etcd的systemd unit模板文件
cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
cat > etcd.service.template <<EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos
[Service]
Type=notify
WorkingDirectory=${ETCD_DATA_DIR}
ExecStart=/opt/k8s/bin/etcd \\
--data-dir=${ETCD_DATA_DIR} \\
--wal-dir=${ETCD_WAL_DIR} \\
--name=##NODE_NAME## \\
--cert-file=/etc/etcd/cert/etcd.pem \\
--key-file=/etc/etcd/cert/etcd-key.pem \\
--trusted-ca-file=/etc/kubernetes/cert/ca.pem \\
--peer-cert-file=/etc/etcd/cert/etcd.pem \\
--peer-key-file=/etc/etcd/cert/etcd-key.pem \\
--peer-trusted-ca-file=/etc/kubernetes/cert/ca.pem \\
--peer-client-cert-auth \\
--client-cert-auth \\
--listen-peer-urls=https://##NODE_IP##:2380 \\
--initial-advertise-peer-urls=https://##NODE_IP##:2380 \\
--listen-client-urls=https://##NODE_IP##:2379,http://127.0.0.1:2379 \\
--advertise-client-urls=https://##NODE_IP##:2379 \\
--initial-cluster-token=etcd-cluster-0 \\
--initial-cluster=${ETCD_NODES} \\
--initial-cluster-state=new \\
--auto-compaction-mode=periodic \\
--auto-compaction-retention=1 \\
--max-request-bytes=33554432 \\
--quota-backend-bytes=6442450944 \\
--heartbeat-interval=250 \\
--election-timeout=2000
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
WorkingDirectory、--data-dir:指定工作目錄和數據目錄爲${ETCD_DATA_DIR},需在啓動服務前創建這個目錄;
--wal-dir:指定wal目錄,爲了提高性能,一般使用SSD或者和--data-dir不同的磁盤;
--name:指定節點名稱,當--initial-cluster-state值爲new時,--name的參數值必須位於--initial-cluster列表中;
--cert-file、--key-file:etcd server與client通信時使用的證書和私鑰;
--trusted-ca-file:簽名client證書的CA證書,用於驗證client證書;
--peer-cert-file、--peer-key-file:etcd與peer通信使用的證書和私鑰;
--peer-trusted-ca-file:簽名peer證書的CA證書,用於驗證peer證書;
1.4、爲各節點創建和分發etcd systemd unit文件
第一步、替換模板文件中的變量,爲各節點創建systemd unit文件
NODE_NAMES和NODE_IPS爲相同長度的bash數組,分別爲節點名稱和對應的IP
source /opt/k8s/bin/environment.sh
for (( i=0; i < 3; i++ ))
do
sed -e "s/##NODE_NAME##/${NODE_NAMES[i]}/" -e "s/##NODE_IP##/${NODE_IPS[i]}/" etcd.service.template > etcd-${NODE_IPS[i]}.service
done
第二步、分發生成的systemd unit文件
文件重命名爲 etcd.service
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp etcd-${node_ip}.service root@${node_ip}:/usr/lib/systemd/system/etcd.service
done
1.5、啓動etcd服務
1、必須創建etcd數據目錄和工作目錄;
2、etcd進程首次啓動時會等待其它節點的etcd加入集羣,命令systemctl start etcd會卡住一段時間,爲正常現象
第一步、啓動etcd服務
cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "mkdir -p ${ETCD_DATA_DIR} ${ETCD_WAL_DIR}"
ssh root@${node_ip} "systemctl daemon-reload && systemctl enable etcd && systemctl restart etcd " &
done
第二步、檢查啓動結果
新開一個xshell窗口,運行如下命令,如果都是active (running),就說明已經啓動正常了,直接在啓動的窗口回車即可。
cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "systemctl status etcd|grep Active"
done
如果狀態不是爲active(running),就查看日誌,確認原因:journalctl -u etcd
1.6、驗證服務狀態
cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ETCDCTL_API=3 /opt/k8s/bin/etcdctl \
--endpoints=https://${node_ip}:2379 \
--cacert=/opt/k8s/work/cert/ca.pem \
--cert=/etc/etcd/cert/etcd.pem \
--key=/etc/etcd/cert/etcd-key.pem endpoint health
done
1.7、查看當前的leader
source /opt/k8s/bin/environment.sh
ETCDCTL_API=3 /opt/k8s/bin/etcdctl \
-w table --cacert=/opt/k8s/work/cert/ca.pem \
--cert=/etc/etcd/cert/etcd.pem \
--key=/etc/etcd/cert/etcd-key.pem \
--endpoints=${ETCD_ENDPOINTS} endpoint status
2、部署flannel網絡
flannel是二次虛擬技術網絡,在物理網絡、docker網絡進行了一次虛擬化,節點中的docker容器的Pod之間進行相互通信。
2.1、下載和分發flannel二進制文件
前面已經將flannel的包上傳到work目錄,不需要再下載了
1、創建flannel文件夾:mkdir flannel
2、解壓flannel並放入flannel文件夾中:tar -xzvf flannel-v0.10.0-linux-amd64.tar.gz -C flannel
3、分發flannel二進制文件到集羣所有節點
cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp flannel/{flanneld,mk-docker-opts.sh} root@${node_ip}:/opt/k8s/bin/
ssh root@${node_ip} "chmod +x /opt/k8s/bin/*"
done
2.2、創建flannel證書和私鑰
flannel從etcd集羣存取網段分配信息,而etcd集羣啓用了雙向x509證書認證,所以需要爲flanneld生成證書和私鑰。
第一步、創建證書籤名請求
該證書只會被kubectl當做client證書使用,所以hosts字段爲空(不需要做主機驗證)
cd /opt/k8s/work/cert
cat > flanneld-csr.json <<EOF
{
"CN": "flanneld",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "study163"
}
]
}
EOF
第二步、生成證書和私鑰
cfssl gencert -ca=/opt/k8s/work/cert/ca.pem \
-ca-key=/opt/k8s/work/cert/ca-key.pem \
-config=/opt/k8s/work/cert/ca-config.json \
-profile=kubernetes flanneld-csr.json | cfssljson -bare flanneld
ls flannel*pem
第三步、將生成的證書和私鑰分發到所有節點
cd /opt/k8s/work/cert
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "mkdir -p /etc/flanneld/cert"
scp flanneld*.pem root@${node_ip}:/etc/flanneld/cert
done
2.3、向etcd寫入集羣Pod網段信息
注意:本步驟只需執行一次。
1、flannel當前版本(v0.10.0)不支持etcd v3,故使用etcd v2 API寫入配置key和網段數據;
2、寫入的Pod網段${CLUSTER_CIDR}地址段如/16必須小於SubnetLen,必須與kube-controller-manager的--cluster-cidr參數值一致;
cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
etcdctl \
--endpoints=${ETCD_ENDPOINTS} \
--ca-file=/opt/k8s/work/cert/ca.pem \
--cert-file=/opt/k8s/work/cert/flanneld.pem \
--key-file=/opt/k8s/work/cert/flanneld-key.pem \
set ${FLANNEL_ETCD_PREFIX}/config '{"Network":"'${CLUSTER_CIDR}'", "SubnetLen": 21, "Backend": {"Type": "vxlan"}}'
2.4、創建flannel的systemd unit文件
mk-docker-opts.sh:腳本將分配給flanneld的Pod子網網段信息寫入/run/flannel/docker文件,
後續docker啓動時使用這個文件中的環境變量配置docker0網橋;
flanneld:使用系統缺省路由所在的接口與其它節點通信,對於有多個網絡接口(如內網和公網)的節點,
可以用-iface參數指定通信接口;
flanneld:運行時需要root權限;
-ip-masq: flanneld爲訪問Pod網絡外的流量設置SNAT規則,同時將傳遞給Docker的變量--ip-masq(/run/flannel/docker 文件中)
設置爲false,這樣Docker將不再創建SNAT規則;Docker的--ip-masq爲true時,
創建的SNAT規則比較“暴力”:將所有本節點Pod發起的、訪問非docker0接口的請求做SNAT,
這樣訪問其他節點Pod的請求來源IP會被設置爲flannel.1接口的IP,
導致目的Pod看不到真實的來源Pod IP。flanneld創建的SNAT規則比較溫和,
只對訪問非Pod網段的請求做SNAT。
cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
cat > flanneld.service << EOF
[Unit]
Description=Flanneld overlay address etcd agent
After=network.target
After=network-online.target
Wants=network-online.target
After=etcd.service
Before=docker.service
[Service]
Type=notify
ExecStart=/opt/k8s/bin/flanneld \\
-etcd-cafile=/etc/kubernetes/cert/ca.pem \\
-etcd-certfile=/etc/flanneld/cert/flanneld.pem \\
-etcd-keyfile=/etc/flanneld/cert/flanneld-key.pem \\
-etcd-endpoints=${ETCD_ENDPOINTS} \\
-etcd-prefix=${FLANNEL_ETCD_PREFIX} \\
-iface=${IFACE} \\
-ip-masq
ExecStartPost=/opt/k8s/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/docker
Restart=always
RestartSec=5
StartLimitInterval=0
[Install]
WantedBy=multi-user.target
RequiredBy=docker.service
EOF
2.5、分發flanneld systemd unit文件到所有節點
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp flanneld.service root@${node_ip}:/usr/lib/systemd/system/
done
2.6、啓動flanneld服務
1、啓動flanneld服務
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "systemctl daemon-reload && systemctl enable flanneld && systemctl restart flanneld"
done
2、檢查啓動結果
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "systemctl status flanneld|grep Active"
done
如果狀態不是爲active(running),就查看日誌,確認原因:journalctl -u etcd
2.7、檢查分配給各flanneld的Pod網段信息
1、查看集羣Pod網段(/16):
source /opt/k8s/bin/environment.sh
etcdctl \
--endpoints=${ETCD_ENDPOINTS} \
--ca-file=/etc/kubernetes/cert/ca.pem \
--cert-file=/etc/flanneld/cert/flanneld.pem \
--key-file=/etc/flanneld/cert/flanneld-key.pem \
get ${FLANNEL_ETCD_PREFIX}/config
2、查看已分配的Pod子網段列表(/24):
source /opt/k8s/bin/environment.sh
etcdctl \
--endpoints=${ETCD_ENDPOINTS} \
--ca-file=/etc/kubernetes/cert/ca.pem \
--cert-file=/etc/flanneld/cert/flanneld.pem \
--key-file=/etc/flanneld/cert/flanneld-key.pem \
ls ${FLANNEL_ETCD_PREFIX}/subnets
3、查看某一Pod網段對應的節點IP和flannel接口地址:
source /opt/k8s/bin/environment.sh
etcdctl \
--endpoints=${ETCD_ENDPOINTS} \
--ca-file=/etc/kubernetes/cert/ca.pem \
--cert-file=/etc/flanneld/cert/flanneld.pem \
--key-file=/etc/flanneld/cert/flanneld-key.pem \
get ${FLANNEL_ETCD_PREFIX}/subnets/172.30.16.0-21
從輸出結果中可以看出:
1、172.30.16.0/21被分配給節點master(192.168.0.32);
2、VtepMAC爲master節點的flannel.1網卡MAC地址
2.8、驗證各節點能通過Pod網段互通
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh ${node_ip} "/usr/sbin/ip addr show flannel.1|grep -w inet"
done
在各節點上ping所有flannel接口IP,確保能通:
下面的ip是“查看已分配的Pod子網段列表”中的ip
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh ${node_ip} "ping -c 1 172.30.16.0"
ssh ${node_ip} "ping -c 1 172.30.72.0"
ssh ${node_ip} "ping -c 1 172.30.232.0"
done
3.2.2.3 K8S基於二進制集羣架構搭建2
待續