가끔 kubernetes 같은건 너무 무거워서 단일 호스트에 docker만 띄워서 운영하는 경우같은걸 고민 하게 됩니다. 하지만 그냥 docker만 가지고 사용하면 컨테이너가 죽었을때 관리해 줘야 하는 불편함과 같이 기능을 보다 더 필요로 하게 됩니다. 그래서 이 방법을 소개해 드립니다.
이건 standalone kubelet 이라고 불리는 master 없이 node만 관리해주는 kubelet을 이용해서 container를 관리하는 방법입니다. 이건 k8s 초기 부터 원래 존재했던 컨셉이나 많이 알려져 있지 않아서 모르시는 분들이 많아서 이글을 작성해 봤습니다.
이 방법을 이용하면 실제 master 없이 kubelet 만으로 서비스를 할 수 있습니다. 컨테이너 자동 재시작, port forwarding, resource limit 등 기본적인 kubelet에서 제공하는 다양한 방법으로 컨테이너들을 관리 할 수 있습니다.
물론 이 방법은 기존에도 많이 소개되었기 때문에 1.20에 docker deprecated를 기념해서 containerd 버전으로 작성해 봤습니다. 미리 1.23에 containerd 사용을 체감할겸해서 재미로 보시면 좋겠습니다.
- demo
-
docker 버전 참고
-
cri-o 버전은 참고
cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
sudo sysctl --system
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo apt-key --keyring /etc/apt/trusted.gpg.d/docker.gpg add -
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
sudo apt update && sudo apt install -y containerd.io
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add
cat << EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo mkdir -p /etc/cni/net.d
cat <<EOF | sudo tee /etc/cni/net.d/10-containerd-net.conflist
{
"cniVersion": "0.4.0",
"name": "containerd-net",
"plugins": [
{
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"promiscMode": true,
"ipam": {
"type": "host-local",
"ranges": [
[{
"subnet": "10.88.0.0/16"
}],
[{
"subnet": "2001:4860:4860::/64"
}]
],
"routes": [
{ "dst": "0.0.0.0/0" },
{ "dst": "::/0" }
]
}
},
{
"type": "portmap",
"capabilities": {"portMappings": true}
}
]
}
EOF
sudo mkdir -p /lib/systemd/system/kubelet.service.d
cat << "EOF" | sudo tee /lib/systemd/system/kubelet.service.d/10-standalone.conf
[Service]
ExecStart=
ExecStart=/usr/bin/kubelet --container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock --pod-manifest-path=/etc/kubernetes/manifests
EOF
sudo apt update -y && sudo apt install -y kubelet kubernetes-cni
VERSION="v1.19.0"
wget https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-$VERSION-linux-amd64.tar.gz
sudo tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin
rm -f crictl-$VERSION-linux-amd64.tar.gz
cat << "EOF" | sudo tee /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF
cat << EOF | sudo tee /etc/kubernetes/manifests/web.yaml
apiVersion: v1
kind: Pod
metadata:
name: static-web
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
hostPort: 8080
protocol: TCP
EOF
PODID=$(sudo crictl pods | awk /static-web/{'print $1'})
PODIP=$(sudo crictl inspectp -o go-template --template '{{.status.network.ip}}' ${PODID})
curl $PODIP:80
ROUTABLE_NODE_IP=$(ip -o r g 1 | awk '{print $7}')
curl $ROUTABLE_NODE_IP:8080