kubeadm으로 고가용성 etcd 클러스터 설정하기

kubeadm으로 고가용성 etcd 클러스터 설정하기 (Set up a High Availability etcd Cluster with kubeadm)

기본적으로 kubeadm은 각 제어 플레인 노드에서 로컬 etcd 인스턴스를 실행해요. etcd 클러스터를 외부로 취급하고 별도 호스트에서 etcd 인스턴스를 프로비저닝할 수도 있어요. 두 접근 방식의 차이는 고가용성 토폴로지 옵션 페이지에 나와 있어요.

이 태스크는 kubeadm이 클러스터 생성 중에 사용할 수 있는 세 멤버의 고가용성 외부 etcd 클러스터를 만드는 과정을 안내해요.

출처: 문서

본문

시작하기 전에 (Before you begin)

  • TCP 포트 2379와 2380으로 서로 통신할 수 있는 호스트 세 개. 이 문서는 기본 포트를 가정해요. 하지만 kubeadm 구성 파일로 구성할 수 있어요.
  • 각 호스트에 systemd와 bash 호환 셸이 설치되어 있어야 해요.
  • 각 호스트에 컨테이너 런타임, kubelet, kubeadm이 설치되어 있어야 해요.
  • 각 호스트가 쿠버네티스 컨테이너 이미지 레지스트리(registry.k8s.io)에 접근할 수 있어야 하며, 필요한 etcd 이미지는 kubeadm config images list/pull 을 사용해 나열·풀할 수 있어요. 이 가이드는 etcd 인스턴스를 kubelet이 관리하는 정적 파드로 설정해요.
  • 호스트 간 파일을 복사할 수 있는 인프라. 예를 들어 sshscp 로 충족할 수 있어요.

클러스터 설정하기

일반적인 접근 방식은 한 노드에서 모든 인증서를 생성하고 필요한 파일만 다른 노드에 배포하는 것이에요.

참고:

kubeadm에는 아래 설명한 인증서를 생성하는 데 필요한 모든 암호화 장치가 포함돼 있으므로, 이 예시에서는 다른 암호화 도구가 필요하지 않아요.

참고:

아래 예시는 IPv4 주소를 사용하지만 kubeadm, kubelet, etcd도 IPv6 주소를 사용하도록 구성할 수 있어요. 듀얼 스택은 일부 쿠버네티스 옵션에서 지원되지만 etcd에서는 지원되지 않아요. 쿠버네티스 듀얼 스택 지원에 대한 자세한 내용은 kubeadm의 듀얼 스택 지원을 참고해요.

kubelet을 etcd의 서비스 매니저로 구성하기

참고:

etcd가 실행되어야 하는 모든 호스트에서 이 작업을 해야 해요.

etcd가 먼저 생성됐으므로, kubeadm이 제공하는 kubelet 유닛 파일보다 더 높은 우선순위를 가진 새 유닛 파일을 만들어 서비스 우선순위를 재정의해야 해요.

cat << EOF > /etc/systemd/system/kubelet.service.d/kubelet.conf
# Replace "systemd" with the cgroup driver of your container runtime. The default value in the kubelet is "cgroupfs".
# Replace the value of "containerRuntimeEndpoint" for a different container runtime if needed.
#
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authentication:
  anonymous:
    enabled: false
  webhook:
    enabled: false
authorization:
  mode: AlwaysAllow
cgroupDriver: systemd
address: 127.0.0.1
containerRuntimeEndpoint: unix:///var/run/containerd/containerd.sock
staticPodPath: /etc/kubernetes/manifests
EOF

cat << EOF > /etc/systemd/system/kubelet.service.d/20-etcd-service-manager.conf
[Service]
ExecStart=
ExecStart=/usr/bin/kubelet --config=/etc/systemd/system/kubelet.service.d/kubelet.conf
Restart=always
EOF

systemctl daemon-reload
systemctl restart kubelet

kubelet 상태를 확인해 실행 중인지 확인합니다:

systemctl status kubelet

kubeadm 구성 파일 만들기

etcd 멤버가 실행될 각 호스트에 대해 다음 스크립트를 사용해 kubeadm 구성 파일을 하나씩 생성해요.

# Update HOST0, HOST1 and HOST2 with the IPs of your hosts
export HOST0=10.0.0.6
export HOST1=10.0.0.7
export HOST2=10.0.0.8

# Update NAME0, NAME1 and NAME2 with the hostnames of your hosts
export NAME0="infra0"
export NAME1="infra1"
export NAME2="infra2"

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

HOSTS=(${HOST0} ${HOST1} ${HOST2})
NAMES=(${NAME0} ${NAME1} ${NAME2})

for i in "${!HOSTS[@]}"; do
HOST=${HOSTS[$i]}
NAME=${NAMES[$i]}
cat << EOF > /tmp/${HOST}/kubeadmcfg.yaml
---
apiVersion: "kubeadm.k8s.io/v1beta4"
kind: InitConfiguration
nodeRegistration:
    name: ${NAME}
localAPIEndpoint:
    advertiseAddress: ${HOST}
---
apiVersion: "kubeadm.k8s.io/v1beta4"
kind: ClusterConfiguration
etcd:
    local:
        serverCertSANs:
        - "${HOST}"
        peerCertSANs:
        - "${HOST}"
        extraArgs:
            initial-cluster: ${NAMES[0]}=https://${HOSTS[0]}:2380,${NAMES[1]}=https://${HOSTS[1]}:2380,${NAMES[2]}=https://${HOSTS[2]}: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

인증서 생성하기

다음 단계는 etcd 인증서를 생성하는 것이에요. 기존 인증서를 사용하는 경우 /etc/kubernetes/pki/etcd/ca.crt 파일과 다음 목록의 다른 인증서들로 이 단계를 건너뛸 수 있어요.

Kubernetes API server와의 동료 인증(peer authentication)을 위해 ca.crt 를 생성하고 ca.key 를 사용해 서명합니다.

kubeadm init phase certs etcd-ca

etcd-ca 인증 기관으로 서명된 다음 인증서를 생성합니다:

kubeadm init phase certs etcd-server --config=/tmp/${HOST2}/kubeadmcfg.yaml
kubeadm init phase certs etcd-peer --config=/tmp/${HOST2}/kubeadmcfg.yaml
kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST2}/kubeadmcfg.yaml
kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST2}/kubeadmcfg.yaml
cp -R /etc/kubernetes/pki /tmp/${HOST2}/
# cleanup non-reusable certificates
find /etc/kubernetes/pki -type f -name '*.crt' -o -name '*.key' | xargs rm -rf

인증서를 어디에 복사해야 하는지 확인하려면 /etc/kubernetes/pki/etcd/ 의 인증서 디렉터리를 고려해야 해요.

서명된 인증서를 생성하고 호스트 간에 배포한 뒤, etcd 구성이 올바른지 확인합니다:

kubeadm init phase etcd local --config=/tmp/${HOST2}/kubeadmcfg.yaml
kubeadm init phase etcd local --config=/tmp/${HOST1}/kubeadmcfg.yaml
kubeadm init phase etcd local --config=/tmp/${HOST0}/kubeadmcfg.yaml

더 알아보기 (Learn more)

etcd 멤버 3개가 정상 동작하는 클러스터를 갖게 되면, kubeadm의 외부 etcd 방법으로 고가용성 제어 플레인 설정을 계속할 수 있어요.