Crie um serviço e uma entrada

Este documento mostra como criar um objeto Ingress do Kubernetes num cluster de utilizador 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.

Antes de começar

Obtenha uma ligação SSH à sua estação de trabalho de administrador:

Crie uma implementação

Segue-se um manifesto para uma 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 ao analisar o código fonte da app hello-app.

Copie o manifesto para um ficheiro com o nome hello-deployment.yaml e crie a implementação:

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

em que USER_CLUSTER_KUBECONFIG é o caminho do ficheiro kubeconfig para o cluster de utilizadores.

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.

Segue-se um manifesto para um serviço que expõe a sua implementação a 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

Copie o manifesto para um ficheiro denominado hello-service.yaml e crie o serviço:

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

Ver o serviço:

kubectl --kubeconfig USER_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 Kubernetes ServicePort: um denominado world-port e outro denominado kubernetes-port.

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. Neste exemplo, 10.96.14.249:60000. O pedido é encaminhado para um membro do pod a targetPort. Neste exemplo, POD_IP_ADDRESS:50000.

  • Usando kubernetes-port: um cliente executado num dos nós do cluster envia um pedido para o clusterIP em port. Neste exemplo, 10.96.14.249:60001. O pedido é encaminhado para um membro do pod a targetPort. Neste exemplo, POD_IP_ADDRESS:8080.

Componentes de entrada

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

  • 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.

Crie um Ingress

Segue-se um manifesto para um Ingress:

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

Copie o manifesto para um ficheiro denominado my-ingress.yaml e crie o Ingress:

kubectl apply --kubeconfig USER_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 está configurado para encaminhar 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, que está a ouvir na porta 8080, apresenta uma mensagem Hello Kubernetes!.

Teste a entrada

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

curl USER_CLUSTER_INGRESS_VIP/greet-the-world

Substitua USER_CLUSTER_INGRESS_VIP pelo endereço IP externo do Ingress.

O resultado mostra uma mensagem Hello, world!:

Hello, world!
Version: 2.0.0
Hostname: ...

Teste o Ingress através do caminho /greet-kubernetes:

curl USER_CLUSTER_INGRESS_VIP/greet-kubernetes

O resultado mostra uma mensagem Hello, Kubernetes!:

Hello Kubernetes!

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.

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

Elimine o Ingress:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete ingress my-ingress

Para processar o tráfego do serviço que criou anteriormente, crie um novo Ingress que tenha uma secção tls. Isto ativa o HTTPS entre os clientes e o proxy de entrada.

Segue-se um manifesto para um Ingress:

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

Guarde o manifesto num ficheiro com o nome my-ingress-2.yaml e crie o Ingress:

kubectl apply --kubeconfig USER_CLUSTER_KUBECONFIG -f my-ingress-2.yaml

Confirme através de testes.

  • Teste o caminho /greet-the-world:

    curl -v --resolve altostrat.com:443:USER_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:USER_CLUSTER_INGRESS_VIP https://altostrat.com/greet-kubernetes --cacert root-ca.crt
    

    Saída:

    Hello Kubernetes!
    

Limpar

Elimine o seu Ingress:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete ingress INGRESS_NAME

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

Elimine o seu serviço:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete service hello-service

Elimine a sua implementação:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete deployment hello-deployment