Esta página mostra como desativar a porta só de leitura do kubelet não segura em clusters do Google Kubernetes Engine (GKE) para reduzir o risco de acesso não autorizado ao kubelet e como migrar aplicações para uma porta mais segura.
Nos clusters do Kubernetes, incluindo o GKE, o processo kubelet
em execução nos nós disponibiliza uma API só de leitura através da porta não segura 10255
.
O Kubernetes não realiza verificações de autenticação nem autorização nesta porta. O kubelet serve os mesmos pontos finais na porta 10250
autenticada e mais segura.
Desative a porta só de leitura do kubelet e mude todas as cargas de trabalho que usam a porta
10255
para usar a porta mais segura 10250
.
Antes de começar
Antes de começar, certifique-se de que realizou as seguintes tarefas:
- Ative a API Google Kubernetes Engine. Ative a API Google Kubernetes Engine
- Se quiser usar a CLI gcloud para esta tarefa,
instale-a e, em seguida,
inicialize-a. Se instalou anteriormente a CLI gcloud, execute
gcloud components update
para obter a versão mais recente.
- Certifique-se de que tem um cluster do Autopilot ou Standard existente. Para criar um novo cluster, consulte o artigo Crie um cluster do Autopilot.
Requisitos
- Só pode desativar a porta só de leitura do kubelet não segura no GKE versão 1.26.4-gke.500 ou posterior.
Verifique a utilização de portas não seguras e migre aplicações
Antes de desativar a porta de leitura apenas insegura, migre todas as aplicações em execução que usam a porta para a porta de leitura apenas mais segura. As cargas de trabalho que podem precisar de migração incluem pipelines de métricas personalizadas e cargas de trabalho que acedem a endpoints kubelet.
- Para cargas de trabalho que precisam de acesso às informações disponibilizadas pela API kubelet no nó, como métricas, use a porta
10250
. - Para cargas de trabalho que recebem informações do Kubernetes através da API kubelet no nó, como a listagem de pods no nó, use a API Kubernetes.
Verifique se as aplicações usam a porta só de leitura do kubelet insegura
Esta secção mostra-lhe como verificar a utilização de portas não seguras no seu cluster.
Verifique a utilização de portas no modo de piloto automático
Para verificar a utilização de portas num cluster do Autopilot, certifique-se de que tem, pelo menos, uma carga de trabalho que não seja um DaemonSet em execução no cluster. Se executar os seguintes passos num cluster do Autopilot vazio, os resultados podem ser inválidos.
Guarde o seguinte manifesto como
read-only-port-metrics.yaml
:# Create a namespace for the DaemonSet that checks for port usage. apiVersion: v1 kind: Namespace metadata: name: node-metrics-printer-namespace --- # Grant access to read node metrics in the cluster. 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 # Bind the ClusterRole to the ServiceAccount that the DaemonSet will use. subjects: - kind: ServiceAccount name: node-metrics-printer-sa namespace: node-metrics-printer-namespace --- # Create a ServiceAccount for the DaemonSet. 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: # Assign the ServiceAccount to the DaemonSet. serviceAccountName: node-metrics-printer-sa containers: - name: metrics-printer image: us-docker.pkg.dev/cloud-builders/ga/v1/curl:latest command: ["sh", "-c"] # Call the /metrics endpoint using the insecure kubelet read-only # port. 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: # Provide credentials and the IP address for the command. - 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
Este manifesto faz o seguinte:
- Cria um espaço de nomes e configura funções RBAC para permitir a leitura de métricas de nós.
- Implementa um DaemonSet que verifica as métricas do kubelet para a porta só de leitura não segura.
Implemente o manifesto:
kubectl create -f read-only-port-metrics.yaml
Verifique os registos do DaemonSet:
kubectl logs --namespace=node-metrics-printer-namespace \ --all-containers --prefix \ --selector=app=node-metrics-printer
Se o resultado tiver resultados que contenham a string
server_type=readonly
, uma aplicação está a usar a porta só de leitura não segura.
Verifique a utilização de portas no modo padrão
Execute o seguinte comando, pelo menos, num nó de cada conjunto de nós no seu cluster:
kubectl get --raw /api/v1/nodes/NODE_NAME/proxy/metrics | grep http_requests_total | grep readonly
Substitua NODE_NAME
pelo nome do nó.
Se a saída contiver entradas com a string server_type="readonly"
, podem ocorrer os seguintes cenários:
- As cargas de trabalho no nó usam a porta só de leitura do kubelet não segura.
- Depois de desativar a porta não segura, o comando continua a devolver a string
server_type="readonly"
. Isto deve-se ao facto de a métricakubelet_http_requests_total
representar o número cumulativo de pedidos HTTP recebidos pelo servidor kubelet desde o último reinício. Este número não é reposto quando a porta não segura é desativada. Este número é reposto depois de o GKE reiniciar o servidor kubelet, como durante uma atualização de nós. Para saber mais, consulte a referência de métricas do Kubernetes.
Se o resultado estiver vazio, nenhuma carga de trabalho nesse nó usa a porta só de leitura não segura.
Identifique as cargas de trabalho que estão a usar a porta só de leitura do kubelet não segura
Para identificar as cargas de trabalho que estão a usar a porta não segura, verifique os ficheiros de configuração da carga de trabalho, como ConfigMaps e pods.
Execute os seguintes comandos:
kubectl get pods --all-namespaces -o yaml | grep 10255
kubectl get configmaps --all-namespaces -o yaml | grep 10255
Se o resultado do comando não estiver vazio, use o seguinte script para identificar os nomes dos ConfigMaps ou dos Pods que estão a usar a porta não segura:
# 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
Depois de identificar as cargas de trabalho relevantes, migre-as para usar a porta segura 10250 concluindo os passos na secção seguinte.
Migre da porta só de leitura do kubelet não segura
Normalmente, a migração de uma aplicação para a porta segura envolve os seguintes passos:
Atualize os URLs ou os pontos finais que fazem referência à porta só de leitura não segura para usar, em alternativa, a porta só de leitura segura. Por exemplo, altere
http://203.0.113.104:10255
parahttp://203.0.113.104:10250
.Defina o certificado da autoridade de certificação (AC) do cliente HTTP para o certificado da AC do cluster. Para encontrar este certificado, execute o seguinte comando:
gcloud container clusters describe CLUSTER_NAME \ --location=LOCATION \ --format="value(masterAuth.clusterCaCertificate)"
Substitua o seguinte:
CLUSTER_NAME
: o nome do cluster.LOCATION
: a localização do seu cluster.
A porta autenticada 10250
requer que conceda funções RBAC adequadas ao assunto para aceder aos recursos específicos. Para ver detalhes, na documentação do Kubernetes, consulte o artigo Autorização do Kubelet.
Se a sua carga de trabalho usar o ponto final /pods
na porta só de leitura do kubelet não segura, tem de conceder a autorização nodes/proxy
RBAC para aceder ao ponto final na porta segura do kubelet. nodes/proxy
é uma autorização poderosa que não pode conceder em clusters do GKE Autopilot e que não deve conceder em clusters do GKE Standard. Em alternativa, use a API Kubernetes com um fieldSelector
para o nome do nó.
Se usar aplicações de terceiros que dependam da porta de leitura exclusiva do kubelet não segura, consulte o fornecedor da aplicação para obter instruções sobre como migrar para a porta segura 10250
.
Exemplo de migração
Considere um Pod que consulte métricas da porta só de leitura do kubelet não segura.
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
Esta aplicação faz o seguinte:
- Usa a
default
ServiceAccount no espaço de nomesdefault
- Executa o comando
curl
no ponto final/metrics
no nó.
Para atualizar este Pod para usar a porta segura 10250
, siga estes passos:
Crie um ClusterRole com acesso para obter métricas de nós:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: curl-authenticated-role rules: # Grant access to read node metrics in the cluster. - apiGroups: - "" resources: - nodes/metrics verbs: - get
Associe o ClusterRole à identidade da sua aplicação:
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 # Bind the ClusterRole to the default ServiceAccount in the default # namespace. subjects: - kind: ServiceAccount name: default namespace: default
Atualize o comando
curl
para usar o ponto final da porta segura com os cabeçalhos de autorização correspondentes: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 # Update the command to send a request with the ServiceAccount # credentials in the header. 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'
Modifique as regras de firewall da VPC
Se atualizar as cargas de trabalho para usar a porta 10250
, crie regras de firewall para que os pods no cluster possam alcançar a porta nos intervalos de endereços IP dos nós. As regras da firewall devem fazer o seguinte:
- Permita o tráfego de entrada para a porta TCP
10250
nos intervalos de endereços IP do nó a partir dos intervalos de endereços IP do pod interno - Recuse o tráfego de entrada para a porta TCP
10250
nos intervalos de endereços IP do nó a partir da Internet pública.
Pode usar as regras de firewall do GKE predefinidas seguintes como um modelo para os parâmetros a especificar nas novas regras:
gke-[cluster-name]-[cluster-hash]-inkubelet
gke-[cluster-name]-[cluster-hash]-exkubelet
Desative a porta de leitura só de escrita não segura em clusters do Autopilot
Pode desativar a porta só de leitura do kubelet não segura para clusters do Autopilot novos e existentes.
Para desativar a porta só de leitura do kubelet não segura num cluster do Autopilot, use a flag --no-autoprovisioning-enable-insecure-kubelet-readonly-port
, como no comando seguinte. Todos os nós novos e existentes no cluster deixam de usar a porta.
gcloud container clusters update CLUSTER_NAME \
--location=LOCATION \
--no-autoprovisioning-enable-insecure-kubelet-readonly-port
Substitua o seguinte:
CLUSTER_NAME
: o nome do seu cluster existente.LOCATION
: a localização do cluster existente.
Também pode usar a flag --no-autoprovisioning-enable-insecure-kubelet-readonly-port
quando
criar um novo cluster usando o comando
gcloud container clusters create-auto.
Desative a porta de leitura só de escrita não segura em clusters padrão
Pode desativar a porta só de leitura do kubelet não segura para clusters padrão completos ou para pools de nós individuais. Recomendamos que desative a porta para todo o cluster.
Se usar o aprovisionamento automático de nós, os conjuntos de nós aprovisionados automaticamente herdam a definição de porta especificada ao nível do cluster. Opcionalmente, pode especificar uma definição diferente para os conjuntos de nós aprovisionados automaticamente, mas recomendamos que desative a porta em todos os nós no cluster.
Também pode usar um ficheiro de configuração do sistema de nós para desativar declarativamente a porta só de leitura do kubelet insegura. Se usar este ficheiro, não pode usar os comandos nas secções seguintes para controlar a definição do kubelet.
Desative a porta de leitura insegura nos clusters padrão existentes
Para desativar a porta só de leitura do kubelet não segura num cluster Standard existente, use o sinalizador --no-enable-insecure-kubelet-readonly-port
, como no comando seguinte. Todos os conjuntos de nós novos não usam a porta não segura.
O GKE não atualiza automaticamente os conjuntos de nós existentes.
gcloud container clusters update CLUSTER_NAME \
--location=LOCATION \
--no-enable-insecure-kubelet-readonly-port
Substitua o seguinte:
CLUSTER_NAME
: o nome do seu cluster padrão existente.LOCATION
: a localização do seu cluster padrão existente.
Também pode usar a flag --no-autoprovisioning-enable-insecure-kubelet-readonly-port
quando
criar um novo cluster com o comando
gcloud container clusters create.
Desative a porta só de leitura não segura em pools de nós padrão
Recomendamos que defina a definição de porta só de leitura ao nível do cluster em todos os casos. Se desativou a porta só de leitura num cluster existente que já tinha pools de nós em execução, use o seguinte comando para desativar a porta nesses pools de nós.
gcloud container node-pools update NODE_POOL_NAME \
--cluster=CLUSTER_NAME \
--location=LOCATION \
--no-enable-insecure-kubelet-readonly-port
Substitua o seguinte:
NODE_POOL_NAME
: o nome do seu node pool.CLUSTER_NAME
: o nome do cluster.LOCATION
: a localização do cluster.
Verifique se a porta está desativada
Para verificar se a porta só de leitura do kubelet insegura está desativada, descreva o recurso do GKE.
Verifique o estado da porta em clusters do Autopilot
Execute o seguinte comando:
gcloud container clusters describe CLUSTER_NAME \
--location=LOCATION \
--flatten=nodePoolAutoConfig \
--format="value(nodeKubeletConfig)"
Substitua o seguinte:
CLUSTER_NAME
: o nome do seu cluster do Autopilot.LOCATION
: a localização do seu cluster do Autopilot.
Se a porta estiver desativada, a saída é a seguinte:
insecureKubeletReadonlyPortEnabled: false
Verifique o estado da porta em clusters padrão
O estado da porta está disponível no campo nodePoolDefaults.nodeConfigDefaults.nodeKubeletConfig
quando descreve o cluster através da API GKE.
Nos clusters padrão, também é apresentado um campo nodeConfig
que define um valor para o estado da porta só de leitura do kubelet. O campo nodeConfig
está obsoleto e aplica-se apenas ao conjunto de nós predefinido que o GKE cria quando cria um novo cluster no modo Standard. O estado da porta no campo nodeConfig
obsoleto não se aplica a outros conjuntos de nós no cluster.
Execute o seguinte comando:
gcloud container clusters describe CLUSTER_NAME \
--location=LOCATION \
--flatten=nodePoolDefaults.nodeConfigDefaults \
--format="value(nodeKubeletConfig)"
Substitua o seguinte:
CLUSTER_NAME
: o nome do seu cluster padrão.LOCATION
: a localização do seu cluster padrão.
Se a porta estiver desativada, a saída é a seguinte:
insecureKubeletReadonlyPortEnabled: false
Se o resultado deste comando estiver em branco, a porta kubelet
só de leitura não segura
pode ainda estar ativada. Para desativar a porta, execute o comando na secção
Desative a porta de leitura insegura nos clusters padrão existentes.
Verifique o estado da porta nos conjuntos de nós padrão
Execute o seguinte comando:
gcloud container node-pools describe NODE_POOL_NAME \
--cluster=CLUSTER_NAME \
--location=LOCATION \
--flatten=config \
--format="value(kubeletConfig)"
Substitua o seguinte:
NODE_POOL_NAME
: o nome do seu node pool.CLUSTER_NAME
: o nome do cluster.LOCATION
: a localização do cluster.
Se a porta estiver desativada, a saída é a seguinte:
insecureKubeletReadonlyPortEnabled: false