- PVSM.RU - https://www.pvsm.ru -
Хочу рассказать об интересном эксперименте, суть которого заключалась в развертывании и настройке Kubernetes на двух старых ноутбуках — один из них, кроме того, был с процессором на архитектуре i386. В качестве теоретической основы использовалось руководство Kubernetes The Hard Way, которое по ходу дела пришлось немного доработать, а в качестве системы на хостах — Gentoo (да, вам не показалось). Давайте погрузимся в этот увлекательный хардкор!

Наверное, многие слышали про полезный и по-своему легендарный репозиторий Келси Хайтауэра [1] — Kubernetes The Hard Way [2], инструкцию по развертыванию кластера K8s без готовых скриптов и утилит. В ней объясняется, как вручную запустить Kubernetes на Google Cloud Platform (GCP). Но даже сам автор утверждает, что стоимость такого кластера будет больше, чем 300 USD, которые даются в подарок за регистрацию на сервисе.
А что, если у вас есть один или несколько старых ноутбуков, которые пылятся на полке, и вы хотите поднять-таки Kubernetes своими руками и бесплатно?
Попробуем!
Важно: эту статью стоит воспринимать лишь как дополнение к оригинальному руководству Келси Хайтауэра, так как практически всё, что им описывается, применимо не только к GCP, но и к любому другому железу или виртуальным машинам, хотя и с некоторыми оговорками.
Для экспериментов у меня было два ноутбука на базе Gentoo Linux:
Dell G3 3590 на базе Intel Core i5-9300H (архитектура AMD64) (далее — просто dell);
HP Compaq 6720s на базе Intel Core2 Duo (архитектура i686) (далее — hpcom).
Они стали узлами кластера. Операционная система ставилась по официальной документации для amd64 [3] и x32 [4]. Но ядро собиралось с несколькими дополнительными настройками для IPSet [5] и Docker [6]. Для kube-proxy были включены параметры ядра NETFILTER_XT_MATCH_COMMENT и NETFILTER_XT_MATCH_STATISTIC. Также в процессе установки я столкнулся с парой трудностей, решить которые помог форум сообщества Gentoo. На всякий случай оставлю ссылки: черный экран сразу после GRUB [7] и ошибка с non-PAE kernel [8].
Что еще:
самый обычный роутер от провайдера;
основной ноутбук, с которого удаленно проводились все работы;
сильное желание повозиться с Kubernetes.
Выше я отметил, что внес лишь небольшие правки в оригинальное руководство по Kubernetes. Поэтому еще раз подчеркну, что в статье описываю только эти правки, указывая места, где нужно отступить от исходных инструкций. В остальных случаях даю ссылки на оригинальные разделы руководства.
В этом разделе [9] ничего не делаем, поэтому его можно со спокойной душой пропустить.
Здесь никаких изменений: делаем так, как написано [10].
Эту страницу [11] официального руководства можно пропустить, а вместо нее для упрощения дальнейшей работы записать локальные IP-адреса будущих узлов кластера (у меня получилось так: hpcom — 192.168.1.71, dell — 192.168.1.253).
Для удобства запишем эти адреса в файлик node_list.txt:
cat <<EOF | tee node_list.txt
dell 192.168.1.253 # Поменять на свои адреса и имена
hpcom 192.168.1.71
EOF
Для имитации Load Balancer’а на рабочей машине можно установить и развернуть NGINX. Затем добавить в конце конфигурационного файла nginx.conf строку include passthrough.conf (на Linux стандартная директория для конфигов NGINX — /etc/nginx/, а на macOS при установке через brew — /opt/homebrew/etc/).
Далее рядом создаем файл passthrough.conf. Сделать это можно такой командой (не забудьте поменять путь до NGINX-директории и путь до файла с хостами на ваши):
cat <<EOF | tee /opt/homebrew/etc/nginx/passthrough.conf
stream {
upstream kube {
$(cat node_list.txt | cut -d" " -f2 | xargs -I{} echo "$(printf '%8s')server {}:6443;")
}
server {
listen 443;
proxy_pass kube;
proxy_next_upstream on;
}
}
EOF
Это поможет нам создать простейшую имитацию High-Availability-кластера (HA). Для обучения большего и не нужно.
В этом разделе [12] выполняем все в точности до пункта The Kubelet Client Certificates. Теперь нам пригодятся записанные ранее IP-адреса узлов будущего кластера:
for instance in $(cat node_list.txt | cut -d" " -f1); do
cat > ${instance}-csr.json <<EOF
{
"CN": "system:node:${instance}",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "system:nodes",
"OU": "Kubernetes The Hard Way",
"ST": "Oregon"
}
]
}
EOF
INTERNAL_IP=$(cat node_list.txt | grep $instance | cut -d" " -f2)
cfssl gencert
-ca=ca.pem
-ca-key=ca-key.pem
-config=ca-config.json
-hostname=${instance},${INTERNAL_IP},127.0.0.1
-profile=kubernetes
${instance}-csr.json | cfssljson -bare ${instance}
done
Далее идем по исходной инструкции вплоть до пункта The Kubernetes API Server Certificate. Здесь меняем вводимые строки на такие:
{
KUBERNETES_HOSTNAMES=kubernetes,kubernetes.default,kubernetes.default.svc,kubernetes.default.svc.cluster,kubernetes.svc.cluster.local
cat > kubernetes-csr.json <<EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "Kubernetes",
"OU": "Kubernetes The Hard Way",
"ST": "Oregon"
}
]
}
EOF
cfssl gencert
-ca=ca.pem
-ca-key=ca-key.pem
-config=ca-config.json
-hostname=$(cut -d" " -f2 node_list.txt| tr 'n' ',')127.0.0.1,${KUBERNETES_HOSTNAMES}
-profile=kubernetes
kubernetes-csr.json | cfssljson -bare kubernetes
}
В следующем разделе, The Service Account Key Pair, выполняем все по инструкции, а в Distribute the Client and Server Certificates просто разносим все нужное по узлам с помощью scp. Чтобы это заработало, на рабочей машине создаем файл ~/.ssh/config с помощью команды:
cat node_list.txt | xargs -n2 bash -c 'echo -e "Host $0ntHostname $1ntUser <Ваш пользователь на узлах>"' | tee ~/.ssh/config
Копируем файлы на узлы:
{
for instance in $(cut -d" " -f1 node_list.txt); do
scp node_list.txt ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem service-account-key.pem service-account.pem ca.pem ${instance}-key.pem ${instance}.pem node_list.txt # Также переносим файл с IP-адресами на все узлы для дальнейшей работы.
${instance}:~/
done
}
В моем случае оба ноутбука будут выступать в качестве master’а и рабочего узла одновременно, поэтому я скопировал на них не только сертификаты для control plane, но и для рабочих узлов.
Здесь [13] пропускаем пункт про Kubernetes Public IP Address, а в The kubelet Kubernetes Configuration File вместо исходной команды выполняем:
for instance in $(cat node_list.txt | cut -d" " -f1); do
kubectl config set-cluster kubernetes-the-hard-way
--certificate-authority=ca.pem
--embed-certs=true
--server=https://127.0.0.1:443
--kubeconfig=${instance}.kubeconfig
kubectl config set-credentials system:node:${instance}
--client-certificate=${instance}.pem
--client-key=${instance}-key.pem
--embed-certs=true
--kubeconfig=${instance}.kubeconfig
kubectl config set-context default
--cluster=kubernetes-the-hard-way
--user=system:node:${instance}
--kubeconfig=${instance}.kubeconfig
kubectl config use-context default --kubeconfig=${instance}.kubeconfig
done
И аналогично для The kube-proxy Kubernetes Configuration File:
kubectl config set-cluster kubernetes-the-hard-way
--certificate-authority=ca.pem
--embed-certs=true
--server=https://127.0.0.1:443
--kubeconfig=kube-proxy.kubeconfig
kubectl config set-credentials system:kube-proxy
--client-certificate=kube-proxy.pem
--client-key=kube-proxy-key.pem
--embed-certs=true
--kubeconfig=kube-proxy.kubeconfig
kubectl config set-context default
--cluster=kubernetes-the-hard-way
--user=system:kube-proxy
--kubeconfig=kube-proxy.kubeconfig
kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
Далее следуем инструкции до момента копирования файлов на узлы. Вместо этого делаем так:
{
for instance in $(cat node_list.txt | cut -d" " -f1); do
scp ${instance}.kubeconfig kube-proxy.kubeconfig admin.kubeconfig kube-controller-manager.kubeconfig kube-scheduler.kubeconfig ${instance}:~/
done
}
В этом разделе [14] выполняем всё по инструкции, за исключением копирования файлов по узлам. Копируем так:
{
for instance in $(cat node_list.txt | cut -d" " -f1); do
scp encryption-config.yaml ${instance}:~/
done
}
Вместо оригинальной инструкции [15] вначале заходим на узел (выполнять для каждого узла):
ssh hpcom
Устанавливаем следующие необходимые утилиты:
sudo emerge --sync && emerge --ask dev-vcs/git sys-devel/make net-misc/wget net-misc/curl dev-lang/go app-shells/bash-completion
Скачиваем и собираем etcd:
git clone https://github.com/etcd-io/etcd.git
cd etcd
git checkout v3.4.15
go mod vendor
./build
sudo mv bin/etcd* /usr/local/bin/
Конфигурируем собранный etcd. Устанавливаем сертификаты:
{
sudo mkdir -p /etc/etcd /var/lib/etcd
sudo chmod 700 /var/lib/etcd
sudo cp ca.pem kubernetes-key.pem kubernetes.pem /etc/etcd/
}
Получаем IP-адрес и имя узла:
INTERNAL_IP=$(grep $(hostname -s) node_list.txt | cut -d' ' -f2)
ETCD_NAME=$(hostname -s)
И формируем Unit для systemd:
cat <<EOF | sudo tee /etc/systemd/system/etcd.service
[Unit]
Description=etcd
Documentation=https://github.com/etcd-io/etcd
[Service]
Type=notify
Environment="ETCD_UNSUPPORTED_ARCH=386" # Только для архитектуры i386, для amd64 не нужно указывать.
ExecStart=/usr/local/bin/etcd \
--name ${ETCD_NAME} \
--cert-file=/etc/etcd/kubernetes.pem \
--key-file=/etc/etcd/kubernetes-key.pem \
--peer-cert-file=/etc/etcd/kubernetes.pem \
--peer-key-file=/etc/etcd/kubernetes-key.pem \
--trusted-ca-file=/etc/etcd/ca.pem \
--peer-trusted-ca-file=/etc/etcd/ca.pem \
--peer-client-cert-auth \
--client-cert-auth \
--initial-advertise-peer-urls https://${INTERNAL_IP}:2380 \
--listen-peer-urls https://${INTERNAL_IP}:2380 \
--listen-client-urls https://${INTERNAL_IP}:2379,https://127.0.0.1:2379 \
--advertise-client-urls https://${INTERNAL_IP}:2379 \
--initial-cluster-token etcd-cluster-0 \
--initial-cluster $(cat node_list.txt | sed 's# #=https://#g' | tr 'n' ',' | sed 's#,#:2380,#g' | sed 's#,$##g') \
--initial-cluster-state new \
--data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
Теперь возвращаемся к исходной инструкции и выполняем все, что идет после пункта Start the etcd Server включительно.
Вначале заходим на узел (выполнять для каждого узла):
ssh hpcom
Создаем каталог для конфигурации:
sudo mkdir -p /etc/kubernetes/config
Скачиваем исходники Kubernetes и собираем control plane:
git clone https://github.com/kubernetes/kubernetes.git
cd kubernetes && git checkout v1.21.0
make kube-scheduler kube-apiserver kube-controller-manager kubectl
cd _output/bin
chmod +x kube-apiserver kube-controller-manager kube-scheduler kubectl
sudo mv kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/local/bin/
Переносим сертификаты:
{
sudo mkdir -p /var/lib/kubernetes/
cd && sudo mv ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem
service-account-key.pem service-account.pem
encryption-config.yaml /var/lib/kubernetes/
}
Для имитирования HA ставим NGINX (перед этим создав файл для USE-флагов дополнительных модулей Gentoo):
cat <<EOF | sudo tee /etc/portage/package.use/nginx
www-servers/nginx NGINX_MODULES_HTTP: access gzip gzip_static gunzip proxy push_stream stub_status upstream_check upstream_hash upstream_ip_hash upstream_keepalive upstream_least_conn upstream_zone
www-servers/nginx NGINX_MODULES_STREAM: access geo limit_conn map return split_clients upstream_hash upstream_least_conn upstream_zone geoip realip ssl_preread geoip2 javascript
EOF
sudo emerge --ask www-servers/nginx
В nginx.conf в блок http добавляем проверку работы сервера:
server {
listen 127.0.0.1:80;
server_name localhost;
access_log /var/log/nginx/localhost.access_log main;
error_log /var/log/nginx/localhost.error_log info;
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
И также в конец файла дописываем строку с include по аналогии с Provisioning Compute Resources выше:
echo include passthrough.conf; | sudo tee -a /etc/nginx/nginx.conf
Затем, как на рабочей машине, создаем рядом файл passthrough.conf:
cat <<EOF | sudo tee /etc/nginx/passthrough.conf
stream {
upstream kube {
$(cat node_list.txt | cut -d" " -f2 | xargs -I{} echo "$(printf '%8s')server {}:6443;")
}
server {
listen 443;
proxy_pass kube;
proxy_next_upstream on;
}
}
EOF
Конфигурируем API-сервер. Получаем нужные IP-адреса:
INTERNAL_IP=$(grep $(hostname -s) node_list.txt | cut -d' ' -f2)
KUBERNETES_PUBLIC_ADDRESS=127.0.0.1
Создаем Unit для systemd:
cat <<EOF | sudo tee /etc/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-apiserver \
--advertise-address=${INTERNAL_IP} \
--allow-privileged=true \
--apiserver-count=$(cat node_list.txt | wc -l) \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/var/log/audit.log \
--authorization-mode=Node,RBAC \
--bind-address=0.0.0.0 \
--client-ca-file=/var/lib/kubernetes/ca.pem \
--enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
--etcd-cafile=/var/lib/kubernetes/ca.pem \
--etcd-certfile=/var/lib/kubernetes/kubernetes.pem \
--etcd-keyfile=/var/lib/kubernetes/kubernetes-key.pem \
--etcd-servers=$(cut -d' ' -f2 node_list.txt | sed 's#^#https://#g' | sed 's#$#:2379#g' | xargs | tr ' ' ',') \
--event-ttl=1h \
--encryption-provider-config=/var/lib/kubernetes/encryption-config.yaml \
--kubelet-certificate-authority=/var/lib/kubernetes/ca.pem \
--kubelet-client-certificate=/var/lib/kubernetes/kubernetes.pem \
--kubelet-client-key=/var/lib/kubernetes/kubernetes-key.pem \
--runtime-config='api/all=true' \
--service-account-key-file=/var/lib/kubernetes/service-account.pem \
--service-account-signing-key-file=/var/lib/kubernetes/service-account-key.pem \
--service-account-issuer=https://${KUBERNETES_PUBLIC_ADDRESS}:6443 \
--service-cluster-ip-range=10.32.0.0/24 \
--service-node-port-range=30000-32767 \
--tls-cert-file=/var/lib/kubernetes/kubernetes.pem \
--tls-private-key-file=/var/lib/kubernetes/kubernetes-key.pem \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
Далее выполняем всё из оригинальной инструкции [16] до пункта The Kubernetes Frontend Load Balancer. Устанавливать и настраивать balancer не требуется, хотя при желании можно развернуть MetalLB после окончательной настройки кластера. Блок Verification также можно пропустить, так как мы уже развернули NGINX.
Проверить работоспособность API-сервера можно так:
curl --cacert /var/lib/kubernetes/ca.pem https://127.0.0.1:443/healthz
Заходим на каждый узел и устанавливаем необходимые пакеты:
ssh hpcom
sudo emerge --ask net-misc/socat net-firewall/conntrack-tools net-firewall/ipset sys-fs/btrfs-progs
Создаем нужные каталоги, скачиваем и собираем нужные бинарники:
sudo mkdir -p
/etc/cni/net.d
/opt/cni/bin
/var/lib/kubelet
/var/lib/kube-proxy
/var/lib/kubernetes
/var/run/kubernetes
crictl для i386:
wget -q --show-progress --https-only --timestamping https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.21.0/crictl-v1.21.0-linux-386.tar.gz
tar -xvf crictl-v1.21.0-linux-386.tar.gz && sudo mv crictl /usr/local/bin/
И для amd64:
https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.21.0/crictl-v1.21.0-linux-amd64.tar.gz
tar -xvf crictl-v1.21.0-linux-amd64.tar.gz && sudo mv crictl /usr/local/bin/
runc:
cd && git clone git@github.com:opencontainers/runc.git && cd runc && git checkout v1.0.0-rc93
make
sudo make install
CNI plugins:
cd && git clone git@github.com:containernetworking/plugins.git && cd plugins && git checkout v0.9.1
./build_linux.sh
sudo mv bin/* /opt/cni/bin/
containerd requirements для i386:
cd && wget -c https://github.com/google/protobuf/releases/download/v3.11.4/protoc-3.11.4-linux-x86_32.zip
sudo unzip protoc-3.11.4-linux-x86_32.zip -d /usr/local
И для amd64:
cd && wget -c
https://github.com/google/protobuf/releases/download/v3.11.4/protoc-3.11.4-linux-x86_64.zip
sudo unzip protoc-3.11.4-linux-x86_64.zip -d /usr/local
containerd:
cd && git clone git@github.com:containerd/containerd.git && cd containerd
git clone git@github.com:containerd/containerd.git && cd containerd/
make
sudo make install
K8s:
cd ~/kubernetes && git checkout v1.21.0
make kubelet kube-proxy
cd _output/bin
chmod +x kubelet kube-proxy
sudo mv kubelet kube-proxy /usr/local/bin/
Конфигурируем CNI-плагин:
POD_CIDR=10.200.$(grep -n $(hostname -s) node_list.txt | cut -d':' -f1).0/24
cat <<EOF | sudo tee /etc/cni/net.d/10-bridge.conf
{
"cniVersion": "0.4.0",
"name": "bridge",
"type": "bridge",
"bridge": "cnio0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"ranges": [
[{"subnet": "${POD_CIDR}"}]
],
"routes": [{"dst": "0.0.0.0/0"}]
}
}
EOF
cat <<EOF | sudo tee /etc/cni/net.d/99-loopback.conf
{
"cniVersion": "0.4.0",
"name": "lo",
"type": "loopback"
}
EOF
Конфигурируем containerd (используется другая версия конфига, в отличие от оригинального репозитория):
sudo mkdir -p /etc/containerd/
cat << EOF | sudo tee /etc/containerd/config.toml
version = 2
[plugins."io.containerd.grpc.v1.cri"]
sandbox_image = "docker.io/alexeymakhonin/pause:i386" # k8s.gcr.io/pause:3.7 для amd64
[plugins."io.containerd.grpc.v1.cri".containerd]
snapshotter = "overlayfs"
[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime]
runtime_type = "io.containerd.runtime.v1.linux"
runtime_engine = "/usr/local/sbin/runc"
runtime_root = ""
EOF
Контейнер pause (он же sandbox_image в конфиге containerd) от K8s не собирается для i386-архитектуры. Поэтому его можно собрать самостоятельно или воспользоваться готовым образом из моего Docker Hub’а: docker.io/alexeymakhonin/pause:i386 [17].
Если вы решили пойти первым путем, на узле с i386-архитектурой нужно собрать бинарник:
cd ~/kubernetes/build/pause && mkdir bin
gcc -Os -Wall -Werror -static -DVERSION=v3.6-bbc2dbb9801 -o bin/pause-linux-i386 linux/pause.c
Полученный бинарник и всю директорию следует скопировать на рабочий ноутбук с Docker Buildx [18], на котором будет собираться образ:
scp -r hpcom:~/kubernetes/build/pause ./ && cd pause
docker buildx build --pull --output=type=docker --platform linux/i386 -t docker.io/<DockerHub username>/pause:i386 --build-arg BASE=scratch --build-arg ARCH=i386 .
docker push docker.io/<DockerHub username>/pause:i386
Затем в конфигурационном файле containerd нужно поменять sandbox_image на собранный образ.
Теперь создаем Unit containerd для systemd:
cat <<EOF | sudo tee /etc/systemd/system/containerd.service
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target
[Service]
ExecStartPre=/sbin/modprobe overlay
ExecStart=/usr/local/bin/containerd
Restart=always
RestartSec=5
Delegate=yes
KillMode=process
OOMScoreAdjust=-999
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
[Install]
WantedBy=multi-user.target
EOF
Сконфигурировать kubelet и kube-proxy можно по оригинальной инструкции [19]. Однако стоит помнить, что ca.pem уже скопирован в /var/lib/kubernetes, поэтому команда mv упадет с ошибкой.
Проверить работоспособность узла можно так:
kubectl get node --kubeconfig ~/admin.kubeconfig
Из этого раздела [20] нас интересует только самое начало — пункт The Admin Kubernetes Configuration File. Выполняем его:
{
KUBERNETES_PUBLIC_ADDRESS=127.0.0.1
kubectl config set-cluster kubernetes-the-hard-way
--certificate-authority=ca.pem
--embed-certs=true
--server=https://${KUBERNETES_PUBLIC_ADDRESS}:443
kubectl config set-credentials admin
--client-certificate=admin.pem
--client-key=admin-key.pem
kubectl config set-context kubernetes-the-hard-way
--cluster=kubernetes-the-hard-way
--user=admin
kubectl config use-context kubernetes-the-hard-way
}
Эти инструкции [21] можно пропустить.
Здесь инструкции [22] придется разделить на две части. Для машины с архитектурой amd64 выполняем всё, как в оригинале, а вот для i386 придется пойти другим путем. Обусловлено это тем, что официального образа coredns для i386 не существует, поэтому его придется собирать самим (или взять уже собранный мной [23]). Чтобы собрать образ самостоятельно, на машине с Docker Buildx [18] выполняем команды:
git clone git@github.com:coredns/coredns.git && cd coredns && git checkout v1.8.3
make CGO_ENABLED=0 GOOS=linux GOARCH=386
docker buildx build --pull --output=type=docker --platform linux/i386 -t docker.io/<DockerHub username>/coredns:i386 .
docker push docker.io/<DockerHub username>/coredns:i386
Затем берем конфиг с заменой образа на наш и деплоим его:
curl -L https://storage.googleapis.com/kubernetes-the-hard-way/coredns-1.8.yaml --silent -o - | sed 's#image: coredns/coredns:1.8.3#image: docker.io/<DockerHub username>/coredns:i386#g' | kubectl apply -f -
Теперь остается только наложить патч на созданный ресурс, заменив значение аннотации на i386 или amd64 в зависимости от того, на какой узел вы хотите назначить coredns по архитектуре:
cat <<EOF | yq -ojson | tee patch.json
spec:
template:
spec:
nodeSelector:
kubernetes.io/arch: "386"
EOF
kubectl patch -n kube-system deployments.apps coredns --patch-file patch.json
Теперь можно проверить, что все работает, выполнив команды из оригинальной инструкции.
На этом этапе может возникнуть ошибка: Pod’ы будут зависать в состоянии ContainerCreating с ошибкой:
cgroups: cgroup mountpoint does not exist: unknown.
Если это произошло, починить можно так:
sudo mkdir /sys/fs/cgroup/systemd
sudo mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd
Делаем всё по инструкции [24], за исключением двух пунктов.
Команда проверки шифрования:
ssh hpcom
sudo ETCDCTL_API=3 etcdctl get
--endpoints=https://127.0.0.1:2379
--cacert=/etc/etcd/ca.pem
--cert=/etc/etcd/kubernetes.pem
--key=/etc/etcd/kubernetes-key.pem
/registry/secrets/default/kubernetes-the-hard-way | hexdump -C
Для NODE_PORT-сервиса:
curl -I http://$(grep hpcom node_list.txt | cut -d' ' -f2):${NODE_PORT}
На этом этапе [25] можно просто снести систему :)
Мы рассмотрели, как можно с интересом провести время и не дать пропасть старому железу, которое, например, давно отложено в кладовку, а выбросить руки не поднимаются. Также мы научились разворачивать Kubernetes на физическом оборудовании, используя готовые инструкции из Kubernetes The Hard Way с небольшими доработками.
Особенно интересным и полезным может быть опыт самостоятельной сборки недостающих образов для архитектуры i386: хотя она уже давно выходит из обращения, иногда все-таки встречается.
Надеюсь, статья поможет тем, кто хочет поглубже влезть в Kubernetes и его настройку.
Читайте также в нашем блоге:
Автор: Махонин Алексей
Источник [29]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/gentoo/379154
Ссылки в тексте:
[1] Келси Хайтауэра: https://github.com/kelseyhightower
[2] Kubernetes The Hard Way: https://github.com/kelseyhightower/kubernetes-the-hard-way
[3] amd64: https://wiki.gentoo.org/wiki/Handbook:AMD64
[4] x32: https://wiki.gentoo.org/wiki/Handbook:X86/Full/Installation
[5] IPSet: https://wiki.gentoo.org/wiki/IPSet
[6] Docker: https://wiki.gentoo.org/wiki/Docker
[7] черный экран сразу после GRUB: https://forums.gentoo.org/viewtopic-t-1083076-start-0.html
[8] ошибка с non-PAE kernel: https://forums.gentoo.org/viewtopic-t-1051792-start-0.html
[9] В этом разделе: https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/01-prerequisites.md
[10] как написано: https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/02-client-tools.md
[11] Эту страницу: https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/03-compute-resources.md
[12] В этом разделе: https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/04-certificate-authority.md
[13] Здесь: https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/05-kubernetes-configuration-files.md
[14] В этом разделе: https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/06-data-encryption-keys.md
[15] оригинальной инструкции: https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/07-bootstrapping-etcd.md
[16] из оригинальной инструкции: https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/08-bootstrapping-kubernetes-controllers.md
[17] docker.io/alexeymakhonin/pause:i386: http://docker.io/alexeymakhonin/pause:i386
[18] Docker Buildx: https://docs.docker.com/buildx/working-with-buildx/
[19] по оригинальной инструкции: https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/09-bootstrapping-kubernetes-workers.md
[20] Из этого раздела: https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/10-configuring-kubectl.md
[21] Эти инструкции: https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/11-pod-network-routes.md
[22] инструкции: https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/12-dns-addon.md
[23] собранный мной: http://docker.io/alexeymakhonin/coredns:i386
[24] по инструкции: https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/13-smoke-test.md
[25] На этом этапе: https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/14-cleanup.md
[26] «Kubernetes в миниатюре для локального запуска: k0s, MicroK8s, kind, k3s и Minikube»: https://habr.com/ru/company/flant/blog/572188/
[27] «Внутреннее устройство Kubernetes-кластера простым языком»: https://habr.com/ru/company/flant/blog/583660/
[28] «Kubernetes — это как океанариум»: https://habr.com/ru/company/flant/blog/544306/
[29] Источник: https://habr.com/ru/post/685616/?utm_source=habrahabr&utm_medium=rss&utm_campaign=685616
Нажмите здесь для печати.