One place for hosting & domains

      CertManager

      How to Set Up an Nginx Ingress with Cert-Manager on DigitalOcean Kubernetes


      Introdução

      Os Ingresses do Kubernetes permitem o roteamento do tráfego externo ao cluster do seu Kubernetes de maneira flexível para os Serviços dentro de seu cluster. Essa condição é alcançada quando usamos os Recursos de Ingress – que definem as regras para rotear o tráfego do HTTP e HTTPS para os Serviços do Kubernetes e para os *Controladores *do Ingress, os quais implementam as regras fazendo o balanceamento da carga do tráfego e o seu roteamento para os serviços de backend apropriados. Nginx, Contour, HAProxy e o Traefik são controladores Ingress populares. Os Ingresses fornecem uma alternativa mais eficiente e flexível para configurar vários serviços de LoadBalancer, cada qual usando seu próprio Load Balancer dedicado.

      Neste guia, vamos configurar o Controlador Ingress para Nginx – mantido pelo Kubernetes – e criaremos alguns Recursos de Ingress para rotear o tráfego para vários serviços de back-end fictício. Uma vez configurado o Ingress, vamos instalar o cert-manager no nosso cluster para gerenciar e fornecer certificados TLS para criptografar o tráfego de HTTP para o Ingress.

      Pré-requisitos

      Antes de começar com este guia, você deve ter o seguinte disponível:

      • Um cluster do Kubernetes 1.10+ com controle de acesso baseado em função (RBAC) habilitado
      • A ferramenta kubectl de linha de comando instalada em sua máquina local e configurada para se conectar ao seu cluster. Você pode ler mais sobre como instalar o kubectl na documentação oficial.
      • Um registro de nome de domínio e DNS A que você possa apontar para o DigitalOcean Load Balancer usado pelo Ingress. Se estiver usando o DigitalOcean para gerenciar os registros de DNS do seu domínio, consulte Como gerenciar os registros de DNS para aprender como criar um registro A.
      • O gerenciador de pacotes Helm instalado em sua máquina local e o Tiller instalados no seu cluster, como descrito no tópico Como instalar um software nos clusters do Kubernetes com o gerenciador de pacotes Helm. Certifique-se de que esteja usando o Helm v2.12.1 ou posterior, senão podem ocorrer problemas ao instalar o gráfico Helm cert-manager. Para verificar a versão do Helm que está instalada, execute a helm version em sua máquina local.
      • O utilitário de linha de comando wget instalado em sua máquina local. Você pode instalar o wget utilizando o gerenciador de pacotes integrado em seu sistema operacional.

      Assim que tiver esses componentes configurados, você estará pronto para começar com este guia.

      Passo 1 — Configurando os serviços de back-end fictício

      Antes de implantar o Controlador Ingress, primeiro vamos criar e implantar dois serviços de eco fictício para os quais vamos rotear o tráfego externo usando o Ingress. Os serviços de eco irão executar o contêiner de servidor Web hashicorp/http-echo, os quais retornarão uma página com uma string de texto transmitida quando o servidor Web for iniciado. Para aprender mais sobre o http-echo, consulte seu GitHub Repo e, para aprender mais sobre os Kubernetes Services, consulte o tópico Serviços dos documentos oficiais do Kubernetes.

      Na sua máquina local, crie e edite um arquivo chamado de eco1.yaml usando o nano ou seu editor favorito:

      Cole no manifesto de Serviço e implantação a seguir:

      echo1.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: echo1
      spec:
        ports:
        - port: 80
          targetPort: 5678
        selector:
          app: echo1
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: echo1
      spec:
        selector:
          matchLabels:
            app: echo1
        replicas: 2
        template:
          metadata:
            labels:
              app: echo1
          spec:
            containers:
            - name: echo1
              image: hashicorp/http-echo
              args:
              - "-text=echo1"
              ports:
              - containerPort: 5678
      

      Neste arquivo, definimos um serviço chamado echo1 que faz o roteamento do tráfego para os Pods com o seletor de rótulo app: echo1. Ele aceita o tráfego TCP na porta 80 e o roteia para a porta 5678 -a porta padrão do http-echo.

      Em eguida, definimos uma Implantação, também chamada de echo1, a qual gerencia os Pods com o Seletor de rótulo app:echo1. Especificamos que a Implantação deve ter 2 réplicas de Pod e que os Pods devem iniciar um contêiner chamado echo1 executando a imagem hashicorp/http-echo. Passamos no parâmetro text e o configuramos para o echo1, para que o servidor Web http-echo retorne echo1. Por fim, abrimos a porta 5678 no contêiner do Pod.

      Assim que estiver satisfeito com seu serviço fictício e o manifesto de implantação, salve e feche o arquivo.

      Crie os recursos do Kubernetes usando o kubectl create com o sinalizador -f, especificando o arquivo que você acabou de salvar como um parâmetro:

      • kubectl create -f echo1.yaml

      Você deve ver o seguinte resultado:

      Output

      service/echo1 created deployment.apps/echo1 created

      Verifique se o serviço iniciou corretamente, confirmando que ele tem um ClusterIP, o IP interno no qual o serviço será exposto:

      Você deve ver o seguinte resultado:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE echo1 ClusterIP 10.245.222.129 <none> 80/TCP 60s

      Isso indica que o serviço de echo1 está disponível internamente em 10.245.222.129 na porta 80. Ele encaminhará o tráfego para a containerPort 5678 nos Pods que ele selecionar.

      Agora que o serviço de echo1 está em execução, repita esse processo para o serviço echo2.

      Crie e abra um arquivo chamado echo2.yaml:

      echo2.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: echo2
      spec:
        ports:
        - port: 80
          targetPort: 5678
        selector:
          app: echo2
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: echo2
      spec:
        selector:
          matchLabels:
            app: echo2
        replicas: 1
        template:
          metadata:
            labels:
              app: echo2
          spec:
            containers:
            - name: echo2
              image: hashicorp/http-echo
              args:
              - "-text=echo2"
              ports:
              - containerPort: 5678
      

      Aqui, usamos basicamente o mesmo manifesto de Serviço e implantação acima, mas nomeamos e rotulamos novamente o Serviço e implantação echo2. Além disso, para darmos mais variedade, criaremos apenas 1 réplica do Pod. Nós garantimos que definimos o parâmetro text para o echo2 para que o servidor Web retorne o texto echo2.

      Salve e feche o arquivo e crie os recursos do Kubernetes usando o kubectl:

      • kubectl create -f echo2.yaml

      Você deve ver o seguinte resultado:

      Output

      service/echo2 created deployment.apps/echo2 created

      Novamente, verifique se o serviço está em execução:

      Você deve ver tanto o serviço echo1 como o serviço echo2 com ClusterIPs atribuídos:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE echo1 ClusterIP 10.245.222.129 <none> 80/TCP 6m6s echo2 ClusterIP 10.245.128.224 <none> 80/TCP 6m3s kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 4d21h

      Agora que nossos serviços de Web echo fictícios estão em execução, podemos seguir em frente para implantar o Controlador Ingress para o Nginx.

      Passo 2 — Configurando o Controlador Ingress do Kubernetes para Nginx

      Neste passo, vamos implantar a versão v0.24.1 do Controlador Ingress para Nginx mantido pelo Kubernetes. Note que existem vários Controladores Ingress para Nginx; a comunidade do Kubernetes mantém o controlador que iremos usar neste guia e a Nginx Inc. mantém o kubernetes-ingress. As instruções neste tutorial são baseadas controladores do Guia de instalação oficial para o Controlador Ingress da Kubernetes para Nginx.

      O Controlador Ingress para Nginx consiste de um Pod que executa o servidor Web Nginx e monitora o plano de controle do Kubernetes em relação aos objetos novos e atualizados de Recursos de Ingress. Um recurso Ingress é, essencialmente, uma lista de regras de roteamento de tráfego para serviços de back-end. Por exemplo, uma regra de Ingress pode especificar que o tráfego HTTP chegando no caminho /web1 deve ser direcionado para o servidor Web de back-end web1. Ao usar os recursos de Ingress, é possível realizar o roteamento baseado em host: por exemplo, roteando os pedidos que chegarem para o web1.your_domain.com para o Serviço de back-end do Kubernetes web1.

      Neste caso, devido a estarmos implantando o controlador Ingress para um cluster de Kubernetes da DigitalOcean, o controlador criará um serviço de LoadBalancer, que irá inicializar um balanceador de carga da DigitalOcean para o qual todo o tráfego externo será direcionado. Este balanceador de carga fará o roteamento do tráfego externo para o Pod do controlador Ingress que executa o Nginx, que, na sequência, encaminhará o tráfego para os serviços de back-end apropriados.

      Vamos começar criando os recursos necessários do Kubernetes pelo Controlador Ingress para Nginx. Tais recursos incluem os ConfigMaps que contêm a configuração do controlador, funções de controle de acesso baseado em função (RBAC) para conceder o acesso do controlador à API do Kubernetes, além da Implantação real do controlador Ingress que usa a versão v0.24.1 da imagem do controlador Ingress para Nginx. Para ver uma lista completa dos recursos necessários, consulte o manifesto do repositório Github do Controlador Ingress para Nginx do Kubernetes.

      Para criar esses recursos obrigatórios, utilize o kubectl apply e o sinalizador -f para especificar o arquivo do manifesto hospedado no GitHub:

      • kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/mandatory.yaml

      Usamos o recurso apply em vez do create para que, no futuro, possamos usar cada vez mais usar o apply para modificar os objetos do controlador Ingress, em vez de substituí-los completamente. Para aprender mais sobre o apply, consulte o tópico Gerenciando recursos dos documentos oficiais do Kubernetes.

      Você deve ver o seguinte resultado:

      Output

      namespace/ingress-nginx created configmap/nginx-configuration created configmap/tcp-services created configmap/udp-services created serviceaccount/nginx-ingress-serviceaccount created clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created role.rbac.authorization.k8s.io/nginx-ingress-role created rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created deployment.extensions/nginx-ingress-controller created

      Este resultado também serve como um resumo conveniente de todos os objetos do controlador Ingress criados a partir do manifesto mandatory.yaml.

      Em seguida, vamos criar o serviço LoadBalance do controlador Ingress, o qual criará um Load Balancer da Digital Ocean que irá balancear a carga e rotear o tráfego de HTTP e HTTPS para o Pod do Controlador Ingress implantado no comando anterior.

      Para criar o serviço do LoadBalancer, mais uma vez, utilize o kubectl apply - um arquivo de manifesto que contém a definição do serviço:

      • kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/provider/cloud-generic.yaml

      Você deve ver o seguinte resultado:

      Output

      service/ingress-nginx created

      Agora, confirme que o Load Balancer da DigitalOcean foi criado com sucesso, buscando os detalhes do serviço com o kubectl:

      • kubectl get svc --namespace=ingress-nginx

      Você deve ver um endereço IP externo, correspondente ao endereço IP do Load Balancer da DigitalOcean:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx LoadBalancer 10.245.247.67 203.0.113.0 80:32486/TCP,443:32096/TCP 20h

      Anote o endereço de IP externo do Load Balancer, já que você precisará dele em um passo mais a frente.

      Nota: por padrão, o serviço LoadBalancer do Ingress para Nginx tem o service.spec.externalTrafficPolicy ajustado para o valor Local, o qual faz o roteamento do tráfego do balancedor de carga para os nós que executam os Pods do Ingress para Nginx. Os outros nós irão fracassar nas inspeções de integridade do balanceador de carga - propositadamente, de modo aque o tráfego do Ingress não seja roteado para os nós. As políticas de tráfego externas estão além do âmbito deste tutorial, mas para saber mais a respeito, consulte Um aprofundamento nas políticas de tráfego externo do Kubernetes e IP de origem para serviços com o Type=LoadBalancer dos documentos oficiais do Kubernetes.

      Este balanceador de carga recebe o tráfego nas portas HTTP e HTTPS 80 e 443 e o encaminha para o pod do controlador Ingress. Na sequência, o controlador Ingress irá rotear o tráfego para o serviço de back-end apropriado.

      Agora podemos apontar nossos registros de DNS neste Load Balancer externo e criar alguns recursos de Ingress para implementar regras de roteamento de tráfego.

      Passo 3 — Criando o Recurso do Ingress

      Vamos começar criando um recurso de Ingress mínimo para rotear o tráfego direcionado a um dado subdomínio para um serviço de back-end correspondente.

      Neste guia, vamos usar o domínio teste example.com. Você deve substituí-lo por um nome de domínio seu.

      Primeiramente, vamos criar uma regra simples para rotear o tráfego direcionado para echo1.example.com para o serviço de back-end do echo1 e o tráfego direcionado para o echo2.example.com para o serviço de back-end do echo2.

      Inicie abrindo um arquivo chamado echo_ingress.yaml no seu editor favorito:

      Cole na seguinte definição de ingresso:

      echo_ingress.yaml

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: echo-ingress
      spec:
        rules:
        - host: echo1.example.com
          http:
            paths:
            - backend:
                serviceName: echo1
                servicePort: 80
        - host: echo2.example.com
          http:
            paths:
            - backend:
                serviceName: echo2
                servicePort: 80
      

      Quando terminar de editar suas regras do Ingress, salve e feche o arquivo.

      Aqui, especificamos que gostaríamos de criar um resurso de Ingress chamado echo-ingress e rotear o tráfeco com base no cabeçalho do Host. O cabeçalho de Host com um pedido de HTTP especifica o nome de domínio do servidor de destino. Para aprender mais sobre os cabeçalhos de pedidos do Host, consulte a página de definições da Rede de Desenvolvedores da Mozilla (MDN). Os pedidos junto ao host echo1.example.com serão direcionados para o back-end echo1 - configurado no Passo 1 - e os pedidos junto ao host echo2.example.com serão direcionados para o back-end echo2.

      Agora, você pode criar o Ingress usando o kubectl:

      • kubectl apply -f echo_ingress.yaml

      Você verá o seguinte resultado confirmando a criação do Ingress:

      Output

      ingress.extensions/echo-ingress created

      Para testar o Ingress, navegue até o seu serviço de gerenciamento DNS e crie registros A para o echo1.example.com e echo2.example.com apontando para o IP externo do balanceador de carga da DigitalOcean. O IP externo do balanceador de carga é o endereço IP externo do serviço ingress-nginx, que buscamos no passo anterior. Se estiver usando o DigitalOcean para gerenciar os registros de DNS do seu domínio, consulte Como gerenciar os registros de DNS para aprender como criar um registro A.

      Assim que você tiver criado os registros DNS echo1.example.com e echo2.example.com necessários, você pode testar controlador e o recurso do Ingress que criou, utilizando o utilitário de linha de comando curl.

      De sua máquina local, faça o curl do serviço echo1:

      Você deve obter a seguinte resposta do serviço echo1:

      Output

      echo1

      Isso confirma que seu pedido de echo1.example.com está sendo roteado corretamente através do Ingress para Nginx para o serviço de back-end echo1.

      Agora, faça o mesmo teste com o serviço echo2:

      Você deve obter a seguinte resposta do serviço echo2:

      Output

      echo2

      Isso confirma que seu pedido para o echo2.example.com está sendo roteado corretamente através do Ingress para Nginx para o serviço de back-end echo2.

      Neste ponto, você terá definido um Ingress para Nginx básico para executar o roteamento com base em host virtual. No próximo passo, vamos instalar o cert-manager usando o Helm para fornecer certificados TLS para nosso Ingress e habilitar o protocolo HTTPS mais seguro.

      Passo 4 — Instalando e configurando o Cert-Manager

      Neste passo, vamos usar o Helm para instalar o cert-manager no nosso cluster. O cert-manager é um serviço do Kubernetes que fornece certificados TLS do Let’s Encrypt e outras autoridades certificadoras e também gerencia seus ciclos de vida. Os certificados podem ser solicitados e configurados através de observações nos recursos do Ingress junto das notas técnicas do certmanager.k8s.io/issuer, anexando-se uma seção de tls para as especificações do Ingress e configurando-se um ou mais Emissores para especificar a autoridade certificadora de sua preferência. Para aprender mais sobre os objetos do Emissor, consulte a documentação oficial do cert-manager sobre Emissores.

      Nota: certifique-se de que esteja usando o Helm v2.12.1 ou posterior antes de instalar o cert-manager. Para verificar a versão do Helm que está instalada, execute a helm version em sua máquina local.

      Antes de usar o Helm para instalar o cert-manager no nosso cluster, precisamos criar as Definições de recursos personalizadas (CRDs) do cert-manager. Crie-as aplicando-as diretamente do repositório do Github do cert-manager:

      • kubectl apply
      • -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.8/deploy/manifests/00-crds.yaml

      Você deve ver o seguinte resultado:

      Output

      customresourcedefinition.apiextensions.k8s.io/certificates.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/issuers.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/clusterissuers.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/orders.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/challenges.certmanager.k8s.io created

      Em seguida, vamos adicionar um rótulo no namespace kube-system, onde vamos instalar o cert-manager a fim de habilitarmos a validação de recursos avançados usando um webhook:

      • kubectl label namespace kube-system certmanager.k8s.io/disable-validation="true"

      Agora, vamos adicionar o repositório Jetstack Helm ao Helm. Esse repositório contém o gráfico Helm cert-manager.

      • helm repo add jetstack https://charts.jetstack.io

      Por fim, podemos instalar o gráfico no namespace kube-system:

      • helm install --name cert-manager --namespace kube-system jetstack/cert-manager --version v0.8.0

      Você deve ver o seguinte resultado:

      Output

      . . . NOTES: cert-manager has been deployed successfully! In order to begin issuing certificates, you will need to set up a ClusterIssuer or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer). More information on the different types of issuers and how to configure them can be found in our documentation: https://cert-manager.readthedocs.io/en/latest/reference/issuers.html For information on how to configure cert-manager to automatically provision Certificates for Ingress resources, take a look at the `ingress-shim` documentation: https://cert-manager.readthedocs.io/en/latest/reference/ingress-shim.html

      Isso indica que a instalação do cert-manager foi bem-sucedida.

      Antes de começar a emitir certificados para nossos hosts do Ingress, precisamos criar um emissor, o qual especifica a autoridade certificadora da qual será possível obter os certificados x509 assinados. Neste guia, vamos usar a autoridade o certificado do Let’s Encrypt, que fornece certificados TLS gratuitos e também oferece um servidor de preparação para a realização dos testes da configuração do seu certificado e um servidor de produção para implantar certificados TLS verificáveis.

      Vamos criar um emissor teste para garantir que o mecanismo de fornecimento do certificado esteja funcionando corretamente. Abra um arquivo chamado staging_issuer.yaml no seu editor de texto favorito:

      nano staging_issuer.yaml
      

      Cole no manifesto do ClusterIssuer a seguir:

      staging_issuer.yaml

      apiVersion: certmanager.k8s.io/v1alpha1
      kind: ClusterIssuer
      metadata:
       name: letsencrypt-staging
      spec:
       acme:
         # The ACME server URL
         server: https://acme-staging-v02.api.letsencrypt.org/directory
         # Email address used for ACME registration
         email: your_email_address_here
         # Name of a secret used to store the ACME account private key
         privateKeySecretRef:
           name: letsencrypt-staging
         # Enable the HTTP-01 challenge provider
         http01: {}
      

      Aqui, especificamos que queremos criar um objeto de ClusterIssuer chamado de letsencrypt-staging e usar o servidor de preparação do Let’s Encrypt. Mais tarde, vamos usar o servidor de produção para implantar nossos certificados. Entretanto, poderá haver solicitações de limitação de taxa em relação ao servidor, de modo que é melhor usar o URL de preparação para os testes.

      Depois, especificamos um endereço de e-mail para registrar o certificado e criamos um Kubernetes Secret chamado letsencrypt-staging para armazenar a chave privada da conta ACME. Também habilitamos o mecanismo de desafio do HTTP-01. Para aprender mais sobre esses parâmetros, consulte a documentação oficial do cert-manager sobre Emissores.

      Implemente o ClusterIssuer usando o kubectl:

      • kubectl create -f staging_issuer.yaml

      Você deve ver o seguinte resultado:

      Output

      clusterissuer.certmanager.k8s.io/letsencrypt-staging created

      Agora que criamos o nosso emissor preparatório do Let’s Encrypt, estamos prontos para modificar o recurso do Ingress que criamos acima e habilitar a criptografia TLS para os caminhos do echo1.example.com e do echo2.example.com.

      Abra novamente o echo_ingress.yaml no seu editor favorito:

      Adicione o seguinte ao manifesto recurso do Ingress:

      echo_ingress.yaml

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: echo-ingress
        annotations:  
          kubernetes.io/ingress.class: nginx
          certmanager.k8s.io/cluster-issuer: letsencrypt-staging
      spec:
        tls:
        - hosts:
          - echo1.example.com
          - echo2.example.com
          secretName: letsencrypt-staging
        rules:
        - host: echo1.example.com
          http:
            paths:
            - backend:
                serviceName: echo1
                servicePort: 80
        - host: echo2.example.com
          http:
            paths:
            - backend:
                serviceName: echo2
                servicePort: 80
      

      Aqui, adicionamos algumas anotações para especificar a ingress.class, a qual determina o controlador do Ingress que deve ser usado para implementar as regras do Ingress. Além disso, definimos o cluster-issuer para ser o letsencrypt-staging, o emissor de certificados que acabamos de criar.

      Por fim, adicionamos um bloco tls para especificar os hosts para os quais queremos adquirir certificados e especificar um secretName. Esse segredo irá conter a chave privada do TLS e o certificado emitido.

      Quando terminar de fazer as alterações, salve e feche o arquivo.

      Agora, vamos atualizar o recurso do Ingress existente usando o kubectl apply:

      • kubectl apply -f echo_ingress.yaml

      Você deve ver o seguinte resultado:

      Output

      ingress.extensions/echo-ingress configured

      É possível usar o kubectl describe para rastrear o estado das alterações do Ingress que acabou de aplicar:

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 14m nginx-ingress-controller Ingress default/echo-ingress Normal UPDATE 1m (x2 over 13m) nginx-ingress-controller Ingress default/echo-ingress Normal CreateCertificate 1m cert-manager Successfully created Certificate "letsencrypt-staging"

      Assim que o certificado tiver sido criado com sucesso, você poderá executar um describe adicional nele para confirmar que sua criação foi bem-sucedida:

      • kubectl describe certificate

      Você deve ver o seguinte resultado na seção Events:

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Generated 63s cert-manager Generated new private key Normal OrderCreated 63s cert-manager Created Order resource "letsencrypt-staging-147606226" Normal OrderComplete 19s cert-manager Order "letsencrypt-staging-147606226" completed successfully Normal CertIssued 18s cert-manager Certificate issued successfully

      Isso confirma que o certificado TLS foi emitido com sucesso e a criptografia do HTTPS agora está ativa para os dois domínios configurados.

      Agora, estamos prontos para enviar um pedido para um servidor echo de back-end para testar o funcionamento correto do HTTPS.

      Execute o comando wget a seguir para enviar um pedido para o echo1.example.com e imprima os cabeçalhos de resposta para o STDOUT:

      • wget --save-headers -O- echo1.example.com

      Você deve ver o seguinte resultado:

      Output

      URL transformed to HTTPS due to an HSTS policy --2018-12-11 14:38:24-- https://echo1.example.com/ Resolving echo1.example.com (echo1.example.com)... 203.0.113.0 Connecting to echo1.example.com (echo1.example.net)|203.0.113.0|:443... connected. ERROR: cannot verify echo1.example.com's certificate, issued by ‘CN=Fake LE Intermediate X1’: Unable to locally verify the issuer's authority. To connect to echo1.example.com insecurely, use `--no-check-certificate'.

      Isso indica que o HTTPS foi habilitado com sucesso, mas o certificado não pode ser verificado, já que ele é um certificado temporário falso emitido pelo servidor de preparação do Let’s Encrypt.

      Agora que testamos que tudo funciona usando esse certificado falso temporário, podemos implantar os certificados de produção para os dois hosts, o echo1.example.com e o echo2.example.com.

      Passo 5 — Implantando o emissor de produção.

      Neste passo, vamos modificar o procedimento usado para fornecer os certificados de preparo e gerar um certificado de produção válido e verificável para os nossos hosts de Ingress.

      Para começar, vamos primeiro criar um certificado de produção ClusterIssuer.

      Abra um arquivo chamado prod_issuer.yaml no seu editor favorito:

      nano prod_issuer.yaml
      

      Cole no manifesto seguinte:

      prod_issuer.yaml

      apiVersion: certmanager.k8s.io/v1alpha1
      kind: ClusterIssuer
      metadata:
        name: letsencrypt-prod
      spec:
        acme:
          # The ACME server URL
          server: https://acme-v02.api.letsencrypt.org/directory
          # Email address used for ACME registration
          email: your_email_address_here
          # Name of a secret used to store the ACME account private key
          privateKeySecretRef:
            name: letsencrypt-prod
          # Enable the HTTP-01 challenge provider
          http01: {}
      

      Note o URL diferente do servidor ACME e o nome da chave secreta do letsencrypt-prod.

      Quando terminar de editar, salve e feche o arquivo.

      Agora, implante esse Emissor usando o kubectl:

      • kubectl create -f prod_issuer.yaml

      Você deve ver o seguinte resultado:

      Output

      clusterissuer.certmanager.k8s.io/letsencrypt-prod created

      Atualize o echo_ingress.yaml para usar este novo emissor:

      Faça as seguintes alterações no arquivo:

      echo_ingress.yaml

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: echo-ingress
        annotations:  
          kubernetes.io/ingress.class: nginx
          certmanager.k8s.io/cluster-issuer: letsencrypt-prod
      spec:
        tls:
        - hosts:
          - echo1.example.com
          - echo2.example.com
          secretName: letsencrypt-prod
        rules:
        - host: echo1.example.com
          http:
            paths:
            - backend:
                serviceName: echo1
                servicePort: 80
        - host: echo2.example.com
          http:
            paths:
            - backend:
                serviceName: echo2
                servicePort: 80
      

      Aqui, atualizamos tanto o ClusterIssuer quanto o nome secreto para o letsencrypt-prod.

      Assim que estiver satisfeito com suas alterações, salve e feche o arquivo.

      Implemente as alterações usando o kubectl apply:

      • kubectl apply -f echo_ingress.yaml

      Output

      ingress.extensions/echo-ingress configured

      Espere alguns minutos para o servidor de produção do Let’s Encrypt emitir o certificado. Você pode rastrear o andamento do processo, usando a opção kubectl describe no objeto certificate:

      • kubectl describe certificate letsencrypt-prod

      Assim que você ver o seguinte resultado, significa que o certificado foi emitido com sucesso:

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Generated 82s cert-manager Generated new private key Normal OrderCreated 82s cert-manager Created Order resource "letsencrypt-prod-2626449824" Normal OrderComplete 37s cert-manager Order "letsencrypt-prod-2626449824" completed successfully Normal CertIssued 37s cert-manager Certificate issued successfully

      Agora, vamos realizar um teste usando o curl para verificar se o HTTPS está funcionando corretamente:

      Você deve ver o seguinte:

      Output

      <html> <head><title>308 Permanent Redirect</title></head> <body> <center><h1>308 Permanent Redirect</h1></center> <hr><center>nginx/1.15.9</center> </body> </html>

      Isso indica que os pedidos do HTTP estão sendo redirecionados para usar o HTTPS.

      Execute o curl em https://echo1.example.com:

      • curl https://echo1.example.com

      Agora, você deve ver o seguinte resultado:

      Output

      echo1

      É possível executar o comando anterior com o sinalizador detalhado -v para uma busca mais aprofundada no handshake do certificado e para verificar as informações do certificado.

      Neste ponto, você já terá configurado o HTTPS com sucesso usando um certificado do Let’s Encrypt para o Ingress do seu Nginx.

      Conclusão

      Neste guia, você configurou um Ingress para Nginx para balancear carga e rotear pedidos externos para serviços de backend dentro do seu cluster do Kubernetes. Você também protegeu o Ingress, instalando o provedor de certificados cert-manager e configurando um certificado do Let’s Encrypt para dois caminhos de host.

      Existem muitas alternativas para o controlador Ingress para Nginx. Para saber mais, consulte o tópico Controladores Ingress da documentação oficial do Kubernetes.



      Source link

      Как настроить Nginx Ingress с Cert-Manager в DigitalOcean Kubernetes


      Введение

      Сущности Ingress в Kubernetes обеспечивают гибкую маршрутизацию внешнего трафика кластера Kubernetes среди служб внутри кластера. Это достигается с помощью ресурсов Ingress, которые определяют правила маршрутизации трафика HTTP и HTTPS для служб Kubernetes, и контроллеров Ingress, которые реализуют правила порседством балансировки нагрузки трафика и его перенаправления на соответствующие службы серверной части. В число популярных контроллеров Ingress входят Nginx, Contour, HAProxy и Traefik. Сущности Ingress — это более эффективная и гибкая альтернатива настройке множеству разных объектов служб LoadBalancer, каждый из которых использует собственный выделенный балансировщик нагрузки.

      В этом руководстве мы настроим контроллер Nginx Ingress, обслуживаемый Kubernetes, и создадим несколько ресурсов Ingress для маршуртизации трафика на фиктивные серверные службы. После настройки Ingress мы установим в наш кластер cert-manager для управления и распределения сертификатами TLS для шифрования трафика HTTP в Ingress.

      Предварительные требования

      Прежде чем начать прохождение этого обучающего модуля, вам потребуется следующее:

      • Кластер Kubernetes 1.10+ с включенным контролем доступа на основе ролей (RBAC)
      • Инструмент командной строки kubectl, установленный на локальном компьютере и настроенный для подключения к вашему кластеру. Дополнительную информацию об установке kubectl можно найти в официальной документации.
      • Доменное имя и записи DNS A, которые можно направить на балансировщик нагрузки DigitalOcean, используемый Ingress. Если вы используете DigitalOcean для управления записями DNS вашего домена, руководство Управление записями DNS поможет вам научиться создавать записи класса A.
      • Диспетчер пакетов Helm на локальном компьютере и Tiller на кластере, установленные в соответствии с указаниями обучающего модуля «Установка программного обеспечения на кластерах Kubernetes с диспетчером пакетов Helm». Убедитесь, что вы используете версию Helm 2.12.1 или более позднюю, иначе могут возникнуть проблемы с установкой таблицы cert-manager в Helm. Чтобы проверить установленную версию Helm, запустите команду helm version на локальном компьютере.
      • Инструмент командной строки wget, установленный на локальном компьютере. Вы можете установить wget с помощью диспетчера пакетов, встроенного в операционную систему.

      Проверив наличие этих компонентов, вы можете начинать прохождение этого обучающего модуля.

      Шаг 1 — Настройка фиктивных серверных служб

      Перед развертыванием контроллера Ingress мы создадим и развернем две фиктивных службы echo, на которые будем перенаправлять внешний трафик с помощью Ingress. Службы echo будут запускать контейнер hashicorp/http-echo, возвращающий страницу с текстовой строкой, переданной при запуске веб-сервера. Дополнительную информацию по http-echo можно получить в GitHub Repo, а дополнительную информацию о службах Kubernetes можно найти в разделе Services в официальной документации Kubernetes.

      Создайте на локальном компьютере файл echo1.yaml и откройте его в nano или другом текстовом редакторе:

      Вставьте в него следующий манифест служб и развертывания:

      echo1.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: echo1
      spec:
        ports:
        - port: 80
          targetPort: 5678
        selector:
          app: echo1
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: echo1
      spec:
        selector:
          matchLabels:
            app: echo1
        replicas: 2
        template:
          metadata:
            labels:
              app: echo1
          spec:
            containers:
            - name: echo1
              image: hashicorp/http-echo
              args:
              - "-text=echo1"
              ports:
              - containerPort: 5678
      

      В этом файле мы определяем службу с именем echo1, которая перенаправляет трафик в поды с помощью селектора ярлыка app: echo1. Она принимает трафик TCP на порту 80 и перенаправляет его на порт 5678,используемый http-echo по умолчанию.

      Затем мы определяем развертывание с именем echo1, которое управляет подами с селектором app: echo1 Label Selector. Мы указываем, что в развертывании должно быть 2 копии пода, и что поды должны запускать контейнер echo1 с образом hashicorp/http-echo. Мы передаем параметр text и устанавливаем для него значение echo1, так что веб-сервер http-echo возвращает echo1. Наконец, мы открываем порт 5678 в контейнере подов.

      Проверив манифест фиктивной службы и развертывания, сохраните и закройте файл.

      Создайте ресурсы Kubernetes с помощью kubectl create с флагом -f, указав только что сохраненный файл в качестве параметра:

      • kubectl create -f echo1.yaml

      Вы должны увидеть следующий результат:

      Output

      service/echo1 created deployment.apps/echo1 created

      Убедитесь, что служба запустилась правильно, и проверьте наличие ClusterIP, внутреннего IP-адреса, по которому доступна служба:

      Вы должны увидеть следующий результат:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE echo1 ClusterIP 10.245.222.129 <none> 80/TCP 60s

      Это означает, что служба echo1 доступна по внутреннему IP-адресу 10.245.222.129 на порту 80. Она будет перенаправлять трафик в порт контейнера 5678 на выбранных ей подах.

      Теперь служба echo1 запущена, и мы можем повторить процедуру для службы echo2.

      Создайте и откройте файл с именем echo2.yaml:

      echo2.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: echo2
      spec:
        ports:
        - port: 80
          targetPort: 5678
        selector:
          app: echo2
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: echo2
      spec:
        selector:
          matchLabels:
            app: echo2
        replicas: 1
        template:
          metadata:
            labels:
              app: echo2
          spec:
            containers:
            - name: echo2
              image: hashicorp/http-echo
              args:
              - "-text=echo2"
              ports:
              - containerPort: 5678
      

      Здесь мы используем тот же манифест служб и развертывания, что и выше, но будем использовать имя и ярлык echo2. Кроме того, для разнообразия мы создадим только 1 копию пода. Для параметра text мы установим значение echo2, чтобы веб-сервер возвращал текст echo2.

      Сохраните и закройте файл и создайте ресурсы Kubernetes с помощью kubectl:

      • kubectl create -f echo2.yaml

      Вы должны увидеть следующий результат:

      Output

      service/echo2 created deployment.apps/echo2 created

      Еще раз проверьте, запущена ли служба:

      Вы должны увидеть службы echo1 и echo2 с назначенными им значениями ClusterIP:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE echo1 ClusterIP 10.245.222.129 <none> 80/TCP 6m6s echo2 ClusterIP 10.245.128.224 <none> 80/TCP 6m3s kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 4d21h

      Теперь наши фиктивные веб-службы эхо запущены, и мы можем перейти к развертыванию контроллера Nginx Ingress.

      Шаг 2 — Настройка контроллера Kubernetes Nginx Ingress

      На этом шаге мы развернем версию v0.24.1 контроллера Nginx Ingress, обслуживаемого Kubernetes. Существует несколько контроллеров Nginx Ingress. Сообщество Kubernetes обслуживает контроллер, используемый в этом обучающем модуле, а Nginx Inc. обслуживает kubernetes-ingress. Указания этого обучающего модуля основаны на приведенных в официальном руководстве по установке контроллера Kubernetes Nginx Ingress.

      Контроллер Nginx Ingress состоит из пода, который запускает веб-сервер Nginx и наблюдает за плоскостью управления Kubernetes для обнаружения новых и обновленных объектов ресурсов Ingress. Ресурс Ingress фактически представляет собой список правил маршрутизации трафика для серверных служб. Например, правило Ingress может указывать, что входящий трафик HTTP на пути /web1 следует перенаправлять на веб-сервер web1. С помощью ресурсов Ingress также можно выполнять маршрутизацию на базе хоста: например, запросы маршрутизации для web1.your_domain.com на серверную службу Kubernetes web1.

      В данном случае мы развертываем контроллер Ingress в кластере DigitalOcean Kubernetes, и контроллер создаст службу LoadBalancer, запускающую балансировщик нагрузки DigitalOcean, на который будет направляться весь внешний трафик. Балансировщик нагрузки будет направлять внешний трафик на под контроллера Ingress под управлением Nginx, откуда трафик будет перенаправляться в соответствующие серверные службы.

      Для начала мы создадим необходимые ресурсы Kubernetes для контроллера Nginx Ingress. В их число входят карты ConfigMaps, содержащие конфигурацию контроллера, роли системы RBAC, предоставляющие контроллеру доступ Kubernetes API, и фактическое развертывание контроллера Ingress, использующее версию 0.24.1 образа контроллера Nginx Ingress. Чтоб просмотреть полный список требуемых ресурсов, ознакомьтесь с манифестом репозитория контроллера Kubernetes Nginx Ingress на GitHub.

      Для создания этих обязательных ресурсов используйте команду kubectl apply с флагом -f для указания файла манифеста, размещенного на GitHub:

      • kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/mandatory.yaml

      Мы используем apply вместо create ,чтобы в будущем мы могли применять изменения к объектам контроллера Ingress, а не перезаписывать их полностью. Дополнительную информацию о команде apply можно найти в разделе «Управление ресурсами» в официальной документации по Kubernetes.

      Вы должны увидеть следующий результат:

      Output

      namespace/ingress-nginx created configmap/nginx-configuration created configmap/tcp-services created configmap/udp-services created serviceaccount/nginx-ingress-serviceaccount created clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created role.rbac.authorization.k8s.io/nginx-ingress-role created rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created deployment.extensions/nginx-ingress-controller created

      На этом экране результатов приведен удобный обзор всех объектов контроллера Ingress, созданных из манифеста mandatory.yaml.

      Далее мы создадим службу LoadBalancer контроллера Ingress, которая создаст балансировщик нагрузки DigitalOcean для балансировки и маршрутизации трафика HTTP и HTTPS на под контроллера Ingress, который мы развернули предыдущей командой.

      Для создания службы LoadBalancer мы снова используем команду kubectl apply с файлом манифеста, содержащим определение службы:

      • kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/provider/cloud-generic.yaml

      Вы должны увидеть следующий результат:

      Output

      service/ingress-nginx created

      Убедитесь, что балансировщик нагрузки DigitalOcean создан успешно, получив детали службы с помощью команды kubectl:

      • kubectl get svc --namespace=ingress-nginx

      Вы должны использовать внешний IP-адрес, соответствующий IP-адресу балансировщика нагрузки DigitalOcean:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx LoadBalancer 10.245.247.67 203.0.113.0 80:32486/TCP,443:32096/TCP 20h

      Запишите внешний IP-адрес балансировщика нагрузки, поскольку он потребуется вам позднее.

      Примечание. По умолчанию служба Nginx Ingress LoadBalancer использует для параметра service.spec.externalTrafficPolicy значение Local, в результате чего весь трафик балансировщика нагрузки перенаправляется на узлы, где запущены поды Nginx Ingress. Другие узлы целенаправленно не будут проходить проверки балансировщика нагрузки, чтобы трафик Ingress не направлялся на эти узлы. Политики внешнего трафика не описываются в этом обучающем модуле, но дополнительную информацию можно найти в руководствах «Подробное описание политик внешнего трафика Kubernetes» и «Исходный IP для служб с типом Type=LoadBalancer» в официальной документации по Kubernetes.

      Этот балансировщик нагрузки принимает трафик на портах HTTP и HTTPS 80 и 443, и перенаправляет его на под контроллера Ingress. Контроллер Ingress перенаправляет трафик на соответствующую серверную службу.

      Теперь мы сделаем так, чтобы наши записи DNS указывали на этот внешний балансировщик нагрузки, и создадим некоторые ресурсы Ingress для внедрения правил маршрутизации трафика.

      Шаг 3 — Создание ресурсов Ingress

      Для начала мы создадим минимальный ресурс Ingress для перенаправления трафика указанного субдомена на соответствующую серверную службу.

      В этом обучающем модуле мы используем тестовый домен example.com. Вы должны заменить его вашим доменным именем.

      Вначале мы создадим простое правило для перенаправления адресованного echo1.example.com трафика на серверную службу echo1 и адресованного echo2.example.com трафика на серверную службу echo2.

      Для начала откройте файл echo_ingress.yaml в предпочитаемом редакторе:

      Вставьте следующее определение Ingress:

      echo_ingress.yaml

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: echo-ingress
      spec:
        rules:
        - host: echo1.example.com
          http:
            paths:
            - backend:
                serviceName: echo1
                servicePort: 80
        - host: echo2.example.com
          http:
            paths:
            - backend:
                serviceName: echo2
                servicePort: 80
      

      Когда вы закончите редактирование правил Ingress, сохраните и закройте файл.

      Мы указали, что хотим создать ресурс Ingress с именем echo-ingress и перенаправлять трафик на базе заголовка Host. В запросе HTTP заголовок Host указывает доменное имя целевого сервера. Дополнительную информацию о заголовках Host можно найти на странице определений Mozilla Developer Network. Запросы хоста echo1.example.com будут перенаправляться на серверную службу echo1, настроенную на шаге 1, а запросы хоста echo2.example.com будут перенаправляться на серверную службу echo2.

      Теперь вы можете создать Ingress с помощью kubectl:

      • kubectl apply -f echo_ingress.yaml

      Вы увидите следующий экран результатов, подвтерждающий создание Ingress:

      Output

      ingress.extensions/echo-ingress created

      Чтобы протестировать Ingress, перейдите в службу управления DNS и создайте записи A для echo1.example.com и echo2.example.com, указывающие на внешний IP-адрес балансировщика нагрузки DigitalOcean. Внешний IP-адрес балансировщика нагрузки соответствует внешнему IP-адресу службы ingress-nginx, полученному на предыдущем шаге. Если вы используете DigitalOcean для управления записями DNS вашего домена, руководство Управление записями DNS поможет вам научиться создавать записи класса A.

      После создания необходимых записей echo1.example.com и echo2.example.com вы можете протестировать контроллер Ingress и созданные ресурсы с помощью утилиты командной строки curl.

      Выполните команду curl для службы echo1 на локальном компьютере:

      Вы должны получить следующий ответ от службы echo1:

      Output

      echo1

      Это подтверждает, что ваш запрос echo1.example.com правильно перенаправляется через Nginx ingress в серверную службу echo1.

      Теперь повторите этот тест для службы echo2:

      Вы должны получить следующий ответ от службы echo2:

      Output

      echo2

      Это подтверждает, что ваш запрос echo2.example.com правильно перенаправляется через Nginx ingress в серверную службу echo2.

      Вы успешно выполнили базовую настройку Nginx Ingress для маршрутизации на базе виртуального хоста. На следующем шаге мы установим cert-manager с помощью Helm для предоставления сертификатов TLS для Ingress и использования более защищенного протокола HTTPS.

      Шаг 4 — Установка и настройка Cert-Manager

      На этмо шаге мы используем Helm для установки cert-manager в нашем кластере. cert-manager — это служба Kubernetes, предоставляющая сертификаты TLS от Let’s Encrypt и других центров сертификации и управляющая их жизненными циклами. Сертификаты можно запрашивать и настраивать посредством аннотации ресурсов Ingress с помощью аннотации certmanager.k8s.io/issuer с добавлением раздела tls в спецификацию Ingress и настройкой одного или нескольких элементов Issuer для определения предпочитаемого центра сертификации. Дополнительную информацию об объектах Issuer можно найти в официальной документации cert-manager по элементам Issuer.

      Примечание. Перед установкой cert-manager убедитесь, что вы используете версию Helm 2.12.1 или более позднюю версию. Чтобы проверить установленную версию Helm, запустите команду helm version на локальном компьютере.

      Прежде чем использовать Helm для установки cert-manager в нашем кластере, нам нужно создать собственные определения ресурсов (CRD) для cert-manager. Используйте для их создания команду apply, чтобы применить их непосредственно из репозитория cert-manager на GitHub:

      • kubectl apply
      • -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.8/deploy/manifests/00-crds.yaml

      Вы должны увидеть следующий результат:

      Output

      customresourcedefinition.apiextensions.k8s.io/certificates.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/issuers.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/clusterissuers.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/orders.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/challenges.certmanager.k8s.io created

      Теперь мы добавим ярлык пространства имен kube-system, куда мы устанавливаем cert-manager, чтобы обеспечить расширенную проверку ресурсов с помощью webhook:

      • kubectl label namespace kube-system certmanager.k8s.io/disable-validation="true"

      Теперь мы добавим репозиторий Jetstack Helm в Helm. Этот репозиторий содержит таблицу Helm для cert-manager.

      • helm repo add jetstack https://charts.jetstack.io

      Наконец, мы установим таблицу в пространство имен kube-system:

      • helm install --name cert-manager --namespace kube-system jetstack/cert-manager --version v0.8.0

      Вы должны увидеть следующий результат:

      Output

      . . . NOTES: cert-manager has been deployed successfully! In order to begin issuing certificates, you will need to set up a ClusterIssuer or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer). More information on the different types of issuers and how to configure them can be found in our documentation: https://cert-manager.readthedocs.io/en/latest/reference/issuers.html For information on how to configure cert-manager to automatically provision Certificates for Ingress resources, take a look at the `ingress-shim` documentation: https://cert-manager.readthedocs.io/en/latest/reference/ingress-shim.html

      Это означает, что установка cert-manager выполнена успешно.

      Прежде чем мы начнем выдачу сертификатов для наших хостов Ingress, нам нужно создать элемент Issuer, определяющий центр сертификации, откуда можно получить подписанные сертификаты x509. В этом обучающем модуле мы используем центр сертификации Let’s Encrypt, предоставляющий бесплатные сертификаты TLS и обеспечивающий сервер для тестирования конфигурации сертификатов и рабочий сервер для развертывания проверяемых сертификатов TLS.

      Создадим тестовый элемент Issuer, чтобы проверить правильность работы механизма распределения сертификатов. Откройте файл с именем staging_issuer.yaml в своем любимом текстовом редакторе:

      nano staging_issuer.yaml
      

      Вставьте в него следующий манифест ClusterIssuer:

      staging_issuer.yaml

      apiVersion: certmanager.k8s.io/v1alpha1
      kind: ClusterIssuer
      metadata:
       name: letsencrypt-staging
      spec:
       acme:
         # The ACME server URL
         server: https://acme-staging-v02.api.letsencrypt.org/directory
         # Email address used for ACME registration
         email: your_email_address_here
         # Name of a secret used to store the ACME account private key
         privateKeySecretRef:
           name: letsencrypt-staging
         # Enable the HTTP-01 challenge provider
         http01: {}
      

      Здесь мы указываем, что хотим создать объект ClusterIssuer с именем letsencrypt-staging и использовать сервер размещения Let’s Encrypt. Далее мы будем использовать для развертывания сертификатов производственный сервер, но в на этом сервере может быть ограничено количество запросов, и поэтому для тестирования лучше всего использовать URL сервера размещения.

      Затем мы укажем адрес электронной почты для регистрации сертификата и создадим секрет Kubernetes с именем letsencrypt-staging для сохранения закрытого ключа учетной записи ACME. Также мы активируем механизм вызовов HTTP-01. Дополнительную информацию об этих параметрах можно найти в официальной документации cert-manager по элементам Issuer.

      Разверните ClusterIssuer с помощью kubectl:

      • kubectl create -f staging_issuer.yaml

      Вы должны увидеть следующий результат:

      Output

      clusterissuer.certmanager.k8s.io/letsencrypt-staging created

      Теперь мы создали элемент Issuer для сервера размещения Let’s Encrypt и готовы изменить созданный выше ресурс Ingress и активировать шифрование TLS для путей echo1.example.com и echo2.example.com.

      Откройте echo_ingress.yaml в своем любимом редакторе еще раз:

      Добавьте в манифест ресурсов Ingress следующее:

      echo_ingress.yaml

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: echo-ingress
        annotations:  
          kubernetes.io/ingress.class: nginx
          certmanager.k8s.io/cluster-issuer: letsencrypt-staging
      spec:
        tls:
        - hosts:
          - echo1.example.com
          - echo2.example.com
          secretName: letsencrypt-staging
        rules:
        - host: echo1.example.com
          http:
            paths:
            - backend:
                serviceName: echo1
                servicePort: 80
        - host: echo2.example.com
          http:
            paths:
            - backend:
                serviceName: echo2
                servicePort: 80
      

      Здесь мы добавим несколько аннотаций для указания класса Ingress.class, определяющего контроллер Ingress, который должен использоваться для реализации правил Ingress. Кроме того, мы определим для cluster-issuer элемент сертификации letsencrypt-staging, который мы только что создали.

      Наконец, мы добавим блок tls для указания хостов, для которых мы хотим получить сертификаты, а также укажем secretName. Этот секрет будет содержать закрытый ключ TLS и выданный сертификат.

      Когда вы закончите внесение изменений, сохраните и закройте файл.

      Теперь мы обновим существующие ресурсы Ingress с помощью команды kubectl apply:

      • kubectl apply -f echo_ingress.yaml

      Вы должны увидеть следующий результат:

      Output

      ingress.extensions/echo-ingress configured

      Вы можете использовать команду kubectl describe для отслеживания состояния изменений Ingress, которые вы только что применили:

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 14m nginx-ingress-controller Ingress default/echo-ingress Normal UPDATE 1m (x2 over 13m) nginx-ingress-controller Ingress default/echo-ingress Normal CreateCertificate 1m cert-manager Successfully created Certificate "letsencrypt-staging"

      После успешного создания сертификата вы можете запустить дополнительную команду describe, чтобы еще раз убедиться в успешном его создании:

      • kubectl describe certificate

      Вы должны увидеть следующие результаты в разделе Events:

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Generated 63s cert-manager Generated new private key Normal OrderCreated 63s cert-manager Created Order resource "letsencrypt-staging-147606226" Normal OrderComplete 19s cert-manager Order "letsencrypt-staging-147606226" completed successfully Normal CertIssued 18s cert-manager Certificate issued successfully

      Это подтверждает, что сертификат TLS выдан успешно, и шифрование HTTPS активно для двух настроенных доменов.

      Теперь мы готовы отправить запрос на сервер echo для тестирования работы HTTPS.

      Запустите следующую команду wget для отправки запроса на echo1.example.com и распечатайте заголовки ответов в STDOUT:

      • wget --save-headers -O- echo1.example.com

      Вы должны увидеть следующий результат:

      Output

      URL transformed to HTTPS due to an HSTS policy --2018-12-11 14:38:24-- https://echo1.example.com/ Resolving echo1.example.com (echo1.example.com)... 203.0.113.0 Connecting to echo1.example.com (echo1.example.net)|203.0.113.0|:443... connected. ERROR: cannot verify echo1.example.com's certificate, issued by ‘CN=Fake LE Intermediate X1’: Unable to locally verify the issuer's authority. To connect to echo1.example.com insecurely, use `--no-check-certificate'.

      Это означает, что протокол HTTPS успешно активирован, но сертификат не удается проверить, поскольку это фиктивный временный сертификат, выданный сервером размещения Let’s Encrypt.

      Мы убедились, что с временным фиктивным сертификатом все работает и можем развернуть два производственных сертификата для двух хостов echo1.example.com и echo2.example.com.

      Шаг 5 — Развертывание элемента Issuer в производственной среде

      На этом шаге мы изменим процедуру, используемую для выделения фиктивных сертификатов, и генерируем действительный производственный сертификат для наших хостов Ingress.

      Вначале мы создадим производственный сертификат ClusterIssuer.

      Откройте файл с именем prod_issuer.yaml в своем любимом редакторе:

      nano prod_issuer.yaml
      

      Вставьте в него следующий манифест:

      prod_issuer.yaml

      apiVersion: certmanager.k8s.io/v1alpha1
      kind: ClusterIssuer
      metadata:
        name: letsencrypt-prod
      spec:
        acme:
          # The ACME server URL
          server: https://acme-v02.api.letsencrypt.org/directory
          # Email address used for ACME registration
          email: your_email_address_here
          # Name of a secret used to store the ACME account private key
          privateKeySecretRef:
            name: letsencrypt-prod
          # Enable the HTTP-01 challenge provider
          http01: {}
      

      Обратите внимание на другой URL сервера ACME и имя секретного ключа letsencrypt-prod.

      Когда вы закончите редактирование, сохраните и закройте файл.

      Теперь разверните элемент Issuer с помощью kubectl:

      • kubectl create -f prod_issuer.yaml

      Вы должны увидеть следующий результат:

      Output

      clusterissuer.certmanager.k8s.io/letsencrypt-prod created

      Обновите echo_ingress.yaml для использования нового элемента Issuer:

      Внесите в файл следующие изменения:

      echo_ingress.yaml

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: echo-ingress
        annotations:  
          kubernetes.io/ingress.class: nginx
          certmanager.k8s.io/cluster-issuer: letsencrypt-prod
      spec:
        tls:
        - hosts:
          - echo1.example.com
          - echo2.example.com
          secretName: letsencrypt-prod
        rules:
        - host: echo1.example.com
          http:
            paths:
            - backend:
                serviceName: echo1
                servicePort: 80
        - host: echo2.example.com
          http:
            paths:
            - backend:
                serviceName: echo2
                servicePort: 80
      

      Здесь мы обновим ClusterIssuer и секретное имя на letsencrypt-prod.

      После внесения изменений сохраните и закройте файл.

      Разверните изменения с помощью команды kubectl apply:

      • kubectl apply -f echo_ingress.yaml

      Output

      ingress.extensions/echo-ingress configured

      Подождите несколько минут, чтобы дать производственному серверу Let’s Encrypt выдать сертификат. Вы можете отслеживать ход выполнения с помощью команды kubectl describe для объекта certificate:

      • kubectl describe certificate letsencrypt-prod

      Следующий экран результатов означает, что сертификат успешно установлен:

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Generated 82s cert-manager Generated new private key Normal OrderCreated 82s cert-manager Created Order resource "letsencrypt-prod-2626449824" Normal OrderComplete 37s cert-manager Order "letsencrypt-prod-2626449824" completed successfully Normal CertIssued 37s cert-manager Certificate issued successfully

      Теперь мы проведем тестирование с помощью curl, чтобы подтвердить правильную работу HTTPS:

      Вы должны увидеть следующее:

      Output

      <html> <head><title>308 Permanent Redirect</title></head> <body> <center><h1>308 Permanent Redirect</h1></center> <hr><center>nginx/1.15.9</center> </body> </html>

      Это означает, что запросы HTTP перенаправляются для использования HTTPS.

      Запустите curl на https://echo1.example.com:

      • curl https://echo1.example.com

      Вы должны увидеть следующий результат:

      Output

      echo1

      Вы можете запустить предыдущую команду с флагом -v для получения развернутой информации о соединении сертификата и проверки информации о сертификате.

      Вы успешно настроили HTTPS с помощью сертификата Let’s Encrypt для вашего Nginx Ingress.

      Заключение

      В этом обучающем модуле вы настроили Nginx Ingress для балансировки нагрузки и перенаправления внешних запросов на серверные службы внутри кластера Kubernetes. Также вы защитили Ingress, установив элемент обеспечения сертификата cert-manager и установив для двух путей хоста сертификат Let’s Encrypt.

      Существует множество альтернатив использованию контроллера Nginx Ingress. Дополнительную информацию можно найти в разделе «Контроллеры Ingress» в официальной документации Kubernetes.



      Source link

      How to Set Up an Nginx Ingress with Cert-Manager on DigitalOcean Kubernetes


      Introduction

      Kubernetes Ingresses allow you to flexibly route traffic from outside your Kubernetes cluster to Services inside of your cluster. This is accomplished using Ingress Resources, which define rules for routing HTTP and HTTPS traffic to Kubernetes Services, and Ingress Controllers, which implement the rules by load balancing traffic and routing it to the appropriate backend Services. Popular Ingress Controllers include Nginx, Contour, HAProxy, and Traefik. Ingresses provide a more efficient and flexible alternative to setting up multiple LoadBalancer services, each of which uses its own dedicated Load Balancer.

      In this guide, we’ll set up the Kubernetes-maintained Nginx Ingress Controller, and create some Ingress Resources to route traffic to several dummy backend services. Once we’ve set up the Ingress, we’ll install cert-manager into our cluster to manage and provision TLS certificates for encrypting HTTP traffic to the Ingress.

      Prerequisites

      Before you begin with this guide, you should have the following available to you:

      • A Kubernetes 1.10+ cluster with role-based access control (RBAC) enabled
      • The kubectl command-line tool installed on your local machine and configured to connect to your cluster. You can read more about installing kubectl in the official documentation.
      • A domain name and DNS A records which you can point to the DigitalOcean Load Balancer used by the Ingress. If you are using DigitalOcean to manage your domain’s DNS records, consult How to Manage DNS Records to learn how to create A records.
      • The Helm package manager installed on your local machine and Tiller installed on your cluster, as detailed in How To Install Software on Kubernetes Clusters with the Helm Package Manager.
      • The wget command-line utility installed on your local machine. You can install wget using the package manager built into your operating system.

      Once you have these components set up, you’re ready to begin with this guide.

      Step 1 — Setting Up Dummy Backend Services

      Before we deploy the Ingress Controller, we’ll first create and roll out two dummy echo Services to which we’ll route external traffic using the Ingress. The echo Services will run the hashicorp/http-echo web server container, which returns a page containing a text string passed in when the web server is launched. To learn more about http-echo, consult its GitHub Repo, and to learn more about Kubernetes Services, consult Services from the official Kubernetes docs.

      On your local machine, create and edit a file called echo1.yaml using nano or your favorite editor:

      Paste in the following Service and Deployment manifest:

      echo1.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: echo1
      spec:
        ports:
        - port: 80
          targetPort: 5678
        selector:
          app: echo1
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: echo1
      spec:
        selector:
          matchLabels:
            app: echo1
        replicas: 2
        template:
          metadata:
            labels:
              app: echo1
          spec:
            containers:
            - name: echo1
              image: hashicorp/http-echo
              args:
              - "-text=echo1"
              ports:
              - containerPort: 5678
      

      In this file, we define a Service called echo1 which routes traffic to Pods with the app: echo1 label selector. It accepts TCP traffic on port 80 and routes it to port 5678,http-echo's default port.

      We then define a Deployment, also called echo1, which manages Pods with the app: echo1 Label Selector. We specify that the Deployment should have 2 Pod replicas, and that the Pods should start a container called echo1 running the hashicorp/http-echo image. We pass in the text parameter and set it to echo1, so that the http-echo web server returns echo1. Finally, we open port 5678 on the Pod container.

      Once you're satisfied with your dummy Service and Deployment manifest, save and close the file.

      Then, create the Kubernetes resources using kubectl create with the -f flag, specifying the file you just saved as a parameter:

      • kubectl create -f echo1.yaml

      You should see the following output:

      Output

      service/echo1 created deployment.apps/echo1 created

      Verify that the Service started correctly by confirming that it has a ClusterIP, the internal IP on which the Service is exposed:

      You should see the following output:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE echo1 ClusterIP 10.245.222.129 <none> 80/TCP 60s

      This indicates that the echo1 Service is now available internally at 10.245.222.129 on port 80. It will forward traffic to containerPort 5678 on the Pods it selects.

      Now that the echo1 Service is up and running, repeat this process for the echo2 Service.

      Create and open a file called echo2.yaml:

      echo2.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: echo2
      spec:
        ports:
        - port: 80
          targetPort: 5678
        selector:
          app: echo2
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: echo2
      spec:
        selector:
          matchLabels:
            app: echo2
        replicas: 1
        template:
          metadata:
            labels:
              app: echo2
          spec:
            containers:
            - name: echo2
              image: hashicorp/http-echo
              args:
              - "-text=echo2"
              ports:
              - containerPort: 5678
      

      Here, we essentially use the same Service and Deployment manifest as above, but name and relabel the Service and Deployment echo2. In addition, to provide some variety, we create only 1 Pod replica. We ensure that we set the text parameter to echo2 so that the web server returns the text echo2.

      Save and close the file, and create the Kubernetes resources using kubectl:

      • kubectl create -f echo2.yaml

      You should see the following output:

      Output

      service/echo2 created deployment.apps/echo2 created

      Once again, verify that the Service is up and running:

      You should see both the echo1 and echo2 Services with assigned ClusterIPs:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE echo1 ClusterIP 10.245.222.129 <none> 80/TCP 6m6s echo2 ClusterIP 10.245.128.224 <none> 80/TCP 6m3s kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 4d21h

      Now that our dummy echo web services are up and running, we can move on to rolling out the Nginx Ingress Controller.

      Step 2 — Setting Up the Kubernetes Nginx Ingress Controller

      In this step, we'll roll out the Kubernetes-maintained Nginx Ingress Controller. Note that there are several Nginx Ingress Controllers; the Kubernetes community maintains the one used in this guide and Nginx Inc. maintains kubernetes-ingress. The instructions in this tutorial are based on those from the official Kubernetes Nginx Ingress Controller Installation Guide.

      The Nginx Ingress Controller consists of a Pod that runs the Nginx web server and watches the Kubernetes Control Plane for new and updated Ingress Resource objects. An Ingress Resource is essentially a list of traffic routing rules for backend Services. For example, an Ingress rule can specify that HTTP traffic arriving at the path /web1 should be directed towards the web1 backend web server. Using Ingress Resources, you can also perform host-based routing: for example, routing requests that hit web1.your_domain.com to the backend Kubernetes Service web1.

      In this case, because we’re deploying the Ingress Controller to a DigitalOcean Kubernetes cluster, the Controller will create a LoadBalancer Service that spins up a DigitalOcean Load Balancer to which all external traffic will be directed. This Load Balancer will route external traffic to the Ingress Controller Pod running Nginx, which then forwards traffic to the appropriate backend Services.

      We'll begin by first creating the Kubernetes resources required by the Nginx Ingress Controller. These consist of ConfigMaps containing the Controller's configuration, Role-based Access Control (RBAC) Roles to grant the Controller access to the Kubernetes API, and the actual Ingress Controller Deployment. To see a full list of these required resources, consult the manifest from the Kubernetes Nginx Ingress Controller’s GitHub repo.

      To create these mandatory resources, use kubectl apply and the -f flag to specify the manifest file hosted on GitHub:

      • kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml

      We use apply instead of create here so that in the future we can incrementally apply changes to the Ingress Controller objects instead of completely overwriting them. To learn more about apply, consult Managing Resources from the official Kubernetes docs.

      You should see the following output:

      Output

      namespace/ingress-nginx created configmap/nginx-configuration created configmap/tcp-services created configmap/udp-services created serviceaccount/nginx-ingress-serviceaccount created clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created role.rbac.authorization.k8s.io/nginx-ingress-role created rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created deployment.extensions/nginx-ingress-controller created

      This output also serves as a convenient summary of all the Ingress Controller objects created from the mandatory.yaml manifest.

      Next, we'll create the Ingress Controller LoadBalancer Service, which will create a DigitalOcean Load Balancer that will load balance and route HTTP and HTTPS traffic to the Ingress Controller Pod deployed in the previous command.

      To create the LoadBalancer Service, once again kubectl apply a manifest file containing the Service definition:

      • kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/cloud-generic.yaml

      You should see the following output:

      Output

      service/ingress-nginx created

      Now, confirm that the DigitalOcean Load Balancer was successfully created by fetching the Service details with kubectl:

      • kubectl get svc --namespace=ingress-nginx

      You should see an external IP address, corresponding to the IP address of the DigitalOcean Load Balancer:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx LoadBalancer 10.245.247.67 203.0.113.0 80:32486/TCP,443:32096/TCP 20h

      Note down the Load Balancer's external IP address, as you'll need it in a later step.

      This load balancer receives traffic on HTTP and HTTPS ports 80 and 443, and forwards it to the Ingress Controller Pod. The Ingress Controller will then route the traffic to the appropriate backend Service.

      We can now point our DNS records at this external Load Balancer and create some Ingress Resources to implement traffic routing rules.

      Step 3 — Creating the Ingress Resource

      Let's begin by creating a minimal Ingress Resource to route traffic directed at a given subdomain to a corresponding backend Service.

      In this guide, we'll use the test domain example.com. You should substitute this with the domain name you own.

      We'll first create a simple rule to route traffic directed at echo1.example.com to the echo1 backend service and traffic directed at echo2.example.com to the echo2 backend service.

      Begin by opening up a file called echo_ingress.yaml in your favorite editor:

      Paste in the following ingress definition:

      echo_ingress.yaml

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: echo-ingress
      spec:
        rules:
        - host: echo1.example.com
          http:
            paths:
            - backend:
                serviceName: echo1
                servicePort: 80
        - host: echo2.example.com
          http:
            paths:
            - backend:
                serviceName: echo2
                servicePort: 80
      

      When you've finished editing your Ingress rules, save and close the file.

      Here, we've specified that we'd like to create an Ingress Resource called echo-ingress, and route traffic based on the Host header. An HTTP request Host header specifies the domain name of the target server. To learn more about Host request headers, consult the Mozilla Developer Network definition page. Requests with host echo1.example.com will be directed to the echo1 backend set up in Step 1, and requests with host echo2.example.com will be directed to the echo2 backend.

      You can now create the Ingress using kubectl:

      • kubectl apply -f echo_ingress.yaml

      You'll see the following output confirming the Ingress creation:

      Output

      ingress.extensions/echo-ingress created

      To test the Ingress, navigate to your DNS management service and create A records for echo1.example.com and echo2.example.com pointing to the DigitalOcean Load Balancer's external IP. The Load Balancer's external IP is the external IP address for the ingress-nginx Service, which we fetched in the previous step. If you are using DigitalOcean to manage your domain's DNS records, consult How to Manage DNS Records to learn how to create A records.

      Once you've created the necessary echo1.example.com and echo2.example.com DNS records, you can test the Ingress Controller and Resource you've created using the curl command line utility.

      From your local machine, curl the echo1 Service:

      You should get the following response from the echo1 service:

      Output

      echo1

      This confirms that your request to echo1.example.com is being correctly routed through the Nginx ingress to the echo1 backend Service.

      Now, perform the same test for the echo2 Service:

      You should get the following response from the echo2 Service:

      Output

      echo2

      This confirms that your request to echo2.example.com is being correctly routed through the Nginx ingress to the echo2 backend Service.

      At this point, you've successfully set up a basic Nginx Ingress to perform virtual host-based routing. In the next step, we'll install cert-manager using Helm to provision TLS certificates for our Ingress and enable the more secure HTTPS protocol.

      Step 4 — Installing and Configuring Cert-Manager

      In this step, we'll use Helm to install cert-manager into our cluster. cert-manager is a Kubernetes service that provisions TLS certificates from Let's Encrypt and other certificate authorities and manages their lifecycles. Certificates can be requested and configured by annotating Ingress Resources with the certmanager.k8s.io/issuer annotation, appending a tls section to the Ingress spec, and configuring one or more Issuers to specify your preferred certificate authority. To learn more about Issuer objects, consult the official cert-manager documentation on Issuers.

      We'll first begin by using Helm to installcert-manager into our cluster:

      • helm install --name cert-manager --namespace kube-system --version v0.4.1 stable/cert-manager

      You should see the following output:

      Output

      . . . NOTES: cert-manager has been deployed successfully! In order to begin issuing certificates, you will need to set up a ClusterIssuer or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer). More information on the different types of issuers and how to configure them can be found in our documentation: https://cert-manager.readthedocs.io/en/latest/reference/issuers.html For information on how to configure cert-manager to automatically provision Certificates for Ingress resources, take a look at the `ingress-shim` documentation: https://cert-manager.readthedocs.io/en/latest/reference/ingress-shim.html

      This indicates that the cert-manager installation was successful.

      Before we begin issuing certificates for our Ingress hosts, we need to create an Issuer, which specifies the certificate authority from which signed x509 certificates can be obtained. In this guide, we'll use the Let's Encrypt certificate authority, which provides free TLS certificates and offers both a staging server for testing your certificate configuration, and a production server for rolling out verifiable TLS certificates.

      Let's create a test Issuer to make sure the certificate provisioning mechanism is functioning correctly. Open a file named staging_issuer.yaml in your favorite text editor:

      nano staging_issuer.yaml
      

      Paste in the following ClusterIssuer manifest:

      staging_issuer.yaml

      apiVersion: certmanager.k8s.io/v1alpha1
      kind: ClusterIssuer
      metadata:
       name: letsencrypt-staging
      spec:
       acme:
         # The ACME server URL
         server: https://acme-staging-v02.api.letsencrypt.org/directory
         # Email address used for ACME registration
         email: your_email_address_here
         # Name of a secret used to store the ACME account private key
         privateKeySecretRef:
           name: letsencrypt-staging
         # Enable the HTTP-01 challenge provider
         http01: {}
      

      Here we specify that we'd like to create a ClusterIssuer object called letsencrypt-staging, and use the Let's Encrypt staging server. We'll later use the production server to roll out our certificates, but the production server may rate-limit requests made against it, so for testing purposes it's best to use the staging URL.

      We then specify an email address to register the certificate, and create a Kubernetes Secret called letsencrypt-staging to store the certificate's private key. We also enable the HTTP-01 challenge mechanism. To learn more about these parameters, consult the official cert-manager documentation on Issuers.

      Roll out the ClusterIssuer using kubectl:

      • kubectl create -f staging_issuer.yaml

      You should see the following output:

      Output

      clusterissuer.certmanager.k8s.io/letsencrypt-staging created

      Now that we've created our Let's Encrypt staging Issuer, we're ready to modify the Ingress Resource we created above and enable TLS encryption for the echo1.example.com and echo2.example.com paths.

      Open up echo_ingress.yaml once again in your favorite editor:

      Add the following to the Ingress Resource manifest:

      echo_ingress.yaml

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: echo-ingress
        annotations:  
          kubernetes.io/ingress.class: nginx
          certmanager.k8s.io/cluster-issuer: letsencrypt-staging
      spec:
        tls:
        - hosts:
          - echo1.example.com
          - echo2.example.com
          secretName: letsencrypt-staging
        rules:
        - host: echo1.example.com
          http:
            paths:
            - backend:
                serviceName: echo1
                servicePort: 80
        - host: echo2.example.com
          http:
            paths:
            - backend:
                serviceName: echo2
                servicePort: 80
      

      Here we add some annotations to specify the ingress.class, which determines the Ingress Controller that should be used to implement the Ingress Rules. In addition, we define the cluster-issuer to be letsencrypt-staging, the certificate Issuer we just created.

      Finally, we add a tls block to specify the hosts for which we want to acquire certificates, and specify the private key we created earlier.

      When you're done making changes, save and close the file.

      We'll now update the existing Ingress Resource using kubectl apply:

      • kubectl apply -f echo_ingress.yaml

      You should see the following output:

      Output

      ingress.extensions/echo-ingress configured

      You can use kubectl describe to track the state of the Ingress changes you've just applied:

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 14m nginx-ingress-controller Ingress default/echo-ingress Normal UPDATE 1m (x2 over 13m) nginx-ingress-controller Ingress default/echo-ingress Normal CreateCertificate 1m cert-manager Successfully created Certificate "letsencrypt-staging"

      Once the certificate has been successfully created, you can run an additional describe on it to further confirm its successful creation:

      • kubectl describe certificate

      You should see the following output in the Events section:

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CreateOrder 50s cert-manager Created new ACME order, attempting validation... Normal DomainVerified 15s cert-manager Domain "echo2.example.com" verified with "http-01" validation Normal DomainVerified 3s cert-manager Domain "echo1.example.com" verified with "http-01" validation Normal IssueCert 3s cert-manager Issuing certificate... Normal CertObtained 1s cert-manager Obtained certificate from ACME server Normal CertIssued 1s cert-manager Certificate issued successfully

      This confirms that the TLS certificate was successfully issued and HTTPS encryption is now active for the two domains configured.

      We're now ready to send a request to a backend echo server to test that HTTPS is functioning correctly.

      Run the following wget command to send a request to echo1.example.com and print the response headers to STDOUT:

      • wget --save-headers -O- echo1.example.com

      You should see the following output:

      Output

      URL transformed to HTTPS due to an HSTS policy --2018-12-11 14:38:24-- https://echo1.example.com/ Resolving echo1.example.com (echo1.example.com)... 203.0.113.0 Connecting to echo1.example.com (echo1.example.net)|203.0.113.0|:443... connected. ERROR: cannot verify echo1.example.com's certificate, issued by ‘CN=Fake LE Intermediate X1’: Unable to locally verify the issuer's authority. To connect to echo1.example.com insecurely, use `--no-check-certificate'.

      This indicates that HTTPS has successfully been enabled, but the certificate cannot be verified as it's a fake temporary certificate issued by the Let's Encrypt staging server.

      Now that we've tested that everything works using this temporary fake certificate, we can roll out production certificates for the two hosts echo1.example.com and echo2.example.com.

      Step 5 — Rolling Out Production Issuer

      In this step we’ll modify the procedure used to provision staging certificates, and generate a valid, verifiable production certificate for our Ingress hosts.

      To begin, we'll first create a production certificate ClusterIssuer.

      Open a file called prod_issuer.yaml in your favorite editor:

      nano prod_issuer.yaml
      

      Paste in the following manifest:

      prod_issuer.yaml

      apiVersion: certmanager.k8s.io/v1alpha1
      kind: ClusterIssuer
      metadata:
        name: letsencrypt-prod
      spec:
        acme:
          # The ACME server URL
          server: https://acme-v02.api.letsencrypt.org/directory
          # Email address used for ACME registration
          email: your_email_address_here
          # Name of a secret used to store the ACME account private key
          privateKeySecretRef:
            name: letsencrypt-prod
          # Enable the HTTP-01 challenge provider
          http01: {}
      

      Note the different ACME server URL, and the letsencrypt-prod secret key name.

      When you're done editing, save and close the file.

      Now, roll out this Issuer using kubectl:

      • kubectl create -f prod_issuer.yaml

      You should see the following output:

      Output

      clusterissuer.certmanager.k8s.io/letsencrypt-prod created

      Update echo_ingress.yaml to use this new Issuer:

      Make the following changes to the file:

      echo_ingress.yaml

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: echo-ingress
        annotations:  
          kubernetes.io/ingress.class: nginx
          certmanager.k8s.io/cluster-issuer: letsencrypt-prod
      spec:
        tls:
        - hosts:
          - echo1.example.com
          - echo2.example.com
          secretName: letsencrypt-prod
        rules:
        - host: echo1.example.com
          http:
            paths:
            - backend:
                serviceName: echo1
                servicePort: 80
        - host: echo2.example.com
          http:
            paths:
            - backend:
                serviceName: echo2
                servicePort: 80
      

      Here, we update both the ClusterIssuer and secret key to letsencrypt-prod.

      Once you're satisfied with your changes, save and close the file.

      Roll out the changes using kubectl apply:

      • kubectl apply -f echo_ingress.yaml

      Output

      ingress.extensions/echo-ingress configured

      Wait a couple of minutes for the Let's Encrypt production server to issue the certificate. You can track its progress using kubectl describe on the certificate object:

      • kubectl describe certificate letsencrypt-prod

      Once you see the following output, the certificate has been issued successfully:

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CreateOrder 4m4s cert-manager Created new ACME order, attempting validation... Normal DomainVerified 3m30s cert-manager Domain "echo2.example.com" verified with "http-01" validation Normal DomainVerified 3m18s cert-manager Domain "echo1.example.com" verified with "http-01" validation Normal IssueCert 3m18s cert-manager Issuing certificate... Normal CertObtained 3m16s cert-manager Obtained certificate from ACME server Normal CertIssued 3m16s cert-manager Certificate issued successfully

      We'll now perform a test using curl to verify that HTTPS is working correctly:

      You should see the following:

      Output

      <html> <head><title>308 Permanent Redirect</title></head> <body> <center><h1>308 Permanent Redirect</h1></center> <hr><center>nginx/1.15.6</center> </body> </html>

      This indicates that HTTP requests are being redirected to use HTTPS.

      Run curl on https://echo1.example.com:

      • curl https://echo1.example.com

      You should now see the following output:

      Output

      echo1

      You can run the previous command with the verbose -v flag to dig deeper into the certificate handshake and to verify the certificate information.

      At this point, you've successfully configured HTTPS using a Let's Encrypt certificate for your Nginx Ingress.

      Conclusion

      In this guide, you set up an Nginx Ingress to load balance and route external requests to backend Services inside of your Kubernetes cluster. You also secured the Ingress by installing the cert-manager certificate provisioner and setting up a Let's Encrypt certificate for two host paths.

      There are many alternatives to the Nginx Ingress Controller. To learn more, consult Ingress controllers from the official Kubernetes documentation.



      Source link