一、kube-apiserver组件部署
获取最新更新以及文章用到的软件包,请移步点击:查看更新
1、下载安装包
#下载安装包
mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}
wget https://dl.k8s.io/v1.20.1/kubernetes-server-linux-amd64.tar.gz
#解压
tar -xf kubernetes-server-linux-amd64.tar.gz
cd kubernetes/server/bin/
#复制到安装目录
cp kube-apiserver kube-controller-manager kube-scheduler /opt/kubernetes/bin
cp kubectl /usr/local/bin
#同步到其他节点
scp kube-apiserver kube-controller-manager kube-scheduler kubectl root@192.168.112.132:/opt/kubernetes/bin
scp kubectl root@192.168.112.132:/usr/local/bin
2、创建ca请求文件
cd /root/k8s
cat > ca-csr.json << EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Sichuan",
"L": "Chengdu",
"O": "k8s",
"OU": "system"
}
],
"ca": {
"expiry": "175200h"
}
}
EOF
#创建ca证书
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
注:
CN:Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法;
O:Organization,kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group)
3、配置ca证书策略
cat > ca-config.json << EOF
{
"signing": {
"default": {
"expiry": "175200h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "175200h"
}
}
}
}
EOF
创建csr请求文件
cat > kube-apiserver-csr.json << EOF
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"192.168.112.131",
"192.168.112.132",
"192.168.112.133",
"192.168.112.134",
"192.168.112.135",
"192.168.112.136",
"192.168.112.137",
"192.168.112.130",
"10.255.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": "Sichuan",
"L": "Chengdu",
"O": "k8s",
"OU": "system"
}
]
}
EOF
生成证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-apiserver-csr.json | cfssljson -bare kube-apiserver
注:
如果 hosts 字段不为空则需要指定授权使用该证书的 IP 或域名列表。
由于该证书后续被 kubernetes master 集群使用,需要将master节点的IP都填上,同时还需要填写 service 网络的首个IP。(一般是 kube-apiserver 指定的 service-cluster-ip-range 网段的第一个IP,如 10.254.0.1)
4、生成token文件
cat > token.csv << EOF
$(head -c 16 /dev/urandom | od -An -t x | tr -d ' '),kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
5、创建配置文件
cat > /opt/kubernetes/cfg/kube-apiserver.conf << EOF
KUBE_APISERVER_OPTS="--enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \\
--anonymous-auth=false \\
--bind-address=192.168.112.131 \\
--secure-port=6443 \\
--advertise-address=192.168.112.131 \\
--authorization-mode=Node,RBAC \\
--runtime-config=api/all=true \\
--enable-bootstrap-token-auth \\
--service-cluster-ip-range=10.255.0.0/16 \\
--token-auth-file=/opt/kubernetes/cfg/token.csv \\
--service-node-port-range=30000-50000 \\
--tls-cert-file=/opt/kubernetes/ssl/kube-apiserver.pem \\
--tls-private-key-file=/opt/kubernetes/ssl/kube-apiserver-key.pem \\
--client-ca-file=/opt/kubernetes/ssl/ca.pem \\
--kubelet-client-certificate=/opt/kubernetes/ssl/kube-apiserver.pem \\
--kubelet-client-key=/opt/kubernetes/ssl/kube-apiserver-key.pem \\
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--service-account-signing-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--service-account-issuer=https://kubernetes.default.svc.cluster.local \\
--etcd-cafile=/opt/etcd/ssl/ca.pem \\
--etcd-certfile=/opt/etcd/ssl/etcd.pem \\
--etcd-keyfile=/opt/etcd/ssl/etcd-key.pem \\
--etcd-servers=https://192.168.112.131:2379,https://192.168.112.132:2379,https://192.168.112.133:2379 \\
--enable-swagger-ui=true \\
--allow-privileged=true \\
--apiserver-count=3 \\
--audit-log-maxage=30 \\
--audit-log-maxbackup=3 \\
--audit-log-maxsize=100 \\
--audit-log-path=/opt/kubernetes/logs/kube-apiserver-audit.log \\
--event-ttl=1h \\
--alsologtostderr=true \\
--logtostderr=false \\
--log-dir=/opt/kubernetes/logs \\
--v=4"
EOF
注:
–logtostderr:启用日志
–v:日志等级
–log-dir:日志目录
–etcd-servers:etcd集群地址
–bind-address:监听地址
–secure-port:https安全端口
–advertise-address:集群通告地址
–allow-privileged:启用授权
–service-cluster-ip-range:Service虚拟IP地址段
–enable-admission-plugins:准入控制模块
–authorization-mode:认证授权,启用RBAC授权和节点自管理
–enable-bootstrap-token-auth:启用TLS bootstrap机制
–token-auth-file:bootstrap token文件
–service-node-port-range:Service nodeport类型默认分配端口范围
–kubelet-client-xxx:apiserver访问kubelet客户端证书
–tls-xxx-file:apiserver https证书
–etcd-xxxfile:连接Etcd集群证书
–audit-log-xxx:审计日志
6、创建服务启动文件
cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=etcd.service
Wants=etcd.service
[Service]
EnvironmentFile=-/opt/kubernetes/cfg/kube-apiserver.conf
ExecStart=/opt/kubernetes/bin/kube-apiserver $KUBE_APISERVER_OPTS
Restart=on-failure
RestartSec=5
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
7、同步相关文件到各个节点
cp ca*.pem kube-apiserver*.pem /opt/kubernetes/ssl/
cp token.csv kube-apiserver.conf /opt/kubernetes/cfg/
scp /usr/lib/systemd/system/kube-apiserver.service root@192.168.112.132:/usr/lib/systemd/system/
scp ca*.pem kube-apiserver*.pem root@192.168.112.132:/opt/kubernetes/ssl/
scp token.csv root@192.168.112.132:/opt/kubernetes/cfg/
注:master2和master3配置文件的IP地址修改为实际的本机IP
启动服务
systemctl daemon-reload
systemctl enable kube-apiserver
systemctl restart kube-apiserver
systemctl status kube-apiserver
测试
curl --insecure https://192.168.112.131:6443/
有返回说明启动正常
二、部署kubectl组件
1、创建csr请求文件
cat > admin-csr.json << EOF
{
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Sichuan",
"L": "Chengdu",
"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
#同步证书
cp admin*.pem /opt/kubernetes/ssl/
scp admin*.pem root@192.168.112.132:/opt/kubernetes/ssl/
说明:
后续 kube-apiserver 使用 RBAC 对客户端(如 kubelet、kube-proxy、Pod)请求进行授权;
kube-apiserver 预定义了一些 RBAC 使用的 RoleBindings,如 cluster-admin 将 Group system:masters 与 Role cluster-admin 绑定,该 Role 授予了调用kube-apiserver 的所有 API的权限;
O指定该证书的 Group 为 system:masters,kubelet 使用该证书访问 kube-apiserver 时 ,由于证书被 CA 签名,所以认证通过,同时由于证书用户组为经过预授权的 system:masters,所以被授予访问所有 API 的权限;
注:
这个admin 证书,是将来生成管理员用的kube config 配置文件用的,现在我们一般建议使用RBAC 来对kubernetes 进行角色权限控制, kubernetes 将证书中的CN 字段 作为User, O 字段作为 Group;
“O”: “system:masters”, 必须是system:masters,否则后面kubectl create clusterrolebinding报错。
2、创建kubeconfig配置文件
kubeconfig 为 kubectl 的配置文件,包含访问 apiserver 的所有信息,如 apiserver 地址、CA 证书和自身使用的证书
设置集群参数
kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://192.168.112.130:7443 --kubeconfig=kube.config
设置客户端认证参数
kubectl config set-credentials admin --client-certificate=admin.pem --client-key=admin-key.pem --embed-certs=true --kubeconfig=kube.config
设置上下文参数
kubectl config set-context kubernetes --cluster=kubernetes --user=admin --kubeconfig=kube.config
设置默认上下文
kubectl config use-context kubernetes --kubeconfig=kube.config
mkdir ~/.kube
cp kube.config ~/.kube/config
同步kubectl配置文件到其他节点
scp -r /root/.kube root@192.168.112.132:/root/
四、安装nginx和keepalived,对apiserver做高可用负载
1、在两台master节点安装nginx
#编辑yum文件
vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
#安装最新版nginx
yum install nginx -y
#编辑nginx配置文件,nginx四层负载,必须与http同级
vi /etc/nginx/nginx.conf
stream {
upstream kube-apiserver {
server 192.168.112.131:6443 max_fails=3 fail_timeout=30s;
server 192.168.112.132:6443 max_fails=3 fail_timeout=30s;
}
server {
listen 7443;
proxy_connect_timeout 2s;
proxy_timeout 900s;
proxy_pass kube-apiserver;
}
}
#启动nginx
nginx -t
systemctl start nginx
systemctl enable nginx
2、部署keepalived实现高可用
#安装keepalived
yum install keepalived -y
#编写keepalived监控脚本
vi /etc/keepalived/check_port.sh
#!/bin/bash
#keepalived 监控端口脚本
#使用方法:
#在keepalived的配置文件中
#vrrp_script check_port {#创建一个vrrp_script脚本,检查配置
# script "/etc/keepalived/check_port.sh 6379" #配置监听的端口
# interval 2 #检查脚本的频率,单位(秒)
#}
CHK_PORT=$1
if [ -n "$CHK_PORT" ];then
PORT_PROCESS=`ss -lnt|grep $CHK_PORT|wc -l`
if [ $PORT_PROCESS -eq 0 ];then
echo "Port $CHK_PORT Is Not Used,End."
exit 1
fi
else
echo "Check Port Cant Be Empty!"
fi
#对监控脚本授权
chmod +x /etc/keepalived/check_port.sh
#编辑keepalived配置文件,注意主从配置文件不一样
vi /etc/keepalived/keepalived.conf
主节点:
! Configuration File for keepalived
global_defs {
router_id 192.168.112.131
}
vrrp_script chk_nginx {
script "/etc/keepalived/check_port.sh 7443"
interval 2
weight -20
}
vrrp_instance VI_1 {
state MASTER
interface ens192 修改网卡名字
virtual_router_id 251
priority 100
advert_int 1
mcast_src_ip 192.168.112.131
nopreempt #非抢占式 ,当主节点挂了以后,从节点vip飘到从上,主节点恢复以后,不主动飘回主,需要手动重启keepalived
authentication {
auth_type PASS
auth_pass 11111111
}
track_script {
chk_nginx
}
virtual_ipaddress {
192.168.112.130
}
}
从节点:
! Configuration File for keepalived
global_defs {
router_id 192.168.112.132
}
vrrp_script chk_nginx {
script "/etc/keepalived/check_port.sh 7443"
interval 2
weight -20
}
vrrp_instance VI_1 {
state BACKUP
interface ens192 修改网卡名字
virtual_router_id 251
mcast_src_ip 192.168.112.132
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 11111111
}
track_script {
chk_nginx
}
virtual_ipaddress {
192.168.112.130
}
}
#启动keepalived并配置开机自启
systemctl start keepalived
systemctl enable keepalived
#检查ip地址
[root@clihouse01 ~]# ip -4 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
inet 192.168.112.131/24 brd 192.168.112.255 scope global noprefixroute ens192
valid_lft forever preferred_lft forever
inet 192.168.112.130/32 scope global ens192 会多一个VIP
valid_lft forever preferred_lft forever
五、验证集群
#授权kubernetes证书访问kubelet api权限
kubectl create clusterrolebinding kube-apiserver:kubelet-apis --clusterrole=system:kubelet-api-admin --user kubernetes
#查看集群组件状态
kubectl cluster-info
kubectl get componentstatuses
kubectl get all --all-namespaces