Crie um serviço e uma entrada

Este documento mostra como criar um objeto Ingress do Kubernetes num cluster de utilizador, híbrido ou autónomo para o Google Distributed Cloud. Um Ingress está associado a um ou mais Serviços, cada um dos quais está associado a um conjunto de Pods.

Crie uma implementação

Use os passos seguintes para criar uma implementação:

  1. Crie um manifesto de implementação:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello-deployment
    spec:
      selector:
        matchLabels:
          greeting: hello
      replicas: 3
      template:
        metadata:
          labels:
            greeting: hello
        spec:
          containers:
          - name: hello-world
            image: "gcr.io/google-samples/hello-app:2.0"
            env:
            - name: "PORT"
              value: "50000"
          - name: hello-kubernetes
            image: "gcr.io/google-samples/node-hello:1.0"
            env:
            - name: "PORT"
              value: "8080"
    

    Para efeitos deste exercício, estes são os pontos importantes a compreender acerca do manifesto de implementação:

    • Cada Pod pertencente à implementação tem a etiqueta greeting: hello.

    • Cada pod tem dois contentores.

    • Os campos env especificam que os contentores hello-app ouvem na porta TCP 50000 e os contentores node-hello ouvem na porta TCP 8080. Para hello-app, pode ver o efeito da variável de ambiente PORT analisando o código-fonte.

  2. Copie o manifesto para um ficheiro com o nome hello-deployment.yaml.

  3. Crie a implementação:

    kubectl apply --kubeconfig CLUSTER_KUBECONFIG -f hello-deployment.yaml
    

    Substitua CLUSTER_KUBECONFIG pelo nome do ficheiro kubeconfig do seu cluster.

Exponha a sua implementação com um serviço

Para oferecer uma forma estável de os clientes enviarem pedidos para os pods da sua implementação, crie um serviço:

  1. Crie um manifesto de serviço que exponha a sua implementação aos clientes no interior do cluster:

    apiVersion: v1
    kind: Service
    metadata:
      name: hello-service
    spec:
      type: ClusterIP
      selector:
        greeting: hello
      ports:
      - name: world-port
        protocol: TCP
        port: 60000
        targetPort: 50000
      - name: kubernetes-port
        protocol: TCP
        port: 60001
        targetPort: 8080
    
  2. Copie o manifesto para um ficheiro com o nome hello-service.yaml.

  3. Crie o serviço:

    kubectl apply --kubeconfig CLUSTER_KUBECONFIG -f hello-service.yaml
    

    Substitua CLUSTER_KUBECONFIG pelo nome do ficheiro kubeconfig do cluster.

  4. Ver o serviço:

    kubectl --kubeconfig CLUSTER_KUBECONFIG get service hello-service --output yaml
    

    A saída mostra o valor de clusterIP que foi atribuído ao serviço. Por exemplo:

    apiVersion: v1
    kind: Service
    metadata:
      annotations:
        ...
    spec:
      clusterIP: 10.96.14.249
      clusterIPs:
      - 10.96.14.249
      ipFamilies:
      - IPv4
      ipFamilyPolicy: SingleStack
      ports:
      - name: world-port
        port: 60000
        protocol: TCP
        targetPort: 50000
      - name: kubernetes-port
        port: 60001
        protocol: TCP
        targetPort: 8080
      selector:
        greeting: hello
      sessionAffinity: None
      type: ClusterIP
    status:
      loadBalancer: {}
    

    Na saída anterior, o campo ports é uma matriz de objetos ServicePort: um denominado world-port e outro denominado kubernetes-port. Para mais informações acerca dos campos de serviço, consulte ServiceSpec na documentação do Kubernetes.

    Seguem-se as formas como um cliente pode chamar o serviço:

    • Usando world-port: um cliente executado num dos nós do cluster envia um pedido para o clusterIP em port (como 10.96.14.249:60000). O controlador de entrada encaminha o pedido para um pod membro em targetPort (como POD_IP_ADDRESS:50000, onde POD_IP_ADDRESS é o endereço IP de um pod membro).

    • Usando kubernetes-port: um cliente executado num dos nós do cluster envia um pedido para o clusterIP em port (10.96.14.249:60001). O controlador de entrada encaminha o pedido para um pod membro em targetPort (POD_IP_ADDRESS:8080).

Componentes de entrada

Seguem-se alguns dos componentes do cluster relacionados com a entrada:

na documentação do Cloud Service Mesh.
  • A istio-ingress implementação. Este é o proxy de entrada. O proxy de entrada encaminha o tráfego para os serviços internos de acordo com as regras especificadas num objeto Ingress.

  • O istio-ingress Serviço. Este serviço expõe a implementação do istio-ingress.

  • A istiod implementação. Este é o controlador de entrada. O controlador de entrada monitoriza a criação de objetos Ingress e configura o proxy de entrada em conformidade.

Todos estes componentes no cluster do Istio são instalados no espaço de nomes gke-system. Este espaço de nomes não entra em conflito com uma instalação completa do Istio/Cloud Service Mesh.

Crie um Ingress

Siga estes passos para criar um Ingress:

  1. Crie um manifesto de entrada:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-ingress
    spec:
      rules:
      - http:
          paths:
          - path: /greet-the-world
            pathType: Exact
            backend:
              service:
                name: hello-service
                port:
                  number: 60000
          - path: /greet-kubernetes
            pathType: Exact
            backend:
              service:
                name: hello-service
                port:
                  number: 60001
    
  2. Copie o manifesto para um ficheiro com o nome my-ingress.yaml.

  3. Crie a entrada:

    kubectl apply --kubeconfig CLUSTER_KUBECONFIG -f my-ingress.yaml
    

Quando cria um cluster de utilizadores, especifica um valor para loadbalancer.ingressVIP no ficheiro de configuração do cluster. Este endereço IP está configurado no balanceador de carga do cluster. Quando cria uma entrada, é atribuído o mesmo VIP à entrada como endereço IP externo.

Quando um cliente envia um pedido para o VIP de entrada do cluster de utilizadores, o pedido é encaminhado para o equilibrador de carga. O equilibrador de carga usa o serviço istio-ingress para encaminhar o pedido para o proxy de entrada, que é executado no cluster de utilizadores. O proxy de entrada encaminha o pedido para diferentes backends consoante o caminho no URL do pedido.

O caminho /greet-the-world

No manifesto do Ingress, pode ver uma regra que indica que o caminho /greet-the-world está associado a serviceName: hello-service e servicePort: 60000. Recorde que 60000 é o valor port na secção world-port do seu serviço hello-service.

- name: world-port
    port: 60000
    protocol: TCP
    targetPort: 50000

O serviço de entrada encaminha o pedido para clusterIP:50000. O pedido é, em seguida, encaminhado para um dos pods membros do serviço hello-service. O contentor, nesse pod, a ouvir na porta 50000 apresenta uma mensagem Hello World!.

O caminho /greet-kubernetes

No manifesto do Ingress, pode ver uma regra que indica que o caminho /greet-kubernetes está associado a serviceName: hello-service e servicePort: 60001. Recorde que 60001 é o valor de port na secção kubernetes-port do seu serviço hello-service.

- name: kubernetes-port
    port: 60001
    protocol: TCP
    targetPort: 8080

O serviço de entrada encaminha o pedido para clusterIP: 8080. O pedido é, em seguida, encaminhado para um dos pods membros do serviço hello-service. O contentor nesse pod, a ouvir na porta 8080, apresenta uma mensagem Hello Kubernetes!.

Teste a entrada

  1. Teste o Ingress através do caminho /greet-the-world:

    curl CLUSTER_INGRESS_VIP/greet-the-world
    

    Substitua CLUSTER_INGRESS_VIP pelo endereço IP externo do Ingress.

    O resultado mostra uma mensagem Hello, world!:

    Hello, world!
    Version: 2.0.0
    Hostname: ...
    
  2. Teste o Ingress através do caminho /greet-kubernetes:

    curl CLUSTER_INGRESS_VIP/greet-kubernetes
    

    O resultado mostra uma mensagem Hello, Kubernetes!:

    Hello Kubernetes!
    

Desative o Ingress incluído

A capacidade de entrada incluída no Google Distributed Cloud suporta apenas capacidades de entrada. Pode optar por integrar com o Istio ou o Cloud Service Mesh. Estes produtos oferecem vantagens adicionais de uma malha de serviços totalmente funcional, como Transport Layer Security (TLS) mútuo, capacidade de gerir a autenticação entre serviços e observabilidade da carga de trabalho. Se fizer a integração com o Istio ou o Cloud Service Mesh, recomendamos que desative a capacidade de entrada incluída.

Pode ativar ou desativar o Ingress integrado com o campo spec.clusterNetwork.bundledIngress no ficheiro de configuração do cluster. Este campo só está disponível para clusters da versão 1.13.0 e superiores. O campo bundledIngress tem como predefinição true e não está presente no ficheiro de configuração do cluster gerado. Este campo é mutável e pode ser alterado quando cria ou atualiza um cluster para a versão 1.13.0 ou superior.

  • Para desativar a capacidade de entrada incluída, adicione o campo bundledIngress à secção clusterNetwork do ficheiro de configuração do cluster e defina o respetivo valor como falso, conforme mostrado no exemplo seguinte:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: cluster-hybrid-basic
    ---
    apiVersion: baremetal.cluster.gke.io/v1
    kind: Cluster
    metadata:
      name: hybrid-basic
      namespace: cluster-hybrid-basic
    spec:
      type: hybrid
      profile: default
      anthosBareMetalVersion: 1.13.0
      gkeConnect:
        projectID: project-fleet
      controlPlane:
        nodePoolSpec:
          nodes:
          - address: 10.200.0.2
      clusterNetwork:
        bundledIngress: false
        pods:
          cidrBlocks:
          - 192.168.0.0/16
        services:
          cidrBlocks:
          - 10.96.0.0/20
    ...
    

Configure o HTTPS para a entrada

Se quiser aceitar pedidos HTTPS dos seus clientes, o proxy de entrada tem de ter um certificado para poder provar a sua identidade aos clientes. Este proxy também tem de ter uma chave privada para concluir o handshake HTTPS.

O exemplo seguinte usa estas entidades:

  • Proxy de entrada: participa na confirmação de HTTPS e, em seguida, encaminha pacotes para os pods membros do serviço hello-service.

  • Domínio do serviço hello-service: altostrat.com na organização de exemplo

Siga estes passos:

  1. Crie um certificado de raiz e uma chave privada. Este exemplo usa uma autoridade de certificação de raiz de root.ca.example.com em Root CA Example Org.

    openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj \
        '/O=Root CA Example Inc./CN=root.ca.example.com' -keyout root-ca.key \
        -out root-ca.crt
    
  2. Crie um pedido de assinatura de certificado:

     openssl req -out server.csr -newkey rsa:2048 -nodes -keyout server.key -subj \
         "/CN=altostrat.com/O=Example Org"
    
  3. Crie um certificado de publicação para o proxy de entrada.

    openssl x509 -req -days 365 -CA root-ca.crt -CAkey root-ca.key -set_serial 0 \
        -in server.csr -out server.crt
    

    Criou os seguintes certificados e chaves:

    • root-ca.crt: Certificado para a CA de raiz
    • root-ca.key: chave privada para a AC raiz
    • server.crt: certificado de publicação para o proxy de entrada
    • server.key: chave privada para o proxy de entrada
  4. Crie um Secret do Kubernetes que contenha o certificado e a chave de publicação.

    kubectl create secret tls example-server-creds --key=server.key --cert=server.crt \
        --namespace gke-system
    

    O Secret resultante tem o nome example-server-creds.

Crie uma implementação e um serviço

Se criou uma implementação e um serviço na parte HTTP deste guia, mantenha-os no lugar. Se não o fez, crie-os agora seguindo os passos descritos para HTTP.

Crie um Ingress

A criação de um Ingress para HTTPS é semelhante à criação de um Ingress para HTTP, mas a especificação do Ingress para HTTPS inclui uma secção tls que especifica o anfitrião e um segredo. O hosts na secção tls tem de corresponder explicitamente ao host na secção rules.

Se o seu serviço de back-end estiver num espaço de nomes separado, tem de criar um serviço do tipo ExternalName no mesmo espaço de nomes que o Ingress para encaminhar o tráfego para o serviço de back-end.

Os passos gerais para criar um Ingress para HTTPS ou HTTP são os mesmos, exceto no que diz respeito à configuração no ficheiro de manifesto:

  1. Se criou anteriormente um Ingress na parte HTTP deste documento, elimine esse Ingress antes de continuar.

    kubectl --kubeconfig CLUSTER_KUBECONFIG delete ingress my-ingress
    
  2. Para processar o tráfego do serviço que criou anteriormente, crie um novo manifesto Ingress que tenha uma secção tls:

    A configuração tls ativa o HTTPS entre os clientes e o proxy de entrada.

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-ingress-2
    spec:
      tls:
      - hosts:
        - altostrat.com
        secretName: example-server-creds
      rules:
      - host: altostrat.com
        http:
          paths:
          - path: /greet-the-world
            pathType: Exact
            backend:
              service:
                name: hello-service
                port:
                  number: 60000
          - path: /greet-kubernetes
            pathType: Exact
            backend:
              service:
                name: hello-service
                port:
                  number: 60001
    
  3. Guarde o manifesto num ficheiro com o nome my-ingress-2.yaml e crie o Ingress:

    kubectl apply --kubeconfig CLUSTER_KUBECONFIG -f my-ingress-2.yaml
    
  4. Confirme se o Ingress foi criado e está a funcionar corretamente testando o seguinte:

    • Teste o caminho /greet-the-world:

      curl -v --resolve altostrat.com:443:CLUSTER_INGRESS_VIP \
          https://altostrat.com/greet-the-world \
          --cacert root-ca.crt
      

      Saída:

      Hello, world!
      Version: 2.0.0
      Hostname: hello-deployment-5ff7f68854-wqzp7
      
    • Teste o caminho /greet-kubernetes:

      curl -v --resolve altostrat.com:443:CLUSTER_INGRESS_VIP \
          https://altostrat.com/greet-kubernetes --cacert root-ca.crt
      

      Saída:

      Hello Kubernetes!
      

Crie um serviço LoadBalancer

Um serviço do tipo LoadBalancer é outra forma de expor as suas cargas de trabalho fora do cluster. Para ver instruções e um exemplo de criação de um serviço do tipo LoadBalancer, consulte o artigo Crie um serviço do tipo LoadBalancer em Implemente uma aplicação.

Limpar

  1. Elimine o seu Ingress:

    kubectl --kubeconfig CLUSTER_KUBECONFIG delete ingress INGRESS_NAME
    

    Substitua INGRESS_NAME pelo nome do Ingress, como my-ingress ou my-ingress-2.

  2. Elimine o seu serviço:

    kubectl --kubeconfig CLUSTER_KUBECONFIG delete service hello-service
    
  3. Elimine a sua implementação:

    kubectl --kubeconfig CLUSTER_KUBECONFIG delete deployment hello-deployment
    
  4. Elimine o serviço LoadBalancer:

    kubectl --kubeconfig CLUSTER_KUBECONFIG delete service service-does-not-use-nodeports