一、介绍
1、k8s的node默认已经有高可用了,因为在pod会随机分配到各个node上,如果有pod挂了,就会分配到其他node上,所以这里主要是做一下master的高可用。
2、kube-controller-manager与kube-scheduler高可用
这两项服务是Master节点的一部分,他们的高可用相对容易,仅需要运行多份实例即可。这两项服务是有状态的服务,这些实例会通过向apiserver中的Endpoint加锁的方式来进行leader election, 当目前拿到leader的实例无法正常工作时,别的实例会拿到锁,变为新的leader。
这种选举操作是通过在kube-system名称空间中创建一个与程序同名的Endpoints资源对象来实现。各实例通过apiserver去获取endpoint的状态,通过竞争的方式去抢占指定的Endpoint资源锁,胜利者将成为leader。
[root@k8s-master-101 ~]# kubectl get endpoints -n kube-system
NAME ENDPOINTS AGE
kube-controller-manager <none> 23d
kube-scheduler <none> 23d
#在搭建完后实验,一开始111这台master为leader,然后把111上的kube-controller关闭后可以看到101这台master变为了leader,实现了高可用。
[root@k8s-master-101 ~]# kubectl describe endpoints kube-controller-manager -n kube-system Name: kube-controller-manager
Namespace: kube-system
Labels: <none>
Annotations: control-plane.alpha.kubernetes.io/leader:
{"holderIdentity":"k8s-master-101_c6cd4e97-53ba-11e9-9694-000c293313a6","leaseDurationSeconds":15,"acquireTime":"2019-03-31T14:14:51Z","re...
Subsets:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal LeaderElection 34m kube-controller-manager k8s-master-111_3fa9e034-53ba-11e9-9ba6-000c29785034 became leader
Normal LeaderElection 29s kube-controller-manager k8s-master-101_c6cd4e97-53ba-11e9-9694-000c293313a6 became leader
kube-scheduler和controller-manager不需要做高可用,因为它们默认会通过选举产生,可以通过下面的命令查看:
3、apiserver的高可用也有三种基本思路:
一是使用外部负载均衡器,不管是使用公有云提供的负载均衡器服务或是在私有云中使用LVS或者HaProxy自建负载均衡器都可以归到这一类。 负载均衡器是非常成熟的方案,在这里略过不做过多介绍。如何保证负载均衡器的高可用,则是选择这一方案需要考虑的新问题。
二是在网络层做负载均衡。比如在Master节点上用BGP做ECMP,或者在Node节点上用iptables做NAT都可以实现。采用这一方案不需要额外的外部服务,但是对网络配置有一定的要求。
三是在Node节点上使用反向代理对多个Master做负载均衡。这一方案同样不需要依赖外部的组件,但是当Master节点有增减时,如何动态配置Node节点上的负载均衡器成为了另外一个需要解决的问题。
4、官方的master节点高可用架构
可以看出,用户通过kubectl发送命令经过LB进行负载均衡到后端的master上的apiserver,再由具体的某一个master进行向集群内部的节点的转发。
同理,节点也是通过LB进行负载均衡连接到master上的apiserver,去获取到apiserver中配置的信息。
5、其他高可用集群架构
可以看到,每一台node上都部署了 nginx做负载均衡到master的apiserver
二、高可用部署(node节点部署nginx代理方式)
将master节点扩展至2个,新增加的master的ip为:10.0.0.111
1、在原先的master上的server-csr.json中增加新增master的ip:
vim server-csr.json
[root@k8s-master-101 ssl]# cat server-csr.json
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"10.10.10.1",
"10.0.0.101",
"10.0.0.102",
"10.0.0.103",
"10.0.0.111",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Shenzhen",
"ST": "Guangzhou",
"O": "k8s",
"OU": "System"
}
]
}
2、重新生成server证书:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server
cp -p server-key.pem server.pem /opt/kubernetes/ssl/
systemctl restart kube-apiserver
3、将原先master上的/opt/kubernetes发送到新的master节点上:
scp -r /opt/kubernetes/ root@10.0.0.111:/opt
4、从原先的master上拷贝服务的配置文件到新的master上:
scp /usr/lib/systemd/system/{kube-apiserver,kube-scheduler,kube-controller-manager}.service root@10.0.0.111:/usr/lib/systemd/system/
5、修改新master节点上的kube-apiserver配置文件:
将advertise-address和bind-address改为新master本机的ip
vim /opt/kubernetes/cfg/kube-apiserver
[root@k8s-master-111 ~]# cat /opt/kubernetes/cfg/kube-apiserver
KUBE_APISERVER_OPTS="--logtostderr=true \
--v=4 \
--etcd-servers=https://10.0.0.101:2379,https://10.0.0.102:2379,https://10.0.0.103:2379 \
--insecure-bind-address=127.0.0.1 \
--bind-address=10.0.0.111 \
--insecure-port=8080 \
--secure-port=6443 \
--advertise-address=10.0.0.111 \
--allow-privileged=true \
--service-cluster-ip-range=10.10.10.0/24 \
--admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota,NodeRestriction --authorization-mode=RBAC,Node \
--kubelet-https=true \
--enable-bootstrap-token-auth \
--token-auth-file=/opt/kubernetes/cfg/token.csv \
--service-node-port-range=30000-50000 \
--tls-cert-file=/opt/kubernetes/ssl/server.pem \
--tls-private-key-file=/opt/kubernetes/ssl/server-key.pem \
--client-ca-file=/opt/kubernetes/ssl/ca.pem \
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \
--etcd-cafile=/opt/kubernetes/ssl/ca.pem \
--etcd-certfile=/opt/kubernetes/ssl/server.pem \
--etcd-keyfile=/opt/kubernetes/ssl/server-key.pem"
6、启动服务
systemctl daemon-reload
systemctl start kube-apiserver.service
systemctl enable kube-apiserver.service
systemctl start kube-scheduler.service
systemctl enable kube-scheduler.service
systemctl start kube-controller-manager.service
systemctl enable kube-controller-manager.service
7、在新的master上使用kubectl查看集群中的节点:
echo PATH=$PATH:/opt/kubernetes/bin >> /etc/profile
source /etc/profile
kubectl get node
[root@k8s-master-111 ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
10.0.0.102 Ready <none> 23d v1.12.2
10.0.0.103 Ready <none> 23d v1.12.2
三、node节点上
node节点配置
1、首先在两台node节点上安装nginx做4层负载均衡:
添加nginx源
vim /etc/yum.repos.d/nginx.repo
[root@k8s-node1-102 ~]# cat /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/\$basearch/
gpgcheck=0
yum install -y nginx
2、配置nginx:把对本机127.0.0.1:6443的请求代理到两个master几点的6443节点上
vim /etc/nginx/nginx.conf
[root@k8s-node1-102 ~]# cat /etc/nginx/nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
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 10.0.0.101:6443;
server 10.0.0.111:6443;
}
server {
listen 127.0.0.1:6443;
proxy_pass k8s-apiserver;
}
}
3、在node节点上修改bootstrap.kubeconfig kubelet.kubeconfig kube-proxy.kubeconfig中的apiserver地址为本地:server: https://127.0.0.1:6443,这样node节点向apiserver的请求会先发向本机127.0.0.1:6443,然后经过代理转发到两个master节点上的apiserver端口
cd /opt/kubernetes/cfg
ls *config | xargs -i sed -i 's/10.0.0.101/127.0.0.1/' {}
4、在node节点上重启服务
systemctl restart kubelet.service
systemctl restart kube-proxy.service
5、在node节点上启动nginx:
systemctl start nginx
systemctl enable nginx
6、查看一下nginx日志有没有代理记录:
tail /var/log/nginx/k8s-access.log
本文分享自 kubernetes中文社区 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!