二进制方式安装K8S
1 节点信息
IP地址 | 主机名称 | DNS记录 | 类型 | 系统 |
---|---|---|---|---|
192.168.122.10 | node1 | node1 | Worker Node/etcd | centos7 |
192.168.122.11 | node2 | node2 | Worker Node | centos7 |
192.168.122.12 | node3 | node3 | Master Node/etcd/nginx | centos8 |
192.168.122.13 | node4 | node4 | Master Node/etcd/nginx | centos8 |
192.168.122.2 | k8s.api | vrrp | ||
10.110.0.0/16 | k8s service | |||
10.120.0.0/16 | k8s pod |
电脑配置较低,这么多虚拟机跑不动,所以这一套高可用集群分两部分实施,先部署一套单Master架构(192.168.122.12),再扩容为多Master架构(上述规划),顺便熟悉下Master扩容流程
1.1 初始化节点
尽管主节点中包含etcd端口,但您也可以在外部或自定义端口上托管您自己的etcd集群
|
|
防火墙放行的端口介绍:
协议 | 方向 | 港口范围 | 目的 | 使用 |
---|---|---|---|---|
TCP | 入站 | 6443*,8080* | Kubernetes API server | 所有 |
TCP | 入站 | 2379-2380 | etcd server client API | etcd |
TCP | 入站 | 10250 | Kubelet API | 本机,控制平面组件 |
TCP | 入站 | 10251 | kube-scheduler | 本机 |
TCP | 入站 | 10252 | kube-controller-manager | 本机 |
TCP | 入站 | 30000-32767 | NodePort Services** | 所有node节点 |
NodePort Services的默认端口范围。
使用 * 标记的端口号都可以自定义的,所以您需要保证所自定义的端口是开放的。
2 安装ETCD集群
参考 etcd安装配置 , 拷贝客户端证书到kubernetes server节点的/opt/kubernetes/ssl/
目录下;
我的客户端证书:etcd-client.crt
etcd-client.key
etcd-ca.crt
3 PKI证书管理
可以参考官方文档:https://kubernetes.io/zh/docs/setup/best-practices/certificates/来生成证书
注意: 证书我是在server1(192.168.122.12)上进行生成管理的
证书的O和CN字段在RBAC授权的时候被认为是组
和用户
,所以请不要随意更改,不然RBAC预定义角色无法匹配,导致授权失败
3.1 创建CA
另外还需要获取用于服务账户管理的密钥对,也就是sa.key和sa.pub。
路径 | 默认 CN | 描述 |
---|---|---|
kube-ca.crt,key | kubernetes-ca | Kubernetes 通用 CA |
front-proxy-ca.crt,key | kubernetes-front-proxy-ca | 用于 [前端代理][proxy] |
kubernetes-ca
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
mkdir -p ~/ca/{kube-ca,kube-proxy-ca} cd ~/ca/kube-ca openssl genrsa -out kube-ca.key 2048 openssl req -extensions v3_ca \ -subj "/C=CN/ST=ShangHai/L=ShangHai/O=net-cc.com/OU=net-cc.com/CN=kubernetes-ca/[email protected]" \ -new -x509 -days 14500 -sha256 \ -key=kube-ca.key -out kube-ca.crt # 创建证书签名用的配置文件 cat > kubernetes-ca.conf<<EOF # 用来对服务端证书签名 [ req_server ] subjectKeyIdentifier = hash basicConstraints = CA:FALSE authorityKeyIdentifier = keyid,issuer:always keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth,serverAuth subjectAltName = @alt_names # dns中kubernetes开头的是APIserver需要用到的记录 # 要包含所有master节点和负载均衡的IP地址、DNS记录 [ alt_names ] DNS.1 = kubernetes DNS.2 = kubernetes.default DNS.3 = kubernetes.default.svc DNS.4 = kubernetes.default.svc.cluster DNS.5 = kubernetes.default.svc.cluster.local DNS.6 = localhost DNS.7 = node3 DNS.8 = node4 DNS.9 = k8s.api IP.1 = 192.168.122.12 IP.2 = 192.168.122.13 IP.3 = 192.168.122.2 IP.4 = 127.0.0.1 IP.5 = 10.110.0.1 # 用来对客户端证书签名 [ req_client ] subjectKeyIdentifier = hash basicConstraints = CA:FALSE authorityKeyIdentifier = keyid,issuer:always keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth EOF # 更改权限 chmod 444 kube-ca.crt chmod 400 kube-ca.key
kubernetes-front-proxy-ca
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
cd ~/ca/kube-proxy-ca openssl genrsa -out front-proxy-ca.key 2048 openssl req -extensions v3_ca \ -subj "/C=CN/ST=ShangHai/L=ShangHai/O=net-cc.com/OU=net-cc.com/CN=kubernetes-front-proxy-ca/[email protected]" \ -new -x509 -days 14500 -sha256 \ -key=front-proxy-ca.key -out front-proxy-ca.crt # 创建证书签名用的配置文件 cat > front-proxy-ca.conf<<EOF # 用来对客户端证书签名 [ req_client ] subjectKeyIdentifier = hash basicConstraints = CA:FALSE authorityKeyIdentifier = keyid,issuer:always keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth EOF # 更改证书/密钥权限为只读 chmod 444 front-proxy-ca.crt chmod 400 front-proxy-ca.key
3.2 Server证书
两台api server我共用了证书,所以SAN的hostname
,host_ip
,advertise_ip
我写了所有主机的名字;
默认 CN | 父级 CA | O (位于 Subject 中) | 类型 | 主机 (SAN) |
---|---|---|---|---|
kube-apiserver | kubernetes-ca | server | [hostname], [Host_IP], [advertise_IP], 注:1 | |
kube-apiserver-kubelet-client | kubernetes-ca | system:masters | client | |
front-proxy-client | kubernetes-front-proxy-ca | client |
注1: kubeadm为负载均衡所使用的固定IP或 NS名: kubernetes、kubernetes.default、kubernetes.default.svc、 kubernetes.default.svc.cluster、kubernetes.default.svc.cluster.local
apiserver证书
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
mkdir -p ~/ca/kube-ca/{apiserver,kubeconfig,kubelet} cd ~/ca/kube-ca/apiserver # 创建密钥 openssl genrsa -out apiserver.key 2048 # 创建证书请求文件 openssl req -new -sha256 \ -subj "/C=CN/ST=ShangHai/L=ShangHai/O=net-cc.com/OU=net-cc.com/CN=kube-apiserver/[email protected]" \ -key apiserver.key -out apiserver.csr # 使用kubernetes-ca进行签名获取带有SAN扩展的证书 openssl x509 -in apiserver.csr -out apiserver.crt \ -CA ../kube-ca.crt -CAkey ../kube-ca.key -CAcreateserial \ -req -sha256 -days 7300 \ -extfile ../kubernetes-ca.conf -extensions req_server # 权限 rm -f apiserver.csr chmod 400 apiserver.key chmod 444 apiserver.crt
apiserver-kubelet-client证书
apiserver访问kubelet的证书密钥对(RBAC会针对
system:masters
用户进行授权)1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
cd ~/ca/kube-ca/apiserver # 创建密钥 openssl genrsa -out apiserver-kubelet-client.key 2048 # 创建证书请求文件 openssl req -new -sha256 \ -subj "/C=CN/ST=ShangHai/L=ShangHai/O=net-cc.com/OU=net-cc.com/CN=system:masters/[email protected]" \ -key apiserver-kubelet-client.key -out apiserver-kubelet-client.csr # 使用kubernetes-ca进行签名 openssl x509 -in apiserver-kubelet-client.csr -out apiserver-kubelet-client.crt \ -CA ../kube-ca.crt -CAkey ../kube-ca.key -CAcreateserial \ -req -sha256 -days 7300 -extfile ../kubernetes-ca.conf -extensions req_client rm -f apiserver-kubelet-client.csr chmod 400 apiserver-kubelet-client.key chmod 444 apiserver-kubelet-client.crt
kubelet服务证书
kubelet也启用https了,所以要给他生成一个证书,外部访问kubelet的的程序可以根据kube-ca进行验证kubelet的服务证书,例如安装metrics-server性能指标监控程序的时候,他需要验证kubelet证书
注意:DNS和IP要写所有的安装kubelet节点的ip和主机名称
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
cd ~/ca/kube-ca/kubelet # 创建密钥 openssl genrsa -out kubelet.key 2048 # 创建证书请求文件 openssl req -new -sha256 \ -subj "/C=CN/ST=ShangHai/L=ShangHai/O=net-cc.com/OU=net-cc.com/CN=kube-kubelet/[email protected]" \ -key kubelet.key -out kubelet.csr # 创建证书签名用的配置文件 cat > kubelet-cert.conf<<EOF # 用来对服务端证书签名 [ req_server ] subjectKeyIdentifier = hash basicConstraints = CA:FALSE authorityKeyIdentifier = keyid,issuer:always keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names # 要包含所有worker节点的IP地址、DNS记录 [ alt_names ] DNS.1 = localhost DNS.2 = node1 DNS.3 = node2 IP.1 = 192.168.122.10 IP.2 = 192.168.122.11 IP.3 = 127.0.0.1 EOF # 使用kubernetes-ca进行签名获取带有SAN扩展的证书 openssl x509 -in kubelet.csr -out kubelet.crt \ -CA ../kube-ca.crt -CAkey ../kube-ca.key -CAcreateserial \ -req -sha256 -days 7300 \ -extfile kubelet-cert.conf -extensions req_server # 权限 rm -f kubelet.csr chmod 400 kubelet.key chmod 444 kubelet.crt
front-proxy-client证书
只有当你运行kube-proxy并要支持扩展API服务器时,才需要front-proxy证书
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
mkdir ~/ca/kube-proxy-ca/front-proxy-client cd ~/ca/kube-proxy-ca/front-proxy-client # 创建密钥 openssl genrsa -out front-proxy-client.key 2048 # 创建证书请求文件 openssl req -new -sha256 \ -subj "/C=CN/ST=ShangHai/L=ShangHai/O=net-cc.com/OU=net-cc.com/CN=front-proxy-client/[email protected]" \ -key front-proxy-client.key -out front-proxy-client.csr # 使用中间CA进行签名 openssl x509 -in front-proxy-client.csr -out front-proxy-client.crt \ -CA ../front-proxy-ca.crt -CAkey ../front-proxy-ca.key -CAcreateserial \ -req -sha256 -days 7300 -extfile ../front-proxy-ca.conf -extensions req_client rm -f front-proxy-client.csr chmod 400 front-proxy-client.key chmod 444 front-proxy-client.crt
服务账户管理的密钥对
1 2 3 4 5
cd ~/ca/kube-ca/apiserver openssl genrsa -out sa.key 2048 openssl rsa -in sa.key -pubout -out sa.pub chmod 400 sa.key chmod 444 sa.pub
3.3 用户证书
用户证书是kubectl、kubelet、kube-controller-manager、kube-scheduler等程序连接API server时候用到的客户端证书,可以直接写入配置文件,不需要拷贝证书/密钥到节点上,
使用kubectl创建连接apiserver的配置文件,等配置生成完后复制admin.conf
到~/.kube/config
, 然后删除KUBECONFIG
的环境变量即可恢复kubectl对apiserver的访问
配置文件信息
文件名 命令 凭据名称 默认 CN O (位于 Subject 中) 说明 admin.conf kubectl default-admin kubernetes-admin system:masters 配置集群的管理员 kubelet.conf kubelet default-auth system:node:[nodeName] (参阅注释) system:nodes 集群中的每个节点都需要一份,配置了连接API Server等的参数 controller-manager.conf kube-controller-manager default-controller-manager system:kube-controller-manager 必需添加到 manifests/kube-controller-manager.yaml
清单中scheduler.conf kube-scheduler default-scheduler system:kube-scheduler 必需添加到 manifests/kube-scheduler.yaml
清单中proxy.conf kube-proxy default-proxy system:kube-proxy 集群中的每个节点都需要一份,配置了连接API Server等的参数proxy 注释:kubelet.conf中[nodeName]的值必须与kubelet向apiserver注册时提供的节点名称的值完全匹配。 有关更多详细信息,请阅读节点授权。
安装kubectl
k8s集群管理工具
1 2 3 4 5 6 7 8
cd /tmp wget https://dl.k8s.io/v1.19.1/kubernetes-client-linux-amd64.tar.gz tar -zxf kubernetes-client-linux-amd64.tar.gz cp kubernetes/client/bin/kubectl /usr/bin/ rm -rf kubernetes* # kubectl命令补全 echo 'eval "$(kubectl completion bash)"' >> ~/.bashrc source ~/.bashrc
admin.conf
kubectl客户端连接apiserver时候使用的配置文件
kubectl客户端默认调用
~/.kube/config
的配置文件可以通过
KUBECONFIG
变量来控制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
mkdir ~/ca/kube-ca/kubeconfig cd ~/ca/kube-ca/kubeconfig # 创建密钥 openssl genrsa -out kube-admin.key 2048 # 创建证书请求文件 openssl req -new -sha256 \ -subj "/C=CN/ST=ShangHai/L=ShangHai/O=system:masters/OU=net-cc.com/CN=kubernetes-admin/[email protected]" \ -key kube-admin.key -out kube-admin.csr # 使用中间CA进行签名 openssl x509 -in kube-admin.csr -out kube-admin.crt \ -CA ../kube-ca.crt -CAkey ../kube-ca.key -CAcreateserial \ -req -sha256 -days 7300 \ -extfile ../kubernetes-ca.conf -extensions req_client rm -f kube-admin.csr chmod 400 kube-admin.key chmod 444 kube-admin.crt # 把证书直接写道配置文件中,客户端不用保留证书了,(`--embed-certs`控制) export KUBECONFIG=admin.conf kubectl config set-cluster default-cluster --server=https://node3:6443 --certificate-authority ../kube-ca.crt --embed-certs kubectl config set-credentials default-admin --client-key kube-admin.key --client-certificate kube-admin.crt --embed-certs kubectl config set-context default-system --cluster default-cluster --user default-admin kubectl config use-context default-system
kubelet.conf
两个Worker节点,node1我使用手动生成证书的方式
node2我使用自动签发证书的方式,所以这里未生成证书
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
cd ~/ca/kube-ca/kubeconfig export NODENAME=node1 # 创建密钥 openssl genrsa -out kube-kubelet-$NODENAME.key 2048 # 创建证书请求文件 openssl req -new -sha256 \ -subj "/C=CN/ST=ShangHai/L=ShangHai/O=system:nodes/OU=net-cc.com/CN=system:node:$NODENAME/[email protected]" \ -key kube-kubelet-$NODENAME.key -out kube-kubelet-$NODENAME.csr # 使用kubernetes-ca进行签名 openssl x509 -in kube-kubelet-$NODENAME.csr -out kube-kubelet-$NODENAME.crt \ -CA ../kube-ca.crt -CAkey ../kube-ca.key -CAcreateserial \ -req -sha256 -days 7300 \ -extfile ../kubernetes-ca.conf -extensions req_client rm -f kube-kubelet-$NODENAME.csr chmod 400 kube-kubelet-$NODENAME.key chmod 444 kube-kubelet-$NODENAME.crt # 把证书直接写道配置文件中,客户端不用保留证书了,(`--embed-certs`控制) export KUBECONFIG=kubelet-$NODENAME.conf kubectl config set-cluster default-cluster --server=https://node3:6443 --certificate-authority ../kube-ca.crt --embed-certs kubectl config set-credentials default-auth --client-key kube-kubelet-$NODENAME.key --client-certificate kube-kubelet-$NODENAME.crt --embed-certs kubectl config set-context default-system --cluster default-cluster --user default-auth kubectl config use-context default-system
proxy.conf
所有Worker节点的kube-proxy程序可以共用这一个配置文件,所以生成一次即可
注意:证书的CN不要变更
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
cd ~/ca/kube-ca/kubeconfig # 创建密钥 openssl genrsa -out kube-proxy.key 2048 # 创建证书请求文件 openssl req -new -sha256 \ -subj "/C=CN/ST=ShangHai/L=ShangHai/O=net-cc.com/OU=net-cc.com/CN=system:kube-proxy/[email protected]" \ -key kube-proxy.key -out kube-proxy.csr # 使用kubernetes-ca进行签名 openssl x509 -in kube-proxy.csr -out kube-proxy.crt \ -CA ../kube-ca.crt -CAkey ../kube-ca.key -CAcreateserial \ -req -sha256 -days 7300 \ -extfile ../kubernetes-ca.conf -extensions req_client rm -f kube-proxy.csr chmod 400 kube-proxy.key chmod 444 kube-proxy.crt # 把证书直接写道配置文件中,客户端不用保留证书了,(`--embed-certs`控制) cd ~/ca/kube-ca/kubeconfig export KUBECONFIG=proxy.conf kubectl config set-cluster default-cluster --server=https://node3:6443 --certificate-authority ../kube-ca.crt --embed-certs kubectl config set-credentials default-proxy --client-key kube-proxy.key --client-certificate kube-proxy.crt --embed-certs kubectl config set-context default-system --cluster default-cluster --user default-proxy kubectl config use-context default-system
controller-manager.conf
注意:证书的CN不要变更
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
cd ~/ca/kube-ca/kubeconfig # 创建密钥 openssl genrsa -out kube-controller-manager.key 2048 # 创建证书请求文件 openssl req -new -sha256 \ -subj "/C=CN/ST=ShangHai/L=ShangHai/O=net-cc.com/OU=net-cc.com/CN=system:kube-controller-manager/[email protected]" \ -key kube-controller-manager.key -out kube-controller-manager.csr # 使用kubernetes-ca进行签名 openssl x509 -in kube-controller-manager.csr -out kube-controller-manager.crt \ -CA ../kube-ca.crt -CAkey ../kube-ca.key -CAcreateserial \ -req -sha256 -days 7300 \ -extfile ../kubernetes-ca.conf -extensions req_client rm -f kube-controller-manager.csr chmod 400 kube-controller-manager.key chmod 444 kube-controller-manager.crt # 把证书直接写道配置文件中,客户端不用保留证书了,(`--embed-certs`控制) cd ~/ca/kube-ca/kubeconfig export KUBECONFIG=controller-manager.conf kubectl config set-cluster default-cluster --server=https://localhost:6443 --certificate-authority ../kube-ca.crt --embed-certs kubectl config set-credentials default-controller-manager --client-key kube-controller-manager.key --client-certificate kube-controller-manager.crt --embed-certs kubectl config set-context default-system --cluster default-cluster --user default-controller-manager kubectl config use-context default-system
scheduler.conf
注意:证书的CN不要变更
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
cd ~/ca/kube-ca/kubeconfig # 创建密钥 openssl genrsa -out kube-scheduler.key 2048 # 创建证书请求文件 openssl req -new -sha256 \ -subj "/C=CN/ST=ShangHai/L=ShangHai/O=net-cc.com/OU=net-cc.com/CN=system:kube-scheduler/[email protected]" \ -key kube-scheduler.key -out kube-scheduler.csr # 使用kubernetes-ca进行签名 openssl x509 -in kube-scheduler.csr -out kube-scheduler.crt \ -CA ../kube-ca.crt -CAkey ../kube-ca.key -CAcreateserial \ -req -sha256 -days 7300 \ -extfile ../kubernetes-ca.conf -extensions req_client rm -f kube-scheduler.csr chmod 400 kube-scheduler.key chmod 444 kube-scheduler.crt # 把证书直接写道配置文件中,客户端不用保留证书了,(`--embed-certs`控制) export KUBECONFIG=scheduler.conf kubectl config set-cluster default-cluster --server=https://localhost:6443 --certificate-authority ../kube-ca.crt --embed-certs kubectl config set-credentials kube-scheduler --client-key kube-scheduler.key --client-certificate kube-scheduler.crt --embed-certs kubectl config set-context default-system --cluster default-cluster --user kube-scheduler kubectl config use-context default-system
3.4 复制证书到各节点
server节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# 复制kube-apiserver证书/密钥到两个server节点 cd ~/ca/kube-ca/apiserver cp ../kube-ca.crt apiserver.crt apiserver-kubelet-client.crt sa.pub /opt/kubernetes/ssl/ cp ../kube-ca.key apiserver.key apiserver-kubelet-client.key sa.key /opt/kubernetes/ssl/ scp ../kube-ca.crt apiserver.crt apiserver-kubelet-client.crt sa.pub root@node4:/opt/kubernetes/ssl/ scp ../kube-ca.key apiserver.key apiserver-kubelet-client.key sa.key root@node4:/opt/kubernetes/ssl/ # 复制front-proxy-client证书/密钥到两个server节点 cd ~/ca/kube-proxy-ca/front-proxy-client cp front-proxy-client.key front-proxy-client.crt ../front-proxy-ca.crt /opt/kubernetes/ssl/ scp front-proxy-client.key front-proxy-client.crt ../front-proxy-ca.crt root@node4:/opt/kubernetes/ssl/ # 复制controller-manager、scheduler连接配置文件到所有server节点 cd ~/ca/kube-ca/kubeconfig mkdir ~/.kube/ unset KUBECONFIG # 恢复kubectl的环境变量 cp admin.conf ~/.kube/config cp controller-manager.conf scheduler.conf /opt/kubernetes/etc/ scp controller-manager.conf scheduler.conf root@node4:/opt/kubernetes/etc/
node节点
1 2 3 4 5 6 7
# 复制kubelet配置文件到所有node节点 cd ~/ca/kube-ca/kubeconfig scp kubelet-node1.conf proxy.conf root@node1:/opt/kubernetes/etc/ # 复制kubelet的服务证书 cd ~/ca/kube-ca/kubelet scp ../kube-ca.crt kubelet.crt kubelet.key root@node1:/opt/kubernetes/ssl/ scp ../kube-ca.crt kubelet.crt kubelet.key root@node2:/opt/kubernetes/ssl/
node节点现有文件
1 2 3 4 5 6 7 8 9 10 11 12 13
tree /opt/kubernetes /opt/kubernetes ├── bin ├── data ├── etc │ └── kubelet-node1.conf # node1才有,node2没有 │ └── proxy.conf | └── conf.d ├── logs └── ssl │ └── kube-ca.crt │ └── kubelet.crt │ └── kubelet.key
Master节点现有文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
$ tree /opt/kubernetes /opt/kubernetes ├── bin ├── data ├── etc │ ├── controller-manager.conf │ └── scheduler.conf ├── logs └── ssl ├── apiserver.crt ├── apiserver.key ├── apiserver-kubelet-client.crt ├── apiserver-kubelet-client.key ├── etcd-ca.crt ├── etcd-client.crt ├── etcd-client.key ├── front-proxy-client.crt ├── front-proxy-client.key ├── front-proxy-ca.crt ├── kube-ca.key ├── kube-ca.crt ├── sa.key └── sa.pub
4 部署Master Node(主)
下边是一些公共参数,主要是日志配置,节点上的所有程序都调用了
|
|
--logtostderr
: 设置为false表示将日志写入文件,不写入stderr--log-dir
: 日志目录--v
: 日志等级
先安装一个主Master节点,另一个等单节点集群创建成功后在添加
4.1 下载程序
|
|
5 部署API Server
主节点上负责提供 Kubernetes API 服务的组件;它是 Kubernetes 控制面的前端。
5. systemd服务
|
|
5.2 配置文件
|
|
配置文件说明:
--storage-backend
: 指定etcd的版本--etcd-servers
: etcd服务的URL--etcd-*file
: 连接etcd的证书和密钥--advertise-address
: 集群通告地址--secure-port
: API Server绑定主机安全端口号,默认为6443--service-cluster-ip-range
: Kubernetes集群中Service的虚拟IP地址范围,该IP范围不能与物理机的IP地址有重合。--service-node-port-range
: Kubernetes集群中Service可使用的物理机端口号范围,默认值为30000~32767--allow-privileged
: 启用授权authorization-mode
: 认证授权,启用RBAC授权和节点自管理audit-log*
: 审计日志--enable-admission-plugins
: Kubernetes集群的准入控制设置,各控制模块以插件的形式依次生效。默认启用的有(NamespaceLifecycle, LimitRanger, ServiceAccount, TaintNodesByCondition, Priority, DefaultTolerationSeconds, DefaultStorageClass, StorageObjectInUseProtection, PersistentVolumeClaimResize, RuntimeClass, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, MutatingAdmissionWebhook, ValidatingAdmissionWebhook, ResourceQuota)--runtime-config
: 传递给 apiserver 用于描述运行时配置的键值对集合。 apis/键可以被用来打开/关闭特定的 api 版本。apis/ / 键被用来打开/关闭特定的资源 . api/all 和 api/legacy 键分别用于控制所有的和遗留的 api 版本 --client-ca-file
: 对于任何请求,如果存包含client-ca-file中的authorities签名的客户端证书,将会使用客户端证书中的 CommonName 对应的身份进行认证--kubelet-client-*
: apiserver访问kubelet客户端证书--tls-*-file
: apiserver https证书--service-account-key-file
: 服务帐户密钥对--enable-bootstrap-token-auth
: 允许 ‘kube-system’ 命名空间中的 ‘bootstrap.kubernetes.io/token’ 类型密钥可以被用于 TLS 的启动认证--token-auth-file
: 这个文件将被用于通过令牌认证来保护 API 服务的安全端口
6 部署Controller Manager
在主节点上运行控制器的组件。
从逻辑上讲,每个控制器都是一个单独的进程,但是为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行。
这些控制器包括:
- 节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应。
- 副本控制器(Replication Controller): 负责为系统中的每个副本控制器对象维护正确数量的 Pod。
- 端点控制器(Endpoints Controller): 填充端点(Endpoints)对象(即加入 Service 与 Pod)。
- 服务帐户和令牌控制器(Service Account & Token Controllers): 为新的命名空间创建默认帐户和 API 访问令牌.
6.1 systemd服务
|
|
6.2 配置文件
|
|
配置文件说明:
--leader-elect
:当该组件启动多个时,自动选举(HA)--kubeconfig
: 指向 kubeconfig 文件的路径。该文件中包含主控节点位置以及鉴权凭据信息。--authentication-kubeconfig
: kubeconfig 文件的路径名。该文件中包含与某 Kubernetes “核心” 服务器相关的信息,并支持足够的权限以创建 tokenreviews.authentication.k8s.io。此选项是可选的。如果设置为空值,所有令牌请求都会被认作匿名请求,Kubernetes 也不再在集群中查找客户端的 CA 证书信息。--authorization-kubeconfig
: 包含 Kubernetes “核心” 服务器信息的 kubeconfig 文件路径,所包含信息具有创建 subjectaccessreviews.authorization.k8s.io 的足够权限。此参数是可选的。如果配置为空字符串,未被鉴权模块所忽略的请求都会被禁止--cert-dir
: TLS 证书所在的目录。如果提供了–tls-cert-file 和 –tls private-key-file,则将忽略此参数--allocate-node-cidrs
: 为 Pod 分配和设置子网掩码--configure-cloud-routes
: 决定是否由 –allocate-node-cidrs 所分配的 CIDR 要通过云驱动程序来配置。--cloud-provider
: 云服务的提供者。external
表示没有对应的提供者(驱动)--cluster-cidr
: Kubernetes集群中pod的IP地址范围--service-cluster-ip-range
: Kubernetes集群中Service的虚拟IP地址范围,该IP范围不能与物理机的IP地址有重合。--client-ca-file
: 对于所有能够提供客户端证书的请求,若该证书由 client-ca-file 中所给机构之一签署,则该请求会被成功认证为客户端证书中 CommonName 所给的实体--root-ca-file
: 服务账号的令牌Secret中会包含此根证书机构--controllers
:要启用的控制器列表。* 表示启用所有默认启用的控制器, 这里我禁用了云检测--cluster-signing-cert-file/--cluster-signing-key-file
:自动为kubelet颁发证书的CA,与apiserver保持一致--cluster-signing-duration
: 自动为kubelet颁发证书的有效期--service-account-private-key-file
: 服务帐户密钥对--use-service-account-credentials
: 为每个控制器单独使用服务账号凭据。
备注:Controller Manager的所有参数说明连接
7 部署scheduler
主节点上的组件,该组件监视那些新创建的未指定运行节点的 Pod,并选择节点让 Pod 在上面运行。
7.1 systemd服务
|
|
7.2 配置文件
|
|
配置文件说明:
--leader-elect
:当该组件启动多个时,自动选举(HA)--cert-dir
: TLS 证书所在的目录。如果提供了–tls-cert-file 和 –tls private-key-file,则将忽略此参数--config
: 指配置文件的路径。命令行参数会覆盖此文件中的值。--authentication-kubeconfig
: 指向具有足够权限以创建 subjectaccessreviews.authorization.k8s.io 的 ‘core’ kubernetes 服务器的 kubeconfig 文件
8 修复文件权限
|
|
9 启动服务
|
|
10 生成scheduler配置文件
需要先启动API server
|
|
11 查看集群状态
由于我的ca管理和kubectl程序都是安装在node3上的,所以在node3上操作
|
|
12 授权APIserver访问kubelet
–kubelet-client-*参数调用证书的CN是system:masters
所以用户就是system:masters
, system:masters
用户默认绑定到了集群管理员了,不要轻易使用哦~~
|
|
13 授权kubelet创建csr
刚刚生成的toke文件中的用户组是system:bootstrappers
,
把用户组和RBAC预定义规则system:node-bootstrapper
进行绑定既可以授权kubelet通过apiserver管理证书了
|
|
14 部署Worker Node
注意:一个节点(node1)的kubelet使用手动生成的密钥/证书, 一个(node2)上kubelet的密钥证书是由TLS Bootstrapping管理的,所以要两个节点上的kubelet配置是不一样的,其他都一样。
下边是一些公共参数,主要是日志配置,节点上的所有程序都调用了
|
|
--logtostderr
: 设置为false表示将日志写入文件,不写入stderr--log-dir
: 日志目录--v
: 日志等级
14.1 安装docker
Kubernetes 支持多个容器运行环境: Docker、 containerd、cri-o、 rktlet 以及任何实现 Kubernetes CRI (容器运行环境接口),我才用docker,毕竟常用
参考我之前写的一篇文章来安装docker
两个worker节点上安装配置都一样
注意docker的配置文件如下:
|
|
14.2 下载程序文件
|
|
15 部署kubelet(node1)
一个在集群中每个节点上运行的代理。它保证容器都运行在 Pod 中。
kubelet 接收一组通过各类机制提供给它的 PodSpecs,确保这些 PodSpecs 中描述的容器处于运行状态且健康。kubelet 不会管理不是由 Kubernetes 创建的容器。
这里我先写在node1节点上通过手动管理证书的方式来启动kubelet,另一个等会在说
15.1 systemd服务
|
|
15.2 配置文件
|
|
配置文件说明:
--kubeconfig
:该文件将用于获取 kubelet 的客户端证书。如果 –kubeconfig 指定的文件不存在,则使用引导 kubeconfig 从 API 服务器请求客户端证书。成功后,将引用生成的客户端证书和密钥的 kubeconfig 文件写入 –kubeconfig 所指定的路径。客户端证书和密钥文件将存储在 –cert-dir 指向的目录中。--hostname-override
: 设置本Node的名称。--network-plugin
: 启用CNI--config
: kubelet 将从该文件加载其初始配置。该路径可以是绝对路径,也可以是相对路径。相对路径从 kubelet 的当前工作目录开始。省略此参数则使用内置的默认配置值。命令行参数会覆盖此文件中的配置。--cert-dir
: LS 证书所在的目录。如果设置了 –tls-cert-file 和 –tls-private-key-file,则该设置将被忽略。(默认值为 “/var/lib/kubelet/pki”)--pod-infra-container-image
: 指定基础设施镜像,Pod 内所有容器与其共享网络和 IPC 命名空间。仅当容器运行环境设置为 docker 时,此特定于 docker 的参数才有效。(默认值为 “k8s.gcr.io/pause:3.1”)默认的由于某种不可描述的原因,无法访问,自己想办法吧。
15.3 安装一些需要用到的工具
|
|
16 部署kubelet(node2)
这个节点的kubelet的密钥证书是由TLS Bootstrapping管理的
16.1 systemd服务
|
|
16.2 配置文件
|
|
这里新增加了一个参数
--bootstrap-kubeconfig
用来首次启动向apiserver申请证书bootstrap-kubeconfig
文件生成方法:由于我的kubectl安装在master 节点(node3)上的,所以需要在master节点上生成,然后复制到worker节点的
/opt/kubernetes/etc/
目录1 2 3 4 5 6 7 8 9 10
cd ~/ca/kube-ca/kubeconfig KUBE_APISERVER="https://node3:6443" # apiserver IP:PORT TOKEN="c47ffb939f5ca36231d9e3121a252940" # 与token.csv里保持一致 # 生成bootstrap配置文件 kubectl config set-cluster kubernetes --certificate-authority=/opt/kubernetes/ssl/kube-ca.crt --embed-certs=true --server=${KUBE_APISERVER} --kubeconfig=bootstrap.conf kubectl config set-credentials system:bootstrappers --token=${TOKEN} --kubeconfig=bootstrap.conf kubectl config set-context default --cluster=kubernetes --user=system:bootstrappers --kubeconfig=bootstrap.conf kubectl config use-context default --kubeconfig=bootstrap.conf # 传到node2节点 scp bootstrap.conf root@node2:/opt/kubernetes/etc/bootstrap.conf
16.3 启动服务
|
|
16.4 批准kubelet证书申请并加入集群
|
|
注:由于网络插件还没有部署,节点会没有准备就绪 NotReady
16.5 安装一些需要用到的工具
|
|
注意:这里的--kubeconfig
指向的配置文件是空的,等会会自动生成
17 部署kube-proxy
kube-proxy 是集群中每个节点上运行的网络代理,实现 Kubernetes Service 概念的一部分。
kube-proxy 维护节点上的网络规则。这些网络规则允许从集群内部或外部的网络会话与 Pod 进行网络通信。
如果操作系统提供了数据包过滤层并可用的话,kube-proxy会通过它来实现网络规则。否则,kube-proxy 仅转发流量本身。
两个worker节点上安装配置都一样
17.1 systemd服务
|
|
17.2 配置文件
|
|
配置文件说明:
--config
: 配置文件的路径。--kubeconfig
: 包含授权信息的 kubeconfig 文件的路径(master 位置由 master 标志设置)--write-config-to
: 将配置值写入此文件并退出程序
注意:所有配置参数说明连接
18 文件权限
|
|
19 启动服务
|
|
20 部署CNI网络
通过给Kubelet传递–network-plugin=cni命令行选项来选择CNI插件。Kubelet从–cni-conf-dir(默认是/etc/cni/net.d)读取文件并使用该文件中的CNI配置来设置每个pod的网络。CNI配置文件必须与CNI规约匹配,并且配置引用的任何所需的CNI插件都必须存在于–cni-bin-dir(默认是/opt/cni/bin)。
如果这个目录中有多个CNI配置文件,kubelet将会使用按文件名的字典顺序排列的第一个作为配置文件。
除了配置文件指定的CNI插件外,Kubernetes还需要标准的CNIlo插件,最低版本是0.2.0。
安装CNI二进制文件
1 2 3 4 5 6 7 8
# 两个Worker Node上都需要安装 mkdir -p /opt/cni/bin/ VERSION=v0.8.7 cd /tmp curl -L https://github.com/containernetworking/plugins/releases/download/${VERSION}/cni-plugins-linux-amd64-${VERSION}.tgz -o cni-plugins-linux-amd64-${VERSION}.tgz tar -zxvf cni-plugins-linux-amd64-${VERSION}.tgz -C /opt/cni/bin/ scp -r /opt/cni/bin/ root@node2:/opt/cni/bin/ rm -f cni-plugins-linux-amd64-${VERSION}.tgz
安装CNI网络插件
flannel
flannel我部署到kube集群里边了,没有单独每个Worker Node部署
1 2 3 4 5
# 在master节点操作,因为master节点安装了kubectl客户端程序和配置 wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml PODIP=10.120.0.0/16 # pod的ip地址,即controller-manager控制器设置的cluster-cidr地址 sed -i 's|10.244.0.0/16|'"$PODIP"'|g' kube-flannel.yml kubectl apply -f kube-flannel.yml
Master Node(备)
和Master Node主配置一样,不在叙述
负载均衡
部署nginx
安装nginx
在两个master node上安装
1
yum install -y nginx
配置nginx
使用nginx的4层负载均衡,主备一样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
setsebool -P nis_enabled 1 # 修改selinux权限 cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak cat >> /etc/nginx/nginx.conf <<EOF # 四层负载均衡,为两台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.122.12:6443; # Master1 APISERVER IP:PORT server 192.168.122.13:6443; # Master2 APISERVER IP:PORT } server { listen 8443; proxy_pass k8s-apiserver; } } EOF
启动nginx
1 2
systemctl start nginx systemctl enable nginx
部署keepalived
安装keepalived
在两个master node上安装keepalived即可(一主一备)
1 2
yum install -y keepalived mkdir -p /etc/keepalived
master节点1(node3)配置文件
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
mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.back cat > /etc/keepalived/keepalived.conf<<EOF ! Configuration File for keepalived global_defs { router_id keepalive-master } vrrp_script check_apiserver { # 检测脚本路径 script "/etc/keepalived/check-nginx.sh" # 多少秒检测一次 interval 3 # 失败的话权重-2 weight -2 fail 1 } vrrp_instance VI-kube-master { state MASTER # 定义节点角色 interface ens3 # 网卡名称 virtual_router_id 68 priority 100 # 启用单播模式~ unicast_src_ip 192.168.122.12 unicast_peer { 192.168.122.13 } dont_track_primary advert_int 3 authentication { auth_type PASS auth_pass net-cc } virtual_ipaddress { # 自定义虚拟ip 192.168.122.2 } track_script { check_apiserver } } EOF
master节点2(node4)配置文件
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
mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.back cat > /etc/keepalived/keepalived.conf<<EOF ! Configuration File for keepalived global_defs { router_id keepalive-backup } vrrp_script check_apiserver { script "/etc/keepalived/check-nginx.sh" interval 3 weight -5 fail 1 } vrrp_instance VI-kube-master { state BACKUP interface ens32 virtual_router_id 68 priority 95 unicast_src_ip 192.168.122.13 unicast_peer { 192.168.122.12 } dont_track_primary advert_int 3 authentication { auth_type PASS auth_pass net-cc } virtual_ipaddress { 192.168.122.2 } track_script { check_apiserver } } EOF
两个节点都创建以下脚本文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
cat > /etc/keepalived/check-nginx.sh<<EOF #!/bin/bash #检查ngin进程是否存在 counter=\$(ps -C nginx --no-heading|wc -l) if [ "\${counter}" = "0" ]; then #尝试启动一次ngnx,停止5秒后再次检测 systemctl restart nginx sleep 5 counter=\$(ps -C nginx --no-heading|wc -l) if [ "\${counter}"="0" ]; then #如果启动没成功,就杀掉keepave触发主备切换 systemctl stop nginx exit 2 fi fi EOF chmod +x /etc/keepalived/check-nginx.sh
启动keepalived
1
systemctl enable keepalived && service keepalived start
测试
1 2 3 4 5 6 7 8 9 10 11 12
curl -k https://192.168.122.2:6443/version { "major": "1", "minor": "19", "gitVersion": "v1.19.1", "gitCommit": "206bcadf021e76c27513500ca24182692aabd17e", "gitTreeState": "clean", "buildDate": "2020-09-09T11:18:22Z", "goVersion": "go1.15", "compiler": "gc", "platform": "linux/amd64" }
测试
关闭主节点Nginx,测试VIP是否漂移到备节点服务器。
1 2 3 4
# 在Nginx Master执行 pkill nginx pkill nginx # 在Nginx Backup,ip addr命令查看已成功绑定VIP ip addr
访问负载均衡器测试
找K8s集群中任意一个节点,使用curl查看K8s版本测试,使用VIP访问:
1 2 3 4 5 6 7 8 9 10 11 12
curl -k https://192.168.122.2:6443/version { "major": "1", "minor": "18", "gitVersion": "v1.18.3", "gitCommit": "2e7996e3e2712684bc73f0dec0200d64eec7fe40", "gitTreeState": "clean", "buildDate": "2020-05-20T12:43:34Z", "goVersion": "go1.13.9", "compiler": "gc", "platform": "linux/amd64" }
修改所有Worker Node连接LB VIP
虽然我们增加了Master2和负载均衡器,但是我们是从单Master架构扩容的,也就是说目前所有的Node组件连接都还是Master1,如果不改为连接VIP走负载均衡器,那么Master还是单点故障。 因此接下来就是要改所有Node组件配置文件
所有Worker Node执行:
1 2 3 4
sed -i 's#192.168.122.12#k8s.api#g' /opt/kubernetes/etc/* sed -i 's#node3#k8s.api#g' /opt/kubernetes/etc/* systemctl restart kubelet systemctl restart kube-proxy
检查节点状态:
1 2 3 4 5 6
kubectl get node NAME STATUS ROLES AGE VERSION k8s-master Ready <none> 34h v1.18.3 k8s-master2 Ready <none> 101m v1.18.3 k8s-node1 Ready <none> 33h v1.18.3 k8s-node2 Ready <none> 33h v1.18.3
至此,一套完整的 Kubernetes 高可用集群就部署完成了!
PS:如果你是在公有云上,一般都不支持keepalived,那么你可以直接用它们的负载均衡器产品(内网就行,还免费~),架构与上面一样,直接负载均衡多台Master kube-apiserver即可!