Introdução
O Orchard Market precisa de um pequeno painel de status para suas aplicações de bancas e entregas. O programa do painel está pronto, mas sua identidade Kubernetes atual não consegue ler os Deployments dessas aplicações. Dê ao painel sua própria identidade e somente as permissões necessárias para exibir réplicas desejadas, réplicas disponíveis e imagens dos modelos reais. Mantenha o namespace da equipe, os Secrets e as alterações de cargas de trabalho fora de seu acesso.
Seu resultado é um painel utilizável e um download CSV, além de quatro manifestos salvos que descrevem sua identidade, duas concessões por namespace e a seleção da identidade da carga de trabalho. O painel faz requisições HTTPS reais ao cluster preparado. Ele não tem dados estáticos de sucesso para substituir os resultados quando o acesso falha.
Você já deve conhecer caminhos básicos no terminal, YAML simples, namespaces, Pods, Deployments, Services e labels. Este laboratório explica ServiceAccounts, Roles, RoleBindings e o cliente fornecido antes de usá-los. Um cluster Kubernetes real de um único nó, o painel, os dados sintéticos da aplicação e a ferramenta de diagnóstico estão preparados. Você não instala o cluster, cria uma imagem, programa o cliente nem copia tokens. A duração é uma estimativa do autor que inclui leitura e erros comuns, não um tempo de conclusão medido com iniciantes.
Crie uma Identidade Dedicada para o Painel
Nesta etapa, você lerá a identidade inicial real do painel e salvará uma ServiceAccount dedicada sem ainda conceder acesso à aplicação.
Comece na aba Board. O Orchard Market deve mostrar A clear view of the working day., os grupos Market stalls e Market delivery e Access denied · API 403 para ambos os grupos. Esse é o problema inicial esperado. O resultado completo mostrará catalogue com 2 réplicas desejadas e 2 disponíveis, checkout com 1 e 1, pickup com 1 e 1 e receipts com 0 e 0. Todos os quatro usam a imagem de modelo preparada python:3.12-alpine. O arquivo de recibos está intencionalmente com escala reduzida a zero.
Os três campos principais respondem a perguntas diferentes. Desired replicas é a quantidade declarada em um Deployment. Available replicas é a contagem do controlador após a prontidão e seu tempo mínimo em estado pronto. Template image é a imagem solicitada pelo modelo do Deployment; durante uma atualização, ela não comprova que todos os Pods existentes já usem essa imagem. Expanda What these fields mean, leia e recolha novamente. Essas são observações do controlador, não verificações de disponibilidade contínua do site para clientes.
Escolha Access details. O valor de Read as vem da API e inicialmente termina em market-board:default. A tabela informa o escopo pretendido das permissões; ela não afirma que o acesso já tenha sido concedido. Use Back to status board e depois mude para Workspace.
O terminal começa em /home/labex/project/status-board. pwd exibe seu diretório de trabalho, ls lista suas entradas e cd com um caminho absoluto retorna aqui se você mudou de diretório:
pwd
ls
cd /home/labex/project/status-board
Espere scope.json, starter e tools. cat exibe o arquivo de escopo preparado. Ele usa JSON (JavaScript Object Notation), um formato de texto de valores nomeados e listas, para registrar os namespaces, a identidade e os nomes reais das aplicações:
cat scope.json
O painel é executado em market-board, enquanto seus dados aprovados de aplicações ficam em market-stalls e market-delivery. market-office está excluído. --context=labex-v135 seleciona o cluster preparado; -n seleciona um namespace. As credenciais existentes do operador de Workspace podem inspecionar e configurar esses objetos do curso. Elas não são as credenciais do painel. Inspecione os Deployments reais de destino como esse operador:
kubectl --context=labex-v135 get deployments -n market-stalls
kubectl --context=labex-v135 get deployments -n market-delivery
Leia os nomes e os resultados desejados/disponíveis, incluindo o arquivo de recibos com zero réplicas desejadas. Os objetos subjacentes existem embora o painel não consiga lê-los. O sucesso a partir deste terminal do operador não comprova acesso para um processo dentro do Pod do painel.
Uma ServiceAccount é uma identidade da API Kubernetes com escopo de namespace para uma carga de trabalho, não um usuário Linux nem um visitante do navegador. O Deployment preparado do painel seleciona inicialmente a ServiceAccount default. describe apresenta a configuração do objeto em seções legíveis:
kubectl --context=labex-v135 describe deployment status-board -n market-board
Procure a ServiceAccount selecionada em seu modelo de Pod. Um Pod recebe uma credencial projetada para essa conta. O cliente preparado a lê internamente e valida o certificado do servidor da API usando a autoridade certificadora fornecida; ele nunca exibe a credencial nem usa o kubeconfig do operador. Você configura a identidade e as permissões em vez de implementar o tratamento de credenciais.
O ./tools/board-test fornecido executa esse cliente dentro do Pod atual do painel. O ./ inicial significa que a ferramenta está neste diretório de trabalho. Seu primeiro argumento seleciona uma operação de diagnóstico ensinada. identity pergunta à API como ela autenticou essa credencial real:
./tools/board-test identity
Espere que username seja system:serviceaccount:market-board:default, com o pod_uid atual. O valor 201 de http_status significa que a API respondeu a essa revisão da própria identidade. A revisão não é um objeto persistido do cluster, não altera permissões e não cria um Deployment. Nenhum token é exibido. Um processo de painel pronto e uma identidade confirmada ainda podem não ter acesso aos dados da aplicação.
Crie seu diretório de versão. mkdir -p o cria se necessário e preserva um diretório existente. No próximo comando, > redireciona a saída para seu arquivo editável. O marcador YAML entre aspas mantém o texto literal até o marcador final em uma linha própria. Repetir o comando sobrescreve somente esse arquivo de versão:
mkdir -p release
cat > release/identity.yaml <<'YAML'
apiVersion: v1
kind: ServiceAccount
metadata:
name: market-reader
namespace: market-board
YAML
Leia seu arquivo e depois aplique-o. apply -f lê o manifesto indicado e cria ou atualiza seu objeto:
cat release/identity.yaml
kubectl --context=labex-v135 apply -f release/identity.yaml
kubectl --context=labex-v135 get serviceaccount market-reader -n market-board
A identidade dedicada agora existe. Um Secret de token de longa duração não é automaticamente necessário: o Kubernetes projeta uma credencial vinculada em um Pod quando esse Pod usa a identidade. Criar somente essa ServiceAccount não concede acesso a Deployments nem altera a identidade do painel em execução. Mantenha inalterada a conta default original.
Se um caminho for digitado incorretamente, use os comandos já mostrados pwd, ls e cd absoluto e depois repita a operação que falhou. Para um erro de YAML, leia seu arquivo editável, compare a indentação com o exemplo completo, reescreva-o e aplique novamente. Mantenha inalterados scope.json, o arquivo inicial, as ferramentas, os namespaces originais, as aplicações e os dados. Você editará somente os manifestos de versão indicados e seus objetos nomeados de identidade/RBAC, além da ServiceAccount selecionada no Deployment do painel.
Conecte o Primeiro Namespace
Nesta etapa, você concederá duas operações de leitura no namespace das bancas e depois fará um novo Pod do painel usar de fato a identidade dedicada.
Comece em Workspace, em /home/labex/project/status-board. RBAC do Kubernetes significa controle de acesso baseado em papéis. Uma Role define permissões dentro de um namespace. Uma RoleBinding conecta a Role desse namespace a uma identidade. Nomes iguais, por si só, não fazem essa conexão.
O painel precisa de list para ler uma coleção de Deployments e de get para abrir um Deployment individual. Deployments pertencem ao grupo de API apps; a regra usa apps, sem /v1. watch solicitaria um fluxo de alterações, que este painel não usa. Nenhum verbo de escrita nem acesso a Secrets é necessário. Mantenha ambos os verbos de leitura disponíveis para todos os Deployments em cada namespace aprovado. Omita resourceNames, o campo opcional de regra que restringe a permissão a recursos nomeados. O roleRef.apiGroup da vinculação identifica a API RBAC, rbac.authorization.k8s.io; ele difere do grupo apps que contém os Deployments permitidos pela Role.
Salve uma Role e sua vinculação em um manifesto. O separador --- inicia um segundo documento YAML. O metadata.namespace da vinculação é onde a permissão se aplica, enquanto subjects.namespace é onde a ServiceAccount existe. Aqui eles são deliberadamente diferentes:
cat > release/first-access.yaml <<'YAML'
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: deployment-reader
namespace: market-stalls
rules:
- apiGroups: [apps]
resources: [deployments]
verbs: [get, list]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: board-reader
namespace: market-stalls
subjects:
- kind: ServiceAccount
name: market-reader
namespace: market-board
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: deployment-reader
YAML
Leia e aplique ambos os objetos e depois inspecione a conexão interpretada:
cat release/first-access.yaml
kubectl --context=labex-v135 apply -f release/first-access.yaml
kubectl --context=labex-v135 describe role deployment-reader -n market-stalls
kubectl --context=labex-v135 describe rolebinding board-reader -n market-stalls
Espere somente get e list para Deployments. Siga roleRef até a Role em market-stalls e o subject até market-reader em market-board. A vinculação não cria uma segunda ServiceAccount no namespace de destino.
O painel em execução ainda usa default. A operação list da ferramenta de diagnóstico solicita a coleção real de Deployments usando a credencial atual desse Pod. Uma leitura proibida retorna http_status: 403 e um código de saída de comando diferente de zero; isso é esperado antes de você trocar a identidade da carga de trabalho:
./tools/board-test list market-stalls
A nova permissão pertence a market-reader, não a default. Não corrija isso concedendo acesso à conta default. Selecione a conta dedicada em uma cópia salva do Deployment preparado do painel.
Leia primeiro o arquivo inicial completo. Ele contém a imagem existente, o código-fonte montado, a verificação de saúde, a quantidade de réplicas e outras configurações a preservar:
cat starter/board.yaml
kubectl set serviceaccount altera a identidade selecionada. --local transforma esse arquivo de entrada sem aplicá-lo ao cluster. -f indica a entrada, -o yaml escreve um manifesto YAML na saída padrão e o > já aprendido o salva como seu arquivo editável de versão:
kubectl --context=labex-v135 set serviceaccount --local -f starter/board.yaml market-reader -o yaml > release/board.yaml
Leia o resultado e confirme que spec.template.spec.serviceAccountName é market-reader. Mantenha todas as outras configurações da aplicação:
cat release/board.yaml
kubectl --context=labex-v135 apply -f release/board.yaml
Um Pod existente não pode ter sua ServiceAccount alterada diretamente. Atualizar o modelo de Pod do Deployment cria um novo Pod. rollout status espera pela nova carga de trabalho; --timeout=120s limita a espera:
kubectl --context=labex-v135 rollout status deployment/status-board -n market-board --timeout=120s
kubectl --context=labex-v135 get pods -n market-board
Espere um Pod atual do painel pronto. Substituir esse Pod do painel é necessário; os Pods das aplicações de destino não são alterados. Leia novamente sua identidade real autenticada:
./tools/board-test identity
Espere system:serviceaccount:market-board:market-reader e um pod_uid diferente do Pod original com identidade default. Isso confirma a credencial do processo, em vez de apenas avaliar uma identidade representada por impersonação.
Os resultados de coleção e detalhe de Deployments também incluem generation, a versão do estado desejado do Deployment, e observed_generation, a versão processada por último pelo controlador. A página de detalhes os identifica como Deployment generation e Observed generation. Um controlador pode ficar brevemente atrás de uma alteração desejada. Esses campos não contam requisições de clientes nem estabelecem disponibilidade de um site.
Leia a coleção de bancas e um Deployment individual. get recebe o namespace seguido do nome do Deployment:
./tools/board-test list market-stalls
./tools/board-test get market-stalls catalogue
Espere http_status: 200, ambos os Deployments originais de bancas na coleção e catalogue com 2 réplicas desejadas e 2 disponíveis no resultado individual. O uid identifica o objeto original; a imagem do modelo permanece python:3.12-alpine. Uma Role de namespace não se estende ao namespace de entregas:
./tools/board-test list market-delivery
Espere API 403 e um status de comando diferente de zero para esse último comando. Mude para Board, use Refresh view, abra Inspect catalogue e leia suas contagens desejadas/disponíveis e Template image. Use Back to status board. Os cartões das bancas devem funcionar enquanto o grupo de entregas ainda mostra Access denied · API 403. Esse resultado parcial é uma evidência útil do limite de namespace.
Se Read as ainda mostrar a identidade anterior logo após um rollout, use Refresh view novamente. Para confirmar o Pod atual, mude para Workspace, repita ./tools/board-test identity, depois retorne a Board e atualize. O roteamento do Service pode precisar de um breve momento para acompanhar o rollout; não conceda acesso à identidade antiga para ocultar a transição.
Compare o leitor real, os cartões bem-sucedidos das bancas e o grupo de entregas ainda negado neste exemplo em execução:

Se o tempo do rollout se esgotar, retorne a Workspace e inspecione o mesmo Deployment e os Pods com os comandos describe e get já mostrados. Se uma leitura for negada inesperadamente, compare a Role, o namespace do subject da RoleBinding e a identidade selecionada da carga de trabalho. Corrija somente seu arquivo de versão, aplique-o e repita o rollout ou a requisição apropriada. Não copie credenciais de operador, não altere a aplicação nem reinicie a VM.
O roleRef de uma RoleBinding é imutável. Se um erro de digitação anterior criou a nova vinculação board-reader deste curso com a referência errada de Role, o Kubernetes se recusará a alterar essa referência diretamente. Após inspecioná-la e corrigir release/first-access.yaml, recrie somente sua própria vinculação nomeada e depois aplique o arquivo salvo corrigido:
kubectl --context=labex-v135 delete rolebinding board-reader -n market-stalls
kubectl --context=labex-v135 apply -f release/first-access.yaml
Esses são comandos condicionais de recuperação, não uma exclusão obrigatória no caminho normal bem-sucedido. Não exclua vinculações default nem da plataforma e não exclua o Deployment original do painel nem as cargas de trabalho de destino.
Amplie o Painel sem Ampliar sua Função
Nesta etapa, você dará à mesma identidade as mesmas duas operações de leitura no namespace de entregas e depois verificará uma saída útil e os limites protegidos.
Comece em Workspace, em /home/labex/project/status-board. Um segundo namespace precisa de sua própria Role e RoleBinding. Reutilize o nome da Role ali, mas mantenha o subject em market-board; a identidade não se mudou:
cat > release/second-access.yaml <<'YAML'
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: deployment-reader
namespace: market-delivery
rules:
- apiGroups: [apps]
resources: [deployments]
verbs: [get, list]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: board-reader
namespace: market-delivery
subjects:
- kind: ServiceAccount
name: market-reader
namespace: market-board
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: deployment-reader
YAML
cat release/second-access.yaml
kubectl --context=labex-v135 apply -f release/second-access.yaml
kubectl --context=labex-v135 describe rolebinding board-reader -n market-delivery
A vinculação concede essa Role de destino à identidade existente do painel. Nenhum rollout adicional do painel é necessário porque o Pod atual já usa essa identidade. As concessões RBAC se somam; alterar a ordem dos arquivos não introduz uma regra de negação nem remove uma concessão não relacionada.
Leia ambas as coleções aprovadas e um detalhe de entrega pela credencial real do painel:
./tools/board-test list market-stalls
./tools/board-test list market-delivery
./tools/board-test get market-delivery pickup
Espere API 200 com os objetos e imagens originais. A coleção de entregas inclui pickup com 1 réplica desejada/1 disponível e receipts com 0/0. O Deployment com zero réplicas desejadas permanece um objeto real embora não tenha Pods em execução. Preserve essa configuração declarada.
Agora verifique os dados excluídos. Um Secret do Kubernetes armazena valores de dados nomeados. O staff-note preparado é um dado sintético de teste; o painel não tem motivo para lê-lo. O operador pode confirmar que esse objeto existe sem exibir seus valores:
kubectl --context=labex-v135 get secret staff-note -n market-stalls
A própria credencial do painel ainda deve receber API 403 para o terceiro namespace e esse Secret. Espera-se que ambos os comandos seguintes terminem com status diferente de zero:
./tools/board-test list market-office
./tools/board-test secret market-stalls staff-note
Um objeto ausente, uma falha de conexão ou uma captura de tela de erro não equivalem a essa recusa real de autorização. O mesmo cliente lê com sucesso os destinos aprovados, enquanto os objetos excluídos existentes permanecem intactos. Seu arquivo de credencial projetada não lhe concede acesso à API de Secrets.
A operação permission da ferramenta pergunta à API se essa credencial real pode realizar uma ação. Ela não realiza essa ação. Os argumentos são o namespace, o verbo e, quando relevante, o nome do Deployment. A revisão não persistida retorna http_status: 201 com allowed: false para cada operação proibida; a ferramenta retorna status diferente de zero para essa negação:
./tools/board-test permission market-stalls patch catalogue
./tools/board-test permission market-delivery delete pickup
./tools/board-test permission market-stalls create
O painel precisa somente de get e list; nenhum fluxo watch nem alteração de carga de trabalho é autorizado. Mantenha inalteradas a identidade default e o RBAC original da plataforma. Não acrescente uma ClusterRole, ClusterRoleBinding, curinga, subject extra nem concessão de outro recurso.
Mude para Board e use Refresh view. Ambos os grupos agora mostram seus Deployments originais. Abra Inspect pickup, leia suas contagens e imagem e depois use Back to status board. Leia o cartão receipts: Scaled to zero, 0 disponíveis, 0 desejadas. Isso não é um substituto vazio para uma requisição que falhou.
Compare o leitor real, todos os quatro cartões de Deployment e o arquivo visível com zero réplicas desejadas neste exemplo concluído:

Escolha Download CSV e abra o orchard-market-deployments.csv real baixado. Ele tem quatro linhas de dados, uma para cada Deployment original, incluindo o arquivo de recibos. Compare namespace, nome do Deployment, valores desejados/disponíveis, imagem do modelo e status da API com a página. Essa é uma exportação nova da API, não uma amostra salva de sucesso. Downloads do navegador e o espaço de trabalho do terminal são locais separados; você não precisa copiar o download para o espaço de trabalho.
Escolha Access details, confirme o valor real de Read as e ambos os escopos pretendidos de namespace e depois use Back to status board. Mantenha todos os Deployments de destino originais, identidades de Pods/contêineres, código-fonte, imagens, dados e labels de namespace. Preserve o Deployment e o Service originais do painel; somente sua ServiceAccount selecionada muda. A versão reutilizável contém identity.yaml, first-access.yaml, second-access.yaml e board.yaml, correspondendo à identidade real e às permissões em execução.
Se o segundo namespace continuar negado, retorne a Workspace, inspecione sua vinculação com o comando describe mostrado, compare o namespace do subject e a referência de Role, corrija seu arquivo salvo e aplique-o novamente. Para um roleRef errado e imutável, use a mesma recuperação de escopo restrito ensinada anteriormente, agora somente para sua nova vinculação de entregas:
kubectl --context=labex-v135 delete rolebinding board-reader -n market-delivery
kubectl --context=labex-v135 apply -f release/second-access.yaml
Execute-os somente para essa recuperação específica. Se o acesso excluído tiver sucesso inesperadamente, inspecione suas duas Roles salvas e suas vinculações, remova a permissão não intencional dentro desses objetos e aplique novamente. Uma concessão ampla não é anulada por outra Role mais restrita. Não edite permissões da plataforma nem a aplicação para ocultar um erro. Erros de caminho e de YAML usam a recuperação já ensinada, sem reinicializar a VM.
A ferramenta concluída lê o estado de Deployments informado pelo controlador neste cluster preparado de um único nó. Ela não autentica visitantes do painel, não lê logs nem métricas de Pods e não comprova disponibilidade contínua em produção. Seu endpoint de prontidão confirma apenas que o processo do painel consegue servir; os resultados reais da API estabelecem se os dados das aplicações estão acessíveis.
Resumo
Você deu a um consumidor real dentro do cluster sua própria ServiceAccount, conectou uma Role e uma RoleBinding com escopo de namespace e fez um novo Pod usar de fato essa identidade. Depois, estendeu a mesma função de leitura a um segundo namespace aprovado sem conceder acesso a dados excluídos nem a alterações de cargas de trabalho.
O painel utilizável, o CSV atual e os manifestos salvos conectam identidade, permissões e saída real da API. Réplicas desejadas, disponibilidade informada pelo controlador e imagens dos modelos continuam sendo observações distintas. Uma recusa da API permanece como indisponibilidade dos dados, enquanto um Deployment intencionalmente com zero réplicas desejadas continua visível como objeto real.



