无法设置HA etcd集群

时间:2020-02-27 15:37:24

标签: kubernetes ubuntu-18.04 etcd

我想在多个节点上设置一个运行的etcd集群。我已经在Hyper-V终端上运行了2台unbuntu 18.04机器。

我在kubernetes官方网站上遵循了该指南: https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm/

因此,我更改了几个脚本并在HOST0和HOST1上执行了该脚本

export HOST0=192.168.101.90
export HOST1=192.168.101.91

mkdir -p /tmp/${HOST0}/ /tmp/${HOST1}/


ETCDHOSTS=(${HOST0} ${HOST1} ${HOST2})
NAMES=("infra0" "infra1")

for i in "${!ETCDHOSTS[@]}"; do
HOST=${ETCDHOSTS[$i]}
NAME=${NAMES[$i]}
cat << EOF > /tmp/${HOST}/kubeadmcfg.yaml
apiVersion: "kubeadm.k8s.io/v1beta2"
kind: ClusterConfiguration
etcd:
    local:
        serverCertSANs:
        - "${HOST}"
        peerCertSANs:
        - "${HOST}"
        extraArgs:
            initial-cluster: ${NAMES[0]}=https://${ETCDHOSTS[0]}:2380,${NAMES[1]}=https://${ETCDHOSTS[1]}:2380
            initial-cluster-state: new
            name: ${NAME}
            listen-peer-urls: https://${HOST}:2380
            listen-client-urls: https://${HOST}:2379
            advertise-client-urls: https://${HOST}:2379
            initial-advertise-peer-urls: https://${HOST}:2380
EOF
done

之后,我在HOST0上执行了此命令

kubeadm init phase certs etcd-ca

我在HOST0上创建了所有必要的东西

# cleanup non-reusable certificates
find /etc/kubernetes/pki -not -name ca.crt -not -name ca.k
kubeadm init phase certs etcd-peer --config=/tmp/${HOST1}/kubeadmcfg.yaml
kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST1}/kubeadmcfg.yaml
kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST1}/kubeadmcfg.yaml
cp -R /etc/kubernetes/pki /tmp/${HOST1}/
find /etc/kubernetes/pki -not -name ca.crt -not -name ca.key -type f -delete


kubeadm init phase certs etcd-server --config=/tmp/${HOST0}/kubeadmcfg.yaml
kubeadm init phase certs etcd-peer --config=/tmp/${HOST0}/kubeadmcfg.yaml
kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST0}/kubeadmcfg.yaml
kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST0}/kubeadmcfg.yaml
# No need to move the certs because they are for HOST0

# clean up certs that should not be copied off this host
find /tmp/${HOST1} -name ca.key -type f -delete

然后,我将文件复制到第二个ETCTD节点(HOST1)。在此之前,我创建了一个root用户mbesystem

USER=mbesystem
 HOST=${HOST1}
 scp -r /tmp/${HOST}/* ${USER}@${HOST}:
 ssh ${USER}@${HOST}
 USER@HOST $ sudo -Es
 root@HOST $ chown -R root:root pki
 root@HOST $ mv pki /etc/kubernetes/

我将检查HOST0和HOST1上的所有文件。

在HOST0上,我使用以下命令启动了etcd集群:

kubeadm init phase etcd local --config=/tmp/192.168.101.90/kubeadmcfg.yaml

在Host1上,我开始使用:

kubeadm init phase etcd local --config=/home/mbesystem/kubeadmcfg.yaml

执行后:

docker run --rm -it \
--net host \
-v /etc/kubernetes:/etc/kubernetes k8s.gcr.io/etcd:3.4.3-0 etcdctl \
--cert /etc/kubernetes/pki/etcd/peer.crt \
--key /etc/kubernetes/pki/etcd/peer.key \
--cacert /etc/kubernetes/pki/etcd/ca.crt \
--endpoints https://192.168.101.90:2379 endpoint health --cluster

我发现群集无法正常运行,我将收到连接被拒绝的消息。

enter image description here

我不知道出了什么问题。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我已经对其进行了研究,复制了您提供的链接Kubernetes.io: Setup ha etcd with kubeadm 中的内容,并设法使其正常工作。

以下是一些说明/问题排查步骤/提示等。

首先,etcd 应该配置为奇数个节点。我的意思是应该将其创建为3个或5个节点群集。

为什么集群成员的数量为奇数?

etcd群集需要大多数节点(即仲裁)来同意对群集状态的更新。对于具有n个成员的群集,仲裁数为(n / 2)+1。对于任何奇数大小的群集,添加一个节点将始终增加仲裁所需的节点数。尽管由于有更多的计算机而将节点添加到奇数大小的群集中看起来更好,但是容错能力更差,因为完全相同数量的节点可能会失败而不会丢失仲裁,但是有更多的节点可能会失败。如果群集处于无法容忍更多故障的状态,则在删除节点之前添加节点是危险的,因为如果新节点无法在群集中注册(例如,地址配置错误),仲裁将永久丢失

- Github.com: etcd documentation


此外,还有一些故障排除步骤:

  • 检查docker是否正在运行您可以通过运行命令(在已安装systemd的操作系统上)检查它: $ systemctl show --property ActiveState docker
  • 使用以下命令检查etcd容器是否正常运行: $ sudo docker ps
  • 检查etcd容器的日志是否与以下设备一起运行: $ sudo docker logs ID_OF_CONTAINER

我如何使其能够正常工作

假定2个Ubuntu 18.04服务器的IP地址为:

  • 10.156.0.15和名称:etcd-1
  • 10.156.0.16和名称:etcd-2

另外:

  • 为根访问权限配置的SSH密钥
  • 两台计算机均可使用DNS解析($ ping etcd-1

步骤:

  • 在正式指南之前进行预配置。

    我使用root帐户进行了以下所有配置

  • 将kubelet配置为etcd的服务管理器。
  • 为kubeadm创建配置文件。
  • 生成证书颁发机构。
  • 为每个成员创建证书
  • 复制证书和kubeadm配置。
  • 创建静态容器清单。
  • 检查集群运行状况。

在官方指南之前进行预配置

此机器的预配置是通过带有Ansible剧本的StackOverflow帖子完成的: Stackoverflow.com: 3 kubernetes clusters 1 base on local machine

您还可以遵循官方文档:Kubernetes.io: Install kubeadm

将kubelet配置为etcd的服务管理器。

使用root帐户在etcd-1etcd-2 上运行以下命令。

cat << EOF > /etc/systemd/system/kubelet.service.d/20-etcd-service-manager.conf
[Service]
ExecStart=
#  Replace "systemd" with the cgroup driver of your container runtime. The default value in the kubelet is "cgroupfs".
ExecStart=/usr/bin/kubelet --address=127.0.0.1 --pod-manifest-path=/etc/kubernetes/manifests --cgroup-driver=systemd
Restart=always
EOF

$ systemctl daemon-reload

$ systemctl restart kubelet

为kubeadm创建配置文件。

etcd-1节点上创建配置文件。

这里是修改后的脚本,将仅为2个节点创建kubeadmcfg.yaml

export HOST0=10.156.0.15
export HOST1=10.156.0.16

# Create temp directories to store files that will end up on other hosts.
mkdir -p /tmp/${HOST0}/ /tmp/${HOST1}/

ETCDHOSTS=(${HOST0} ${HOST1})
NAMES=("etcd-1" "etcd-2")

for i in "${!ETCDHOSTS[@]}"; do
HOST=${ETCDHOSTS[$i]}
NAME=${NAMES[$i]}
cat << EOF > /tmp/${HOST}/kubeadmcfg.yaml
apiVersion: "kubeadm.k8s.io/v1beta2"
kind: ClusterConfiguration
etcd:
    local:
        serverCertSANs:
        - "${HOST}"
        peerCertSANs:
        - "${HOST}"
        extraArgs:
            initial-cluster: ${NAMES[0]}=https://${ETCDHOSTS[0]}:2380,${NAMES[1]}=https://${ETCDHOSTS[1]}:2380
            initial-cluster-state: new
            name: ${NAME}
            listen-peer-urls: https://${HOST}:2380
            listen-client-urls: https://${HOST}:2379
            advertise-client-urls: https://${HOST}:2379
            initial-advertise-peer-urls: https://${HOST}:2380
EOF
done

特别关注:

  • export HOSTX位于脚本顶部。 在此处粘贴您计算机的IP地址。
  • NAMES=("etcd-1" "etcd-2")在此处粘贴您的计算机的名称(主机名)。

从根帐户运行此脚本,并检查它是否在/tmp/IP_ADDRESS目录中创建了文件。

生成证书颁发机构

etcd-1节点上的根帐户运行以下命令:

$ kubeadm init phase certs etcd-ca

为每个成员创建证书

以下是脚本的一部分,该脚本负责为etcd集群的每个成员创建证书。 请修改HOST0HOST1变量。

#!/bin/bash
HOST0=10.156.0.15
HOST1=10.156.0.16

kubeadm init phase certs etcd-server --config=/tmp/${HOST1}/kubeadmcfg.yaml
kubeadm init phase certs etcd-peer --config=/tmp/${HOST1}/kubeadmcfg.yaml
kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST1}/kubeadmcfg.yaml
kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST1}/kubeadmcfg.yaml
cp -R /etc/kubernetes/pki /tmp/${HOST1}/
find /etc/kubernetes/pki -not -name ca.crt -not -name ca.key -type f -delete

kubeadm init phase certs etcd-server --config=/tmp/${HOST0}/kubeadmcfg.yaml
kubeadm init phase certs etcd-peer --config=/tmp/${HOST0}/kubeadmcfg.yaml
kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST0}/kubeadmcfg.yaml
kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST0}/kubeadmcfg.yaml
# No need to move the certs because they are for HOST0

从根帐户运行上述脚本,并检查pki中是否有/tmp/10.156.0.16/目录。

pki中不应有任何/tmp/10.156.0.15/目录,因为它已经存在。

复制证书和kubeadm配置。

使用以下命令将kubeadmcfg.yaml中的etcd-1/tmp/10.156.0.15复制到root目录: $ mv /tmp/10.156.0.15/kubeadmcfg.yaml /root/

/tmp/10.156.0.16的内容从etcd-1复制到etcd-2节点到/root/目录:

$ scp -r /tmp/10.156.0.16/* root@10.156.0.16:

检查文件是否正确复制之后,具有正确的权限,并使用pki上的命令将/etc/kubernetes/文件夹复制到etcd-2

$ mv /root/pki /etc/kubernetes/

创建静态容器清单。

etcd-1etcd-2上运行以下命令

$ kubeadm init phase etcd local --config=/root/kubeadmcfg.yaml

所有程序现在应该正在运行。

检查集群运行状况。

运行以下命令以检查etcd-1上的群集运行状况。

docker run --rm -it --net host -v /etc/kubernetes:/etc/kubernetes k8s.gcr.io/etcd:3.4.3-0 etcdctl --cert /etc/kubernetes/pki/etcd/peer.crt --key /etc/kubernetes/pki/etcd/peer.key --cacert /etc/kubernetes/pki/etcd/ca.crt --endpoints https://10.156.0.15:2379 endpoint health --cluster

修改: --endpoints https://10.156.0.15:2379,其IP地址为etcd-1

它应该给您这样的消息:

https://10.156.0.15:2379 is healthy: successfully committed proposal: took = 26.308693ms
https://10.156.0.16:2379 is healthy: successfully committed proposal: took = 26.614373ms

以上消息表明etcd正常运行,但请注意偶数节点。

如果您对此有任何疑问,请告诉我。