Red Hat Training

A Red Hat training course is available for OpenShift Container Platform

38장. etcd 쿼럼 복원

etcd 쿼럼이 손실되면 이를 복원할 수 있습니다.

  • 별도의 호스트에서 etcd를 실행하는 경우 etcd를 백업하고 etcd 클러스터를 끄고 새 호스트를 형성해야 합니다. 하나의 정상 etcd 노드를 사용하여 새 클러스터를 구성할 수 있지만 다른 모든 정상 노드를 제거해야 합니다.
  • 마스터 노드에서 etcd를 정적 포드로 실행하는 경우 etcd pod를 중지하고 임시 클러스터를 생성한 다음 etcd pod를 다시 시작합니다.
참고

etcd 쿼럼이 손실되는 동안 OpenShift Container Platform에서 실행되는 애플리케이션에 영향을 미치지 않습니다. 그러나 플랫폼 기능은 읽기 전용 작업으로 제한됩니다. 애플리케이션 확장 또는 축소, 배포 변경, 빌드 실행 또는 수정과 같은 조치를 취할 수 없습니다.

etcd 쿼럼 손실을 확인하려면 다음 명령 중 하나를 실행하고 클러스터가 비정상인지 확인합니다.

  • etcd v2 API를 사용하는 경우 다음 명령을 실행합니다.

    # etcd_ctl=2 etcdctl  --cert-file=/etc/origin/master/master.etcd-client.crt  \
              --key-file /etc/origin/master/master.etcd-client.key \
              --ca-file /etc/origin/master/master.etcd-ca.crt \
              --endpoints="https://*master-0.example.com*:2379,\
              https://*master-1.example.com*:2379,\
              https://*master-2.example.com*:2379"\
              cluster-health
    
    member 165201190bf7f217 is unhealthy: got unhealthy result from https://master-0.example.com:2379
    member b50b8a0acab2fa71 is unreachable: [https://master-1.example.com:2379] are all unreachable
    member d40307cbca7bc2df is unreachable: [https://master-2.example.com:2379] are all unreachable
    cluster is unhealthy
  • v3 API를 사용하는 경우 다음 명령을 실행합니다.

    # ETCDCTL_API=3 etcdctl --cert=/etc/origin/master/master.etcd-client.crt  \
              --key=/etc/origin/master/master.etcd-client.key \
              --cacert=/etc/origin/masterca.crt \
              --endpoints="https://*master-0.example.com*:2379,\
              https://*master-1.example.com*:2379,\
              https://*master-2.example.com*:2379"\
              endpoint health
    https://master-0.example.com:2379 is unhealthy: failed to connect: context deadline exceeded
    https://master-1.example.com:2379 is unhealthy: failed to connect: context deadline exceeded
    https://master-2.example.com:2379 is unhealthy: failed to connect: context deadline exceeded
    Error:  unhealthy cluster

호스트의 멤버 ID와 호스트 이름을 확인합니다. 새 클러스터를 구성하기 위해 연결할 수 있는 노드 중 하나를 사용합니다.

38.1. 별도의 서비스에 대해 etcd 쿼럼 복원

38.1.1. etcd 백업

etcd를 백업할 때 etcd 구성 파일과 etcd 데이터를 둘 다 백업해야 합니다.

38.1.1.1. etcd 구성 파일 백업

보존할 etcd 구성 파일은 모두 etcd가 실행 중인 인스턴스의 /etc/etcd 디렉터리에 저장됩니다. 여기에는 etcd 구성 파일(/etc/etcd/etcd.conf)과 클러스터 통신에 필요한 인증서가 포함됩니다. 이러한 모든 파일은 Ansible 설치 프로그램에서 설치 시 생성됩니다.

절차

클러스터의 etcd 멤버마다 etcd 구성을 백업하십시오.

$ ssh master-0 1
# mkdir -p /backup/etcd-config-$(date +%Y%m%d)/
# cp -R /etc/etcd/ /backup/etcd-config-$(date +%Y%m%d)/
1
master-0 을 etcd 멤버 이름으로 바꿉니다.
참고

각 etcd 클러스터 멤버의 인증서 및 구성 파일은 고유합니다.

38.1.1.2. etcd 데이터 백업

전제 조건
참고

OpenShift Container Platform 설치 프로그램에서는 별칭을 생성하여 etcd v2 작업의 경우 etcdctl2라는 모든 플래그, etcd v3 작업의 경우 etcdctl3이라는 모든 플래그를 입력하지 않아도 되게 합니다.

그러나 etcdctl3 별칭에서는 etcdctl 명령에 전체 끝점 목록을 제공하지 않으므로, --endpoints 옵션을 지정하고 모든 끝점을 나열해야 합니다.

etcd를 백업하기 전에 다음을 수행하십시오.

  • etcdctl 바이너리가 사용 가능해야 합니다. 컨테이너화된 설치에서는 rhel7/etcd 컨테이너를 사용할 수 있어야 합니다.
  • OpenShift Container Platform API 서비스가 실행 중인지 확인하십시오.
  • etcd 클러스터(2379/tcp 포트)와의 연결을 확인하십시오.
  • etcd 클러스터에 연결하기 위한 적절한 인증서를 확인하십시오.
절차
참고

백업을 수행할 때 etcdctl backup 명령을 사용하지만 etcd v3에는 백업이라는 개념이 없습니다. 대신 etcdctl snapshot save 명령으로 활성 멤버에서 스냅샷을 작성하거나 etcd 데이터 디렉터리에서 member/snap/db 파일을 복사합니다.

etcdctl backup 명령을 실행하면 백업에 포함된 일부 메타데이터, 특히 노드 ID 및 클러스터 ID가 다시 작성됩니다. 즉, 백업에서 노드의 이전 ID가 손실됩니다. 백업에서 클러스터를 다시 생성하려면 새로운 단일 노드 클러스터를 생성한 후 나머지 노드를 클러스터에 추가하십시오. 새 노드가 기존 클러스터에 조인하지 못하도록 메타데이터가 다시 작성됩니다.

etcd 데이터를 백업하십시오.

중요

이전 버전의 OpenShift Container Platform에서 업그레이드된 클러스터에는 v2 데이터 저장소가 포함될 수 있습니다. 모든 etcd 데이터 저장소를 백업하십시오.

  1. 정적 포드 매니페스트에서 etcd 끝점 IP 주소를 확보하십시오.

    $ export ETCD_POD_MANIFEST="/etc/origin/node/pods/etcd.yaml"
    $ export ETCD_EP=$(grep https ${ETCD_POD_MANIFEST} | cut -d '/' -f3)
  2. 관리자로 로그인합니다.

    $ oc login -u system:admin
  3. etcd 포드 이름을 확보하십시오.

    $ export ETCD_POD=$(oc get pods -n kube-system | grep -o -m 1 '^master-etcd\S*')
  4. kube-system 프로젝트로 변경합니다.

    $ oc project kube-system
  5. 포드에서 etcd 데이터의 스냅샷을 작성하여 로컬에 저장하십시오.

    $ oc exec ${ETCD_POD} -c etcd -- /bin/bash -c "ETCDCTL_API=3 etcdctl \
        --cert /etc/etcd/peer.crt \
        --key /etc/etcd/peer.key \
        --cacert /etc/etcd/ca.crt \
        --endpoints $ETCD_EP \
        snapshot save /var/lib/etcd/snapshot.db" 1
    1
    /var/lib/etcd/의 디렉터리에 스냅샷을 써야 합니다.

38.1.2. etcd 호스트 제거

복원 후 etcd 호스트에 장애가 발생하면 클러스터에서 제거하십시오. etcd 쿼럼 손실에서 복구하려면 클러스터에서 정상적인 etcd 노드를 모두 제거해야 합니다.

모든 마스터 호스트에서 수행할 단계

프로시저
  1. etcd 클러스터에서 서로 다른 etcd 호스트를 제거하십시오. 각 etcd 노드에 대해 다음 명령을 실행하십시오.

    # etcdctl3 --endpoints=https://<surviving host IP>:2379
      --cacert=/etc/etcd/ca.crt
      --cert=/etc/etcd/peer.crt
      --key=/etc/etcd/peer.key member remove <failed member ID>
  2. 모든 마스터의 /etc/origin/master/master-config.yaml +master 구성 파일에서 다른 etcd 호스트를 제거합니다.

    etcdClientInfo:
      ca: master.etcd-ca.crt
      certFile: master.etcd-client.crt
      keyFile: master.etcd-client.key
      urls:
        - https://master-0.example.com:2379
        - https://master-1.example.com:2379 1
        - https://master-2.example.com:2379 2
    1 2
    제거할 호스트입니다.
  3. 모든 마스터에서 마스터 API 서비스를 다시 시작하십시오.

    # master-restart api restart-master controller

현재 etcd 클러스터에서 수행할 단계

절차
  1. 클러스터에서 실패한 호스트를 제거하십시오.

    # etcdctl2 cluster-health
    member 5ee217d19001 is healthy: got healthy result from https://192.168.55.12:2379
    member 2a529ba1840722c0 is healthy: got healthy result from https://192.168.55.8:2379
    failed to check the health of member 8372784203e11288 on https://192.168.55.21:2379: Get https://192.168.55.21:2379/health: dial tcp 192.168.55.21:2379: getsockopt: connection refused
    member 8372784203e11288 is unreachable: [https://192.168.55.21:2379] are all unreachable
    member ed4f0efd277d7599 is healthy: got healthy result from https://192.168.55.13:2379
    cluster is healthy
    
    # etcdctl2 member remove 8372784203e11288 1
    Removed member 8372784203e11288 from cluster
    
    # etcdctl2 cluster-health
    member 5ee217d19001 is healthy: got healthy result from https://192.168.55.12:2379
    member 2a529ba1840722c0 is healthy: got healthy result from https://192.168.55.8:2379
    member ed4f0efd277d7599 is healthy: got healthy result from https://192.168.55.13:2379
    cluster is healthy
    1
    remove 명령에는 호스트 이름이 아니라 etcd ID가 필요합니다.
  2. etcd 서비스를 다시 시작할 때 etcd 구성이 실패한 호스트를 사용하지 않게 하려면 나머지 모든 etcd 호스트에서 /etc/etcd/etcd.conf 파일을 수정하고 ETCD_INITIAL_CLUSTER 변수의 값에서 실패한 호스트를 제거하십시오.

    # vi /etc/etcd/etcd.conf

    예를 들면 다음과 같습니다.

    ETCD_INITIAL_CLUSTER=master-0.example.com=https://192.168.55.8:2380,master-1.example.com=https://192.168.55.12:2380,master-2.example.com=https://192.168.55.13:2380

    이는 다음이 됩니다.

    ETCD_INITIAL_CLUSTER=master-0.example.com=https://192.168.55.8:2380,master-1.example.com=https://192.168.55.12:2380
    참고

    실패한 호스트는 etcdctl을 사용하여 제거되므로 etcd 서비스를 다시 시작할 필요가 없습니다.

  3. 클러스터의 현재 상태를 반영하고 플레이북을 다시 실행할 때 문제가 발생하지 않도록 Ansible 인벤토리 파일을 수정하십시오.

    [OSEv3:children]
    masters
    nodes
    etcd
    
    ... [OUTPUT ABBREVIATED] ...
    
    [etcd]
    master-0.example.com
    master-1.example.com
  4. Flannel을 사용하는 경우 모든 호스트에서 /etc/sysconfig/flanneld에 있는 flanneld 서비스 구성을 수정하고 etcd 호스트를 제거하십시오.

    FLANNEL_ETCD_ENDPOINTS=https://master-0.example.com:2379,https://master-1.example.com:2379,https://master-2.example.com:2379
  5. flanneld 서비스를 다시 시작하십시오.

    # systemctl restart flanneld.service

38.1.3. 단일 노드 etcd 클러스터 생성

OpenShift Container Platform 인스턴스의 전체 기능을 복원하려면 나머지 etcd 노드를 독립 실행형 etcd 클러스터로 설정합니다.

절차
  1. 클러스터에서 제거하지 않은 etcd 노드에서 etcd pod 정의를 제거하여 모든 etcd 서비스를 중지합니다.

    # mkdir -p /etc/origin/node/pods-stopped
    # mv /etc/origin/node/pods/etcd.yaml /etc/origin/node/pods-stopped/
    # systemctl stop atomic-openshift-node
    # mv /etc/origin/node/pods-stopped/etcd.yaml /etc/origin/node/pods/
  2. 호스트에서 etcd 서비스를 실행하여 새 클러스터를 강제 실행합니다.

    이러한 명령은 etcd 서비스의 사용자 지정 파일을 생성하여 etcd start 명령에 --force-new-cluster 옵션을 추가합니다.

    # mkdir -p /etc/systemd/system/etcd.service.d/
    # echo "[Service]" > /etc/systemd/system/etcd.service.d/temp.conf
    # echo "ExecStart=" >> /etc/systemd/system/etcd.service.d/temp.conf
    # sed -n '/ExecStart/s/"$/ --force-new-cluster"/p' \
        /usr/lib/systemd/system/etcd.service \
        >> /etc/systemd/system/etcd.service.d/temp.conf
    
    # systemctl daemon-reload
    # master-restart etcd
  3. etcd 멤버를 나열하고 멤버 목록에 단일 etcd 호스트만 포함되어 있는지 확인합니다.

    # etcdctl member list
    165201190bf7f217: name=192.168.34.20 peerURLs=http://localhost:2380 clientURLs=https://master-0.example.com:2379 isLeader=true
  4. 데이터를 복원하고 새 클러스터를 생성한 후 etcd가 피어 통신을 수신하는 IP 주소를 사용하도록 peerURLs 매개변수 값을 업데이트해야 합니다.

    # etcdctl member update 165201190bf7f217 https://192.168.34.20:2380 1
    1
    165201190bf7f217 은 이전 명령의 출력에 표시된 멤버 ID이며 https://192.168.34.20:2380 은(는) IP 주소입니다.
  5. 검증하려면 IP가 멤버 목록에 있는지 확인하십시오.

    $ etcdctl2 member list
    5ee217d17301: name=master-0.example.com peerURLs=https://*192.168.55.8*:2380 clientURLs=https://192.168.55.8:2379 isLeader=true

38.1.4. 복원 후 etcd 노드 추가

첫 번째 인스턴스가 실행되면 클러스터에 여러 etcd 서버를 추가할 수 있습니다.

절차
  1. ETCD_NAME 변수에서 인스턴스의 etcd 이름을 가져옵니다.

    # grep ETCD_NAME /etc/etcd/etcd.conf
  2. etcd가 피어 통신을 청취하는 IP 주소를 가져옵니다.

    # grep ETCD_INITIAL_ADVERTISE_PEER_URLS /etc/etcd/etcd.conf
  3. 노드가 이전에 etcd 클러스터의 일부인 경우 이전 etcd 데이터를 삭제합니다.

    # rm -Rf /var/lib/etcd/*
  4. etcd가 올바르게 실행되는 etcd 호스트에서 새 멤버를 추가합니다.

    # etcdctl3 member add *<name>* \
      --peer-urls="*<advertise_peer_urls>*"

    명령은 일부 변수를 출력합니다. 예를 들면 다음과 같습니다.

    ETCD_NAME="master2"
    ETCD_INITIAL_CLUSTER="master-0.example.com=https://192.168.55.8:2380"
    ETCD_INITIAL_CLUSTER_STATE="existing"
  5. 이전 명령의 값을 새 호스트의 /etc/etcd/etcd.conf 파일에 추가합니다.

    # vi /etc/etcd/etcd.conf
  6. 클러스터에 가입하는 노드에서 etcd 서비스를 시작합니다.

    # systemctl start etcd.service
  7. 오류 메시지를 확인하십시오.

    # master-logs etcd etcd
  8. 모든 노드를 추가하고 나면 클러스터 상태 및 클러스터 상태를 확인합니다.

    # etcdctl3 endpoint health --endpoints="https://<etcd_host1>:2379,https://<etcd_host2>:2379,https://<etcd_host3>:2379"
    https://master-0.example.com:2379 is healthy: successfully committed proposal: took = 1.423459ms
    https://master-1.example.com:2379 is healthy: successfully committed proposal: took = 1.767481ms
    https://master-2.example.com:2379 is healthy: successfully committed proposal: took = 1.599694ms
    
    # etcdctl3 endpoint status --endpoints="https://<etcd_host1>:2379,https://<etcd_host2>:2379,https://<etcd_host3>:2379"
    https://master-0.example.com:2379, 40bef1f6c79b3163, 3.2.5, 28 MB, true, 9, 2878
    https://master-1.example.com:2379, 1ea57201a3ff620a, 3.2.5, 28 MB, false, 9, 2878
    https://master-2.example.com:2379, 59229711e4bc65c8, 3.2.5, 28 MB, false, 9, 2878
  9. 나머지 피어를 클러스터에 다시 추가합니다.