Catatan perev. : Penulis artikel, Marshall Brekka, menempati posisi direktur desain sistem di Fair.com, yang menawarkan aplikasinya untuk penyewaan mobil. Di waktu luangnya, ia suka menggunakan pengalamannya yang luas untuk memecahkan masalah "rumah" yang tidak mungkin mengejutkan geek mana pun (oleh karena itu, pertanyaan "Mengapa?" - sehubungan dengan tindakan yang dijelaskan di bawah ini - dihilangkan secara apriori). Jadi, dalam terbitannya, Marshall membagikan hasil penyebaran Kubernet baru-baru ini di ... papan ARM.
Seperti banyak Geeks lainnya, selama bertahun-tahun saya telah mengumpulkan berbagai papan pengembangan seperti Raspberry Pi. Dan seperti banyak geek, mereka membersihkan debu di rak dengan pikiran bahwa suatu hari mereka akan berguna. Dan sekarang bagiku hari ini akhirnya tiba!
Selama liburan musim dingin, beberapa minggu di luar pekerjaan muncul, di mana ada cukup waktu untuk inventaris semua besi yang terakumulasi dan memutuskan apa yang harus dilakukan dengannya. Inilah yang saya miliki:
- Penutup RAID 5-drive dengan koneksi USB3;
- Raspberry Pi Model B (model OG);
- CubbieBoard 1;
- Pisang Pi M1;
- Netbook HP (2012?).
Dari 5 komponen besi yang terdaftar, saya menggunakan kecuali RAID dan netbook sebagai NAS sementara. Namun, karena kurangnya dukungan USB3 di netbook, RAID tidak menggunakan potensi kecepatan penuh.
Tujuan hidup
Karena bekerja dengan RAID tidak optimal saat menggunakan netbook, saya menetapkan tujuan berikut untuk mendapatkan konfigurasi terbaik:
- NAS dengan USB3 dan gigabit ethernet;
- Cara terbaik untuk mengelola perangkat lunak di perangkat Anda
- (bonus) kemampuan untuk melakukan streaming konten multimedia dari RAID ke Fire TV.
Karena tidak ada perangkat yang mendukung USB3 dan gigabit ethernet, sayangnya, saya harus melakukan pembelian tambahan. Pilihan jatuh pada
ROC-RK3328-CC . Dia memiliki semua spesifikasi yang diperlukan dan dukungan yang memadai untuk sistem operasi.
Setelah menyelesaikan kebutuhan perangkat keras saya (dan menunggu kedatangan solusi ini), saya beralih ke tujuan kedua.
Mengelola perangkat lunak pada perangkat
Sebagian, proyek-proyek masa lalu saya yang terkait dengan papan pengembangan telah gagal karena kurangnya perhatian terhadap masalah reproduksi dan dokumentasi. Saat membuat konfigurasi berikutnya untuk kebutuhan saya saat ini, saya tidak repot untuk menuliskan langkah-langkah yang diambil atau tautan ke posting blog yang saya ikuti. Dan ketika, setelah berbulan-bulan atau bertahun-tahun, ada yang tidak beres dan saya mencoba memperbaiki masalahnya, saya tidak memiliki pemahaman tentang bagaimana semuanya pada awalnya diatur.
Jadi aku berkata pada diriku sendiri bahwa kali ini semuanya akan berbeda!

Dan dia beralih ke fakta bahwa saya cukup tahu - untuk Kubernetes.
Meskipun K8 adalah solusi yang terlalu sulit untuk masalah yang agak sederhana, setelah hampir tiga tahun mengelola cluster menggunakan berbagai alat (saya sendiri, kops, dll.) Di pekerjaan utama saya, saya sangat akrab dengan sistem ini. Selain itu, menyebarkan K8 di luar lingkungan cloud, dan bahkan pada perangkat ARM - semua ini sepertinya tugas yang menarik.
Saya juga berpikir bahwa karena perangkat keras yang tersedia tidak memenuhi persyaratan yang diperlukan untuk NAS, saya akan mencoba untuk setidaknya mengumpulkan gugus dari itu dan, mungkin, beberapa perangkat lunak yang tidak begitu menuntut sumber daya akan dapat bekerja pada perangkat yang lebih tua.
Kubernet di ARM
Di tempat kerja, saya tidak memiliki kesempatan untuk menggunakan utilitas
kubeadm
untuk menyebarkan cluster, jadi saya memutuskan bahwa sekarang adalah waktu untuk mencobanya dalam tindakan.
Raspbian dipilih sebagai sistem operasi, karena terkenal akan dukungan terbaik untuk papan saya.
Saya menemukan
artikel yang bagus tentang pengaturan Kubernetes pada Raspberry Pi menggunakan HypriotOS. Karena saya tidak yakin tentang ketersediaan HypriotOS untuk semua board saya, saya mengadaptasi instruksi ini untuk Debian / Raspbian.
Komponen yang Diperlukan
Pertama, instalasi alat-alat berikut diperlukan:
- Docker,
- kubelet
- kubeadm,
- kubectl.
Docker harus diinstal menggunakan skrip khusus -
skrip kenyamanan (seperti yang ditunjukkan untuk kasus menggunakan Raspbian).
curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh
Setelah itu, saya menginstal komponen Kubernetes sesuai dengan instruksi dari blog Hypriot, mengadaptasinya sehingga versi spesifik digunakan untuk semua dependensi:
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" > /etc/apt/sources.list.d/kubernetes.list apt-get update apt-get install -y kubelet=1.13.1-00 kubectl=1.13.1-00 kubeadm=1.13.1-00
Raspberry pi b
Kesulitan pertama muncul ketika mencoba untuk mem-bootstrap sebuah cluster pada Raspberry Pi B:
$ kubeadm init Illegal instruction
Ternyata Kubernetes
menghapus dukungan untuk ARMv6 . Yah, saya juga punya CubbieBoard dan Banana Pi.
Pi pisang
Awalnya, urutan tindakan yang sama untuk Pisang Pi tampaknya lebih berhasil, namun, perintah
kubeadm init
saat mencoba menunggu pesawat kontrol bekerja:
error execution phase wait-control-plane: couldn't initialize a Kubernetes cluster
Mencari tahu dengan
docker ps
apa yang terjadi dengan wadah, saya melihat bahwa
kube-controller-manager
dan
kube-scheduler
telah bekerja setidaknya 4-5 menit, tetapi
kube-api-server
bangun hanya 1-2 menit yang lalu:
$ docker ps CONTAINER ID COMMAND CREATED STATUS de22427ad594 "kube-apiserver --au…" About a minute ago Up About a minute dc2b70dd803e "kube-scheduler --ad…" 5 minutes ago Up 5 minutes 60b6cc418a66 "kube-controller-man…" 5 minutes ago Up 5 minutes 1e1362a9787c "etcd --advertise-cl…" 5 minutes ago Up 5 minutes
Jelas,
api-server
sedang sekarat atau proses strontium mematikan dan me-restart itu.
Memeriksa log, saya melihat prosedur start-up yang sangat standar - ada catatan awal mendengarkan port aman dan jeda panjang sebelum munculnya banyak kesalahan dalam jabat tangan TLS:
20:06:48.604881 naming_controller.go:284] Starting NamingConditionController 20:06:48.605031 establishing_controller.go:73] Starting EstablishingController 20:06:50.791098 log.go:172] http: TLS handshake error from 192.168.1.155:50280: EOF 20:06:51.797710 log.go:172] http: TLS handshake error from 192.168.1.155:50286: EOF 20:06:51.971690 log.go:172] http: TLS handshake error from 192.168.1.155:50288: EOF 20:06:51.990556 log.go:172] http: TLS handshake error from 192.168.1.155:50284: EOF 20:06:52.374947 log.go:172] http: TLS handshake error from 192.168.1.155:50486: EOF 20:06:52.612617 log.go:172] http: TLS handshake error from 192.168.1.155:50298: EOF 20:06:52.748668 log.go:172] http: TLS handshake error from 192.168.1.155:50290: EOF
Dan segera setelah itu, server mengakhiri kerjanya. Googling menyebabkan
masalah seperti itu , menunjukkan kemungkinan alasan lambatnya operasi algoritma kriptografi pada beberapa perangkat ARM.
Saya melangkah lebih jauh dan berpikir bahwa mungkin
api-server
mendapatkan terlalu banyak permintaan berulang dari
scheduler
dan
controller-manager
.
Menghapus file-file ini dari direktori manifes akan memberitahu kubelet untuk menghentikan eksekusi pod yang sesuai:
mkdir /etc/kubernetes/manifests.bak mv /etc/kubernetes/manifests/kube-scheduler.yaml /etc/kubernetes/manifests.bak/ mv /etc/kubernetes/manifests/kube-controller-mananger.yaml /etc/kubernetes/manifests.bak/
Melihat log
api-server
terbaru menunjukkan bahwa sekarang prosesnya berjalan lebih jauh, namun, itu masih mati setelah sekitar 2 menit. Kemudian saya ingat bahwa manifes dapat berisi sampel live dengan timeout yang memiliki nilai terlalu rendah untuk perangkat yang lambat.
Oleh karena itu, saya memeriksa
/etc/kubernetes/manifests/kube-api-server.yaml
- dan di dalamnya, tentu saja ...
livenessProbe: failureThreshold: 8 httpGet: host: 192.168.1.155 path: /healthz port: 6443 scheme: HTTPS initialDelaySeconds: 15 timeoutSeconds: 15
Pod terbunuh setelah 135 detik (
initialDelaySeconds
+
timeoutSeconds
*
failureThreshold
). Tingkatkan
initialDelaySeconds
ke 120 ...
Sukses! Yah, kesalahan jabat tangan masih terjadi (mungkin dari kubelet), namun peluncuran masih terjadi:
20:06:54.957236 log.go:172] http: TLS handshake error from 192.168.1.155:50538: EOF 20:06:55.004865 log.go:172] http: TLS handshake error from 192.168.1.155:50384: EOF 20:06:55.118343 log.go:172] http: TLS handshake error from 192.168.1.155:50292: EOF 20:06:55.252586 cache.go:39] Caches are synced for autoregister controller 20:06:55.253907 cache.go:39] Caches are synced for APIServiceRegistrationController controller 20:06:55.545881 controller_utils.go:1034] Caches are synced for crd-autoregister controller ... 20:06:58.921689 storage_rbac.go:187] created clusterrole.rbac.authorization.k8s.io/cluster-admin 20:06:59.049373 storage_rbac.go:187] created clusterrole.rbac.authorization.k8s.io/system:discovery 20:06:59.214321 storage_rbac.go:187] created clusterrole.rbac.authorization.k8s.io/system:basic-user
Ketika
api-server
bangkit, saya memindahkan file YAML untuk controller dan scheduler kembali ke direktori manifes, setelah itu mereka mulai secara normal juga.
Sekarang saatnya memastikan bahwa unduhan akan berhasil jika Anda meninggalkan semua file di direktori sumber: apakah cukup untuk mengubah penundaan yang diizinkan dalam inisialisasi
livenessProbe
?
20:29:33.306983 reflector.go:134] k8s.io/client-go/informers/factory.go:132: Failed to list *v1.Service: Get https://192.168.1.155:6443/api/v1/services?limit=500&resourceVersion=0: dial tcp 192.168.1.155:6443: i/o timeout 20:29:33.434541 reflector.go:134] k8s.io/client-go/informers/factory.go:132: Failed to list *v1.ReplicationController: Get https://192.168.1.155:6443/api/v1/replicationcontrollers?limit=500&resourceVersion=0: dial tcp 192.168.1.155:6443: i/o timeout 20:29:33.435799 reflector.go:134] k8s.io/client-go/informers/factory.go:132: Failed to list *v1.PersistentVolume: Get https://192.168.1.155:6443/api/v1/persistentvolumes?limit=500&resourceVersion=0: dial tcp 192.168.1.155:6443: i/o timeout 20:29:33.477405 reflector.go:134] k8s.io/client-go/informers/factory.go:132: Failed to list *v1beta1.PodDisruptionBudget: Get https://192.168.1.155:6443/apis/policy/v1beta1/poddisruptionbudgets?limit=500&resourceVersion=0: dial tcp 192.168.1.155:6443: i/o timeout 20:29:33.493660 reflector.go:134] k8s.io/client-go/informers/factory.go:132: Failed to list *v1.PersistentVolumeClaim: Get https://192.168.1.155:6443/api/v1/persistentvolumeclaims?limit=500&resourceVersion=0: dial tcp 192.168.1.155:6443: i/o timeout 20:29:37.974938 controller_utils.go:1027] Waiting for caches to sync for scheduler controller 20:29:38.078558 controller_utils.go:1034] Caches are synced for scheduler controller 20:29:38.078867 leaderelection.go:205] attempting to acquire leader lease kube-system/kube-scheduler 20:29:38.291875 leaderelection.go:214] successfully acquired lease kube-system/kube-scheduler
Ya, semuanya berfungsi, meskipun perangkat lama tersebut, tampaknya, tidak dimaksudkan untuk meluncurkan pesawat kontrol, karena koneksi TLS yang berulang menyebabkan rem yang signifikan. Satu atau lain cara - instalasi K8 yang aktif di ARM diterima! Mari kita melangkah lebih jauh ...
Pemasangan RAID
Karena kartu SD tidak cocok untuk direkam dalam jangka panjang, saya memutuskan untuk menggunakan penyimpanan yang lebih andal untuk bagian sistem file yang paling tidak stabil - dalam hal ini, RAID. 4 bagian disorot di atasnya:
Saya belum datang dengan tujuan khusus untuk partisi 20-gigabyte, tetapi saya ingin meninggalkan peluang tambahan untuk masa depan.
Dalam file
/etc/fstab
untuk partisi 50 GB, titik mount ditentukan sebagai
/mnt/root
, dan untuk 3,9 TB -
/mnt/raid
. Setelah itu, saya memasang direktori dengan etcd dan docker ke partisi 50 GB:
UUID=655a39e8-9a5d-45f3-ae14-73b4c5ed50c3 /mnt/root ext4 defaults,rw,user,auto,exec 0 0 UUID=0633df91-017c-4b98-9b2e-4a0d27989a5c /mnt/raid ext4 defaults,rw,user,auto 0 0 /mnt/root/var/lib/etcd /var/lib/etcd none defaults,bind 0 0 /mnt/root/var/lib/docker /var/lib/docker none defaults,bind 0 0
Kedatangan ROC-RK3328-CC
Ketika papan baru dikirim, saya menginstal komponen yang diperlukan untuk K8 di atasnya
(lihat bagian awal artikel) dan meluncurkan
kubeadm init
. Beberapa menit menunggu adalah keberhasilan dan keluaran dari perintah
join
untuk dijalankan pada node lain.
Hebat! Tidak repot dengan timeout.
Dan karena RAID juga akan digunakan pada board ini, mount perlu dikonfigurasikan lagi. Untuk merangkum semua langkah:
1. Pasang disk di / etc / fstab
UUID=655a39e8-9a5d-45f3-ae14-73b4c5ed50c3 /mnt/root ext4 defaults,rw,user,auto,exec 0 0 UUID=0633df91-017c-4b98-9b2e-4a0d27989a5c /mnt/raid ext4 defaults,rw,user,auto 0 0 /mnt/root/var/lib/etcd /var/lib/etcd none defaults,bind 0 0 /mnt/root/var/lib/docker /var/lib/docker none defaults,bind 0 0
2. Menginstal Docker dan binari K8
curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" > /etc/apt/sources.list.d/kubernetes.list apt-get update apt-get install -y kubelet=1.13.1-00 kubectl=1.13.1-00 kubeadm=1.13.1-00
3. Mengkonfigurasi nama host yang unik (penting karena banyak node ditambahkan)
hostnamectl set-hostname k8s-master-1
4. Inisialisasi Kubernetes
Saya menghilangkan fase dengan bidang kontrol, karena saya ingin dapat merencanakan pod yang normal pada simpul ini:
kubeadm init --skip-phases mark-control-plane
5. Menginstal plugin jaringan
Informasi tentang ini dalam artikel Hypriot sedikit tertanggal karena plugin jaringan Weave sekarang juga
didukung di ARM :
export KUBECONFIG=/etc/kubernetes/admin.conf kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
6. Menambahkan label host
Pada simpul ini, saya akan memulai server NAS, jadi saya akan menandainya dengan label untuk kemungkinan penggunaan di masa depan dalam penjadwal:
kubectl label nodes k8s-master-1 marshallbrekka.raid=true kubectl label nodes k8s-master-1 marshallbrekka.network=gigabit
Menghubungkan node lain ke cluster
Menyiapkan perangkat lain (Banana Pi, CubbieBoard) sama mudahnya. Bagi mereka, Anda perlu mengulangi 3 langkah pertama (mengubah pengaturan untuk memasang disk / media flash, tergantung pada ketersediaannya) dan menjalankan perintah
kubeadm join
bukan
kubeadm init
.
Menemukan Wadah Docker untuk ARM
Sebagian besar wadah Docker yang diperlukan dibuat secara normal di Mac, tetapi untuk ARM itu sedikit lebih rumit. Setelah menemukan banyak artikel tentang cara menggunakan QEMU untuk keperluan ini, saya sampai pada
kesimpulan bahwa sebagian besar aplikasi yang saya
butuhkan sudah dirakit, dan banyak di antaranya tersedia di
server linux .
Langkah selanjutnya
Masih tidak mendapatkan konfigurasi awal perangkat dalam bentuk otomatis / scripted seperti yang saya inginkan, saya setidaknya menyusun seperangkat perintah dasar (mounts,
docker
dan
kubeadm
) dan mendokumentasikannya dalam repositori Git. Sisa dari aplikasi yang digunakan juga menerima konfigurasi YAML untuk K8 yang disimpan dalam repositori yang sama, jadi sekarang sangat mudah untuk mendapatkan konfigurasi yang diperlukan dari awal.
Di masa depan, saya ingin mencapai yang berikut:
- Jadikan situs master sangat tersedia
- tambahkan pemantauan / pemberitahuan untuk mengetahui tentang kegagalan dalam komponen apa pun;
- Ubah pengaturan DCHP router untuk menggunakan server DNS dari cluster untuk menyederhanakan penemuan aplikasi (siapa yang ingin mengingat alamat IP internal?);
- menjalankan MetalLB untuk meneruskan layanan cluster ke jaringan pribadi (DNS, dll.)
PS dari penerjemah
Baca juga di blog kami: