Halaman ini menunjukkan cara menyelesaikan masalah pada penjadwal Kubernetes
(kube-scheduler
) untuk Google Distributed Cloud.
Kubernetes selalu menjadwalkan Pod ke kumpulan node yang sama
Error ini dapat diamati dengan beberapa cara:
Pemanfaatan cluster yang tidak seimbang. Anda dapat memeriksa pemanfaatan cluster untuk setiap Node dengan perintah
kubectl top nodes
. Hal berikut yang dilebih-lebihkan contoh output menunjukkan pemakaian yang jelas pada Node tertentu:NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% XXX.gke.internal 222m 101% 3237Mi 61% YYY.gke.internal 91m 0% 2217Mi 0% ZZZ.gke.internal 512m 0% 8214Mi 0%
Terlalu banyak permintaan. Jika Anda menjadwalkan banyak Pod sekaligus pada Node dan Pod tersebut membuat permintaan HTTP, node dapat diberi rating secara terbatas. Error umum yang ditampilkan oleh server dalam skenario ini adalah
429 Too Many Requests
.Layanan tidak tersedia. Server web, misalnya, dihosting di {i>Node<i} di bawah {i>high<i} pemuatan mungkin merespons semua permintaan dengan
503 Service Unavailable
error sampai karena bebannya lebih ringan.
Untuk memeriksa apakah Anda memiliki Pod yang selalu dijadwalkan ke node yang sama, gunakan metode langkah-langkah berikut:
Jalankan perintah
kubectl
berikut untuk melihat status Pod:kubectl get pods -o wide -n default
Untuk melihat distribusi Pod di seluruh Node, periksa kolom
NODE
di {i>output<i} tersebut. Pada contoh output berikut, semua Pod dijadwalkan di Node yang sama:NAME READY STATUS RESTARTS AGE IP NODE nginx-deployment-84c6674589-cxp55 1/1 Running 0 55s 10.20.152.138 10.128.224.44 nginx-deployment-84c6674589-hzmnn 1/1 Running 0 55s 10.20.155.70 10.128.226.44 nginx-deployment-84c6674589-vq4l2 1/1 Running 0 55s 10.20.225.7 10.128.226.44
Pod memiliki sejumlah fitur yang dapat Anda gunakan untuk menyesuaikan penjadwalannya
perilaku model. Fitur ini mencakup batasan penyebaran topologi dan anti-afinitas
aturan. Anda dapat menggunakan salah satu, atau kombinasi, fitur-fitur ini. Persyaratan
yang Anda tentukan adalah AND disatukan oleh kube-scheduler
.
Log penjadwal tidak direkam di tingkat verbositas logging default. Jika Anda memerlukan log penjadwal untuk pemecahan masalah, lakukan langkah-langkah berikut ambil log penjadwal:
Meningkatkan level panjang logging:
Edit Deployment
kube-scheduler
:kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG edit deployment kube-scheduler \ -n USER_CLUSTER_NAMESPACE
Tambahkan tanda
--v=5
di bawah bagianspec.containers.command
:containers: - command: - kube-scheduler - --profiling=false - --kubeconfig=/etc/kubernetes/scheduler.conf - --leader-elect=true - --v=5
Setelah selesai memecahkan masalah, reset tingkat verbositas kembali ke tingkat default:
Edit Deployment
kube-scheduler
:kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG edit deployment kube-scheduler \ -n USER_CLUSTER_NAMESPACE
Setel kembali tingkat verbositas ke nilai default:
containers: - command: - kube-scheduler - --profiling=false - --kubeconfig=/etc/kubernetes/scheduler.conf - --leader-elect=true
Batasan penyebaran topologi
Batasan penyebaran topologi
dapat digunakan untuk mendistribusikan Pod secara merata di antara Node sesuai dengan zones
-nya,
regions
, node
, atau topologi lain yang ditentukan secara khusus.
Contoh manifes berikut menunjukkan Deployment yang menyebarkan replika secara merata di antara semua Node yang dapat dijadwalkan menggunakan batasan penyebaran topologi:
apiVersion: apps/v1
kind: Deployment
metadata:
name: topology-spread-deployment
labels:
app: myapp
spec:
replicas: 30
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
topologySpreadConstraints:
- maxSkew: 1 # Default. Spreads evenly. Maximum difference in scheduled Pods per Node.
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule # Default. Alternatively can be ScheduleAnyway
labelSelector:
matchLabels:
app: myapp
matchLabelKeys: # beta in 1.27
- pod-template-hash
containers:
# pause is a lightweight container that simply sleeps
- name: pause
image: registry.k8s.io/pause:3.2
Pertimbangan berikut berlaku saat menggunakan batasan penyebaran topologi:
labels.app: myapp
Pod dicocokkan denganlabelSelector
batasan.topologyKey
menentukankubernetes.io/hostname
. Label ini secara otomatis terhubung ke semua Node dan diisi dengan nama host Node.matchLabelKeys
mencegah peluncuran Deployment baru agar tidak mempertimbangkan Pod revisi lama saat menghitung lokasi untuk menjadwalkan Pod. Tujuan Labelpod-template-hash
secara otomatis diisi oleh Deployment.
Anti-afinitas Pod
Anti-afinitas pod dapat digunakan untuk menentukan batasan agar Pod dapat ditempatkan bersama di Node yang sama.
Contoh manifes berikut menunjukkan Deployment yang menggunakan anti-afinitas untuk membatasi replika ke satu Pod per Node:
apiVersion: apps/v1
kind: Deployment
metadata:
name: pod-affinity-deployment
labels:
app: myapp
spec:
replicas: 30
selector:
matchLabels:
app: myapp
template:
metadata:
name: with-pod-affinity
labels:
app: myapp
spec:
affinity:
podAntiAffinity:
# requiredDuringSchedulingIgnoredDuringExecution
# prevents Pod from being scheduled on a Node if it
# does not meet criteria.
# Alternatively can use 'preferred' with a weight
# rather than 'required'.
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- myapp
# Your nodes might be configured with other keys
# to use as `topologyKey`. `kubernetes.io/region`
# and `kubernetes.io/zone` are common.
topologyKey: kubernetes.io/hostname
containers:
# pause is a lightweight container that simply sleeps
- name: pause
image: registry.k8s.io/pause:3.2
Contoh Deployment ini menetapkan replika 30
, tetapi hanya diperluas ke banyak Node yang
yang tersedia di cluster Anda.
Pertimbangan berikut berlaku saat menggunakan anti-afinitas Pod:
labels.app: myapp
Pod dicocokkan denganlabelSelector
batasan.topologyKey
menentukankubernetes.io/hostname
. Label ini secara otomatis terhubung ke semua Node dan diisi dengan nama host Node. Anda dapat memilih untuk menggunakan label lain jika cluster mendukungnya, sepertiregion
atauzone
.
Gambar container pra-tarik
Jika tidak ada batasan lainnya, kube-scheduler
akan memilih untuk secara default
menjadwalkan Pod di Node yang sudah mendownload image container
mereka. Perilaku ini mungkin menarik bagi klaster
yang lebih kecil tanpa faktor
konfigurasi penjadwalan yang memungkinkan
untuk mengunduh gambar pada
setiap Node. Namun, mengandalkan konsep ini harus dianggap sebagai upaya terakhir. J
solusi yang lebih baik adalah menggunakan nodeSelector
, batasan penyebaran topologi, atau
afinitas / anti-afinitas. Untuk informasi selengkapnya, lihat
Menetapkan Pod ke Node.
Jika ingin memastikan bahwa image container sudah
ditarik ke semua Node, Anda
dapat menggunakan DaemonSet
seperti contoh berikut:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: prepulled-images
spec:
selector:
matchLabels:
name: prepulled-images
template:
metadata:
labels:
name: prepulled-images
spec:
initContainers:
- name: prepulled-image
image: IMAGE
# Use a command the terminates immediately
command: ["sh", "-c", "'true'"]
containers:
# pause is a lightweight container that simply sleeps
- name: pause
image: registry.k8s.io/pause:3.2
Setelah Pod berada di Running
di semua Node, deploy ulang Pod Anda lagi untuk melihat apakah
container kini didistribusikan secara merata di seluruh Node.