|
| 1 | +--- |
| 2 | +title: kubeadm 설치하기 |
| 3 | +content_type: task |
| 4 | +weight: 10 |
| 5 | +card: |
| 6 | + name: setup |
| 7 | + weight: 20 |
| 8 | + title: kubeadm 설정 도구 설치 |
| 9 | +--- |
| 10 | + |
| 11 | +<!-- overview --> |
| 12 | + |
| 13 | +<img src="https://raw.githubusercontent.com/kubernetes/kubeadm/master/logos/stacked/color/kubeadm-stacked-color.png" align="right" width="150px">이 페이지에서는 `kubeadm` 툴박스를 설치하는 방법을 보여준다. |
| 14 | +이 설치 프로세스를 수행한 후 kubeadm으로 클러스터를 만드는 방법에 대한 자세한 내용은 [kubeadm을 사용하여 클러스터 생성하기](/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/) 페이지를 참고한다. |
| 15 | + |
| 16 | + |
| 17 | + |
| 18 | +## {{% heading "prerequisites" %}} |
| 19 | + |
| 20 | + |
| 21 | +* 다음 중 하나를 실행하는 하나 이상의 머신이 필요하다. |
| 22 | + - Ubuntu 16.04+ |
| 23 | + - Debian 9+ |
| 24 | + - CentOS 7+ |
| 25 | + - Red Hat Enterprise Linux (RHEL) 7+ |
| 26 | + - Fedora 25+ |
| 27 | + - HypriotOS v1.0.1+ |
| 28 | + - Flatcar Container Linux (2512.3.0으로 테스트됨) |
| 29 | +* 2 GB 이상의 램을 장착한 머신. (이 보다 작으면 사용자의 앱을 위한 공간이 거의 남지 않음) |
| 30 | +* 2 이상의 CPU. |
| 31 | +* 클러스터의 모든 머신에 걸친 전체 네트워크 연결. (공용 또는 사설 네트워크면 괜찮음) |
| 32 | +* 모든 노드에 대해 고유한 호스트 이름, MAC 주소 및 product_uuid. 자세한 내용은 [여기](#verify-mac-address)를 참고한다. |
| 33 | +* 컴퓨터의 특정 포트들 개방. 자세한 내용은 [여기](#check-required-ports)를 참고한다. |
| 34 | +* 스왑의 비활성화. kubelet이 제대로 작동하게 하려면 **반드시** 스왑을 사용하지 않도록 설정한다. |
| 35 | + |
| 36 | + |
| 37 | + |
| 38 | +<!-- steps --> |
| 39 | + |
| 40 | +## MAC 주소 및 product_uuid가 모든 노드에 대해 고유한지 확인 {#verify-mac-address} |
| 41 | +* 사용자는 `ip link` 또는 `ifconfig -a` 명령을 사용하여 네트워크 인터페이스의 MAC 주소를 확인할 수 있다. |
| 42 | +* product_uuid는 `sudo cat /sys/class/dmi/id/product_uuid` 명령을 사용하여 확인할 수 있다. |
| 43 | + |
| 44 | +일부 가상 머신은 동일한 값을 가질 수 있지만 하드웨어 장치는 고유한 주소를 가질 |
| 45 | +가능성이 높다. 쿠버네티스는 이러한 값을 사용하여 클러스터의 노드를 고유하게 식별한다. |
| 46 | +이러한 값이 각 노드에 고유하지 않으면 설치 프로세스가 |
| 47 | +[실패](https://github.com/kubernetes/kubeadm/issues/31)할 수 있다. |
| 48 | + |
| 49 | +## 네트워크 어댑터 확인 |
| 50 | + |
| 51 | +네트워크 어댑터가 두 개 이상이고, 쿠버네티스 컴포넌트가 디폴트 라우트(default route)에서 도달할 수 없는 |
| 52 | +경우, 쿠버네티스 클러스터 주소가 적절한 어댑터를 통해 이동하도록 IP 경로를 추가하는 것이 좋다. |
| 53 | + |
| 54 | +## iptables가 브리지된 트래픽을 보게 하기 |
| 55 | + |
| 56 | +`br_netfilter` 모듈이 로드되었는지 확인한다. `lsmod | grep br_netfilter` 를 실행하면 된다. 명시적으로 로드하려면 `sudo modprobe br_netfilter` 를 실행한다. |
| 57 | + |
| 58 | +리눅스 노드의 iptables가 브리지된 트래픽을 올바르게 보기 위한 요구 사항으로, `sysctl` 구성에서 `net.bridge.bridge-nf-call-iptables` 가 1로 설정되어 있는지 확인해야 한다. 다음은 예시이다. |
| 59 | + |
| 60 | +```bash |
| 61 | +cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf |
| 62 | +br_netfilter |
| 63 | +EOF |
| 64 | + |
| 65 | +cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf |
| 66 | +net.bridge.bridge-nf-call-ip6tables = 1 |
| 67 | +net.bridge.bridge-nf-call-iptables = 1 |
| 68 | +EOF |
| 69 | +sudo sysctl --system |
| 70 | +``` |
| 71 | + |
| 72 | +자세한 내용은 [네트워크 플러그인 요구 사항](/ko/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/#네트워크-플러그인-요구-사항) 페이지를 참고한다. |
| 73 | + |
| 74 | +## 필수 포트 확인 {#check-required-ports} |
| 75 | + |
| 76 | +### 컨트롤 플레인 노드 |
| 77 | + |
| 78 | +| 프로토콜 | 방향 | 포트 범위 | 목적 | 사용자 | |
| 79 | +|----------|-----------|------------|-------------------------|---------------------------| |
| 80 | +| TCP | 인바운드 | 6443* | 쿠버네티스 API 서버 | 모두 | |
| 81 | +| TCP | 인바운드 | 2379-2380 | etcd 서버 클라이언트 API | kube-apiserver, etcd | |
| 82 | +| TCP | 인바운드 | 10250 | kubelet API | 자체, 컨트롤 플레인 | |
| 83 | +| TCP | 인바운드 | 10251 | kube-scheduler | 자체 | |
| 84 | +| TCP | 인바운드 | 10252 | kube-controller-manager | 자체 | |
| 85 | + |
| 86 | +### 워커 노드 |
| 87 | + |
| 88 | +| 프로토콜 | 방향 | 포트 범위 | 목적 | 사용자 | |
| 89 | +|----------|-----------|-------------|-----------------------|-------------------------| |
| 90 | +| TCP | 인바운드 | 10250 | kubelet API | 자체, 컨트롤 플레인 | |
| 91 | +| TCP | 인바운드 | 30000-32767 | NodePort 서비스† | 모두 | |
| 92 | + |
| 93 | +† [NodePort 서비스](/ko/docs/concepts/services-networking/service/)의 기본 포트 범위. |
| 94 | + |
| 95 | +*로 표시된 모든 포트 번호는 재정의할 수 있으므로, 사용자 지정 포트도 |
| 96 | +열려 있는지 확인해야 한다. |
| 97 | + |
| 98 | +etcd 포트가 컨트롤 플레인 노드에 포함되어 있지만, 외부 또는 사용자 지정 포트에서 |
| 99 | +자체 etcd 클러스터를 호스팅할 수도 있다. |
| 100 | + |
| 101 | +사용자가 사용하는 파드 네트워크 플러그인(아래 참조)은 특정 포트를 열어야 할 수도 |
| 102 | +있다. 이것은 각 파드 네트워크 플러그인마다 다르므로, 필요한 포트에 대한 |
| 103 | +플러그인 문서를 참고한다. |
| 104 | + |
| 105 | +## 런타임 설치 {#installing-runtime} |
| 106 | + |
| 107 | +파드에서 컨테이너를 실행하기 위해, 쿠버네티스는 |
| 108 | +{{< glossary_tooltip term_id="container-runtime" text="컨테이너 런타임" >}}을 사용한다. |
| 109 | + |
| 110 | +{{< tabs name="container_runtime" >}} |
| 111 | +{{% tab name="리눅스 노드" %}} |
| 112 | + |
| 113 | +기본적으로, 쿠버네티스는 |
| 114 | +{{< glossary_tooltip term_id="cri" text="컨테이너 런타임 인터페이스">}}(CRI)를 |
| 115 | +사용하여 사용자가 선택한 컨테이너 런타임과 인터페이스한다. |
| 116 | + |
| 117 | +런타임을 지정하지 않으면, kubeadm은 잘 알려진 유닉스 도메인 소켓 목록을 검색하여 |
| 118 | +설치된 컨테이너 런타임을 자동으로 감지하려고 한다. |
| 119 | +다음 표에는 컨테이너 런타임 및 관련 소켓 경로가 나열되어 있다. |
| 120 | + |
| 121 | +{{< table caption = "컨테이너 런타임과 소켓 경로" >}} |
| 122 | +| 런타임 | 유닉스 도메인 소켓 경로 | |
| 123 | +|------------|-----------------------------------| |
| 124 | +| 도커 | `/var/run/docker.sock` | |
| 125 | +| containerd | `/run/containerd/containerd.sock` | |
| 126 | +| CRI-O | `/var/run/crio/crio.sock` | |
| 127 | +{{< /table >}} |
| 128 | + |
| 129 | +<br /> |
| 130 | +도커와 containerd가 모두 감지되면 도커가 우선시된다. 이것이 필요한 이유는 도커 18.09에서 |
| 131 | +도커만 설치한 경우에도 containerd와 함께 제공되므로 둘 다 감지될 수 있기 |
| 132 | +때문이다. |
| 133 | +다른 두 개 이상의 런타임이 감지되면, kubeadm은 오류와 함께 종료된다. |
| 134 | + |
| 135 | +kubelet은 빌트인 `dockershim` CRI 구현을 통해 도커와 통합된다. |
| 136 | + |
| 137 | +자세한 내용은 [컨테이너 런타임](/ko/docs/setup/production-environment/container-runtimes/)을 |
| 138 | +참고한다. |
| 139 | +{{% /tab %}} |
| 140 | +{{% tab name="다른 운영 체제" %}} |
| 141 | +기본적으로, kubeadm은 컨테이너 런타임으로 {{< glossary_tooltip term_id="docker" >}}를 사용한다. |
| 142 | +kubelet은 빌트인 `dockershim` CRI 구현을 통해 도커와 통합된다. |
| 143 | + |
| 144 | +자세한 내용은 [컨테이너 런타임](/ko/docs/setup/production-environment/container-runtimes/)을 |
| 145 | +참고한다. |
| 146 | +{{% /tab %}} |
| 147 | +{{< /tabs >}} |
| 148 | + |
| 149 | + |
| 150 | +## kubeadm, kubelet 및 kubectl 설치 |
| 151 | + |
| 152 | +모든 머신에 다음 패키지들을 설치한다. |
| 153 | + |
| 154 | +* `kubeadm`: 클러스터를 부트스트랩하는 명령이다. |
| 155 | + |
| 156 | +* `kubelet`: 클러스터의 모든 머신에서 실행되는 파드와 컨테이너 시작과 |
| 157 | + 같은 작업을 수행하는 컴포넌트이다. |
| 158 | + |
| 159 | +* `kubectl`: 클러스터와 통신하기 위한 커맨드 라인 유틸리티이다. |
| 160 | + |
| 161 | +kubeadm은 `kubelet` 또는 `kubectl` 을 설치하거나 관리하지 **않으므로**, kubeadm이 |
| 162 | +설치하려는 쿠버네티스 컨트롤 플레인의 버전과 일치하는지 |
| 163 | +확인해야 한다. 그렇지 않으면, 예상치 못한 버그 동작으로 이어질 수 있는 |
| 164 | +버전 차이(skew)가 발생할 위험이 있다. 그러나, kubelet과 컨트롤 플레인 사이에 _하나의_ |
| 165 | +마이너 버전 차이가 지원되지만, kubelet 버전은 API 서버 버전 보다 |
| 166 | +높을 수 없다. 예를 들어, 1.7.0 버전의 kubelet은 1.8.0 API 서버와 완전히 호환되어야 하지만, |
| 167 | +그 반대의 경우는 아니다. |
| 168 | + |
| 169 | +`kubectl` 설치에 대한 정보는 [kubectl 설치 및 설정](/ko/docs/tasks/tools/install-kubectl/)을 참고한다. |
| 170 | + |
| 171 | +{{< warning >}} |
| 172 | +이 지침은 모든 시스템 업그레이드에서 모든 쿠버네티스 패키지를 제외한다. |
| 173 | +이는 kubeadm 및 쿠버네티스를 |
| 174 | +[업그레이드 하는 데 특별한 주의](/ko/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/)가 필요하기 때문이다. |
| 175 | +{{</ warning >}} |
| 176 | + |
| 177 | +버전 차이에 대한 자세한 내용은 다음을 참고한다. |
| 178 | + |
| 179 | +* 쿠버네티스 [버전 및 버전-차이 정책](/docs/setup/release/version-skew-policy/) |
| 180 | +* Kubeadm 관련 [버전 차이 정책](/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#version-skew-policy) |
| 181 | + |
| 182 | +{{< tabs name="k8s_install" >}} |
| 183 | +{{% tab name="Ubuntu, Debian 또는 HypriotOS" %}} |
| 184 | +```bash |
| 185 | +sudo apt-get update && sudo apt-get install -y apt-transport-https curl |
| 186 | +curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - |
| 187 | +cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list |
| 188 | +deb https://apt.kubernetes.io/ kubernetes-xenial main |
| 189 | +EOF |
| 190 | +sudo apt-get update |
| 191 | +sudo apt-get install -y kubelet kubeadm kubectl |
| 192 | +sudo apt-mark hold kubelet kubeadm kubectl |
| 193 | +``` |
| 194 | +{{% /tab %}} |
| 195 | +{{% tab name="CentOS, RHEL 또는 Fedora" %}} |
| 196 | +```bash |
| 197 | +cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo |
| 198 | +[kubernetes] |
| 199 | +name=Kubernetes |
| 200 | +baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch |
| 201 | +enabled=1 |
| 202 | +gpgcheck=1 |
| 203 | +repo_gpgcheck=1 |
| 204 | +gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg |
| 205 | +exclude=kubelet kubeadm kubectl |
| 206 | +EOF |
| 207 | + |
| 208 | +# permissive 모드로 SELinux 설정(효과적으로 비활성화) |
| 209 | +sudo setenforce 0 |
| 210 | +sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config |
| 211 | + |
| 212 | +sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes |
| 213 | + |
| 214 | +sudo systemctl enable --now kubelet |
| 215 | +``` |
| 216 | + |
| 217 | + **참고:** |
| 218 | + |
| 219 | + - `setenforce 0` 및 `sed ...` 를 실행하여 permissive 모드로 SELinux를 설정하면 효과적으로 비활성화된다. |
| 220 | + 컨테이너가 호스트 파일시스템(예를 들어, 파드 네트워크에 필요한)에 접근하도록 허용하는 데 필요하다. |
| 221 | + kubelet에서 SELinux 지원이 개선될 때까지 이 작업을 수행해야 한다. |
| 222 | + |
| 223 | + - 구성 방법을 알고 있는 경우 SELinux를 활성화된 상태로 둘 수 있지만 kubeadm에서 지원하지 않는 설정이 필요할 수 있다. |
| 224 | + |
| 225 | +{{% /tab %}} |
| 226 | +{{% tab name="Fedora CoreOS 또는 Flatcar Container Linux" %}} |
| 227 | +CNI 플러그인 설치(대부분의 파드 네트워크에 필요) |
| 228 | + |
| 229 | +```bash |
| 230 | +CNI_VERSION="v0.8.2" |
| 231 | +sudo mkdir -p /opt/cni/bin |
| 232 | +curl -L "https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-amd64-${CNI_VERSION}.tgz" | sudo tar -C /opt/cni/bin -xz |
| 233 | +``` |
| 234 | + |
| 235 | +명령어 파일을 다운로드할 디렉터리 정의 |
| 236 | + |
| 237 | +{{< note >}} |
| 238 | +`DOWNLOAD_DIR` 변수는 쓰기 가능한 디렉터리로 설정되어야 한다. |
| 239 | +Flatcar Container Linux를 실행 중인 경우, `DOWNLOAD_DIR=/opt/bin` 을 설정한다. |
| 240 | +{{< /note >}} |
| 241 | + |
| 242 | +```bash |
| 243 | +DOWNLOAD_DIR=/usr/local/bin |
| 244 | +sudo mkdir -p $DOWNLOAD_DIR |
| 245 | +``` |
| 246 | + |
| 247 | +crictl 설치(kubeadm / Kubelet 컨테이너 런타임 인터페이스(CRI)에 필요) |
| 248 | + |
| 249 | +```bash |
| 250 | +CRICTL_VERSION="v1.17.0" |
| 251 | +curl -L "https://github.com/kubernetes-sigs/cri-tools/releases/download/${CRICTL_VERSION}/crictl-${CRICTL_VERSION}-linux-amd64.tar.gz" | sudo tar -C $DOWNLOAD_DIR -xz |
| 252 | +``` |
| 253 | + |
| 254 | +`kubeadm`, `kubelet`, `kubectl` 설치 및 `kubelet` systemd 서비스 추가 |
| 255 | + |
| 256 | +```bash |
| 257 | +RELEASE="$(curl -sSL https://dl.k8s.io/release/stable.txt)" |
| 258 | +cd $DOWNLOAD_DIR |
| 259 | +sudo curl -L --remote-name-all https://storage.googleapis.com/kubernetes-release/release/${RELEASE}/bin/linux/amd64/{kubeadm,kubelet,kubectl} |
| 260 | +sudo chmod +x {kubeadm,kubelet,kubectl} |
| 261 | + |
| 262 | +RELEASE_VERSION="v0.4.0" |
| 263 | +curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubelet/lib/systemd/system/kubelet.service" | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee /etc/systemd/system/kubelet.service |
| 264 | +sudo mkdir -p /etc/systemd/system/kubelet.service.d |
| 265 | +curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubeadm/10-kubeadm.conf" | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee /etc/systemd/system/kubelet.service.d/10-kubeadm.conf |
| 266 | +``` |
| 267 | + |
| 268 | +`kubelet` 활성화 및 시작 |
| 269 | + |
| 270 | +```bash |
| 271 | +systemctl enable --now kubelet |
| 272 | +``` |
| 273 | + |
| 274 | +{{< note >}} |
| 275 | +Flatcar Container Linux 배포판은 `/usr` 디렉터리를 읽기 전용 파일시스템으로 마운트한다. |
| 276 | +클러스터를 부트스트랩하기 전에, 쓰기 가능한 디렉터리를 구성하기 위한 추가 단계를 수행해야 한다. |
| 277 | +쓰기 가능한 디렉터리를 설정하는 방법을 알아 보려면 [Kubeadm 문제 해결 가이드](/docs/setup/production-environment/tools/kubeadm/troubleshooting-kubeadm/#usr-mounted-read-only/)를 참고한다. |
| 278 | +{{< /note >}} |
| 279 | +{{% /tab %}} |
| 280 | +{{< /tabs >}} |
| 281 | + |
| 282 | + |
| 283 | +kubelet은 이제 kubeadm이 수행할 작업을 알려 줄 때까지 크래시루프(crashloop) 상태로 |
| 284 | +기다려야 하므로 몇 초마다 다시 시작된다. |
| 285 | + |
| 286 | +## 컨트롤 플레인 노드에서 kubelet이 사용하는 cgroup 드라이버 구성 |
| 287 | + |
| 288 | +도커를 사용할 때, kubeadm은 kubelet 용 cgroup 드라이버를 자동으로 감지하여 |
| 289 | +런타임 중에 `/var/lib/kubelet/config.yaml` 파일에 설정한다. |
| 290 | + |
| 291 | +다른 CRI를 사용하는 경우, 다음과 같이 `cgroupDriver` 값을 `kubeadm init` 에 전달해야 한다. |
| 292 | + |
| 293 | +```yaml |
| 294 | +apiVersion: kubelet.config.k8s.io/v1beta1 |
| 295 | +kind: KubeletConfiguration |
| 296 | +cgroupDriver: <value> |
| 297 | +``` |
| 298 | +
|
| 299 | +자세한 내용은 [구성 파일과 함께 kubeadm init 사용](/docs/reference/setup-tools/kubeadm/kubeadm-init/#config-file)을 참고한다. |
| 300 | +
|
| 301 | +`cgroupfs` 가 이미 kubelet의 기본값이기 때문에, 사용자의 |
| 302 | +CRI cgroup 드라이버가 `cgroupfs` 가 아닌 **경우에만** 위와 같이 설정해야 한다. |
| 303 | + |
| 304 | +{{< note >}} |
| 305 | +`--cgroup-driver` 플래그가 kubelet에 의해 사용 중단되었으므로, `/var/lib/kubelet/kubeadm-flags.env` |
| 306 | +또는 `/etc/default/kubelet`(RPM에 대해서는 `/etc/sysconfig/kubelet`)에 있는 경우, 그것을 제거하고 대신 KubeletConfiguration을 |
| 307 | +사용한다(기본적으로 `/var/lib/kubelet/config.yaml` 에 저장됨). |
| 308 | +{{< /note >}} |
| 309 | + |
| 310 | +CRI-O 및 containerd와 같은 다른 컨테이너 런타임에 대한 cgroup 드라이버의 |
| 311 | +자동 감지에 대한 작업이 진행 중이다. |
| 312 | + |
| 313 | + |
| 314 | +## 문제 해결 |
| 315 | + |
| 316 | +kubeadm에 문제가 있는 경우, [문제 해결 문서](/docs/setup/production-environment/tools/kubeadm/troubleshooting-kubeadm/)를 참고한다. |
| 317 | + |
| 318 | +## {{% heading "whatsnext" %}} |
| 319 | + |
| 320 | + |
| 321 | +* [kubeadm을 사용하여 클러스터 생성](/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/) |
0 commit comments