Halaman ini menunjukkan cara menonaktifkan port hanya baca kubelet yang tidak aman di cluster Google Kubernetes Engine (GKE) untuk mengurangi risiko akses tidak sah ke kubelet, dan cara memigrasikan aplikasi ke port yang lebih aman.
Di cluster Kubernetes, termasuk GKE, proses kubelet
yang berjalan di node menayangkan API hanya baca menggunakan port 10255
yang tidak aman.
Kubernetes tidak melakukan pemeriksaan autentikasi atau otorisasi apa pun pada
port ini. Kubelet menayangkan endpoint yang sama di port 10250
yang lebih aman dan diautentikasi.
Nonaktifkan port hanya baca kubelet dan alihkan workload apa pun yang menggunakan port
10255
untuk menggunakan port 10250
yang lebih aman.
Sebelum memulai
Sebelum memulai, pastikan Anda telah menjalankan tugas berikut:
- Aktifkan Google Kubernetes Engine API. Aktifkan Google Kubernetes Engine API
- Jika ingin menggunakan Google Cloud CLI untuk tugas ini,
instal lalu
lakukan inisialisasi
gcloud CLI. Jika sebelumnya Anda telah menginstal gcloud CLI, dapatkan versi terbaru dengan menjalankan
gcloud components update
.
Persyaratan
- Anda hanya dapat menonaktifkan port hanya baca kubelet yang tidak aman di GKE versi 1.26.4-gke.500 atau yang lebih baru.
Memeriksa penggunaan port yang tidak aman dan memigrasikan aplikasi
Sebelum menonaktifkan port hanya baca yang tidak aman, migrasikan aplikasi yang sedang berjalan yang menggunakan port ke port hanya baca yang lebih aman. Workload yang mungkin memerlukan migrasi mencakup pipeline metrik kustom dan workload yang mengakses endpoint kubelet.
- Untuk beban kerja yang memerlukan akses ke informasi yang ditayangkan oleh kubelet API
di node, seperti metrik, gunakan port
10250
. - Untuk workload yang mendapatkan informasi Kubernetes menggunakan kubelet API di node, seperti mencantumkan Pod di node, gunakan Kubernetes API.
Memeriksa apakah aplikasi menggunakan port hanya baca kubelet yang tidak aman
Bagian ini menunjukkan cara memeriksa penggunaan port yang tidak aman di cluster Anda.
Memeriksa penggunaan port pada mode Autopilot
Untuk memeriksa penggunaan port di cluster Autopilot, pastikan Anda memiliki setidaknya satu workload yang bukan DaemonSet yang berjalan di cluster. Jika Anda melakukan langkah-langkah berikut pada cluster Autopilot kosong, hasilnya mungkin tidak valid.
Simpan manifes berikut sebagai
read-only-port-metrics.yaml
:apiVersion: v1 kind: Namespace metadata: name: node-metrics-printer-namespace --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: node-metrics-printer-role rules: - apiGroups: - "" resources: - nodes/metrics verbs: - get --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: node-metrics-printer-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: node-metrics-printer-role subjects: - kind: ServiceAccount name: node-metrics-printer-sa namespace: node-metrics-printer-namespace --- apiVersion: v1 kind: ServiceAccount metadata: name: node-metrics-printer-sa namespace: node-metrics-printer-namespace --- apiVersion: apps/v1 kind: DaemonSet metadata: name: node-metrics-printer namespace: node-metrics-printer-namespace spec: selector: matchLabels: app: node-metrics-printer template: metadata: labels: app: node-metrics-printer spec: serviceAccountName: node-metrics-printer-sa containers: - name: metrics-printer image: us-docker.pkg.dev/cloud-builders/ga/v1/curl:latest command: ["sh", "-c"] args: - 'while true; do curl -s --cacert "${CA_CERT}" -H "Authorization: Bearer $(cat ${TOKEN_FILE})" "https://${NODE_ADDRESS}:10250/metrics"|grep kubelet_http_requests_total; sleep 20; done' env: - name: CA_CERT value: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - name: TOKEN_FILE value: /var/run/secrets/kubernetes.io/serviceaccount/token - name: NODE_ADDRESS valueFrom: fieldRef: fieldPath: status.hostIP
Manifes ini melakukan hal berikut:
- Membuat namespace dan menyiapkan peran RBAC untuk mengizinkan metrik node dibaca.
- Men-deploy DaemonSet yang memeriksa metrik kubelet untuk port hanya baca yang tidak aman.
Deploy manifes:
kubectl create -f read-only-port-metrics.yaml
Periksa log DaemonSet:
kubectl logs --namespace=node-metrics-printer-namespace \ --all-containers --prefix \ --selector=app=node-metrics-printer
Jika output memiliki hasil yang berisi string
server_type=readonly
, aplikasi menggunakan port hanya baca yang tidak aman.
Memeriksa penggunaan port pada mode Standar
Jalankan perintah berikut di setidaknya satu node di setiap node pool dalam cluster Anda:
kubectl get --raw /api/v1/nodes/NODE_NAME/proxy/metrics | grep http_requests_total | grep readonly
Ganti NODE_NAME
dengan nama node.
Jika output berisi entri dengan string server_type="readonly"
, skenario berikut dapat terjadi:
- Workload di node menggunakan port hanya baca kubelet yang tidak aman.
- Setelah menonaktifkan port yang tidak aman, perintah masih menampilkan string
server_type="readonly"
. Hal ini karena metrikkubelet_http_requests_total
mewakili jumlah kumulatif permintaan HTTP yang diterima oleh server kubelet sejak mulai ulang terakhirnya. Nomor ini tidak direset saat port tidak aman dinonaktifkan. Jumlah ini direset setelah GKE memulai ulang server kubelet, seperti selama upgrade node. Untuk mempelajari lebih lanjut, lihat Referensi Metrik Kubernetes.
Jika outputnya kosong, tidak ada workload di node tersebut yang menggunakan port hanya baca yang tidak aman.
Mengidentifikasi workload yang menggunakan port hanya baca kubelet yang tidak aman
Untuk mengidentifikasi beban kerja yang menggunakan port tidak aman, periksa file konfigurasi beban kerja seperti ConfigMaps dan Pod.
Jalankan perintah berikut:
kubectl get pods --all-namespaces -o yaml | grep 10255
kubectl get configmaps --all-namespaces -o yaml | grep 10255
Jika output perintah tidak kosong, gunakan skrip berikut untuk mengidentifikasi nama ConfigMap atau Pod yang menggunakan port tidak aman:
# This function checks if a Kubernetes resource is using the insecure port 10255.
#
# Arguments:
# $1 - Resource type (e.g., pod, configmap, )
# $2 - Resource name
# $3 - Namespace
#
# Output:
# Prints a message indicating whether the resource is using the insecure port.
isUsingInsecurePort() {
resource_type=$1
resource_name=$2
namespace=$3
config=$(kubectl get $resource_type $resource_name -n $namespace -o yaml)
# Check if kubectl output is empty
if [[ -z "$config" ]]; then
echo "No configuration file detected for $resource_type: $resource_name (Namespace: $namespace)"
return
fi
if echo "$config" | grep -q "10255"; then
echo "Warning: The configuration file ($resource_type: $namespace/$resource_name) is using insecure port 10255. It is recommended to migrate to port 10250 for enhanced security."
else
echo "Info: The configuration file ($resource_type: $namespace/$resource_name) is not using insecure port 10255."
fi
}
# Get the list of ConfigMaps with their namespaces
configmaps=$(kubectl get configmaps -A -o custom-columns=NAMESPACE:.metadata.namespace,NAME:.metadata.name | tail -n +2 | awk '{print $1"/"$2}')
# Iterate over each ConfigMap
for configmap in $configmaps; do
namespace=$(echo $configmap | cut -d/ -f1)
configmap_name=$(echo $configmap | cut -d/ -f2)
isUsingInsecurePort "configmap" "$configmap_name" "$namespace"
done
# Get the list of Pods with their namespaces
pods=$(kubectl get pods -A -o custom-columns=NAMESPACE:.metadata.namespace,NAME:.metadata.name | tail -n +2 | awk '{print $1"/"$2}')
# Iterate over each Pod
for pod in $pods; do
namespace=$(echo $pod | cut -d/ -f1)
pod_name=$(echo $pod | cut -d/ -f2)
isUsingInsecurePort "pod" "$pod_name" "$namespace"
done
Setelah mengidentifikasi workload yang relevan, migrasikan workload tersebut untuk menggunakan port aman 10250 dengan menyelesaikan langkah-langkah di bagian berikut.
Bermigrasi dari port hanya baca kubelet yang tidak aman
Biasanya, memigrasikan aplikasi ke port aman melibatkan langkah-langkah berikut:
Perbarui URL atau endpoint yang merujuk ke port hanya baca yang tidak aman untuk menggunakan port hanya baca yang aman. Misalnya, ubah
http://203.0.113.104:10255
menjadihttp://203.0.113.104:10250
.Tetapkan sertifikat certificate authority (CA) klien HTTP ke sertifikat CA cluster. Untuk menemukan sertifikat ini, jalankan perintah berikut:
gcloud container clusters describe CLUSTER_NAME \ --location=LOCATION \ --format="value(masterAuth.clusterCaCertificate)"
Ganti kode berikut:
CLUSTER_NAME
: nama cluster Anda.LOCATION
: lokasi cluster Anda.
Port 10250
yang diautentikasi mengharuskan Anda memberikan peran RBAC
yang sesuai kepada subjek untuk mengakses resource tertentu. Untuk mengetahui detailnya, dalam
dokumentasi Kubernetes, lihat
otorisasi kubelet.
/pods
di port hanya baca kubelet
yang tidak aman, Anda harus memberikan izin RBAC nodes/proxy
untuk mengakses endpoint
di port kubelet yang aman. nodes/proxy
adalah izin canggih yang tidak dapat Anda berikan di cluster GKE Autopilot dan tidak boleh Anda berikan di cluster GKE Standard. Sebagai gantinya, gunakan
Kubernetes API dengan fieldSelector
untuk nama node.
Jika Anda menggunakan aplikasi pihak ketiga yang bergantung pada port hanya baca kubelet
yang tidak aman, hubungi vendor aplikasi untuk mendapatkan petunjuk guna bermigrasi
ke port 10250
yang aman.
Contoh migrasi
Pertimbangkan Pod yang mengkueri metrik dari port hanya baca kubelet yang tidak aman.
apiVersion: v1
kind: Pod
metadata:
name: kubelet-readonly-example
spec:
restartPolicy: Never
containers:
- name: kubelet-readonly-example
image: us-docker.pkg.dev/cloud-builders/ga/v1/curl:latest
command:
- curl
- http://$(NODE_ADDRESS):10255/metrics
env:
- name: NODE_ADDRESS
valueFrom:
fieldRef:
fieldPath: status.hostIP
Aplikasi ini melakukan hal berikut:
- Menggunakan ServiceAccount
default
di namespacedefault
- Menjalankan perintah
curl
terhadap endpoint/metrics
di node.
Untuk mengupdate Pod ini agar menggunakan port aman 10250
, lakukan langkah-langkah berikut:
Buat ClusterRole dengan akses untuk mendapatkan metrik node:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: curl-authenticated-role rules: - apiGroups: - "" resources: - nodes/metrics verbs: - get
Ikat ClusterRole ke identitas aplikasi Anda:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: curl-authenticated-role-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: curl-authenticated-role subjects: - kind: ServiceAccount name: default namespace: default
Perbarui perintah
curl
untuk menggunakan endpoint port aman dengan header otorisasi yang sesuai:apiVersion: v1 kind: Pod metadata: name: kubelet-authenticated-example spec: restartPolicy: Never containers: - name: kubelet-readonly-example image: us-docker.pkg.dev/cloud-builders/ga/v1/curl:latest env: - name: NODE_ADDRESS valueFrom: fieldRef: fieldPath: status.hostIP command: - sh - -c - 'curl -s --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://${NODE_ADDRESS}:10250/metrics'
Mengubah aturan firewall VPC
Jika Anda mengupdate workload untuk menggunakan port 10250
, buat aturan firewall agar Pod di cluster dapat menjangkau port dalam rentang alamat IP node Anda. Aturan
firewall harus melakukan hal berikut:
- Izinkan traffic masuk ke port TCP
10250
pada rentang alamat IP node Anda dari rentang alamat IP Pod internal - Tolak traffic masuk ke port TCP
10250
pada rentang alamat IP node Anda dari internet publik.
Anda dapat menggunakan aturan firewall GKE default berikut sebagai template untuk parameter yang akan ditentukan dalam aturan baru Anda:
gke-[cluster-name]-[cluster-hash]-inkubelet
gke-[cluster-name]-[cluster-hash]-exkubelet
Menonaktifkan port hanya baca yang tidak aman di cluster Autopilot
Anda dapat menonaktifkan port hanya baca kubelet yang tidak aman untuk cluster Autopilot baru dan yang sudah ada.
Menonaktifkan port hanya baca yang tidak aman di cluster Autopilot baru
Untuk menonaktifkan port hanya baca kubelet yang tidak aman saat Anda membuat cluster Autopilot baru, gunakan flag --no-autoprovisioning-enable-insecure-kubelet-readonly-port
, seperti dalam perintah berikut:
gcloud container clusters create-auto CLUSTER_NAME \
--location=LOCATION \
--no-autoprovisioning-enable-insecure-kubelet-readonly-port
Ganti kode berikut:
CLUSTER_NAME
: nama cluster Autopilot baru Anda.LOCATION
: lokasi cluster Autopilot baru Anda.
Menonaktifkan port hanya baca yang tidak aman di cluster Autopilot yang ada
Untuk menonaktifkan port hanya baca kubelet yang tidak aman di cluster Autopilot
yang ada, gunakan
tanda --no-autoprovisioning-enable-insecure-kubelet-readonly-port
, seperti dalam
perintah berikut. Semua node baru dan yang sudah ada di cluster berhenti menggunakan
port.
gcloud container clusters update CLUSTER_NAME \
--location=LOCATION \
--no-autoprovisioning-enable-insecure-kubelet-readonly-port
Ganti kode berikut:
CLUSTER_NAME
: nama cluster yang ada.LOCATION
: lokasi cluster yang ada.
Menonaktifkan port hanya baca yang tidak aman di cluster Standard
Anda dapat menonaktifkan port hanya baca kubelet yang tidak aman untuk seluruh cluster Standard atau untuk setiap node pool. Sebaiknya nonaktifkan port untuk seluruh cluster.
Jika Anda menggunakan penyediaan otomatis node, node pool yang disediakan otomatis akan mewarisi setelan port yang Anda tentukan di tingkat cluster. Secara opsional, Anda dapat menentukan setelan yang berbeda untuk node pool yang disediakan otomatis, tetapi sebaiknya nonaktifkan port di semua node dalam cluster Anda.
Anda juga dapat menggunakan file konfigurasi sistem node untuk menonaktifkan port hanya baca kubelet yang tidak aman secara deklaratif. Jika menggunakan file ini, Anda tidak dapat menggunakan perintah di bagian berikut untuk mengontrol setelan kubelet.
Menonaktifkan port hanya baca yang tidak aman di cluster Standard baru
Untuk menonaktifkan port hanya baca kubelet yang tidak aman di cluster Standar
baru, gunakan flag --no-enable-insecure-kubelet-readonly-port
seperti dalam
perintah berikut:
gcloud container clusters create CLUSTER_NAME \
--location=LOCATION \
--no-enable-insecure-kubelet-readonly-port
Ganti kode berikut:
CLUSTER_NAME
: nama cluster Standard yang baru.LOCATION
: lokasi cluster Standard yang baru.
Anda dapat menambahkan flag --no-autoprovisioning-enable-insecure-kubelet-readonly-port
secara opsional untuk mengontrol setelan penyediaan otomatis node secara terpisah, tetapi sebaiknya jangan gunakan pendekatan ini.
Flag ini memulai update bertahap pada node pool yang disediakan otomatis, yang
dapat menyebabkan gangguan pada workload yang sedang berjalan.
Menonaktifkan port hanya baca yang tidak aman di cluster Standard yang ada
Untuk menonaktifkan port hanya baca kubelet yang tidak aman di cluster Standar yang ada, gunakan flag --no-enable-insecure-kubelet-readonly-port
seperti dalam perintah berikut. Semua node pool baru tidak akan menggunakan port yang tidak aman.
GKE tidak otomatis mengupdate node pool yang ada.
gcloud container clusters update CLUSTER_NAME \
--location=LOCATION \
--no-enable-insecure-kubelet-readonly-port
Ganti kode berikut:
CLUSTER_NAME
: nama cluster Standard yang ada.LOCATION
: lokasi cluster Standar yang ada.
Menonaktifkan port hanya baca yang tidak aman di node pool Standar
Sebaiknya tetapkan setelan port hanya baca di tingkat cluster dalam semua kasus. Jika Anda menonaktifkan port hanya baca di cluster yang sudah ada dan sudah menjalankan node pool, gunakan perintah berikut untuk menonaktifkan port di node pool tersebut.
gcloud container node-pools update NODE_POOL_NAME \
--cluster=CLUSTER_NAME \
--location=LOCATION \
--no-enable-insecure-kubelet-readonly-port
Ganti kode berikut:
NODE_POOL_NAME
: nama node pool Anda.CLUSTER_NAME
: nama cluster.LOCATION
: lokasi cluster.
Memastikan port dinonaktifkan
Untuk memverifikasi bahwa port hanya baca kubelet yang tidak aman dinonaktifkan, deskripsikan resource GKE.
Memeriksa status port di cluster Autopilot
Jalankan perintah berikut:
gcloud container clusters describe CLUSTER_NAME \
--location=LOCATION \
--flatten=nodePoolAutoConfig \
--format="value(nodeKubeletConfig)"
Ganti kode berikut:
CLUSTER_NAME
: nama cluster Autopilot Anda.LOCATION
: lokasi cluster Autopilot Anda.
Jika port dinonaktifkan, output-nya adalah sebagai berikut:
insecureKubeletReadonlyPortEnabled: false
Memeriksa status port di cluster Standard
Status port tersedia di kolom nodePoolDefaults.nodeConfigDefaults.nodeKubeletConfig
saat Anda mendeskripsikan cluster menggunakan GKE API.
Di cluster Standar, Anda juga akan melihat kolom nodeConfig
yang menetapkan
nilai untuk status port hanya baca kubelet. Kolom nodeConfig
tidak digunakan lagi dan hanya berlaku untuk node pool default yang dibuat GKE saat Anda membuat cluster mode Standar baru. Status
port di kolom nodeConfig
yang tidak digunakan lagi tidak berlaku untuk node pool lain
di cluster.
Jalankan perintah berikut:
gcloud container clusters describe CLUSTER_NAME \
--location=LOCATION \
--flatten=nodePoolDefaults.nodeConfigDefaults \
--format="value(nodeKubeletConfig)"
Ganti kode berikut:
CLUSTER_NAME
: nama cluster Standard Anda.LOCATION
: lokasi cluster Standar Anda.
Jika port dinonaktifkan, output-nya adalah sebagai berikut:
insecureKubeletReadonlyPortEnabled: false
Memeriksa status port di node pool Standar
Jalankan perintah berikut:
gcloud container node-pools describe NODE_POOL_NAME \
--cluster=CLUSTER_NAME \
--location=LOCATION \
--flatten=config \
--format="value(kubeletConfig)"
Ganti kode berikut:
NODE_POOL_NAME
: nama node pool Anda.CLUSTER_NAME
: nama cluster.LOCATION
: lokasi cluster.
Jika port dinonaktifkan, output-nya adalah sebagai berikut:
insecureKubeletReadonlyPortEnabled: false