目录
Rocky 8.8 二进制安装多 master 节点的 k8s 高可用集群内容1.25. 1
K8S各个组件介绍_k8s组件有哪些-CSDN博客... 1
k8s各种证书配置参数_ca.pem_huangzhihuan0813的博客-CSDN博客... 1
6.关闭 selinux,所有 k8s 机器均操作... 3
10.配置阿里云的 repo 源:安装 docker 和 containerd. 5
11.配置安装 k8s 组件需要的阿里云的 repo 源... 5
8.3 etcd配置systemd service管理文件... 13
8.4 根据etcd.service,etcd.conf,创建目录... 13
8.5 根据service启动文件,将文件放到对应位置... 14
四、为kubelet-bootstrap创建 token.csv 用户描述文件... 19
4 创建服务启动文件(system unit svc文件)... 24
6 kube-apiserver.conf文件修改... 25
六、部署 kubectl 组件(重要理解内容!)... 27
这一步部署,只是制作kubeconfig文件,所有组件也只有它可以操作集群资源!... 28
[root@wang82 work]# kubectl config view.. 33
[root@wang82 work]# kubectl config view --kubeconfig=kube.config. 33
4.5 将kubectl的kubeconfig文件放到~/.kube/config. 34
七、部署 kube-controller-manager 组件... 36
5 创建服务启动文件(system unit svc文件)... 40
4. 创建服务启动文件(system unit svc文件)... 45
1.1 启动 TLS Bootstrapping 机制介绍... 46
1.7 master节点Approve bootstrap 请求... 54
5 对apiserver系统用户 kubernetes 做授权... 58
十、安装 keepalived+nginx 实现 k8s apiserver 高可用... 59
3 keepalive 配置主 keepalived. 62
7.1 Work节点组件连接apiserver地址修改为VIP. 65
7.2 kubectl访问apiserver的负载均衡地址修改为VIP. 65
十一、关于二进制K8S集群的kubeconfig文件注意点... 66
3 k8s中,apiserver和controller-manager,他们的证书都是由同一个ca根证书签发,他们的证书之间的关系是什么?... 68
4 kube-controller-manager 如何与 apiserver 通信?... 69
1.2 这个是集群根证书的ca-config文件... 72
3.3 生成新客户端证书,O字段代表用户组, CN字段代表组里用户。... 80
3.4 根据新客户端证书生成授权文件,授权文件名称为xiaopan.kubeconfig。... 81
3.7 将kubeconfig文件放到普通用户家目录下的~/.kube. 83
Rocky 8.8 二进制安装多 master 节点的 k8s 高可用集群内容1.25
K8S各个组件介绍_k8s组件有哪些-CSDN博客
k8s各种证书配置参数_ca.pem_huangzhihuan0813的博客-CSDN博客
k8s基础11——安全控制之RBAC用户授权、RBAC用户组授权、SA程序授权_k8s 用户组-CSDN博客
k8s 环境规划:
podSubnet(pod 网 段 ) 10.244.0.0/16 serviceSubnet(service 网段): 10.96.0.0/12
实验环境规划:
操作系统:Rocky8.8
配置: 4Gib 内存/4vCPU/60G 硬盘
提示:正常下应先做好VIP,本文只是做演示
一、初始化安装 k8s 集群的实验环境
1. 配置静态 ip
在rocky系统中需要把dns配
置在这里
vim /etc/sysconfig/network-scripts/ifcfg-ens33 文件
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
IPADDR=192.168.137.80
NETMASK=255.255.255.0
GATEWAY=192.168.137.2
DNS1=192.168.137.2
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
DEVICE=ens33
ONBOOT=yes
#修改配置文件之后需要重启网络服务才能使配置生效,重启网络服务命令如下:
Nmcli connection up ens33
注:/etc/sysconfig/network-scripts/ifcfg-ens33 文件里的配置说明:
NAME=ens33 #网卡名字,跟 DEVICE 名字保持一致即可
DEVICE=ens33 #网卡设备名,大家 ip addr 可看到自己的这个网卡设备名,每个人的机器可能这个名字不一样,需要写自己的
BOOTPROTO=static #static 表示静态 ip 地址
ONBOOT=yes # 开 机 自 启 动 网 络 , 必 须 是 yes IPADDR=192.168.137.80 #ip 地址,需要跟自己电脑所在网段一致NETMASK=255.255.255.0 #子网掩码,需要跟自己电脑所在网段一致
GATEWAY=192.168.16.2 #网关,在自己电脑打开 cmd,输入 ipconfig /all 可看到
DNS1=192.168.16.2 #DNS,在自己电脑打开 cmd,输入 ipconfig /all 可看到
各个节点执行如下命令更新 yum 源和操作系统:
yum update -y
2.配置主机名
hostnamectl set-hostname 80 && bash
hostnamectl set-hostname 81 && bash
hostnamectl set-hostname 82 && bash
hostnamectl set-hostname 83 && bash
3.配置主机 hosts 文件
修改每台机器的/etc/hosts 文件,文件最后增加如下内容:
192.168.137.80 wang80
192.168.137.81 wang 81
192.168.137.82 wang 82
192.168.137.83 wang 83
4.配置主机之间无密码登录
ssh-keygen
ssh-copy-id wang80.。。。
5.关闭 firewalld 防火墙
systemctl stop firewalld ; systemctl disable firewalld
6.关闭 selinux,所有 k8s 机器均操作
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
7.关闭交换分区 swap,提升性能#临时关闭
swapoff -a
vim /etc/fstab
#/dev/mapper/centos-swap swap swap defaults 0 0
问题 1:为什么要关闭 swap 交换分区?
Swap 是交换分区,如果机器内存不够,会使用 swap 分区,但是 swap 分区的性能较低,k8s 设计的时候为了能提升性能,默认是不允许使用交换分区的。Kubeadm 初始化的时候会检测 swap 是否关闭, 如果没关闭,那就初始化失败。如果不想要关闭交换分区,安装 k8s 的时候可以指定--ignore- preflight-errors=Swap 来解决。
8.修改机器内核参数
[root@80 ~]# modprobe br_netfilter
[root@80 ~]# cat > /etc/sysctl.d/k8s.conf <<EOF net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1 EOF
[root@80 ~]# sysctl -p /etc/sysctl.d/k8s.conf
问题 1:sysctl 是做什么的? 在运行时配置内核参数
-p 从指定的文件加载系统参数,如不指定即从/etc/sysctl.conf 中加载
问题 2:为什么要执行 modprobe br_netfilter?
修改/etc/sysctl.d/k8s.conf 文件,增加如下三行参数:
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
sysctl -p /etc/sysctl.d/k8s.conf 出现报错:
sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-ip6tables: No such file or directory sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-iptables: No such file or directory
解决方法:
modprobe br_netfilter
问题 3:为什么开启 net.bridge.bridge-nf-call-iptables 内核参数? 在 centos 下 安 装 docker, 执 行 docker info 出 现 如 下 警 告 : WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
解决办法:
vim /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
问题 4:为什么要开启 net.ipv4.ip_forward = 1 参数?
kubeadm 初始化 k8s 如果报错:
就表示没有开启 ip_forward,需要开启。net.ipv4.ip_forward 是数据包转发:
出于安全考虑,Linux 系统默认是禁止数据包转发的。所谓转发即当主机拥有多于一块的网卡时,其中一块收到数据包,根据数据包的目的 ip 地址将数据包发往本机另一块网卡,该网卡根据路由表继续发送数据包。这通常是路由器所要实现的功能。
要让 Linux 系统具有路由转发功能,需要配置一个 Linux 的内核参数 net.ipv4.ip_forward。这个参数指定了 Linux 系统当前对路由转发功能的支持情况;其值为 0 时表示禁止进行 IP 转发;如果是 1,则说明IP 转发功能已经打开。
9. 配置时间同步
yum -y install chrony
systemctl enable chronyd –now
vim /etc/chrony.conf
server ntp1.aliyun.com iburst
server ntp2.aliyun.com iburst
server ntp1.tencent.com iburst
server ntp2.tencent.com iburst
systemctl restart chronyd
crontab -e
* * * * * /usr/bin/systemctl restart chronyd
systemctl restart crond
10.配置阿里云的 repo 源:安装 docker 和 containerd
#配置国内安装 docker 和 containerd 的阿里云的repo 源
yum install yum-utils -y
yum-config-manager --add-repo http://mirrors.aliyun.com/docker- ce/linux/centos/docker-ce.repo
11.配置安装 k8s 组件需要的阿里云的 repo 源
Rocky版本K8S源
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
Dnf makecache
12.安装 containerd 服务
在 k8s 集群每个节点都操作如下命令:
yum install containerd.io-1.6.6 -y
接下来生成 containerd 的配置文件:
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
修改配置文件:
打开/etc/containerd/config.toml
把 SystemdCgroup = false 修改成 SystemdCgroup = true
把 sandbox_image = "k8s.gcr.io/pause:3.6"修改成
sandbox_image="registry.aliyuncs.com/google_containers/pause:3.7"
配置 containerd 开机启动,并启动 containerd
systemctl enable containerd --now
sed -i 's/sandbox_image = "k8s.gcr.io\/\pause:3.6"/sandbox_image="registry.aliyuncs.com\/\google_containers\/\pause:3.7"/g' /etc/containerd/config.toml
13.安装 docker 服务
k8s 所有节点均按照以下配置:
yum install docker-ce -y
systemctl enable docker --now
配置 docker 镜像加速器,k8s 所有节点均按照以下配置
vim /etc/docker/daemon.json
写入如下内容:
{
"registry-mirrors":["https://vh3bm52y.mirror.aliyuncs.com","https://registry.dockercn.com","https://docker.mirrors.ustc.edu.cn","https://dockerhub.azk8s.cn","http://hubmirror.c.163.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
重启 docker:
systemctl restart docker
二、搭建 etcd 集群
1 配置 etcd 工作目录
80-82创建配置文件和证书文件存放目录
mkdir -p /etc/etcd
mkdir -p /etc/etcd/ssl
2 安装签发证书工具 cfssl (官方指定的)
CFSSL(CloudFlare's SSL)是由 CloudFlare 开发的工具集,用于创建和管理 PKI(Public Key Infrastructure,公钥基础设施)。PKI 是一种广泛使用的安全框架,用于确保网络通信的机密性、完整性和身份验证。
CFSSL 包含以下主要组件:
1、cfssl: 这是命令行工具,用于生成证书、密钥和其他安全资产。它支持多种证书配置选项,使用户能够轻松地生成自签名证书、服务器证书、客户端证书等。
2、cfssljson: 该工具用于将 JSON 格式的证书请求(CSR)转换为其他格式,如 PEM 格式。PEM 是一种常用的证书格式,适用于许多应用程序和服务器。
3、cfssl-bundle: 用于将证书绑定到其相应的中间证书和根证书,创建一个完整的证书链。
4、cfssl-certinfo: 用于解码和打印证书的信息,方便用户查看证书的详细信息。
5、cfssl-newkey: 用于生成新的私钥。
[root@80 ~]# mkdir /data/work -p
存放文件
[root@80 ~]# cd /data/work/
把 cfssl-certinfo_linux-amd64 、cfssljson_linux-amd64 、cfssl_linux-amd64 上传到
/data/work/目录下[root@80 work]# ls
cfssl-certinfo_linux-amd64 cfssljson_linux-amd64 cfssl_linux-amd64 #把文件变成可执行权限
[root@80 work]# chmod +x *
[root@80 work]# mv cfssl_linux-amd64 /usr/local/bin/cfssl
[root@80 work]# mv cfssljson_linux-amd64 /usr/local/bin/cfssljson [root@80 work]# mv cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo
3 ca 证书请求文件
- 定义了一个权威机构kubernetes,其他组件都要以profile=kubernetes来指定这个权威机构
- 可以改为100年CA证书过期
- 它颁发的证书有效期在ca-config文件里定义(颁发其他组件的客户端证书)
- CN字段:kubernetes用户,kubeconfig中的user用户
vim ca-csr.json
{
"CN": "kubernetes", # 权威机构是kubernetes
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Hubei",
"L": "Wuhan",
"O": "k8s",
"OU": "system"
}
],
"ca": {
"expiry": "87600h"
}
}
4 生成ca证书
- 用ca证书请求文件,签发ca根证书+私钥+csr
- ca.csr ca-key.pem ca.pem
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
ca.csr #ca请求文件
ca.pem #ca证书
ca-key.pem # ca私钥
5 创建ca 证书的配置文件
- 解释:
- k8s其他组件都要使用ca的私钥,去签发,客户端证书
- 这个ca-config文件定义了用ca去签发证书的属性:
证书申请json文件及其中指定的kubernetes参数+ca证书+ca私钥+ca配置文件=同时为其他组件签发,请求证书+证书+私钥,3个证书
- 定义了使用这个profiles为kubernetes的证书配置文件+ca制作的证书,有效期10年
cat ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
6 etcd证书的请求文件
留个心眼,多写几个etcd的ip,方便后期扩容,不然要重新创建证书
[root@82 work]# cat etcd-csr.json
{
"CN": "etcd",
"hosts": [
"127.0.0.1",
"192.168.137.80",
"192.168.137.81",
"192.168.137.82",
"192.168.137.199"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [{
"C": "CN",
"ST": "Hubei",
"L": "Wuhan",
"O": "k8s",
"OU": "system"
}]
}
7 生成etcd证书
- 解释
- 用ca证书+私钥+ca证书的配置文件及指定其中的一个配置文件参数+etcd请求json文件=etcd请求证书+etcd证书+私钥
- etcd.csr etcd-key.pem etcd.pem
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes etcd-csr.json | cfssljson -bare etcd
# 权威机构是kubernetes(profile=kubernetes)
8部署 etcd 集群
8.1 etcd二进制管理命令配置
Wget https://github.com/etcd-io/etcd/releases/download/v3.4.13/etcd-v3.4.13-linux-amd64.tar.gz
[root@82 work]# tar xzvf etcd-v3.4.13-linux-amd64.tar.gz #二进制文件
[root@82 work]# chmod +x /usr/local/bin/etcd*
[root@82 work]# scp -r etcd-v3.4.13-linux-amd64/etcd* wang80:/usr/local/bin/
[root@82 work]# scp -r etcd-v3.4.13-linux-amd64/etcd* wang81:/usr/local/bin/
81,82,83
chmod +x /usr/local/bin/etcd*
[root@82 ~]# ls /usr/local/bin/etcd*
/usr/local/bin/etcd /usr/local/bin/etcdctl
8.2 创建conf配置文件
[root@82 work]# cat etcd.conf
#[Member]
ETCD_NAME="etcd3"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.137.82:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.137.82:2379,http://127.0.0.1:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.137.82:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.137.82:2379"
ETCD_INITIAL_CLUSTER="etcd1=https://192.168.137.80:2380,etcd2=https://192.168.137.81:2380,etcd3=https://192.168.137.82:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
8.3 etcd配置systemd service管理文件
[root@82 work]# cat etcd.service
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
EnvironmentFile=-/etc/etcd/etcd.conf
WorkingDirectory=/var/lib/etcd/
ExecStart=/usr/local/bin/etcd \
--cert-file=/etc/etcd/ssl/etcd.pem \
--key-file=/etc/etcd/ssl/etcd-key.pem \
--trusted-ca-file=/etc/etcd/ssl/ca.pem \
--peer-cert-file=/etc/etcd/ssl/etcd.pem \
--peer-key-file=/etc/etcd/ssl/etcd-key.pem \
--peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \
--peer-client-cert-auth \
--client-cert-auth
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
8.4 根据etcd.service,etcd.conf,创建目录
[root@80 ~]# mkdir -p /var/lib/etcd/default.etcd
[root@81 ~]# mkdir -p /var/lib/etcd/default.etcd
[root@82 work]# mkdir -p /var/lib/etcd/default.etcd
8.5 根据service启动文件,将文件放到对应位置
[root@82 work]# cp ca*.pem /etc/etcd/ssl/
[root@82 work]# cp etcd*.pem /etc/etcd/ssl/
[root@82 work]# cp etcd.conf /etc/etcd/
[root@82 work]# cp etcd.service /usr/lib/systemd/system
[root@82 work]# for i in wang{80,81};do scp ca*.pem $i:/etc/etcd/ssl/; done
[root@82 work]# for i in wang{80,81};do scp etcd*.pem $i:/etc/etcd/ssl/; done
[root@82 work]# for i in wang{80,81};do scp etcd.conf $i:/etc/etcd/; done
[root@82 work]# for i in wang{80,81};do scp etcd.service $i:/usr/lib/systemd/system/; done
8.6 分别修改etcd.conf文件
[root@80 ~]# cat /etc/etcd/etcd.conf
#[Member]
ETCD_NAME="etcd1"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.137.80:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.137.80:2379,http://127.0.0.1:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.137.80:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.137.80:2379"
ETCD_INITIAL_CLUSTER="etcd1=https://192.168.137.80:2380,etcd2=https://192.168.137.81:2380,etcd3=https://192.168.137.82:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
[root@81 ~]# cat /etc/etcd/etcd.conf
#[Member]
ETCD_NAME="etcd2"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.137.81:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.137.81:2379,http://127.0.0.1:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.137.81:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.137.81:2379"
ETCD_INITIAL_CLUSTER="etcd1=https://192.168.137.80:2380,etcd2=https://192.168.137.81:2380,etcd3=https://192.168.137.82:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
8.7 启动 etcd 集群
[root@80 work]# systemctl daemon-reload
[root@80 work]# systemctl enable etcd.service –now
[root@81 work]# systemctl daemon-reload
[root@81 work]# systemctl enable etcd.service --now
[root@82 work]# systemctl daemon-reload
[root@82 work]# systemctl enable etcd.service –now
启动 etcd 的时候,先启动 80 的 etcd 服务,会一直卡住在启动的状态,然后接着再启动
81 和 82 的etcd,这样 80 这个节点 etcd 才会正常起来
[root@80]# systemctl status etcd
[root@81]# systemctl status etcd
[root@82]# systemctl status etcd
8.8 查看 etcd 集群状态
/usr/local/bin/etcdctl --write-out=table --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem --endpoints=https://192.168.137.80:2379,https://192.168.137.81:2379,https://192.168.137.82:2379 endpoint status --cluster
三、安装 k8s 组件准备工作
1 下载安装包,1.25版本
二进制包所在的 github 地址如下:
https://github.com/kubernetes/kubernetes
2 对源码文件进行编译
Clone下来默认是master分支,网速太慢,在线下很难,留个仓库
git clone -b release-1.23 GitHub - kubernetes/kubernetes: Production-Grade Container Scheduling and Management
git describe –tags
git branch --show-current
下载go
wget https://studygolang.com/dl/golang/go1.17.5.linux-amd64.tar.gz
tar xzvf go1.17.5.linux-amd64.tar.gz
cp go/bin/go /usr/local/bin/
编译kubectl
make WHAT=cmd/kubectl
find kubernetes/_output -name kubectl
其余类似
3 直接下载编译好的
https://dl.k8s.io/v1.25.0/kubernetes-server-linux-amd64.tar.gz
4 拷贝二进制包给各个节点
把 kubernetes-server-linux-amd64.tar.gz 上传到 82 上的/data/work 目录下:
[root@82 work]# tar zxvf kubernetes-server-linux-amd64.tar.gz
[root@82 work]# cd kubernetes/server/bin/
[root@82 bin]# cp kube-apiserver kube-controller-manager kube-scheduler kubectl kubelet /usr/local/bin/
[root@82 bin]# scp kube-apiserver kube-controller-manager kube-scheduler kubectl kubelet wang80:/usr/local/bin/
[root@82 bin]# scp kube-apiserver kube-controller-manager kube-scheduler kubectl kubelet wang81:/usr/local/bin/
[root@82 bin]# scp kubelet kube-proxy kubectl wang83:/usr/local/bin/
3个主节点分别创建目录
mkdir -p /etc/kubernetes/
mkdir -p /etc/kubernetes/ssl
mkdir /var/log/kubernetes
[root@82 bin]# cd /data/work/
- 说明
- 1#:以下k8s组件,master,node,都要同时创建
- 2#:所有master80-82都有下面几个二进制文件
cp kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/local/bin/
- 3#:node61有以下二进制文件
Scp kubelet kube-proxy 83:/usr/local/bin/
- 4#:为每个组件签发kubeconfig文件,都是为了和apiserver进行交互
1.kubelet和apiserver的用户,都被绑定了cluster-admin角色,具备管理员权限,可以操作整个集群资源
2.操纵kubelet要被授权,apiserver就被授权操纵kubelet的权限,为了安全!kubelet的权限太大!
四、为kubelet-bootstrap创建 token.csv 用户描述文件
后面的piserver组件要用到,提前创建
[root@82 ~]# cd /data/work/
[root@82 work]# cat > token.csv << EOF
$(head -c 16 /dev/urandom | od -An -t x | tr -d ' '),kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
k8s----------各种证书配置参数_ca.pem_huangzhihuan0813的博客-CSDN博客
- apiserver.conf会引用
--enable-bootstrap-token-auth: 这个选项用于启用 Bootstrap Token 认证机制,用于节点加入集群时的身份验证。
--token-auth-file: 这个选项用于指定 Token 认证文件的路径。在这里,设置为-token-auth-file: 这个选项用于指定 Token 认证文件的路径。/etc/kubernetes/token.csv
- 这个文件写入了apiserver的配置文件,apiserver启动时加载,然后相当于在集群内创建了这个用户,接下来,就可以对这个用户RBAC授权
1. 4ea03c812f8f415da08ff54dc032e7c9:这是一个随机生成的 16 位的 token,用于身份验证和授权访问 Kubernetes 集群。
2. kubelet-bootstrap:这是一个用户名,用于标识该 token 的用途,表示它是用于向 kubelet 进行引导认证的。
3.10001:这是一个用户 ID(User ID),用于标识该用户在系统中的唯一身份。
4. "system:kubelet-bootstrap":这是用户所属的用户组,表示该用户是属于名为 "system:kubelet-bootstrap" 的用户组的成员。
- 这些字段共同描述了一个用于 kubelet 引导认证的 token 的相关信息,用于身份验证和授权需求。
- Token:用于认证和授权, 用于 kubelet 引导
- system:kubelet-bootstrap:特殊的用户组,用于授权 Kubelet 身份进行引导认证。允许 Kubelet 在与控制平面进行通信时建立初始的信任关系。这些权限通常包括:
- 用户组创建 CSR(Certificate Signing Request):Kubelet 在引导时将生成一个证书签名请求(CSR),该请求将被提交给 Kubernetes CA(Certificate Authority)以获得证书。system:kubelet-bootstrap 用户组被授予创建 CSR 的权限。
- 自动批准证书签名请求:Kubernetes 控制平面(如 kube-apiserver)通常配置为自动批准 system:kubelet-bootstrap 用户组生成的证书签名请求,从而允许 Kubelet 能够正常启动和加入集群。
- 需要注意的是,system:kubelet-bootstrap 用户组没有访问或管理集群其他资源的权限。它仅用于初始引导阶段,用于建立 Kubelet 与控制平面之间的信任。
具体看后面的第九节
五、部署 api-server组件
1 创建证书请求文件
生产中预留10个ip,防止重新生成证书
Kubernetes这个用户自己给自己颁发证书,让apiserver使用这个用户,拿着证书和私钥,ca证书与其他组件通信(apiserver需要一套证书和私钥)
- CN字段:kubernetes用户,kubeconfig中的user用户
- 跨ns写FQDN,本ns不用FQDN的原因
[root@wang82 work]# cat kube-apiserver-csr.json
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"192.168.137.80",
"192.168.137.81",
"192.168.137.82",
"192.168.137.83",
"192.168.137.199",
"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": "Hubei",
"L": "Wuhan",
"O": "k8s",
"OU": "system"
}
]
}
2 生成证书
Ca +ca配置文件及指定其中配置为kubenetes的参数+json请求文件 =csr请求证书+证书+私钥
[root@82 work]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-apiserver-csr.json | cfssljson -bare kube-apiserver
3 创建conf配置文件
[root@wang82 work]# cat kube-apiserver.conf
KUBE_APISERVER_OPTS="--enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
--anonymous-auth=false \
--bind-address=192.168.137.82 \
--secure-port=6443 \
--advertise-address=192.168.137.82 \
--authorization-mode=Node,RBAC \
--runtime-config=api/all=true \
--enable-bootstrap-token-auth \
--service-cluster-ip-range=10.96.0.0/12 \
--token-auth-file=/etc/kubernetes/token.csv \
--service-node-port-range=30000-50000 \
--tls-cert-file=/etc/kubernetes/ssl/kube-apiserver.pem \
--tls-private-key-file=/etc/kubernetes/ssl/kube-apiserver-key.pem \
--client-ca-file=/etc/kubernetes/ssl/ca.pem \
--kubelet-client-certificate=/etc/kubernetes/ssl/kube-apiserver.pem \
--kubelet-client-key=/etc/kubernetes/ssl/kube-apiserver-key.pem \
--service-account-key-file=/etc/kubernetes/ssl/ca-key.pem \
--service-account-signing-key-file=/etc/kubernetes/ssl/ca-key.pem \
--service-account-issuer=https://kubernetes.default.svc.cluster.local \
--etcd-cafile=/etc/etcd/ssl/ca.pem \
--etcd-certfile=/etc/etcd/ssl/etcd.pem \
--etcd-keyfile=/etc/etcd/ssl/etcd-key.pem \
--etcd-servers=https://192.168.137.80:2379,https://192.168.137.81:2379,https://192.168.137.82:2379 \
--allow-privileged=true \
--apiserver-count=3 \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/var/log/kube-apiserver-audit.log \
--event-ttl=1h \
--alsologtostderr=true \
--logtostderr=false \
--log-dir=/var/log/kubernetes \
--v=4"
4 创建服务启动文件(system unit svc文件)
[root@wang82 work]# cat kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=etcd.service
Wants=etcd.service
[Service]
EnvironmentFile=-/etc/kubernetes/kube-apiserver.conf
ExecStart=/usr/local/bin/kube-apiserver $KUBE_APISERVER_OPTS
Restart=on-failure
RestartSec=5
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
5. 拷贝证书到定义位置
[root@wang82 work]# cp ca*.pem /etc/kubernetes/ssl
[root@wang82 work]# cp kube-apiserver*.pem /etc/kubernetes/ssl/ [root@wang82 work]# cp token.csv /etc/kubernetes/
[root@wang82 work]# cp kube-apiserver.conf /etc/kubernetes/
[root@wang82 work]# cp kube-apiserver.service /usr/lib/systemd/system/
[root@wang82 work]# scp ca*.pem wang80:/etc/kubernetes/ssl/
[root@wang82 work]# scp ca*.pem wang81:/etc/kubernetes/ssl/
[root@wang82 work]# scp kube-apiserver*.pem wang80:/etc/kubernetes/ssl/
[root@wang82 work]# scp kube-apiserver*.pem wang81:/etc/kubernetes/ssl/
[root@wang82 work]# scp token.csv wang80:/etc/kubernetes/
[root@wang82 work]# scp token.csv wang81:/etc/kubernetes/
拷贝过去,修改为各个节点的地址
[root@wang82 work]# scp kube-apiserver.conf wang80:/etc/kubernetes/
[root@wang82 work]# scp kube-apiserver.conf wang81:/etc/kubernetes/
[root@wang82 work]# scp kube-apiserver.service wang80:/usr/lib/systemd/system/
[root@wang82 work]# scp kube-apiserver.service wang81:/usr/lib/systemd/system/
6 kube-apiserver.conf文件修改
注:80 配置文件 kube-apiserver.conf 的 IP 地址修改为实际的本机 IP [root@wang80 ~]# cat /etc/kubernetes/kube-apiserver.conf
KUBE_APISERVER_OPTS="--enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
--anonymous-auth=false \
--bind-address=192.168.137.80 \
--secure-port=6443 \
--advertise-address=192.168.137.80 \
--authorization-mode=Node,RBAC \
--runtime-config=api/all=true \
--enable-bootstrap-token-auth \
--service-cluster-ip-range=10.96.0.0/12 \
--token-auth-file=/etc/kubernetes/token.csv \
--service-node-port-range=30000-50000 \
--tls-cert-file=/etc/kubernetes/ssl/kube-apiserver.pem \
--tls-private-key-file=/etc/kubernetes/ssl/kube-apiserver-key.pem \
--client-ca-file=/etc/kubernetes/ssl/ca.pem \
--kubelet-client-certificate=/etc/kubernetes/ssl/kube-apiserver.pem \
--kubelet-client-key=/etc/kubernetes/ssl/kube-apiserver-key.pem \
--service-account-key-file=/etc/kubernetes/ssl/ca-key.pem \
--service-account-signing-key-file=/etc/kubernetes/ssl/ca-key.pem \
--service-account-issuer=https://kubernetes.default.svc.cluster.local \
--etcd-cafile=/etc/etcd/ssl/ca.pem \
--etcd-certfile=/etc/etcd/ssl/etcd.pem \
--etcd-keyfile=/etc/etcd/ssl/etcd-key.pem \
--etcd-servers=https://192.168.137.80:2379,https://192.168.137.81:2379,https://192.168.137.82:2379 \
--allow-privileged=true \
--apiserver-count=3 \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/var/log/kube-apiserver-audit.log \
--event-ttl=1h \
--alsologtostderr=true \
--logtostderr=false \
--log-dir=/var/log/kubernetes \
--v=4"
注:81 配置文件 kube-apiserver.conf 的 IP 地址修改为实际的本机 IP [root@wang81 ~]# cat /etc/kubernetes/kube-apiserver.conf
KUBE_APISERVER_OPTS="--enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
--anonymous-auth=false \
--bind-address=192.168.137.81 \
--secure-port=6443 \
--advertise-address=192.168.137.81 \
--authorization-mode=Node,RBAC \
--runtime-config=api/all=true \
--enable-bootstrap-token-auth \
--service-cluster-ip-range=10.96.0.0/12 \
--token-auth-file=/etc/kubernetes/token.csv \
--service-node-port-range=30000-50000 \
--tls-cert-file=/etc/kubernetes/ssl/kube-apiserver.pem \
--tls-private-key-file=/etc/kubernetes/ssl/kube-apiserver-key.pem \
--client-ca-file=/etc/kubernetes/ssl/ca.pem \
--kubelet-client-certificate=/etc/kubernetes/ssl/kube-apiserver.pem \
--kubelet-client-key=/etc/kubernetes/ssl/kube-apiserver-key.pem \
--service-account-key-file=/etc/kubernetes/ssl/ca-key.pem \
--service-account-signing-key-file=/etc/kubernetes/ssl/ca-key.pem \
--service-account-issuer=https://kubernetes.default.svc.cluster.local \
--etcd-cafile=/etc/etcd/ssl/ca.pem \
--etcd-certfile=/etc/etcd/ssl/etcd.pem \
--etcd-keyfile=/etc/etcd/ssl/etcd-key.pem \
--etcd-servers=https://192.168.137.80:2379,https://192.168.137.81:2379,https://192.168.137.82:2379 \
--allow-privileged=true \
--apiserver-count=3 \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/var/log/kube-apiserver-audit.log \
--event-ttl=1h \
--alsologtostderr=true \
--logtostderr=false \
--log-dir=/var/log/kubernetes \
--v=4"
7 启动服务
3台
systemctl daemon-reload
systemctl enable kube-apiserver --now
systemctl status kube-apiserver
六、部署 kubectl 组件(重要理解内容!)
很重要!
这一步部署,只是制作kubeconfig文件,所有组件也只有它可以操作集群资源!
Kubectl 是客户端工具,操作k8s 资源的,如增删改查等。
- Ca +ca配置文件及指定其中配置为kubenetes的参数+json请求文件=csr请求证书+证书+私钥
- 为kubectl的admin用户(请求文件的CN字段),为它创建一个kubeconfig文件,配置安全上下文
- 配置安全上下文 = 设置集群参数+设置客户端认证参数+设置默认上下文
- Admin用户使用kubeconfig文件切换集群上下文
- 对admin用户(对ca证书做证书申请的json申请文件中的CN字段)进行RBAC授权
1 创建 csr 请求文件
- CN字段:用户admin,kubeconfig中的user用户
[root@wang82 work]# cat admin-csr.json
{
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Hubei",
"L": "Wuhan",
"O": "system:masters",
"OU": "system"
}
]
}
- 关于”hosts”:[]
2 生成证书
[root@wang82 work]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin
3 将证书放到master节点指定位置
[root@wang82 work]# cp admin*.pem /etc/kubernetes/ssl/
[root@wang82 work]# scp admin*.pem wang80:/etc/kubernetes/ssl/
[root@wang82 work]# scp admin*.pem wang81:/etc/kubernetes/ssl/
4 配置安全上下文
- 为kubectl的admin用户,创建一个kubeconfig文件,配置安全上下文
- 配置安全上下文 = 设置集群参数+设置客户端认证参数+设置默认上下文
- Kubectl配置安全上下文:实质是创建一个kubeconfig文件,给某个用户创建kubeconfig步骤一样(普通用户的ca证书,和签发集群组件的ca证书,是一套证书)
- 安全上下文:设置集群参数+设置客户端认证参数+设置当前上下文
- 为kubectl创建kubeconfig文件,包含访问apiserver的所有信息,如apiserver地址,ca证书、自身服务、客户端证书(注意是否有报错找不到路径,需要手动拷贝)
- 为kubectl组件的admin用户生成一个可以切换集群上下文的kubeconfig文件
4.1 设置集群参数
- 为kubectl的admin用户,创建一个kubeconfig文件,配置安全上下文中的第1步:设置集群参数
- [root@wang82 work]# kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://192.168.137.82:6443 --kubeconfig=kube.config
Cluster "kubernetes" set.
- 查看 kube.config 内容
4.2 设置客户端认证参数
为kubectl的admin用户,创建一个kubeconfig文件,配置安全上下文中的第2步:设置客户端认证参数
[root@wang82 work]# kubectl config set-credentials admin --client-certificate=admin.pem --client-key=admin-key.pem --embed-certs=true --kubeconfig=kube.config
User "admin" set.
4.3 设置默认上下文参数
为kubectl的admin用户,创建一个kubeconfig文件,配置安全上下文中的第3步:设置默认上下文
(就是把cluster,认证好的用户加进来,最后切换集群上下文用)
[root@wang82 work]# kubectl config set-context kubernetes --cluster=kubernetes --user=admin --kubeconfig=kube.config
4.4 设置当前上下文
[root@wang82 work]# kubectl config use-context kubernetes --kubeconfig=kube.config
[root@wang82 work]# kubectl config view
[root@wang82 work]# kubectl config view --kubeconfig=kube.config
4.5 将kubectl的kubeconfig文件放到~/.kube/config
可以避免指定kubeconfig文件,作为默认的kubeconfig文件
[root@wang82 work]# mkdir -p ~/.kube
[root@wang82 work]# cp kube.config ~/.kube/config
4.6 RBAC授权
4.6.1为api-server的kubernetes用户做RBAC授权
[root@wang82 work]# kubectl create clusterrolebinding kube-apiserver:kubelet-apis --clusterrole=system:kubelet-api-admin --user kubernetes
权限很大
4.6.2为kubectl的admin用户做RBAC授权
- kubelet对ca证书申请证书的json申请文件中的CN字段
- 绑定cluster-admin最高权限,对集群资源操作的权限
[root@wang82 work]# kubectl create clusterrolebinding kubectl-admin --clusterrole=cluster-admin --user admin
Clusterrolebinding名称任意,这里写的kubectl-admin,创建集群写的kubelet-admin,描述不准确
权限超级超级大
#查看集群组件状态
[root@wang82 work]# kubectl cluster-info
#同步 kubectl 文件到其他节点
[root@81 ~]# mkdir /root/.kube/ [root@82 ~]# mkdir /root/.kube/
4.6.3所有节点都具备操作K8s权限
注意:集群后面修改为VIP,kubectl访问apiserver的负载均衡
scp kube.config wang80:/root/.kube/config
scp kube.config wang81:/root/.kube/config
scp kube.config wang83:/root/.kube/config
七、部署 kube-controller-manager 组件
- kube-controller-manager是高可用的,会选举一个为主
- kube-controller-manager.kubeconfig
--leader-elect=true
1 创建 csr 请求文件
生产中预留10个ip,防止重新生成证书
[root@wang82 work]# cat kube-controller-manager-csr.json
{
"CN": "system:kube-controller-manager",
"key": {
"algo": "rsa",
"size": 2048
},
"hosts": [
"127.0.0.1",
"192.168.137.80",
"192.168.137.81",
"192.168.137.82",
"192.168.137.199"
],
"names": [
{
"C": "CN",
"ST": "Hubei",
"L": "Wuhan",
"O": "system:kube-controller-manager",
"OU": "system"
}
]
}
- "system:kube-controller-manager"
在 Kubernetes 中既可以表示一个特定用户,也可以表示一个特定用户组。
当将 "system:kube-controller-manager" 作为证书主体时,它可以表示一个特定的用户,该用户具有特定的权限和角色来管理控制器。
RBAC绑定clusterrolebinding时也可以通过将该用户添加到某个用户组中,来赋予一组用户相同的权限和角色。
2 生成证书
[root@wang82 work]# 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
3 制作kubeconfig文件
- 这里不需要把kubeconfig文件也放到~/.Kube中,因为这个不是给管理员操纵kubectl使用的
- 而是给controller-manager成员中认证用的,因为没有RBAC授权,只能做认证
--kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig
- kube scheduller是高可用的,会选举一个为主
--leader-elect=true \
#创建 kube-controller-manager 的 kubeconfig
1.设置集群参数
[root@wang82 work]# kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://192.168.137.82:6443 --kubeconfig=kube-controller-manager.kubeconfig
设置客户端认证参数
[root@wang82 work]# kubectl config set-credentials system:kube-controller-manager --client-certificate=kube-controller-manager.pem --client-key=kube-controller-manager-key.pem --embed-certs=true --kubeconfig=kube-controller-manager.kubeconfig
设置默认上下文参数
[root@wang82 work]# kubectl config set-context system:kube-controller-manager --cluster=kubernetes --user=system:kube-controller-manager --kubeconfig=kube-controller-manager.kubeconfig
切换为当前安全上下文,与apiserver建立TLS连接时使用
[root@wang82 work]# kubectl config use-context system:kube-controller-manager --kubeconfig=kube-controller-manager.kubeconfig
4 创建conf配置文件
# 创 建 配 置 文 件 kube-controller-manager.conf
[root@wang82 work]# cat kube-controller-manager.conf
KUBE_CONTROLLER_MANAGER_OPTS=" \
--secure-port=10257 \
--bind-address=127.0.0.1 \
--kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig \
--service-cluster-ip-range=10.96.0.0/12 \
--cluster-name=kubernetes \
--cluster-signing-cert-file=/etc/kubernetes/ssl/ca.pem \
--cluster-signing-key-file=/etc/kubernetes/ssl/ca-key.pem \
--allocate-node-cidrs=true \
--cluster-cidr=10.244.0.0/16 \
--root-ca-file=/etc/kubernetes/ssl/ca.pem \
--service-account-private-key-file=/etc/kubernetes/ssl/ca-key.pem \
--leader-elect=true \
--feature-gates=RotateKubeletServerCertificate=true \
--controllers=*,bootstrapsigner,tokencleaner \
--horizontal-pod-autoscaler-sync-period=10s \
--tls-cert-file=/etc/kubernetes/ssl/kube-controller-manager.pem \
--tls-private-key-file=/etc/kubernetes/ssl/kube-controller-manager-key.pem \
--use-service-account-credentials=true \
--alsologtostderr=true \
--logtostderr=false \
--v=2"
5 创建服务启动文件(system unit svc文件)
[root@wang82 work]# cat kube-controller-manager.service
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=-/etc/kubernetes/kube-controller-manager.conf
ExecStart=/usr/local/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
6 拷贝证书到定义位置
[root@wang82 work]# cp kube-controller-manager*.pem /etc/kubernetes/ssl/
[root@wang82 work]# cp kube-controller-manager.kubeconfig /etc/kubernetes/
[root@wang82 work]# cp kube-controller-manager.conf /etc/kubernetes/
[root@wang82 work]# cp kube-controller-manager.service /usr/lib/systemd/system/
[root@wang82 work]# scp kube-controller-manager*.pem wang80:/etc/kubernetes/ssl/
[root@wang82 work]# scp kube-controller-manager*.pem wang81:/etc/kubernetes/ssl/
拷贝过去,修改为各个节点的地址
[root@wang82 work]# scp kube-controller-manager.kubeconfig wang80:/etc/kubernetes/
[root@wang82 work]# scp kube-controller-manager.kubeconfig wang81:/etc/kubernetes/
注意:kube-controller-manager.conf绑定地址为127.0.0.1,其他机器可以直接用
[root@wang82 work]# scp kube-controller-manager.conf wang80:/etc/kubernetes/
[root@wang82 work]# scp kube-controller-manager.conf wang81:/etc/kubernetes/
[root@wang82 work]# scp kube-controller-manager.service wang80:/usr/lib/systemd/system/
[root@wang82 work]# scp kube-controller-manager.service wang81:/usr/lib/systemd/system/
7 启动服务
systemctl daemon-reload
[root@82 work]# systemctl daemon-reload
[root@82 work]# systemctl enable kube-controller-manager
[root@82 work]# systemctl start kube-controller-manager [root@80 work]# systemctl status kube-controller-manager
Active: active (running) since
[root@81]# systemctl daemon-reload
[root@81]# systemctl enable kube-controller-manager [root@81]# systemctl start kube-controller-manager [root@81]# systemctl status kube-controller-manager
Active: active (running) since
[root@82]# systemctl daemon-reload
[root@82]# systemctl enable kube-controller-manager [root@82]# systemctl start kube-controller-manager [root@82]# systemctl status kube-controller-manager
Active: active (running) since
八、部署 kube-scheduler 组件
- kube-scheduler是高可用的,会选举一个为主
- kube-scheduler.kubeconfig
--leader-elect=true
1 制作客户端证书
生产中预留10个ip,防止重新生成证书
[root@wang82 work]# cat kube-scheduler-csr.json
{
"CN": "system:kube-scheduler",
"hosts": [
"127.0.0.1",
"192.168.137.80",
"192.168.137.81",
"192.168.137.82",
"192.168.137.199"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Hubei",
"L": "Wuhan",
"O": "system:kube-scheduler",
"OU": "system"
}
]
}
注:
- hosts 列表包含所有 kube-scheduler 节点 IP;
- CN 为 system:kube-scheduler、
- O 为system:kube-scheduler,kubernetes 内 置 的 ClusterRoleBindings system:kube-scheduler 将赋予 kube-scheduler 工作所需的权限。
2 生成证书
[root@wang82 work]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler
3 制作kubeconfig文件
为kube-scheduler组件用户生成一个可以切换集群上下文的
设置集群参数
[root@wang82 work]# kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://192.168.137.82:6443 --kubeconfig=kube-scheduler.kubeconfig
设置客户端认证参数
[root@wang82 work]# 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
设置默认上下文参数
[root@wang82 work]# kubectl config set-context system:kube-scheduler --cluster=kubernetes --user=system:kube-scheduler --kubeconfig=kube-scheduler.kubeconfig
切换为当前安全上下文,与apiserver建立TLS连接时使用
[root@wang82 work]# kubectl config use-context system:kube-scheduler --kubeconfig=kube-scheduler.kubeconfig
4 创建conf配置文件
[root@wang82 work]# cat kube-scheduler.conf
KUBE_SCHEDULER_OPTS="--bind-address=127.0.0.1 \
--kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig \
--leader-elect=true \
--alsologtostderr=true \
--logtostderr=false \
--log-dir=/var/log/kubernetes \
--v=2"
4. 创建服务启动文件(system unit svc文件)
[root@wang82 work]# cat kube-scheduler.service
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=-/etc/kubernetes/kube-scheduler.conf
ExecStart=/usr/local/bin/kube-scheduler $KUBE_SCHEDULER_OPTS
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
5 拷贝文件到相应为止
[root@wang82 work]# cp kube-scheduler*.pem /etc/kubernetes/ssl/
[root@wang82 work]# cp kube-scheduler.kubeconfig /etc/kubernetes/
[root@wang82 work]# cp kube-scheduler.conf /etc/kubernetes/
[root@wang82 work]# cp kube-scheduler.service /usr/lib/systemd/system/
[root@wang82 work]# scp kube-scheduler*.pem wang80:/etc/kubernetes/ssl/
[root@wang82 work]# scp kube-scheduler*.pem wang81:/etc/kubernetes/ssl/
拷贝过去,修改为各个节点的地址
[root@wang82 work]# scp kube-scheduler.kubeconfig wang80:/etc/kubernetes/
[root@wang82 work]# scp kube-scheduler.kubeconfig wang81:/etc/kubernetes/
[root@wang82 work]# scp kube-scheduler.conf wang80:/etc/kubernetes/
[root@wang82 work]# scp kube-scheduler.conf wang81:/etc/kubernetes/
[root@wang82 work]# scp kube-scheduler.service wang80:/usr/lib/systemd/system/
[root@wang82 work]# scp kube-scheduler.service wang81:/usr/lib/systemd/system/
6 启动服务
80-82
systemctl daemon-reload
systemctl enable kube-scheduler –now
systemctl status kube-scheduler
九、工作节点配置
导入离线镜像压缩包
把三下载好的文件中的 pause-cordns.tar.gz 上传到 83 节点,手动解压镜像
[root@wang 83 ~]# docker load -i pause-cordns.tar.gz
[root@wang83 ~]# docker images
[root@wang83 ~]# ctr -n=k8s.io image import pause-cordns.tar.gz
[root@wang83 ~]# ctr -n=k8s.io image ls
1 部署 kubelet 组件
1.1 启动 TLS Bootstrapping 机制介绍
1.1.1 TLS bootstrapping 具体引导过程需要了解的知识点
1.1.2 kubelet 首次启动流程
1.1.3 Kubelet功能介绍
1.1.4 kubelet TLS bootstraping 工作流程
1.2 kubelet创建安全上下文
安装和配置 kubelet,步骤如下: 以下操作在 82 上操作
创 建 kubelet-bootstrap.kubeconfig
[root@82 work]# cd /data/work/
找到四,apiserver要加载,已经提前创建;为kubelet-bootstrap创建 token.csv 用户描述文件
[root@82 work]# BOOTSTRAP_TOKEN=$(awk -F "," '{print $1}' /etc/kubernetes/token.csv)
这里暂时先连接82的apiserver IP,最后安装好负载均衡器,统一更改为vip地址
[root@82 work]# kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://192.168.137.82:6443 --kubeconfig=kubelet-bootstrap.kubeconfig
token.csv里面预定义了token和kubelet-bootstrap用户(apiserver配置启用的准入控制),看四
[root@82 work]# kubectl config set-credentials kubelet-bootstrap --token=${BOOTSTRAP_TOKEN} --kubeconfig=kubelet-bootstrap.kubeconfig
设置默认上下文参数
[root@82 work]# kubectl config set-context default --cluster=kubernetes --user=kubelet-bootstrap --kubeconfig=kubelet-bootstrap.kubeconfig
切换为当前安全上下文,与apiserver建立TLS连接时使用
[root@82 work]# kubectl config use-context default --kubeconfig=kubelet-bootstrap.kubeconfig
1.3 Kubelet内置用户RBAC授权
[root@82 work]# kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap
1.4 创建配置文件 kubelet.json
- 定义了kubelet自身的配置
- address 替换为自己工作节点 83 的 IP 地址。
- 文件传给工作节点使用,master节点可以单独创建
- 用工作节点IP
[root@wang82 work]# cat kubelet.json
{
"kind": "KubeletConfiguration",
"apiVersion": "kubelet.config.k8s.io/v1beta1",
"authentication": {
"x509": {
"clientCAFile": "/etc/kubernetes/ssl/ca.pem"
},
"webhook": {
"enabled": true,
"cacheTTL": "2m0s"
},
"anonymous": {
"enabled": false
}
},
"authorization": {
"mode": "Webhook",
"webhook": {
"cacheAuthorizedTTL": "5m0s",
"cacheUnauthorizedTTL": "30s"
}
},
"address": "192.168.137.83", #改为工作节点IP
"port": 10250, #见1.1.3
"readOnlyPort": 10255, #见1.1.3
"cgroupDriver": "systemd",
"hairpinMode": "promiscuous-bridge",
"serializeImagePulls": false,
"featureGates": {
"RotateKubeletServerCertificate": true
},
"clusterDomain": "cluster.local.",
"clusterDNS": ["10.96.0.2"]
}
1.5 创建systemd管理service unit文件
- "cgroupDriver": "systemd"要和 containerd/docker 的驱动一致。这里我们使用containerd
[root@wang82 work]# cat kubelet.service
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=docker.service
Requires=docker.service
[Service]
WorkingDirectory=/var/lib/kubelet
ExecStart=/usr/local/bin/kubelet \
--bootstrap-kubeconfig=/etc/kubernetes/kubelet-bootstrap.kubeconfig \
--cert-dir=/etc/kubernetes/ssl \
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig \
--config=/etc/kubernetes/kubelet.json \
--container-runtime-endpoint=unix:///run/containerd/containerd.sock \
--pod-infra-container-image=k8s.gcr.io/pause:3.2 \
--alsologtostderr=true \
--logtostderr=false \
--log-dir=/var/log/kubernetes \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
注:
–hostname-override:显示名称,集群中唯一
–kubeconfig:空路径,会自动生成,后面用于连接 apiserver
–bootstrap-kubeconfig:首次启动向 apiserver 申请证书
–config:配置参数文件
–cert-dir:kubelet 证书生成目录
–pod-infra-container-image:管理 Pod 网络的容器镜像
注:kubelet.json 配置文件 address 改为各个节点的 ip 地址,在各个 work 节点上启动服务
1.5 拷贝kubelet文件传到工作节点
- kubelet-bootstrap.kubeconfig 文件,先用82的apiserver ip
- 如果有多个节点安装,拷贝过去,修改为各个节点的地址
- 先连接82的apiserver,最后安装好负载均衡器,统一更改为vip地址
[root@wang83 ~]# mkdir /etc/kubernetes/ssl -p
[root@wang82 work]# scp kubelet-bootstrap.kubeconfig kubelet.json wang83:/etc/kubernetes/ [root@wang82 work]# scp ca.pem wang83:/etc/kubernetes/ssl/
[root@wang82 work]# scp kubelet.service wang83:/usr/lib/systemd/system/
1.6 启动 kubelet 服务
[root@83 ~]# mkdir /var/lib/kubelet
[root@83 ~]# mkdir /var/log/kubernetes
[root@83 ~]# systemctl daemon-reload
[root@83 ~]# systemctl enable kubelet --now
[root@83 ~]# systemctl status kubelet
1.7 master节点Approve bootstrap 请求
确认 kubelet 服务启动成功后,接着到 80 节点上 Approve 一下 bootstrap 请求。
执行如下命令可以看到一个 worker 节点发送了一个 CSR 请求:
[root@wang82 work]# kubectl get csr
[root@wang82 work]# kubectl certificate approve node-csr-D0FczHgRpU4Wim9QA3_Rq86z7RwqzHl0KR1QDFEOGzs
[root@wang82 work]# kubectl get csr
[root@wang82 work]# kubectl get node
注意:STATUS 是 NotReady 表示还没有安装网络插件
1.3 看不到master节点
是因为为了安全,流量不打到master节点(且没有pod),故不安装kubelet组件,如果放开,按同样步骤!
2 部署 kube-proxy 组件
2.1 创建 csr 请求
[root@wang82 work]# cat kube-proxy-csr.json
{
"CN": "system:kube-proxy",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Hubei",
"L": "Wuhan",
"O": "k8s",
"OU": "system"
}
]
}
2.2 生成证书
[root@wang82 work]# 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.3 创建 kubeconfig 文件
这里暂时先连接82的apiserver IP,最后安装好负载均衡器,统一更改为vip地址
[root@wang82 work]# kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://192.168.137.82:6443 --kubeconfig=kube-proxy.kubeconfig
[root@wang82 work]# kubectl config set-credentials kube-proxy --client-certificate=kube-proxy.pem --client-key=kube-proxy-key.pem --embed-certs=true --kubeconfig=kube-proxy.kubeconfig
设置默认上下文参数
[root@wang82 work]# kubectl config set-context default --cluster=kubernetes --user=kube-proxy --kubeconfig=kube-proxy.kubeconfig
切换为当前安全上下文,与apiserver建立TLS连接时使用
[root@wang82 work]# kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
2.4 创建 kube-proxy 配置文件
IP改网段和工作节点IP
[root@wang82 work]# cat kube-proxy.yaml
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 192.168.137.83
clientConnection:
kubeconfig: /etc/kubernetes/kube-proxy.kubeconfig
clusterCIDR: 192.168.137.0/24
healthzBindAddress: 192.168.137.83:10256
kind: KubeProxyConfiguration
metricsBindAddress: 192.168.137.83:10249
mode: "ipvs"
2.5 创建服务启动文件
[root@wang82 work]# cat kube-proxy.service
[Unit]
Description=Kubernetes Kube-Proxy Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target
[Service]
WorkingDirectory=/var/lib/kube-proxy
ExecStart=/usr/local/bin/kube-proxy \
--config=/etc/kubernetes/kube-proxy.yaml \
--alsologtostderr=true \
--logtostderr=false \
--log-dir=/var/log/kubernetes \
--v=2
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
2.6 拷贝文件传到对应位置
kube-proxy.kubeconfig kube-proxy.yaml 两个文件
这里暂时先连接82的apiserver,最后安装好负载均衡器,统一更改为vip地址
[root@wang82 work]# scp kube-proxy.kubeconfig kube-proxy.yaml wang83:/etc/kubernetes/
[root@wang82 work]# scp kube-proxy.service wang83:/usr/lib/systemd/system/
2.7 启动服务
[root@wang 83 ~]# mkdir -p /var/lib/kube-proxy
[root@wang 83 ~]# systemctl daemon-reload
[root@wang 83 ~]# systemctl enable kube-proxy --now
[root@wang 83 ~]# systemctl status kube-proxy
3 部署 calico 组件
把安装 calico 需要的镜像 calico.tar.gz 传到 83 节点,手动解压:
[root@wang 83 ~]# ctr -n=k8s.io images import calico.tar.gz
上传 calico.yaml 到 80 上,使用 yaml 文件安装 calico 网络插件 。
由于master没安装kubelet,会自动调度到83,也可以把kubectl二进制文件传到83,把config文件放过去
[root@wang 80 ~]# kubectl apply -f calico.yaml
[root@wang 80 ~]# kubectl get pods -n kube-system
[root@wang83 ~]# kubectl get node
4 部署 coredns 组件
[root@wang 80 ~]# kubectl apply -f coredns.yaml
[root@wang 80 ~]# kubectl get pods -n kube-system
[root@wang 80 ~]# kubectl get svc -n kube-system
5 对apiserver系统用户 kubernetes 做授权![](https://img-blog.csdnimg.cn/direct/83fe1eb61b7b46c0b6cd8a179436672a.png)
- 前面已经为这个apiserver系统用户 kubernetes 做绑定到了对kubelet角色的权限
- 现在要为它搞一个最高权限,绑定集群管理员角色
[root@wang82 erjinzhiwenjian]# kubectl create clusterrolebinding kubernetes-kubectl --clusterrole=cluster-admin --user=kubernetes
[root@wang82 erjinzhiwenjian]# ctr -n=k8s.io images import busybox-1-28.tar.gz
[root@wang82 erjinzhiwenjian]# kubectl run busybox --image busybox:1.28 --restart=Never --rm -it busybox – sh
/ # ping www.baidu.com
PING www.baidu.com (39.156.66.18): 56 data bytes
64 bytes from 39.156.66.18: seq=0 ttl=127 time=39.3 ms #通过上面可以看到能访问网络
/ # nslookup kubernetes
Server: 10.96.0.2
Address 1: 10.96.0.2 kube-dns.kube-system.svc.cluster.local
Name: kubernetes
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
#注意:
busybox 要用指定的 busybox:1.28 版本,不能用最新版本,最新版本,nslookup 会解析不到dns 和 ip
十、安装 keepalived+nginx 实现 k8s apiserver 高可用
- Master节点扮演着总控中心的角色,通过不断与工作节点上的Kubelet和kube-proxy进行通信来维护整个集群的健康工作状态。如果Master节点故障,将无法使用kubectl工具或者API做任何集群管理。
- Master节点主要有三个服务kube-apiserver、kube-controller-manager和kube-scheduler
- 其中kube-controller-manager和kube-scheduler组件自身通过选择机制已经实现了高可用
--leader-elect:开启此准入控制器,当该组件启动多个时,自动选举(HA),所以Master高可用主要针对kube-apiserver组件,而该组件是以HTTP API提供服务,因此对他高可用与Web服务器类似,增加负载均衡器+高可用(nginx+keepalived)对其负载均衡即可,并且可水平扩容。
- 多Master架构图:
1 安装 nginx 主备
在 80 和 81 上做 nginx 主备安装
[root@80 ~]# yum install epel-release -y
[root@81 ~]# yum install epel-release -y
[root@80 ~]# yum install nginx keepalived nginx-mod-stream -y
[root@81 ~]# yum install nginx keepalived nginx-mod-stream -y
2 修改 nginx 配置文件。
主备一样
[root@wang80 etcd-v3.4.13-linux-amd64]# cat /etc/nginx/nginx.conf
[root@wang81 ~]# vim /etc/nginx/nginx.conf user nginx;
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
# 四层负载均衡,为两台Master apiserver组件提供负载均衡
stream {
log_format main '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent';
access_log /var/log/nginx/k8s-access.log main;
upstream k8s-apiserver {
server 192.168.137.80:6443 weight=5 max_fails=3 fail_timeout=30s;
server 192.168.137.81:6443 weight=5 max_fails=3 fail_timeout=30s;
server 192.168.137.82:6443 weight=5 max_fails=3 fail_timeout=30s;
}
server {
listen 16443; # 由于nginx与master节点复用,这个监听端口不能是6443,否则会冲突
proxy_pass k8s-apiserver;
}
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# server {
# listen 80 default_server;
# server_name _;
#
# location / {
# }
# }
}
- 配置文件说明:
- weight 是权重,默认是 1.权重越大接受的请求越多。
- max_falis 允许请求失败的次数,默认是 1,当超过最大次数时,返回 proxy_next_upstream 模块定义的错误。0 表示禁止失败尝试,企业场景:2-3.京东 1 次,蓝汛 10 次,根据业务需求去配置。
- fail timeout 在经历了 max_fails 次失败后,暂停服务的时间。京东是 3s,蓝汛是 3s,根据业务需求配置。常规业务 2-3 秒合理。
- 例:如果 max_fails 是 3,他就检测 3 次,如果 3 次都是 502.那么,他就会根据 fail_timeout 的值, 等待 30 秒,再去检测。
3 keepalive 配置主 keepalived
2台改一下backup
[root@wang80 etcd-v3.4.13-linux-amd64]# cat /etc/keepalived/keepalived.conf
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id NGINX_MASTER
}
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh"
}
vrrp_instance VI_1 {
state MASTER #BACKUP
interface ens33 # 修改为实际网卡名
virtual_router_id 51 # VRRP 路由 ID实例,每个实例是唯一的
priority 100 #90 # 优先级,备服务器设置 90
advert_int 1 # 指定VRRP 心跳包通告间隔时间,默认1秒
authentication {
auth_type PASS
auth_pass 1111
}
# 虚拟IP
virtual_ipaddress {
192.168.137.199/24
}
track_script {
check_nginx
}
}
4 check_nginx.sh脚本
2台一样
[root@wang80 etcd-v3.4.13-linux-amd64]# cat /etc/keepalived/check_nginx.sh
#!/bin/bash
#1、判断Nginx是否存活
counter=$(ps -ef |grep nginx | grep sbin | egrep -cv "grep|$$" )
if [ $counter -eq 0 ]; then
#2、如果不存活则尝试启动Nginx
service nginx start
sleep 2
#3、等待2秒后再次获取一次Nginx状态
counter=$(ps -ef |grep nginx | grep sbin | egrep -cv "grep|$$" )
#4、再次进行判断,如Nginx还不存活则停止Keepalived,让地址进行漂移
if [ $counter -eq 0 ]; then
service keepalived stop
fi
fi
#注:keepalived 根据脚本返回状态码(0 为工作正常,非 0 不正常)判断是否故障转移。
#注:keepalived 根据脚本返回状态码(0 为工作正常,非 0 不正常)判断是否故障转移。
5 启动服务
systemctl daemon-reload
systemctl enable nginx --now
systemctl enable nginx keepalived –now
systemctl status keepalived.service
systemctl status nginx
6 测试 vip 是否绑定成功
[root@wang80 ~]# ip a s
7 测试 keepalived:
停掉 80 上的keepalived,Vip 会漂移到 81
[root@wang80 ~]# service keepalived stop
[root@wang81 ~]# ip a s
启动 80 上的 nginx 和 keepalived,vip 又会漂移回来
[root@wang80 ~]# systemctl daemon-reload
[root@wang80 ~]# systemctl start nginx
[root@wang80 ~]# systemctl restart keepalived.service
[root@wang80 ~]# ip a s
7 Work节点修改连接VIP配置
7.1 Work节点组件连接apiserver地址修改为VIP
目前所有的 Worker Node 组件连接都还是 82 Node,如果不改为连接 VIP 走负载均衡器,那么
Master 还是单点故障。
因此接下来就是要改所有 Worker Node(kubectl get node 命令查看到的节点)组件配置文件,由原来 192.168.137.82 修改为 192.168.137.199(VIP)。
在所有 Worker Node 执行:
[root@83 ~]# sed -i 's#192.168.137.82:6443#192.168.137.199:16443#'
/etc/kubernetes/kubelet-bootstrap.kubeconfig
kubelet.kubeconfig是kubelet-bootstrap自动签发的证书
[root@83 ~]# sed -i 's#192.168.137.82:6443#192.168.137.199:16443#'
/etc/kubernetes/kubelet.kubeconfig
[root@83 ~]# sed -i 's#192.168.137.82:6443#192.168.137.199:16443#'
/etc/kubernetes/kube-proxy.kubeconfig
7.2 kubectl访问apiserver的负载均衡地址修改为VIP
80-82 修改~/.kube/config的IP地址为VIP地址
[root@83 ~]# systemctl restart kubelet kube-proxy
这样客户端连的都是VIP
高可用集群就安装好了
k8s基础11——安全控制之RBAC用户授权、RBAC用户组授权、SA程序授权_k8s 用户组-CSDN博客
十一、关于二进制K8S集群的kubeconfig文件注意点
十二、关于安全上下文注意点
安全上下文:设置集群参数+设置客户端认证参数+设置默认default上下文+设置当前上下文其中,设置默认default上下文,如果有多个集群,可以给这个上下文取名
kubectl config set-context default --cluster=kubernetes --user=kube-proxy --kubeconfig=kube-proxy.kubeconfig
十三、关于k8s客户端证书的思考
1 什么是客户端证书和服务端证书?
客户端证书:是一种用于验证客户端身份的证书。客户端证书通常由服务器信任的证书颁发机构签名,包含了公钥和与之关联的私钥。客户端使用其私钥与服务器进行身份验证,而服务器使用客户端证书中的公钥验证客户端身份。客户端证书用于证明客户端是经过授权的用户或实体。
服务端证书:是一种服务器使用的证书,用于验证服务器的身份。服务端证书也常常由证书颁发机构签名,包含了公钥和与之关联的私钥。客户端使用服务端证书中的公钥验证服务器身份,而服务器使用其私钥进行身份验证。服务端证书用于证明服务器是经过合法验证和信任的。
客户端证书和服务端证书之间的联系是,它们都是数字证书的不同应用场景。客户端证书用于客户端对服务器进行身份验证,而服务端证书用于服务器对客户端进行身份验证。它们都使用公钥和私钥,其中私钥用于对消息进行签名或对称加密,公钥用于验证签名或解密。
公钥和私钥是数字证书中的关键组成部分。公钥是由证书颁发机构签署的证书的一部分,用于验证身份和加密通信。私钥是与公钥相关联的秘密密钥,只有拥有私钥的人或实体可以进行签名和解密操作。
在客户端和服务端通信中,客户端证书和服务端证书都包含公钥和私钥,它们一起用于建立安全通信通道,验证身份,确保数据的机密性和完整性。
2 K8s中,客户端证书的解释
在 Kubernetes 中,客户端证书通常由一个证书颁发机构(Certificate Authority,CA)签署并包含了公钥和私钥。客户端证书用于身份验证和安全通信,它们是用于验证客户端身份并确保通信安全的重要组成部分。
客户端证书的生成流程一般如下:
- 创建一套k8s,CA私钥 + CA证书,证书中包含公钥,CA私钥 + CA证书 = 以下简称CA
- CA使用私钥 + 用客户端提交的csr.json文件 = 客户端私钥 + 客户端证书签名请求(Certificate Signing Request,CSR)。
- 将 CSR 提交给 CA 进行签名。CA 使用自己的私钥生成一个签名文件,并将其与 CSR 一起打包成一个证书。
- 签名后的证书包含了公钥、签名和其他元数据。
- 客户端将证书及其私钥用于与 Kubernetes API 服务器进行身份验证和通信。
- kube-controller-manager-key.pem:这是 kube-controller-manager 的私钥文件,它包含了与 kube-controller-manager 相关的私钥信息,可以用于对其他证书进行签名和加密操作。
- kube-controller-manager.pem:这是 kube-controller-manager 的证书文件,它包含了 kube-controller-manager 的证书和公钥信息。该证书已由在 CA.pem 中定义的证书颁发机构(CA)签署
3 k8s中,apiserver和controller-manager,他们的证书都是由同一个ca根证书签发,他们的证书之间的关系是什么?
在 Kubernetes 中,kube-apiserver 和 kube-controller-manager 的证书都可以由同一个 CA(证书颁发机构)签发,以确保它们之间的安全通信和身份验证。
具体而言,kube-apiserver 和 kube-controller-manager 的证书之间的关系可以概括为以下几点:
- 相互信任关系:CA 作为一个可信的第三方,会使用自己的私钥对证书进行签名,证明其信任 kube-apiserver 和 kube-controller-manager 的身份。这意味着 kube-apiserver 和 kube-controller-manager 之间是相互信任的。
- CA 的私钥和证书:CA 使用自己的私钥签发证书,这个私钥是唯一的,用于签署和验证所有证书。同时,CA 的证书(CA 证书)用于验证由它签发的证书的真实性和合法性。
- 证书链:客户端(如 kube-controller-manager)在验证服务器(如 kube-apiserver)的证书时,会追溯证书的签名链。也就是说,kube-controller-manager 会使用 CA 的根证书来验证 kube-apiserver 的证书,以确保其有效性和可信度。
总结来说,kube-apiserver 和 kube-controller-manager 的证书之间建立了相互的信任关系,并且都依赖于由同一个 CA 签发的证书。通过这种方式,它们能够在安全信任的基础上建立起安全的通信通道,并确保彼此的身份认证。
注意:在实际环境中,尽管 kube-apiserver 和 kube-controller-manager 可以使用相同的 CA,但也可以使用不同的 CA 进行证书的签发。这取决于实际部署和配置的要求。
4 kube-controller-manager
如何与 apiserver 通信?
A 使用客户端证书通信的过程
B 同时使用到kubeconfig文件的解释
5 K8s中的token
token 是一种用于身份验证和授权的令牌,属于鉴权的HTTP认证。token 在 Kubernetes 中广泛用于在不同组件之间进行身份验证,如 kubelet 进行 TLS Bootstrapping 时使用的 token,用于验证 CSR 请求的合法性。
十四、给小弟签发客户端证书
了解RBAC
1 管理一个集群
1.1 给小弟创建linux普通账户
[root@wang82 work]# useradd xiaodi
1.2 这个是集群根证书的ca-config文件
[root@wang80 ssl]# cat ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
1.3 创建证书申请文件
[root@wang82 work]#
cat > xiaodi-csr.json << EOF
{
"CN": "xiaodi",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Hubei",
"L": "Wuhan",
"O": "k8s",
"OU": "system"
}
]
}
EOF
1.4 给小弟创建客户端证书
[root@wang82 work]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes xiaodi-csr.json | cfssljson -bare xiaodi
1.5 给小弟创建kubeconfig文件
1. 填充认证要访问的集群
kubectl config set-cluster kubernetes --certificate-authority=./ca.pem --embed-certs=true --server=https://192.168.137.199:16443 --kubeconfig=/home/xiaodi/xiaodi.kubeconfig
2. 给小弟配置客户端认证
[root@wang82 work]# kubectl config set-credentials xiaodi --client-certificate=./xiaodi.pem --client-key=./xiaodi-key.pem --embed-certs=true --kubeconfig=/home/xiaodi/xiaodi.kubeconfig
3. 在小弟的kubeconfig文件中设置默认上下文
指定集群+小弟的客户端认证
[root@wang82 work]# kubectl config set-context kubernetes --cluster=kubernetes --user=xiaodi --kubeconfig=/home/xiaodi/xiaodi.kubeconfig
4. 自己先用root账户试下有无权限
没有 很好
[root@wang82 work]# kubectl get nodes --kubeconfig=/home/xiaodi/xiaodi.kubeconfig
5. 给小弟的kubeconfig文件修改账户权限
[root@wang82 work]# chown xiaodi:xiaodi /home/xiaodi/xiaodi.kubeconfig
6. 测试小弟账户是否能用
[root@wang82 work]# su xiaodi
必须要切换文件中的上下文,使用文件中的kubernetes上下文
[xiaodi@wang82]$ kubectl config use-context kubernetes --kubeconfig=xiaodi.kubeconfig
1.6 给小弟CN字段用户RBAC授权
7.1 集群四大角色,先给他集群范围的vew权限
[root@wang82 work]# kubectl get clusterrole view
[root@wang82 work]# kubectl create clusterrolebinding xiaodi-view --clusterrole=view --user=xiaodi
切回xiaodi账户,有全局view权限了
必须要切换文件中的上下文,使用文件中的kubernetes上下文
[xiaodi@wang82 ~]$ kubectl get pod -A --kubeconfig=xiaodi.kubeconfig
7.2 领导说只给它dev名称空间的pod查看权限
删除xiaodi-view角色绑定定
[root@wang82 work]# kubectl delete clusterrolebinding xiaodi-view
[root@wang82 work]# cat xiaodi-rbac.yaml
#创建角色,该角色具备什么操作权限。
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: dev
name: xiaodi-view-dev-pod-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
#绑定角色,和客户端用户绑定在一起,使客户端拥有该种角色的操作权限。
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: xiaodi-view-dev-pod-rolebinding
namespace: dev
subjects:
- kind: User
name: xiaodi
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: xiaodi-view-dev-pod-role
apiGroup: rbac.authorization.k8s.io
顺便在dev搞个busybox pod
kubectl run busybox -n dev --image=busybox:1.28 --restart=Never --quiet -- sh -c "while true; do sleep 3600; done"
切回xiaodi用户
只能查看dev ns 的pod
小弟表现不错,给他dev名称空间的,edit权限,和上面相同步骤
7.3 在其他集群使用xiaodi的kubeconfig文件可以远程操作本集群
2 管理第二个集群
第二个集群是adm安装的集群
添加第二个集群到kubeconfig文件
步骤是一样的
创建任意用户
使用第二套集群的ca根证书,创建用户的客户端证书….kubeconfig认证文件….RBAC…
放到任意其他K8S集群的节点,任何人,拿到这个文件(记得修改所有者权限)
都可以访问你所切换的上下文中的集群
2.1 添加ca-config.json文件
- adm安装的集群不是手动部署,这个文件是没的
- 这个集群名称我们定义为k8s-adm
- 时间也给久一点
[xiaodi@k8s-master-1 pki]$ cat ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"k8s-admin": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
2.2 ca证书申请文件
[xiaodi@k8s-master-1 pki]$ cat wang-csr.json
{
"CN": "xiaodi",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Hubei",
"L": "Wuhan",
"O": "k8s", # 对k8s组进行申请
"OU": "system"
}
]
}
cfssl gencert -ca=ca.crt -ca-key=ca.key -config=ca-config.json -profile=k8s-admin wang-csr.json | cfssljson -bare wang
[root@k8s-master-1 pki]# kubectl config set-cluster k8s-admin --certificate-authority=./ca.crt --embed-certs=true --server=https://192.168.157.199:16443 --kubeconfig=/root/xiaodi.kubeconfig
[root@k8s-master-1 pki]# kubectl config set-credentials wang --client-certificate=./wang.pem --client-key=./wang-key.pem --embed-certs=true --kubeconfig=/root/xiaodi.kubeconfig
[root@k8s-master-1 pki]# kubectl config set-context k8s-admin --cluster=k8s-admin --user=wang --kubeconfig=/root/xiaodi.kubeconfig
[root@k8s-master-1 pki]# kubectl create clusterrolebinding wang-view --clusterrole=view --user=wang
useradd zhang
[root@k8s-master-1 pki]# cp /root/xiaodi.kubeconfig /home/zhang/
[root@k8s-master-1 pki]# chown zhang.zhang /home/zhang/xiaodi.kubeconfig
su zhang
2.3 访问k8s-admin上下文中的集群
[zhang@k8s-master-1 ~]$ kubectl config use-context k8s-admin --kubeconfig=xiaodi.kubeconfig #先切换
[zhang@k8s-master-1 ~]$ kubectl get pod -A --kubeconfig=xiaodi.kubeconfig
2.4 访问kubernetes上下文中的集群
[zhang@k8s-master-1 ~]$ kubectl config use-context kubernetes --kubeconfig=xiaodi.kubeconfig
[zhang@k8s-master-1 ~]$ kubectl get pod -A --kubeconfig=xiaodi.kubeconfig
xiaodi.kubeconfig传到kubernetes集群
[root@k8s-master-1 pki]# scp ~/xiaodi.kubeconfig 192.168.137.83:~
[root@wang83 ~]# useradd xiao-zheng
[root@wang83 ~]# cp xiaodi.kubeconfig /home/xiao-zheng/
[root@wang83 ~]# chown xiao-zheng.xiao-zheng /home/xiao-zheng/xiaodi.kubeconfig
[xiao-zheng@wang83 ~]$ kubectl config view --kubeconfig=xiaodi.kubeconfig
[xiao-zheng@wang83 ~]$ kubectl get pod -A --kubeconfig=xiaodi.kubeconfig
[xiao-zheng@wang83 ~]$ kubectl config use-context k8s-admin --kubeconfig=xiaodi.kubeconfig
[xiao-zheng@wang83 ~]$ kubectl get pod -n kube-system --kubeconfig=xiaodi.kubeconfig
2.5 注意点
user , cluster , context都应是不同的2个
3 RBAC给用户组授权(TLS)
3.1 基本知识
- K8s user,读取客户端申请证书中的CN字段。
- K8s group用户组,读取客户端申请证书中的O字段。
- 优势:用户组的好处是无需单独为某个用户创建权限,统一为这个组名进行授权,所有的用户都以组的身份访问资源。
- 使用用户组流程
生成客户端证书时,修改里面的O字段------生成授权文件-----将O字段对应的用户组与角色绑定。
3.2 ca-config.json
这里使用adm集群演示
Xiaopan是dev组里的用户,xiaopan有独立客户端证书,独立kubeconfig文件,RBAC,dev组绑定role角色对组成员集体授权权限
[root@k8s-master-1 pki]# cat ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"k8s-admin": { #自定义集群名称
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
3.3 生成新客户端证书,O字段代表用户组, CN字段代表组里用户。
[root@k8s-master-1 pki]# cat xiaopan-csr.json
{
"CN": "xiaopan", # dev组用户
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Hubei",
"L": "Wuhan",
"O": "dev", # 用户组
"OU": "system"
}
]
}
3.4 根据新客户端证书生成授权文件,授权文件名称为xiaopan.kubeconfig。
[root@k8s-master-1 pki]# cfssl gencert -ca=ca.crt -ca-key=ca.key -config=ca-config.json -profile=k8s-admin xiaopan-csr.json | cfssljson -bare xiaopan
[root@k8s-master-1 pki]# kubectl config set-cluster k8s-admin --certificate-authority=./ca.crt --embed-certs=true --server=https://192.168.157.199:16443 --kubeconfig=/root/xiaopan.kubeconfig
[root@k8s-master-1 pki]# kubectl config set-credentials xiaopan --client-certificate=./xiaopan.pem --client-key=./xiaopan-key.pem --embed-certs=true --kubeconfig=/root/xiaopan.kubeconfig
[root@k8s-master-1 pki]# kubectl config set-context k8s-admin --cluster=k8s-admin --user=xiaopan --kubeconfig=/root/xiaopan.kubeconfig
3.5 角色和组进行绑定,指定组名。
[root@k8s-master-1 pki]# cat xiaopan-rbac.yaml
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: ms
name: xiaopan-view-springcloud-role
rules:
- apiGroups: ["", "apps"] #写为apps/v1访问失败
resources: ["pods", "deployments", "daemonsets", "services"]
verbs: ["get", "watch", "list", "update"]
---
#绑定角色,和客户端用户绑定在一起,使客户端拥有该种角色的操作权限。
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: xiaopan-view-springcloud-rolebinding
namespace: ms
subjects:
- kind: Group
name: dev
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: xiaopan-view-springcloud-role
apiGroup: rbac.authorization.k8s.io
[root@k8s-master-1 ~]# cp xiaopan.kubeconfig /home/xiaodi/
[root@k8s-master-1 ~]# chown xiaodi.xiaodi /home/xiaodi/xiaopan.kubeconfig
[root@k8s-master-1 ~]# su xiaodi && cd
3.6 测试dev组的用户可以访问定义的资源
切换kubeconfig的上下文
[xiaodi@k8s-master-1 ~]$ kubectl config use-context k8s-admin --kubeconfig=xiaopan.kubeconfig
[xiaodi@k8s-master-1 ~]$ kubectl get deploy,ds,svc -nms --kubeconfig=xiaopan.kubeconfig
3.7 将kubeconfig文件放到普通用户家目录下的~/.kube
可以看到,不需要手动指定kubeconfig文件了,只需要切换安全上下文
[xiaodi@k8s-master-1 ~]$ cp xiaopan.kubeconfig ~/.kube/config
4 RBAC给程序授权(SA)
1. ServiceAccount,简称SA,是一种用于让程序访问K8s API的服务账号。也就是后面在绑定角色时,不再写user、 group,而是写SA。
2. 当创建namespace时,会自动创建一个名为default的SA,这个SA没有绑定任何权限。(adm安装能看到,二进制看不到)
3. 当创建Pod时,若没有指定SA,会自动为pod以volume方式挂载这个default SA,在容器目录: /var/run/secrets/kubernetes.io/serviceaccount,任何一个pod都会有这个路径文件。
ca.crt文件: k8s根证书。
namespace文件:该pod在哪个命名空间下。
token文件:该pod拿此文件连接apiserver的凭据。
4. 实现方式:
创建sa-----RBAC授权------挂载sa到pod这个位置deployment.spec.template.spec.serviceAccount
[xiaodi@k8s-master-1 ~]$ kubectl explain deployment.spec.template.spec.serviceAccount
以下不再赘述