在本地使用 kubeadm 的 Kubernetes multi-master 问题
Issues with Kubernetes multi-master using kubeadm on premises
正在关注 Kubernetes v1.11 documentation, I have managed to setup Kubernetes high availability using kubeadm, stacked control plane nodes, with 3 masters running on-premises on CentOS7 VMs. But with no load-balancer available, I used Keepalived to set a failover virtual IP (10.171.4.12) for apiserver as described in Kubernetes v1.10 documentation。结果,我的 "kubeadm-config.yaml" 用于控制平面的 boostrap 具有以下 header:
apiVersion: kubeadm.k8s.io/v1alpha2
kind: MasterConfiguration
kubernetesVersion: v1.11.0
apiServerCertSANs:
- "10.171.4.12"
api:
controlPlaneEndpoint: "10.171.4.12:6443"
etcd:
...
配置正常,在引导所有 3 个主控器时出现以下警告:
[endpoint] WARNING: port specified in api.controlPlaneEndpoint
overrides api.bindPort in the controlplane address
加入 Workers 时出现此警告:
[WARNING RequiredIPVSKernelModulesAvailable]: the IPVS proxier will
not be used, because the following required kernel modules are not
loaded: [ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh] or no builtin kernel ipvs
support: map[ip_vs:{} ip_vs_rr:{} ip_vs_wrr:{} ip_vs_sh:{}
nf_conntrack_ipv4:{}] you can solve this problem with following
methods:
1. Run 'modprobe -- ' to load missing kernel modules;
2. Provide the missing builtin kernel ipvs support
之后基本测试成功:
- 停止后,Keepalived 将故障转移到另一个 Master,并且 apiserver 始终可访问(所有 kubectl 命令都成功)。
- 当停止主 Master(具有最高的 Keepalived 偏好)时,应用程序部署成功(使用 Kubernetes bootcamp 测试)并且当主 Master 恢复在线时一切都与主 Master 正确同步。
- Kubernetes bootcamp 应用程序 运行 成功,并且当使用 NodePort 公开 bootcamp 的服务卷曲时,所有主节点和工作节点都正确响应。
- 已根据 https://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/docker-registry
成功部署 docker-registry
但随之而来的是这些问题:
- Nginx Ingress Controller pod 无法 运行 并进入 CrashLoopBackOff 状态(请参阅下面的事件)
- 在任何 Master 上安装 helm 和 tiller 后,所有使用 "helm install" 或 "helm list" 的命令都无法执行(请参阅下面的命令输出)
我正在 运行ning Kubernetes v1.11.1 但 kubeadm-config.yaml 提到 1.11.0,这是我应该担心的事情吗?
我是否可以不遵循官方文档并寻求其他替代方案,例如:https://medium.com/@bambash/ha-kubernetes-cluster-via-kubeadm-b2133360b198
注意:与使用最新版本 1.11.2(三个主节点 + 一个工作节点)的新 Kubernetes HA 安装和部署的 nginx 最新入口控制器版本 0.18.0 存在相同问题。
-- Nginx 控制器 pod 事件和日志:
Normal Pulled 28m (x38 over 2h) kubelet, node3.local Container image "quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.17.1" already present on machine
Warning Unhealthy 7m (x137 over 2h) kubelet, node3.local Liveness probe failed: Get http://10.240.3.14:10254/healthz: dial tcp 10.240.3.14:10254: connect: connection refused
Warning BackOff 2m (x502 over 2h) kubelet, node3.local Back-off restarting failed container
nginx version: nginx/1.13.12
W0809 14:05:46.171066 5 client_config.go:552] Neither --kubeconfig nor --master was specified. Using the inClusterConfig. This might not work.
I0809 14:05:46.171748 5 main.go:191] Creating API client for https://10.250.0.1:443
-- helm 命令输出:
'# helm install ...
Error: no available release name found
'# helm list
Error: Get https://10.250.0.1:443/api/v1/namespaces/kube-system/configmaps?labelSelector=OWNER%!D(MISSING)TILLER: dial tcp 10.250.0.1:443: i/o timeout
-- kubernetes 服务和端点:
# kubectl describe svc kubernetes
Name: kubernetes
Namespace: default
Labels: component=apiserver
provider=kubernetes
Annotations: <none>
Selector: <none>
Type: ClusterIP
IP: 10.250.0.1
Port: https 443/TCP
TargetPort: 6443/TCP
Endpoints: 10.171.4.10:6443,10.171.4.8:6443,10.171.4.9:6443
Session Affinity: None
Events: <none>
# kubectl get endpoints --all-namespaces
NAMESPACE NAME ENDPOINTS AGE
default bc-svc 10.240.3.27:8080 6d
default kubernetes 10.171.4.10:6443,10.171.4.8:6443,10.171.4.9:6443 7d
ingress-nginx default-http-backend 10.240.3.24:8080 4d
kube-system kube-controller-manager <none> 7d
kube-system kube-dns 10.240.2.4:53,10.240.2.5:53,10.240.2.4:53 + 1 more... 7d
kube-system kube-scheduler <none> 7d
kube-system tiller-deploy 10.240.3.25:44134 5d
如您在Kubernetes client-go code中所见,IP地址和端口是从容器内的环境变量中读取的:
host, port := os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT")
如果您 运行 以下命令提及其中任何健康的 pod,则可以检查这些变量:
$ kubectl exec <healthy-pod-name> -- printenv | grep SERVICE
我认为问题的原因是变量 KUBERNETES_SERVICE_HOST:KUBERNETES_SERVICE_PORT
设置为 10.250.0.1:443
而不是 10.171.4.12:6443
你能通过检查集群中的这些变量来确认吗?
重要附加说明:
经过 运行 几次实验后,我遇到了同样的问题:
- 新的 Kubernetes HA 安装使用最新版本 1.11.2(三个主节点 + 一个工作节点)和 nginx 最新入口控制器版本 0.18.0。
- 独立的 Kubernetes master 和少数 worker 使用版本 1.11.1(一个 master + 两个 worker)和 nginx 最新的入口控制器版本 0.18.0。
- 但使用独立的 Kubernetes 主版本 1.11.0(一个主 + 两个工作人员),nginx 入口控制器 0.17.1 没有任何投诉,而 0.18.0 抱怨就绪探测失败但 pod 进入 运行 状态。
=> 因此,我认为这个问题与 kubernetes 1.11.1 和 1.11.2 版本有关,因为它们解释健康探测的方式可能
将我的 POD 网络从 Flanneld 切换到 Calico 时问题已解决。
(在 Kubernetes 1.11.0 上测试;明天将在最新的 k8s 版本 1.11.2 上重复测试)
正在关注 Kubernetes v1.11 documentation, I have managed to setup Kubernetes high availability using kubeadm, stacked control plane nodes, with 3 masters running on-premises on CentOS7 VMs. But with no load-balancer available, I used Keepalived to set a failover virtual IP (10.171.4.12) for apiserver as described in Kubernetes v1.10 documentation。结果,我的 "kubeadm-config.yaml" 用于控制平面的 boostrap 具有以下 header:
apiVersion: kubeadm.k8s.io/v1alpha2
kind: MasterConfiguration
kubernetesVersion: v1.11.0
apiServerCertSANs:
- "10.171.4.12"
api:
controlPlaneEndpoint: "10.171.4.12:6443"
etcd:
...
配置正常,在引导所有 3 个主控器时出现以下警告:
[endpoint] WARNING: port specified in api.controlPlaneEndpoint overrides api.bindPort in the controlplane address
加入 Workers 时出现此警告:
[WARNING RequiredIPVSKernelModulesAvailable]: the IPVS proxier will not be used, because the following required kernel modules are not loaded: [ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh] or no builtin kernel ipvs support: map[ip_vs:{} ip_vs_rr:{} ip_vs_wrr:{} ip_vs_sh:{} nf_conntrack_ipv4:{}] you can solve this problem with following methods:
1. Run 'modprobe -- ' to load missing kernel modules;
2. Provide the missing builtin kernel ipvs support
之后基本测试成功:
- 停止后,Keepalived 将故障转移到另一个 Master,并且 apiserver 始终可访问(所有 kubectl 命令都成功)。
- 当停止主 Master(具有最高的 Keepalived 偏好)时,应用程序部署成功(使用 Kubernetes bootcamp 测试)并且当主 Master 恢复在线时一切都与主 Master 正确同步。
- Kubernetes bootcamp 应用程序 运行 成功,并且当使用 NodePort 公开 bootcamp 的服务卷曲时,所有主节点和工作节点都正确响应。
- 已根据 https://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/docker-registry 成功部署 docker-registry
但随之而来的是这些问题:
- Nginx Ingress Controller pod 无法 运行 并进入 CrashLoopBackOff 状态(请参阅下面的事件)
- 在任何 Master 上安装 helm 和 tiller 后,所有使用 "helm install" 或 "helm list" 的命令都无法执行(请参阅下面的命令输出)
我正在 运行ning Kubernetes v1.11.1 但 kubeadm-config.yaml 提到 1.11.0,这是我应该担心的事情吗?
我是否可以不遵循官方文档并寻求其他替代方案,例如:https://medium.com/@bambash/ha-kubernetes-cluster-via-kubeadm-b2133360b198
注意:与使用最新版本 1.11.2(三个主节点 + 一个工作节点)的新 Kubernetes HA 安装和部署的 nginx 最新入口控制器版本 0.18.0 存在相同问题。
-- Nginx 控制器 pod 事件和日志:
Normal Pulled 28m (x38 over 2h) kubelet, node3.local Container image "quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.17.1" already present on machine
Warning Unhealthy 7m (x137 over 2h) kubelet, node3.local Liveness probe failed: Get http://10.240.3.14:10254/healthz: dial tcp 10.240.3.14:10254: connect: connection refused
Warning BackOff 2m (x502 over 2h) kubelet, node3.local Back-off restarting failed container
nginx version: nginx/1.13.12
W0809 14:05:46.171066 5 client_config.go:552] Neither --kubeconfig nor --master was specified. Using the inClusterConfig. This might not work.
I0809 14:05:46.171748 5 main.go:191] Creating API client for https://10.250.0.1:443
-- helm 命令输出:
'# helm install ...
Error: no available release name found
'# helm list
Error: Get https://10.250.0.1:443/api/v1/namespaces/kube-system/configmaps?labelSelector=OWNER%!D(MISSING)TILLER: dial tcp 10.250.0.1:443: i/o timeout
-- kubernetes 服务和端点:
# kubectl describe svc kubernetes
Name: kubernetes
Namespace: default
Labels: component=apiserver
provider=kubernetes
Annotations: <none>
Selector: <none>
Type: ClusterIP
IP: 10.250.0.1
Port: https 443/TCP
TargetPort: 6443/TCP
Endpoints: 10.171.4.10:6443,10.171.4.8:6443,10.171.4.9:6443
Session Affinity: None
Events: <none>
# kubectl get endpoints --all-namespaces
NAMESPACE NAME ENDPOINTS AGE
default bc-svc 10.240.3.27:8080 6d
default kubernetes 10.171.4.10:6443,10.171.4.8:6443,10.171.4.9:6443 7d
ingress-nginx default-http-backend 10.240.3.24:8080 4d
kube-system kube-controller-manager <none> 7d
kube-system kube-dns 10.240.2.4:53,10.240.2.5:53,10.240.2.4:53 + 1 more... 7d
kube-system kube-scheduler <none> 7d
kube-system tiller-deploy 10.240.3.25:44134 5d
如您在Kubernetes client-go code中所见,IP地址和端口是从容器内的环境变量中读取的:
host, port := os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT")
如果您 运行 以下命令提及其中任何健康的 pod,则可以检查这些变量:
$ kubectl exec <healthy-pod-name> -- printenv | grep SERVICE
我认为问题的原因是变量 KUBERNETES_SERVICE_HOST:KUBERNETES_SERVICE_PORT
设置为 10.250.0.1:443
而不是 10.171.4.12:6443
你能通过检查集群中的这些变量来确认吗?
重要附加说明:
经过 运行 几次实验后,我遇到了同样的问题: - 新的 Kubernetes HA 安装使用最新版本 1.11.2(三个主节点 + 一个工作节点)和 nginx 最新入口控制器版本 0.18.0。 - 独立的 Kubernetes master 和少数 worker 使用版本 1.11.1(一个 master + 两个 worker)和 nginx 最新的入口控制器版本 0.18.0。 - 但使用独立的 Kubernetes 主版本 1.11.0(一个主 + 两个工作人员),nginx 入口控制器 0.17.1 没有任何投诉,而 0.18.0 抱怨就绪探测失败但 pod 进入 运行 状态。
=> 因此,我认为这个问题与 kubernetes 1.11.1 和 1.11.2 版本有关,因为它们解释健康探测的方式可能
将我的 POD 网络从 Flanneld 切换到 Calico 时问题已解决。 (在 Kubernetes 1.11.0 上测试;明天将在最新的 k8s 版本 1.11.2 上重复测试)