1

I have set a kubernetes (version 1.6.1) cluster with three servers in control plane. Apiserver is running with the following config:

/usr/bin/kube-apiserver \
  --admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota \
  --advertise-address=x.x.x.x \
  --allow-privileged=true \
  --audit-log-path=/var/lib/k8saudit.log \
  --authorization-mode=ABAC \
  --authorization-policy-file=/var/lib/kubernetes/authorization-policy.jsonl \
  --bind-address=0.0.0.0 \
  --etcd-servers=https://kube1:2379,https://kube2:2379,https://kube3:2379 \
  --etcd-cafile=/etc/etcd/ca.pem \
  --event-ttl=1h \
  --insecure-bind-address=0.0.0.0 \
  --kubelet-certificate-authority=/var/lib/kubernetes/ca.pem \
  --kubelet-client-certificate=/var/lib/kubernetes/kubernetes.pem \
  --kubelet-client-key=/var/lib/kubernetes/kubernetes-key.pem \
  --kubelet-https=true \
  --service-account-key-file=/var/lib/kubernetes/ca-key.pem \
  --service-cluster-ip-range=10.32.0.0/24 \
  --service-node-port-range=30000-32767 \
  --tls-cert-file=/var/lib/kubernetes/kubernetes.pem \
  --tls-private-key-file=/var/lib/kubernetes/kubernetes-key.pem \
  --token-auth-file=/var/lib/kubernetes/token.csv \
  --v=2 \
  --apiserver-count=3 \
  --storage-backend=etcd2

Now I am running kubelet with following config:

/usr/bin/kubelet \
  --api-servers=https://kube1:6443,https://kube2:6443,https://kube3:6443 \
  --allow-privileged=true \
  --cluster-dns=10.32.0.10 \
  --cluster-domain=cluster.local \
  --container-runtime=docker \
  --network-plugin=kubenet \
  --kubeconfig=/var/lib/kubelet/kubeconfig \
  --serialize-image-pulls=false \
  --register-node=true \
  --cert-dir=/var/lib/kubelet \
  --tls-cert-file=/var/lib/kubernetes/kubelet.pem \
  --tls-private-key-file=/var/lib/kubernetes/kubelet-key.pem \
  --hostname-override=node1 \
  --v=2

This works great as long as kube1 is running. If I take kube1 down, the node does not communicate with kube2 or kube3. It always takes up the first apiserver passed to the --api-servers flag and does not failover in case the first apiserver crashes. What is the correct way to do a failover in case one of the apiserver fails?

4

2 回答 2

1

--api-servers标志已弃用。它不再在文档中。kubeconfig 是将 kubelet 指向 kube-apiserver 的全新方式。

今天这样做的犹太方法是在每个工作节点(即运行 kubelet 的节点)上部署一个带有 nginx 的 Pod,在 3 个 kube-apiserver 之间进行负载平衡。nginx 会知道一个 master 何时宕机,并且不会将流量路由到它;这就是它的工作。kubespray 项目使用这种方法。

第二个不太好的方法是使用 DNS RR。为 3 个主服务器的 IP 创建 DNS“A”记录。将 kubelet 指向这个 RR 主机名,而不是 3x IP。kubelet 每次联系一个 master,都会被路由到 RR 列表中的 IP。这种技术并不可靠,因为流量仍将路由到故障节点,因此集群将遇到间歇性中断。

第三种,更复杂的方法恕我直言,是使用keepalived。keepalived 使用 VRRP 来确保至少一个节点拥有虚拟 IP (VIP)。如果一个 master 宕机,另一个 master 会劫持 VIP 以确保连续性。这种方法的坏处是负载平衡不是默认的。所有流量将被路由到 1 个主节点(即主 VRRP 节点),直到它关闭。然后辅助 VRRP 节点将接管。您可以在此页面上看到我贡献的精彩文章:)

有关 kube-apiserver HA 的更多详细信息,请点击此处。祝你好运!

于 2017-07-27T02:07:37.470 回答
0

目前,在 1.8 之前,最好的解决方案似乎是使用负载均衡器,正如已经建议的那样。

请参阅https://github.com/sipb/h​​omeworld/issues/10

于 2017-07-31T15:13:49.230 回答