K8S二进制部署高可用集群-1.22[四]
本节前言:
本节关键字:KUBE-APISERVER、KUBECTL;
本节为部署K8S集群的"KUBE-APISERVER"组件,"KUBE-APISERVER"组件的主要作用为:提供了资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制;发往集群的所有操作命令的接入点,并负责接收、校验并响应所有的请求,是整个集群的网关;
关于"KUBECTL"组件,主要作用为:命令行工具,用于管理K8S集群;
本节开始……
一、KUBE-APISERVER组件
注意:在执行本步骤前,你应该已经将[ kubectl、kube-apiserver ]这些文件保存至"/usr/local/bin"[192.168.100.41 - 43]:
以下操作均在[192.168.100.41]进行,然后按需要推送至[192.168.100.42 - 43];开始:生成"KUBE-APISERVER"相关证书:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# 生成证书请求"kube-apiserver-csr.json" $ cd /opt/cluster/ssl $ cat > kubernetes/kube-apiserver-csr.json << "EOF" { "CN": "kube-apiserver", # 这里的定义的"CN"值相对APISERVER来说没什么特殊意义[只是一个普通的"CN"] "hosts": [ # K8S默认会提取"CN"字段的值作为用户名,这实际是指K8S"RoleBinding/ClusterRoleBinding"资源中的 "127.0.0.1", # "subjects.kind"的值为"User";例如K8S内建用户"system:kube-proxy",其相应的定义为"User" "192.168.100.41", # 所有"MASTER节点的IP" "192.168.100.42", "192.168.100.43", "192.168.100.44", # LB节点的IP "192.168.100.45", # LB节点的IP "192.168.100.40", # LB集群的VIP "10.96.0.1", # "ClusterIP的首个IP";K8S的"ClusterIP"范围"10.96.0.0/16"[--service-cluster-ip-range] "kubernetes", # 猜测此IP的作用类似网络中网关的概念 "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster", "kubernetes.default.svc.cluster.local" ], "key": { "algo": "ecdsa", "size": 256 }, "names": [ { "C": "CN", "ST": "GuangDong", "L": "GuangZhou", "O": "system:masters", # 定义的"O"值原因:APISERVER向KUBELET发起请求将复用此证书[官方有提及此配置] "OU": "LEMONSYS" # K8S默认会提取"O"字段的值作为组,这实际是指K8S"RoleBinding/ClusterRoleBinding"资源中的 } # "subjects.kind"的值为"Group";例如K8S内建用户"system:masters",其相应的定义为"Group" ] } EOF # 生成服务器密钥对 -- "kube-apiserver-key.pem"和"kube-apiserver.pem" $ cd /opt/cluster/ssl $ cfssl gencert -ca=rootca/rootca.pem -ca-key=rootca/rootca-key.pem --config=cfssl-conf.json -profile=common kubernetes/kube-apiserver-csr.json | cfssljson -bare kubernetes/kube-apiserver |
生成"TOKEN.CSV"文件,注意,这份文件的作为主要为在"工作节点[KUBELET]"在加入K8S集群的过程中,用于向"KUBE-APISERVER"申请签发证书的中间过程[发起要求签发证书的请求]:
1 2 3 4 |
# 请特别注意"kubelet-bootstrap"这个用户名 # 在后续的"KUBECTL"组件的部署过程中的某步操作与此有关!!! $ cd /opt/cluster/ssl $ echo $(head -c 16 /dev/urandom | od -An -t x | tr -d ' '),kubelet-bootstrap,10001,"system:kubelet-bootstrap" > kubernetes/kube-apiserver.token.csv |
将证书与配置文件分发至其它服务器[分发至:192.168.100.42 - 43];
1 2 |
scp -r /opt/cluster/ssl 192.168.100.42:/opt/cluster/ scp -r /opt/cluster/ssl 192.168.100.43:/opt/cluster/ |
为"KUBE-APISERVER"生成"kube-apiserver.service"启动文件;本处特别注意,此文件非通用,需要修改的地方已在下文标注,请按实际情况生成;本步操作目标[192.168.100.41 - 43]:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# 关于"--bind-address=0.0.0.0" # 本处只能配置为此值[不能配置为节点的IP]!!!这是由本示例的两个条件决定的: # --> 1、负载均衡方案的选择 # --> 2、VIP与服务的IP网段处于同一个网段 # 以上两个条件决定了"LVS"只能选择"DR"模式![其实"NAT"模式应该也可以,但应该很复杂,未测试过!] # 在"LVS"的"DR"模式下,APISERVER的"6443"至少需要监听在两个地址上["VIP:6443"及"网卡IP:6443"], # 而"--bind-address="在指定IP的情况下,默认只能绑定一个IP地址,这就是为什么本处只能配置为"0.0.0.0" # # 如果:VIP与服务的IP网段不处于同一个网段,你可以尝试使用"LVS"的"NAT"模式,使"--bind-address="可绑定指定IP; cat > /usr/lib/systemd/system/kube-apiserver.service << "EOF" [Unit] Description=Kubernetes:Apiserver After=network.target network-online.target Wants=network-online.target [Service] Restart=on-failure RestartSec=5 ExecStart=/usr/local/bin/kube-apiserver \ --runtime-config=api/all=true \ # 启用所有的API版本 --anonymous-auth=false \ # 禁用匿名请求 --bind-address=0.0.0.0 \ # API-SERVER节点监听地址 --advertise-address=192.168.100.41 \ # [修改]API-SERVER节点宣告地址 --secure-port=6443 \ # API-SERVER HTTPS 监听端口 --tls-cert-file=/opt/cluster/ssl/kubernetes/kube-apiserver.pem \ # API-SERVER的证书 --tls-private-key-file=/opt/cluster/ssl/kubernetes/kube-apiserver-key.pem \ # API-SERVER的私钥 --client-ca-file=/opt/cluster/ssl/rootca/rootca.pem \ # 用户验证客户端所提供的证书的合法所使用的CA证书 # [证书通过表示客户端是合法的,在K8S集群内的权限控制则由证书内的"CN"/"O"字段的值来控制] --etcd-cafile=/opt/cluster/ssl/rootca/rootca.pem \ # ETCD CA证书 --etcd-certfile=/opt/cluster/ssl/etcd/etcd.pem \ # ETCD 证书 --etcd-keyfile=/opt/cluster/ssl/etcd/etcd-key.pem \ # ETCD 私钥 --etcd-servers=https://192.168.100.41:2379,https://192.168.100.42:2379,https://192.168.100.43:2379 \ # ETCD集群地址 --kubelet-client-certificate=/opt/cluster/ssl/kubernetes/kube-apiserver.pem \ # 向KUBELET访问时所使用的证书[复用APISERVER的证书] --kubelet-client-key=/opt/cluster/ssl/kubernetes/kube-apiserver-key.pem \ # 向KUBELET访问时所使用的私钥[复用APISERVER的私钥] --service-account-key-file=/opt/cluster/ssl/rootca/rootca-key.pem \ # 验证客户端证书合法时使用的CA私钥? --service-account-signing-key-file=/opt/cluster/ssl/rootca/rootca-key.pem \ # 签发时所使用的签发CA私钥[1.20以上强制参数] --service-account-issuer=https://kubernetes.default.svc.cluster.local \ # 定义签发者的信息?[1.20以上强制参数] --enable-bootstrap-token-auth=true \ # 启用TOKEN认证模式 --token-auth-file=/opt/cluster/ssl/kubernetes/kube-apiserver.token.csv \ # TOKEN认证的文件位置[暂时保存至证书目录] --allow-privileged=true \ # 允许特权容器 --service-cluster-ip-range=10.96.0.0/16 \ # ClusterIP地址范围[为"Service"资源分配的IP范围] --service-node-port-range=30000-50000 \ # NODEIP允许的端口配置范围 --authorization-mode=RBAC,Node \ # 认证/授权模式[默认"AlwayAllow"] --enable-aggregator-routing=true \ # 启用聚合路由[在未运行"API-SERVER"的主机上运行"kube-proxy"则必须启用] --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \ # 启用额外的准入控制插件 --audit-log-maxage=30 \ # 审计日志配置 --audit-log-maxbackup=3 \ --audit-log-maxsize=100 \ --audit-log-path=/opt/cluster/log/kube-apiserver/audit.log \ --logtostderr=false \ # API-SERVER日志配置 --v=2 \ --log-dir=/opt/cluster/log/kube-apiserver [Install] WantedBy=multi-user.target EOF |
启动"KUBE-APISERVER"组件[192.168.100.41 - 43];注意,此时你并不能使用"kubectl"命令去从"KUBE-APISERVER"组件中获取数据,因为缺失相关配置,但你应该可以看到"KUBE-APISERVER"组件的正常启动:
1 |
systemctl daemon-reload && systemctl enable --now kube-apiserver.service && systemctl status kube-apiserver.service |
关于"KUBE-APISERVER"组件的部署至此结束~~
二、KUBECTL组件
以下操作均在[192.168.100.41]进行,然后按需要推送至[192.168.100.42 - 43];开始:生成"KUBECTL"组件的相关证书:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# 生成证书请求"kubectl-csr.json" $ cd /opt/cluster/ssl $ cat > kubernetes/kubectl-csr.json << "EOF" { "CN": "clusteradmin", # KUBECTL证书中的"CN"值没什么意义 "key": { "algo": "ecdsa", "size": 256 }, "names": [ { "C": "CN", "ST": "GuangDong", "L": "GuangZhou", "O": "system:masters", # 因为希望使用KUBECTL时有完整的集群操作权限,所以本处应配置为值"system:masters" "OU": "LEMONSYS" # K8S默认会提取"O"字段的值作为组,这实际是指K8S"RoleBinding/ClusterRoleBinding"资源中的 } # "subjects.kind"的值为"Group";例如K8S内建用户"system:masters",其相应的定义为"Group" ] } EOF # 生成服务器密钥对 -- "kubectl-key.pem" 和"kubectl.pem" $ cd /opt/cluster/ssl $ cfssl gencert -ca=rootca/rootca.pem -ca-key=rootca/rootca-key.pem --config=cfssl-conf.json -profile=common kubernetes/kubectl-csr.json | cfssljson -bare kubernetes/kubectl |
生成"KUBECTL"组件的"kubectl.kubeconfig"配置文件,注意,有了这份配置文件,你便可以在任何计算机上以超级管理员的身份对K8S集群做任何操作[前提是你可以连接到前置的负载均衡器,又或者可以连接到K8S集群的MASTER节点(需要一点小修改)],请务必保证此文件的安全性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
$ cd /opt/cluster/ssl # 关于集群名称 # "kubernetes"实际上与真正的K8S集群无关,这是KUBECONF配置文件中描述某个K8S集群信息的标记 # 关于"https://192.168.100.40:6443",如果直接在MASTER节点上使用"kubectl"命令,则将地址 # 更换为对应的"MASTER IP"更为合适 $ kubectl config set-cluster kubernetes \ # 自定义的一个集群名称[用于描述某个K8S集群] --certificate-authority=/opt/cluster/ssl/rootca/rootca.pem \ # K8S集群CA证书的位置 --embed-certs=true \ # 启用证书嵌套? --server=https://192.168.100.40:6443 \ # 高可用应指向APISERVER负载均衡器的VIP --kubeconfig=kubernetes/kubectl.kubeconfig # 指定配置写入到的目标文件 # 关于用户名称 # "clusteradmin"为定义一个用户,在KUBECONF配置文件中,这个用户用于关联一组证书; # 这个用户对K8S集群来说可以说是无意义[猜测]; # 真正重要的是证书中"O"字段与"CN"字段的定义[更多见官方文档] $ kubectl config set-credentials clusteradmin \ # 自定义的一个用户名称[用于描述一组证书] --client-certificate=/opt/cluster/ssl/kubernetes/kubectl.pem \ # 客户端证书的位置 --client-key=/opt/cluster/ssl/kubernetes/kubectl-key.pem \ # 客户端私钥的位置 --embed-certs=true \ # 启用证书嵌套? --kubeconfig=kubernetes/kubectl.kubeconfig # 指定配置写入到的目标文件 # 关于上下文 # "default"用于将KUBECONF配置文件"clusteradmin"与"kubernetes"作关联 $ kubectl config set-context default \ # 上下文的标识/名称 --cluster=kubernetes \ # 要关联的KUBECTL配置文件中的集群名称 --user=clusteradmin \ # 要关联的KUBECTL配置文件中的用户名称 --kubeconfig=kubernetes/kubectl.kubeconfig # 指定配置写入到的目标文件 # 设定KUBECTL默认使用的上下文环境 $ kubectl config use-context default \ # 设定KUBECTL默认使用的上下文环境 --kubeconfig=kubernetes/kubectl.kubeconfig # 指定配置写入到的目标文件 |
将证书与配置文件分发至其它服务器[192.168.100.42 - 43];
1 2 |
scp -r /opt/cluster/ssl 192.168.100.42:/opt/cluster/ scp -r /opt/cluster/ssl 192.168.100.43:/opt/cluster/ |
复制"kubectl.kubeconfig"至指定位置;"kubectl"命令默认使用的配置文件位置为"~/.kube/config",本处假定当前用户为"root"用户:
1 2 |
$ mkdir /root/.kube $ cp /opt/cluster/ssl/kubernetes/kubectl.kubeconfig /root/.kube/config |
测试"kubectl"命令与命令补全,你应该可以从"KUBE-APISERVER"的服务中获取到一些集群的信息:
1 2 3 4 5 6 |
$ kubectl cluster-info $ kubectl get componentstatuses $ kubectl get all --all-namespaces *、命令补全[需要退出SHELL环境重新进入] $ kubectl completion bash > /usr/share/bash-completion/completions/kubectl |
关于"KUBECTL"组件的配置至此结束~~
结、
关于"KUBE-APISERVER"与"KUBECTL"组件,本节实际上已经写了很多了,但实际上还有更更多的东西,别问博主,实际博主也了解得很少……下一节将是关于"KUBE-CONTROLLER-MANAGER"组件与"KUBE-SCHEDULER"组件的二进制部署,完成了下一节的那两个组件的部署,实际上一个MASTER节点就已经部署完成了。本篇完,读者可点击以下链接进入下一章或返回上一章;
下一章:K8S二进制部署高可用集群-1.22 [五] KUBE-CONTROLLER-MANAGER组件与KUBE-SCHEDULER组件
按你的文档操作, kube-api死活起不来。。 我醉了。 真是怀疑人生了!
2021-11-16 下午9:04本来就是很不容易,要看你用什么版本的K8S,不同版本可能还有区别,查看报错提示
2021-11-19 上午11:35