독립형 kubelet
독립형 kubelet (Standalone kubelet) 튜토리얼
이 튜토리얼에서는 독립형(standalone) kubelet 인스턴스를 실행하는 방법을 보여줘요.
독립형 kubelet을 실행하게 된 동기는 다양할 수 있어요. 이 튜토리얼은 쿠버네티스에 대한 경험이 많지 않더라도 쿠버네티스를 소개하는 것을 목표로 해요. 이 튜토리얼을 따라가면 노드 설정, 기본(정적) 파드, 쿠버네티스가 컨테이너를 관리하는 방법에 대해 배울 수 있습니다.
이 튜토리얼을 따라 한 뒤에는 파드와 노드, 그리고 다른 유형의 오브젝트를 관리하는 컨트롤 플레인이 있는 클러스터를 사용해볼 수 있어요. 예를 들어 Hello, minikube가 그렇습니다.
또한 kubelet을 독립형 모드로 실행해 고가용성이고 탄력적으로 배포된 클러스터의 컨트롤 플레인을 실행하는 것 같은 프로덕션 사용 사례에 맞출 수도 있어요. 이 튜토리얼은 탄력적인 컨트롤 플레인을 실행하는 데 필요한 세부 사항은 다루지 않습니다.
출처: 문서
본문
목표 (Objectives)
- Linux 시스템에
cri-o와kubelet을 설치하고systemd서비스로 실행한다. - Pod의 IP 주소에서 TCP 포트 80의 요청을 수신하는
nginx를 실행하는 파드를 시작한다. - 솔루션의 서로 다른 구성 요소들이 서로 어떻게 상호작용하는지 배운다.
이 튜토리얼에 사용되는 kubelet 구성은 설계상 안전하지 않으며, 프로덕션 환경에서 사용해서는 안 됩니다.
시작하기 전에
systemd와iptables(또는iptables에뮬레이션을 가진 nftables)를 사용하는 Linux 시스템에 대한 관리자(root) 접근.- 튜토리얼에 필요한 구성 요소를 다운로드할 인터넷 접근. 예를 들어:
- 쿠버네티스 CRI를 구현하는 컨테이너 런타임.
- 네트워크 플러그인(흔히 CNI 플러그인으로 알려짐).
- 필요한 CLI 도구:
curl,tar,jq.
시스템 준비
Swap 구성
기본적으로 kubelet은 노드에서 swap 메모리가 감지되면 시작에 실패해요. 즉 swap을 비활성화하거나 kubelet이 허용해야 합니다.
kubelet이 swap을 허용하도록 구성해도 kubelet은 여전히 파드(및 그 파드의 컨테이너)가 swap 공간을 사용하지 않도록 구성합니다. 파드가 실제로 사용 가능한 swap을 어떻게 사용할 수 있는지 알아보려면 Linux 노드의 swap 메모리 관리에 대해 더 읽을 수 있습니다.
swap 메모리가 활성화되어 있다면 비활성화하거나 kubelet 구성 파일에 failSwapOn: false를 추가해요.
swap이 활성화되었는지 확인하려면:
sudo swapon --show
명령의 출력이 없으면 swap 메모리가 이미 비활성화된 것입니다.
swap을 임시로 비활성화하려면:
sudo swapoff -a
재부팅 후에도 지속되게 하려면:
시스템에서 어떻게 구성했는지에 따라 /etc/fstab 또는 systemd.swap에서 swap이 비활성화되어 있는지 확인해요.
IPv4 패킷 포워딩 활성화
IPv4 패킷 포워딩이 활성화되었는지 확인하려면:
cat /proc/sys/net/ipv4/ip_forward
출력이 1이면 이미 활성화되어 있어요. 0이면 다음 단계를 따릅니다.
IPv4 패킷 포워딩을 활성화하려면 net.ipv4.ip_forward 파라미터를 1로 설정하는 구성 파일을 만들어요:
sudo tee /etc/sysctl.d/k8s.conf <<EOF
net.ipv4.ip_forward = 1
EOF
변경 사항을 시스템에 적용해요:
sudo sysctl --system
출력은 다음과 비슷합니다:
...
* Applying /etc/sysctl.d/k8s.conf ...
net.ipv4.ip_forward = 1
* Applying /etc/sysctl.conf ...
구성 요소 다운로드·설치·구성
컨테이너 런타임 설치
필요한 패키지의 최신 사용 가능 버전을 다운로드해요(권장).
이 튜토리얼은 CRI-O 컨테이너 런타임(외부 링크)을 설치할 것을 제안합니다.
Linux 배포판에 따라 CRI-O 컨테이너 런타임을 설치하는 여러 방법이 있습니다. CRI-O는 deb나 rpm 패키지를 권장하지만, 이 튜토리얼은 전체 과정을 간소화하고 배포판에 구애받지 않기 위해 CRI-O Packaging 프로젝트의 정적 바이너리 번들(static binary bundle) 스크립트를 사용합니다.
이 스크립트는 컨테이너 네트워킹용 cni-plugins, 컨테이너 실행용 crun과 runc 같은 추가 필수 소프트웨어를 설치·구성합니다.
스크립트는 시스템의 프로세서 아키텍처(amd64 또는 arm64)를 자동으로 감지해 최신 버전의 소프트웨어 패키지를 선택·설치합니다.
CRI-O 설정
releases 페이지(외부 링크)를 방문해요.
정적 바이너리 번들 스크립트를 다운로드해요:
curl https://raw.githubusercontent.com/cri-o/packaging/main/get > crio-install
설치기 스크립트를 실행해요:
sudo bash crio-install
crio 서비스를 활성화하고 시작해요:
sudo systemctl daemon-reload
sudo systemctl enable --now crio.service
빠른 테스트:
sudo systemctl is-active crio.service
출력은 다음과 비슷합니다:
active
상세 서비스 확인:
sudo journalctl -f -u crio.service
네트워크 플러그인 설치
cri-o 설치기는 cni-plugins 패키지를 설치·구성해요. 다음 명령을 실행해 설치를 확인할 수 있습니다:
/opt/cni/bin/bridge --version
출력은 다음과 비슷합니다:
CNI bridge plugin v1.5.1
CNI protocol versions supported: 0.1.0, 0.2.0, 0.3.0, 0.3.1, 0.4.0, 1.0.0
기본 구성을 확인하려면:
cat /etc/cni/net.d/11-crio-ipv4-bridge.conflist
출력은 다음과 비슷합니다:
{
"cniVersion": "1.0.0",
"name": "crio",
"plugins": [
{
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"hairpinMode": true,
"ipam": {
"type": "host-local",
"routes": [
{ "dst": "0.0.0.0/0" }
],
"ranges": [
[{ "subnet": "10.85.0.0/16" }]
]
}
}
]
}
기본 subnet 범위(10.85.0.0/16)가 활성 네트워크 중 어떤 것과도 겹치지 않는지 확인해요. 겹치면 파일을 편집해 그에 맞게 변경할 수 있습니다. 변경 후 서비스를 재시작하세요.
kubelet 다운로드 및 설정
kubelet의 최신 안정 릴리스를 다운로드해요.
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubelet"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubelet"
구성해요:
sudo mkdir -p /etc/kubernetes/manifests
sudo tee /etc/kubernetes/kubelet.yaml <<EOF
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authentication:
webhook:
enabled: false # Do NOT use in production clusters!
authorization:
mode: AlwaysAllow # Do NOT use in production clusters!
enableServer: false
logging:
format: text
address: 127.0.0.1 # Restrict access to localhost
readOnlyPort: 10255 # Do NOT use in production clusters!
staticPodPath: /etc/kubernetes/manifests
containerRuntimeEndpoint: unix:///var/run/crio/crio.sock
EOF
프로덕션 클러스터를 설정하는 것이 아니므로, kubelet의 API에 대한 인증 없는 질의에 일반 HTTP(readOnlyPort: 10255)를 사용하고 있어요.
_인증 웹훅_은 비활성화되고 _인가 모드_는 이 튜토리얼 목적상 AlwaysAllow로 설정됩니다. 환경에서 독립형 모드로 kubelet을 제대로 구성하려면 인가 모드와 웹훅 인증에 대해 더 배울 수 있어요.
쿠버네티스 구성 요소가 어떤 포트를 사용하는지 이해하려면 Ports and Protocols를 참고하세요.
설치해요:
chmod +x kubelet
sudo cp kubelet /usr/bin/
systemd 서비스 유닛 파일을 만들어요:
sudo tee /etc/systemd/system/kubelet.service <<EOF
[Unit]
Description=Kubelet
[Service]
ExecStart=/usr/bin/kubelet \
--config=/etc/kubernetes/kubelet.yaml
Restart=always
[Install]
WantedBy=multi-user.target
EOF
서비스 구성 파일에서 --kubeconfig 명령줄 인자를 의도적으로 생략했어요. 이 인자는 API 서버에 연결하는 방법을 지정하는 kubeconfig 파일 경로를 설정해 API 서버 모드를 가능하게 합니다. 생략하면 독립형 모드가 활성화됩니다.
kubelet 서비스를 활성화하고 시작해요:
sudo systemctl daemon-reload
sudo systemctl enable --now kubelet.service
빠른 테스트:
sudo systemctl is-active kubelet.service
출력은 다음과 비슷합니다:
active
상세 서비스 확인:
sudo journalctl -u kubelet.service
kubelet API의 /healthz 엔드포인트를 확인해요:
curl http://localhost:10255/healthz?verbose
출력은 다음과 비슷합니다:
[+]ping ok
[+]log ok
[+]syncloop ok
healthz check passed
kubelet API의 /pods 엔드포인트를 질의해요:
curl http://localhost:10255/pods | jq '.'
출력은 다음과 비슷합니다:
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {},
"items": null
}
kubelet에서 파드 실행하기
독립형 모드에서는 파드 매니페스트를 사용해 파드를 실행할 수 있어요. 매니페스트는 로컬 파일시스템에 있거나, 구성 소스에서 HTTP로 가져올 수 있습니다.
파드 매니페스트를 만들어요:
cat <<EOF > static-web.yaml
apiVersion: v1
kind: Pod
metadata:
name: static-web
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
protocol: TCP
EOF
static-web.yaml 매니페스트 파일을 /etc/kubernetes/manifests 디렉토리에 복사해요.
sudo cp static-web.yaml /etc/kubernetes/manifests/
kubelet과 파드에 대한 정보 알아보기
파드 네트워킹 플러그인은 각 파드에 대해 네트워크 브리지(cni0)와 veth 인터페이스 쌍을 만듭니다(쌍 중 하나는 새로 만들어진 파드 안에, 다른 하나는 호스트 레벨에 있습니다).
http://localhost:10255/pods에서 kubelet API 엔드포인트를 질의해요:
curl http://localhost:10255/pods | jq '.'
static-web 파드의 IP 주소를 얻으려면:
curl http://localhost:10255/pods | jq '.items[].status.podIP'
출력은 다음과 비슷합니다:
"10.85.0.4"
이 경우 http://<IP>:<Port>(포트 80이 기본)에서 nginx 서버 파드에 연결해요:
curl http://10.85.0.4
출력은 다음과 비슷합니다:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
더 많은 세부 사항을 볼 곳
이 튜토리얼을 동작시키는 데 문제가 있으면 모니터링과 문제 해결을 위해 다음 디렉토리를 살펴볼 수 있어요:
/var/lib/cni
/var/lib/containers
/var/lib/kubelet
/var/log/containers
/var/log/pods
정리하기
kubelet
sudo systemctl disable --now kubelet.service
sudo systemctl daemon-reload
sudo rm /etc/systemd/system/kubelet.service
sudo rm /usr/bin/kubelet
sudo rm -rf /etc/kubernetes
sudo rm -rf /var/lib/kubelet
sudo rm -rf /var/log/containers
sudo rm -rf /var/log/pods
Container Runtime
sudo systemctl disable --now crio.service
sudo systemctl daemon-reload
sudo rm -rf /usr/local/bin
sudo rm -rf /usr/local/lib
sudo rm -rf /usr/local/share
sudo rm -rf /usr/libexec/crio
sudo rm -rf /etc/crio
sudo rm -rf /etc/containers
Network Plugins
sudo rm -rf /opt/cni
sudo rm -rf /etc/cni
sudo rm -rf /var/lib/cni
결론
이 페이지에서는 독립형 모드로 kubelet을 배포하는 기본적인 측면을 다뤘어요. 이제 파드를 배포하고 추가 기능을 테스트할 준비가 되었습니다.
독립형 모드에서 kubelet은 컨트롤 플레인에서 파드 구성을 가져오는 것을 지원하지 않는다는 점에 유의하세요(컨트롤 플레인 연결이 없기 때문입니다).
또한 정적 파드의 컨테이너를 구성하기 위해 ConfigMap이나 Secret을 사용할 수 없습니다.
더 알아보기 (Learn more)
- 컨트롤 플레인 과 함께 쿠버네티스를 실행하는 방법을 배우려면 Hello, minikube를 따라가세요. minikube 도구는 자신의 컴퓨터에 연습 클러스터를 설정하는 데 도움을 줍니다.
- 네트워크 플러그인에 대해 더 알아보기.
- 컨테이너 런타임에 대해 더 알아보기.
- kubelet에 대해 더 알아보기.
- 정적 파드에 대해 더 알아보기.