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 데이터 저장소를 백업하십시오.
정적 포드 매니페스트에서 etcd 끝점 IP 주소를 확보하십시오.
$ export ETCD_POD_MANIFEST="/etc/origin/node/pods/etcd.yaml"
$ export ETCD_EP=$(grep https ${ETCD_POD_MANIFEST} | cut -d '/' -f3)
관리자로 로그인합니다.
$ oc login -u system:admin
etcd 포드 이름을 확보하십시오.
$ export ETCD_POD=$(oc get pods -n kube-system | grep -o -m 1 '^master-etcd\S*')
kube-system
프로젝트로 변경합니다.$ oc project kube-system
포드에서 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 노드를 모두 제거해야 합니다.
모든 마스터 호스트에서 수행할 단계
프로시저
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>
모든 마스터의
/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
모든 마스터에서 마스터 API 서비스를 다시 시작하십시오.
# master-restart api restart-master controller
현재 etcd 클러스터에서 수행할 단계
절차
클러스터에서 실패한 호스트를 제거하십시오.
# 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가 필요합니다.
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 서비스를 다시 시작할 필요가 없습니다.클러스터의 현재 상태를 반영하고 플레이북을 다시 실행할 때 문제가 발생하지 않도록 Ansible 인벤토리 파일을 수정하십시오.
[OSEv3:children] masters nodes etcd ... [OUTPUT ABBREVIATED] ... [etcd] master-0.example.com master-1.example.com
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
flanneld
서비스를 다시 시작하십시오.# systemctl restart flanneld.service
38.1.3. 단일 노드 etcd 클러스터 생성
OpenShift Container Platform 인스턴스의 전체 기능을 복원하려면 나머지 etcd 노드를 독립 실행형 etcd 클러스터로 설정합니다.
절차
클러스터에서 제거하지 않은 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/
호스트에서 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
etcd 멤버를 나열하고 멤버 목록에 단일 etcd 호스트만 포함되어 있는지 확인합니다.
# etcdctl member list 165201190bf7f217: name=192.168.34.20 peerURLs=http://localhost:2380 clientURLs=https://master-0.example.com:2379 isLeader=true
데이터를 복원하고 새 클러스터를 생성한 후 etcd가 피어 통신을 수신하는 IP 주소를 사용하도록
peerURLs
매개변수 값을 업데이트해야 합니다.# etcdctl member update 165201190bf7f217 https://192.168.34.20:2380 1
- 1
165201190bf7f217
은 이전 명령의 출력에 표시된 멤버 ID이며https://192.168.34.20:2380
은(는) IP 주소입니다.
검증하려면 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 서버를 추가할 수 있습니다.
절차
ETCD_NAME
변수에서 인스턴스의 etcd 이름을 가져옵니다.# grep ETCD_NAME /etc/etcd/etcd.conf
etcd가 피어 통신을 청취하는 IP 주소를 가져옵니다.
# grep ETCD_INITIAL_ADVERTISE_PEER_URLS /etc/etcd/etcd.conf
노드가 이전에 etcd 클러스터의 일부인 경우 이전 etcd 데이터를 삭제합니다.
# rm -Rf /var/lib/etcd/*
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"
이전 명령의 값을 새 호스트의
/etc/etcd/etcd.conf
파일에 추가합니다.# vi /etc/etcd/etcd.conf
클러스터에 가입하는 노드에서 etcd 서비스를 시작합니다.
# systemctl start etcd.service
오류 메시지를 확인하십시오.
# master-logs etcd etcd
모든 노드를 추가하고 나면 클러스터 상태 및 클러스터 상태를 확인합니다.
# 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
- 나머지 피어를 클러스터에 다시 추가합니다.