这篇文章开始介绍二进制建立 Kubernetes v1.20,由于内容过多,分三篇介绍。

现在Kubernetes最新版别是v1.24,但大部分公司一般不会运用最新版别,而是老版别中的v1.15,或者新版别的v1.18、v1.20,其间v1.16改变了许多API接口版别。

单master集群架构图

二进制搭建Kubernetes集群(上)——部署etcd集群和单master

试验环境

生产环境中,etcd集群和master、node节点都应该布置在不同的机器上,此处为了试验便利,将三台etcd节点别离布置在了master和node节点上了。

k8s集群master

  • k8s集群master01:192.168.44.20、需准备kube-apiserver、kube-controller-manager、kube-scheduler etcd
  • k8s集群master02:192.168.44.50

k8s集群node

  • k8s集群node01:192.168.44.30、需准备kubelet、kube-proxy、docker
  • k8s集群node02:192.168.44.40

etcd集群节点

  • etcd集群节点1:192.168.44.20、需准备etcd
  • etcd集群节点2:192.168.44.30
  • etcd集群节点3:192.168.44.40

负载均衡nginx+keepalive

  • 负载均衡nginx+keepalive01(master):192.168.44.100
  • 负载均衡nginx+keepalive02(backup):192.168.44.150

操作体系初始化装备

一切节点都操作

#封闭防火墙,铲除防火墙规矩
systemctl stop firewalld
systemctl disable firewalld
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
#-X能够铲除一些自定义的链表规矩
#封闭selinux
setenforce 0
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
#--------修正/etc/hosts文件------
#增加主机名和IP的映射关系
 cat >> /etc/hosts << EOF
 192.168.44.20 master01
 192.168.44.30 node01
 192.168.44.40 node02
 EOF
#-----------调整内核参数--------------
cat > /etc/sysctl.d/k8s.conf << EOF
#敞开网桥方式,可将网桥的流量传递给iptables链
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
#封闭ipv6协议
net.ipv6.conf.all.disable_ipv6=1
 net.ipv4.ip_forward=1
 EOF
#敞开路由转发功用
sysctl --system  #加载体系的内核参数
#-----------时刻同步-------------------
yum install ntpdate -y
ntpdate ntp.aliyun.com
#将时刻同步加入计划性使命,每30分钟履行一次
crontab -e
*/30 * * * * /usr/sbin/ntpdate ntp.aliyun.com

封闭防火墙

二进制搭建Kubernetes集群(上)——部署etcd集群和单master

封闭selinux

二进制搭建Kubernetes集群(上)——部署etcd集群和单master

封闭swap

二进制搭建Kubernetes集群(上)——部署etcd集群和单master

依据规划设置主机名

二进制搭建Kubernetes集群(上)——部署etcd集群和单master
二进制搭建Kubernetes集群(上)——部署etcd集群和单master
二进制搭建Kubernetes集群(上)——部署etcd集群和单master

在master增加hosts

二进制搭建Kubernetes集群(上)——部署etcd集群和单master

调整内核参数

二进制搭建Kubernetes集群(上)——部署etcd集群和单master
二进制搭建Kubernetes集群(上)——部署etcd集群和单master

时刻同步

二进制搭建Kubernetes集群(上)——部署etcd集群和单master

将时刻同步加入计划性使命

二进制搭建Kubernetes集群(上)——部署etcd集群和单master

布置 docker 集群

一切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 docker-ce-cli containerd.io

二进制搭建Kubernetes集群(上)——部署etcd集群和单master
二进制搭建Kubernetes集群(上)——部署etcd集群和单master
二进制搭建Kubernetes集群(上)——部署etcd集群和单master
二进制搭建Kubernetes集群(上)——部署etcd集群和单master

布置 etcd 集群

etcd内 部选用raft协议作为共同性算法,etcd是go言语编写的。

etcd作为服务发现体系,有以下的特色:

  • 简略:装置装备简略,而且供给了HTTP API进行交互,运用也很简略。
  • 安全:支持SSL证书验证。
  • 快速:单实例支持每秒2k+读操作。
  • 可靠:选用raft算法,实现分布式体系数据的可用性和共同性。

etcd现在默许运用2379端口供给HTTP API服务,2380端口和peer通讯(这两个端口已经被IANA(互联网数字分配组织)官方预留给etcd)。

即etcd默许运用2379端口对外为客户端供给通讯,运用端口2380来进行服务器间内部通讯。 (etcd和api-server通讯运用2379端口,etcd之间运用2380通讯)

etcd在生产环境中一般推荐集群方式布置。由于etcd的leader推举机制,要求至少为3台或以上的奇数台。

准备签发证书环境

CFSSL是CloudFlare公司开源的一款PKI/TLS 东西。CFSSL包含一个指令行东西和一个用于签名、验证和绑缚TLS证书的HTTP API服务。运用Go言语编写。

CFSSL运用装备文件生成证书,因而自签之前,需求生成它识别的json 格局的装备文件,CFSSL 供给了便利的指令行生成装备文件。

CFSSL用来为etcd供给TLS证书,它支持签三种类型的证书:

  1. client证书,服务端衔接客户端时带着的证书,用于客户端验证服务端身份,如kubeapiserver 拜访etcd;
  2. server证书,客户端衔接服务端时带着的证书,用于服务端验证客户端身份,如etcd对外供给服务;
  3. peer证书,相互之间衔接时运用的证书,如etcd节点之间进行验证和通讯。

这儿全部都运用同一套证书认证。

在 master01 节点上操作

#-----------------------准备cfssl证书生成东西----------
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
#-O:指定下载目录
#Linux指令行两种下载方式:
#wget 源URL地址 [-O 下载到指定途径]
#curl 源URL地址 [-o 下载到指定途径]
chmod +x /usr/local/bin/cfssl*
--------------------- 虚线内注释 ------------------------------------------------
cfssl:证书签发的东西指令。
cfssljson:将cfssl生成的证书(json格局)变为文件承载式证书。
cfssl-certinfo:验证证书的信息。
cfssl-certinfo -cert <证书称号>  #查看证书的信息
-------------------------------------------------------------------------------
#------------------------生成Etcd证书-----------------------
#k8s目录用于寄存生成证书的脚本文件
mkdir /opt/k8s/
cd /opt/k8s/
#上传 etcd-cert.sh 和 etcd.sh 到 /opt/k8s/ 目录中,为两个文件增加履行权限
chmod +x etcd-cert.sh etcd.sh
#创立用于生成CA证书、etcd 服务器证书以及私钥的目录
mkdir /opt/k8s/etcd-cert/
mv etcd-cert.sh etcd-cert/  #将etcd-cert.sh移动到该目录
cd /opt/k8s/etcd-cert/  #切换到该目录
./etcd-cert.sh    #运转脚本生成CA证书、etcd 服务器证书以及私钥
#查看etcd-cert目录,以.json和.csr结束的文件都是恳求生成证书的文件,以pem结束的文件都是终究生成的证书文件。
ls         
ca-config.json  ca-csr.json  ca.pem     server.csr    server-key.pem
ca.csr      ca-key.pem  etcd-cert.sh  server-csr.json  server.pem
#上传 etcd-v3.4.9-linux-amd64.tar.gz 到 /opt/k8s/ 目录中,发动etcd服务
#下载地址https://github.com/etcd-io/etcd/releases/download/v3.4.9/etcd-v3.4.9-1inux-amd64.tar.gz
cd /opt/k8s/
tar zxvf etcd-v3.4.9-linux-amd64.tar.gz
#查看装置包解压后的目录,该目录包含了etcd的发动文件etcd和etcd的办理文件etcdctl
cd /opt/k8s/etcd-v3.4.9-linux-amd64/
ls
--------------------------------------------------------------------------------
etcd:便是etcd服务的发动指令,后边可跟各种发动参数
etcdctl:主要为etcd服务供给了指令行操作
--------------------------------------------------------------------------------
#创立/opt/etcd目录,并创立三个子目录cfg、bin、ssl。cfg用于寄存装备文件,bin用于寄存履行文件,ssl用于寄存证书文件
mkdir -p /opt/etcd/{cfg,bin,ssl}
#将etcd和etcdctl两个文件移动到/opt/etcd/bin目录
mv etcd etcdctl /opt/etcd/bin/
#将证书文件仿制到etcd01节点的/opt/etcd/ssl/目录
cp /opt/k8s/etcd-cert/*.pem /opt/etcd/ssl/
cd /opt/k8s/
#运转脚本,会卡在前台
./etcd.sh etcd01 192.168.44.20 etcd02=https://192.168.44.30:2380,etcd03=https://192.168.44.40:2380
#另开一台终端,查看进程信息
ps -ef | grep etcd
#将etcd目录中的一切文件发送给etcd02和etcd03节点
scp -r /opt/etcd/ root@192.168.41.42:/opt/
scp -r /opt/etcd/ root@192.168.41.43:/opt/
#传输etcd的体系服务办理文件
scp /usr/lib/systemd/system/etcd.service root@192.168.41.42:/usr/lib/systemd/system/
scp /usr/lib/systemd/system/etcd.service root@192.168.41.43:/usr/lib/systemd/system/

在 etcd02 和 etcd03 节点上操作

#-------------1、在 etcd02 节点上操作(30主机)------------------
vim /opt/etcd/cfg/etcd
#[Member]
ETCD_NAME="etcd02"                                          #修正
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.44.30:2380"          #修正
ETCD_LISTEN_CLIENT_URLS="https://192.168.44.30:2379"        #修正
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.44.30:2380"     #修正
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.44.30:2379"           #修正
ETCD_INITIAL_CLUSTER="etcd01=https://192.168.44.20:2380,etcd02=https://192.168.44.30:2380,etcd03=https://192.168.44.40:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
systemctl start etcd
systemctl enable etcd
systemctl status etcd
#-----------2、在 etcd03 节点上操作(40主机)-----------------------
vim /opt/etcd/cfg/etcd
#[Member]
ETCD_NAME="etcd03"                                          #修正
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.44.40:2380"          #修正
ETCD_LISTEN_CLIENT_URLS="https://192.168.44.40:2379"        #修正
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.44.40:2380"     #修正
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.44.40:2379"           #修正
ETCD_INITIAL_CLUSTER="etcd01=https://192.168.44.20:2380,etcd02=https://192.168.44.30:2380,etcd03=https://192.168.44.40:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
systemctl start etcd
systemctl enable etcd
systemctl status etcd
#-------------3、查看etcd群集状况-------------------------------
#三个etcd节点都可用查看
#切换到/opt/etcd/ssl目录,证书可运用相对途径。假如不在该目录下,证书要运用绝对途径。
#查看etcd集群每个节点的健康状况,true表明健康
ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.44.20:2379,https://192.168.44.30:2379,https://192.168.44.40:2379" endpoint health --write-out=table
#查看etcd集群成员列表
ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.44.20:2379,https://192.168.44.30:2379,https://192.168.44.40:2379" --write-out=table member list
#查看etcd集群中哪个节点是leader,true表明leader
ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.44.20:2379,https://192.168.44.30:2379,https://192.168.44.40:2379" endpoint status --write-out=table
 #------------------注释---------------------------------------
--cert-file:识别HTTPS端运用SSL证书文件
--key-file:运用此SSL密钥文件标识HTTPS客户端
--ca-file:运用此CA证书验证启用https的服务器的证书
--endpoints:集群中以逗号分隔的机器地址列表
cluster-health:查看etcd集群的运转状况
#-------------------------------------------------------------

#由于是经过客户端的方式进行拜访,所以用2379端口,查看每个节点的状况

附录1:etcd-cert.sh

#!/bin/bash
#装备证书生成战略,让 CA 软件知道颁发有什么功用的证书,生成用来签发其他组件证书的根证书
cat > ca-config.json <<EOF
{
 "signing": {
  "default": {
   "expiry": "87600h"
   },
  "profiles": {
   "www": {
     "expiry": "87600h",
     "usages": [
      "signing",
      "key encipherment",
      "server auth",
      "client auth"
     ]
    }
   }
  }
}
EOF
#ca-config.json:能够定义多个 profiles,别离指定不同的过期时刻、运用场景等
参数;
#后续在签名证书时会运用某个 profile;此实例只要一个 www 模板。
#expiry:指定了证书的有效期,87600h 为10年,假如用默许值一年的话,证书到期
后集群会当即宕掉
#signing:表明该证书可用于签名其它证书;生成的 ca.pem 证书中 CA=TRUE;
#key encipherment:表明运用非对称密钥加密,如 RSA 加密;
#key encipherment:表明运用非对称密钥加密,如 RSA 加密;
#server auth:表明client能够用该 CA 对 server 供给的证书进行验证;
#client auth:表明server能够用该 CA 对 client 供给的证书进行验证;
#留意标点符号,最终一个字段一般是没有逗号的。
#-----------------------
#生成CA证书和私钥(根证书和私钥)
#特别说明: cfssl和openssl有一些区别,openssl需求先生成私钥,然后用私钥生>成恳求文件,最终生成签名的证书和私钥等,可是cfssl能够直接得到恳求文件。
cat > ca-csr.json <<EOF
{
  "CN": "etcd",
  "key": {
    "algo": "rsa",
    "size": 2048
   },
  "names": [
     {
      "C": "CN",
      "L": "Beijing",
      "ST": "Beijing"
     }
   ]
}
EOF
#CN:Common Name,浏览器运用该字段验证网站或组织是否合法,一般写的是域名
#key:指定了加密算法,一般运用rsa(size:2048)
#C:Country,国家
#ST:State,州,省
#L:Locality,区域,城市
#O: Organization Name,安排称号,公司称号
#OU: Organization Unit Name,安排单位称号,公司部门
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
#生成的文件:
#ca-key.pem:根证书私钥
#ca.pem:根证书
#ca.csr:根证书签发恳求文件
#cfssl gencert -initca <CSRJSON>:运用 CSRJSON 文件生成生成新的证书和私钥>。假如不增加管道符号,会直接把一切证书内容输出到屏幕。
#留意:CSRJSON 文件用的是相对途径,所以 cfssl 的时候需求 csr 文件的途径下>履行,也能够指定为绝对途径。
#cfssljson 将 cfssl 生成的证书(json格局)变为文件承载式证书,-bare 用于命名生成的证书文件。

#-----------------------
#生成 etcd 服务器证书和私钥
cat > server-csr.json <<EOF
{
  "CN": "etcd",
  "hosts": [
  "192.168.44.20",
  "192.168.44.30",
  "192.168.44.40"
   ],
  "key": {
    "algo": "rsa",
    "size": 2048
   },
  "names": [
     {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing"
     }
   ]
}
EOF
#hosts:将一切 etcd 集群节点增加到 host 列表,需求指定一切 etcd 集群的节点ip 或主机名不能运用网段,新增 etcd 服务器需求从头签发证书。
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server
#生成的文件:
#server.csr:服务器的证书恳求文件
#server-key.pem:服务器的私钥
#server.pem:服务器的数字签名证书
#-config:引用证书生成战略文件 ca-config.json
#-profile:指定证书生成战略文件中的的运用场景,比方 ca-config.json 中的 www

附录2:etcd.sh

#!/bin/bash
#example: ./etcd.sh etcd01 192.168.44.20 etcd02=https://192.168.44.30:2380,etcd03=https://192.168.44.40:2380
#创立etcd装备文件/opt/etcd/cfg/etcd
ETCD_NAME=$1
ETCD_IP=$2
ETCD_CLUSTER=$3
WORK_DIR=/opt/etcd
cat > $WORK_DIR/cfg/etcd  <<EOF
#[Member]
ETCD_NAME="${ETCD_NAME}"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://${ETCD_IP}:2380"
ETCD_LISTEN_CLIENT_URLS="https://${ETCD_IP}:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://${ETCD_IP}:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://${ETCD_IP}:2379"
ETCD_INITIAL_CLUSTER="etcd01=https://${ETCD_IP}:2380,${ETCD_CLUSTER}"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF
#Member:成员装备
#ETCD_NAME:节点称号,集群中唯一。成员名字,集群中有必要具有唯一性,如etcd01
#ETCD_DATA_DIR:数据目录。指定节点的数据存储目录,这些数据包含节点ID,集群ID,集群初始化装备,Snapshot文件,若未指定-wal-dir,还会存储WAL文件;假如不指定会用缺省目录
#ETCD_LISTEN_PEER_URLS:集群通讯监听地址。用于监听其他member发送信息的地址。ip为全0代表监听本机一切接口
#ETCD_LISTEN_CLIENT_URLS:客户端拜访监听地址。用于监听etcd客户发送信息的地址。ip为全0代表监听本机一切接口
#Clustering:集群装备
#ETCD_INITIAL_ADVERTISE_PEER_URLS:集群布告地址。其他member运用,其他member经过该地址与本member交互>信息。一定要确保从其他member能可拜访该地址。静态装备方式下,该参数的value一定要一起在--initial-cluster参数中存在
#ETCD_ADVERTISE_CLIENT_URLS:客户端布告地址。etcd客户端运用,客户端经过该地址与本member交互信息。一>定要确保从客户侧能可拜访该地址
#ETCD_INITIAL_CLUSTER:集群节点地址。本member运用。描述集群中一切节点的信息,本member依据此信息去联>系其他member
#ETCD_INITIAL_CLUSTER_TOKEN:集群Token。用于区别不同集群。本地如有多个集群要设为不同
#ETCD_INITIAL_CLUSTER_STATE:加入集群的当时状况,new是新集群,existing表明加入已有集群。
#创立etcd.service服务办理文件
cat > /usr/lib/systemd/system/etcd.service <<EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
EnvironmentFile=${WORK_DIR}/cfg/etcd
ExecStart=${WORK_DIR}/bin/etcd \
--cert-file=${WORK_DIR}/ssl/server.pem \
--key-file=${WORK_DIR}/ssl/server-key.pem \
--trusted-ca-file=${WORK_DIR}/ssl/ca.pem \
--peer-cert-file=${WORK_DIR}/ssl/server.pem \
--peer-key-file=${WORK_DIR}/ssl/server-key.pem \
--peer-trusted-ca-file=${WORK_DIR}/ssl/ca.pem \
--logger=zap \
--enable-v2
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
#--enable-v2:敞开 etcd v2 API 接口。当时 flannel 版别不支持 etcd v3 通讯
#--logger=zap:运用 zap 日志结构。zap.Logger 是go言语中相对日志库中性能最高的
#--peer开头的装备项用于指定集群内部TLS相关证书(peer 证书),这儿全部都运用同一套证书认证
#不带--peer开头的的参数是指定 etcd 服务器TLS相关证书(server 证书),这儿全部都运用同一套证书认证
systemctl daemon-reload
systemctl enable etcd
systemctl restart etcd

布置 Master 组件

master01:192.168.44.20

#在 master01 节点上操作,由于master01和etcd01布置在同一台机器上,所以/opt/k8s/目录已存在。
#上传 master.zip 和 k8s-cert.sh 到 /opt/k8s 目录中,解压 master.zip 压缩包
cd /opt/k8s/
unzip master.zip
chmod +x *.sh  #为一切脚本文件加上履行权限
#创立kubernetes作业目录
mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}
#创立用于生成CA证书、相关组件的证书和私钥的目录
mkdir /opt/k8s/k8s-cert/
mv /opt/k8s/k8s-cert.sh /opt/k8s/k8s-cert/  #将k8s-cert.sh脚本移动到该目录
cd /opt/k8s/k8s-cert/             #切换到该目录
./k8s-cert.sh  #运转脚本,生成CA证书、相关组件的证书和私钥
#查看生成的证书文件
ls *pem
admin-key.pem  apiserver-key.pem  ca-key.pem  kube-proxy-key.pem 
admin.pem    apiserver.pem    ca.pem    kube-proxy.pem
#仿制CA证书、apiserver相关证书和私钥到kubernetes作业目录的ssl子目录中
cp ca*pem apiserver*pem /opt/kubernetes/ssl/
#上传 kubernetes-server-linux-amd64.tar.gz 到 /opt/k8s/ 目录中,解压 kubernetes 压缩包。
#下载地址: https://github.com/kubernetes/kubernetes/blob/release-1.20/CHANGELOG/CHANGELOG-1.20.nd
#注:翻开链接你会发现里面有许多包,下载一个server包就够了,包含了Master和Worker Node二进制文件。
cd /opt/k8s/
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 给他授权
cd /opt/k8s/
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"
EOF
chmod +x token.sh  #为脚本增加履行权限
./token.sh      #运转脚本   
cat /opt/kubernetes/cfg/token.csv
#二进制文件、token、证书都准备好后,敞开apiserver服务,和etcd进行对接。
cd /opt/k8s/
#脚本后边跟master01的IP,以及etcd集群的地址和端口
./apiserver.sh 192.168.44.20 https://192.168.44.20:2379,https://192.168.44.30:2379,https://192.168.44.40:2379
#查看进程是否发动成功
ps aux | grep kube-apiserver
netstat -natp | grep 6443  #安全端口6443用于接收HTTPS恳求,用于基于Token文件或客户端证书等认证
#发动 scheduler 服务
./scheduler.sh
ps aux | grep kube-scheduler
#发动 controller-manager 服务
./controller-manager.sh
ps aux | grep kube-controller-manager
#生成kubectl衔接集群的kubeconfig文件,即令kubectl对接apiserver
./admin.sh

#绑定默许cluster-admin办理员集群角色,授权kubectl拜访集群
kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous
#经过kubectl东西查看当时集群组件状况
kubectl get cs
NAME         STATUS   MESSAGE       ERROR
controller-manager  Healthy  ok         
scheduler       Healthy  ok         
etcd-2        Healthy  {"health":"true"}  
etcd-1        Healthy  {"health":"true"}  
etcd-0        Healthy  {"health":"true"} 
#查看版别信息
kubectl version

附录1:k8s-cert.sh脚本

#!/bin/bash
#装备证书生成战略,让 CA 软件知道颁发有什么功用的证书,生成用来签发其他组件证书的根证书
cat > ca-config.json <<EOF
{
 "signing": {
  "default": {
   "expiry": "87600h"
   },
  "profiles": {
   "kubernetes": {
     "expiry": "87600h",
     "usages": [
      "signing",
      "key encipherment",
      "server auth",
      "client auth"
     ]
    }
   }
  }
}
EOF
#生成CA证书和私钥(根证书和私钥)
cat > ca-csr.json <<EOF
{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
   },
  "names": [
     {
      "C": "CN",
      "L": "Beijing",
      "ST": "Beijing",
      "O": "k8s",
      "OU": "System"
     }
   ]
}
EOF
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
#-----------------------
#生成 apiserver 的证书和私钥(apiserver和其它k8s组件通讯运用)
#hosts中将一切或许作为 apiserver 的 ip 增加进去,后边 keepalived 运用的VIP 也要加入
cat > apiserver-csr.json <<EOF
{
  "CN": "kubernetes",
  "hosts": [
   "10.0.0.1",
   "127.0.0.1",
   "192.168.44.20",
       #master01。运用脚本时,要将这5行注释删去
   "192.168.44.50",
       #master02
   "192.168.44.200",
       #vip,后边keepalived要用到
   "192.168.44.100",
       #负载均衡器01(master)
   "192.168.44.150",
       #负载均衡器02(backup)
   "kubernetes",
   "kubernetes.default",
   "kubernetes.default.svc",
   "kubernetes.default.svc.cluster",
   "kubernetes.default.svc.cluster.local"
   ],
  "key": {
    "algo": "rsa",
    "size": 2048
   },
  "key": {
    "algo": "rsa",
    "size": 2048
   },
  "names": [
     {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing",
      "O": "k8s",
      "OU": "System"
     }
   ]
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes apiserver-csr.json | cfssljson -bare apiserver
#-----------------------
#生成 kubectl 衔接集群的证书和私钥,具有admin权限
cat > admin-csr.json <<EOF
{
 "CN": "admin",
 "hosts": [],
 "key": {
  "algo": "rsa",
  "size": 2048
  },
 "names": [
   {
   "C": "CN",
   "L": "BeiJing",
   "ST": "BeiJing",
   "O": "system:masters",
   "OU": "System"
   }
  ]
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin

#-----------------------
#生成 kube-proxy 的证书和私钥
cat > kube-proxy-csr.json <<EOF
{
 "CN": "system:kube-proxy",
 "hosts": [],
 "key": {
  "algo": "rsa",
  "size": 2048
  },
 "names": [
   {
   "C": "CN",
   "L": "BeiJing",
   "ST": "BeiJing",
   "O": "k8s",
   "OU": "System"
   }
  ]
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy

附录2:apiserver.sh

#!/bin/bash
#example: apiserver.sh 192.168.44.20 https://192.168.44.20:2379,https://192.168.44.30:2379,https://192.168.44.40:2379
#创立 kube-apiserver 发动参数装备文件
MASTER_ADDRESS=$1
ETCD_SERVERS=$2
cat >/opt/kubernetes/cfg/kube-apiserver <<EOF
KUBE_APISERVER_OPTS="--logtostderr=false  \
--v=2 \
--log-dir=/opt/kubernetes/logs \
--etcd-servers=${ETCD_SERVERS} \
--bind-address=${MASTER_ADDRESS} \
--secure-port=6443 \
--advertise-address=${MASTER_ADDRESS} \
--allow-privileged=true \
--service-cluster-ip-range=10.0.0.0/24 \
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \
--authorization-mode=RBAC,Node \
--enable-bootstrap-token-auth=true \
--token-auth-file=/opt/kubernetes/cfg/token.csv \
--service-node-port-range=30000-50000 \
--kubelet-client-certificate=/opt/kubernetes/ssl/apiserver.pem \
--kubelet-client-key=/opt/kubernetes/ssl/apiserver-key.pem \
--tls-cert-file=/opt/kubernetes/ssl/apiserver.pem  \
--tls-private-key-file=/opt/kubernetes/ssl/apiserver-key.pem \
--client-ca-file=/opt/kubernetes/ssl/ca.pem \
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \
--service-account-issuer=api \
--service-account-signing-key-file=/opt/kubernetes/ssl/apiserver-key.pem \
--etcd-cafile=/opt/k8s/etcd-cert/ca.pem \
--etcd-certfile=/opt/k8s/etcd-cert/server.pem \
--etcd-keyfile=/opt/k8s/etcd-cert/server-key.pem \
--requestheader-client-ca-file=/opt/kubernetes/ssl/ca.pem \
--proxy-client-cert-file=/opt/kubernetes/ssl/apiserver.pem \
--proxy-client-key-file=/opt/kubernetes/ssl/apiserver-key.pem \
--requestheader-allowed-names=kubernetes \
--requestheader-extra-headers-prefix=X-Remote-Extra- \
--requestheader-group-headers=X-Remote-Group \
--requestheader-username-headers=X-Remote-User \
--enable-aggregator-routing=true \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/opt/kubernetes/logs/k8s-audit.log"
EOF
#--logtostderr=true:启用日志。输出日志到规范错误操控台,不输出到文件
#--v=4:日志等级。指定输出日志的等级,v=4为调试等级详细输出
#--etcd-servers:etcd集群地址。指定etcd服务器列表(格局://ip:port),逗号分隔
#--bind-address:监听地址。指定 HTTPS 安全接口的监听地址,默许值0.0.0.0
#--secure-port:https安全端口。指定 HTTPS 安全接口的监听端口,默许值6443
#--advertise-address:集群布告地址。经过该 ip 地址向集群其他节点发布 api server 的信息,有必要能够被其他节点拜访
#--allow-privileged=true:启用授权。允许拥有体系特权的容器运转,默许值false
#--service-cluster-ip-range:Service虚拟IP地址段。指定 Service Cluster IP 地址段
#--enable-admission-plugins:准入操控模块。kuberneres集群的准入操控机制,各操控模块以>插件的方式顺次收效,集群时有必要包含ServiceAccount,运转在认证(Authentication)、授权(Authorization)之后,Admission Control是权限认证链上的最终一环, 对恳求API资源对象进行修正和校验
#--authorization-mode:认证授权,启用RBAC授权和节点自办理。在安全端口运用RBAC,Node授权方式,未经过授权的恳求拒绝,默许值AlwaysAllow。RBAC是用户经过角色与权限进行相关的方式>;Node方式(节点授权)是一种特别用处的授权方式,专门授权由kubelet发出的API恳求,在进行认证时,先经过用户名、用户分组验证是否是集群中的Node节点,只要是Node节点的恳求才干运用Node方式授权
#--enable-bootstrap-token-auth:启用TLS bootstrap机制。在apiserver上启用Bootstrap Token 认证
#--token-auth-file=/opt/kubernetes/cfg/token.csv:指定bootstrap token认证文件途径
#--service-node-port-range:指定 Service  NodePort 的端口范围,默许值30000-32767
#–-kubelet-client-xxx:apiserver拜访kubelet客户端证书
#--tls-xxx-file:apiserver https证书
#1.20版别有必要加的参数:–-service-account-issuer,–-service-account-signing-key-file
#--etcd-xxxfile:衔接Etcd集群证书
#–-audit-log-xxx:审计日志
#发动聚合层相关装备:–requestheader-client-ca-file,–proxy-client-cert-file,–proxy-client-key-file,–requestheader-allowed-names,–requestheader-extra-headers-prefix,–requestheader-group-headers,–requestheader-username-headers,–enable-aggregator-routing
#创立 kube-apiserver.service 服务办理文件
cat >/usr/lib/systemd/system/kube-apiserver.service <<EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=-/opt/kubernetes/cfg/kube-apiserver
ExecStart=/opt/kubernetes/bin/kube-apiserver $KUBE_APISERVER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable kube-apiserver
systemctl restart kube-apiserver

附录3:scheduler.sh

#!/bin/bash
##创立 kube-scheduler 发动参数装备文件
MASTER_ADDRESS=$1
cat >/opt/kubernetes/cfg/kube-scheduler <<EOF
KUBE_SCHEDULER_OPTS="--logtostderr=false \
--v=2 \
--log-dir=/opt/kubernetes/logs \
--leader-elect=true \
--kubeconfig=/opt/kubernetes/cfg/kube-scheduler.kubeconfig \
--bind-address=127.0.0.1"
EOF
#-–kubeconfig:衔接 apiserver 用的装备文件,用于识别 k8s 集群
#--leader-elect=true:当该组件发动多个时,主动发动 leader 推举
#k8s中Controller-Manager和Scheduler的选主逻辑:k8s中的etcd是整个集群一切状况信>息的存储,触及数据的读写和多个etcd之间数据的同步,对数据的共同性要求严格,所以>运用较杂乱的 raft 算法来挑选用于提交数据的主节点。而 apiserver 作为集群进口,本身是无状况的web服务器,多个 apiserver 服务之间直接负载恳求并不需求做选主。Controller-Manager 和 Scheduler 作为使命类型的组件,比方 controller-manager 内置的 k8s 各种资源对象的操控器实时的 watch apiserver 获取对象最新的变化事情做期望状况>和实践状况调整,调度器watch未绑定节点的pod做节点挑选,明显多个这些使命一起作业>是彻底没有必要的,所以 controller-manager 和 scheduler 也是需求选主的,可是选主逻辑和 etcd 不一样的,这儿只需求确保从多个 controller-manager 和 scheduler 之间选出一个 leader 进入作业状况即可,而无需考虑它们之间的数据共同和同步。
##生成kube-scheduler证书
cd /opt/k8s/k8s-cert/
#创立证书恳求文件
cat > kube-scheduler-csr.json << EOF
{
 "CN": "system:kube-scheduler",
 "hosts": [],
 "key": {
  "algo": "rsa",
  "size": 2048
  },
 "names": [
   {
   "C": "CN",
   "L": "BeiJing",
   "ST": "BeiJing",
   "O": "system:masters",
   "OU": "System"
   }
  ]
}
EOF
#生成证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler
#生成kubeconfig文件
KUBE_CONFIG="/opt/kubernetes/cfg/kube-scheduler.kubeconfig"
KUBE_APISERVER="https://192.168.44.20:6443"  #master01的IP
kubectl config set-cluster kubernetes \
 --certificate-authority=/opt/kubernetes/ssl/ca.pem \
 --embed-certs=true \
 --server=${KUBE_APISERVER} \
 --kubeconfig=${KUBE_CONFIG}
kubectl config set-credentials kube-scheduler \
 --client-certificate=./kube-scheduler.pem \
 --client-key=./kube-scheduler-key.pem \
 --embed-certs=true \
 --kubeconfig=${KUBE_CONFIG}
kubectl config set-context default \
 --cluster=kubernetes \
 --user=kube-scheduler \
 --kubeconfig=${KUBE_CONFIG}
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
##创立 kube-scheduler.service 服务办理文件
cat >/usr/lib/systemd/system/kube-scheduler.service <<EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=-/opt/kubernetes/cfg/kube-scheduler
ExecStart=/opt/kubernetes/bin/kube-scheduler $KUBE_SCHEDULER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable kube-scheduler
systemctl restart kube-scheduler

附录4:controller-manager.sh

#!/bin/bash
##创立 kube-controller-manager 发动参数装备文件
MASTER_ADDRESS=$1
cat >/opt/kubernetes/cfg/kube-controller-manager <<EOF
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \
--v=2 \
--log-dir=/opt/kubernetes/logs \
--leader-elect=true \
--kubeconfig=/opt/kubernetes/cfg/kube-controller-manager.kubeconfig \
--bind-address=127.0.0.1 \
--allocate-node-cidrs=true \
--cluster-cidr=10.244.0.0/16 \
--service-cluster-ip-range=10.0.0.0/24 \
--cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \
--cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem  \
--root-ca-file=/opt/kubernetes/ssl/ca.pem \
--service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \
--cluster-signing-duration=87600h0m0s"
EOF
#––leader-elect:当该组件发动多个时,主动推举(HA)
#-–kubeconfig:衔接 apiserver 用的装备文件,用于识别 k8s 集群
#--cluster-cidr=10.244.0.0/16:pod资源的网段,需与pod网络插件的值设置共同。一般,Flannel网络插件的默许为10.244.0.0/16,Calico插件的默许值为192.168.0.0/16
#--cluster-signing-cert-file/–-cluster-signing-key-file:主动为kubelet颁发证书>的CA,与apiserver保持共同。指定签名的CA组织根证书,用来签名为 TLS BootStrapping 创立的证书和私钥
#--root-ca-file:指定根CA证书文件途径,用来对 kube-apiserver 证书进行校验,指定该参数后,才会在 Pod 容器的 ServiceAccount 中放置该 CA 证书文件
#--experimental-cluster-signing-duration:设置为 TLS BootStrapping 签署的证书有效时刻为10年,默许为1年
##生成kube-controller-manager证书
cd /opt/k8s/k8s-cert/
#创立证书恳求文件
cat > kube-controller-manager-csr.json << EOF
{
 "CN": "system:kube-controller-manager",
 "hosts": [],
 "key": {
  "algo": "rsa",
  "size": 2048
  },
 "names": [
   {
   "C": "CN",
   "L": "BeiJing",
   "ST": "BeiJing",
   "O": "system:masters",
   "OU": "System"
   }
  ]
}
EOF
#生成证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager
#生成kubeconfig文件
KUBE_CONFIG="/opt/kubernetes/cfg/kube-controller-manager.kubeconfig"
KUBE_APISERVER="https://192.168.44.20:6443"  #master01的IP
kubectl config set-cluster kubernetes \
 --certificate-authority=/opt/kubernetes/ssl/ca.pem \
 --embed-certs=true \
 --server=${KUBE_APISERVER} \
 --kubeconfig=${KUBE_CONFIG}
kubectl config set-credentials kube-controller-manager \
 --client-certificate=./kube-controller-manager.pem \
 --client-key=./kube-controller-manager-key.pem \
 --embed-certs=true \
 --kubeconfig=${KUBE_CONFIG}
kubectl config set-context default \
 --cluster=kubernetes \
 --user=kube-controller-manager \
 --kubeconfig=${KUBE_CONFIG}
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
##创立 kube-controller-manager.service 服务办理文件
cat >/usr/lib/systemd/system/kube-controller-manager.service <<EOF
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=-/opt/kubernetes/cfg/kube-controller-manager
ExecStart=/opt/kubernetes/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable kube-controller-manager
systemctl restart kube-controller-manager

附录5:admin.sh

#!/bin/bash
mkdir /root/.kube
KUBE_CONFIG="/root/.kube/config"
KUBE_APISERVER="https://192.168.44.20:6443"  #master01的IP
cd /opt/k8s/k8s-cert/
kubectl config set-cluster kubernetes \
 --certificate-authority=/opt/kubernetes/ssl/ca.pem \
 --embed-certs=true \
 --server=${KUBE_APISERVER} \
 --kubeconfig=${KUBE_CONFIG}
kubectl config set-credentials cluster-admin \
 --client-certificate=./admin.pem \
 --client-key=./admin-key.pem \
 --embed-certs=true \
 --kubeconfig=${KUBE_CONFIG}
kubectl config set-context default \
 --cluster=kubernetes \
 --user=cluster-admin \
 --kubeconfig=${KUBE_CONFIG}
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}