Prefácio
A seguir, um exemplo de integração do Kubernetes com o serviço Edgio Delivery CDN para profissionais experientes do Kubernetes. Ele assume um nível de conhecimento em Kubernetes e conhecimento de protocolos padrão de internet, como TCP, DNS e HTTP/HTTPS. O objetivo final é demonstrar uma maneira de fazer com que o serviço Edgio Delivery CDN apareça como entrada padrão. O utilizador do Kubernetes pode manter a configuração de entrada em sistemas familiares como o Portainer ou o terraform .
Kubernetes
O Kubernetes.io define o Kubernetes como “um sistema de código aberto para automatizar a implementação, o escalonamento e o gerenciamento de aplicativos em contentores.” Há várias maneiras de criar um cluster. A maneira mais rápida e fácil é aproveitar um dos muitos provedores de nuvem que permitem implantações de “um clique”.
Os clusters do Kubernetes contêm muitas partes. Na demonstração, vamos concentrar-nos num subconjunto do total.
Peças do Kubernetes
- Nó: Máquina ou VM que aloja cargas de trabalho e serviços.
- Carga de trabalho: Aplicação simples ou complexa
- POD: Recipientes dentro dos quais o software da aplicação está a ser executado. Um ou mais pods compõem uma carga de trabalho.
- Serviço: Um mecanismo que expõe uma carga de trabalho a outras cargas de trabalho ou cargas de trabalho
- Ingress: Um mecanismo para expor serviços ao mundo exterior
Edgio
Edgio torna a vida ligada mais rápida, mais segura e mais simples de gerir, fornecendo velocidade, segurança e simplicidade inigualáveis na ponta com as nossas soluções integradas de entrega, aplicações e, streaming. A nossa tecnologia de escala global e serviços especializados alimentam as melhores marcas do mundo com a capacidade de oferecer a educação, entretenimento, eventos e aplicações mais rápidas, mais dinâmicas e sem atrito, a todos os utilizadores. Dedicado a fornecer atendimento inigualável ao cliente e aumentar o valor a cada passo do caminho, Edgio é um parceiro de eleição, impulsionando o tráfego mundial da Internet para apoiar os programas, filmes, esportes, jogos e música mais populares e sites de carregamento instantâneo.
Arquitectura
Edgio Delivery CDN
Para esta demonstração, usamos o Edgio python SDK no GitHub – lnw/llnw-sdk-python: Limelight Networks Python SDK. A configuração básica será mantida simples.
Ao configurar a CDN, são necessários os seguintes dados (que não a autenticação).
- Nome curto: Um identificador exclusivo no Edgio Delivery CDN que contém regras de CDN.
- Nome de anfitrião publicado: O nome de anfitrião que está virado para a Internet a partir da CDN. No caso desta demonstração, o nome de anfitrião cstradtman.s.llnwi.net foi previamente configurado.
- Caminho de URL publicado: O caminho mapeado para a regra específica em questão.
- Nome do anfitrião da fonte: O nome do anfitrião da origem. Neste caso, um recorde de round-robin aponta para o cluster do Kubernetes.
- Caminho do URL de origem: O caminho de destino associado ao nome do anfitrião. Neste caso, estará em branco, uma vez que o descrevemos mais tarde neste documento. Nesta demonstração, as cargas de trabalho serão diferenciadas por número de porta e não por caminho.
DNS
A demonstração usa a API de DNS Vultr. Configurar a CDN usando endereços IP como origens não é uma prática recomendada. A demonstração usa uma API para criar ou modificar um round-Robin Um registo a apontar para os nós do cluster.
Cluster
A demonstração está no Vultr num cluster de três nós.
Namespaces
A demonstração existirá sob o namespace padrão, uma vez que é a única coisa em execução neste cluster
Nós
- Cluster VKE – 3 nós cada um com
- 4G ram
- Disco de 80 G
- 2 vCPU
- Rede 1 G.
Cargas de trabalho
A carga de trabalho é um programa Python simples que retorna informações básicas sobre a conexão HTTP. Nós implantamos esta demonstração em linha, que não é um método de implementação típico. No entanto, permite que a demonstração seja totalmente independente em vez de ter dependências externas para construir os contentores e armazená-los. O código-fonte está no apêndice 1. O código Python está em itálico, e o código YAML que descreve a implementação não é. A carga de trabalho utiliza a porta 8000 do TCP.
Serviços
Existem vários tipos de serviço disponíveis. Estamos a utilizar o tipo de serviço NodePort. Ele expõe o serviço nos endereços IP externos do cluster em um número de porta alto selecionado aleatoriamente. O Kubernetes cuida da conexão com um nó onde a carga de trabalho é executada.
Entrada
O Kubernetes Ingress é um objeto de software que descreve o comportamento de uma coleção de recursos que tornam um serviço Kubernetes disponível fora do cluster.
Um controlador de entrada combina software e/ou hardware que instancia o objeto de software de entrada.
Uma CDN é um proxy reverso distribuído rico em recursos, além da função de proxy reverso, os CDNs geralmente têm algoritmos de cache flexíveis, diversidade geográfica, recursos de segurança (ACLS (GEO, método, regex), firewalls de aplicativos da Web, marca d’água e outros recursos mais avançados não encontrados em simples proxies reversos.
As APIs para o monitoramento de objetos do Kubernetes são bem definidas, e vários proxies reversos de HTTP e balanceadores de carga foram estendidos para funcionar como controladores de entrada. Por exemplo, O NGINX e o HAProxy são proxies da velha escola que foram estendidos para funcionar como controladores de entrada e aqueles como o Traefik e o Itsio foram desenvolvidos em paralelo ao Kubernetes. Uma CDN é uma próxima progressão natural a partir de simples proxies reversos. No caso desta demonstração, vamos criar um controlador de entrada personalizado que controla o Edgio Delivery CDN. Os dados normalmente necessários para descrever uma entrada são
- Nome de anfitrião público: O nome de anfitrião em que o serviço Kubernetes estará disponível
- Caminho público: O caminho associado ao nome de anfitrião público em que os serviços do Kubernetes estarão disponíveis
- Nome do serviço de back-end: Nome do serviço definido por uma estrofe de serviços do Kubernetes
- Porta de back-end: Um nome que corresponde à descrição da porta na descrição do serviço
Mapeamentos de ativos CDN da Edgio Delivery:
Kubernetes |
Edgio Delivery CDN |
Nome de anfitrião público |
Nome do anfitrião publicado |
Caminho Público |
Caminho de URL publicado |
Nome do serviço de back-end Único dentro do cluster do Kubernetes Não conhecido/disponível para o mundo exterior |
Nome do anfitrião de origem Nome de domínio totalmente qualificado Na verdade, não um para um |
A lógica por trás disso é:
- Escutar o evento de entrada de namespace do cluster
- Se o tipo de evento for “adicionado”.
- Obter o endereço IP dos nós no cluster
- Criar registo de DNS no vultr
- Crie regras de CDN no Edgio CDN apontando para os registros de DNS criados e para a porta alocada pelo serviço NodePort.
- Se o tipo de evento for “modificado”.
- Encontre regras de CDN no Edgio CDN que correspondam à entrada existente
- Modificar regras no Edgio CDN para refletir novos dados no evento
- Se o tipo de evento for “excluído”.
- Encontre regras de CDN no Edgio CDN que correspondam à entrada removida
- Remova os registos DNS no Vultr associados a esta entrada
- Remova as regras de CDN no Edgio que correspondem à entrada removida
Configuração
Objectos
Os objetos do Kubernetes são descritos em arquivos YAML. No Kubernetes, cada configuração é um objeto. Você pode colocar todas as configurações de implantação em um único arquivo. É prática comum dividi-los com base na parte da implementação que descrevem.
Implementação
No apêndice 1, há um grande arquivo YAML que é uma combinação de código Python e YAML. Tudo depois do “spec.template.spec.containers.command” é o código Python que é transformado num contentor durante a implementação. Do ponto de vista do objeto Kubernetes as linhas que são importantes para nós para a demonstração são:
- Tipo: Implementação – descreve o objeto como uma implementação
- Metadata.name: O nome é usado pelo objeto de serviço para criar a ligação entre os dois.
- Spec.selector.matchlabels.app: diz a que pods a implementação será aplicada.
- Spec.template.spec.containers.image: Aponta para a imagem oficial do docker Hub python 3
- Spec.template.spec.containers.ports.name: Um rótulo para a porta a ser referenciada no serviço de outros objetos neste caso
- Spec.template.spec.containers.ports.containerport: Lista a porta tcp exposta do contentor em execução
Serviço
- Tipo: Implementação – descreve o objeto como uma implementação
- Metadata.name: O nome é usado pelo objeto de entrada para criar a ligação entre os dois.
- Spec.selector.app: aponta para o nome da implementação – pywai-inline-serviço como nomeado no objeto deployment.
- Spec.selector.type: Nodeport Isto define este serviço como o tipo Nodeport, conforme descrito acima
- Spec.ports.name: A etiqueta para a porta a ser referenciada por outros objetos (neste caso, entrada)
- Spec.ports.protocol: define o protocolo IP em uso – TCP
- Spec.ports.port: Define a porta exposta por este serviço
- Spec.ports.targetPort: Aponta para a porta exposta pela implementação – pywai-inline-deployment neste caso
Entrada
No apêndice 3, você verá o arquivo YAML descrevendo o objeto Kubernetes para o controlador Edgio Ingress. Os objetos com que se preocupar são:
- Tipo: Entrada – Isto diz ao Kubernetes que é um objeto de entrada
- Medatdata.name – Tudo no Kubernetes deve ter um nome
- Metadata.labels.cdn – Esta tag é usada para sinalizar ao controlador de entrada que este objeto é para o controlador de entrada edgio
- Spec.rules.host – nome de anfitrião público para expor o serviço.
- Spec.rules.http.paths.path – caminho associado ao serviço.
- Spec.rules.http.paths.backend.service.name – etiqueta do serviço a expor
- Spec.rules.http.paths.backend.service.port.name – etiqueta da porta do serviço a expor
Configurar mapas
Segredos
O Kubernetes tem um conceito integrado de segredos para o armazenamento de dados confidenciais. Esta demonstração utiliza isto para os nomes de utilizador e chaves partilhadas tanto para o Edgio SDK como para a API de DNS Vultr
Exemplos de código
O código para esta demonstração incluído no git repos
- Edgio Delivery python SDK
- Implementação de demonstração do Kubernetes
- https://github.com/llnw/edgio-delivery-k8s-demo
- Estes são uma série de objetos Kubernetes descritos como yaml que mostram como implementar a integração do Edgio Delivery
- Demonstração do controlador Edgio Delivery Ingress
- https://github.com/llnw/edgio-delivery-k8s-ingress-demo
- Este é o código real que implementa o controlador Edgio Delivery Ingress
- A longo prazo, deve ser executado como um serviço dentro do Kubernetes, no entanto, para manter a demonstração simples, simplesmente roda como um processo separado
Futuras adições e melhorias ao design atual
Em um post futuro, vamos mostrar como aproveitar outras soluções Edgio, por exemplo, aplicações. Poderíamos usar o cluster do Kubernetes como uma forma de aproveitar e sincronizar configurações entre várias ofertas do Edgio CDN para diferentes fluxos de trabalho.
Apêndice 1 – pywai-inline-deployment.yaml
ApiVersion: Apps/v1
Tipo: Implementação
metadados:
nome: pywai-inline-deployment
espec.:
seletor:
MatchLabels:
app: pywai-inline-deployment
réplicas: 1
modelo:
metadados:
etiquetas:
app: pywai-inline-deployment
espec.:
recipientes:
– nome: python
imagem: python: 3
comando:
– /bin/sh
– c
– |
cat > /test.py <<EOF
/usr/bin/env python3
“””
Servidor HTTP muito simples no python para pedidos de log
Uso::
./server.py< [ porto>]
“””
A partir de http.server, importe BaseHTTPRequestHandler, HTTPServer
importar registo
importar pprint
Classe S (BaseHTTPRequestHandler):
def _set_response(auto):
self.send_response(200)
self.send_header(‘Content-type’, ‘texto/html’)
auto.end_headers()
def do_get(auto):
logging.info(“GET Request, Caminho: %S cabeçalhos: N%s, str(auto.path), str(pprint.pformat(auto.headers)))
auto._set_response()
pprint.pformat(self.headers.items())
pprint.pformat(auto.cliente_endereço)
pprint.pformat(auto.requestline)
pprint.pformat(auto.request_version)
auto.wfile.write(“<pré>< /pre >”.format(headerinfo).encode(‘utf-8’))
auto.wfile.write(“<>pre </pre>”.format(cliente).encode(‘utf-8’))
auto.wfile.write(“<pré>< /pre >”.format(lineinfo).encode(‘utf-8’))
auto.wfile.write(“<>pre </pre>”.format(versioninfo).encode(‘utf-8’))
def run (server_class) HTTPServer, handler_class, port-8080):
Logging.basicConfig(nível-logging.INFO)
endereço_do_servidor: (“, porta)
servidor_classe(server_address, handler_class)
logging.info(‘Starting (… n’)
tentar:
httpd.serve_forever()
Exceto KeyboardInterrupt:
passe
httpd.server_close()
logging.info(‘Stopping (… n’)
se __name__ == ‘__principal_’:
do sistema de importação argv
se len(argv) == 2:
run (port-int(argv[1])
mais:
correr ()
EOF
exec python /test.py 8000
portas:
– nome: http
ContainerPort: 8000
Apêndice 2 – pywai-inline-serviço.yaml
ApiVersion: v1
Tipo: Serviço
metadados:
nome: pywai-inline-serviço
espec.:
seletor:
app: pywai-inline-deployment
Tipo: NodePort
portas:
– nome: http
Protocolo: TCP
porto: 80
TargetPort: 8000
Apêndice 3 – pywai-edgio-Ingress.yaml
ApiVersion: Networking.k8s.io/v1
Tipo: Entrada
metadados:
nome: externo-pywai-inline-ingress
anotações:
kubernetes.io/ingress.class: edgio
etiquetas:
cdn: edgio
espec.:
regras:
– HOST<: Digite o nome abreviado único> .s.llnwi.net
http:
caminhos:
– caminho: /fred
PathType: Exato
back-end:
serviço:
nome: externo-pywai-inline-serviço
porta:
nome: pywai-port