自建高可用k8s集群前置概念与操作
一、内核升级
代码语言:javascript复制3.10内核在大规模集群具有不稳定性 内核升级到4.19
# 查看内核版本
uname -sr
# 0、升级软件包,不升级内核
yum update -y --exclude=kernel*
# 1、下载公钥
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
# 安装镜像加速
yum install -y yum-plugin-fastestmirror
# 3、仓库启用后,列出可用的内核相关包:
yum --disablerepo="*" --enablerepo="elrepo-kernel" list available
kernel-lt: long term support:长期支持版
kernel-ml: mainline stable: 主线稳定版
# 4、选择自己的版本进行安装 5.4.119-1.el7.elrepo
yum --enablerepo=elrepo-kernel install -y kernel-lt
# 5、查看内核
uname -sr
#查看内核位置
awk -F' '$1=="menuentry " {print $2}' /etc/grub2.cfg
CentOS Linux 7 Rescue 0a87210b6f6337e79a6611c512e524ce (5.4.119-1.el7.elrepo.x86_64) #第0个
CentOS Linux (5.4.119-1.el7.elrepo.x86_64) 7 (Core) ##我们的在第1个
CentOS Linux (3.10.0-1160.el7.x86_64) 7 (Core)
CentOS Linux (0-rescue-cc2c86fe566741e6a2ff6d399c5d5daa) 7 (Core)
# 6、重新创建内核配置。
grub2-mkconfig -o /boot/grub2/grub.cfg
# 确认内核的位置,修改默认内核即可
# 7、修改使用默认内核
vi /etc/default/grub
# 将 GRUB_DEFAULT 设置为 0,代表 GRUB 初始化页面的第一个内核将作为默认内核
# 再重新整理下内核
grub2-mkconfig -o /boot/grub2/grub.cfg
# 8、重开机
reboot
# 9、检查
uname -r
在内核4.19 版本nf_conntrack_ipv4已经改为nf_conntrack, 4.18以下使用nf_conntrack_ipv4即可:
sysctl -a 可以查看所有的内核参数
二、k8s集群架构
k8s集群架构:
master node
- master:一旦宕机,k8s集群就是不可用状态。但是可能node节点上其他已经运行的Pod还在运行。一般还能提供服务
- 所有数据是保存到etcd(有状态)(存储数据的键值库。保CP)类似ZK。etcd可能会取代zk
- CAP:C一致性(6个redis,访问任何一个redis都能得到一样的数据): A可用性;P分区容错。
- Raft:一致性协议
- 中文动画: Raft 分布式共识算法动画演示
- 领导选举:Leader Election
- Log Replication*日志复制。
- 一个raft一致性的集群最多允许挂 n/2(不管余数) 台机器 6/2 = 3 (大多数存活【n/2 1】)
- 奇数个机器(很快就成功投票)。leader可以多选几轮就能选择出来
- 心跳的速度决定集群的一致性速度。50ms
- 只要大多数节点,直接告诉leader,节点日志已经生成了。leader认为此次操作成功
- P分区容错
- 一旦分区,就产生脑裂问题。出现多个领导
- 会听从多数节点服从的领导
k8s集群里面除了etcd都是无状态的。
三、cfssl使用
CFSSL是CloudFlare开源的一款PKI/TLS工具。 CFSSL 包含一个命令行工具 和一个用于 签名,验证并且捆绑TLS证书的 HTTP API 服务。 使用Go语言编写。
Github 地址: https://github.com/cloudflare/cfssl
官网地址: https://pkg.cfssl.org/
浏览访问kylw.12306.com:
1、假冒网站直接用12306.com证书。浏览器会按照此CA机构给世界暴露的公钥(验钞机(公钥))解密证书看是哪个网站的,如果不符合直接打回
2、自造证书: 浏览器直接提示不安全。(没有注册,联系不到法人)
1、集群相关证书类型
- client certificate: 用于服务端认证客户端,例如etcdctl、etcd proxy、fleetctl、docker客户端
- server certificate: 服务端使用,客户端以此验证服务端身份,例如docker服务端、kube-apiserver
- peer certificate: 双向证书,用于etcd集群成员间通信
根据认证对象可以将证书分成三类:
- 服务器证书
server cert
, - 客户端证书
client cert
, - 对等证书
peer cert
(表示既是server cert
又是client cert
在kubernetes 集群中需要的证书种类如下:
-
etcd
节点需要标识自己服务的server cert,也需要client cert与etcd集群其他节点交互,当然可以分别指定2个证书,也可以使用一个对等证书 -
master
节点需要标识 apiserver服务的server cert,也需要client cert连接etcd集群,这里也使用一个对等证书 -
kubectl
calico
kube-proxy
只需要client cert
,因此证书请求中 hosts 字段可以为空 -
kubelet
证书比较特殊,不是手动生成,它由node节点TLS BootStrap
向apiserver
请求,由master
节点的controller-manager
自动签发,包含一个client cert
和一个server cert
2、简单使用
2.1、创建CA配置文件
配置证书生成策略,规定CA可以颁发那种类型的证书
代码语言:javascript复制vim /opt/ssl/k8sca/ca-config.json
代码语言:javascript复制{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
2.2、创建CA证书签名请求
代码语言:javascript复制vim /opt/ssl/k8sca/ ca-csr.json
代码语言:javascript复制{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"O": "kubernetes",
"ST": "BeiJing",
"OU": "kubernetes"
} ]
}
2.3、生成CA和私钥
生成CA所必需的文件ca-key.pem(私钥)和ca.pem(证书),还会生成ca.csr(证书签名请求),用于交叉签名或重新签名。
代码语言:javascript复制$ cd /opt/ssl/k8sca/
$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca
$ ls
ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem
3、cfssl使用
CFSSL 组成:
- 自定义构建 TLS PKI 工具
- the
cfssl
program, which is the canonical command line utility using the CFSSL packages. - the
multirootca
program, which is a certificate authority server that can use multiple signing keys. - the
mkbundle
program is used to build certificate pool bundles. - the
cfssljson
program, which takes the JSON output from thecfssl
andmultirootca
programs and writes certificates, keys, CSRs, and bundles to disk.
安装:去官网下载cfssl-certinfo_linux-amd64
cfssljson_linux-amd64
cfssl_linux-amd64
这三个组件
# 下载核心组件
wget https://github.com/cloudflare/cfssl/releases/download/v1.5.0/cfssl-certinfo_1.5.0_linux_amd64
wget https://github.com/cloudflare/cfssl/releases/download/v1.5.0/cfssl_1.5.0_linux_amd64
wget https://github.com/cloudflare/cfssl/releases/download/v1.5.0/cfssljson_1.5.0_linux_amd64
#授予执行权限
chmod x cfssl*
#批量重命名
for name in `ls cfssl*`; do mv $name ${name%_1.5.0_linux_amd64}; done
#移动到文件
mv cfssl* /usr/bin
4、证书规划
5、证书生成
生成ca配置
- client certificate: 用于服务端认证客户端,例如etcdctl、etcd proxy、fleetctl、docker客户端
- server certificate: 服务端使用,客户端以此验证服务端身份,例如docker服务端、kube-apiserver
- peer certificate: 双向证书,用于etcd集群成员间通信
创建ca配置文件 (ca-config.json)
- 相当于证书颁发机构的工作规章制度
- "ca-config.json":可以定义多个 profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个 profile;
- "signing":表示该证书可用于签名其它证书;生成的 ca.pem 证书中 CA=TRUE;
- "server auth":表示client可以用该 CA 对server提供的证书进行验证;
- "client auth":表示server可以用该CA对client提供的证书进行验证;
vi ca-config.json
代码语言:javascript复制{
"signing": {
"default": {
"expiry": "43800h"
},
"profiles": {
"server": {
"expiry": "43800h",
"usages": [
"signing",
"key encipherment",
"server auth"
]
},
"client": {
"expiry": "43800h",
"usages": [
"signing",
"key encipherment",
"client auth"
]
},
"peer": {
"expiry": "43800h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
},
"kubernetes": {
"expiry": "43800h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
},
"etcd": {
"expiry": "43800h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
csr.json
- 我们自己准备一个证书申请请求书。证书机构就会根据我们请求签发证书
cfssl print-defaults
cfssl print-defaults csr #使用这个命令打印模板
代码语言:javascript复制{
"CN": "example.net", //浏览器验证该字段是否合法,一般写域名,非常重要.
"hosts": [
"example.net",
"www.example.net"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "US",
"ST": "CA",
"L": "San Francisco"
}
]
}
创建ca证书签名(ca-csr.json)
- "CN":
- Common Name,从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法;
- "O":
- Organization,从证书中提取该字段作为请求用户所属的组 (Group); 这两个参数在后面的kubernetes启用RBAC模式中很重要,因为需要设置kubelet、admin等角色权限,那么在配置证书的时候就必须配置对了,具体后面在部署kubernetes的时候会进行讲解。
- "在etcd这两个参数没太大的重要意义,跟着配置就好。"
vi ca-csr.json
代码语言:javascript复制{
"CN": "SelfSignedCa",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "shanghai",
"O": "cfssl",
"ST": "shanghai",
"OU": "System"
}
]
}
生成ca证书和私钥
代码语言:javascript复制cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
# ca.csr ca.pem(ca公钥) ca-key.pem(ca私钥,妥善保管)
创建etcd证书签名(etcd-csr.json)
代码语言:javascript复制vi etcd-csr.json
代码语言:javascript复制{
"CN": "etcd",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "shanghai",
"O": "etcd",
"ST": "shanghai",
"OU": "System"
}
]
}
代码语言:javascript复制# 生成etcd证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd etcd-csr.json | cfssljson -bare etcd
#etcd.csr etcd-csr.json etcd-key.pem(etcd私钥) etcd.pem(etcd公钥)
创建kubernetes证书签名(kubernetes-csr.json)
代码语言:javascript复制vi kubernetes-csr.json
代码语言:javascript复制{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "shanghai",
"O": "kubernetes",
"ST": "shanghai",
"OU": "System"
}
]
}
代码语言:javascript复制# 生成k8s证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes
# kubernetes.csr kubernetes-key.pem kubernetes.pem
最后校验证书是否合适
代码语言:javascript复制openssl x509 -in ca.pem -text -noout
openssl x509 -in etcd.pem -text -noout
openssl x509 -in kubernetes.pem -text -noout