溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

使用二進(jìn)制的方式部署 K8S-1.16 高可用集群(二十)

發(fā)布時間:2020-08-02 15:08:38 來源:網(wǎng)絡(luò) 閱讀:1886 作者:wzlinux 欄目:系統(tǒng)運(yùn)維

一、項(xiàng)目介紹

項(xiàng)目致力于讓有意向使用原生kubernetes集群的企業(yè)或個人,可以方便的、系統(tǒng)的使用二進(jìn)制的方式手工搭建kubernetes高可用集群。并且讓相關(guān)的人員可以更好的理解kubernetes集群的運(yùn)作機(jī)制。

軟件版本

  • os centos7.7(ubuntu也適用,需要替換部分命令)
  • kubernetes 1.16.2
  • etcd 3.4.3
  • docker 18.06
  • calico 3.10.1-2
  • coredns

配置策略

kube-apiserver:

  • 使用節(jié)點(diǎn)本地 nginx 4 層透明代理實(shí)現(xiàn)高可用;
  • 關(guān)閉非安全端口 8080 和匿名訪問;
  • 在安全端口 6443 接收 https 請求;
  • 嚴(yán)格的認(rèn)證和授權(quán)策略 (x509、token、RBAC);
  • 開啟 bootstrap token 認(rèn)證,支持 kubelet TLS bootstrapping;
  • 使用 https 訪問 kubelet、etcd,加密通信;

kube-controller-manager:

  • 3 節(jié)點(diǎn)高可用;
  • 關(guān)閉非安全端口 10252,在安全端口 10257 接收 https 請求;
  • 使用 kubeconfig 訪問 apiserver 的安全端口;
  • 自動 approve kubelet 證書簽名請求 (CSR),證書過期后自動輪轉(zhuǎn);
  • 各 controller 使用自己的 ServiceAccount 訪問 apiserver;

kube-scheduler:

  • 3 節(jié)點(diǎn)高可用;
  • 關(guān)閉非安全端口 10251,在安全端口 10259 接收 https 請求;
  • 使用 kubeconfig 訪問 apiserver 的安全端口;

kubelet:

  • 使用 kubeadm 動態(tài)創(chuàng)建 bootstrap token,而不是在 apiserver 中靜態(tài)配置;
  • 使用 TLS bootstrap 機(jī)制自動生成 client 和 server 證書,過期后自動輪轉(zhuǎn);
  • 在 KubeletConfiguration 類型的 JSON 文件配置主要參數(shù);
  • 關(guān)閉只讀端口 10255,在安全端口 10250 接收 https 請求,對請求進(jìn)行認(rèn)證和授權(quán),拒絕匿名訪問和非授權(quán)訪問;
  • 使用 kubeconfig 訪問 apiserver 的安全端口;

kube-proxy:

  • 使用 kubeconfig 訪問 apiserver 的安全端口;
  • 在 KubeProxyConfiguration 類型的 JSON 文件配置主要參數(shù);
  • 使用 ipvs 代理模式;

集群插件:

  • DNS:使用功能、性能更好的 coredns;
  • Dashboard:支持登錄認(rèn)證;
  • Metric:metrics-server,使用 https 訪問 kubelet 安全端口;
  • Log:Elasticsearch、Fluend、Kibana;
  • Registry 鏡像庫:docker-registry、harbor;

二、實(shí)踐環(huán)境準(zhǔn)備

1. 服務(wù)器說明

我們這里使用的是五臺centos 7.7虛擬機(jī),具體信息如下表:

系統(tǒng)類型 IP地址 節(jié)點(diǎn)角色 CPU Memory Hostname
centos-7.7 172.18.0.100 master >=2 >=2G k8s-m01
centos-7.7 172.18.0.101 master >=2 >=2G k8s-m02
centos-7.7 172.18.0.102 master >=2 >=2G k8s-m03
centos-7.7 172.18.0.103 worker >=2 >=2G k8s-n01
centos-7.7 172.18.0.104 worker >=2 >=2G k8s-n02

使用二進(jìn)制的方式部署 K8S-1.16 高可用集群(二十)

2. 系統(tǒng)設(shè)置(所有節(jié)點(diǎn))

2.1 主機(jī)名

主機(jī)名必須每個節(jié)點(diǎn)都不一樣,并且保證所有點(diǎn)之間可以通過 hostname 互相訪問。

# 查看主機(jī)名
$ hostname

# 修改主機(jī)名
$ hostnamectl set-hostname <your_hostname>

# 配置host,使主節(jié)點(diǎn)之間可以通過hostname互相訪問
$ vi /etc/hosts
# <node-ip> <node-hostname>
2.2 安裝依賴包
# 更新yum
$ yum update

# 安裝依賴包
$ yum install -y conntrack ipvsadm ipset jq sysstat curl iptables libseccomp wget

## 時間同步
$ ntpdate time1.aliyun.com
2.3 關(guān)閉防火墻、swap,重置iptables
# 關(guān)閉防火墻
$ systemctl stop firewalld && systemctl disable firewalld

# 重置iptables
$ iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat && iptables -P FORWARD ACCEPT

# 關(guān)閉swap
$ swapoff -a
$ sed -i '/swap/s/^\(.*\)$/#\1/g' /etc/fstab

# 關(guān)閉selinux
$ setenforce 0

# 關(guān)閉dnsmasq(否則可能導(dǎo)致docker容器無法解析域名)
$ service dnsmasq stop && systemctl disable dnsmasq
2.4 系統(tǒng)參數(shù)設(shè)置
# 制作配置文件
$ cat > /etc/sysctl.d/kubernetes.conf <<EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
vm.swappiness=0
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
EOF

# 生效文件
$ sysctl -p /etc/sysctl.d/kubernetes.conf
2.5 加載內(nèi)核模塊
modprobe ip_vs_rr
modprobe br_netfilter

3. 安裝docker(worker節(jié)點(diǎn))

根據(jù)kubernetes對docker版本的兼容測試情況,我們選擇18.06版本,我們配置阿里云的源,速度比較快。

# 添加 yum 源
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -P /etc/yum.repos.d/

# 清理原有版本
yum remove -y docker* container-selinux

# 安裝docker
yum list docker-ce.x86_64  --showduplicates |sort -r
yum install docker-ce-18.06.1.ce -y

# 開機(jī)啟動
systemctl enable docker

# 配置加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://hdi5v8p1.mirror.aliyuncs.com"]
}
EOF

# 啟動docker服務(wù)
service docker restart

4. 準(zhǔn)備二進(jìn)制文件(所有節(jié)點(diǎn))

4.1 配置免密登錄

為了方便文件的copy我們選擇一個中轉(zhuǎn)節(jié)點(diǎn)(隨便一個節(jié)點(diǎn),可以是集群中的也可以是非集群中的),配置好跟其他所有節(jié)點(diǎn)的免密登錄,我們這里使用 k8s-m01。

# 看看是否已經(jīng)存在rsa公鑰
$ cat ~/.ssh/id_rsa.pub

# 如果不存在就創(chuàng)建一個新的
$ ssh-keygen -t rsa

# 免密鑰認(rèn)證
$ ssh-copy-id root@<your-server-ip>
4.2 下載二進(jìn)制文件

官方下載地址(在CHANGELOG鏈接里面):
https://github.com/kubernetes/kubernetes/releases

我們選擇的版本是 1.16.2。

網(wǎng)盤下載地址--推薦(我從官網(wǎng)下載整理好的文件):
鏈接: https://pan.baidu.com/s/1Ut9VERgm55B4lmz0wjjzFQ
提取碼: mjem

4.3 分發(fā)文件
# 把文件copy到每個節(jié)點(diǎn)上(注意替換自己的文件目錄)
$ scp master/* <user>@<master-ip>:/usr/local/bin/
$ scp worker/* <user>@<worker-ip>:/usr/local/bin/

# 給文件添加可執(zhí)行權(quán)限
$ chmod +x /usr/local/bin/*

5. 準(zhǔn)備配置文件(k8s-m01 節(jié)點(diǎn))

上一步我們下載了kubernetes各個組件的二進(jìn)制文件,這些可執(zhí)行文件的運(yùn)行也是需要添加很多參數(shù)的,包括有的還會依賴一些配置文件。現(xiàn)在我們就把運(yùn)行它們需要的參數(shù)和配置文件都準(zhǔn)備好。

5.1 下載配置文件

我這準(zhǔn)備了一個項(xiàng)目,專門為大家按照自己的環(huán)境生成配置的。它只是幫助大家盡量的減少了機(jī)械化的重復(fù)工作。它并不會幫你設(shè)置系統(tǒng)環(huán)境,不會給你安裝軟件。總之就是會減少你的部署工作量,但不會耽誤你對整個系統(tǒng)的認(rèn)識和把控。

$ cd ~
$ git clone https://github.com/wangzan18/kubernetes-ha-binary.git

# 看看git內(nèi)容
$ ls -l kubernetes-ha-binary
addons/
configs/
pki/
services/
init.sh
global-configs.properties
5.2 文件說明

addons :kubernetes的插件目錄,包括calico、coredns、dashboard等。

configs:這個目錄比較 - 凌亂,包含了部署集群過程中用到的雜七雜八的配置文件、腳本文件等。

pki:各個組件的認(rèn)證授權(quán)相關(guān)證書配置。

services:所有的kubernetes服務(wù)(service)配置文件。

global-configs.properties:全局配置,包含各種易變的配置內(nèi)容。

init.sh:初始化腳本,配置好global-config之后,會自動生成所有配置文件。

5.3 生成配置

這里會根據(jù)大家各自的環(huán)境生成kubernetes部署過程需要的配置文件。
在每個節(jié)點(diǎn)上都生成一遍,把所有配置都生成好,后面會根據(jù)節(jié)點(diǎn)類型去使用相關(guān)的配置。

# cd到之前下載的git代碼目錄
$ cd kubernetes-ha-binary

# 編輯屬性配置(根據(jù)文件注釋中的說明填寫好每個key-value)
$ vim global-config.properties

# 生成配置文件,確保執(zhí)行過程沒有異常信息
$ ./init.sh

# 查看生成的配置文件,確保腳本執(zhí)行成功
$ find target/ -type f

三、高可用集群部署

1. CA證書(任意節(jié)點(diǎn))

1.1 安裝cfssl

cfssl是非常好用的CA工具,我們用它來生成證書和秘鑰文件
安裝過程比較簡單,如下:

# 下載
$ 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

# 修改為可執(zhí)行權(quán)限
$ chmod +x /usr/local/bin/cfssl /usr/local/bin/cfssljson

# 驗(yàn)證
$ cfssl version
Version: 1.2.0
Revision: dev
Runtime: go1.6
1.2 生成根證書

查看證書配置文件,CA 配置文件用于配置根證書的使用場景 (profile) 和具體參數(shù) (usage,過期時間、服務(wù)端認(rèn)證、客戶端認(rèn)證、加密等),后續(xù)在簽名其它證書時需要指定特定場景。

$ cd target/pki/
$ cat ca-config.json
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "87600h"
      }
    }
  }
}
  • signing:表示該證書可用于簽名其它證書,生成的 ca.pem 證書中 CA=TRUE
  • server auth:表示 client 可以用該該證書對 server 提供的證書進(jìn)行驗(yàn)證;
  • client auth:表示 server 可以用該該證書對 client 提供的證書進(jìn)行驗(yàn)證;

查看證書簽名請求文件。

$ cat ca-csr.json 
{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "seven"
    }
  ]
}
  • CN:Common Name,kube-apiserver 從證書中提取該字段作為請求的用戶名 (User Name),瀏覽器使用該字段驗(yàn)證網(wǎng)站是否合法;
  • O:Organization,kube-apiserver 從證書中提取該字段作為請求用戶所屬的組 (Group);
  • kube-apiserver 將提取的 User、Group 作為 RBAC 授權(quán)的用戶標(biāo)識;

根證書是集群所有節(jié)點(diǎn)共享的,只需要創(chuàng)建一個 CA 證書,后續(xù)創(chuàng)建的所有證書都由它簽名。

# 生成證書和私鑰
$ cd target/pki
$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca

# 生成完成后會有以下文件(我們最終想要的就是ca-key.pem和ca.pem,一個秘鑰,一個證書)
$ ls
ca-config.json  ca.csr  ca-csr.json  ca-key.pem  ca.pem

# 創(chuàng)建目錄
$ ssh <user>@<node-ip> "mkdir -p /etc/kubernetes/pki/"

# 分發(fā)到每個matser主節(jié)點(diǎn)
$ scp ca*.pem <user>@<master-ip>:/etc/kubernetes/pki/

2. 部署etcd集群(master節(jié)點(diǎn))

2.1 下載etcd,并傳到各master節(jié)點(diǎn)
$ wget https://github.com/etcd-io/etcd/releases/download/v3.4.3/etcd-v3.4.3-linux-amd64.tar.gz
$ tar xf etcd-v3.4.3-linux-amd64.tar.gz
$ scp etcd-v3.4.3-linux-amd64/etcd* <user>@<master-ip>:/usr/local/bin/
2.2 生成證書和私鑰

查看證書請求文件。

$ cd target/pki/etcd
$ cat etcd-csr.json
{
  "CN": "etcd",
  "hosts": [
    "127.0.0.1",
    "172.18.0.100",
    "172.18.0.101",
    "172.18.0.102"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "seven"
    }
  ]
}
  • hosts 字段指定授權(quán)使用該證書的 etcd 節(jié)點(diǎn) IP 或域名列表,需要將 etcd 集群的三個節(jié)點(diǎn) IP 都列在其中;
# 生成證書、私鑰
$ cfssl gencert -ca=../ca.pem \
    -ca-key=../ca-key.pem \
    -config=../ca-config.json \
    -profile=kubernetes etcd-csr.json | cfssljson -bare etcd

# 分發(fā)到每個etcd節(jié)點(diǎn)(master節(jié)點(diǎn))
$ scp etcd*.pem <user>@<master-ip>:/etc/kubernetes/pki/
2.3 創(chuàng)建service文件
# scp配置文件到每個master節(jié)點(diǎn)
$ scp target/<node-ip>/services/etcd.service <node-ip>:/etc/systemd/system/

# 創(chuàng)建數(shù)據(jù)和工作目錄
$ ssh <user>@<node-ip> "mkdir -p /var/lib/etcd"
2.4 啟動服務(wù)

etcd 進(jìn)程首次啟動時會等待其它節(jié)點(diǎn)的 etcd 加入集群,命令 systemctl start etcd 會卡住一段時間,為正常現(xiàn)象。

#啟動服務(wù)
$ systemctl daemon-reload && systemctl enable etcd && systemctl restart etcd

#查看狀態(tài)
$ service etcd status

#查看啟動日志
$ journalctl -f -u etcd

#查看服務(wù)監(jiān)聽端口
$ netstat -tlnp |grep etcd

3. 部署api-server(master節(jié)點(diǎn))

3.1 生成證書和私鑰

查看證書請求文件。

$ cd target/pki/apiserver
$ cat kubernetes-csr.json 
{
  "CN": "kubernetes",
  "hosts": [
    "127.0.0.1",
    "172.18.0.100",
    "172.18.0.101",
    "172.18.0.102",
    "172.18.0.88",
    "10.96.0.1",
    "kubernetes",
    "kubernetes.default",
    "kubernetes.default.svc",
    "kubernetes.default.svc.cluster",
    "kubernetes.default.svc.cluster.local"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "seven"
    }
  ]
}
# 生成證書、私鑰
$ cfssl gencert -ca=../ca.pem \
  -ca-key=../ca-key.pem \
  -config=../ca-config.json \
  -profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes

# 分發(fā)到每個master節(jié)點(diǎn)
$ scp kubernetes*.pem <user>@<master-ip>:/etc/kubernetes/pki/
3.2 創(chuàng)建后續(xù)訪問 metrics-server 使用的證書

創(chuàng)建證書簽名請求:

$ cd target/pki/metrics-server
$ cat > proxy-client-csr.json <<EOF
{
  "CN": "aggregator",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "seven"
    }
  ]
}
EOF
  • CN 名稱需要位于 kube-apiserver 的 --requestheader-allowed-names 參數(shù)中,否則后續(xù)訪問 metrics 時會提示權(quán)限不足。

生成證書和私鑰:

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

# 分發(fā)到每個master節(jié)點(diǎn)
$ scp proxy-client*.pem <user>@<master-ip>:/etc/kubernetes/pki/
3.3 創(chuàng)建service文件
# scp配置文件到每個master節(jié)點(diǎn)
$ scp target/<node-ip>/services/kube-apiserver.service <user>@<node-ip>:/etc/systemd/system/

# 創(chuàng)建日志目錄
$ ssh <user>@<node-ip> "mkdir -p /var/log/kubernetes"

# 復(fù)制配置文件
$ scp target/configs/encryption-config.yaml <user>@<master-ip>:/etc/kubernetes/
$ scp target/configs/audit-policy.yaml <user>@<master-ip>:/etc/kubernetes/
3.3 啟動服務(wù)
#啟動服務(wù)
$ systemctl daemon-reload && systemctl enable kube-apiserver && systemctl restart kube-apiserver

#查看運(yùn)行狀態(tài)
$ service kube-apiserver status

#查看日志
$ journalctl -f -u kube-apiserver

#檢查監(jiān)聽端口
$ netstat -ntlp|grep kube-apiserver

4. 部署keepalived - apiserver高可用(master節(jié)點(diǎn))

可以使用 nginx 做負(fù)載均衡器,把請求分發(fā)到后面三臺apiserver服務(wù)器上面,這樣最好,也是官方推薦的。

4.1 安裝keepalived
# 在兩個主節(jié)點(diǎn)上安裝keepalived(一主一備),我這里選擇 k8s-m01, k8s-m02
$ yum install -y keepalived
4.2 創(chuàng)建keepalived配置文件
# 創(chuàng)建目錄
$ ssh <user>@<master-ip> "mkdir -p /etc/keepalived"
$ ssh <user>@<backup-ip> "mkdir -p /etc/keepalived"

# 分發(fā)配置文件
$ scp target/configs/keepalived-master.conf <user>@<master-ip>:/etc/keepalived/keepalived.conf
$ scp target/configs/keepalived-backup.conf <user>@<backup-ip>:/etc/keepalived/keepalived.conf

# 分發(fā)監(jiān)測腳本
$ scp target/configs/check-apiserver.sh <user>@<master-ip>:/etc/keepalived/
$ scp target/configs/check-apiserver.sh <user>@<backup-ip>:/etc/keepalived/
4.3 啟動keepalived
# 分別在master和backup上啟動服務(wù)
$ systemctl enable keepalived && service keepalived start

# 檢查狀態(tài)
$ service keepalived status

# 查看日志
$ journalctl -f -u keepalived

# 訪問測試
$ curl --insecure https://<master-vip>:6443/
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {

  },
  "status": "Failure",
  "message": "Unauthorized",
  "reason": "Unauthorized",
  "code": 401
}

5. 部署kubectl(任意節(jié)點(diǎn)),我選擇 k8s-m01

kubectl 是 kubernetes 集群的命令行管理工具,它默認(rèn)從 ~/.kube/config 文件讀取 kube-apiserver 地址、證書、用戶名等信息。

5.1 創(chuàng)建 admin 證書和私鑰

kubectl 與 apiserver https 安全端口通信,apiserver 對提供的證書進(jìn)行認(rèn)證和授權(quán)。

kubectl 作為集群的管理工具,需要被授予最高權(quán)限。這里創(chuàng)建具有最高權(quán)限的 admin 證書。

$ cd target/pki/admin
$ cat admin-csr.json 
{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "system:masters",
      "OU": "seven"
    }
  ]
}
  • O 為 system:masters,kube-apiserver 收到該證書后將請求的 Group 設(shè)置為 system:masters;
  • 預(yù)定義的 ClusterRoleBinding cluster-admin 將 Group system:masters 與 Role cluster-admin 綁定,該 Role 授予所有 API的權(quán)限;
  • 該證書只會被 kubectl 當(dāng)做 client 證書使用,所以 hosts 字段為空;
# 創(chuàng)建證書、私鑰
$ cfssl gencert -ca=../ca.pem \
  -ca-key=../ca-key.pem \
  -config=../ca-config.json \
  -profile=kubernetes admin-csr.json | cfssljson -bare admin
5.2 創(chuàng)建kubeconfig配置文件

kubeconfig 為 kubectl 的配置文件,包含訪問 apiserver 的所有信息,如 apiserver 地址、CA 證書和自身使用的證書

# 設(shè)置集群參數(shù)
$ kubectl config set-cluster kubernetes \
  --certificate-authority=../ca.pem \
  --embed-certs=true \
  --server=https://<MASTER_VIP>:6443 \
  --kubeconfig=kube.config

# 設(shè)置客戶端認(rèn)證參數(shù)
$ kubectl config set-credentials admin \
  --client-certificate=admin.pem \
  --client-key=admin-key.pem \
  --embed-certs=true \
  --kubeconfig=kube.config

# 設(shè)置上下文參數(shù)
$ kubectl config set-context admin@kubernetes \
  --cluster=kubernetes \
  --user=admin \
  --kubeconfig=kube.config

# 設(shè)置默認(rèn)上下文
$ kubectl config use-context admin@kubernetes --kubeconfig=kube.config

# 分發(fā)到目標(biāo)節(jié)點(diǎn)
$ scp kube.config <user>@<node-ip>:~/.kube/config
  • --certificate-authority:驗(yàn)證 kube-apiserver 證書的根證書;
  • --client-certificate、--client-key:剛生成的 admin 證書和私鑰,連接 kube-apiserver 時使用;
  • --embed-certs=true:將 ca.pem 和 admin.pem 證書內(nèi)容嵌入到生成的 kubectl.kubeconfig 文件中(不加時,寫入的是證書文件路徑,后續(xù)拷貝 kubeconfig 到其它機(jī)器時,還需要單獨(dú)拷貝證書文件,不方便。);
5.3 授予 kubernetes 證書訪問 kubelet API 的權(quán)限

在執(zhí)行 kubectl exec、run、logs 等命令時,apiserver 會轉(zhuǎn)發(fā)到 kubelet。這里定義 RBAC 規(guī)則,授權(quán) apiserver 調(diào)用 kubelet API。

$ kubectl create clusterrolebinding kube-apiserver:kubelet-apis --clusterrole=system:kubelet-api-admin --user kubernetes
5.4 小測試
# 查看集群信息
$ kubectl cluster-info
$ kubectl get all -A
$ kubectl get cs

6. 部署controller-manager(master節(jié)點(diǎn))

controller-manager啟動后將通過競爭選舉機(jī)制產(chǎn)生一個 leader 節(jié)點(diǎn),其它節(jié)點(diǎn)為阻塞狀態(tài)。當(dāng) leader 節(jié)點(diǎn)不可用后,剩余節(jié)點(diǎn)將再次進(jìn)行選舉產(chǎn)生新的 leader 節(jié)點(diǎn),從而保證服務(wù)的可用性。

6.1 創(chuàng)建證書和私鑰

查看證書請求。

$ cd target/pki/controller-manager
$ cat controller-manager-csr.json 
{
    "CN": "system:kube-controller-manager",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "hosts": [
      "127.0.0.1",
      "172.18.0.100",
      "172.18.0.101",
      "172.18.0.102"
    ],
    "names": [
      {
        "C": "CN",
        "ST": "BeiJing",
        "L": "BeiJing",
        "O": "system:kube-controller-manager",
        "OU": "seven"
      }
    ]
}
  • hosts 列表包含所有 kube-controller-manager 節(jié)點(diǎn) IP;
  • CN 和 O 均為 system:kube-controller-manager,kubernetes 內(nèi)置的 ClusterRoleBindings system:kube-controller-manager 賦予 kube-controller-manager 工作所需的權(quán)限。
# 生成證書、私鑰
$ cfssl gencert -ca=../ca.pem \
  -ca-key=../ca-key.pem \
  -config=../ca-config.json \
  -profile=kubernetes controller-manager-csr.json | cfssljson -bare controller-manager

# 分發(fā)到每個master節(jié)點(diǎn)
$ scp controller-manager*.pem <user>@<node-ip>:/etc/kubernetes/pki/
6.2 創(chuàng)建controller-manager的kubeconfig
# 創(chuàng)建kubeconfig
$ kubectl config set-cluster kubernetes \
  --certificate-authority=../ca.pem \
  --embed-certs=true \
  --server=https://<MASTER_VIP>:6443 \
  --kubeconfig=controller-manager.kubeconfig

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

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

$ kubectl config use-context system:kube-controller-manager@kubernetes --kubeconfig=controller-manager.kubeconfig

# 分發(fā)controller-manager.kubeconfig
$ scp controller-manager.kubeconfig <user>@<node-ip>:/etc/kubernetes/
6.3 創(chuàng)建service文件
# scp配置文件到每個master節(jié)點(diǎn)
$ scp target/<node-ip>/services/kube-controller-manager.service <user>@<node-ip>:/etc/systemd/system/
6.4 啟動服務(wù)
# 啟動服務(wù)
$ systemctl daemon-reload && systemctl enable kube-controller-manager && systemctl restart kube-controller-manager

# 檢查狀態(tài)
$ service kube-controller-manager status

# 查看日志
$ journalctl -f -u kube-controller-manager

# 查看leader
$ kubectl get endpoints kube-controller-manager --namespace=kube-system -o yaml

7. 部署scheduler(master節(jié)點(diǎn))

scheduler啟動后將通過競爭選舉機(jī)制產(chǎn)生一個 leader 節(jié)點(diǎn),其它節(jié)點(diǎn)為阻塞狀態(tài)。當(dāng) leader 節(jié)點(diǎn)不可用后,剩余節(jié)點(diǎn)將再次進(jìn)行選舉產(chǎn)生新的 leader 節(jié)點(diǎn),從而保證服務(wù)的可用性。

7.1 創(chuàng)建證書和私鑰

查看證書請求文件。

$ cd target/pki/scheduler
$ cat scheduler-csr.json 
{
    "CN": "system:kube-scheduler",
    "hosts": [
      "127.0.0.1",
      "172.18.0.100",
      "172.18.0.101",
      "172.18.0.102"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
      {
        "C": "CN",
        "ST": "BeiJing",
        "L": "BeiJing",
        "O": "system:kube-scheduler",
        "OU": "seven"
      }
    ]
}
  • hosts 列表包含所有 kube-scheduler 節(jié)點(diǎn) IP;
  • CN 和 O 均為 system:kube-scheduler,kubernetes 內(nèi)置的 ClusterRoleBindings system:kube-scheduler 將賦予 kube-scheduler 工作所需的權(quán)限;
# 生成證書、私鑰
$ cfssl gencert -ca=../ca.pem \
  -ca-key=../ca-key.pem \
  -config=../ca-config.json \
  -profile=kubernetes scheduler-csr.json | cfssljson -bare kube-scheduler

# 分發(fā)到每個master節(jié)點(diǎn)
$ scp kube-scheduler*.pem <user>@<node-ip>:/etc/kubernetes/pki/
7.2 創(chuàng)建scheduler的kubeconfig
# 創(chuàng)建kubeconfig
$ kubectl config set-cluster kubernetes \
  --certificate-authority=../ca.pem \
  --embed-certs=true \
  --server=https://<MASTER_VIP>:6443 \
  --kubeconfig=kube-scheduler.kubeconfig

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

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

$ kubectl config use-context system:kube-scheduler@kubernetes --kubeconfig=kube-scheduler.kubeconfig

# 分發(fā)kubeconfig
$ scp kube-scheduler.kubeconfig <user>@<node-ip>:/etc/kubernetes/
7.3 創(chuàng)建service文件
# scp配置文件到每個master節(jié)點(diǎn)
$ scp target/<node-ip>/services/kube-scheduler.service <user>@<node-ip>:/etc/systemd/system/
$ scp target/<node-ip>/configs/kube-scheduler.config.yaml <user>@<node-ip>:/etc/kubernetes/
7.4 啟動服務(wù)
# 啟動服務(wù)
$ systemctl daemon-reload && systemctl enable kube-scheduler && systemctl restart kube-scheduler

# 檢查狀態(tài)
$ service kube-scheduler status

# 查看日志
$ journalctl -f -u kube-scheduler

# 查看leader
$ kubectl get endpoints kube-scheduler --namespace=kube-system -o yaml

8. 部署kubelet(worker節(jié)點(diǎn))

8.1 創(chuàng)建bootstrap配置文件
# 創(chuàng)建 token
$ cd target/pki/admin
$ export BOOTSTRAP_TOKEN=$(kubeadm token create \
      --description kubelet-bootstrap-token \
      --groups system:bootstrappers:worker \
      --kubeconfig kube.config)

# 設(shè)置集群參數(shù)
$ kubectl config set-cluster kubernetes \
      --certificate-authority=../ca.pem \
      --embed-certs=true \
      --server=https://<MASTER_VIP>:6443 \
      --kubeconfig=kubelet-bootstrap.kubeconfig

# 設(shè)置客戶端認(rèn)證參數(shù)
$ kubectl config set-credentials kubelet-bootstrap \
      --token=${BOOTSTRAP_TOKEN} \
      --kubeconfig=kubelet-bootstrap.kubeconfig

# 設(shè)置上下文參數(shù)
$ kubectl config set-context kubelet@kubernetes \
      --cluster=kubernetes \
      --user=kubelet-bootstrap \
      --kubeconfig=kubelet-bootstrap.kubeconfig

# 設(shè)置默認(rèn)上下文
$ kubectl config use-context kubelet@kubernetes --kubeconfig=kubelet-bootstrap.kubeconfig

# 把生成的配置copy到每個worker節(jié)點(diǎn)上
$ scp kubelet-bootstrap.kubeconfig <user>@<node-ip>:/etc/kubernetes/kubelet-bootstrap.kubeconfig

# 把ca分發(fā)到每個worker節(jié)點(diǎn)
$ scp target/pki/ca.pem <user>@<node-ip>:/etc/kubernetes/pki/

# 查看生成的 token
$ kubeadm token list --kubeconfig ~/.kube/config
  • 向 kubeconfig 寫入的是 token,bootstrap 結(jié)束后 kube-controller-manager 為 kubelet 創(chuàng)建 client 和 server 證書;
  • token 有效期為 1 天,超期后將不能再被用來 boostrap kubelet,且會被 kube-controller-manager 的 tokencleaner 清理;
  • kube-apiserver 接收 kubelet 的 bootstrap token 后,將請求的 user 設(shè)置為 system:bootstrap:&lt;Token ID&gt;,group 設(shè)置為 system:bootstrappers,后續(xù)將為這個 group 設(shè)置 ClusterRoleBinding;
8.2 kubelet配置文件

把kubelet配置文件分發(fā)到每個worker節(jié)點(diǎn)上

$ scp target/worker-<node-ip>/kubelet.config.json <user>@<node-ip>:/etc/kubernetes/
cat kubelet.config.json 
{
  "kind": "KubeletConfiguration",
  "apiVersion": "kubelet.config.k8s.io/v1beta1",
  "authentication": {
    "x509": {
      "clientCAFile": "/etc/kubernetes/pki/ca.pem"
    },
    "webhook": {
      "enabled": true,
      "cacheTTL": "2m0s"
    },
    "anonymous": {
      "enabled": false
    }
  },
  "authorization": {
    "mode": "Webhook",
    "webhook": {
      "cacheAuthorizedTTL": "5m0s",
      "cacheUnauthorizedTTL": "30s"
    }
  },
  "address": "172.18.0.103",
  "staticPodPath": "",
  "port": 10250,
  "readOnlyPort": 10255,
  "cgroupDriver": "cgroupfs",
  "hairpinMode": "promiscuous-bridge",
  "serializeImagePulls": false,
  "featureGates": {
    "RotateKubeletClientCertificate": true,
    "RotateKubeletServerCertificate": true
  },
  "clusterDomain": "cluster.local.",
  "clusterDNS": ["10.96.0.2"]
}
  • authentication.anonymous.enabled:設(shè)置為 false,不允許匿名訪問 10250 端口;
  • authentication.x509.clientCAFile:指定簽名客戶端證書的 CA 證書,開啟 HTTPs 證書認(rèn)證;
  • authentication.webhook.enabled=true:開啟 HTTPs bearer token 認(rèn)證;

同時配置了如下授權(quán)參數(shù):

  • authroization.mode=Webhook:開啟 RBAC 授權(quán);

kubelet 收到請求后,使用 clientCAFile 對證書簽名進(jìn)行認(rèn)證,或者查詢 bearer token 是否有效。如果兩者都沒通過,則拒絕請求,提示 Unauthorized:

8.3 kubelet服務(wù)文件

把kubelet服務(wù)文件分發(fā)到每個worker節(jié)點(diǎn)上

$ scp target/worker-<node-ip>/kubelet.service <user>@<node-ip>:/etc/systemd/system/
8.4 啟動服務(wù)

kublet 啟動時查找配置的 --kubeletconfig 文件是否存在,如果不存在則使用 --bootstrap-kubeconfig 向 kube-apiserver 發(fā)送證書簽名請求 (CSR)。
kube-apiserver 收到 CSR 請求后,對其中的 Token 進(jìn)行認(rèn)證(事先使用 kubeadm 創(chuàng)建的 token),認(rèn)證通過后將請求的 user 設(shè)置為 system:bootstrap:,group 設(shè)置為 system:bootstrappers,這就是Bootstrap Token Auth。

# bootstrap附權(quán)
$ kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --group=system:bootstrappers

# 啟動服務(wù)
$ mkdir -p /var/lib/kubelet
$ mkdir -p /var/log/kubernetes
$ systemctl daemon-reload && systemctl enable kubelet && systemctl restart kubelet

# 在master上Approve bootstrap請求
$ kubectl get csr
$ kubectl certificate approve <name> 

# 查看服務(wù)狀態(tài)
$ service kubelet status

# 查看日志
$ journalctl -f -u kubelet
  • kubelet 啟動后使用 --bootstrap-kubeconfig 向 kube-apiserver 發(fā)送 CSR 請求,當(dāng)這個 CSR 被 approve 后,kube-controller-manager 為 kubelet 創(chuàng)建 TLS 客戶端證書、私鑰和 --kubeletconfig 文件。
  • 注意:kube-controller-manager 需要配置 --cluster-signing-cert-file 和 --cluster-signing-key-file 參數(shù),才會為 TLS Bootstrap 創(chuàng)建證書和私鑰。

9. 部署kube-proxy(worker節(jié)點(diǎn))

9.1 創(chuàng)建證書和私鑰

查看證書請求文件。

$ cd target/pki/proxy
cat kube-proxy-csr.json 
{
  "CN": "system:kube-proxy",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "seven"
    }
  ]
}
  • CN:指定該證書的 User 為 system:kube-proxy;
  • 預(yù)定義的 RoleBinding system:node-proxier 將User system:kube-proxy 與 Role system:node-proxier 綁定,該 Role 授予了調(diào)用 kube-apiserver Proxy 相關(guān) API 的權(quán)限;
  • 該證書只會被 kube-proxy 當(dāng)做 client 證書使用,所以 hosts 字段為空;
$ cfssl gencert -ca=../ca.pem \
  -ca-key=../ca-key.pem \
  -config=../ca-config.json \
  -profile=kubernetes  kube-proxy-csr.json | cfssljson -bare kube-proxy
9.2 創(chuàng)建和分發(fā) kubeconfig 文件
# 創(chuàng)建kube-proxy.kubeconfig
$ kubectl config set-cluster kubernetes \
  --certificate-authority=../ca.pem \
  --embed-certs=true \
  --server=https://<master-vip>:6443 \
  --kubeconfig=kube-proxy.kubeconfig

$ kubectl config set-credentials kube-proxy \
  --client-certificate=kube-proxy.pem \
  --client-key=kube-proxy-key.pem \
  --embed-certs=true \
  --kubeconfig=kube-proxy.kubeconfig

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

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

# 分發(fā)kube-proxy.kubeconfig 到 node 節(jié)點(diǎn)
$ scp kube-proxy.kubeconfig <user>@<node-ip>:/etc/kubernetes/
9.3 分發(fā)kube-proxy.config
$ scp target/worker-<node-ip>/kube-proxy.config.yaml <user>@<node-ip>:/etc/kubernetes/
9.4 分發(fā)kube-proxy服務(wù)文件
$ scp target/services/kube-proxy.service <user>@<node-ip>:/etc/systemd/system/
9.5 啟動服務(wù)
# 創(chuàng)建依賴目錄
$ mkdir -p /var/lib/kube-proxy

# 啟動服務(wù)
$ systemctl daemon-reload && systemctl enable kube-proxy && systemctl restart kube-proxy

# 查看狀態(tài)
$ service kube-proxy status

# 查看日志
$ journalctl -f -u kube-proxy

目前是 iptables 模式,使用 ipvs 模式可以修改文件 kube-proxy.config.yaml
我這里遇到的一個問題是 iptables 版本過低,如果遇到,可以編譯安裝使用新版本。

10. 部署CNI插件 - calico

我們使用calico官方的安裝方式來部署。

# 創(chuàng)建目錄(在配置了kubectl的節(jié)點(diǎn)上執(zhí)行)
$ mkdir -p /etc/kubernetes/addons

# 上傳calico配置到配置好kubectl的節(jié)點(diǎn)(一個節(jié)點(diǎn)即可)
$ scp target/addons/calico.yaml <user>@<node-ip>:/etc/kubernetes/addons/

# 部署calico
$ kubectl apply -f /etc/kubernetes/addons/calico.yaml

# 查看狀態(tài)
$ kubectl get pods -n kube-system

https://docs.projectcalico.org/v3.10/getting-started/kubernetes/

11. 部署DNS插件 - coredns

# 上傳配置文件
$ scp target/addons/coredns.yaml <user>@<node-ip>:/etc/kubernetes/addons/

# 部署coredns
$ kubectl apply -f /etc/kubernetes/addons/coredns.yaml

https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns/coredns/coredns.yaml.base

四、集群可用性測試

1. 創(chuàng)建nginx ds

 # 寫入配置
$ cat > nginx-ds.yml <<EOF
apiVersion: v1
kind: Service
metadata:
  name: nginx-ds
  labels:
    app: nginx-ds
spec:
  type: NodePort
  selector:
    app: nginx-ds
  ports:
  - name: http
    port: 80
    targetPort: 80
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-ds
  labels:
    addonmanager.kubernetes.io/mode: Reconcile
spec:
  template:
    metadata:
      labels:
        app: nginx-ds
    spec:
      containers:
      - name: my-nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
  selector:
    matchLabels:
      app: nginx-ds
EOF

# 創(chuàng)建ds
$ kubectl apply -f nginx-ds.yml

2. 檢查各種ip連通性

# 檢查各 Node 上的 Pod IP 連通性(主節(jié)點(diǎn)沒有calico所以不能訪問podip)
$ kubectl get pods -o wide

# 在每個worker節(jié)點(diǎn)上ping pod ip
$ ping <pod-ip>

# 檢查service可達(dá)性
$ kubectl get svc

# 在每個worker節(jié)點(diǎn)上訪問服務(wù)(主節(jié)點(diǎn)沒有proxy所以不能訪問service-ip)
$ curl <service-ip>:<port>

# 在每個節(jié)點(diǎn)檢查node-port可用性
$ curl <node-ip>:<port>

3. 檢查dns可用性

# 創(chuàng)建一個nginx pod
$ cat > pod-nginx.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.7.9
    ports:
    - containerPort: 80
EOF

# 創(chuàng)建pod
$ kubectl apply -f pod-nginx.yaml

# 進(jìn)入pod,查看dns
$ kubectl exec nginx -it -- /bin/bash

# 查看dns配置
root@nginx:/# cat /etc/resolv.conf

# 查看名字是否可以正確解析
root@nginx:/# ping nginx-ds
root@nginx:/# ping kubernetes

五. 部署dashboard

1. 部署dashboard

# 上傳dashboard配置
$ scp target/addons/dashboard-all.yaml <user>@<node-ip>:/etc/kubernetes/addons/

# 創(chuàng)建服務(wù)
$ kubectl apply -f /etc/kubernetes/addons/dashboard-all.yaml

# 查看服務(wù)運(yùn)行情況
$ kubectl get deployment kubernetes-dashboard -n kube-system
$ kubectl --namespace kube-system get pods -o wide
$ kubectl get services kubernetes-dashboard -n kube-system
$ netstat -ntlp|grep 8401

2. 訪問dashboard

為了集群安全,從 1.7 開始,dashboard 只允許通過 https訪問,我們使用nodeport的方式暴露服務(wù),可以使用 https://NodeIP:NodePort 地址訪問。

關(guān)于自定義證書

默認(rèn)dashboard的證書是自動生成的,肯定是非安全的證書,如果大家有域名和對應(yīng)的安全證書可以自己替換掉。使用安全的域名方式訪問dashboard。
在dashboard-all.yaml中增加dashboard啟動參數(shù),可以指定證書文件,其中證書文件是通過secret注進(jìn)來的。

--tls-cert-file=dashboard.cer --tls-key-file=dashboard.key

3. 登錄dashboard

Dashboard 默認(rèn)只支持 token 認(rèn)證,所以如果使用 KubeConfig 文件,需要在該文件中指定 token,我們這里使用token的方式登錄

# 創(chuàng)建service account
$ kubectl create sa dashboard-admin -n kube-system

# 創(chuàng)建角色綁定關(guān)系
$ kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin

# 查看dashboard-admin的secret名字
$ ADMIN_SECRET=$(kubectl get secrets -n kube-system | grep dashboard-admin | awk '{print $1}')

# 打印secret的token
$ kubectl describe secret -n kube-system ${ADMIN_SECRET} | grep -E '^token' | awk '{print $2}'

六、部署 metrics-server

metrics-server 通過 kube-apiserver 發(fā)現(xiàn)所有節(jié)點(diǎn),然后調(diào)用 kubelet APIs(通過 https 接口)獲得各節(jié)點(diǎn)(Node)和 Pod 的 CPU、Memory 等資源使用情況。

從 Kubernetes 1.12 開始,kubernetes 的安裝腳本移除了 Heapster,從 1.13 開始完全移除了對 Heapster 的支持,Heapster 不再被維護(hù)。

1. 安裝 metrics-server

$ cd target/addons
$ git clone https://github.com/kubernetes-incubator/metrics-server.git
$ cd metrics-server/deploy/1.8+/

修改metrics-server-deployment.yaml文件,把 metrics-server 修改為如下命令行參數(shù):

      containers:
      - name: metrics-server
        image: wangzan18/metrics-server-amd64:v0.3.6
        args:
          - --cert-dir=/tmp
          - --secure-port=4443
          - --metric-resolution=30s
          - --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP
  • --metric-resolution=30s:從 kubelet 采集數(shù)據(jù)的周期;
  • --kubelet-preferred-address-types:優(yōu)先使用 InternalIP 來訪問 kubelet,這樣可以避免節(jié)點(diǎn)名稱沒有 DNS 解析記錄時,通過節(jié)點(diǎn)名稱調(diào)用節(jié)點(diǎn) kubelet API 失敗的情況(未配置時默認(rèn)的情況);

2. 部署

$ cd target/addons/metrics-server/deploy/1.8+/
$ kubectl apply -f .

參考文檔:https://k8s-install.opsnull.com/

歡迎大家掃碼關(guān)注,獲取更多信息

使用二進(jìn)制的方式部署 K8S-1.16 高可用集群(二十)

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI