Kubernetes mit CRI-O auf Arch Linux ARM
Auch wenn Docker stand heute die vermutlich am weitesten verbreitete Container-Lösung darstellt, gibt es doch einen regen Wettbewerb.
Besonders seit Kubernetes in Version 1.5 das Container-Runtime-Interface (CRI) eingeführt hat, mit dem sich die tatsächliche Container-Implementierung austauschen lässt.
Das CRI-O Projekt stellt einen Adapter zwischen der durch die OCI (Open Container Initiative) spezifizierten Schnittstellen für Container-Runtimes und dem durch Kubernetes mit CRI definierten Integrationspunkten dar.
Standardmäßig verwendet CRI-O die OCI konforme Containerimplementierung runc
.
Andere OCI kompatible Laufzeitumgebungen wie rkt
oder Intel Clear Container lassen sich damit ebenfalls einsetzen.
In einem typischen Docker basierten Setup sähe die Interaktion so aus:
-
Der
kubelet
Prozess verwaltet die Container der Node, nutzt dabei die CRI Schnittstelle zur Kommunikation -
mit dem
dockershim
, einer CRI-zu-Docker API Bridge, die ihrerseits -
mit dem eigentlichen
docker
-Daemon kommuniziert, der dann -
mit dem
containerd
-Daemon kommuniziert und darüber -
runc
aufruft, um konkrete Container zu managen
Mit CRI-O sieht die Interaktion so aus:
-
Der
kubelet
Prozess verwaltet die Container der Node, nutzt dabei die CRI Schnittstelle zur Kommunikation -
mit dem
CRI-O
-Daemon, der dann eine OCI kompatible Container-Laufzeitumgebung aufruft, im Default ist das -
die
runc
, die auch Docker verwendet
Der Stack bei CRI-O ist also deutlich geringer, ist jedoch als auf Kubernetes fokussierter Stack auch kein vollständiger Ersatz für die vielen verschiedenen Anwendungsfälle von Docker.
Im folgenden geht es um das konkrete Setup von CRI-O mit Kubernetes unter Arch Linux ARM.
Benötigt werden die folgenden Pakete:
-
runc zur Ausführung von Containern
-
CRI-O als Daemon zur Verwaltung der Container
-
crictl als CRI-O Kommandozeilenwerkzeug für Tests und Analyse (optional)
-
CNI und CNI-Plugins zur Implementierung von Container Netzwerken
runc für ARM
Als erstes wird runc
bereitgestellt.
Über dieses Programm können Container gestartet und gestoppt werden, runc übernimmt dabei die direkte Kommunikation mit dem Linux Kernel.
Der Build des Arch Linux ARM Pakets wird durch eine passende PKGBUILD Datei beschrieben.
# Maintainer: Thomas Kruse <[email protected]>
# Contributor: Sébastien "Seblu" Luttringer
pkgname=runc
pkgver=1.0.0rc5+19+g69663f0b
pkgrel=1
pkgdesc='CLI tool for managing OCI compliant containers'
arch=(x86_64 aarch64)
url='https://runc.io/'
license=(Apache)
depends=(glibc libseccomp)
makedepends=(git go go-md2man)
_commit=v1.0.0-rc5 # master
source=(git+https://github.com/opencontainers/runc.git#commit=$_commit)
md5sums=('SKIP')
pkgver() {
cd runc
git describe | sed 's/^v//;s/-//;s/-/+/g'
}
prepare() {
mkdir -p src/github.com/opencontainers
cp -r runc src/github.com/opencontainers/
}
build() {
cd src/github.com/opencontainers/runc
GOPATH="$srcdir" BUILDTAGS='seccomp' make runc man
}
package() {
cd src/github.com/opencontainers/runc
install -Dm755 runc "$pkgdir/usr/bin/runc"
install -Dm644 contrib/completions/bash/runc \
"$pkgdir/usr/share/bash-completion/completions/runc"
install -d "$pkgdir/usr/share/man/man8"
install -m644 man/man8/*.8 "$pkgdir/usr/share/man/man8"
}
Die eigentliche Paketierung erfolgt dann durch makepkg -s
.
$ makepkg -s
==> Making package: runc 1.0.0rc5-1
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
==> Retrieving sources...
-> Updating runc git repo...
Fetching origin
==> Validating source files with md5sums...
runc ... Skipped
==> Extracting sources...
-> Creating working copy of runc git repo...
Cloning into 'runc'...
done.
Switched to a new branch 'makepkg'
==> Starting prepare()...
==> Starting pkgver()...
==> Removing existing $pkgdir/ directory...
==> Starting build()...
go build -buildmode=pie -ldflags "-X main.gitCommit="4fc53a81fb7c994640722ac585fa9ca548971871" -X main.version=1.0.0-rc5 " -tags "seccomp" -o runc .
man/md2man-all.sh
...
+ go-md2man -in runc.8.md -out ./man8/runc.8
==> Entering fakeroot environment...
==> Starting package()...
==> Tidying install...
-> Removing, diskussionen libtool files...
-> Purging unwanted files...
-> Removing static library files...
-> Stripping unneeded symbols from binaries and libraries...
-> Compressing man and info pages...
==> Checking for packaging issues...
==> WARNING: Package contains reference to $srcdir
usr/bin/runc
==> Creating package "runc"...
-> Generating .PKGINFO file...
-> Generating .BUILDINFO file...
-> Generating .MTREE file...
-> Compressing package...
==> Leaving fakeroot environment.
==> Finished making: runc 1.0.0rc5-1
Nun steht mit runc die grundlegende Infrastruktur bereit, um Container zu starten. Damit Kubernetes damit arbeiten kann, wird als nächstes CRI-O installiert.
CRI-O für ARM 64 (aarch64)
Um CRI-O für ARM 64 auf Arch Linux zu paketieren wird eine PKBUILD Datei benötigt. Darin ist der Build des Paketes beschreiben.
# Maintainer: Thomas Kruse <[email protected]>
# Contributor: Tony Lambiris <[email protected]>
pkgname=cri-o
pkgver=1.11
pkgrel=1
pkgdesc='Open Container Initiative-based implementation of Kubernetes Container Runtime Interface'
arch=(x86_64 aarch64)
url='https://github.com/kubernetes-incubator/cri-o'
license=(Apache)
makedepends=(go go-md2man ostree)
backup=('etc/crio/crio.conf')
source=("git+https://github.com/kubernetes-incubator/cri-o")
sha256sums=('SKIP')
prepare() {
cd "$srcdir/$pkgname"
git checkout "v$pkgver"
install -m755 -d "$srcdir/go/src/github.com/kubernetes-incubator"
cp -a "$srcdir/$pkgname" "$srcdir/go/src/github.com/kubernetes-incubator/cri-o"
}
build() {
cd "$srcdir/go/src/github.com/kubernetes-incubator/cri-o"
export GOPATH="$srcdir/go"
make -j1 binaries docs
./bin/crio --selinux=true \
--storage-driver=overlay \
--conmon /usr/libexec/crio/conmon \
--cni-plugin-dir /usr/libexec/cni \
--default-mounts /run/secrets \
--cgroup-manager=systemd config > crio.conf
}
package() {
cd "$srcdir/go/src/github.com/kubernetes-incubator/cri-o"
make install install.systemd PREFIX="$pkgdir/usr"
# fix-up paths pointing to /usr/local to /usr
sed -i --follow-symlinks -re 's|/usr/local|/usr|g' $pkgdir/usr/lib/systemd/system/*.service
# install configs
install -dm755 $pkgdir/etc/crio/
install -Dm644 crio.conf $pkgdir/etc/crio/crio.conf
install -Dm644 seccomp.json $pkgdir/etc/crio/seccomp.json
}
Ausgeführt wird der Build anschließend mit makepkg -s
, wie im folgenden zu sehen:
$ makepkg -s
==> Making package: cri-o 1.11-1 (Sun Jul 22 17:57:22 2018)
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
==> Retrieving sources...
-> Updating cri-o git repo...
Fetching origin
==> Validating source files with sha256sums...
cri-o ... Skipped
==> Extracting sources...
-> Creating working copy of cri-o git repo...
Switched to a new branch 'makepkg'
==> Starting prepare()...
Branch 'release-1.11' set up to track remote branch 'release-1.11' from 'origin'.
Switched to a new branch 'release-1.11'
==> Starting build()...
touch "/home/tkruse/cri-o/src/go/.gopathok"
go build -i -ldflags '-s -w -X main.gitCommit="cd1f68f3d6183995526fb8935f5fc5feaa45245c" -X main.buildInfo=1532282245' -tags "btrfs_noversion exclude_graphdriver_btrfs seccomp containers_image_ostree_stub" -o bin/crio github.com/kubernetes-incubator/cri-o/cmd/crio
( cd conmon && /home/tkruse/cri-o/src/go/src/github.com/kubernetes-incubator/cri-o/bin/crio-config )
make -C conmon
make[1]: Entering directory '/home/tkruse/cri-o/src/go/src/github.com/kubernetes-incubator/cri-o/conmon'
cc -march=armv8-a -O2 -pipe -fstack-protector-strong -fno-plt -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -DVERSION=\"1.11.2-dev\" -DGIT_COMMIT=\""cd1f68f3d6183995526fb8935f5fc5feaa45245c"\" -D_FORTIFY_SOURCE=2 -c -o conmon.o conmon.c
cc -march=armv8-a -O2 -pipe -fstack-protector-strong -fno-plt -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -DVERSION=\"1.11.2-dev\" -DGIT_COMMIT=\""cd1f68f3d6183995526fb8935f5fc5feaa45245c"\" -D_FORTIFY_SOURCE=2 -c -o cmsg.o cmsg.c
cc -o ../bin/conmon config.h conmon.o cmsg.o -march=armv8-a -O2 -pipe -fstack-protector-strong -fno-plt -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -DVERSION=\"1.11.2-dev\" -DGIT_COMMIT=\""cd1f68f3d6183995526fb8935f5fc5feaa45245c"\" -lglib-2.0
make[1]: Leaving directory '/home/tkruse/cri-o/src/go/src/github.com/kubernetes-incubator/cri-o/conmon'
make -C pause
make[1]: Entering directory '/home/tkruse/cri-o/src/go/src/github.com/kubernetes-incubator/cri-o/pause'
cc -march=armv8-a -O2 -pipe -fstack-protector-strong -fno-plt -static -D_FORTIFY_SOURCE=2 -c -o pause.o pause.c
cc -o ../bin/pause pause.o -march=armv8-a -O2 -pipe -fstack-protector-strong -fno-plt -static
make[1]: Leaving directory '/home/tkruse/cri-o/src/go/src/github.com/kubernetes-incubator/cri-o/pause'
(go-md2man -in docs/crio.conf.5.md -out docs/crio.conf.5.tmp && touch docs/crio.conf.5.tmp && mv docs/crio.conf.5.tmp docs/crio.conf.5) || (/home/tkruse/cri-o/src/go/bin/go-md2man -in docs/crio.conf.5.md -out docs/crio.conf.5.tmp && touch docs/crio.conf.5.tmp && mv docs/crio.conf.5.tmp docs/crio.conf.5)
(go-md2man -in docs/crio.8.md -out docs/crio.8.tmp && touch docs/crio.8.tmp && mv docs/crio.8.tmp docs/crio.8) || (/home/tkruse/cri-o/src/go/bin/go-md2man -in docs/crio.8.md -out docs/crio.8.tmp && touch docs/crio.8.tmp && mv docs/crio.8.tmp docs/crio.8)
WARN[0000] default configuration file does not exist: /etc/crio/crio.conf
==> Entering fakeroot environment...
==> Starting package()...
go build -i -ldflags '-s -w -X main.gitCommit="cd1f68f3d6183995526fb8935f5fc5feaa45245c" -X main.buildInfo=1532282435' -tags "btrfs_noversion exclude_graphdriver_btrfs seccomp containers_image_ostree_stub" -o bin/crio github.com/kubernetes-incubator/cri-o/cmd/crio
make -C conmon
make[1]: Entering directory '/home/tkruse/cri-o/src/go/src/github.com/kubernetes-incubator/cri-o/conmon'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/tkruse/cri-o/src/go/src/github.com/kubernetes-incubator/cri-o/conmon'
make -C pause
make[1]: Entering directory '/home/tkruse/cri-o/src/go/src/github.com/kubernetes-incubator/cri-o/pause'
make[1]: '../bin/pause' is up to date.
make[1]: Leaving directory '/home/tkruse/cri-o/src/go/src/github.com/kubernetes-incubator/cri-o/pause'
install -D -m 755 bin/crio /home/tkruse/cri-o/pkg/cri-o/usr/bin/crio
install -D -m 755 bin/conmon /home/tkruse/cri-o/pkg/cri-o/usr/libexec/crio/conmon
install -D -m 755 bin/pause /home/tkruse/cri-o/pkg/cri-o/usr/libexec/crio/pause
install -d -m 755 /home/tkruse/cri-o/pkg/cri-o/usr/share/man/man5
install -d -m 755 /home/tkruse/cri-o/pkg/cri-o/usr/share/man/man8
install -m 644 docs/crio.conf.5 -t /home/tkruse/cri-o/pkg/cri-o/usr/share/man/man5
install -m 644 docs/crio.8 -t /home/tkruse/cri-o/pkg/cri-o/usr/share/man/man8
install -D -m 644 contrib/systemd/crio.service /home/tkruse/cri-o/pkg/cri-o/usr/lib/systemd/system/crio.service
ln -sf crio.service /home/tkruse/cri-o/pkg/cri-o/usr/lib/systemd/system/cri-o.service
install -D -m 644 contrib/systemd/crio-shutdown.service /home/tkruse/cri-o/pkg/cri-o/usr/lib/systemd/system/crio-shutdown.service
==> Tidying install...
-> Removing libtool files...
-> Purging unwanted files...
-> Removing static library files...
-> Stripping unneeded symbols from binaries and libraries...
-> Compressing man and info pages...
==> Checking for packaging issues...
==> WARNING: Package contains reference to $srcdir
usr/bin/crio
==> Creating package "cri-o"...
-> Generating .PKGINFO file...
-> Generating .BUILDINFO file...
-> Generating .MTREE file...
-> Compressing package...
==> Leaving fakeroot environment.
==> Finished making: cri-o 1.11-1 (Sun Jul 22 18:01:58 2018)
Das fertige Paket kann dann wie gewohnt, zum Beispiel mit pacman
, installiert werden.
$ sudo pacman -U cri-o-1.11-1-aarch64.pkg.tar.xz
loading packages...
resolving dependencies...
looking for conflicting packages...
Packages (1) cri-o-1.11-1
Total Installed Size: 30.48 MiB
:: Proceed with installation? [Y/n]
(1/1) checking keys in keyring [##############################################] 100%
(1/1) checking package integrity [##############################################] 100%
(1/1) loading package files [##############################################] 100%
(1/1) checking for file conflicts [##############################################] 100%
(1/1) checking available disk space [##############################################] 100%
:: Processing package changes...
(1/1) installing cri-o [##############################################] 100%
:: Running post-transaction hooks...
(1/2) Reloading system manager configuration...
(2/2) Arming ConditionNeedsUpdate...
Damit CRI-O funktioniert, müssen noch einige Konfigurationen vorgenommen werden. Dazu gehört zum einen die zu verwendende Container-Registry für Images, die ohne voll qualifizierten Namen referenziert werden. Zum anderen müssen die "default_mounts" deaktiviert sein, sonst gibt es später Probleme mit Kubernetes Secrets.
/etc/crio/crio.conf
registries = ['docker.io']
#default_mounts = [
# "/run/secrets",
#]
Auch muss eine Policy definiert werden, von wo Images akzeptiert werden, die nicht über eine vertrauenswürdige Signatur verfügen.
Diese Konfiguration erfolgt in der JSON Datei /etc/containers/policy.json
.
Das Docker Standardverhalten, von überall Images zu akzeptieren, kann dann wie folgt erzielt werden:
/etc/containers/policy.json
{
"default": [{"type": "insecureAcceptAnything"}]
}
Der Pfad der CNI Plugins muss korrekt gesetzt sein, damit die Netzwerkkonfiguration durch CRI-O vorgenommen werden kann.
/etc/crio/crio.conf
plugin_dir = "/opt/cni/bin"
Zur Verwaltung des CRI-O Dienstes durch systemd wird nun noch ein systemd-Unit-File erzeugt.
$ sudo sh -c 'echo "[Unit]
Description=OCI-based implementation of Kubernetes Container Runtime Interface
Documentation=https://github.com/kubernetes-incubator/cri-o
[Service]
ExecStart=/usr/bin/crio
Restart=always
RestartSec=15
[Install]
WantedBy=multi-user.target" > /etc/systemd/system/crio.service'
Wie üblich wird nun die systemd Konfiguration neu geladen und der CRI-O Dienst aktiviert. Er kann im Anschluß auch direkt gestartet werden.
$ sudo systemctl daemon-reload
$ sudo systemctl enable crio
$ sudo systemctl start crio
Wenn bis hierhin keine Fehler aufgetreten sind, steht CRI-O nun zur Verfügung.
Um zu verifizieren, dass CRI-O korrekt arbeitet, kann mit dem Kommandozeilenwerkzeug crictl
gearbeitet werden.
Auch das muss zunächst paketiert werden, das passende PKGBUILD sieht wie folgt aus:
# Maintainer: Thomas Kruse <[email protected]>
# Maintainer: ProFfeSsoRr <evvsoft at gmail dot com>
pkgname=crictl-bin
pkgver=1.11.1
pkgrel=1
pkgdesc="CLI tool for Kubelet Container Runtime Interface (CRI)"
arch=(x86_64 aarch64)
url="https://github.com/kubernetes-incubator/cri-tools/blob/master/docs/crictl.md"
license=('Apache')
source=("https://github.com/kubernetes-incubator/cri-tools/releases/download/v${pkgver}/crictl-v${pkgver}-linux-arm64.tar.gz"
"crictl.yaml")
sha256sums=('SKIP' 'SKIP')
package() {
cd "$srcdir"
install -Dm755 crictl "$pkgdir"/usr/bin/crictl
install -Dm644 crictl.yaml "$pkgdir"/etc/crictl.yaml
}
Die globale Konfiguration von crictl
erfolgt in der YAML Datei /etc/crictl.yaml
, dort werden z.B. die CRI-O Endpoints konfiguriert.
crictl
in /etc/crictl.yaml
runtime-endpoint: unix:///var/run/crio/crio.sock
image-endpoint: unix:///var/run/crio/crio.sock
timeout: 10
debug: false
Nach der Installation der erstellten Pakets kann mittels crictl
die CRI-O Version abgefragt werden.
$ sudo crictl --runtime-endpoint unix:///var/run/crio/crio.sock version
Version: 0.1.0
RuntimeName: cri-o
RuntimeVersion: 1.11.2-dev
RuntimeApiVersion: v1alpha1
Analog zu Docker können mittels crictl
auch Images gepullt werden, im Beispiel das Kubernetes Pause Image für ARM 64 bit.
$ sudo crictl pull k8s.gcr.io/pause-arm64:3.1
Image is up to date for k8s.gcr.io/pause-arm64@sha256:f365626a556e58189fc21d099fc64603db0f440bff07f77c740989515c544a39
Auffällig ist dabei, dass es keine Fortschrittsanzeige, wie bei Docker gibt. Das ist normal, über die CRI API werden die Fortschrittsinformationen nicht bereitgestellt. Im nicht-interaktiven Umfeld eines Kubernetes Clusters werden diese schlicht nicht benötigt, und Ziel von CRI ist schließlich eine minimale Schnittstelle.
Um Images zu pullen und Container zu starten ist nun alles vorhanden. Es fehlt jedoch noch eine Möglichkeit, für die Container ein isoliertes Netzwerk bereitzustellen. Dafür gibt es CNI, das Container Network Interface.
CNI Setup
CNI ist aus der rkt Runtime entstanden und mittlerweile ein Projekt der Cloud Native Computing Foundation. Durch CNI werden Netzwerkkonfigurationen für Container vorgenommen.
Die Paketierung von CNI und den CNI-Plugins erfolgt analog. Dazu können die folgenden PKGBUILD Konfigurationen verwendet werden.
# Maintainer: Thomas Kruse <[email protected]>
# Contributor: Tobias Martin <tm-x at gmx dot net>
pkgname=cni
pkgver=0.6.0
pkgrel=2
pkgdesc="Specification and libraries for writing plugins to configure network interfaces in Linux containers"
arch=('i686' 'x86_64' 'aarch64')
url="https://github.com/containernetworking/cni"
license=('Apache')
makedepends=('go')
depends=('glibc')
source=("https://github.com/containernetworking/${pkgname}/archive/v${pkgver}.tar.gz")
sha512sums=('3b5b35ed546f82a939b3090ac49d2f7ab0542a079d0f45b0dd9b45cf4849abb6c10fbcb810b7567a7a15d6b8144f5b3962bfca319a37342c5bc39f5fa58f0777')
build() {
cd "${srcdir}/${pkgname}-${pkgver}"
./build.sh
}
package() {
cd "${srcdir}/${pkgname}-${pkgver}"
mkdir -p "${pkgdir}/opt/${pkgname}/"
cp -dr --no-preserve=ownership bin "${pkgdir}/opt/${pkgname}/"
mkdir -p ${pkgdir}/usr/share/licenses/${pkgname}
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
}
Der Build erfolgt auch hier mit makepkg -s
.
# Maintainer: Thomas Kruse <[email protected]>
# Contributor: Roman Lisagor <rlisagor at gmail dot com>
pkgname=cni-plugins
pkgver=0.6.0
pkgrel=1
pkgdesc="Some standard networking plugins, maintained by the CNI team"
arch=('i686' 'x86_64' 'aarch64')
url="https://github.com/containernetworking/plugins"
license=('Apache')
makedepends=('go')
optdepends=('cni')
depends=('glibc')
source=("https://github.com/containernetworking/plugins/archive/v${pkgver}.tar.gz")
sha512sums=('4b3c1901154eb1af86dc35888fda7b7666ee88d2cf728fb09182df5385d32b747de34c5c01598e1f37ae1e3497dbf5af2bc6ad6f737e683ccfccf9c1860cf6dc')
build() {
cd "${srcdir}/plugins-${pkgver}"
./build.sh
}
package() {
cd "${srcdir}/plugins-${pkgver}"
mkdir -p "${pkgdir}/opt/cni/"
cp -dr --no-preserve=ownership bin "${pkgdir}/opt/cni/"
mkdir -p ${pkgdir}/usr/share/licenses/${pkgname}
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
}
Um Container-Networking zu ermöglichen muss im Kernel das IP-Forwarding aktiviert werden.
Am besten wird die Konfiguration dauerhaft vorgenommen, indem eine entsprechende sysctl
Konfiguration vorgenommen wird.
/etc/sysctl.d/30-ipforward.conf
net.ipv4.ip_forward=1
Damit ist eine grundlegende Container-Laufzeitumgebung vorbereitet. Als nächstes muss noch Kubernetes zur Verwendung von CRI-O konfiguriert werden.
kubelet Konfiguration für CRI-O
Eine Standardinstallation von kubelet als systemd-Dienst wird diesen mit einer Abhängigkeit auf den Docker Daemon konfigurieren.
Da nun CRI-O zum Einsatz kommt, muss die systemd-Unit angepasst werden und den crio.service
statt Docker deklarieren.
/usr/lib/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet Server
Documentation=https://kubernetes.io/docs/concepts/overview/components/#kubelet https://kubernetes.io/docs/reference/generated/kubelet
After=crio.service
Requires=crio.service
[Service]
WorkingDirectory=/var/lib/kubelet
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/kubelet
ExecStart=/usr/bin/kubelet \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBELET_KUBECONFIG \
$KUBELET_ADDRESS \
$KUBELET_PORT \
$KUBELET_HOSTNAME \
$KUBE_ALLOW_PRIV \
$KUBELET_ARGS
Restart=always
KillMode=process
RestartSec=60s
[Install]
WantedBy=multi-user.target
Die folgenden Einstellungen für kubelet werden in der /etc/kubernetes/kubelet
Datei vorgenommen:
-
Auswahl von CRI-O als Runtime für Container
-
Auswahl von systemd als cgroup Treiber, damit die Namespaces von CRI-O und kubelet zusammen passen
-
Pfad für statische Pods, die kubeadm erzeugt, um die Kubernetes Control-Plane zu booten
-
Angabe der - später - durch kubeadm erzeugten Datei
kubelet.conf
als weitere Konfigurationsdatei
/etc/kubernetes/kubelet
KUBELET_ARGS="--cluster-domain=cluster.local --cluster-dns=10.96.0.10 --pod-manifest-path=/etc/kubernetes/manifests --cgroup-driver=systemd --fail-swap-on=false --network-plugin=kubenet --container-runtime=remote --container-runtime-endpoint=unix:///var/run/crio/crio.sock"
KUBELET_KUBECONFIG="--kubeconfig=/etc/kubernetes/kubelet.conf"
KUBELET_HOSTNAME=""
Zusätzlich werden noch Parameter in der /etc/kubernetes/config
gesetzt:
Für den kube-proxy werden privilegierte Container benötigt, sodass diese erlaubt werden müssen.
Außerdem wird die Adresse des kube-apiserver erst einmal leer gelassen - die von kubeadm später erzeugte Datei wird die korrekte URL enthalten.
/etc/kubernetes/config
KUBE_ALLOW_PRIV="--allow-privileged=true"
KUBE_MASTER=""
Anschließend können die Konfigdateien von systemd neu eingelesen und der kubelet Dienst aktiviert werden.
Der Start des kubelet Dienstes erfolgt erst später, wenn durch kubeadm auch die kubelet.conf
Datei erzeugt wurde.
Bis dahin werden Startversuche fehlschlagen, da die Datei noch nicht existiert.
$ sudo systemctl daemon-reload
$ sudo systemctl enable kubelet.service
Cluster Setup mit CRI-O und kubeadm
Bei der Einrichtung eines Kubernetes Cluster mit CRI-O Containern und kubeadm muss diesem ebenfalls die Verwendung von CRI-O konfiguriert werden.
Dazu muss der Pfad zum CRI-Socket angegeben werden, dieser ist standardmäßig auf dockershim
konfiguriert, dass bei CRI-O nicht zum Einsatz kommt.
$ sudo kubeadm init --pod-network-cidr 10.244.0.0/24 --ignore-preflight-errors Swap --cri-socket=/var/run/crio/crio.sock
Sollte etwas schief gehen, ist zu beachten, dass bei einem kubeadm reset
auch hier der CRI-Socket zu spezifizieren ist, damit alle Container korrekt gelöscht werden.
$ sudo kubeadm reset --cri-socket=/var/run/crio/crio.sock
Während die Container durch kubelet gestartet werden, kann bereits mittels crictl
der Status beobachtet werden:
$ sudo crictl pods
POD ID CREATED STATE NAME NAMESPACE ATTEMPT
92944837d1bbb 4 seconds ago Ready kube-scheduler kube-system 0
39e8d6401df44 4 seconds ago Ready kube-controller kube-system 0
37b8cb3450a84 4 seconds ago Ready kube-apiserver kube-system 0
d753b24712a99 4 seconds ago Ready etcd kube-system 0
Im nächsten Beitrag geht es um die Einrichtung von Workernodes mit diesem Setup: Kubernetes CRI-O Worker.
Aktualisierte Pakete werden hier beschrieben: Kubernetes 1.13.
Zu den Themen Kubernetes, Docker und Cloud Architektur bieten wir sowohl Beratung, Entwicklungsunterstützung als auch passende Schulungen an:
Auch für Ihren individuellen Bedarf können wir Workshops und Schulungen anbieten. Sprechen Sie uns gerne an.