Kubernetes cluster untuk $ 20 per bulan

TL DR


Kami meningkatkan cluster untuk melayani aplikasi web tanpa kewarganegaraan dengan masuknya , letsencrypt , tanpa menggunakan alat otomatisasi seperti kubespray, kubeadm, dan lainnya.
Waktu baca: ~ 45-60 menit, untuk aksi pemutaran ulang: mulai 3 jam.


Pembukaan


Saya diminta untuk menulis artikel dengan kebutuhan untuk kubernetes saya sendiri untuk eksperimen. Instalasi otomatis dan solusi konfigurasi open source tidak berfungsi dalam kasus saya, karena saya menggunakan distribusi Linux non-mainstream. Pekerjaan intensif dengan kubernet di IPONWEB mendorong Anda untuk memiliki platform seperti itu, menyelesaikan tugas Anda dengan cara yang nyaman, termasuk untuk proyek-proyek rumah.


Komponen


Komponen berikut akan muncul di artikel:


- Linux favorit Anda - Saya menggunakan Gentoo (node-1: systemd / node-2: openrc), Ubuntu 18.04.1.
- Server Kubernetes - kube-apiserver, kube-controller-manager, kube-scheduler, kubelet, kube-proxy.
- Containerd + CNI Plugins (0.7.4) - untuk kontainerisasi, kami akan mengambil contenterd + CNI alih-alih buruh pelabuhan (meskipun pada awalnya seluruh konfigurasi diunggah ke buruh pelabuhan, jadi tidak ada yang akan mencegahnya digunakan jika diperlukan).
- CoreDNS - untuk mengatur penemuan layanan dari komponen yang bekerja di dalam kubernetes cluster. Versi yang tidak lebih rendah dari 1.2.5 direkomendasikan, karena dengan versi ini ada dukungan waras untuk bekerja sebagai proses yang berjalan di luar cluster.
- Flannel - untuk mengatur tumpukan jaringan, mengkomunikasikan perapian dan wadah di antara mereka sendiri.
- db favorit Anda .


Untuk semua


Keterbatasan dan Asumsi


  • Artikel ini tidak membahas biaya solusi vps / vds di pasar, serta kemungkinan penempatan mesin pada layanan ini. Diasumsikan bahwa Anda telah memiliki sesuatu yang diperluas, atau Anda dapat melakukannya sendiri. Juga, instalasi / konfigurasi database favorit Anda dan repositori buruh pelabuhan pribadi, jika Anda memerlukannya, tidak tercakup.
  • Kita bisa menggunakan kedua plugin +erdi cni dan docker. Artikel ini tidak mempertimbangkan menggunakan buruh pelabuhan sebagai alat kontainerisasi. Jika Anda ingin menggunakan buruh pelabuhan, Anda sendiri akan dapat mengonfigurasi flanel yang sesuai , selain itu Anda harus mengonfigurasi kubelet, yaitu, menghapus semua opsi yang terkait dengan containerd. Seperti yang diperlihatkan percobaan saya, buruh pelabuhan dan penampung di berbagai node sebagai wadah akan bekerja dengan benar.
  • Kami tidak dapat menggunakan backend host-gw untuk flanel, baca bagian Konfigurasi Flanel untuk lebih jelasnya
  • Kami tidak akan menggunakan apa pun untuk memantau, mencadangkan, menyimpan file pengguna (status), menyimpan file konfigurasi dan kode aplikasi (git / hg / svn / dll)

Pendahuluan


Dalam perjalanan kerja, saya menggunakan sejumlah besar sumber, tetapi saya ingin menyebutkan secara terpisah Kubernetes panduan jalan yang agak rinci, yang mencakup sekitar 90% dari konfigurasi dasar cluster sendiri. Jika Anda sudah membaca manual ini, Anda dapat dengan aman melanjutkan langsung ke bagian Konfigurasi Flannel .


Penunjukan

Daftar Istilah / Glosarium


  • api-server - mesin fisik atau virtual tempat kumpulan aplikasi untuk meluncurkan dan memfungsikan kubernetes kube-apiserver berada. Untuk keperluan artikel ini, ini adalah etcd, kube-apiserver, kube-controller-manager, kube-scheduler.
  • master - instalasi workstation atau VPS khusus, sinonim untuk api-server.
  • simpul-X - stasiun kerja khusus atau instalasi VPS, X menunjukkan nomor seri stasiun. Dalam artikel ini, semua angka unik dan merupakan kunci untuk memahami:
    • simpul-1 - mesin nomor 1
    • simpul-2 - nomor mesin 2
  • vCPU - CPU virtual, inti prosesor. Jumlahnya sesuai dengan jumlah inti: 1vCPU - satu inti, 2vCPU - dua, dan seterusnya.
  • pengguna - pengguna atau ruang pengguna. Saat menggunakan instruksi baris perintah user$ in, istilah ini merujuk ke mesin klien mana pun.
  • pekerja - simpul kerja di mana perhitungan langsung akan dilakukan, secara sinonim dengan node-X
  • sumber daya adalah entitas yang dioperasikan oleh kluster Kubernetes. Sumber daya Kubernetes mencakup sejumlah besar entitas terkait .

Solusi arsitektur jaringan


Dalam proses meningkatkan cluster, saya tidak menetapkan tugas mengoptimalkan sumber daya besi sedemikian rupa agar sesuai dengan anggaran $ 20 per bulan. Itu hanya perlu untuk merakit sebuah cluster yang bekerja dengan setidaknya dua node kerja (node). Oleh karena itu, pada awalnya cluster tampak seperti ini:


  • mesin dengan 2 vCPU / 4G RAM: api-server + node-1 [20 $]
  • mesin dengan 2 vCPU / 4G RAM: node-2 [$ 20]

Setelah versi pertama dari cluster berfungsi, saya memutuskan untuk membangunnya kembali untuk membedakan antara node yang bertanggung jawab untuk menjalankan aplikasi di dalam cluster (work node, mereka juga pekerja) dan API dari server master.


Akibatnya, saya mendapat jawaban untuk pertanyaan: "Bagaimana cara mendapatkan lebih banyak atau lebih murah, tetapi berfungsi cluster, jika saya ingin menempatkan bukan aplikasi yang paling tebal di sana."


Keputusan $ 20

Desain
(Direncanakan seperti itu)


Arsitektur Umum Informasi Kubernet

Desain
(Dicuri dari Internet jika seseorang tiba-tiba masih tidak tahu atau belum melihat)


Komponen dan kinerjanya


Langkah pertama adalah memahami berapa banyak sumber daya yang saya butuhkan untuk menjalankan paket perangkat lunak yang terkait langsung dengan cluster. Pencarian untuk "persyaratan perangkat keras" tidak memberikan hasil yang spesifik, jadi saya harus mendekati tugas dari sudut pandang praktis. Sebagai pengukuran MEM dan CPU, saya mengambil statistik dari systemd - kita dapat mengasumsikan bahwa pengukuran dilakukan dengan cara yang sangat amatir, tetapi saya tidak memiliki tugas untuk mendapatkan nilai yang akurat, karena saya masih tidak dapat menemukan opsi yang lebih murah daripada $ 5 per contoh.


Kenapa tepatnya $ 5?

Dimungkinkan untuk menemukan VPS / VDS lebih murah ketika hosting server di Rusia atau CIS, tetapi kisah sedih yang terkait dengan ILV dan tindakannya menimbulkan risiko tertentu dan menimbulkan keinginan alami untuk menghindarinya.


Jadi:


  • Master Server / Konfigurasi Server (Master Nodes):
    • etcd (3.2.17): 80 - 100M, metrik diambil pada waktu yang dipilih secara acak. Konsumsi memori rata-rata etcd tidak melebihi 300 juta;
    • kube-apiserver (1.12.x - 1.13.0): 237.6M ~ 300M;
    • kube-controller-manager (1.12.x - 1.13.0): sekitar 90M, tidak naik di atas 100M;
    • kube-scheduler (1.12.x - 1.13.0): sekitar 20M, konsumsi di atas 30-50M tidak tetap.
  • Konfigurasi server pekerja (Worker Nodes):
    • kubelet (1.12.3 - 1.13.1): sekitar 35 Mb, konsumsi di atas 50M tidak tetap;
    • kube-proxy (1.12.3 - 1.13.1): sekitar 7.5 - 10M;
    • flanel (0.10.0): sekitar 15-20M;
    • coredns (1.3.0): sekitar 25M;
    • containerd (1.2.1): konsumsi containerd rendah, tetapi statistik juga menunjukkan proses kontainer diluncurkan oleh daemon.

Apakah contenterd / docker diperlukan pada node master?

Tidak, tidak dibutuhkan . Master node tidak memerlukan buruh pelabuhan atau server konten per se, meskipun ada sejumlah besar manual di Internet yang termasuk menggunakan lingkungan containerization untuk berbagai keperluan. Dalam konfigurasi yang dimaksud, Conteerd sengaja dimatikan dari daftar dependensi, namun, saya tidak menyoroti keuntungan nyata dari pendekatan ini.


Konfigurasi yang disediakan di atas minimal dan cukup untuk memulai cluster. Tidak ada tindakan / komponen tambahan yang diperlukan, kecuali jika Anda ingin menambahkan sesuatu seperti yang Anda inginkan.


Untuk membangun gugus uji atau gugus untuk proyek-proyek rumah, RAM 1vCPU / 1G akan cukup untuk master node berfungsi. Tentu saja, beban pada node master akan bervariasi tergantung pada jumlah pekerja yang terlibat, serta ketersediaan dan volume permintaan pihak ketiga ke server api.


Saya meledak konfigurasi master dan pekerja sebagai berikut:


  • 1x Master dengan komponen yang diinstal: etcd, kube-apiserver, kube-controller-manager, kube-scheduler
  • 2x Pekerja dengan komponen yang dipasang: containerd, coredns, flannel, kubelet, kube-proxy

Konfigurasi


Untuk mengkonfigurasi wizard, diperlukan komponen berikut:


  • etcd - untuk menyimpan data untuk api-server, serta untuk flannel;


  • kube-apiserver - sebenarnya, api-server;


  • kube-controller-manager - untuk menghasilkan dan memproses acara;


  • kube-scheduler - untuk distribusi sumber daya yang terdaftar melalui api-server - misalnya, perapian .
    Untuk konfigurasi workhorses, diperlukan komponen berikut:


  • kubelet - untuk menjalankan perapian, untuk mengkonfigurasi pengaturan jaringan;


  • kube-proxy - untuk mengatur perutean / penyeimbangan layanan kubernetes;


  • coredns - untuk penemuan layanan di dalam wadah yang berjalan;


  • flannel - untuk mengatur akses jaringan kontainer yang beroperasi pada node yang berbeda, serta untuk distribusi dinamis jaringan di antara node (kubernetes node) dari sebuah cluster.



Coredns

Penyimpangan kecil harus dilakukan di sini: coredn juga dapat diluncurkan pada server master. Tidak ada batasan yang akan memaksa coredns untuk berjalan di node kerja, kecuali untuk nuansa konfigurasi coredns.service, yang sama sekali tidak dimulai pada server Ubuntu standar / tidak dimodifikasi karena konflik dengan layanan yang diselesaikan oleh systemd. Saya tidak mencoba menyelesaikan masalah ini, karena 2 ns server yang terletak di node yang bekerja cukup senang dengan saya.


Agar tidak membuang waktu sekarang membiasakan diri dengan semua detail dari proses konfigurasi komponen, saya sarankan Anda membiasakan diri dengan mereka dalam panduan cara yang sulit Kubernetes . Saya akan fokus pada fitur yang membedakan opsi konfigurasi saya.


File


Semua file untuk berfungsinya komponen cluster untuk wisaya dan node kerja ditempatkan di / var / lib / kubernetes / untuk kenyamanan. Jika perlu, Anda dapat menempatkannya dengan cara lain.


Sertifikasi


Dasar untuk pembuatan sertifikat adalah Kubernetes yang sama dengan cara yang sulit , praktis tidak ada perbedaan yang signifikan. Untuk membuat ulang sertifikat bawahan, skrip bash sederhana ditulis di sekitar aplikasi cfssl - ini sangat berguna dalam proses debugging.


Anda dapat menghasilkan sertifikat untuk kebutuhan Anda menggunakan skrip di bawah ini, resep dari Kubernetes dengan cara yang sulit atau alat lain yang sesuai.


Pembuatan sertifikat menggunakan skrip bash

Anda bisa mendapatkan skrip di sini: kubernetes bootstrap . Sebelum memulai, edit file certs / env.sh , tentukan pengaturan Anda. Contoh:


 $ cd certs #:   certs$ ./generate-keys.sh # ... certificate generate output #:  kubeconfig     certs$ ./generate-configkube.sh 

Jika Anda menggunakan env.sh dan menentukan semua parameter dengan benar, maka tidak perlu menyentuh sertifikat yang dihasilkan. Jika Anda membuat kesalahan di beberapa titik, maka sertifikat dapat dibuat ulang di beberapa bagian. Skrip bash di atas sepele, menyortirnya tidak sulit.


Catatan penting - Anda tidak harus sering membuat ulang ca.pem dan ca-key.pem , karena mereka adalah sertifikat root untuk semua sertifikat berikutnya, dengan kata lain, Anda harus membuat ulang semua sertifikat yang menyertainya dan mengirimkannya ke semua mesin dan semua direktori yang diperlukan.


Tuan


Sertifikat yang diperlukan untuk memulai layanan pada node master harus diletakkan di /var/lib/kubernetes/ :


  • ca.pem - sertifikat ini digunakan di mana-mana, hanya dapat dihasilkan sekali dan kemudian digunakan tanpa perubahan, jadi berhati-hatilah. Ketika Anda membuat ulang, Anda harus menyalinnya ke semua node, serta memperbarui file kubeconfig yang menggunakannya (juga pada semua mesin).
  • ca-key.pem sama dengan menyalin node.
  • kube-controller-manager.pem - dibutuhkan hanya untuk kube-controller-manager.
  • kube-controller-manager-key.pem - dibutuhkan hanya untuk kube-controller-manager.
  • kubernetes.pem - diperlukan untuk kain flanel, coredn saat terhubung ke etcd, kube-apiserver.


    Retret teoretis

    Fitur ini didasarkan pada logika konfigurasi hard drive Kubernetes .
    Berdasarkan ini, file ini akan dibutuhkan di mana-mana - baik pada wizard dan pada node kerja. Saya tidak mengubah pendekatan yang diberikan oleh manual asli, karena dengan bantuannya dimungkinkan untuk mengatur operasi klaster lebih cepat dan lebih jelas dan memahami sejumlah besar dependensi.


    Pendapat pribadi saya adalah bahwa untuk etcd Anda memerlukan sertifikat terpisah yang tidak tumpang tindih dengan sertifikat yang digunakan untuk kubernet.




  • kubernetes-key.pem - tetap berada di server master.
  • service-account.pem - hanya diperlukan untuk daemon kube-controller-manager.
  • service-account-key.pem - sama.

Unit kerja


  • ca.pem - diperlukan untuk semua layanan yang terlibat pada simpul kerja (kubelet, kube-proxy), serta untuk flanel, coredns. Antara lain, isinya termasuk dalam file kubeconfig ketika mereka dihasilkan menggunakan kubectl.
  • kubernetes-key.pem - hanya diperlukan untuk flanel dan coredn untuk terhubung ke etcd, yang terletak di node master api.
  • kubernetes.pem - mirip dengan yang sebelumnya, hanya dibutuhkan untuk kain flanel dan coredn.
  • kubelet / node-1.pem - kunci untuk otorisasi simpul-1.
  • kubelet / node-1-key.pem - kunci untuk otorisasi simpul-1.

Penting! Jika Anda memiliki lebih dari satu node, maka setiap node akan menyertakan file node-X-key.pem , node-X.pem dan node-X.kubeconfig di dalam kubelet.


Sertifikat Debugging

Sertifikat Debugging


Terkadang Anda mungkin perlu melihat bagaimana sertifikat dikonfigurasikan untuk mencari tahu IP / DNS host mana yang digunakan untuk menghasilkannya. Perintah cfssl-certinfo -cert <cert> akan membantu kami dalam hal ini. Sebagai contoh, kita mempelajari informasi ini untuk node-1.pem :


 $ cfssl-certinfo -cert node-1.pem 

 { "subject": { "common_name": "system:node:node-1", "country": "RU", "organization": "system:nodes", "organizational_unit": "Infrastructure Unit", "locality": "Moscow", "province": "Moscow", "names": [ "RU", "Moscow", "Moscow", "system:nodes", "Infrastructure Unit", "system:node:node-1" ] }, "issuer": { "common_name": "Kubernetes", "country": "RU", "organization": "Kubernetes", "organizational_unit": "Infrastructure", "locality": "Moscow", "province": "Moscow", "names": [ "RU", "Moscow", "Moscow", "Kubernetes", "Infrastructure", "Kubernetes" ] }, "serial_number": "161113741562559533299282037709313751074033027073", "sans": [ "w40k.net", "node-1", "178.79.168.130", "192.168.164.230" ], "not_before": "2019-01-04T14:24:00Z", "not_after": "2029-01-01T14:24:00Z", "sigalg": "SHA256WithRSA", "authority_key_id": "6:C8:94:67:59:55:19:82:AD:ED:6D:50:F1:89:B:8D:46:78:FD:9A", "subject_key_id": "A1:5E:B3:3C:45:14:3D:C6:C:A:97:82:1:D5:2B:75:1A:A6:9D:B0", "pem": "<pem content>" } 

Semua sertifikat lain untuk kubelet dan kube-proxy disematkan langsung ke kubeconfig yang sesuai.


kubeconfig


Semua kubeconfig yang diperlukan dapat dilakukan dengan menggunakan Kubernetes dengan cara yang sulit , namun, di sini beberapa perbedaan dimulai. Manual ini menggunakan kubedns dan cni bridge , juga mencakup coredns dan flanel . Kedua layanan ini, pada gilirannya, menggunakan kubeconfig untuk kubeconfig ke cluster.


 $ cd certs #:  kubeconfig     certs$ ./generate-configkube.sh 

Tuan


Untuk panduan, file kubeconfig berikut diperlukan (seperti yang disebutkan di atas, setelah generasi dapat diambil dalam certs/kubeconfig ):


 master /var/lib/kubernetes/$ tree -L 2 . +-- kube-controller-manager.kubeconfig L-- kube-scheduler  L-- kube-scheduler.kubeconfig 

File-file ini akan diperlukan untuk menjalankan masing-masing komponen layanan.


Unit kerja


Untuk simpul kerja, file kubeconfig berikut ini diperlukan:


 node-1 /var/lib/kubernetes/$ tree -L 2 . +-- coredns ยฆ  L-- coredns.kubeconfig +-- flanneld ยฆ  L-- flanneld.kubeconfig +-- kubelet ยฆ  L-- node-1.kubeconfig L-- kube-proxy  L-- kube-proxy.kubeconfig 

Peluncuran layanan


Layanan

Terlepas dari kenyataan bahwa node pekerjaan saya menggunakan sistem inisialisasi yang berbeda, contoh dan repositori memberikan opsi menggunakan systemd. Dengan bantuan mereka, akan lebih mudah untuk memahami proses mana dan dengan parameter mana Anda perlu memulai, di samping itu, mereka seharusnya tidak menyebabkan masalah besar ketika mempelajari layanan dengan flag tujuan.


Untuk memulai layanan, Anda perlu menyalin service-name.service ke /lib/systemd/system/ atau direktori lain di mana layanan untuk systemd berada, dan kemudian nyalakan dan mulai layanan. Contoh untuk apubever kubus:


 $ systemctl enable kube-apiserver.service $ systemctl start kube-apiserver.service 

Tentu saja, semua layanan harus berwarna hijau (yaitu berjalan dan berfungsi). Jika Anda menemukan kesalahan, perintah journalct -xe atau journal -f -t kube-apiserver akan membantu Anda memahami apa yang sebenarnya salah.


Jangan terburu-buru untuk memulai semua server sekaligus, untuk memulainya akan cukup untuk mengaktifkan etcd dan kube-apiserver. Jika semuanya berjalan dengan baik, dan Anda segera mendapatkan keempat layanan pada wizard, peluncuran wizard dapat dianggap berhasil.


Tuan


Anda dapat menggunakan pengaturan systemd atau menghasilkan skrip init untuk konfigurasi yang Anda gunakan. Seperti yang telah disebutkan, untuk master yang Anda butuhkan:


- systemd / etcd
- systemd / kube-apiserver
- systemd / kube-controller-manager
- systemd / kube-scheduler


Unit kerja


- systemd / containerd
- systemd / kubelet
- systemd / kube-proxy
- systemd / coredns
- systemd / flanel


Pelanggan


Agar klien dapat bekerja, cukup salin certs/kubeconfig/admin.kubeconfig (setelah Anda membuatnya atau menulis sendiri) di ${HOME}/.kube/config


Unduh kubectl dan periksa pengoperasian kube-apiserver. Izinkan saya mengingatkan Anda sekali lagi bahwa pada tahap ini, agar kube-apiserver berfungsi, hanya etcd yang akan berfungsi. Komponen yang tersisa akan dibutuhkan untuk operasi penuh dari cluster sesaat kemudian.


Periksa apakah kube-apiserver dan kubectl berfungsi:


 $ kubectl version Client Version: version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.0", "extra info": "..."} Server Version: version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.0", "extra info": "..."} 

Konfigurasi Flanel


Sebagai konfigurasi flanel, saya memilih backend vxlan . Baca lebih lanjut tentang backend di sini .


host-gw dan mengapa itu tidak berhasil

Saya harus mengatakan segera bahwa menjalankan kluster kubernet pada VPS cenderung membatasi Anda untuk menggunakan backend host-gw . Tidak menjadi insinyur jaringan yang berpengalaman, saya menghabiskan sekitar dua hari debugging untuk memahami apa masalahnya dengan penggunaannya pada penyedia VDS / VPS yang populer.


Linode.com dan digitalocean telah diuji. Inti masalahnya adalah bahwa penyedia tidak memberikan L2 jujur โ€‹โ€‹untuk jaringan pribadi. Ini, pada gilirannya, membuat tidak mungkin untuk memindahkan lalu lintas jaringan antara node dalam konfigurasi ini:


Lalu lintas


Agar lalu lintas jaringan berfungsi antara node, routing normal akan cukup. Jangan lupa bahwa net.ipv4.ip_forward harus disetel ke 1, dan rantai FORWARD dalam tabel filter tidak boleh berisi aturan larangan untuk node.


 node1$ ip route add 10.200.12.0/24 via 192.168.1.2 node2$ ip route add 10.200.8.0/24 via 192.168.1.1 

 [10.200.80.23 container-1]->[192.168.1.1 node-1]->[192.168.1.2 node-2]->[10.200.12.5 container-2] 

Inilah yang tidak bekerja pada VPS / VDS yang ditunjukkan (dan, kemungkinan besar, umumnya pada semua).


Oleh karena itu, jika konfigurasi solusi dengan kinerja jaringan tinggi antara node penting bagi Anda, Anda masih harus menghabiskan lebih dari $ 20 untuk mengatur cluster.


Anda dapat menggunakan set-flannel-config.sh dari etc / flannel untuk mengatur konfigurasi flanel yang diinginkan. Penting untuk diingat : jika Anda memutuskan untuk mengubah backend, Anda harus menghapus konfigurasi di etcd dan restart semua daemon flanel pada semua node, jadi pilihlah dengan bijak. Standarnya adalah vxlan.


 master$ export ETCDCTL_CA_FILE='/var/lib/kubernetes/ca.pem' master$ export ETCDCTL_CERT_FILE='/var/lib/kubernetes/kubernetes.pem' master$ export ETCDCTL_KEY_FILE='/var/lib/kubernetes/kubernetes-key.pem' master$ export ETCDCTL_ENDPOINTS='https://127.0.0.1:2379' master$ etcdctl ls /coreos.com/network/subnets/ /coreos.com/network/subnets/10.200.8.0-24 /coreos.com/network/subnets/10.200.12.0-24 master$ etcdctl get /coreos.com/network/subnets/10.200.8.0-24 {"PublicIP":"178.79.168.130","BackendType":"vxlan","BackendData":{"VtepMAC":"22:ca:ac:15:71:59"}} 

Setelah Anda mendaftarkan konfigurasi yang diinginkan di etcd, Anda perlu mengonfigurasi layanan untuk menjalankannya di masing-masing node yang berfungsi.


layanan flannel


Contoh untuk layanan dapat diambil di sini: systemd / flannel


layanan flannel
 [Unit] Description=Flanneld overlay address etcd agent After=network.target [Service] Type=notify #: current host ip. don't change if ip have not changed Environment=PUBLIC_IP=178.79.168.130 Environment=FLANNEL_ETCD=https://192.168.153.60:2379 ExecStart=/usr/bin/flanneld \ -etcd-endpoints=${FLANNEL_ETCD} -etcd-prefix=${FLANNEL_ETCD_KEY} \ -etcd-cafile=/var/lib/kubernetes/ca.pem \ -etcd-certfile=/var/lib/kubernetes/kubernetes.pem \ -etcd-keyfile=/var/lib/kubernetes/kubernetes-key.pem \ -etcd-prefix=/coreos.com/network \ -healthz-ip=127.0.0.1 \ -subnet-file=/run/flannel/subnet.env \ -public-ip=${PUBLIC_IP} \ -kubeconfig-file=/var/lib/kubernetes/config/kubeconfig/flanneld.kubeconfig \ $FLANNEL_OPTIONS ExecStartPost=/usr/libexec/flannel/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/docker Restart=on-failure RestartSec=5 [Install] RequiredBy=docker.service 

Kustomisasi


Seperti dijelaskan sebelumnya, kita memerlukan file ca.pem, kubernetes.pem dan kubernetes-key.pem untuk otorisasi di etcd. Semua parameter lain tidak memiliki makna suci. Satu-satunya hal yang benar-benar penting adalah mengonfigurasi alamat ip global yang akan digunakan paket jaringan antar jaringan:


Jaringan flanel
( Overlay Jaringan Multi-Host dengan Flanel )


 #:   node-1$ systemctl enable flanneld.service #:  node-1$ systemctl start flanneld 

Setelah flanel mulai berhasil, Anda harus menemukan antarmuka jaringan flanel. N pada sistem Anda:


 node-1$ ifconfig flannel.100: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.200.8.0 netmask 255.255.255.255 broadcast 0.0.0.0 inet6 fe80::20ca:acff:fe15:7159 prefixlen 64 scopeid 0x20<link> ether 22:ca:ac:15:71:59 txqueuelen 0 (Ethernet) RX packets 18853 bytes 1077085 (1.0 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 11856 bytes 264331154 (252.0 MiB) TX errors 0 dropped 47 overruns 0 carrier 0 collisions 0 

Memeriksa bahwa antarmuka Anda berfungsi dengan baik pada semua node cukup sederhana. Dalam kasus saya, masing-masing node-1 dan node-2 memiliki 10.200.8.0/24 dan 10.200.12.0/24, jadi dengan permintaan icmp reguler kami memeriksa ketersediaannya:


 #:  node-2  node-1 node-1 $ ping -c 1 10.200.12.0 PING 10.200.12.0 (10.200.12.0) 56(84) bytes of data. 64 bytes from 10.200.12.0: icmp_seq=1 ttl=64 time=4.58 ms #:  node-1  node-2 node-2 $ ping -c 1 10.200.8.0 PING 10.200.8.0 (10.200.8.0) 56(84) bytes of data. 64 bytes from 10.200.8.0: icmp_seq=1 ttl=64 time=1.44 ms 

Dalam hal terjadi masalah, disarankan untuk memeriksa apakah ada aturan pemotongan di iptables atas UDP antara host.


Konfigurasi Containerd


Tempatkan etc / berisierd / config.toml di /etc/containerd/config.toml atau di tempat yang nyaman bagi Anda, yang utama adalah ingat untuk mengubah jalur ke file konfigurasi dalam layanan (berisi layananerd, layanan yang dijelaskan di bawah).


Konfigurasi dengan beberapa modifikasi standar. Penting untuk tidak mengatur enable_tls_streaming = true jika Anda tidak mengerti mengapa Anda melakukan ini. kubectl exec , .


containerd.service


containerd.service
 [Unit] Description=containerd container runtime Documentation=https://containerd.io After=network.target [Service] ; uncomment this if your overlay module are built as module ; ExecStartPre=/sbin/modprobe overlay ExecStart=/usr/bin/containerd \ -c /etc/containerd/config.toml Restart=always RestartSec=5 Delegate=yes KillMode=process OOMScoreAdjust=-999 LimitNOFILE=1048576 LimitNPROC=infinity LimitCORE=infinity [Install] WantedBy=multi-user.target 

Kustomisasi


, , cri-tools .
etc/crictl.yaml /etc/crictl.yaml . :


 node-1$ CONTAINERD_NAMESPACE=k8s.io crictl ps CONTAINER ID IMAGE CREATED STATE NAME ATTEMPT POD ID 

, - kubernetes , crictl , , .


CNI Plugins


CNI , , , .


Kustomisasi


cni plugins /opt/cni/bin/


/etc/cni/net.d :


/etc/cni/net.d/10-flannel.conflist
 { "cniVersion": "0.3.0", "name": "cbr0", "plugins": [ { "type": "flannel", "name": "kubenet", "delegate": { "hairpinMode": true, "isDefaultGateway": true } }, { "type": "portmap", "capabilities": { "portMappings": true }, "externalSetMarkChain": "KUBE-MARK-MASQ" } ] } 

/etc/cni/net.d/99-loopback.conf
 { "cniVersion": "0.3.0", "type": "loopback" } 

, . , , Red Hat Docker Podman , Intro to Podman


Kubelet


kubelet ( cni) โ€” . kubelet hostname. , "" kubectl logs , kubectl exec , kubectl port-forward .


kubelet-config.yaml

, etc/kubelet-config.yaml , , . :


 systemReserved: cpu: 200m memory: 600Mi 

, GO kubernetes, , . . 0.2 vCPU 600 MB .


, , kubelet, kube-proxy, coredns, flannel . , โ€” 2 vCPU / 4G ram, , kubernetes + postgresql .


- (micro nodes) .


kubelet.service


service : systemd/kubelet


kubelet.service
 [Unit] Description=Kubernetes Kubelet Documentation=https://github.com/kubernetes/kubernetes Requires=containerd.service [Service] #Environment=NODE_IP=192.168.164.230 Environment=NODE_IP=178.79.168.130 #: node name given by env Environment=NODE_NAME=w40k.net ExecStart=kubelet \ --allow-privileged \ --root-dir=/var/lib/kubernetes/kubelet \ --config=/var/lib/kubernetes/kubelet/kubelet-config.yaml \ --kubeconfig=/var/lib/kubernetes/kubelet/node-1.kubeconfig \ --cni-bin-dir=/opt/cni/bin \ --cni-conf-dir=/etc/cni/net.d/ \ --network-plugin=cni \ --container-runtime=remote \ --container-runtime-endpoint=unix:///var/run/containerd/containerd.sock \ --image-pull-progress-deadline=10m \ --node-ip=${NODE_IP} \ --hostname-override=${NODE_NAME} \ --v=1 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target 

Kustomisasi


, RBAC , kubelet.


etc/kubelet-default-rbac.yaml , kubelet :


 user$ kubectl apply -f etc/kubelet-default-rbac.yaml 

, , .


 #:   node-1$ systemctl enable kubelet.service #:  node-1$ systemctl start kubelet 

, api :


 $ kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME w40k.net Ready <none> 5m v1.13.1 178.79.168.130 <none> Gentoo/Linux 4.18.16-x86_64-linode118 containerd://1.2.1 

Kube Proxy


: systemd/kubelet . , , kube-proxy-config.yaml : etc/kube-proxy


kube-proxy.service


kube-proxy.service
 [Unit] Description=Kubernetes Proxy Documentation=https://github.com/kubernetes/kubernetes After=network.target [Service] ExecStart=kube-proxy \ --config=/var/lib/kubernetes/kube-proxy/kube-proxy-config.yaml Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target 

Kustomisasi


 #:   node-1$ systemctl enable kube-proxy.service #:  node-1$ systemctl start kube-proxy 

kube-proxy "" iptables, , - kubernetes (- ). .


CoreDNS


Corefile : etc/coredns/Corefile , :


/etc/coredns/Corefile
 .:53 { errors log stdout health :8081 kubernetes cluster.local 10.200.0.0/16 { endpoint https://178.79.148.185:6443 tls /var/lib/kubernetes/kubernetes.pem /var/lib/kubernetes/kubernetes-key.pem /var/lib/kubernetes/ca.pem pods verified upstream /etc/resolv.conf kubeconfig /var/lib/kubernetes/config/kubeconfig/coredns.kubeconfig default } proxy . /etc/resolv.conf cache 30 } 

coredns.kubeconfig pem- ( ) worker . , coredns systemd-resolved. , Ubuntu , , , , . .


coredns.service


coredns.service
 [Unit] Description=CoreDNS Documentation=https://coredns.io/ After=network.target [Service] ExecStart=/usr/bin/coredns -conf /etc/coredns/Corefile Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target 

Kustomisasi


 #:   node-1$ systemctl enable coredns.service #:  node-1$ systemctl start coredns 

, , :


 node-1$ dig kubernetes.default.svc.cluster.local @127.0.0.1 #:    ;kubernetes.default.svc.cluster.local. IN A ;; ANSWER SECTION: kubernetes.default.svc.cluster.local. 5 IN A 10.32.0.1 

, coredns ip kubernetes .
, kubernetes.default kube-controller-manager, :


 $ kubectl get svc -n default NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.32.0.1 <none> 443/TCP 26h 

nginx-ingress & cert-manager


, . nginx-ingress cert-manager.


โ€” nginx kubernetes ingress (master), :


  user$ git clone https://github.com/nginxinc/kubernetes-ingress.git user$ cd kubernetes-ingress/deployments user$ kubectl apply -f common/ns-and-sa.yaml user$ kubectl apply -f common/nginx-config.yaml user$ kubectl apply -f common/default-server-secret.yaml user$ kubectl apply -f daemon-set/nginx-ingress.yaml user$ kubectl apply -f rbac/rbac.yaml 

โ€” cert manager (v0.5.2)


  user$ git clone https://github.com/jetstack/cert-manager.git user$ cd cert-manager && git co v0.5.2 user$ cd contrib/manifests/cert-manager user$ kubectl apply -f with-rbac.yaml 

, , , :


 NAMESPACE NAME READY STATUS RESTARTS AGE cert-manager cert-manager-554c76fbb7-t9762 1/1 Running 0 3h38m nginx-ingress nginx-ingress-sdztf 1/1 Running 0 10h nginx-ingress nginx-ingress-vrf85 1/1 Running 0 10h 

cert-manager nginx-ingress running state, , . , Running . .



, . , kubernetes resource : app/k8s


 user$ kube apply -f ns-and-sa.yaml user$ kube apply -f configmap.yaml #:  secret-example.yaml       #: secret.yaml user$ kube apply -f secret.yaml user$ kube apply -f tls-production.yaml user$ kube apply -f deployment.yaml user$ kube apply -f service.yaml user$ kube apply -f ingress-production.yaml 

, - . , ( kubernetes-example.w40k.net), , , cert-manager nginx-ingress . , ingress tls/ssl.


:



, - . - , , .


Referensi


, , :


โ€” Kubernetes the hard way
โ€” Multi-Host Networking Overlay with Flannel
โ€” Intro to Podman
โ€” Stateless Applications
โ€” What is ingress


:


โ€” Kubernetes Networking: Behind the scenes ( )
โ€” A Guide to the Kubernetes Networking Model
โ€” Understanding kubernetes networking: services ( )


Q&A


<tbd>, .



, , . , , - , , .


Api Server


kube-apiserver.service , api-server' curl http . - .
admin.kubeconfig ${HOME}/.kube/config, kubectl api-server (kube-apiserver).


( ) HTTP 200 OK + , api-server :


 curl -H "Authorization: Bearer e5qXNAtwwCHUUwyLilZmAoFPozrQwUpw" -k -L https://<api-server-address>:6443/api/v1/ 

Kube Controller Manager


, controller manager api , . , service account' :


 $ kubectl get sa NAME SECRETS AGE default 1 19h 

, , kube-controller-manager .


Kube Scheduler


. , , debug/job.yaml kubectl describe <type/resource> .
, kube controller manager .


 #:   job user$ kubectl apply -f debug/job.yaml job.batch/app created #:  ,   job user$ kubectl get pods -l job-name=app NAME READY STATUS RESTARTS AGE app-9kr9z 0/1 Completed 0 54s #: ,        #:   user$ kubectl describe pods app-9kr9z # ...   ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 12s default-scheduler Successfully assigned example/app-9kr9z to w40k.net 

, default-scheduler pod w40k.net. - , โ€” .


. , , , โ€” "". systemd .


kube scheduler


Kubelet


Kubelet kubernetes . kubelet . kubernetes event ( kubectl get events -o wide ) .


( )


Kube Proxy


kube-proxy :


  • ( Flannel , );
  • iptables, filter nat .

, 10.32.0.0/24 "". , . iptables, , , - +. icmp , ping' . , .


, kube-proxy, :


 #:    user$ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE backend ClusterIP 10.32.0.195 <none> 80/TCP 5m #:     user$ kubectl get pods -o wide #:     ' NAME READY STATUS RESTARTS AGE IP NODE backend-896584448-4r94s 1/1 Running 0 11h 10.200.8.105 w40k.net backend-896584448-np992 1/1 Running 0 11h 10.200.12.68 docker.grart.net #:  10   /status/ endpoint ,       #:       node-1$ for i in `seq 10`; do curl -L http://10.32.0.195/status/; done okokokokokokokokokok node-1$ conntrack -L -d 10.32.0.195 tcp 6 62 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62158 dport=80 src=10.200.12.68 dst=10.200.8.0 sport=8000 dport=62158 [ASSURED] mark=0 use=1 tcp 6 60 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62144 dport=80 src=10.200.12.68 dst=10.200.8.0 sport=8000 dport=62144 [ASSURED] mark=0 use=1 tcp 6 58 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62122 dport=80 src=10.200.12.68 dst=10.200.8.0 sport=8000 dport=62122 [ASSURED] mark=0 use=1 tcp 6 59 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62142 dport=80 src=10.200.8.105 dst=10.200.8.1 sport=8000 dport=62142 [ASSURED] mark=0 use=1 tcp 6 58 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62130 dport=80 src=10.200.8.105 dst=10.200.8.1 sport=8000 dport=62130 [ASSURED] mark=0 use=1 tcp 6 61 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62150 dport=80 src=10.200.12.68 dst=10.200.8.0 sport=8000 dport=62150 [ASSURED] mark=0 use=1 tcp 6 56 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62116 dport=80 src=10.200.8.105 dst=10.200.8.1 sport=8000 dport=62116 [ASSURED] mark=0 use=1 tcp 6 57 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62118 dport=80 src=10.200.12.68 dst=10.200.8.0 sport=8000 dport=62118 [ASSURED] mark=0 use=1 tcp 6 59 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62132 dport=80 src=10.200.12.68 dst=10.200.8.0 sport=8000 dport=62132 [ASSURED] mark=0 use=1 tcp 6 56 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62114 dport=80 src=10.200.8.105 dst=10.200.8.1 sport=8000 dport=62114 [ASSURED] mark=0 use=1 

src/dst (9 10 ). , src :


  • 10.200.8.105
  • 10.200.12.68

, . , - ( , ) . .


 #: node-1   10.200.8.105, node-2 10.200.12.68, #:      8000  #:  node-1 node-1$ curl -L http://10.200.8.105:8000/status/ ok node-1$ curl -L http://10.200.12.68:8000/status/ ok #:  node-2 node-2$ curl -L http://10.200.8.105:8000/status/ ok node-2$ curl -L http://10.200.12.68:8000/status/ ok 

, , conntrack , , kube-proxy. , nat :


node-1$ iptables -t nat -vnL


.


. , , . , . - , , .


Source: https://habr.com/ru/post/id435228/


All Articles