一邮旷、K8S 集群架構方案
Kubernetes 集群組件:
- etcd 一個高可用的 K/V 鍵值對存儲和服務發(fā)現(xiàn)系統(tǒng)
- flannel 實現(xiàn)夸主機的容器網絡的通信
- kube-apiserver 提供 kubernetes 集群的 API 調用
- kube-controller-manager 確保集群服務
- kube-scheduler 調度容器,分配到 Node
- kubelet 在 Node 節(jié)點上按照配置文件中定義的容器規(guī)格啟動容器
- kube-proxy 提供網絡代理服務
1.1 Kubernetes 集群部署方案
??如下是集群部署策略蝇摸,1個 master + 2個 node婶肩。存儲集群 etcd 是單點集群(真實環(huán)境為了避免單點故障,一般是多個節(jié)點的集群)貌夕;網絡使用的是 flannel 虛擬二次網絡律歼。
Kubernetes 具有完備的集群管理能力:
- 包括多層次的安全防護和準入機制
- 多租戶應用支撐能力
- 透明的服務注冊和服務發(fā)現(xiàn)機制
- 內建智能負載均衡器
- 強大的故障發(fā)現(xiàn)和自我修復能力
- 服務滾動升級和在線擴容能力
- 可擴展的資源自動調度機制
- 以及多粒度的資源管理能力
??同時,kubernetes 提供了完善的管理工具啡专,這些工具涵蓋了包括開發(fā)险毁、部署測試、運維監(jiān)控在內的各個環(huán)節(jié)们童。
??在 kubernetes 中畔况,service(服務)是分布式集群架構的核心,一個 service 對象擁有如下關鍵特征:
- 擁有一個唯一指定的名字(比如 mysql-service)慧库。
- 擁有一個虛擬 IP(Cluster IP跷跪、service IP 或 VIP)和端口號。
- 能夠提供某種遠程服務能力齐板。
- 被映射到了提供這種服務能力的一組容器應用上吵瞻。
??Kubernetes.io 開發(fā)了一個交互式教程,通過 WEB 瀏覽器就能使用預先部署好的一個Kubernetes 集群甘磨,快速體驗 kubernetes 的功能和應用場景听皿。
??鏈接:https://kubernetes.io/docs/tutorials/kubernetes-basics/
??K8s 官方下載地址:https://github.com/kubernetes
1.2 環(huán)境準備
??我在我的 PC 上裝了三臺虛擬機,一臺 centos 作為 master宽档,兩臺 ubuntu 作為 node尉姨,信息列表如下:
節(jié)點 | IP地址 | 操作系統(tǒng) |
---|---|---|
master | 192.168.27.135 | Centos 7.7 - x86_64 |
node1 | 192.168.27.133 | Ubuntu 16.04 - x86_64 |
node2 | 192.168.27.134 | Ubuntu 16.04 - x86_64 |
1.3 集群詳情
- OS:CentOS Linux release 7.7.1908 (Core) 3.10.0-1062.12.1.el7.x86_64
- Kubernetes: 1.6.0+(最低的版本要求是 1.6)
- Docker:建議使用 Docker CE
- Etcd: 3.3.10
- Flannel: 0.7.1 vxlan 或者 host-gw 網絡
- TLS 認證通信: (所有組件,如 etcd吗冤、kubernetes master 和 node)
- RBAC 授權
- kubelet TLS BootStrapping
- kubedns又厉、dashboard九府、heapster(influxdb、grafana)覆致、EFK(elasticsearch侄旬、fluentd、kibana) 集群插件
-
鏡像倉庫:私有 docker 鏡像倉庫 harbor(請自行部署煌妈,harbor 提供離線安裝包儡羔,直接使用 docker-compose 啟動即可),不會的請參官文檔:
安裝文檔:https://github.com/goharbor/harbor/blob/master/docs/installation_guide.md
配置 https 訪問:https://github.com/goharbor/harbor/blob/master/docs/configure_https.md
二璧诵、集群環(huán)境搭建
??下面的搭建過程使用二進制部署最新的 kubernetes v1.12.3 集群的所有步驟汰蜘,而不是使用 kubeadm 等自動化方式來部署集群。
??在部署的過程中之宿,將詳細列出各組件的啟動參數(shù)族操,它們的含義和可能遇到的問題;部署完成后比被,你將理解系統(tǒng)各組件的交互原理色难,進而能快速解決實際問題。
提醒
- 本文檔適用于
CentOS 7.x
等缀、Ubuntu 16.x
及以上版本系統(tǒng)- 由于啟用了
TLS
雙向認證枷莉、RBAC
授權等嚴格的安全機制,建議從頭開始部署尺迂,而不要從中間開始依沮,
否則可能會認證、授權等失斍箍瘛!- 部署過程中需要有很多證書的操作宋渔,請從頭到尾耐心操作
- 該部署操作僅是搭建成了一個可用 kubernetes 集群州疾,而很多地方還需要進行優(yōu)化,
heapster
插件皇拣、EFK
插件不一定會用于真實的生產環(huán)境中严蓖,但是通過部署這些插件,可以讓了解到如何部署應用到集群上氧急。
2.1?組件版本和配置策略
2.1.1?組件版本
- Kubernetes 1.12.3
- Docker 18.09.0-ce
- Etcd 3.3.10
- Flanneld 0.10.0
- 插件:
? Coredns
? Dashboard
? Heapster (influxdb颗胡、grafana)
? Metrics-Server
? EFK (elasticsearch、fluentd吩坝、kibana) - 鏡像倉庫:
? docker registry
? harbor
2.1.2?配置策略
kube-apiserver:
- 使用節(jié)點本地 nginx 4 層透明代理實現(xiàn)高可用毒姨;
- 關閉非安全端口 8080 和匿名訪問;
- 在安全端口 6443 接收 https 請求钉寝;
- 嚴格的認證和授權策略 (x509弧呐、token闸迷、RBAC);
- 開啟 bootstrap token 認證俘枫,支持 kubelet TLS bootstrapping腥沽;
- 使用 https 訪問 kubelet、etcd鸠蚪,加密通信换帜;
kube-controller-manager
- 3 節(jié)點高可用;
- 關閉非安全端口谢翎,在安全端口 10252 接收 https 請求隅熙;
- 使用 kubeconfig 訪問 apiserver 的安全端口;
- 自動 approve kubelet 證書簽名請求 (CSR)汹押,證書過期后自動輪轉矿筝;
- 各 controller 使用自己的 ServiceAccount 訪問 apiserver;
kube-scheduler
- 3 節(jié)點高可用棚贾;
- 使用 kubeconfig 訪問 apiserver 的安全端口窖维;
kubelet
- 使用 kubeadm 動態(tài)創(chuàng)建 bootstrap token,而不是在 apiserver 中靜態(tài)配置妙痹;
- 使用 TLS bootstrap 機制自動生成 client 和 server 證書铸史,過期后自動輪轉;
- 在 KubeletConfiguration 類型的 JSON 文件配置主要參數(shù)怯伊;
- 關閉只讀端口琳轿,在安全端口 10250 接收 https 請求,對請求進行認證和授權耿芹,拒絕匿名訪問和非授權訪問崭篡;
- 使用 kubeconfig 訪問 apiserver 的安全端口;
kube-proxy
- 使用 kubeconfig 訪問 apiserver 的安全端口吧秕;
- 在 KubeProxyConfiguration 類型的 JSON 文件配置主要參數(shù)琉闪;
- 使用 ipvs 代理模式;
集群插件
- DNS:使用功能砸彬、性能更好的 coredns颠毙;
- Dashboard:支持登錄認證;
- Metric:heapster砂碉、metrics-server蛀蜜,使用 https 訪問 kubelet 安全端口;
- Log:Elasticsearch增蹭、Fluend滴某、Kibana;
- Registry 鏡像庫:docker-registry、harbor壮池;
2.2?系統(tǒng)初始化和全局變量
2.2.1?集群機器
??master:192.168.27.135
??node1:192.168.27.133
??node2:192.168.27.134
??我用 VMWare 安裝了三臺虛擬機偏瓤,一臺使用centos,兩臺使用ubuntu椰憋,下面的 etcd 集群厅克、master 節(jié)點、worker 節(jié)點均使用這三臺機器橙依,但是使用 VMWare 或者 VirtualBox 創(chuàng)建的虛擬機通常 IP 都是動態(tài)分配的证舟,我們希望能夠固定虛擬機 IP,可以參考 Centos和Ubuntu虛擬機固定IP 進行配置窗骑。
注意:
- 需要在所有機器上執(zhí)行下面步驟的初始化命令女责;
- 需要使用具有 root 權限的賬號執(zhí)行這些命令。
2.2.2?主機名
??設置永久主機名稱创译,然后重新登陸
hostnamectl set-hostname [主機名]
??設置的主機名保存在 /etc/hostname
文件中抵知,這里我將 135 的 VM 設成 master
,133软族、134 分別設置為 node1
刷喜、node2
。
??為了讓集群中的機器都能解析其他機器的主機名稱立砸,需要修改每臺機器的 /etc/hosts
文件掖疮,添加主機名和 IP 的對應關系:
# 添加完之后應該類似下面的內容
cat /etc/hosts
192.168.27.135 master
192.168.27.133 node1
192.168.27.134 node2
??最好再每臺機器上 ping 以下每個主機名驗證一下。
ping master
ping node1
ping node2
2.2.3?添加 docker 賬戶
??在每臺機器上添加 docker 賬戶
useradd -m docker
2.2.4?無密碼 ssh 登陸其他節(jié)點
??如果沒有特殊指明颗祝,本文檔的所有操作均在 master 節(jié)點上執(zhí)行浊闪,然后遠程分發(fā)文件和執(zhí)行命令,所以需要添加該節(jié)點到其它節(jié)點的 ssh 信任關系螺戳。
??設置 master 可以無密碼登錄所有節(jié)點的 root 賬戶:
ssh-keygen -t rsa
ssh-copy-id root@master
ssh-copy-id root@node1
ssh-copy-id root@node2
??如果設置完之后使用 ssh node1
測試遠程登陸 node1
被拒絕搁宾,或者提示沒有權限,解決方法參考 SSH遠程登陸問題匯總 倔幼。
2.2.5?將可執(zhí)行文件路徑 /opt/k8s/bin 添加到 PATH 變量中
??在每臺機器上添加環(huán)境變量
echo 'PATH=/opt/k8s/bin:$PATH' >> /root/.bashrc
source /root/.bashrc
??當然盖腿,也可以在 /etc/profile
文件中添加環(huán)境變量,跟上面相比凤藏,區(qū)別在于 /etc/profile
屬于全局變量,服務器所有的用戶都可以使用該變量堕伪;/root/.bashrc
屬于用戶變量揖庄,只有 root 用戶可以使用。
2.2.6?安裝依賴包
Centos:
yum install -y epel-release
yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget
/usr/sbin/modprobe ip_vs
Ubuntu:
apt-get install -y conntrack ipvsadm ntp ipset jq iptables curl sysstat libseccomp
/usr/sbin/modprobe ip_vs
Ubuntu中執(zhí)行 /usr/sbin/modprobe ip_vs
時報錯找不到文件或目錄欠雌,又用 whereis modprobe
查詢了以下蹄梢,發(fā)現(xiàn)可執(zhí)行文件所在目錄為 /sbin/modprobe
,所以如果執(zhí)行報錯的話參考將 /usr/sbin/modprobe ip_vs
修改成 /sbin/modprobe ip_vs
。
- ipvs 依賴 ipset禁炒;
- ntp 保證各機器系統(tǒng)時間同步而咆;
2.2.7?關閉防火墻
??由于集群提供服務和通訊時涉及各種端口,為了避免各種報錯幕袱,在每臺機器上都關閉防火墻暴备,清理防火墻規(guī)則,設置默認轉發(fā)策略们豌。
Centos:
systemctl stop firewalld
systemctl disable firewalld
iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat
iptables -P FORWARD ACCEPT
Ubuntu:
sudo ufw disable
iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat
iptables -P FORWARD ACCEPT
2.2.8?關閉 swap 分區(qū)
??如果開啟了 swap 分區(qū)涯捻,kubelet 會啟動失敗(可以通過將參數(shù) --fail-swap-on 設置為 false 來忽略 swap on),故需要在每臺機器上關閉 swap 分區(qū)望迎。同時注釋 /etc/fstab 中相應的條目障癌,防止開機自動掛載 swap 分區(qū):
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
2.2.9?關閉 SELinux
??關閉 SELinux,否則后續(xù) K8S 掛載目錄可能報錯 Permission denied
:
setenforce 0
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
??如果執(zhí)行報錯辩尊,如下圖所示涛浙,則是因為機器沒裝 SELinux的原因,這一步可以跳過
2.2.10?關閉 dnsmasq(可選)
??Linux 系統(tǒng)開啟了 dnsmasq 后(如 GUI 環(huán)境)摄欲,將系統(tǒng) DNS Server 設置為 127.0.0.1轿亮,這會導致 docker 容器無法解析域名,需要關閉它:
systemctl stop dnsmasq
systemctl disable dnsmasq
??同樣的蒿涎,如果執(zhí)行報錯找不到服務或目錄哀托,證明服務器沒有安裝 dnsmasq,直接跳過
2.2.11?加載內核模塊
modprobe ip_vs_rr
modprobe br_netfilter
2.2.12?優(yōu)化內核參數(shù)
??如果執(zhí)行中有一些報錯不會理會劳秋,繼續(xù)往下執(zhí)行仓手。
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 空間,只有當系統(tǒng) 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
cp kubernetes.conf /etc/sysctl.d/kubernetes.conf
sysctl -p /etc/sysctl.d/kubernetes.conf
- 必須關閉 tcp_tw_recycle玻淑,否則和 NAT 沖突嗽冒,會導致服務不通;
- 關閉 IPV6补履,防止觸發(fā) docker BUG添坊;
2.2.13?設置系統(tǒng)時區(qū)
# 調整系統(tǒng) TimeZone
timedatectl set-timezone Asia/Shanghai
# 將當前的 UTC 時間寫入硬件時鐘
timedatectl set-local-rtc 0
# 重啟依賴于系統(tǒng)時間的服務
systemctl restart rsyslog
systemctl restart crond
2.2.14?更新系統(tǒng)時間(可選)
ntpdate cn.pool.ntp.org
2.2.15?關閉無關的服務
systemctl stop postfix && systemctl disable postfix
2.2.16?設置 rsyslogd 和 systemd journal
??systemd 的 journald 是 Centos7 缺省的日志記錄工具,它記錄了所有系統(tǒng)箫锤、內核贬蛙、Service Unit 的日志。
??相比 systemd谚攒,journald 記錄的日志有如下優(yōu)勢:
- 可以記錄到內存或文件系統(tǒng)阳准;(默認記錄到內存,對應的位置為 /run/log/jounal)
- 可以限制占用的磁盤空間馏臭、保證磁盤剩余空間野蝇;
- 可以限制日志文件大小、保存的時間;
??journald 默認將日志轉發(fā)給 rsyslog绕沈,這會導致日志寫了多份锐想,/var/log/messages 中包含了太多無關日志,不方便后續(xù)查看乍狐,同時也影響系統(tǒng)性能赠摇。
mkdir /var/log/journal # 持久化保存日志的目錄
mkdir /etc/systemd/journald.conf.d
cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF
[Journal]
# 持久化保存到磁盤
Storage=persistent
# 壓縮歷史日志
Compress=yes
SyncIntervalSec=5m
RateLimitInterval=30s
RateLimitBurst=1000
# 最大占用空間 10G
SystemMaxUse=10G
# 單日志文件最大 200M
SystemMaxFileSize=200M
# 日志保存時間 2 周
MaxRetentionSec=2week
# 不將日志轉發(fā)到 syslog
ForwardToSyslog=no
EOF
systemctl restart systemd-journald
2.2.17?創(chuàng)建相關目錄
??創(chuàng)建 k8s 的可執(zhí)行和工作目錄,以及證書目錄
mkdir -p /opt/k8s/{bin,work} /etc/{kubernetes,etcd}/cert
2.2.18?如果服務器OS內核較舊澜躺,升級內核(可選)
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
# 安裝完成后檢查 /boot/grub2/grub.cfg 中對應內核 menuentry 中是否包含 initrd16 配置蝉稳,如果
沒有,再安裝一次掘鄙!
yum --enablerepo=elrepo-kernel install -y kernel-lt
# 設置開機從新內核啟動
grub2-set-default 0
??安裝內核源文件(可選耘戚,在升級完內核并重啟機器后執(zhí)行):
# yum erase kernel-headers
yum --enablerepo=elrepo-kernel install kernel-lt-devel-$(uname -r) kernel-lt-headers-$(uname
-r)
2.2.19?關閉 NUMA(可選)
cp /etc/default/grub{,.bak}
vim /etc/default/grub # 在 GRUB_CMDLINE_LINUX 一行添加 `numa=off` 參數(shù),如下所示:
diff /etc/default/grub.bak /etc/default/grub
6c6
< GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rhgb quiet"
---
> GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rhgb quiet numa=off"
??重新生成 grub2 配置文件
cp /boot/grub2/grub.cfg{,.bak}
grub2-mkconfig -o /boot/grub2/grub.cfg
2.2.20?檢查系統(tǒng)內核和模塊是否適合運行 docker
curl https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh >
check-config.sh
bash ./check-config.sh
??有可能出現(xiàn)下載不到的情況操漠,這是DNS污染的原因收津,參考修改Hosts臨時解決GitHub的raw.githubusercontent.com無法鏈接的問題即可正常下載。
2.2.21?分發(fā)集群環(huán)境變量定義腳本(擴容時不需要執(zhí)行該步驟)
??先來看以下環(huán)境變量腳本中定義的環(huán)境變量及配置
#!/usr/bin/bash
# 生成 EncryptionConfig 所需的加密 key
export ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64)
# 集群各機器 IP 數(shù)組
export NODE_IPS=(192.168.27.135 192.168.27.133 192.168.27.134)
# 集群各 IP 對應的 主機名數(shù)組
export NODE_NAMES=(master node1 node2)
# etcd 集群服務地址列表
export ETCD_ENDPOINTS="https://192.168.27.135:2379,https://192.168.27.133:2379,https://192.168.27.133:2379"
# etcd 集群間通信的 IP 和端口
export ETCD_NODES="master=https://192.168.27.135:2380,node1=https://192.168.27.133:2380,node2=https://192.168.27.134:2380"
# kube-apiserver 的反向代理(kube-nginx)地址端口
# export KUBE_APISERVER="https://127.0.0.1:8443"
export KUBE_APISERVER="https://192.168.27.135:8443"
# 節(jié)點間互聯(lián)網絡接口名稱
export IFACE="ens33"
# etcd 數(shù)據目錄
export ETCD_DATA_DIR="/data/k8s/etcd/data"
# etcd WAL 目錄浊伙,建議是 SSD 磁盤分區(qū)撞秋,或者和 ETCD_DATA_DIR 不同的磁盤分區(qū)
export ETCD_WAL_DIR="/data/k8s/etcd/wal"
# k8s 各組件數(shù)據目錄
export K8S_DIR="/data/k8s/k8s"
# docker 數(shù)據目錄
export DOCKER_DIR="/data/k8s/docker"
## 以下參數(shù)一般不需要修改
# TLS Bootstrapping 使用的 Token,可以使用命令 head -c 16 /dev/urandom | od -An -t x | tr -d ' ' 生成
BOOTSTRAP_TOKEN="41f7e4ba8b7be874fcff18bf5cf41a7c"
# 最好使用 當前未用的網段 來定義服務網段和 Pod 網段
# 服務網段嚣鄙,部署前路由不可達吻贿,部署后集群內路由可達(kube-proxy 保證)
SERVICE_CIDR="10.254.0.0/16"
# Pod 網段,建議 /16 段地址哑子,部署前路由不可達舅列,部署后集群內路由可達(flanneld 保證)
CLUSTER_CIDR="172.30.0.0/16"
# 服務端口范圍 (NodePort Range)
export NODE_PORT_RANGE="30000-32767"
# flanneld 網絡配置前綴
export FLANNEL_ETCD_PREFIX="/kubernetes/network"
# kubernetes 服務 IP (一般是 SERVICE_CIDR 中第一個IP)
export CLUSTER_KUBERNETES_SVC_IP="10.254.0.1"
# 集群 DNS 服務 IP (從 SERVICE_CIDR 中預分配)
export CLUSTER_DNS_SVC_IP="10.254.0.2"
# 集群 DNS 域名(末尾不帶點號)
export CLUSTER_DNS_DOMAIN="cluster.local"
# 將二進制目錄 /opt/k8s/bin 加到 PATH 中
export PATH=/opt/k8s/bin:$PATH
??需要根據環(huán)境實際情況修改的變量有:
??然后,把全局變量定義腳本拷貝到所有節(jié)點的
/opt/k8s/bin
目錄卧蜓,并分發(fā)到集群中各個節(jié)點
source /opt/k8s/bin/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
2.2.22?參考
??系統(tǒng)內核相關參數(shù)參考:https://docs.openshift.com/enterprise/3.2/admin_guide/overcommit.html
2.3?創(chuàng)建 CA 證書和密鑰
??為確保安全帐要,kubernetes 系統(tǒng)各組件需要使用 x509 證書對通信進行加密和認證。CA (Certificate Authority)
是自簽名的根證書弥奸,用來簽名后續(xù)創(chuàng)建的其它證書榨惠。
??這里使用 CloudFlare 的 PKI 工具集 cfssl 創(chuàng)建所有證書。
注意:如果沒有特殊指明盛霎,本安裝步驟的所有操作均在 master 節(jié)點上執(zhí)行赠橙,然后遠程分發(fā)文件和執(zhí)行命令。
2.3.1?安裝 cfssl 工具
sudo mkdir -p /opt/k8s/work/cert && cd /opt/k8s/work
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
mv cfssl_linux-amd64 /opt/k8s/bin/cfssl
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
mv cfssljson_linux-amd64 /opt/k8s/bin/cfssljson
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
mv cfssl-certinfo_linux-amd64 /opt/k8s/bin/cfssl-certinfo
chmod +x /opt/k8s/bin/*
export PATH=/opt/k8s/bin:$PATH
??下載的時候發(fā)現(xiàn)下載速度過慢愤炸,需要反復下載才能成功期揪,所以這里將環(huán)境搭建用到的軟件包(cfssl.tar.gz)放在百度云盤上,通過xshell上傳到服務器即可摇幻,操作參考:如何快捷地將文件通過xshell上傳到服務器 横侦。
鏈接:https://pan.baidu.com/s/1Zt9SGin72ahERM7ykJ8o7w
提取碼:27m2
??將 cfssl.tar.gz 解壓并將整個目錄下的可執(zhí)行文件移到 /opt/k8s/bin
:
??修改可執(zhí)行文件名字,修改完后如圖:
2.3.2?創(chuàng)建根證書 (CA)
??CA 證書是集群所有節(jié)點共享的绰姻,只需要創(chuàng)建一個 CA 證書枉侧,后續(xù)創(chuàng)建的所有證書都由它簽名。
2.3.3?創(chuàng)建配置文件
??CA 配置文件用于配置根證書的使用場景 (profile) 和具體參數(shù) (usage狂芋,過期時間榨馁、服務端認證、客戶端認證帜矾、加密等)翼虫,后續(xù)在簽名其它證書時需要指定特定場景。
cd /opt/k8s/work/cert
cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
EOF
- signing:表示該證書可用于簽名其它證書屡萤,生成的 ca.pem 證書中 CA=TRUE珍剑;
- server auth:表示 client 可以用該該證書對 server 提供的證書進行驗證;
- client auth:表示 server 可以用該該證書對 client 提供的證書進行驗證死陆;
2.3.4?創(chuàng)建證書簽名請求文件
cd /opt/k8s/work/cert
cat > ca-csr.json <<EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "study163"
}
]
}
EOF
- CN:Common Name招拙,kube-apiserver 從證書中提取該字段作為請求的用戶名 (User Name),瀏覽器使用該字段驗證網站是否合法措译;
- O:Organization别凤,kube-apiserver 從證書中提取該字段作為請求用戶所屬的組 (Group);
- kube-apiserver 將提取的 User领虹、Group 作為 RBAC 授權的用戶標識规哪;
2.3.5?生成 CA 證書和私鑰
cd /opt/k8s/work/cert
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
ls ca*
2.3.6?分發(fā) CA 證書和私鑰
??將生成的 CA 證書、秘鑰文件塌衰、配置文件拷貝到所有節(jié)點的
/etc/kubernetes/cert
目錄下:
cd /opt/k8s/work/cert
source /opt/k8s/bin/environment.sh # 導入 NODE_IPS 環(huán)境變量
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
2.3.7?CA 資料參考
各種 CA 證書類型:
https://github.com/kubernetes-incubator/apiserver-builder/blob/master/docs/concepts/auth.md
2.4?部署 kubectl 命令行工具
??kubectl 是 kubernetes 集群的命令行管理工具诉稍,這了介紹安裝和配置的步驟。
??kubectl 默認從 ~/.kube/config
文件讀取 kube-apiserver 地址猾蒂、證書均唉、用戶名等信息,如果沒有配置肚菠,執(zhí)行 kubectl 命令時可能會出錯:
kubectl get pods
注意:
- 如果沒有特殊指明舔箭,本文檔的所有操作均在 master 節(jié)點上執(zhí)行,然后遠程分發(fā)文件和執(zhí)行命令蚊逢。
- 本文檔只需要部署一次层扶,生成的 kubeconfig 文件是通用的,可以拷貝到需要執(zhí)行 kubeclt 命令的機器上烙荷。
2.4.1 下載和分發(fā) kubectl 命令行工具
??下載和解壓:
cd /opt/k8s/work
wget https://dl.k8s.io/v1.12.3/kubernetes-client-linux-amd64.tar.gz
tar -xzvf kubernetes-client-linux-amd64.tar.gz
??分發(fā)到所有使用 kubectl 的節(jié)點:
cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp kubernetes/client/bin/kubectl root@${node_ip}:/opt/k8s/bin/
ssh root@${node_ip} "chmod +x /opt/k8s/bin/*"
done
2.4.2 創(chuàng)建 admin 證書和私鑰
??kubectl 與 apiserver https 安全端口通信镜会,apiserver 對提供的證書進行認證和授權。
??kubectl 作為集群的管理工具终抽,需要被授予最高權限戳表。這里創(chuàng)建具有最高權限的 admin 證書桶至。
創(chuàng)建證書簽名請求:
cd /opt/k8s/work/cert
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 字段為空女蜈;
??生成證書和私鑰
cd /opt/k8s/work/cert
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
ls admin*
2.4.3 創(chuàng)建 kubeconfig 文件
??kubeconfig 為 kubectl 的配置文件,包含訪問 apiserver 的所有信息色瘩,如 apiserver 地址伪窖、CA 證書和自身使用的證書;
cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
# 設置集群參數(shù)
kubectl config set-cluster kubernetes \
--certificate-authority=/opt/k8s/work/cert/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kubectl.kubeconfig
# 設置客戶端認證參數(shù)
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
# 設置上下文參數(shù)
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 文件中(不加時汹买,寫入的是證書文件路徑);
??生成kubectl.kubeconfig
文件
2.4.4 分發(fā) kubeconfig 文件
??分發(fā)到所有使用 kubectl 命令的節(jié)點聊倔,在所有節(jié)點的 root 用戶目錄下創(chuàng)建一個 .kube
的目錄晦毙,并將分發(fā)的文件重命名為 config
放置其中。
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 ~/.kube"
scp kubectl.kubeconfig root@${node_ip}:~/.kube/config
done
??查詢每個節(jié)點的
/root/.kube/config
配置文件