#Conteinerização

0 Seguidores · 24 Postagens

Conteinerização é uma alternativa leve para a completa virtualização de máquina que envolve o encapsulamento de uma aplicação em um contêiner com seu próprio ambiente operacional. 

Artigo Heloisa Paiva · Maio 9, 2025 2m read

Às vezes, clientes precisam de uma pequena instância IRIS para fazer algo na nuvem e desligá-la, ou precisam de centenas de contêineres (ou seja, um por usuário final ou um por interface) com pequenas cargas de trabalho. Este exercício surgiu para ver quão pequena uma instância IRIS poderia ser. Para este exercício, focamos em qual é a menor quantidade de memória que podemos configurar para uma instância IRIS. Você conhece todos os parâmetros que afetam a memória alocada pelo IRIS?

Configurações de Memória

0
0 36
Artigo Danusa Calixto · Nov. 27, 2023 6m read

Olá, comunidade!

Acho que todo mundo deixa o código-fonte do projeto no repositório hoje em dia: Github, GitLab, bitbucket, etc. A mesma coisa para projetos do InterSystems IRIS , confira qualquer um no Open Exchange.

O que fazemos sempre que começamos ou continuamos a trabalhar com um determinado repositório usando a Plataformas de Dados InterSystems?

Precisamos de uma máquina do InterSystems IRIS local, bem como configurar o ambiente para o projeto e importar o código-fonte.

Portanto, todo desenvolvedor faz o seguinte:

  1. Verifica o código no repositório
  2. Instala/executa a instalação do IRIS local
  3. Cria um novo namespace/banco de dados para um projeto
  4. Importa o código nesse novo namespace
  5. Configura todo o ambiente rest
  6. Começa/continua a programar o projeto 

Se você "dockerizar" seu repositório, as linhas de etapas podem ser resumidas em 3 etapas:

  1. Verifica o código no repositório
  2. Executa o docker-compose build 
  3. Começa/continua a programar o projeto 

Aproveite - nada do trabalho manual das etapas 3, 4 e 5, que podem levar minutos e trazer dor de cabeça às vezes.

Você pode "dockerizar" (quase) qualquer repositório da InterSystems seguindo algumas etapas. Vamos lá!

Como "dockerizar" o repositório e o que isso significa? 

Basicamente, a ideia é ter o docker instalado na máquina que compilará o código e o ambiente em um contêiner, que será executado no docker e funcionará da maneira apresentada em primeiro lugar pelo desenvolvedor. Sem "Qual é a versão do SO?" e "O que mais você tinha nessa instalação do IRIS?".

É sempre uma página limpa (ou um contêiner IRIS limpo) que usamos para configurar o ambiente (namespaces, bancos de dados, web apps, usuários/funções) e importar o código em um banco de dados limpo recém-criado.

Esse procedimento de "dockerizar" prejudicará muito seu repositório atual? 

Não. Ele precisará adicionar 2 ou 3 novos arquivos na raiz do repositório e seguir algumas regras que você pode configurar por conta própria.

Pré-requisitos

Baixar e instalar o docker.

Baixar e instalar a imagem do docker IRIS. Neste exemplo, usarei a prévia completa do InterSystems IRIS:  iris:2019.1.0S.111.0, que você pode baixar na prévia da WRC. Veja os detalhes.

Se você trabalha com a instância que precisa de uma chave, coloque a iris.key no local que você a usará o tempo todo. Coloquei no diretório de usuário do meu Mac.

"Dockerizando" o repositório

Para "dockerizar" seu repositório, você precisa adicionar três arquivos na pasta raiz dele.

Aqui está o exemplo de repositório dockerizadodo projeto - ISC-DEV, que ajuda a importar/exportar o código-fonte do banco de dados IRIS.  Esse repositório tem Dockerfile, docker-compose.yml e installer.cls adicionais que vou descrever abaixo.

Primeiro, há um Dockerfile, que será usado pelo comando docker-compose build

 
Dockerfile
FROM intersystems/iris:2019.1.0S.111.0 # precisa ser a mesma imagem instalada 

WORKDIR /opt/app

COPY ./Installer.cls ./

COPY ./cls/ ./src/

RUN iris start $ISC_PACKAGE_INSTANCENAME quietly EmergencyId=sys,sys && \

    /bin/echo -e "sys\nsys\n" \

            # dando %ALL ao usuário administrador

            " Do ##class(Security.Users).UnExpireUserPasswords(\"*\")\n" \

            " Do ##class(Security.Users).AddRoles(\"admin\", \"%ALL\")\n" \

            # importando e executando o instalador

            " Do \$system.OBJ.Load(\"/opt/app/Installer.cls\",\"ck\")\n" \

            " Set sc = ##class(App.Installer).setup(, 3)\n" \

            " If 'sc do \$zu(4, \$JOB, 1)\n" \

            # apresentando a autorização no nível do SO (para remover o prompt de login/senha do contêiner)

            " Do ##class(Security.System).Get(,.p)\n" \

            " Set p(\"AutheEnabled\")=p(\"AutheEnabled\")+16\n" \

            " Do ##class(Security.System).Modify(,.p)\n" \

            " halt" \

    | iris session $ISC_PACKAGE_INSTANCENAME && \

    /bin/echo -e "sys\nsys\n" \

    | iris stop $ISC_PACKAGE_INSTANCENAME quietly

CMD [ "-l", "/usr/irissys/mgr/messages.log" ]

 

Esse Dockerfile copia o installer.cls e o código-fonte da pasta /cls do repositório para a pasta /src e para o contêiner

Ele também executa algumas configurações, dando ao usuário administrador a função %All e a senha infinita ‘SYS’, apresenta a autorização no nível do SO e executa o %Installer. 

O que está no %Installer?

Class App.Installer

{

XData MyInstall [ XMLNamespace = INSTALLER ]

{

<Manifest>

  <Default Name="NAMESPACE" Value="ISCDEV"/>

  <Default Name="DBNAME" Value="ISCDEV"/>

  <Default Name="APPPATH" Dir="/opt/app/" />

  <Default Name="SOURCESPATH" Dir="${APPPATH}src" />

  <Default Name="RESOURCE" Value="%DB_${DBNAME}" /> 

  <Namespace Name="${NAMESPACE}" Code="${DBNAME}-CODE" Data="${DBNAME}-DATA" Create="yes" Ensemble="0">

    <Configuration>

      <Database Name="${DBNAME}-CODE" Dir="${APPPATH}${DBNAME}-CODE" Create="yes" Resource="${RESOURCE}"/>

      <Database Name="${DBNAME}-DATA" Dir="${APPPATH}${DBNAME}-DATA" Create="yes" Resource="${RESOURCE}"/>

    </Configuration>

    <Import File="${SOURCESPATH}" Recurse="1"/>

  </Namespace>

</Manifest>

}

ClassMethod setup(ByRef pVars, pLogLevel As %Integer = 3, pInstaller As %Installer.Installer, pLogger As %Installer.AbstractLogger) As %Status [ CodeMode = objectgenerator, Internal ]

{

  Return ##class(%Installer.Manifest).%Generate(%compiledclass, %code, "MyInstall")

}

}

Isso cria o namespace/banco de dados ISCDEV e importa o código da pasta de origem -/src.

Em seguida, há o arquivo docker-compose.yml, que será usado ao executar o contêiner com o comando docker-compose up.

version: '2.4'

services:

iris:

build: .

restart: always

ports:

  - 52773:52773

volumes:

  - ~/iris.key:/usr/irissys/mgr/iris.key</pre>

 

Essa config dirá ao docker em qual porta vamos esperar que o IRIS trabalhe em nosso host. O primeiro (52773) é um host, o segundo é uma porta interna de um contêiner (52773)

na seção "volumes", o docker-compose.yml fornece acesso a uma chave iris na sua máquina dentro do contêiner  no local em que o IRIS está procurando por ela:

- ~/iris.key:/usr/irissys/mgr/iris.key

Para começar a programar com esse repositório, faça o seguinte:

1. Faça o clone/git pull do repositório em qualquer diretório local.

 2. Abra o terminal nesse diretório e execute

user# docker-compose build

isso criará o contêiner.

3. Execute o contêiner IRIS com seu projeto

user# docker-compose up -d

Abra seu IDE favorito, conecte ao servidor em localhost://52773 e desenvolva seu sucesso com as Plataformas de Dados do InterSystems IRIS ;)

Você pode usar esses 3 arquivos para "dockerizar" seu repositório. Basta colocar o nome correto para o código-fonte no Dockerfile, o(s) namespace(s) correto(s) no Installer.cls e um local para a iris.key no docker-compose.yml para aproveitar os benefícios dos contêineres do Docker no seu desenvolvimento diário do InterSystems IRIS.

0
0 119
Artigo Danusa Calixto · Nov. 27, 2023 1m read

Os contêineres nos arquivos ECS não são editáveis se o tamanho do arquivo for maior do que o espaço disponível de armazenamento temporário. Por exemplo, se eu tenho 4 GB livres, não posso editar um arquivo de 8 GB. No entanto, se eu iniciar um contêiner com 50 GB de armazenamento temporário (24 GB livre), posso editar normalmente meu arquivo de 8 GB. Até os atributos do arquivo não podem ser alterados: chattr -i <file> falha se a quantidade de armazenamento temporário não for suficiente (e então o banco de dados não pode ser montado para escrita).

Isso pode fazer com que o contêiner iris falhe na inicialização se o banco de dados grande for ambas leitura/escrita e tiver sido montado na inicialização. Possivelmente, pode causar a falha do contêiner durante o tempo de execução se o banco de dados passar de um limite definido pelo espaço disponível.

Para resolver o problema:

  • Torne grandes bancos de dados somente leitura
  • Aloque armazenamento temporário suficiente

Isso provavelmente se aplica ao EKS Fargate, mas não verifiquei.

0
0 89
Artigo Danusa Calixto · Ago. 18, 2023 2m read

A InterSystems também lançou o IRIS como implantações em contêineres. Esta postagem demonstra como o InterSystems IRIS e os aplicativos que dependem do IRIS como um back-end podem ser empacotados em uma imagem e executados em outras máquinas em contêineres e como é simples fazer isso.

Um contêiner executa imagens que possuem todos os executáveis, código binário, bibliotecas e arquivos de configuração necessários. E as imagens podem ser movidas de uma máquina para outra, e um repositório de imagens como o Docker Hub pode simplificar esse processo.

Usei um aplicativo do Open Exchange para esta demonstração.

**Vídeo da demonstração: **https://www.loom.com/share/93f9a760b5f54c0a8811b7a212387b9d

A imagem para a Plataforma de Dados IRIS Community Edition pode ser encontrada no InterSystems Container Registry: https://containers.intersystems.com/contents

Para usar uma instância em contêiner do IRIS em uma máquina host, ela precisa ser extraída durante o tempo de execução.

Para isso, o Dockerfile precisa ter os seguintes comandos, conforme mostrado abaixo:

Dockerfile

ARG IMAGE=intersystemsdc/irishealth-community ARG IMAGE=intersystemsdc/iris-community ARG IMAGE=intersystemsdc/iris-community:preview FROM $IMAGE RUN iris start IRIS \  && iris merge IRIS /tmp/merge.cpf \  && iris stop IRIS quietly

Esses são os comandos básicos que criam um Dockerfile escrito para construir uma imagem que possui instruções para o IRIS em contêiner.

Também podem ser adicionados os comandos para executar a instalação de outras dependências necessárias para o aplicativo que está sendo executado com a instância em contêiner do IRIS.

São fornecidos os comandos do Docker que marcam e enviam uma imagem que carrega a instância IRIS para o Docker Hub e, subsequentemente, extraem e executam essa imagem em outra máquina host.

Comandos

docker build -t image_name filepath docker tag image_name dockerhub_username/repository_name:tag_name docker push dockerhub_username/repository_name:tag_name

   

Comandos

docker pull dockerhub_username/repository_name:tag_name docker run --name test -p host_8080:52773 padhikar/irisincontainer:main

Aplicativo usado na demonstração: https://openexchange.intersystems.com/package/iris-geo-map

Criando imagens do InterSystems IRIS: https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=ADOCK#ADOCK_iris_creating

0
0 65
Artigo Danusa Calixto · Abr. 3, 2023 7m read

Nesta série de artigos, quero apresentar e discutir várias abordagens possíveis para o desenvolvimento de software com tecnologias da InterSystems e do GitLab. Vou cobrir tópicos como:

  • Git básico
  • Fluxo Git (processo de desenvolvimento)
  • Instalação do GitLab
  • Fluxo de trabalho do GitLab
  • Entrega contínua
  • Instalação e configuração do GitLab
  • CI/CD do GitLab
  • Por que contêineres?
  • Infraestrutura dos contêineres
  • CD usando contêineres
  • CD usando ICM
  • Arquitetura do contêiner

Neste artigo, falaríamos sobre como criar e implantar seu próprio contêiner.

%SYS durável

Como os contêineres são bastante efêmeros, eles não devem armazenar nenhum dado do aplicativo. O recurso %SYS Durável permite exatamente isso — armazenar configurações, definições, dados %SYS, etc. em um volume de host, especificamente:

  • O arquivo iris.cpf.
  • O diretório /csp, contendo a configuração do web gateway e os arquivos do log.
  • O arquivo /httpd/httpd.conf, o arquivo de configuração do servidor Web privado da instância.
  • O diretório /mgr, contendo o seguinte:
    • O banco de dados do sistema IRISSYS, composta pelos arquivos IRIS.DAT e iris.lck e diretório de stream, e iristemp, irisaudit, iris e os diretórios do usuário, com os bancos de dados do sistema IRISTEMP, IRISAUDIT, IRIS e USER.
    • O arquivo do registro de log de imagem de gravação, IRIS.WIJ.
    • O diretório /journal com os arquivos do registro de log.
    • O diretório /temp para arquivos temporários.
    • Arquivos de registro, incluindo messages.log, journal.log e SystemMonitor.log.

Arquitetura do contêiner

Por outro lado, precisamos armazenar o código do aplicativo dentro do nosso contêiner para atualizá-lo quando necessário.

Tudo isso nos leva a esta arquitetura:

Para fazer isso durante o tempo de compilação, precisamos, no mínimo, criar um banco de dados adicional (para armazenar o código do aplicativo) e mapeá-lo no namespace do aplicativo. No meu exemplo, eu usaria o namespace USER para manter os dados do aplicativo, como ele já existe e é durável.

Instalador

Com base no descrito acima, nosso instalador precisa:

  • Criar o namespace/banco de dados APP
  • Carregar o código no namespace APP
  • Mapear as classes do aplicativo para o namespace USER
  • Fazer todas as outras instalações (nesse caso, criei o web app CSP e o app REST)
Class MyApp.Hooks.Local
{

Parameter Namespace = "APP";

/// See generated code in zsetup+1^MyApp.Hooks.Local.1
XData Install [ XMLNamespace = INSTALLER ]
{
<Manifest>

<Log Text="Creating namespace ${Namespace}" Level="0"/>
<Namespace Name="${Namespace}" Create="yes" Code="${Namespace}" Ensemble="" Data="IRISTEMP">
<Configuration>
<Database Name="${Namespace}" Dir="/usr/irissys/mgr/${Namespace}" Create="yes" MountRequired="true" Resource="%DB_${Namespace}" PublicPermissions="RW" MountAtStartup="true"/>
</Configuration>

<Import File="${Dir}Form" Recurse="1" Flags="cdk" IgnoreErrors="1" />
</Namespace>
<Log Text="End Creating namespace ${Namespace}" Level="0"/>

 
<Log Text="Mapping to USER" Level="0"/>
<Namespace Name="USER" Create="no" Code="USER" Data="USER" Ensemble="0">
<Configuration>
<Log Text="Mapping Form package to USER namespace" Level="0"/>
<ClassMapping From="${Namespace}" Package="Form"/>
<RoutineMapping From="${Namespace}" Routines="Form" />
</Configuration>

<CSPApplication  Url="/" Directory="${Dir}client" AuthenticationMethods="64" IsNamespaceDefault="false" Grant="%ALL" Recurse="1" />
</Namespace>

</Manifest>
}

/// This is a method generator whose code is generated by XGL.
/// Main setup method
/// set vars("Namespace")="TEMP3"
/// do ##class(MyApp.Hooks.Global).setup(.vars)
ClassMethod setup(ByRef pVars, pLogLevel As %Integer = 0, pInstaller As %Installer.Installer) As %Status [ CodeMode = objectgenerator, Internal ]
{
     Quit ##class(%Installer.Manifest).%Generate(%compiledclass, %code, "Install")
}

/// Entry point
ClassMethod onAfter() As %Status
{
    try {
        write "START INSTALLER",!
        set vars("Namespace") = ..#Namespace
        set vars("Dir") = ..getDir()
        set sc = ..setup(.vars)
        write !,$System.Status.GetErrorText(sc),!
        
        set sc = ..createWebApp()
    } catch ex {
        set sc = ex.AsStatus()
        write !,$System.Status.GetErrorText(sc),!
    }
    quit sc
}

/// Modify web app REST
ClassMethod createWebApp(appName As %String = "/forms") As %Status
{
    set:$e(appName)'="/" appName = "/" _ appName
    #dim sc As %Status = $$$OK
    new $namespace
    set $namespace = "%SYS"
    if '##class(Security.Applications).Exists(appName) {
        set props("AutheEnabled") = $$$AutheUnauthenticated
        set props("NameSpace") = "USER"
        set props("IsNameSpaceDefault") = $$$NO
        set props("DispatchClass") = "Form.REST.Main"
        set props("MatchRoles")=":" _ $$$AllRoleName
        set sc = ##class(Security.Applications).Create(appName, .props)
    }
    quit sc
}

ClassMethod getDir() [ CodeMode = expression ]
{
##class(%File).NormalizeDirectory($system.Util.GetEnviron("CI_PROJECT_DIR"))
}

}

Para criar o banco de dados não durável, usei um subdiretório de /usr/irissys/mgr, que não é persistente. Observe que a chamada para ##class(%File).ManagerDirectory() retorna um caminho para o diretório durável, e não para o diretório do contêiner interno.

 

Configuração da entrega contínua

Confira a parte VII para ver as informações completas, mas tudo o que você precisa fazer é adicionar estas duas linhas (em negrito) à configuração existente.

run image:
  stage: run
  environment:
    name: $CI_COMMIT_REF_NAME
    url: http://$CI_COMMIT_REF_SLUG.docker.eduard.win/index.html
  tags:
    - test
  script:
    - docker run -d
      --expose 52773
      --volume /InterSystems/durable/$CI_COMMIT_REF_SLUG:/data
      --env ISC_DATA_DIRECTORY=/data/sys
      --env VIRTUAL_HOST=$CI_COMMIT_REF_SLUG.docker.eduard.win
      --name iris-$CI_COMMIT_REF_NAME
      docker.eduard.win/test/docker:$CI_COMMIT_REF_NAME
      --log $ISC_PACKAGE_INSTALLDIR/mgr/messages.log

O argumento do volume monta o diretório do host para o contêiner e a variável ISC_DATA_DIRECTORY mostra ao InterSystems IRIS qual diretório usar. Para citar a documentação:

  • Ao executar um contêiner InterSystems IRIS usando essas opções, ocorre o seguinte:
  • O volume externo especificado é montado.
  • Se o diretório %SYS durável especificado pela variável de ambiente ISC_DATA_DIRECTORY, iconfig/ no exemplo anterior, já existe e contém os dados %SYS duráveis, todos os ponteiros internos da instância são redefinidos para esse diretório e a instância usa os dados que contém.
  • Se o diretório %SYS durável especificado na variável de ambiente ISC_DATA_DIRECTORY já existir, mas não conter os dados %SYS duráveis, nenhum dado é copiado e a instância é executada usando os dados na árvore de instalação dentro do contêiner, ou seja, os dados específicos da instância não são persistentes. Por esse motivo, é recomendável incluir nos scripts uma verificação para essa condição antes de executar o contêiner.
  • Se o diretório %SYS durável especificado por ISC_DATA_DIRECTORY não existir:
  • É criado o diretório %SYS durável.
  • Os diretórios e arquivos listados no conteúdo do Diretório %SYS Durável são copiados dos locais instalados para o diretório %SYS durável (os originais permanecem no local).
  • Todos os ponteiros internos da instância são redefinidos para o diretório %SYS durável e a instância usa os dados que contém.

 

Atualizações

Quando o aplicativo evoluir e uma nova versão (contêiner) for lançada, às vezes é necessário executar algum código. Pode ser antes ou depois dos hooks de compilação, das migrações do esquema e dos testes de unidade, mas é necessário executar código arbitrário. Por isso, você precisa de um framework que gerencie seu aplicativo. Em artigos anteriores, descrevi a estrutura básica desse framework, mas, é claro, ele pode ser consideravelmente ampliado para atender a requisitos específicos do aplicativo.

Conclusão

A criação de um aplicativo em contêiner requer algumas considerações, mas o InterSystems IRIS oferece vários recursos para facilitar esse processo.

0
0 77
Artigo Danusa Calixto · Fev. 23, 2023 9m read

Nesta série de artigos, quero apresentar e discutir várias abordagens possíveis para o desenvolvimento de software com tecnologias da InterSystems e do GitLab. Vou cobrir tópicos como:

  • Git básico
  • Fluxo Git (processo de desenvolvimento)
  • Instalação do GitLab
  • Fluxo de trabalho do GitLab
  • Entrega contínua
  • Instalação e configuração do GitLab
  • CI/CD do GitLab
  • Por que contêineres?
  • Infraestrutura dos contêineres
  • CD usando contêineres
  • CD usando ICM

Neste artigo, vamos desenvolver a entrega contínua com o InterSystems Cloud Manager. O ICM é uma solução de provisionamento e implantação na nuvem para aplicativos baseados no InterSystems IRIS. Ele permite definir a configuração de implantação desejada e o ICM provisiona de maneira automática. Para mais informações, consulte First Look: ICM.

Fluxo de trabalho

Na nossa configuração de entrega contínua:

  • Enviamos código para o repositório do GitLab
  • Criamos a imagem docker
  • Publicamos a imagem no registro docker
  • Testamos em um servidor de teste
  • Se os testes forem aprovados, implantamos em um servidor de produção

Ou em formato gráfico:

Como você pode ver, é praticamente igual, exceto que usaríamos o ICM em vez de gerenciar os contêineres do Docker manualmente.

Configuração do ICM

Antes de atualizar os contêineres, eles devem ser provisionados. Para isso precisamos definir defaults.json e definitions.json, descrevendo nossa arquitetura. Vou fornecer esses 2 arquivos para um servidor LIVE, as definições para um servidor TEST são as mesmas, e os padrões são os mesmos, exceto para os valores Tag e SystemMode.

defaults.json:

{
    "Provider": "GCP",
    "Label": "gsdemo2",
    "Tag": "LIVE","SystemMode": "LIVE",
    "DataVolumeSize": "10",
    "SSHUser": "sample",
    "SSHPublicKey": "/icmdata/ssh/insecure.pub",
    "SSHPrivateKey": "/icmdata/ssh/insecure",
    "DockerImage": "eduard93/icmdemo:master",
    "DockerUsername": "eduard93",
    "DockerPassword": "...",
    "TLSKeyDir": "/icmdata/tls",
    "Credentials": "/icmdata/gcp.json",
    "Project": "elebedyu-test",
    "MachineType": "n1-standard-1",
    "Region": "us-east1",
    "Zone": "us-east1-b",
    "Image": "rhel-cloud/rhel-7-v20170719",
    "ISCPassword": "SYS",
    "Mirror": "false"
}

definitions.json

[
    {
    "Role": "DM",
    "Count": "1",
    "ISCLicense": "/icmdata/iris.key"
    }
]

Dentro do contêiner ICM, a pasta /icmdata é montada a partir do host e:

  • As definições do servidor TEST são colocadas na pasta /icmdata/test
  • As definições do servidor LIVE são colocadas na pasta /icmdata/live

Depois de obter todas as chaves necessárias:

keygenSSH.sh /icmdata/ssh
keygenTLS.sh /icmdata/tls

E colocar os arquivos necessários em /icmdata:

  • iris.key
  • gcp.json (para a implantação no Google Cloud Platform)

Chame o ICM para provisionar suas instâncias:

cd /icmdata/test
icm provision
icm run
cd /icmdata/live
icm provision
icm run

Um servidor TEST e um servidor LIVE seriam provisionados com uma instância do InterSystems IRIS independente em cada um.

Consulte ICM First Look para ver um guia mais detalhado.

Criação

Primeiro, precisamos criar nossa imagem.

Nosso código seria, como sempre, armazenado no repositório, a configuração de CD em gitlab-ci.yml. No entanto, além disso (para aumentar a segurança), armazenaríamos vários arquivos específicos do servidor em um servidor de compilação.

iris.key

Chave de licença. Como alternativa, ela pode ser baixada durante a compilação do contêiner em vez de armazenada em um servidor. É bastante arriscado armazenar no repositório.

pwd.txt

Arquivo contendo a senha padrão. Novamente, é bastante arriscado armazená-lo no repositório. Além disso, se você estiver hospedando um ambiente de produção em um servidor separado, ele poderá ter uma senha padrão diferente.

load_ci_icm.script

O script inicial:

  • Carrega o instalador
  • O instalador inicializa o aplicativo
  • Carrega o código
set dir = ##class(%File).NormalizeDirectory($system.Util.GetEnviron("CI_PROJECT_DIR"))
do ##class(%SYSTEM.OBJ).Load(dir _ "Installer/Global.cls","cdk")
do ##class(Installer.Global).init()
halt

Observe que a primeira linha é deixada em branco de maneira intencional.

Várias coisas diferem dos exemplos anteriores. Em primeiro lugar, não habilitamos a autenticação do SO, pois o ICM interagiria com o contêiner em vez do GitLab diretamente. Segundo, estou usando o manifesto do instalador para inicializar nosso aplicativo para mostrar diferentes abordagens de inicialização. Leia mais sobre o Instalador neste artigo. Por fim, publicaremos nossa imagem em um Docher Hub como um repositório privado.

 

Installer/Global.cls

Nosso manifesto do instalador fica desta forma:

E implementa as seguintes mudanças:

  1. Cria o namespace do aplicativo.
  2. Cria o banco de dados de código do aplicativo (os dados seriam armazenados no banco de dados USER).
  3. carrega o código no banco de dados de código do aplicativo.
  4. Mapeia o pacote MyApp para o namespace USER.
  5. Cria dois aplicativos para a Web: para HTML e para REST.

gitlab-ci.yml

Agora, para a configuração da entrega contínua:

build image:
  stage: build
  tags:
    - master
  script:
    - cp -r /InterSystems/mount ci
    - cd ci
    - echo 'SuperUser' | cat - pwd.txt load_ci_icm.script > temp.txt
    - mv temp.txt load_ci.script
    - cd ..
    - docker build --build-arg CI_PROJECT_DIR=$CI_PROJECT_DIR -t eduard93/icmdemo:$CI_COMMIT_REF_NAME .

O que está acontecendo aqui?

Primeiro, como o docker build pode acessar apenas subdiretórios de um diretório de compilação base — na raiz do repositório do nosso caso, precisamos copiar nosso diretório "secreto" (aquele com iris.keypwd.txt e load_ci_icm.script) no repositório clonado.

Em seguida, o primeiro acesso ao terminal requer um usuário/senha, então nós os adicionamos a load_ci.script (por isso a linha vazia no início de load_ci.script).

Por fim, criamos a imagem do docker e a marcamos adequadamente:  eduard93/icmdemo:$CI_COMMIT_REF_NAME

onde $CI_COMMIT_REF_NAME é o nome de um branch atual. Observe que a primeira parte da tag de imagem deve ter o mesmo nome do nome do projeto no GitLab, para que possa ser vista na guia GitLab Registry (instruções sobre a marcação estão disponíveis na guia Registry).

Dockerfile

A criação de uma imagem docker é feita usando o Dockerfile:

FROM intersystems/iris:2018.1.1-released

ENV SRC_DIR=/tmp/src
ENV CI_DIR=$SRC_DIR/ci
ENV CI_PROJECT_DIR=$SRC_DIR

COPY ./ $SRC_DIR

RUN cp $CI_DIR/iris.key $ISC_PACKAGE_INSTALLDIR/mgr/ \
 && cp $CI_DIR/GitLab.xml $ISC_PACKAGE_INSTALLDIR/mgr/ \
 && $ISC_PACKAGE_INSTALLDIR/dev/Cloud/ICM/changePassword.sh $CI_DIR/pwd.txt \
 && iris start $ISC_PACKAGE_INSTANCENAME \
 && irissession $ISC_PACKAGE_INSTANCENAME -U%SYS < $CI_DIR/load_ci.script \
 && iris stop $ISC_PACKAGE_INSTANCENAME quietly

Começamos a partir do contêiner básico iris.

Primeiro, copiamos nosso repositório (e diretório "secreto") dentro do contêiner.

Em seguida, copiamos a chave de licença para o diretório mgr.

Em seguida, alteramos a senha para o valor de pwd.txt. Observe que pwd.txt é excluído nessa operação.

Depois disso, a instância é iniciada e load_ci.script é executado.

Por fim, a instância iris é interrompida.

Estou usando o executor GitLab Shell, e não o executor Docker. O executor Docker é usado quando você precisa de algo de dentro da imagem, por exemplo, você está criando um aplicativo Android em um contêiner java e precisa apenas de um apk. No nosso caso, precisamos de um contêiner inteiro e, para isso, precisamos do executor Shell. Então, estamos executando comandos do Docker pelo executor GitLab Shell.

Publicar

Agora, vamos publicar nossa imagem em um Docker Hub

publish image:
  stage: publish
  tags:
    - master
  script:
    - docker login -u eduard93 -p ${DOCKERPASSWORD}
    - docker push eduard93/icmdemo:$CI_COMMIT_REF_NAME

Observe a variável ${DOCKERPASSWORD}, é uma variável secreta do GitLab. Podemos adicioná-la em GitLab > Project > Settings > CI/CD > Variables:

Os logs de job também não contêm valor de senha:

Running with gitlab-runner 10.6.0 (a3543a27)
  on icm 82634fd1
Using Shell executor...
Running on docker...
Fetching changes...
Removing ci/
HEAD is now at 8e24591 Add deploy to LIVE
Checking out 8e245910 as master...Skipping Git submodules setup$ docker login -u eduard93 -p ${DOCKERPASSWORD}
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded
$ docker push eduard93/icmdemo:$CI_COMMIT_REF_NAME
The push refers to repository [docker.io/eduard93/icmdemo]
master: digest: sha256:d1612811c11154e77c84f0c08a564a3edeb7ddbbd9b7acb80754fda97f95d101 size: 2620
Job succeeded

e no Docker Hub podemos ver nossa nova imagem:

 

Executar

Temos nossa imagem, agora vamos executá-la em nosso servidor de teste. Aqui está o script.

run image:
  stage: run
  environment:
    name: $CI_COMMIT_REF_NAME
  tags:
    - master
  script:
    - docker exec icm sh -c "cd /icmdata/test && icm upgrade -image eduard93/icmdemo:$CI_COMMIT_REF_NAME"

Com o ICM, precisamos executar apenas um comando (icm upgrade) para fazer upgrade da implantação existente. Estamos chamando-a executando "docker exec icm sh -c ", que executa um comando especificado dentro do contêiner icm.  Primeiro, entramos no modo /icmdata/test, onde a definição da implantação do ICM é configurada para um servidor TEST. Depois disso, chamamos icm upgrade para substituir o contêiner existente por um novo contêiner.

Teste

Vamos fazer alguns testes.

test image:
  stage: test
  tags:
    - master
  script:
    - docker exec icm sh -c "cd /icmdata/test && icm session -namespace USER -command 'do \$classmethod(\"%UnitTest.Manager\",\"RunTest\",\"MyApp/Tests\",\"/nodelete\")' | tee /dev/stderr | grep 'All PASSED' && exit 0 || exit 1"

Novamente, estamos executando um comando dentro do nosso contêiner icm. A sessão icm executa um comando em um nó implantado. O comando executa testes de unidade. Depois disso, ele canaliza todos os resultados para a tela e também para o grep para encontrar os resultados dos testes de unidade e sair do processo com sucesso ou com um erro.

Implantar

A implantação em um servidor de produção é absolutamente igual à implantação em teste, exceto por outro diretório para a definição da implantação LIVE. Se os testes falhassem, essa etapa não seria executada.

deploy image:
  stage: deploy
  environment:
    name: $CI_COMMIT_REF_NAME
  tags:
    - master
  script:
    - docker exec icm sh -c "cd /icmdata/live && icm upgrade -image eduard93/icmdemo:$CI_COMMIT_REF_NAME"

Conclusão

O ICM oferece uma maneira simples e intuitiva de provisionar uma infraestrutura na nuvem e implantar serviços nela, ajudando você a entrar na nuvem<nobr>agora</nobr> sem grande desenvolvimento ou reorganização. Os benefícios da infraestrutura como código (IaC) e da implantação em contêiner facilitam a implantação de aplicativos baseados no InterSystems IRIS em plataformas de nuvem públicas, como Google, Amazon e Azure, ou na sua nuvem privada VMware vSphere. Defina o que você quer, emita alguns comandos e o ICM faz o resto.
Mesmo se você já estiver usando infraestrutura de nuvem, contêineres ou ambos, o ICM reduz drasticamente o tempo e o esforço necessários para provisionar e implantar seu aplicativo automatizando várias etapas manuais.
0
0 71
Artigo Danusa Calixto · Fev. 23, 2023 11m read

Nesta série de artigos, quero apresentar e discutir várias abordagens possíveis para o desenvolvimento de software com tecnologias da InterSystems e do GitLab. Vou cobrir tópicos como:

  • Git básico
  • Fluxo Git (processo de desenvolvimento)
  • Instalação do GitLab
  • Fluxo de trabalho do GitLab
  • Entrega contínua
  • Instalação e configuração do GitLab
  • CI/CD do GitLab
  • Por que contêineres?
  • Infraestrutura dos contêineres
  • CD usando contêineres

No primeiro artigo, abordamos os fundamentos do Git, por que um entendimento de alto nível dos conceitos do Git é importante para o desenvolvimento de software moderno e como o Git pode ser usado para desenvolver software.

No segundo artigo, abordamos o fluxo de trabalho do GitLab: um processo inteiro do ciclo de vida do software e a entrega contínua.

No terceiro artigo, abordamos a instalação e configuração do GitLab e a conexão dos seus ambientes a ele

No quarto artigo, escrevemos uma configuração de CD.

No quinto artigo, falamos sobre contêineres e como (e por que) eles podem ser usados.

No sexto artigo, vamos discutir os principais componentes necessários para executar um pipeline de entrega contínua com contêineres e como eles trabalham juntos.

Neste artigo, criaremos a configuração de entrega contínua discutida nos artigos anteriores.

Fluxo de trabalho

Na nossa configuração de entrega contínua:

  • Enviamos código para o repositório do GitLab
  • Criamos a imagem docker
  • Testamos
  • Publicamos a imagem no nosso registro docker
  • Trocamos o contêiner antigo pela nova versão do registro

Ou em formato gráfico:

Vamos começar.

Criação

Primeiro, precisamos criar nossa imagem.

Nosso código seria, como sempre, armazenado no repositório, a configuração de CD em gitlab-ci.yml. No entanto, além disso (para aumentar a segurança), armazenaríamos vários arquivos específicos do servidor em um servidor de compilação.

GitLab.xml

Contém o código dos hooks de CD. Foi desenvolvido no artigo anterior e disponibilizado no GitHub. É uma pequena biblioteca para carregar código, executar vários hooks e testar código. Como alternativa preferencial, você pode usar submódulos git para incluir este projeto ou algo semelhante no seu repositório. Os submódulos são melhores porque é mais fácil mantê-los atualizados. Uma outra alternativa seria marcar as versões no GitLab e carregá-las com o comando ADD.

iris.key

Chave de licença. Como alternativa, ela pode ser baixada durante a compilação do contêiner em vez de armazenada em um servidor. É bastante arriscado armazenar no repositório.

pwd.txt

Arquivo contendo a senha padrão. Novamente, é bastante arriscado armazená-lo no repositório. Além disso, se você estiver hospedando um ambiente de produção em um servidor separado, ele poderá ter uma senha padrão diferente.

load_ci.script

O script inicial:

  • Ativa a autenticação do SO

  • Carrega GitLab.xml

  • Inicializa as configurações do utilitário GitLab

  • Carrega o código

    set sc = ##Class(Security.System).Get("SYSTEM",.Properties) write:('sc) $System.Status.GetErrorText(sc) set AutheEnabled = Properties("AutheEnabled") set AutheEnabled = $zb(+AutheEnabled,16,7) set Properties("AutheEnabled") = AutheEnabled set sc = ##Class(Security.System).Modify("SYSTEM",.Properties) write:('sc) $System.Status.GetErrorText(sc) zn "USER" do ##class(%SYSTEM.OBJ).Load(##class(%File).ManagerDirectory() _ "GitLab.xml","cdk") do ##class(isc.git.Settings).setSetting("hooks", "MyApp/Hooks/") do ##class(isc.git.Settings).setSetting("tests", "MyApp/Tests/") do ##class(isc.git.GitLab).load() halt

Observe que a primeira linha é deixada em branco de maneira intencional.

Como algumas configurações podem ser específicas do servidor, elas não são armazenadas no repositório, mas separadamente. Se o hook inicial for sempre o mesmo, você pode simplesmente armazená-lo no repositório.

gitlab-ci.yml

Agora, para a configuração da entrega contínua:

build image:
  stage: build
  tags:
    - test
  script:
    - cp -r /InterSystems/mount ci
    - cd ci
    - echo 'SuperUser' | cat - pwd.txt load_ci.script > temp.txt
    - mv temp.txt load_ci.script
    - cd ..
    - docker build --build-arg CI_PROJECT_DIR=$CI_PROJECT_DIR -t docker.domain.com/test/docker:$CI_COMMIT_REF_NAME .

O que está acontecendo aqui?

Primeiro, como o docker build pode acessar apenas subdiretórios de um diretório de compilação base — na raiz do repositório do nosso caso, precisamos copiar nosso diretório "secreto" (aquele com GitLab.xmliris.key, pwd.txt e load_ci.script) no repositório clonado.

Em seguida, o primeiro acesso ao terminal requer um usuário/senha, então nós os adicionamos a load_ci.script (por isso a linha vazia no início de load_ci.script).

Por fim, criamos a imagem do docker e a marcamos adequadamente: docker.domain.com/test/docker:$CI_COMMIT_REF_NAME

onde $CI_COMMIT_REF_NAME é o nome de um branch atual. Observe que a primeira parte da tag de imagem deve ter o mesmo nome do nome do projeto no GitLab, para que possa ser vista na guia GitLab Registry (instruções sobre a marcação estão disponíveis na guia Registry).

Dockerfile

A criação da imagem docker é feita usando o Dockerfile:

FROM docker.intersystems.com/intersystems/iris:2018.1.1.611.0

ENV SRC_DIR=/tmp/src
ENV CI_DIR=$SRC_DIR/ci
ENV CI_PROJECT_DIR=$SRC_DIR

COPY ./ $SRC_DIR

RUN cp $CI_DIR/iris.key $ISC_PACKAGE_INSTALLDIR/mgr/ \
 && cp $CI_DIR/GitLab.xml $ISC_PACKAGE_INSTALLDIR/mgr/ \
 && $ISC_PACKAGE_INSTALLDIR/dev/Cloud/ICM/changePassword.sh $CI_DIR/pwd.txt \
 && iris start $ISC_PACKAGE_INSTANCENAME \
 && irissession $ISC_PACKAGE_INSTANCENAME -U%SYS &lt; $CI_DIR/load_ci.script \
 && iris stop $ISC_PACKAGE_INSTANCENAME quietly

Começamos a partir do contêiner básico iris.

Primeiro, copiamos nosso repositório (e diretório "secreto") dentro do contêiner.

Em seguida, copiamos a chave de licença e GitLab.xml para o diretório mgr.

Em seguida, alteramos a senha para o valor de pwd.txt. Observe que pwd.txt é excluído nessa operação.

Depois disso, a instância é iniciada e load_ci.script é executado.

Por fim, a instância iris é interrompida.

Veja o registro do job (parcial, os registros de carregamento/compilação foram ignorados):

Running with gitlab-runner 10.6.0 (a3543a27)
  on docker 7b21e0c4
Using Shell executor...
Running on docker...
Fetching changes...
Removing ci/
Removing temp.txt
HEAD is now at 5ef9904 Build load_ci.script
From http://gitlab.eduard.win/test/docker
   5ef9904..9753a8d  master     -> origin/master
Checking out 9753a8db as master...
Skipping Git submodules setup
$ cp -r /InterSystems/mount ci
$ cd ci
$ echo 'SuperUser' | cat - pwd.txt load_ci.script > temp.txt
$ mv temp.txt load_ci.script
$ cd ..
$ docker build --build-arg CI_PROJECT_DIR=$CI_PROJECT_DIR -t docker.eduard.win/test/docker:$CI_COMMIT_REF_NAME .
Sending build context to Docker daemon  401.4kB

Step 1/6 : FROM docker.intersystems.com/intersystems/iris:2018.1.1.611.0
 ---> cd2e53e7f850
Step 2/6 : ENV SRC_DIR=/tmp/src
 ---> Using cache
 ---> 68ba1cb00aff
Step 3/6 : ENV CI_DIR=$SRC_DIR/ci
 ---> Using cache
 ---> 6784c34a9ee6
Step 4/6 : ENV CI_PROJECT_DIR=$SRC_DIR
 ---> Using cache
 ---> 3757fa88a28a
Step 5/6 : COPY ./ $SRC_DIR
 ---> 5515e13741b0
Step 6/6 : RUN cp $CI_DIR/iris.key $ISC_PACKAGE_INSTALLDIR/mgr/  && cp $CI_DIR/GitLab.xml $ISC_PACKAGE_INSTALLDIR/mgr/  && $ISC_PACKAGE_INSTALLDIR/dev/Cloud/ICM/changePassword.sh $CI_DIR/pwd.txt  && iris start $ISC_PACKAGE_INSTANCENAME  && irissession $ISC_PACKAGE_INSTANCENAME -U%SYS &lt; $CI_DIR/load_ci.script  && iris stop $ISC_PACKAGE_INSTANCENAME quietly
 ---> Running in 86526183cf7c
.
Waited 1 seconds for InterSystems IRIS to start
This copy of InterSystems IRIS has been licensed for use exclusively by:
ISC Internal Container Sharding
Copyright (c) 1986-2018 by InterSystems Corporation
Any other use is a violation of your license agreement

%SYS>
1

%SYS>
Using 'iris.cpf' configuration file

This copy of InterSystems IRIS has been licensed for use exclusively by:
ISC Internal Container Sharding
Copyright (c) 1986-2018 by InterSystems Corporation
Any other use is a violation of your license agreement

1 alert(s) during startup. See messages.log for details.
Starting IRIS

Node: 39702b122ab6, Instance: IRIS

Username:
Password:

Load started on 04/06/2018 17:38:21
Loading file /usr/irissys/mgr/GitLab.xml as xml
Load finished successfully.

USER>

USER>

[2018-04-06 17:38:22.017] Running init hooks: before

[2018-04-06 17:38:22.017] Importing hooks dir /tmp/src/MyApp/Hooks/

[2018-04-06 17:38:22.374] Executing hook class: MyApp.Hooks.Global

[2018-04-06 17:38:22.375] Executing hook class: MyApp.Hooks.Local

[2018-04-06 17:38:22.375] Importing dir /tmp/src/

Loading file /tmp/src/MyApp/Tests/TestSuite.cls as udl

Compilation started on 04/06/2018 17:38:22 with qualifiers 'c'
Compilation finished successfully in 0.194s.

Load finished successfully.

[2018-04-06 17:38:22.876] Running init hooks: after

[2018-04-06 17:38:22.878] Executing hook class: MyApp.Hooks.Local

[2018-04-06 17:38:22.921] Executing hook class: MyApp.Hooks.Global
Removing intermediate container 39702b122ab6
 ---> dea6b2123165
[Warning] One or more build-args [CI_PROJECT_DIR] were not consumed
Successfully built dea6b2123165
Successfully tagged docker.domain.com/test/docker:master
Job succeeded

Estou usando o executor GitLab Shell, e não o executor Docker. O executor Docker é usado quando você precisa de algo de dentro da imagem, por exemplo, você está criando um aplicativo Android em um contêiner java e precisa apenas de um apk. No nosso caso, precisamos de um contêiner inteiro e, para isso, precisamos do executor Shell. Então, estamos executando comandos do Docker pelo executor GitLab Shell.

 

Executar

Temos nossa imagem, agora vamos executá-la.  No caso de ramificações de recursos, podemos simplesmente destruir o contêiner antigo e iniciar o novo. No caso do ambiente, podemos executar um container temporário e substituir o contêiner do ambiente caso os testes tenham êxito (isso fica como um exercício para o leitor).

Aqui está o script.

destroy old:
  stage: destroy
  tags:
    - test
  script:
    - docker stop iris-$CI_COMMIT_REF_NAME || true
    - docker rm -f iris-$CI_COMMIT_REF_NAME || true

Esse script destrói o contêiner em execução no momento e é sempre bem-sucedido (por padrão, o docker falha se tentar parar/remover um contêiner inexistente).

Em seguida, iniciamos a nova imagem e a registramos como um ambiente. Contêiner Nginx faz proxy automático de solicitações usando a variável de ambiente VIRTUAL_HOST e a diretiva de exposição (para saber em qual porta fazer o proxy).

run image:
  stage: run
  environment:
    name: $CI_COMMIT_REF_NAME
    url: http://$CI_COMMIT_REF_SLUG. docker.domain.com/index.html
  tags:
    - test
  script:
    - docker run -d
      --expose 52773
      --env VIRTUAL_HOST=$CI_COMMIT_REF_SLUG.docker.eduard.win
      --name iris-$CI_COMMIT_REF_NAME
      docker.domain.com/test/docker:$CI_COMMIT_REF_NAME
      --log $ISC_PACKAGE_INSTALLDIR/mgr/messages.log

 

Testes

Vamos fazer alguns testes.

test image:
  stage: test
  tags:
    - test
  script:
    - docker exec iris-$CI_COMMIT_REF_NAME irissession iris -U USER "##class(isc.git.GitLab).test()"

Publicar

Por fim, vamos publicar nossa imagem no registro

publish image:
  stage: publish
  tags:
    - test
  script:
    - docker login docker.domain.com -u dev -p 123
    - docker push docker.domain.com/test/docker:$CI_COMMIT_REF_NAME

O usuário/código pode ser transmitido usando variáveis secretas do GitLab.

Agora, podemos ver a imagem no GitLab:

E outros desenvolvedores podem a extrair do registro. Na guia de ambientes, todos os ambientes estão disponíveis para a fácil navegação:

 

Conclusão

Nessa série de artigos, discuti abordagens gerais de entrega contínua. É um tema extremamente vasto e essa série de artigos precisa ser vista mais como uma coleção de receitas do que algo definitivo. Se você deseja automatizar o desenvolvimento, os testes e a entrega do seu aplicativo, a entrega contínua em geral e o GitLab em particular é o melhor caminho. A entrega contínua e os contêineres permitem que você personalize seu fluxo de trabalho conforme necessário.

Links

O que vem a seguir

É isso. Espero que eu tenha abordado os conceitos básicos da entrega contínua e dos contêineres.

Há vários tópicos sobre os quais não falei (talvez mais tarde), especialmente em relação a contêineres:

  • Os dados podem ser persistentes fora do contêiner. Veja a documentação relacionada.
  • Plataformas de orquestração como kubernetes
  • InterSystems Cloud Manager
  • Gerenciamento de ambiente - criando ambientes temporários para testes, removendo ambientes antigos após a mesclagem de ramificações de recursos
  • Docker compose para implantações de vários contêineres
  • Diminuindo o tamanho da imagem docker e os tempos de construção
  • ...
0
0 157
Artigo Danusa Calixto · Fev. 23, 2023 7m read

Nesta série de artigos, quero apresentar e discutir várias abordagens possíveis para o desenvolvimento de software com tecnologias da InterSystems e do GitLab. Vou cobrir tópicos como:

  • Git básico
  • Fluxo Git (processo de desenvolvimento)
  • Instalação do GitLab
  • Fluxo de trabalho do GitLab
  • Entrega contínua
  • Instalação e configuração do GitLab
  • CI/CD do GitLab
  • Por que contêineres?
  • Infraestrutura dos contêineres
  • CI/CD do GitLab usando contêineres

No primeiro artigo, abordamos os fundamentos do Git, por que um entendimento de alto nível dos conceitos do Git é importante para o desenvolvimento de software moderno e como o Git pode ser usado para desenvolver software.

No segundo artigo, abordamos o fluxo de trabalho do GitLab: um processo inteiro do ciclo de vida do software e a entrega contínua.

No terceiro artigo, abordamos a instalação e configuração do GitLab e a conexão dos seus ambientes a ele

No quarto artigo, escrevemos uma configuração de CD.

No quinto artigo, falamos sobre contêineres e como (e por que) eles podem ser usados.

Neste artigo, vamos discutir os principais componentes necessários para executar um pipeline de entrega contínua com contêineres e como eles trabalham juntos.

A configuração deve ser assim:

Aqui podemos ver a separação de três etapas principais:

  • Criação
  • Envio
  • Execução

Criação

Nas partes anteriores, a criação era frequentemente incremental — calculamos a diferença entre o ambiente e a codebase atuais e modificamos nosso ambiente para corresponder à codebase. Com contêineres, cada build é completo. O resultado de um build é uma imagem que pode ser executada em qualquer lugar com dependências.

Envio

Depois que nossa imagem é criada e aprovada nos testes, ela é carregada no registro — servidor especializado para hospedar imagens docker. Então, é possível substituir a imagem anterior pela mesma tag. Por exemplo, devido ao novo commit para o master branch, nós construímos a nova imagem (project/version:master) e, se os testes funcionarem, podemos substituir a imagem no registro pela nova com a mesma tag, então todos que extraírem project/version:master obtêm uma nova versão.

Execução

Por fim, nossas imagens são implantadas. Uma solução de CI, como o GitLab, pode controlar isso ou um orquestrador especializado, mas o ponto é o mesmo: algumas imagens são executadas, verificadas periodicamente quanto à integridade e atualizadas se uma nova versão estiver disponível.

Confira o webinar docker explicando esses diferentes estágios.

Como alternativa, do ponto de vista do commit:

Na nossa configuração de entrega:

  • Enviamos código para o repositório do GitLab
  • Criamos a imagem docker
  • Testamos
  • Publicamos a imagem no nosso registro docker
  • Trocamos o contêiner antigo pela nova versão do registro

Para fazer isso, precisamos do seguinte:

  • Docker
  • Registro docker
  • Domínio registrado (opcional, mas recomendado)
  • Ferramentas de GUI (opcional)

 

Docker

Primeiro de tudo, precisamos executar o docker em algum lugar. Recomendo começar com um servidor mais convencional tipo o Linux, como Ubuntu, RHEL ou Suse. Não use distribuições voltadas para a nuvem, como CoreOS, RancherOS etc. — elas não são destinadas a iniciantes. Não se esqueça de trocar o driver de armazenamento para devicemapper

Em caso de grandes implantações, usar ferramentas de orquestração de contêineres, como Kubernetes, Rancher ou Swarm, pode automatizar a maioria das tarefas, mas não vamos discuti-las (pelo menos nesta parte).

 

Registro docker

Esse é o primeiro contêiner que precisamos executar e é um aplicativo do lado do servidor escalável e sem estado que armazena e permite distribuir imagens Docker.
Use o registro se quiser:

  •  controlar rigidamente onde as imagens estão sendo armazenadas
  •  possuir totalmente o pipeline de distribuição das imagens
  •  integrar o armazenamento e a distribuição de imagens firmemente no seu fluxo de trabalho de desenvolvimento interno

Veja a documentação do registro.

Conexão do registro e do GitLab

Observação: o GitLab inclui registro integrado. Você pode executá-lo em vez do registro externo. Leia os documentos do GitLab vinculados neste parágrafo.

Para conectar seu registro ao GitLab, você precisará executar seu registro com suporte HTTPS  — eu uso o Let's Encrypt para obter os certificados e segui este Gist para obter e transmitir os certificados a um contêiner. Depois de garantir a disponibilidade do registro em HTTPS (você pode verificar no navegador), siga estas instruções sobre como conectar o registro ao GitLab.  Essas instruções diferem com base no que você precisa e na sua instalação do GitLab. No meu caso, a configuração foi adicionar o certificado do registro e a chave (com o nome adequado e as permissões corretas) a /etc/gitlab/ssl e estas linhas a /etc/gitlab/gitlab.rb:

registry_external_url 'https://docker.domain.com'
gitlab_rails['registry_api_url'] = "https://docker.domain.com"

Depois de reconfigurar o GitLab, pude ver a nova guia do Registro, com informações sobre como marcar corretamente as imagens recém-criadas para que elas apareçam aqui.

 

Domínio

Na nossa configuração de Entrega Contínua, construímos automaticamente uma imagem por branch e, se a imagem passar nos testes, ela é publicada no registro e executada automaticamente. Para que nosso aplicativo fique disponível em todos os "estados" de maneira automática, por exemplo, podemos acessar:

  • Vários recursos de ramificações em <featureName>.docker.domain.com
  • Versão de teste em master.docker.domain.com
  • Versão pré-produção em preprod.docker.domain.com
  • Versão de produção em prod.docker.domain.com

Para isso, precisamos de um nome de domínio e adicionamos um registro DNS curinga que aponta *.docker.domain.com ao endereço IP de docker.domain.com. Outra opção seria usar portas diferentes.

Proxy Nginx

Como temos várias ramificações de recursos, precisamos redirecionar os subdomínios automaticamente para o contêiner correto. Para fazer isso, podemos usar o Nginx como proxy reverso. Veja aqui um guia.

Ferramentas de GUI

Para começar a trabalhar com contêineres, você pode usar a linha de comando ou uma das interfaces GUI. Há várias disponíveis, por exemplo:

  • Rancher
  • MicroBadger
  • Portainer
  • Simple Docker UI
  • ...

Eles permitem que você crie contêineres e os gerencie a partir da GUI em vez da CLI. Veja como o Rancher aparenta:

 

Runner do GitLab

Como antes, para executar scripts em outros servidores, precisaremos instalar o runner do GitLab. Discuti isso no terceiro artigo.

Você precisará usar o executor Shell, e não o executor Docker. O executor Docker é usado quando você precisa de algo de dentro da imagem, por exemplo, você está criando um aplicativo Android em um contêiner java e precisa apenas de um apk. No nosso caso, precisamos de um contêiner inteiro e, para isso, precisamos do executor Shell.

 

Conclusão

É fácil começar a executar contêineres e há muitas ferramentas disponíveis.

A entrega contínua usando contêineres difere da configuração usual de várias maneiras:

  • As dependências são atendidas no momento da compilação e, após a criação da imagem, você não precisa pensar nas dependências.
  • Reprodutibilidade — é possível reproduzir facilmente qualquer ambiente existente ao executar o mesmo contêiner localmente.
  • Velocidade — como os contêineres não têm nada além do que você adicionou explicitamente, eles podem ser construídos com mais rapidez e, principalmente, eles são construídos uma vez e usados sempre que necessário.
  • Eficiência — como acima, os contêineres produzem menos sobrecarga do que, por exemplo, VMs.
  • Escalabilidade — com ferramentas de orquestração, você pode dimensionar automaticamente seu aplicativo para a carga de trabalho e consumir apenas os recursos necessários no momento.

O que vem a seguir

      <p>
        No próximo artigo, vamos falar sobre a criação da configuração de CD que usa o contêiner Docker do InterSystems IRIS.
      </p>
    </div>
  </div>
</div>
0
0 364
Artigo Danusa Calixto · Dez. 22, 2022 6m read

Nesta série de artigos, quero apresentar e discutir várias abordagens possíveis para o desenvolvimento de software com tecnologias da InterSystems e do GitLab. Vou cobrir tópicos como:

  • Git básico
  • Fluxo Git (processo de desenvolvimento)
  • Instalação do GitLab
  • Fluxo de trabalho do GitLab
  • Entrega contínua
  • Instalação e configuração do GitLab
  • CI/CD do GitLab
  • Por que contêineres?
  • CI/CD do GitLab usando contêineres

No primeiro artigo, abordamos os fundamentos do Git, por que um entendimento de alto nível dos conceitos do Git é importante para o desenvolvimento de software moderno e como o Git pode ser usado para desenvolver software.

No segundo artigo, abordamos o fluxo de trabalho do GitLab: um processo inteiro do ciclo de vida do software e a entrega contínua.

No terceiro artigo, abordamos a instalação e configuração do GitLab e a conexão dos seus ambientes a ele

No quarto artigo, escrevemos uma configuração de CD.

Neste artigo, falaremos sobre os contêineres e como (e por que) podem ser usados.

Este artigo presume a familiaridade com os conceitos de docker e contêiner. Confira estes artigos do @Luca Ravazzolo se quiser ler sobre contêineres e imagens.

Vantagens

Há muitas vantagens em usar contêineres:

  • Portabilidade
  • Eficiência
  • Isolamento
  • Leveza
  • Imutabilidade

Vamos falar sobre cada uma em detalhes.

Portabilidade

Um contêiner embrulha um aplicativo com tudo o que ele precisa para ser executado, como arquivos de configuração e dependências. Isso permite que você execute aplicativos de maneira fácil e confiável em diferentes ambientes, como seu desktop local, servidores físicos, servidores virtuais, testes, staging, ambientes de produção e nuvens públicas ou privadas.

Outro ponto da portabilidade é que, depois de criar sua imagem do Docker e verificar que ela é executada corretamente, ela pode ser executada em qualquer outro lugar que execute o docker, que atualmente são os servidores Windows, Linux e MacOS.

Eficiência

Você só precisa que o processo do aplicativo seja executado, e não todo o sistema, etc. E os contêineres oferecem exatamente isso: eles executam apenas os processos de que você precisa explicitamente e nada mais. Como os contêineres não exigem um sistema operacional separado, eles consomem menos recursos. Enquanto uma VM costuma ter vários gigabytes de tamanho, um contêiner geralmente tem apenas algumas centenas de megabytes, tornando possível executar muito mais contêineres do que VMs em um único servidor. Como os contêineres têm um nível de uso mais alto em relação ao hardware subjacente, você precisa de menos hardware, resultando em uma redução nos custos dos servidores bare metal, bem como dos centros de processamento de dados.

Isolamento

Os contêineres isolam seu aplicativo de todo o resto e, embora vários contêineres possam ser executados no mesmo servidor, eles podem ser completamente independentes uns dos outros. Qualquer interação entre contêineres deve ser explicitamente declarada como tal. Se um contêiner falhar, ele não afetará os outros e poderá ser reiniciado rapidamente. A segurança também se beneficia desse isolamento. Por exemplo, explorar a vulnerabilidade do servidor web em um servidor bare metal pode dar a um invasor acesso a todo o servidor, mas, no caso dos contêineres, o invasor só teria acesso ao contêiner do servidor web.

Leveza

Como os contêineres não exigem um sistema operacional separado, eles podem ser iniciados, interrompidos ou reinicializados em questão de segundos, o que acelera todos os pipelines de desenvolvimento relacionados e o tempo de produção. Você pode começar a trabalhar antes e não gastar nenhum tempo na configuração. 

Imutabilidade

A infraestrutura imutável é composta por componentes imutáveis que são substituídos a cada implantação, em vez de serem atualizados no local. Esses componentes são inicializados a partir de uma imagem comum que é criada uma vez por implantação e pode ser testada e validada. A imutabilidade reduz a inconsistência e permite a replicação e a movimentação entre diferentes estados do seu aplicativo com facilidade. Mais sobre a imutabilidade.

Novas possibilidades

Todas essas vantagens nos permitem gerenciar a infraestrutura e o fluxo de trabalho de maneiras totalmente novas.

Orquestração

Há um problema com ambientes bare metal ou VM, eles ganham individualidade, o que traz várias surpresas depois, geralmente desagradáveis. A resposta para isso é a infraestrutura como código, o gerenciamento da infraestrutura em um modelo descritivo, usando as mesmas versões que a equipe de DevOps usa para o código-fonte.

Com a infraestrutura como código, um comando de implantação sempre coloca o ambiente de destino na mesma configuração, não importa o estado inicial do ambiente. Isso é alcançado ao configurar automaticamente um destino existente ou descartar o destino existente e recriar um novo ambiente.

Assim, com a infraestrutura como código, as equipes fazem alterações na descrição do ambiente e na versão do modelo de configuração, que normalmente está em formatos de código bem documentados, como JSON. O pipeline de lançamento executa o modelo para configurar ambientes de destino. Se a equipe precisar fazer alterações, ela editará a fonte, e não o destino.

Tudo isso é possível e muito mais fácil de fazer com contêineres. Leva poucos segundos para desativar um contêiner e iniciar outro, enquanto o provisionamento de uma nova VM leva alguns minutos. E nem estou falando em reverter um servidor para um estado limpo.

Escalonamento

Do ponto anterior, você pode ter uma ideia de que a infraestrutura como código é estática por si só. Não é, pois as ferramentas de orquestração também podem fornecer escalonamento horizontal (provisionando mais do mesmo) com base na carga de trabalho atual. Você só deve executar o que é necessário no momento e escalonar seu aplicativo de acordo. Isso também pode reduzir custos.

Conclusão

Os contêineres podem otimizar seu pipeline de desenvolvimento. A eliminação de inconsistências entre ambientes permite testes e depurações mais fáceis. A orquestração permite que você crie aplicativos escalonáveis.  A implantação ou reversão para qualquer ponto do histórico imutável é possível e fácil.

As organizações querem trabalhar em um nível mais alto, onde todos os problemas listados acima já estejam resolvidos e onde encontramos agendadores e orquestradores lidando com mais coisas de maneira automatizada.

O que vem a seguir

      <p>
        No próximo artigo, vamos falar sobre o provisionamento com contêineres e a criação da configuração de CD que usa o contêiner Docker do InterSystems IRIS.
      </p>
    </div>
  </div>
</div>
0
0 88
InterSystems Oficial Angelo Bruno Braga · Dez. 13, 2022

Anunciando a Interface Web para Usuários do Registro de Contêineres InterSystems

A InterSystems tem o prazer de anunciar o lançamento da Interface Web para Usuários do Registro de Contêineres InterSystems. Essa ferramenta foi projetada para facilitar a descoberta, o acesso e o uso de muitas imagens de contêiner hospedadas no ICR

A IU do InterSystems Container Registry está disponível em: https://containers.intersystems.com/contents

Contêineres da Edição Community

0
0 60
Artigo Danusa Calixto · Nov. 9, 2022 10m read

Nesta série de artigos, quero apresentar e discutir várias abordagens possíveis para o desenvolvimento de software com tecnologias da InterSystems e do GitLab. Vou cobrir tópicos como:

  • Git básico
  • Fluxo Git (processo de desenvolvimento)
  • Instalação do GitLab
  • Fluxo de trabalho do GitLab
  • Entrega contínua
  • Instalação e configuração do GitLab
  • CI/CD do GitLab

No artigo anterior, abordamos os fundamentos do Git, por que um entendimento de alto nível dos conceitos do Git é importante para o desenvolvimento de software moderno e como o Git pode ser usado para desenvolver software. Ainda assim, nosso foco foi na parte da implementação do desenvolvimento de software, mas esta parte apresenta:

  • Fluxo de trabalho do GitLab — um processo completo do ciclo de vida do software, desde a ideia até o feedback do usuário
  • Entrega Contínua — uma abordagem de engenharia de software em que as equipes produzem software em ciclos curtos, garantindo que o software possa ser lançado de forma confiável a qualquer momento. Seu objetivo é construir, testar e lançar software com mais rapidez e frequência.

Fluxo de trabalho do GitLab

O fluxo de trabalho do GitLab é uma sequência lógica de possíveis ações a serem tomadas durante todo o ciclo de vida do processo de desenvolvimento de software.

O fluxo de trabalho do GitLab leva em consideração o fluxo do GitLab, que discutimos em um artigo anterior. Veja como funciona:

  1. Ideia: todas as novas propostas começam com uma ideia.
  2. Problema: a maneira mais eficaz de discutir uma ideia é criar um problema para ela. Sua equipe e seus colaboradores podem ajudar você a aprimorar e melhorar a ideia no rastreador de problemas.
  3. Plano: quando a discussão chega a um acordo, é hora de programar. Porém, primeiro, precisamos priorizar e organizar nosso fluxo de trabalho ao atribuir problemas a marcos e quadro de problemas.
  4. Código: agora estamos prontos para escrever nosso código, já que está tudo organizado.
  5. Commit: depois de satisfeitos com o rascunho, podemos enviar nosso código para um feature-branch com controle de versão. O fluxo do GitLab foi explicado em detalhes no artigo anterior.
  6. Teste: executamos nossos scripts usando o CI GitLab, para construir e testar nosso aplicativo.
  7. Revisão: assim que nosso script funcionar e nossos testes e compilações forem bem-sucedidos, estamos prontos para que nosso código seja revisado e aprovado.
  8. Staging: agora é hora de implantar nosso código em um ambiente de staging para verificar se tudo funciona como esperado ou se ainda precisamos de ajustes.
  9. Produção: quando tudo estiver funcionando como deve, é hora de implantar no nosso ambiente de produção!
  10. Feedback: agora é hora de olhar para trás e verificar qual etapa do nosso trabalho precisa ser melhorada.

Novamente, o processo em si não é novo (ou exclusivo do GitLab) e pode ser alcançado com outras ferramentas da sua escolha.

Vamos discutir várias dessas etapas e o que elas implicam. Também há documentação disponível.

Problema e plano

As etapas iniciais do fluxo de trabalho do GitLab são centradas em um problema: um recurso, bug ou outro tipo de trabalho semanticamente separado.

O problema tem várias finalidades, como:

  • Gerenciamento: um problema tem data de vencimento, pessoa designada, tempo gasto e estimativas, etc. para ajudar a monitorar a resolução do problema.
  • Administrativo: um problema faz parte de um marco, quadro kanban, que nos permite rastrear nosso software à medida que ele avança de versão para versão.
  • Desenvolvimento: um problema tem uma discussão e commits associados a ele.

A etapa de planejamento nos permite agrupar os problemas por prioridade, marco, quadro kanban e ter uma visão geral disso.

O desenvolvimento foi discutido na parte anterior, basta seguir qualquer fluxo git que quiser. Depois que desenvolvemos nosso novo recurso e o mesclamos no master: o que vem depois?

Entrega contínua

A entrega contínua é uma abordagem de engenharia de software em que as equipes produzem software em ciclos curtos, garantindo que o software possa ser lançado de forma confiável a qualquer momento. Seu objetivo é construir, testar e lançar software com mais rapidez e frequência. A abordagem ajuda a reduzir o custo, o tempo e o risco da entrega de alterações, permitindo mais atualizações incrementais para aplicativos em produção. Um processo de implantação simples e repetível é importante para a entrega contínua.

Entrega contínua no GitLab

No GitLab, a configuração da entrega contínua é definida por repositório como um arquivo de configuração YAML.

  • A configuração de entrega contínua é uma série de estágios consecutivos.
  • Cada estágio tem um ou vários scripts que são executados em paralelo.

O script define uma ação e quais condições devem ser atendidas para executá-la:

  • O que fazer (executar o comando do SO, executar um contêiner)?
  • Quando executar o script:
    • Quais são os gatilhos (commit de um branch específico)?
    • Nós o executamos se os estágios anteriores falharam?
  • Executar manualmente ou automaticamente?
  • Em que ambiente executar o script?
  • Quais artefatos salvar após a execução dos scripts (eles são carregados do ambiente para o GitLab para facilitar o acesso)?

Ambiente - é um servidor ou contêiner configurado no qual você pode executar seus scripts.

Runners executam scripts em ambientes específicos. Eles são conectados ao GitLab e executam scripts conforme necessário.

O runner pode ser implantado em um servidor, contêiner ou até mesmo na sua máquina local.

Como acontece a entrega contínua?

  1. O novo commit é enviado para o repositório.
  2. O GitLab verifica a configuração de entrega contínua.
  3. A configuração de entrega contínua contém todos os scripts possíveis para todos os casos, para que sejam filtrados para um conjunto de scripts que devem ser executados para esse commit específico (por exemplo, um commit para o branch master aciona apenas ações relacionadas a um branch master). Esse conjunto é chamado de pipeline.
  4. O pipeline é executado em um ambiente de destino e os resultados da execução são salvos e exibidos no GitLab.

Por exemplo, aqui está um pipeline executado após um commit em um branch master:

Ele consiste em quatro etapas, executadas consecutivamente

  1. O estágio de carregamento carrega o código em um servidor
  2. O estágio de teste executa testes de unidade
  3. O estágio de pacote consiste em dois scripts executados em paralelo:
    • Compilação cliente
    • Código de exportação do servidor (principalmente para fins informativos)
  4. O estágio de implantação move o cliente criado para o diretório do servidor web.

Como podemos ver, todos os scripts foram executados com sucesso. Se um dos scripts falhar, por padrão, os scripts posteriores não são executados (mas podemos alterar esse comportamento):

Se abrirmos o script, podemos ver o log e determinar por que ele falhou:

Running with gitlab-runner 10.4.0 (857480b6)
 on test runner (ab34a8c5)
Using Shell executor...
Running on gitlab-test...
&lt;span class="term-fg-l-green term-bold">Fetching changes...&lt;/span>
Removing diff.xml
Removing full.xml
Removing index.html
Removing tests.html
HEAD is now at a5bf3e8 Merge branch '4-versiya-1-0' into 'master'
From http://gitlab.eduard.win/test/testProject
 * [new branch] 5-versiya-1-1 -> origin/5-versiya-1-1
 a5bf3e8..442a4db master -> origin/master
 d28295a..42a10aa preprod -> origin/preprod
 3ac4b21..7edf7f4 prod -> origin/prod
&lt;span class="term-fg-l-green term-bold">Checking out 442a4db1 as master...&lt;/span>
&lt;span class="term-fg-l-green term-bold">Skipping Git submodules setup&lt;/span>
&lt;span class="term-fg-l-green term-bold">$ csession ensemble "##class(isc.git.GitLab).loadDiff()"&lt;/span>

[2018-03-06 13:58:19.188] Importing dir /home/gitlab-runner/builds/ab34a8c5/0/test/testProject/

[2018-03-06 13:58:19.188] Loading diff between a5bf3e8596d842c5cc3da7819409ed81e62c31e3 and 442a4db170aa58f2129e5889a4bb79261aa0cad0

[2018-03-06 13:58:19.192] Variable modified
var=$lb("MyApp/Info.cls")

Load started on 03/06/2018 13:58:19
Loading file /home/gitlab-runner/builds/ab34a8c5/0/test/testProject/MyApp/Info.cls as udl
Load finished successfully.

[2018-03-06 13:58:19.241] Variable items
var="MyApp.Info.cls"
var("MyApp.Info.cls")=""

Compilation started on 03/06/2018 13:58:19 with qualifiers 'cuk /checkuptodate=expandedonly'
Compiling class MyApp.Info
Compiling routine MyApp.Info.1
ERROR: MyApp.Info.cls(version+2) #1003: Expected space : '}' : Offset:14 [zversion+1^MyApp.Info.1]
 TEXT:  quit, "1.0" }
Detected 1 errors during compilation in 0.010s.

[2018-03-06 13:58:19.252] ERROR #5475: Error compiling routine: MyApp.Info.1. Errors: ERROR: MyApp.Info.cls(version+2) #1003: Expected space : '}' : Offset:14 [zversion+1^MyApp.Info.1]
 > ERROR #5030: An error occurred while compiling class 'MyApp.Info'
&lt;span class="term-fg-l-red term-bold">ERROR: Job failed: exit status 1
&lt;/span>

O erro de compilação causou a falha do nosso script.

Conclusão

  • O GitLab é compatível com todos os principais estágios de desenvolvimento de software.
  • A entrega contínua pode ajudar você a automatizar tarefas de construção, teste e implantação do seu software.

O que vem a seguir?

No próximo artigo, vamos:

  • Instalar o GitLab.
  • Conectá-lo a diversos ambientes com os produtos InterSystems instalados.
  • Escrever uma configuração de entrega contínua.

Vamos discutir como a entrega contínua deve funcionar.

Em primeiro lugar, precisamos de vários ambientes e branches que correspondam a eles. O código entra nesse branch e é entregue ao ambiente de destino:

AmbienteBranchEntregaQuem pode fazer enviosQuem pode mesclar
TestemasterAutomáticoDesenvolvedores  ProprietáriosDesenvolvedores  Proprietários
PreprodpreprodAutomáticoNinguémProprietários
ProdprodSemiautomático (pressionar botão para entregar)NinguémProprietários

E, como exemplo, desenvolveremos um novo recurso usando o fluxo do GitLab e o entregaremos usando a CD do GitLab.

  1. O recurso é desenvolvido em um branch de recursos.
  2. O branch de recurso é revisado e mesclado no master branch.
  3. Depois de um tempo (vários recursos mesclados), o master é mesclado com o preprod
  4. Depois de um tempo (teste do usuário, etc.), o preprod é mesclado com o prod

Veja como ficaria:

  1. Desenvolvimento e teste
    • O desenvolvedor envia o código para o novo recurso em um branch de recursos separado
    • Depois que o recurso se torna estável, o desenvolvedor mescla nosso branch de recursos no master branch
    • O código do branch master é entregue ao ambiente de teste, onde é carregado e testado
  2. Entrega para o ambiente de pré-produção
    • O desenvolvedor cria a solicitação de mesclagem do branch master para o branch de pré-produção
    • Depois de algum tempo, o proprietário do repositório aprova a solicitação de mesclagem
    • O código do branch de pré-produção é entregue ao ambiente de pré-produção
  3. Entrega para o ambiente de produção
    • O desenvolvedor cria a solicitação de mesclagem do branch de pré-produção para o branch de produção
    • Depois de algum tempo, o proprietário do repositório aprova a solicitação de mesclagem
    • O proprietário do repositório aperta o botão "Implantar"
    • O código do branch de produção é entregue ao ambiente de produção

Ou o mesmo, mas em formato gráfico:

 

0
0 302
Artigo Danusa Calixto · Out. 18, 2022 1m read

Análise do InterSystems Developer Community. Projeto criado com o BI do InterSystems IRIS (DeepSee), Power BI e Logi Report Designer para visualizar e analisar membros, artigos, perguntas, respostas, visualizações e outros conteúdos e atividades no InterSystems Developer Community.

Você pode ver sua própria atividade, artigos e perguntas. Monitore a forma como sua contribuição muda a comunidade de desenvolvedores.

Analise estatísticas sobre você e seus amigos usando BI do IRIS, Análise Adaptativa, Relatórios da InterSystems, Tableau e Power BI.

Esse projeto contém implantação IRIS e Atscale pré-configurada em contêineres Docker e arquivos de projeto para sistemas de BI.

Veja mais informações detalhadas no README do aplicativo correspondente.

Esse projeto também foi implantado online e você pode conferir aqui.

0
0 65
InterSystems Oficial Angelo Bruno Braga · Mar. 23, 2022

O InterSystems Kubernetes Operation (IKO) versão 3.3 está disponível através da página de download do WRC e do InterSystems Container Registry.

IKO simplifica o trabalho com o InterSystems IRIS ou InterSystems IRIS for Health em Kubernetes fornecendo uma definição de recursoirisCluster fácil de se utilizar. Verifique a documentação para uma lista completa de funcionalidades, incluindo sharding, espelhamento e configuração de ECP.

IKO 3.3 Destaques:

  • Suporte para as edições 2021.2 e 2022.1 do InterSystems IRIS & IRIS for Health
  • Suporte para Kuberentes 1.21
  • Implantação de configurações do System Alerting and Monitoring (SAM) como parte de seu irisCluster
  • O InterSystems API Manager (IAM) pode agora ser implantado e gerenciado como parte do irisCluster
  • Marcação automática do membro ativo do par de espelhamento, permitindo que um serviço possa sempre apontar para o membro ativo do espelhamento.
0
0 100
Artigo Eduard Lebedyuk · Nov. 22, 2021 8m read

Todo mundo tem um ambiente de teste.

Algumas pessoas têm a sorte de ter um ambiente totalmente separado para executar a produção.

-- Desconhecido

.

Nesta série de artigos, gostaria de apresentar e discutir várias abordagens possíveis para o desenvolvimento de software com as tecnologias InterSystems e GitLab. Vou cobrir tópicos como:

  • Git Básico
  • Fluxo Git (processo de desenvolvimento)
  • Instalação do GitLab
  • Fluxo de Trabalho do GitLab
  • GitLab CI/CD
  • CI/CD com contêineres

Esta primeira parte trata do pilar do desenvolvimento de software moderno - sistema de controle de versão Git e vários fluxos Git.

Git Básico

Embora o tópico principal que iremos discutir seja o desenvolvimento de software em geral e como o GitLab pode nos capacitar nesse esforço, o Git, ou melhor, os vários conceitos de alto nível subjacentes no design do Git, são importantes para o melhor entendimento de conceitos posteriores.

Dito isso, o Git é um sistema de controle de versão, baseado nessas ideias (existem muitas outras, essas são as mais importantes):

  • Desenvolvimento não linear significa que enquanto nosso software é lançado consequentemente da versão 1 para a 2 para a 3, sob a mesa a mudança da versão 1 para a 2 é feita em paralelo - vários desenvolvedores desenvolvem uma série de recursos/correções de bugs simultaneamente.
  • Desenvolvimento distribuído significa que o desenvolvedor é independente de um servidor central ou de outros desenvolvedores e pode desenvolver facilmente em seu próprio ambiente.
  • Fusão - as duas ideias anteriores nos levam à situação em que muitas versões diferentes da verdade existem simultaneamente e precisamos uni-las de volta em um estado completo.

Agora, não estou dizendo que Git inventou esses conceitos. Não. Em vez disso, o Git os tornou fáceis e populares e isso, juntamente com várias inovações relacionadas, ou seja,  infraestrutura como código/conteinerização mudou o desenvolvimento de software.

Termos básicos do Git

Repositório é um projeto que armazena dados e metainformações sobre os dados.

  • O repositório "físico" é um diretório em um disco.
  • O repositório armazena arquivos e diretórios.
  • O repositório também armazena um histórico completo de alterações para cada arquivo.

O repositório pode ser armazenado:

  • Localmente, em seu próprio computador
  • Remotamente em um servidor remoto

Mas não há nenhuma diferença particular entre repositórios locais e remotos do ponto de vista do git.

Commit é um estado fixo do repositório. Obviamente, se cada commit armazenasse o estado completo do repositório, nosso repositório cresceria muito rapidamente. É por isso que um commit armazena um diff que é uma diferença entre o commit atual e seu commit pai.

Commits diferentes podem ter um número diferente de pais:

  • 0 - o primeiro commit no repositório não tem pais.
  • 1 - conforme o habitual - nosso commit mudou algo no repositório como era durante o commit pai
  • 2 - quando temos dois estados diferentes do repositório, podemos uni-los em um novo estado. E esse estado e esse commit teriam 2 pais.
  • 2 - pode acontecer quando unimos mais de 2 estados diferentes do repositório em um novo estado. Não seria particularmente relevante para nossa discussão, mas existe.

Agora, para um pai, cada commit diferente é chamado de commit filho. Cada commit pai pode ter qualquer número de commits filhos.

Branch é uma referência (ou ponteiro) para um commit.  Veja como funciona:

Nesta imagem, podemos ver o repositório com dois commits (círculos cinza), o segundo é o head do branch master. Depois de adicionar mais commits, nosso repositório começa a ficar assim:

Esse é o caso mais simples. Um desenvolvedor trabalha em uma mudança de cada vez. No entanto, normalmente, existem muitos desenvolvedores trabalhando simultaneamente em diferentes recursos e precisamos de uma árvore de commit para mostrar o que está acontecendo em nosso repositório.

Árvore de commit

Vamos começar do mesmo ponto de partida. Aqui está o repositório com dois commits:

Mas agora, dois desenvolvedores estão trabalhando ao mesmo tempo e para não interferir um no outro, eles trabalham em branches separados:

Depois de um tempo, eles precisam unir as alterações feitas e para isso eles criam uma solicitação de mesclagem (merge) (também chamada de pull request) - que é exatamente o que parece - é uma solicitação para unir dois estados diferentes do repositório (no nosso caso, queremos mesclar o develop branch no master branch) em um novo estado. Depois de ser devidamente revisado e aprovado, nosso repositório fica assim:

E o desenvolvimento continua:

Resumo - Git Básico

Conceitos principais:

  • Git é um sistema de controle de versão distribuído não linear.
  • Repositório armazena dados e metainformações sobre os dados.
  • Commit é um estado fixo do repositório.
  • Branch é uma referência para um commit. 
  • Solicitação de mesclagem (também chamada de pull request) - é uma solicitação para unir dois estados diferentes do repositório em um novo estado.

Se você quiser ler mais sobre o Git, existem livros disponíveis.

Fluxos Git

Agora que o leitor está familiarizado com os termos e conceitos básicos do Git, vamos falar sobre como a parte do desenvolvimento do ciclo de vida do software pode ser gerenciada usando o Git.  Existem várias práticas (chamadas  de fluxos) que descrevem o processo de desenvolvimento usando Git, mas vamos falar sobre duas delas:

  • Fluxo do GitHub
  • Fluxo do GitLab

Fluxo do GitHub

O fluxo do GitHub é tão fácil quanto parece. Aqui está:

  1. Crie um branch (ramificação) do repositório.
  2. Commit suas alterações para seu novo branch
  3. Envie um pull request do seu branch com as alterações propostas para iniciar uma discussão.
  4. Commit mais alterações em seu branch conforme necessário. Seu pull request será atualizado automaticamente.
  5. Mescle o pull request assim que o branch estiver pronto para ser mesclado.

E existem várias regras que devemos seguir:

  • master branch é sempre implantável (e funcionando!)

  • Não há desenvolvimento indo diretamente para o master branch

  • O desenvolvimento está acontecendo nos branches de recursos

  • master == ambiente** de produção*

  • Você precisa implantar na produção o mais rápido possível

    • Não confunda com "Produções Ensemble", aqui "Produção" significa SISTEMA EM PRODUÇÃO.

** Ambiente é um local configurado onde seu código é executado - pode ser um servidor, uma VM, até mesmo um contêiner.

Veja como funciona:

Você pode ler mais sobre o fluxo do GitHub aqui. Também há um guia ilustrado.

O fluxo do GitHub é bom para pequenos projetos e para testes se você está começando com os fluxos do Git. No entanto, o GitHub o usa, portanto, também pode ser viável em projetos grandes.

Fluxo do GitLab

Se você não estiver pronto para implantar na produção imediatamente, o fluxo do GitLab oferece um fluxo do GitHub + ambientes. É assim que funciona - você desenvolve em branches de recursos, como acima, mescla (merge) no master, como acima, mas aqui está uma diferença: o master é igual apenas no ambiente de teste. Além disso, você tem "Branches de ambiente" que estão vinculados a vários outros ambientes que você possa ter.

Normalmente, existem três ambientes (você pode criar mais se precisar):

  • Ambiente de teste == master branch
  • Ambiente de pré-produção == preprod branch
  • Ambiente de produção == prod branch

O código que chega em um dos branches do ambiente deve ser movido para o ambiente correspondente imediatamente, isso pode ser feito:

  • Automaticamente (cobriremos isso nas partes 2 e 3)
  • Parcialmente automático (igual ao automaticamente, exceto que um botão que autoriza a implantação deve ser pressionado)
  • Manualmente

Todo o processo é assim:

  1. O recurso é desenvolvido no branch de recursos.
  2. O branch de recurso é revisado e mesclado no master branch.
  3. Depois de um tempo (vários recursos mesclados), o master é mesclado com o preprod
  4. Depois de um tempo (teste do usuário, etc.), o preprod é mesclado com o prod  
  5. Enquanto estávamos mesclando e testando, vários novos recursos foram desenvolvidos e mesclados no master, então vá para parte 3.

Veja como funciona:

Você pode ler mais sobre o fluxo do GitLab aqui.

Conclusão

  • Git ****é um sistema de controle de versão distribuído não linear.
  • O fluxo Git pode ser usado como uma diretriz para o ciclo de desenvolvimento de software; existem vários que você pode escolher.

Links

Questões para discussão

  • Você usa um fluxo git? Qual?
  • Quantos ambientes você tem para um projeto padrão?

O que vem a seguir

Na próxima parte, iremos:

  • Instalar o GitLab.
  • Falar sobre alguns ajustes recomendados.
  • Discutir o fluxo de trabalho do GitLab (não deve ser confundido com o fluxo do GitLab).

Fique ligado.

0
0 311
Artigo Mikhail Khomenko · Nov. 19, 2021 15m read

Da última vez, lançamos uma aplicação IRIS no Google Cloud usando seu serviço GKE.

E, embora criar um cluster manualmente (ou por meio do gcloud) seja fácil, a abordagem de Infraestrutura como Código (IaC) moderna recomenda que a descrição do cluster Kubernetes também seja armazenada no repositório como código. Como escrever este código é determinado pela ferramenta que é usada para IaC.

No caso do Google Cloud, existem várias opções, entre elas o Deployment Manager e o Terraform. As opiniões estão divididas quanto o que é melhor: se você quiser saber mais, leia este tópico no Reddit Opiniões sobre Terraform vs. Deployment Manager? e o artigo no Medium Comparando o GCP Deployment Manager e o Terraform

Para este artigo, escolheremos o Terraform, já que ele está menos vinculado a um fornecedor específico e você pode usar seu IaC com diferentes provedores em nuvem.

Suporemos que você leu o artigo anterior e já tem uma conta do Google, e que criou um projeto chamado “Desenvolvimento”, como no artigo anterior. Neste artigo, seu ID é mostrado como . Nos exemplos abaixo, altere-o para o ID de seu próprio projeto

Lembre-se de que o Google não é gratuito, embora tenha um nível gratuito. Certifique-se de controlar suas despesas.

Também presumiremos que você já bifurcou o repositório original. Chamaremos essa bifurcação (fork) de “my-objectscript-rest-docker-template” e nos referiremos ao seu diretório raiz como"" ao longo deste artigo.

Todos os exemplos de código são armazenados neste repositório para simplificar a cópia e a colagem.

O diagrama a seguir descreve todo o processo de implantação em uma imagem:

Então, vamos instalar a versão mais recente do Terraform no momento desta postagem:

$ terraform version
Terraform v0.12.17

A versão é importante aqui, pois muitos exemplos na Internet usam versões anteriores, e a 0.12 trouxe muitas mudanças.

Queremos que o Terraform execute certas ações (use certas APIs) em nossa conta do GCP. Para ativar isso, crie uma conta de serviço com o nome 'terraform' e ative a API do Kubernetes Engine. Não se preocupe sobre como vamos conseguir isso — basta continuar lendo e suas perguntas serão respondidas.

Vamos tentar um exemplo com o utilitário gcloud, embora também possamos usar o console web.

Usaremos alguns comandos diferentes nos exemplos a seguir. Consulte os tópicos da documentação a seguir para obter mais detalhes sobre esses comandos e recursos.

  • Como criar contas de serviço IAM no gcloud
  • Como atribuir papéis a uma conta de serviço para recursos específicos
  • Como criar chaves de conta de serviço IAM no gcloud
  • Como ativar uma API no projeto do Google Cloud
  • Agora vamos analisar o exemplo.

    $ gcloud init

    Como trabalhamos com o gcloud no artigo anterior, não discutiremos todos os detalhes de configuração aqui. Para este exemplo, execute os seguintes comandos:

    $ cd
    $ mkdir terraform; cd terraform
    $ gcloud iam service-accounts create terraform --description "Terraform" --display-name "terraform"

    Agora, vamos adicionar alguns papéis à conta de serviço do terraform além de “Administrador do Kubernetes Engine” (container.admin). Essas funções serão úteis para nós no futuro.

    $ gcloud projects add-iam-policy-binding \
      --member serviceAccount:terraform@.iam.gserviceaccount.com \
      --role roles/container.admin

    $ gcloud projects add-iam-policy-binding \
      --member serviceAccount:terraform@.iam.gserviceaccount.com \
      --role roles/iam.serviceAccountUser

    $ gcloud projects add-iam-policy-binding \
      --member serviceAccount:terraform@.iam.gserviceaccount.com \
      --role roles/compute.viewer

    $ gcloud projects add-iam-policy-binding \
      --member serviceAccount:terraform@.iam.gserviceaccount.com \
      --role roles/storage.admin

    $ gcloud iam service-accounts keys create account.json \
    --iam-account terraform@.iam.gserviceaccount.com

    Observe que a última entrada cria o seu arquivo account.json. Certifique-se de manter este arquivo em segredo.

    $ gcloud projects list
    $ gcloud config set project
    $ gcloud services list --available | grep 'Kubernetes Engine'
    $ gcloud services enable container.googleapis.com
    $ gcloud services list --enabled | grep 'Kubernetes Engine'
    container.googleapis.com Kubernetes Engine API

     

    A seguir, vamos descrever o cluster GKE na linguagem HCL do Terraform. Observe que usamos vários placeholders aqui; substitua-os por seus valores:

    <td>
      Significado
    </td>
    
    <td>
      Exemplo
    </td>
    
    <td>
        ID do projeto do GCP
    </td>
    
    <td>
        possible-symbol-254507
    </td>
    
    <td>
       Armazenamento para estado/bloqueio do Terraform - deve ser único
    </td>
    
    <td>
        circleci-gke-terraform-demo
    </td>
    
    <td>
        Região onde os recursos serão criados
    </td>
    
    <td>
        europe-west1
    </td>
    
    <td>
        Zona onde os recursos serão criados
    </td>
    
    <td>
        europe-west1-b
    </td>
    
    <td>
        Nome do cluster GKE
    </td>
    
    <td>
        dev-cluster
    </td>
    
    <td>
        Nome do pool de nós de trabalho do GKE
    </td>
    
    <td>
        dev-cluster-node-pool
    </td>
    
    Placeholder
      
     
     
     
     

     

    Aqui está a configuração HCL para o cluster na prática:

    $ cat main.tf
    terraform {
      required_version = "~> 0.12"
      backend "gcs" {
        bucket = ""
        prefix = "terraform/state"
        credentials = "account.json"
      }
    }

    provider "google" {
      credentials = file("account.json")
      project = ""
      region = ""
    }

    resource "google_container_cluster" "gke-cluster" {
      name = ""
      location = ""
      remove_default_node_pool = true
      # No cluster regional (localização é região, não zona) 
      # este é um número de nós por zona 
      initial_node_count = 1
    }

    resource "google_container_node_pool" "preemptible_node_pool" {
      name = ""
      location = ""
      cluster = google_container_cluster.gke-cluster.name
      # No cluster regional (localização é região, não zona) 
      # este é um número de nós por zona
      node_count = 1

      node_config {
        preemptible = true
        machine_type = "n1-standard-1"
        oauth_scopes = [
          "storage-ro",
          "logging-write",
          "monitoring"
        ]
      }
    }

    Para garantir que o código HCL esteja no formato adequado, o Terraform fornece um comando de formatação útil que você pode usar:

    $ terraform fmt

    O fragmento de código (snippet) mostrado acima indica que os recursos criados serão fornecidos pelo Google e os próprios recursos são google_container_cluster e google_container_node_pool, que designamos como preemptivos para economia de custos. Também optamos por criar nosso próprio pool em vez de usar o padrão.

    Vamos nos concentrar brevemente na seguinte configuração:

    terraform {
      required_version = "~> 0.12"
      backend "gcs" {
        Bucket = ""
        Prefix = "terraform/state"
        credentials = "account.json"
      }
    }

    O Terraform grava tudo o que é feito no arquivo de status e usa esse arquivo para outro trabalho. Para um compartilhamento conveniente, é melhor armazenar este arquivo em algum lugar remoto. Um lugar típico é umGoogle Bucket.

    Vamos criar este bucket. Use o nome do seu bucket em vez do placeholder . Antes da criação do bucket, vamos verificar se está disponível, pois deve ser único em todo o GCP:

    $ gsutil acl get gs://

    Boa resposta:

    BucketNotFoundException: 404 gs:// bucket does not exist

    A resposta ocupado "Busy" significa que você deve escolher outro nome:

    AccessDeniedException: 403 does not have storage.buckets.get access to

    Também vamos habilitar o controle de versão, como o Terraform recomenda.

    $ gsutil mb -l EU gs://

    $ gsutil versioning get gs://
    gs://: Suspended

    $ gsutil versioning set on gs://

    $ gsutil versioning get gs://
    gs://: Enabled

    O Terraform é modular e precisa adicionar um plugin de provedor do Google para criar algo no GCP. Usamos o seguinte comando para fazer isso:

    $ terraform init

    Vejamos o que o Terraform fará para criar um cluster do GKE:

    $ terraform plan -out dev-cluster.plan

    A saída do comando inclui detalhes do plano. Se você não tem objeções, vamos implementar este plano:

    $ terraform apply dev-cluster.plan

    A propósito, para excluir os recursos criados pelo Terraform, execute este comando a partir do diretório /terraform/:

    $ terraform destroy -auto-approve

    Vamos deixar o cluster como está por um tempo e seguir em frente. Mas primeiro observe que não queremos colocar tudo no repositório, então vamos adicionar vários arquivos às exceções:

    $ cat /.gitignore
    .DS_Store
    terraform/.terraform/
    terraform/*.plan
    terraform/*.json

    Usando Helm

    No artigo anterior, armazenamos os manifestos do Kubernetes como arquivos YAML no diretório /k8s/, que enviamos ao cluster usando o comando "kubectl apply". 

    Desta vez, tentaremos uma abordagem diferente: usando o gerenciador de pacotes Helm do Kubernetes, que foi atualizado recentemente para a versão 3. Use a versão 3 ou posterior porque a versão 2 tinha problemas de segurança do lado do Kubernetes (veja Executando o Helm na produção: melhores práticas de Segurança para mais detalhes). Primeiro, empacotaremos os manifestos Kubernetes de nosso diretório k8s/ em um pacote Helm, que é conhecido como chart. Um chart Helm instalado no Kubernetes é chamado de release. Em uma configuração mínima, um chart consistirá em vários arquivos:

    $ mkdir /helm; cd /helm
    $ tree /helm/
    helm/
    ├── Chart.yaml
    ├── templates
    │   ├── deployment.yaml
    │   ├── _helpers.tpl
    │   └── service.yaml
    └── values.yaml

    Seu propósito está bem descrito no site oficial. As práticas recomendadas para criar seus próprios charts são descritas no Guia de Melhores Práticas do Chart na documentação do Helm. 

    Esta é a aparência do conteúdo de nossos arquivos:

    $ cat Chart.yaml
    apiVersion: v2
    name: iris-rest
    version: 0.1.0
    appVersion: 1.0.3
    description: Helm for ObjectScript-REST-Docker-template application
    sources:
    - https://github.com/intersystems-community/objectscript-rest-docker-template
    - https://github.com/intersystems-community/gke-terraform-circleci-objectscript-rest-docker-template
    $ cat templates/deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: {{ template "iris-rest.name" . }}
      labels:
        app: {{ template "iris-rest.name" . }}
        chart: {{ template "iris-rest.chart" . }}
        release: {{ .Release.Name }}
        heritage: {{ .Release.Service }}
    spec:
      replicas: {{ .Values.replicaCount }}
      strategy:
        {{- .Values.strategy | nindent 4 }}
      selector:
        matchLabels:
          app: {{ template "iris-rest.name" . }}
          release: {{ .Release.Name }}
      template:
        metadata:
          labels:
            app: {{ template "iris-rest.name" . }}
            release: {{ .Release.Name }}
        spec:
          containers:
          - image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
            name: {{ template "iris-rest.name" . }}
            ports:
            - containerPort: {{ .Values.webPort.value }}
              name: {{ .Values.webPort.name }}
    $ cat templates/service.yaml
    {{- if .Values.service.enabled }}
    apiVersion: v1
    kind: Service
    metadata:
      name: {{ .Values.service.name }}
      labels:
        app: {{ template "iris-rest.name" . }}
        chart: {{ template "iris-rest.chart" . }}
        release: {{ .Release.Name }}
        heritage: {{ .Release.Service }}
    spec:
      selector:
        app: {{ template "iris-rest.name" . }}
        release: {{ .Release.Name }}
      ports:
      {{- range $key, $value := .Values.service.ports }}
        - name: {{ $key }}
    {{ toYaml $value | indent 6 }}
      {{- end }}
      type: {{ .Values.service.type }}
      {{- if ne .Values.service.loadBalancerIP "" }}
      loadBalancerIP: {{ .Values.service.loadBalancerIP }}
      {{- end }}
    {{- end }}
    $ cat templates/_helpers.tpl
    {{/* vim: set filetype=mustache: */}}
    {{/*
    Expande o nome do chart.
    */}}

    {{- define "iris-rest.name" -}}
    {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
    {{- end -}}

    {{/*
    Cria o nome e a versão do chart conforme usado pelo rótulo do chart.
    */}}
    {{- define "iris-rest.chart" -}}
    {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
    {{- end -}}

    $ cat values.yaml
    namespaceOverride: iris-rest

    replicaCount: 1

    strategy: |
      type: Recreate

    image:
      repository: eu.gcr.io/iris-rest
      tag: v1

    webPort:
      name: web
      value: 52773

    service:
      enabled: true
      name: iris-rest
      type: LoadBalancer
      loadBalancerIP: ""
      ports:
        web:
          port: 52773
          targetPort: 52773
          protocol: TCP

    Para criar os charts do Helm, instaleo cliente Helm e o utilitário de linha de comando kubectl.

    $ helm version
    version.BuildInfo{Version:"v3.0.1", GitCommit:"7c22ef9ce89e0ebeb7125ba2ebf7d421f3e82ffa", GitTreeState:"clean", GoVersion:"go1.13.4"}

    Crie um namespace chamado iris. Seria bom se isso fosse criado durante a implantação, mas até agora não é o caso.

    Primeiro, adicione credenciais para o cluster criado pelo Terraform ao kube-config:

    $ gcloud container clusters get-credentials --zone --project
    $ kubectl create ns iris

     

    Confirme (sem iniciar uma implantação real) se o Helm criará o seguinte no Kubernetes:

    $ cd /helm
    $ helm upgrade iris-rest \
      --install \
      . \
      --namespace iris \
      --debug \
      --dry-run

    A saída — os manifestos do Kubernetes — foi omitida por causa do espaço aqui. Se tudo estiver certo, vamos implantar:

    $ helm upgrade iris-rest --install . --namespace iris
    $ helm list -n iris --all
    Iris-rest  iris  1  2019-12-14 15:24:19.292227564  +0200  EET  deployed    iris-rest-0.1.0  1.0.3

    Vemos que o Helm implantou nossa aplicação, mas como ainda não criamos a imagem Docker eu.gcr.io/iris-rest:v1, o Kubernetes não pode extraí-la (ImagePullBackOff):

    $ kubectl -n iris get po
    NAME                                           READY  STATUS                       RESTARTS  AGE
    iris-rest-59b748c577-6cnrt 0/1         ImagePullBackOff  0                    10m

    Vamos terminar com isso por agora:

    $ helm delete iris-rest -n iris

    O Lado do CircleCI

    Agora que experimentamos o Terraform e o cliente Helm, vamos colocá-los em uso durante o processo de implantação no lado do CircleCI.

    $ cat /.circleci/config.yml
    version: 2.1

    orbs:
      gcp-gcr: circleci/gcp-gcr@0.6.1

    jobs:
      terraform:
        docker:
        # A versão da imagem do Terraform deve ser a mesma de quando
        # você executa o terraform antes da máquina local
          - image: hashicorp/terraform:0.12.17
        steps:
          - checkout
          - run:
              name: Create Service Account key file from environment variable
              working_directory: terraform
              command: echo ${TF_SERVICE_ACCOUNT_KEY} > account.json
          - run:
              name: Show Terraform version
              command: terraform version
          - run:
              name: Download required Terraform plugins
              working_directory: terraform
              command: terraform init
          - run:
              name: Validate Terraform configuration
              working_directory: terraform
              command: terraform validate
          - run:
              name: Create Terraform plan
              working_directory: terraform
              command: terraform plan -out /tmp/tf.plan
          - run:
              name: Run Terraform plan
              working_directory: terraform
              command: terraform apply /tmp/tf.plan
      k8s_deploy:
        docker:
          - image: kiwigrid/gcloud-kubectl-helm:3.0.1-272.0.0-218
        steps:
          - checkout
          - run:
              name: Authorize gcloud on GKE
              working_directory: helm
              command: |
                echo ${GCLOUD_SERVICE_KEY} > gcloud-service-key.json
                gcloud auth activate-service-account --key-file=gcloud-service-key.json
                gcloud container clusters get-credentials ${GKE_CLUSTER_NAME} --zone ${GOOGLE_COMPUTE_ZONE} --project ${GOOGLE_PROJECT_ID}
          - run:
              name: Wait a little until k8s worker nodes up
              command: sleep 30 # It’s a place for improvement
          - run:
              name: Create IRIS namespace if it doesn't exist
              command: kubectl get ns iris || kubectl create ns iris
          - run:
              name: Run Helm release deployment
              working_directory: helm
              command: |
                helm upgrade iris-rest \
                  --install \
                  . \
                  --namespace iris \
                  --wait \
                  --timeout 300s \
                  --atomic \
                  --set image.repository=eu.gcr.io/${GOOGLE_PROJECT_ID}/iris-rest \
                  --set image.tag=${CIRCLE_SHA1}
          - run:
              name: Check Helm release status
              command: helm list --all-namespaces --all
          - run:
              name: Check Kubernetes resources status
              command: |
                kubectl -n iris get pods
                echo
                kubectl -n iris get services
    workflows:
      main:
        jobs:
          - terraform
          - gcp-gcr/build-and-push-image:
              dockerfile: Dockerfile
              gcloud-service-key: GCLOUD_SERVICE_KEY
              google-compute-zone: GOOGLE_COMPUTE_ZONE
              google-project-id: GOOGLE_PROJECT_ID
              registry-url: eu.gcr.io
              image: iris-rest
              path: .
              tag: ${CIRCLE_SHA1}
          - k8s_deploy:
              requires:
                - terraform
                - gcp-gcr/build-and-push-image

    Você precisará adicionar várias variáveis de ambiente ao seu projeto no lado do CircleCI:

    O GCLOUD_SERVICE_KEY é a chave da conta de serviço CircleCI e o TF_SERVICE_ACCOUNT_KEY é a chave da conta de serviço Terraform. Lembre-se de que a chave da conta de serviço é todo o conteúdo do arquivo account.json.

    A seguir, vamos enviar nossas alterações para um repositório:

    $ cd
    $ git add .circleci/ helm/ terraform/ .gitignore
    $ git commit -m "Add Terraform and Helm"
    $ git push

    O painel da IU do CircleCI deve mostrar que tudo está bem:

    Terraform é uma ferramenta idempotente e se o cluster GKE estiver presente, o trabalho "terraform" não fará nada. Se o cluster não existir, ele será criado antes da implantação do Kubernetes.
    Por fim, vamos verificar a disponibilidade de IRIS:

    $ gcloud container clusters get-credentials --zone --project

    $ kubectl -n iris get svc
    NAME        TYPE                     CLUSTER-IP     EXTERNAL-IP   PORT(S)                     AGE
    Iris-rest    LoadBalancer  10.23.249.42    34.76.130.11    52773:31603/TCP   53s

    $ curl -XPOST -H "Content-Type: application/json" -u _system:SYS 34.76.130.11:52773/person/ -d '{"Name":"John Dou"}'

    $ curl -XGET -u _system:SYS 34.76.130.11:52773/person/all
    [{"Name":"John Dou"},]

    Conclusão

    Terraform e Helm são ferramentas DevOps padrão e devem ser perfeitamente integrados à implantação do IRIS.

    Eles exigem algum aprendizado, mas depois de alguma prática, eles podem realmente economizar seu tempo e esforço.

    0
    0 200
    Artigo Vinicius Maranhao Ribeiro de Castro · Jul. 6, 2021 11m read

    Introdução

    Suponha que você desenvolveu uma nova aplicação utilizando a parte de Interoperabilidade do InterSystems IRIS e você tem certeza de que será um sucesso! No entanto, você ainda não tem um número concreto de quantas pessoas irão utilizá-la. Além disso, pode haver dias específicos em que há mais pessoas utilizando sua aplicação e dias em que quase ninguém irá acessar. Deste modo, você necessita de que sua aplicação seja escalável!

    0
    0 139
    InterSystems Oficial Steven LeBlanc · Maio 20, 2021

    Estou muito grato em anunciar o lançamento do InterSystems Container Registry. Este lançamento disponibiliza um novo canal de distribuição para que clientes possam acessar lançamentos é prévias de lançamentos baseadas em contêineres. Todas as imagens Community Edition estão disponíveis em um repositório público sem necessidade de login. Todas as imagens de produto completos (IRIS, IRIS for Health, Health Connect, System Alerting and Monitoring, InterSystems Cloud Manager) e imagens utilitárias (como o árbitro, Web Gateway e PasswordHash) necessitam de token de login, gerado a partir das credenciais de sua conta do WRC.

    0
    0 91
    Artigo Vinicius Maranhao Ribeiro de Castro · Maio 11, 2021 7m read

    Introdução

    Suponha que você desenvolveu uma nova aplicação utilizando a parte de Interoperabilidade do InterSystems IRIS e você tem certeza de que será um sucesso! No entanto, você ainda não tem um número concreto de quantas pessoas irão utilizá-la. Além disso, pode haver dias específicos em que há mais pessoas utilizando sua aplicação e dias em que quase ninguém irá acessar. Deste modo, você necessita de que sua aplicação seja escalável!

    0
    2 139
    Artigo Vinicius Maranhao Ribeiro de Castro · Mar. 9, 2021 12m read

    Introdução

    Com a transformação digital no mundo dos negócios, novos recursos ou funcionalidades nos softwares oferecidos por uma empresa, podem significar vantagem competitiva. No entanto, se o time de TI não estiver preparado com a cultura, metodologia, práticas e ferramentas corretas, pode ser muito difícil garantir a entrega dessas novas funcionalidades a tempo hábil.

    0
    0 859
    Artigo Mark Bolinsky · Dez. 14, 2020 37m read

    O Google Cloud Platform (GCP) fornece um ambiente rico em recursos para Infraestrutura como um Serviço (IaaS) como uma oferta em nuvem totalmente capaz de oferecer suporte a todos os produtos da InterSystems, incluindo a mais recente plataforma de dados InterSystems IRIS . Deve-se ter cuidado, como com qualquer plataforma ou modelo de implantação, para garantir que todos os aspectos de um ambiente sejam considerados, como desempenho, disponibilidade, operações e procedimentos de gerenciamento.  As especificidades de cada uma dessas áreas serão abordadas neste artigo.

    A visão geral e os detalhes abaixo são fornecidos pelo Google e estão disponíveis aqui.

    Visão geral

    Recursos do GCP

    O GCP é composto por um conjunto de ativos físicos, como computadores e unidades de disco rígido, e também recursos virtuais, como máquinas virtuais (VMs), nos centros de dados do Google em todo o mundo. Cada centro de dados está em uma região do mundo. Cada região é uma coleção de zonas, isoladas de cada uma dentro da região. Cada zona é identificada por um nome que combina uma letra identificadora com o nome da região.

    Essa distribuição de recursos tem várias vantagens, incluindo redundância em caso de falha e latência reduzida colocando recursos mais perto dos clientes. Essa distribuição também tem algumas regras quanto a como os recursos podem ser usados conjuntamente.

    Acesso aos recursos do GCP

    Na computação em nuvem, o hardware físico e o software se tornam serviços. Esses serviços oferecem acesso aos recursos adjacentes. Ao implantar sua aplicação baseada em InterSytems IRIS no GCP, você combina esses serviços para obter a infraestrutura necessária e depois adiciona seu código para possibilitar a concretização dos cenários que deseja criar.  Os detalhes dos recursos disponíveis estão disponíveis aqui.

    Projetos

    Todos os recursos do GCP que você aloca e usa devem pertencer a um projeto. Um projeto é composto por configurações, permissões e outros metadados que descrevem suas aplicações. Os recursos em um único projeto podem funcionar juntos facilmente, por exemplo, comunicando-se por uma rede interna, sujeita a regras das regiões e zonas. Os recursos que cada projeto contêm permanecem separados por fronteiras de projetos. Você só pode interconectá-los por uma conexão de rede externa.

    Interação com os serviços

    O GCP oferece três formas básicas de interagir com os serviços e recursos.

    Console

    O Google Cloud Platform Console possui uma interface gráfica web do usuário que você pode usar para gerenciar os projetos e recursos do GCP. No GCP Console, você pode criar um novo projeto ou escolher um existente, e usar os recursos criados no contexto desse projeto. É possível criar diversos projetos, então você pode usá-los para segregar o trabalho da melhor maneira de acordo com suas necessidades. Por exemplo, você pode iniciar um novo projeto se quiser garantir que somente determinados membros da equipe consigam acessar recursos nesse projeto, enquanto todos os membros da equipe podem continuar acessando os recursos em outro projeto.

    Interface de linha de comandos

    Se você preferir trabalhar em uma janela de terminal, o Google Cloud SDK oferece a ferramenta de linha de comandos gcloud, que permite acesso aos comandos de que você precisa. A ferramenta gcloud pode ser usada para gerenciar o fluxo de trabalho de desenvolvimento e os recursos do GCP. Os detalhes de referências sobre o gcloud estão disponíveis aqui.

    O GCP também oferece o Cloud Shell, um ambiente de shell interativo no navegador para o GCP. Você pode acessar o Cloud Shell pelo GCP Console. O Cloud Shell oferece:

  • Uma instância temporária de máquina virtual de mecanismo de computação.
  • Acesso de linha de comando à instância por um navegador.
  • Um editor de código integrado.
  • 5 GB de armazenamento em disco persistente.
  • Google Cloud SDK e outras ferramentas pré-instalados.
  • Suporte às linguagens Java, Go, Python, Node.js, PHP, Ruby e .NET.
  • Funcionalidade de visualização da web.
  • Autorização integrada para acesso aos projetos e recursos no GCP Console.
  • Bibliotecas de cliente

    O Cloud SDK inclui bibliotecas de cliente que permitem criar e gerenciar recursos com facilidade. As bibliotecas de cliente expõem APIs para dois propósitos principais:

    • As APIs de aplicações concedem acesso aos serviços. As APIs de aplicações são otimizadas para as linguagens compatíveis, como Node.js e Python. As bibliotecas foram desenvolvidas com metáforas de serviço, então você pode usar os serviços de modo mais natural e escrever menos código boilerplate. As bibliotecas também oferecem elementos auxiliares para autenticação e autorização.  Os detalhes estão disponíveis aqui.
    • As APIs de administração oferecem funcionalidades de gerenciamento de recursos. Por exemplo, você pode usar as APIs de administração se quiser criar suas próprias ferramentas automatizadas.

    Também é possível usar as bibliotecas de cliente da API do Google para acessar APIs de produtos, como Google Maps, Google Drive e YouTube.  Os detalhes das bibliotecas de cliente do GCP estão disponíveis aqui.

    Exemplos de arquitetura da InterSystems IRIS

    Neste artigo, são fornecidos exemplos de implantações da InterSystems IRIS para GCP como ponto de partida para a implantação específica de sua aplicação.  Eles podem ser usados como diretrizes para diversas possibilidades de implantação.  Esta arquitetura de referência demonstra opções de implantação muito robustas, começando com implantações de pequeno porte até cargas de trabalho extremamente escaláveis para os requisitos de computação e dados. 

    Também são abordadas neste documento opções de alta disponibilidade e recuperação de desastres, junto com outras operações de sistema recomendadas.  Espera-se que elas sejam modificadas pelos técnicos para se adequarem às práticas e políticas de segurança padrão da organização.

    A InterSystems está disponível para conversar ou responder a perguntas sobre as implantações da InterSystems IRIS com GCP para sua aplicação específica.


    Exemplos de arquitetura de referência

    Os seguintes exemplos de arquitetura apresentam diversas configurações diferentes, com capacidade e funcionalidades cada vez maiores.  Considere estes exemplos de implantação de pequeno porte / produção / produção de grande porte / produção com cluster fragmentado que mostram a progressão desde uma configuração pequena modesta para desenvolvimento até soluções extremamente escaláveis com alta disponibilidade entre zonas e recuperação de desastres multirregião.  Além disso, é fornecido um exemplo de arquitetura usando as novas funcionalidades de fragmentação da InterSystems IRIS Data Plataform para cargas de trabalho híbridas com processamento de consulta SQL altamente paralelizado.

     

    Configuração de implantação de pequeno porte

    Neste exemplo, é usada uma configuração mínima para ilustrar um ambiente de desenvolvimento de pequeno porte que suporta até 10 desenvolvedores e 100 GB de dados.  É fácil dar suporte a mais desenvolvedores e dados: basta alterar o tipo de instância da máquina virtual e aumentar o armazenamento dos discos persistentes conforme necessário.

    Esta configuração é adequada para ambientes de desenvolvimento e para se familiarizar com a funcionalidade da InterSystems IRIS junto com construção de contêineres e orquestração do Docker, se desejar.  Em geral, não se usam alta disponibilidade e espelhamento de bancos de dados em configurações de pequeno porte, mas essas funcionalidades podem ser adicionadas a qualquer momento, se for necessário prover alta disponibilidade. 

    Diagrama do exemplo de configuração de pequeno porte

    O diagrama de exemplo abaixo na Figura 2.1.1-a ilustra a tabela de recursos na Figura 2.1.1-b.  Os gateways incluídos são apenas exemplos e podem ser ajustados para se adequarem às práticas de rede padrão de sua organização. 

    Os seguintes recursos do projeto GCP VPC são provisionados com uma configuração mínima de pequeno porte.  Podem ser adicionados ou removidos recursos do GCP conforme necessário. 

    Recursos do GCP para configuração de pequeno porte

    Um exemplo de recursos do GCP para uma configuração de pequeno porte é fornecido na tabela abaixo.

    É preciso considerar segurança de rede e regras de firewall adequadas para evitar o acesso não autorizado ao VPC.  O Google desenvolveu melhores práticas de segurança de rede para dar os primeiros passos, disponíveis aqui.

    Nota: as instâncias de máquina virtual precisam de um endereço IP público para estabelecerem conexão com os serviços do GCP.  Embora esta prática possa suscitar preocupações, o Google recomenda usar regras de firewall para limitar o tráfego de entrada a essas instâncias de máquina virtual.

    Caso sua política de segurança exija instâncias de máquina virtual verdadeiramente internas, você precisará configurar um proxy NAT manualmente em sua rede e uma rota correspondente para que as instâncias internas consigam estabelecer conexão com a Internet. É importante salientar que não é possível estabelecer conexão a uma instância de máquina virtual verdadeiramente interna diretamente usando-se SSH. Para estabelecer conexão a essas máquinas internas, você precisa configurar uma instância de bastion que tenha um endereço IP externo para usá-la como um túnel. É possível provisionar um host bastion para fornecer um ponto de entrada externo ao seu VPC. 

    Os detalhes dos hosts bastion estão disponíveis aqui.

    Configuração de produção

    Neste exemplo, temos uma configuração de maior porte como exemplo de configuração de produção que incorpora a funcionalidade de espelhamento de bancos de dados da InterSystems IRIS para fornecer alta disponibilidade e recuperação de desastres.

    Está incluído nesta configuração um par de espelhos assíncronos dos servidores de banco de dados da InterSystems IRIS, divididos entre duas zonas dentro da região 1 para failover automático, e um terceiro membro espelho DR assíncrono na região 2 para recuperação de desastres no caso improvável de uma região GCP inteira ficar offline.

    O servidor Arbiter e ICM da InterSystems é implantado em uma terceira zona separada para oferecer maior resiliência.  O exemplo de arquitetura também inclui um conjunto de servidores web com balanceamento de carga opcionais para dar suporte a aplicações web.  Esses servidores web com o InterSystems Gateway podem ser escaláveis de maneira independente, conforme necessário.

    Diagrama do exemplo de configuração de produção

    O diagrama de exemplo abaixo na Figura 2.2.1-a ilustra a tabela de recursos exibida na Figura 2.2.1-b.  Os gateways incluídos são apenas exemplos e podem ser ajustados para se adequarem às práticas de rede padrão de sua organização. 

    Os seguintes recursos do GCP VPC Project são o mínimo recomendado para dar suporte a um cluster fragmentado.  Podem ser adicionados ou removidos recursos do GCP conforme necessário. 

    Recursos do GCP configuração de produção

    Um exemplo de recursos do GCP uma configuração de produção é fornecido nas tabelas abaixo.

    Configuração de produção de grande porte

    Neste exemplo, é fornecida uma configuração extremamente escalável expandindo-se a funcionalidade da InterSystems IRIS para fornecer servidores de aplicação usando-se o Enterprise Cache Protocol (ECP) da InterSystems para oferecer uma enorme escalabilidade horizontal de usuários.  Neste exemplo, é incluído um nível ainda maior de disponibilidade, pois os clientes ECP preservam os detalhes de sessões mesmo caso haja failover da instância do banco de dados.  São usadas diversas zonas GCP, com servidores de aplicação baseados em ECP e membros espelho de bancos de dados implantados em várias regiões.  Esta configuração oferece suporte a dezenas de milhões de acessos ao banco de dados por segundo e a diversos terabytes de dados. 

    Diagrama do exemplo de configuração de produção de grande porte

    O diagrama de exemplo na Figura 2.3.1-a ilustra a tabela de recursos na Figura 2.3.1-b.  Os gateways incluídos são apenas exemplos e podem ser ajustados para se adequarem às práticas de rede padrão de sua organização. 

    Estão incluídos nesta configuração um par de espelhos de failover, quatro ou mais clientes ECP (servidores de aplicação) e um ou mais servidores web por servidor de aplicação. Os pares de espelhos de bancos de dados para failover são divididos entre duas zonas GCP diferentes na mesma região para proteção com domínio de falha, com o servidor Arbiter e ICM da InterSystems implantado em uma terceira zona para oferecer maior resiliência. 

    A recuperação de desastres se estende para uma segunda região e zona(s) GCP similar ao exemplo anterior.  Podem ser usadas diversas regiões de recuperação de desastres com vários membros espelho DR assíncronos, se desejar.

    Os seguintes recursos do GCP VPC Project são o mínimo recomendado para dar suporte a uma implantação em produção de grande escala.  Podem ser adicionados ou removidos recursos do GCP conforme necessário.

    Recursos do GCP para configuração de produção de grande porte

    Um exemplo de recursos do GCP para uma configuração de produção de grande porte é fornecido nas tabelas abaixo.

    Configuração de produção com cluster fragmentado da InterSystems IRIS

    Neste exemplo, é fornecida uma configuração com escalabilidade horizontal para cargas de trabalho híbridas com SQL, incluindo-se os novos recursos de cluster fragmentado da InterSystems IRIS para fornecer uma enorme escalabilidade horizontal de consultas e tabelas SQL entre diversos sistemas.  Os detalhes do cluster fragmentado da InterSystems IRIS e suas funcionalidades são abordados com mais detalhes posteriormente neste artigo.

    Configuração de produção com cluster fragmentado da InterSystems IRIS

    O diagrama de exemplo na Figura 2.4.1-a ilustra a tabela de recursos na Figura 2.4.1-b.  Os gateways incluídos são apenas exemplos e podem ser ajustados para se adequarem às práticas de rede padrão de sua organização. 

    Estão incluídos nesta configuração quatro pares de espelhos como nós de dados.  Cada um dos pares de espelhos de bancos de dados para failover é dividido entre duas zonas GCP diferentes na mesma região para proteção com domínio de falha, com o servidor Arbiter e ICM da InterSystems implantado em uma terceira zona para oferecer maior resiliência. 

    Esta configuração permite que todos os métodos de acesso ao banco de dados fiquem disponíveis a partir de qualquer nó de dados do cluster.  Os dados das tabelas SQL grandes são particionados fisicamente em todos os nós de dados para permitir enorme paralelização de processamento de consultas e volume de dados.  A combinação de todas essas funcionalidades permite o suporte a cargas de trabalho híbridas complexas, como consultas analíticas SQL de grande escala com ingestão simultânea de novos dados, tudo com uma única InterSystems IRIS Data Platform.

    No diagrama acima e na coluna "tipo do recurso" na tabela abaixo, "Compute [Engine] (Computação [Mecanismo])" é um termo do GCP que representa uma instância de servidor GCP (virtual), conforme descrito com mais detalhes na seção 3.1 deste documento. Ele não representa nem sugere o uso de "nós de computação" na arquitetura de cluster descrita posteriormente neste artigo.

    Os seguintes recursos do GCP VPC Project são o mínimo recomendado para dar suporte a um cluster fragmentado.  Podem ser adicionados ou removidos recursos do GCP conforme necessário.

    Recursos do GCP para configuração de produção com cluster fragmentado

    Um exemplo de recursos do GCP para uma configuração de cluster fragmentado é fornecido na tabela abaixo.


    Introdução aos conceitos de nuvem

    O Google Cloud Platform (GCP) fornece um ambiente em nuvem repleto de recursos para infraestrutura como serviço (IaaS) totalmente capaz de dar suporte a todos os produtos da InterSystems, incluindo ao DevOps baseado em contêiner com a nova InterSystems IRIS Data Platform. Deve-se ter cuidado, assim como em qualquer plataforma ou modelo de implantação, para garantir que todos os aspectos de um ambiente sejam considerados, como desempenho, disponibilidade, operações de sistema, alta disponibilidade, recuperação de desastres, controles de segurança e outros procedimentos de gerenciamento.  Este documento aborda os três principais componentes de todas as implantações em nuvem: Computação, Armazenamento e Rede.

    Mecanismos de computação (máquinas virtuais)

    No GCP, há diversas opções disponíveis para recursos de mecanismo de computação, com várias especificações de CPU e memória virtuais e das opções de armazenamento.  Um item importante sobre o GCP: referências ao número de vCPUs em um determinado tipo de máquina é igual a um vCPU em um hyper-thread no host físico na camada do hypervisor. 

    Neste documento, os tipos de instância n1-standard* e n1-highmem* serão usados e estão amplamente disponíveis na maioria das regiões de implantação do GCP.  Porém, o uso dos tipos de instância n1-ultramem* é uma excelente opção para conjuntos de dados muito grandes, pois são mantidas enormes quantidades de dados em cache na memória.  As configurações padrão da instância, como a Política de disponibilidade da instância ou outros recursos avançados, são usadas, salvo indicação em contrário.  Os detalhes dos vários tipos de máquina estão disponíveis aqui.

    Armazenamento em disco

    O tipo de armazenamento relacionado mais diretamente com os produtos da InterSystems são os tipos de disco persistente. Porém, o armazenamento local pode ser usado para altos níveis de desempenho, desde que as restrições de disponibilidade de dados sejam entendidas e atendidas. Existem várias outras opções, como armazenamento em nuvem (buckets). Porém, elas são mais específicas para os requisitos de cada aplicação, em vez de darem suporte à operação da InterSystems IRIS Data Platform. 

    Como vários outros provedores de nuvem, o GCP impõe limites da quantidade de armazenamento persistente que pode ser associado a um mecanismo de computação específico.  Esses limites incluem o tamanho máximo de cada disco, o número de discos persistentes conectados a cada mecanismo de computação e a quantidade de IOPS por disco persistente com um limite geral de IOPS da instância específica do mecanismo de computação.  Além disso, há limites de IOPS impostos por GB de espaço em disco. Então, às vezes é necessário provisionar mais capacidade de disco para alcançar a taxa de IOPS desejada.

    Esses limites podem variar ao longo do tempo e devem ser confirmados com o Google conforme necessário.

    Existem dois tipos de armazenamento persistente para volumes de disco: discos padrão persistentes e discos SSD persistentes.  Os discos SSD persistentes são mais adequados para cargas de trabalho de produção que exigem um IOPS de baixa latência previsível e uma maior taxa de transferência.  Os discos padrão persistentes são uma opção mais acessível para ambientes de desenvolvimento e teste ou para cargas de trabalho de arquivamento. 

    Os detalhes dos vários tipos de disco e limitações estão disponíveis aqui.

    Rede do VPC

    A rede Virtual Private Cloud (VPC) é recomendável para dar suporte aos diversos componentes da InterSystems IRIS Data Platform e também para fornecer controles de segurança de rede adequados, vários gateways, roteamento, atribuições de endereço IP interno, isolamento de interface de rede e controles de acesso.  Um exemplo de VPC será detalhado nos exemplos apresentados neste documento.

    Os detalhes de rede e firewall do VPC estão disponíveis aqui.


    Visão geral do Virtual Private Cloud (VPC) 

    Os VPCs do GCP são um pouco diferentes dos de outros provedores de nuvem e oferecem maior simplicidade e flexibilidade.  Uma comparação dos conceitos está disponível aqui

    São permitidos diversos VPCs por projeto do GCP (atualmente, 5 por projeto, no máximo), e existem duas opções para criar uma rede no VPC: modo automático e modo personalizado. 

    Os detalhes de cada tipo estão disponíveis aqui.

    Na maioria das implantações em nuvem de grande porte, vários VPCs são provisionados para isolar os diversos tipos de gateways dos VPCs para aplicações e para aproveitar o emparelhamento de VPCs para comunicações de entrada e saída. Recomendamos consultar seu administrador de rede para verificar detalhes das subredes permitidas e qualquer regra de firewall de sua organização.  O emparelhamento de VPCs não é abordado neste documento.

    Nos exemplos fornecidos neste documento, um único VPC com três subredes será usado para fornecer isolamento de rede dos vários componentes e para se ter uma latência e largura de banda previsíveis, além de isolamento de segurança dos diversos componentes da InterSystems IRIS. 

    Definições de subrede e gateway de rede

    São fornecidos dois gateways no exemplo deste documento para dar suporte a conectividade via Internet e VPN segura.  Cada acesso de entrada precisa ter regras de firewall e roteamento corretas para fornecer segurança adequada à aplicação.  Os detalhes de como usar rotas estão disponíveis aqui.

    São usadas três subredes nos exemplos de arquitetura fornecidos, exclusivas para uso com a InterSystems IRIS Data Platform.  O uso dessas subredes e interfaces de rede separadas permite maior flexibilidade dos controles de segurança e proteção da largura de banda, além do monitoramento de cada um dos três principais componentes acima.  Os detalhes dos vários casos de uso estão disponíveis aqui.

    Os detalhes da criação de instâncias de máquina virtual com várias interfaces de rede estão disponíveis aqui.

    Subredes incluídas nestes exemplos:

  • Rede do Espaço do Usuáriopara consultas e usuários conectados de entrada
  • Rede Fragmentadapara comunicações interfragmentos entre os nós fragmentados
  • Rede de Espelhamentopara alta disponibilidade usando replicação assíncrona e failover automático de nós de dados individuais. 
  • Nota:: o espelhamento síncrono de bancos de dados para failover só é recomendado entre diversas zonas com interconexões de baixa latência em uma única região GCP.  Geralmente, a latência entre as regiões é alta demais para fornecer uma boa experiência do usuário, principalmente para implantações com altas taxas de atualização.

    Balanceadores de carga internos

    A maioria dos servidores de nuvem IaaS não tem a capacidade de fornecer um endereço IP virtual (VIP), geralmente usado nos projetos com failover automático de bancos de dados. Para tratar esse problema, vários dos métodos de conectividade usados com mais frequência, especificamente clientes ECP e gateways web, são aprimorados na InterSystems IRIS para não depender da funcionalidade de VIP, tornando-os cientes do espelhamento e automáticos. 

    Métodos de conectividade como xDBC, sockets TCP-IP diretos ou outros protocolos de conexão direta exigem o uso de endereços tipo VIP.  Para dar suporte a esses protocolos de entrada, a tecnologia de espelhamento de bancos de dados da InterSystems possibilita o failover automático para esses métodos de conectividade no GCP, usando uma página de status de verificação de integridade chamada <span class="Characteritalic" style="font-style:italic">mirror_status.cxw </span> para interagir com o balanceador de carga para conseguir funcionalidade parecida com a do VIP do balanceador de carga, encaminhando o tráfego somente para o membro espelho primário ativo e, portanto, fornecendo um projeto de alta disponibilidade completo e robusto no GCP. 

    Os detalhes de como usar um balanceador de carga para fornecer funcionalidade parecida com a do VIP estão disponíveis aqui.

    Exemplo de topologia do VPC

    Combinando todos os componentes, a ilustração da Figura 4.3-a abaixo demonstra o layout de um VPC com as seguintes características:

  • Usa várias zonas dentro de uma região para fornecer alta disponibilidade
  • Fornece duas regiões para recuperação de desastres
  • Usa subredes múltiplas para segregação da rede
  • Inclui gateways separados para conectividade via Internet e conectividade via VPN
  • Usa um balanceador de carga em nuvem para failover de IP para membros espelho

  • Visão geral do armazenamento persistente

    Conforme abordado na introdução, recomenda-se o uso dos discos persistentes do GCP, especificamente os tipos de disco SSD persistente.  Recomendam-se os discos SSD persistentes devido a taxas IOPS de leitura e gravação maiores, além da baixa latência necessária para cargas de trabalho de bancos de dados transacionais e analíticos.  Podem ser usadas SSDs locais em determinadas circunstâncias, mas é importante salientar que os ganhos de desempenho das SSDs locais são obtidos ao custo de disponibilidade, durabilidade e flexibilidade. 

    Os detalhes de persistência de dados em SSDs locais estão disponíveis aqui para entender quando os dados de SSDs locais são preservados e quando não são.

    LVM Striping

    Como outros fornecedores de nuvem, o GCP impõe diversos limites no armazenamento, em termos de IOPS, espaço de armazenamento e número de dispositivos por instância de máquina virtual.  Consulte a documentação do GCP para conferir os limites atuais aqui.

    Com esses limites, o LVM stripping se torna necessário para maximizar o IOPS para além de um único dispositivo de disco para uma instância de banco de dados.  No exemplo das instâncias de máquina virtual fornecido, recomendam-se os seguintes layouts de disco.  Os limites de desempenho relativos aos discos de SSD persistentes estão disponíveis aqui.

    Nota: atualmente, há um limite máximo de 16 discos persistentes por instância de máquina virtual, embora o GCP tenha informado que, atualmente, um aumento para 128 está em fase beta, o que será uma melhoria muito bem-vinda.

    Com o LVM stripping, é possível espalhar cargas de trabalho de E/S aleatórias para mais dispositivos de disco e herdar filhas de discos.  Veja abaixo um exemplo de como usar o LVM stripping com o Linux para o grupo de volumes do banco de dados.  Este exemplo usa quatro discos em um LVM PE stripe com uma tamanho de extensão física (PE) de 4 MB.  Também é possível usar tamanhos de PE maiores, se necessário.

    • Passo 1: Criar os discos padrão ou discos SSD persistentes conforme necessário
    • Etapa 2: O agendador de E/S é o NOOP para cada dispositivo de disco, usando-se "lsblk -do NAME,SCHED"
    • Etapa 3: Identificar os dispositivos de disco usando "lsblk -do KNAME,TYPE,SIZE,MODEL"
    • Etapa 4: Criar o grupo de volumes com novos dispositivos de disco
      • vgcreate s 4M  
      • exemplo: vgcreate -s 4M vg_iris_db /dev/sd[h-k]
    • Etapa 4: Criar volume lógico
      • lvcreate n -L -i -I 4MB
      • exemplo: lvcreate -n lv_irisdb01 -L 1000G -i 4 -I 4M vg_iris_db
    • Etapa 5: Criar sistema de arquivo
      • mkfs.xfs K
      • exemplo: mkfs.xfs -K /dev/vg_iris_db/lv_irisdb01
    • Etapa 6: Montar sistema de arquivo
      • edit /etc/fstab com as seguintes entradas de montagem
        • /dev/mapper/vg_iris_db-lv_irisdb01    /vol-iris/db    xfs  defaults 0 0
        • mount /vol-iris/db

    Usando a tabela acima, cada servidor da InterSystems IRIS terá a seguinte configuração com dois discos para SYS (sistema), quatro discos para DB (banco de dados), dois discos para registros de log primários e dois discos para registros de log alternativos.

    Para escalabilidade, o LVM permite a expansão de dispositivos e volumes lógicos quando necessário sem interrupções.  Consulte as melhores práticas de gerenciamento constante e expansão de volumes LVM na documentação do Linux.

    Nota: a ativação de E/S assíncrona para o banco de dados e os arquivos de registros de log de imagem de gravação são altamente recomendáveis.  Consulte os detalhes de ativação no Linux no seguinte artigo da comunidade: https://community.intersystems.com/post/lvm-pe-striping-maximize-hyper-converged-storage-throughput

    Provisionamento

    O InterSystems Cloud Manager (ICM) é uma novidade da InterSystems IRIS.  O ICM realiza muitas tarefas e oferece diversas opções para provisionamento da InterSystems IRIS Data Platform. O ICM é fornecido como uma imagem do Docker que inclui tudo que é necessário para provisionar uma solução em nuvem do GCP robusta.

    Atualmente, o ICM dá suporte ao provisionamento nas seguintes plataformas:

    • Google Cloud Platform (GCP)
    • Amazon Web Services, incluindo GovCloud (AWS / GovCloud)
    • Microsoft Azure Resource Manager, incluindo Government (ARM / MAG)
    • VMware vSphere (ESXi)

    O ICM e o Docker podem ser executados em uma estação de trabalho desktop/notebook ou em um servidor de "provisionamento" simples, exclusivo e centralizado com um repositório centralizado.  

    A função do ICM no ciclo de vida da aplicação é Definir -> Provisionar -> Implantar -> Gerenciar

    Os detalhes de instalação e uso do ICM com o Docker estão disponíveis aqui.

    NOTA: o uso do ICM não é obrigatório para implantações em nuvem.  O método tradicional de instalação e implantação com distribuições tarball é totalmente compatível e disponível.  Porém, o ICM é recomendado para facilidade de provisionamento e gerenciamento em implantações em nuvem.

    Monitoramento de contêiner

    O ICM inclui um recurso de monitoramento básico usando Weave Scope para implantação baseada em contêiner.  Ela não é implantada por padrão e precisa ser especificada no campo Monitor do arquivo de padrões. 

    Os detalhes de monitoramento, orquestração e agendamento com o ICM estão disponíveis aqui.

    Uma visão geral e documentação do Weave Scope estão disponíveis aqui.


    Alta disponibilidade

    O espelhamento de bancos de dados da InterSystems proporciona o mais alto nível de disponibilidade em qualquer ambiente de nuvem.  Existem opções para fornecer alguma resiliência de máquina virtual diretamente no nível da instância.  Os detalhes das diversas políticas disponíveis no GCP estão disponíveis aqui.

    As seções anteriores explicaram como um balanceador de carga em nuvem fornece failover automático de endereço IP para uma funcionalidade de IP Virtual (parecida com VIP) com espelhamento de bancos de dados.  O balanceador de carga em nuvem usa a página de status de verificação de integridade <span class="Characteritalic" style="font-style:italic">mirror_status.cxw</span> mencionada anteriormente na seção Balanceadores de carga internos.  Existem dois modos de espelhamento de bancos de dados: síncrono com failover automático e assíncrono.  Neste exemplo, será abordado o espelhamento com failover síncrono.  Os detalhes do espelhamento estão disponíveis aqui.

    A configuração de espelhamento mais básica é um par de membros espelho de failover em uma configuração controlada pelo Arbiter.  O Arbiter é colocado em uma terceira zona dentro da mesma região para proteção contra possíveis interrupções na zona que impactem tanto o Arbiter quanto um dos membros espelho.

    Existem várias maneiras de configurar o espelhamento na configuração de rede.  Neste exemplo, usaremos as subredes definidas anteriormente na seção Definições de subrede e gateway de rededeste documento.  Serão fornecidos exemplos de esquemas de endereço IP em uma seção abaixo e, para o objetivo desta seção, somente as interfaces de rede e subredes designadas serão representadas.


    Recuperação de desastres

    O espelhamento de bancos de dados da InterSystems estende a funcionalidade de alta disponibilidade para também dar suporte à recuperação de desastres para outra região geográfica do GCP para proporcionar resiliência operacional no caso improvável de uma região GCP inteira ficar offline.  Como uma aplicação conseguirá suportar essas interrupções depende da meta de tempo de recuperação (RTO) e das metas de ponto de recuperação (RPO).  Elas fornecerão a estrutura inicial para a análise necessária para projetar um plano de recuperação de desastres adequado.  Os seguintes links apresentam um guia para os itens que devem ser considerados ao criar um plano de recuperação de desastres para sua aplicação.  https://cloud.google.com/solutions/designing-a-disaster-recovery-plan e https://cloud.google.com/solutions/disaster-recovery-cookbook

    Espelhamento assíncrono de bancos de dados

    O espelhamento de bancos de dados da InterSystems IRIS Data Platform fornece funcionalidades robustas para replicação assíncrona de dados entre zonas e regiões do GCP para ajudar a alcançar os objetivos de RTO e RPO de seu plano de recuperação de desastres.  Os detalhes de membros espelho assíncronos estão disponíveis aqui.

    Similar à seção anterior sobre alta disponibilidade, um balanceador de carga em nuvem fornece failover automático de endereço IP para uma funcionalidade de IP Virtual (parecida com IP virtual) para espelhamento assíncrono para recuperação de desastres também usando a mesma página de status de verificação de integridade <span class="Characteritalic" style="font-style:italic">mirror_status.cxw</span> mencionada anteriormente na seção Balanceadores de carga internos

    Neste exemplo, o espelhamento assíncrono de failover para recuperação de desastres será abordado junto com a introdução do serviço de Balanceamento de carga global do GCP para fornecer a sistemas upstream e estações de trabalho clientes um único endereço IP anycast, independentemente de em qual zona ou região sua implantação da InterSystems IRIS esteja operando. 

    Um dos avanços do GCP é o que o balancedador de carga é um recurso global definido por software e não está vinculado a uma região específica.  Dessa forma, você terá o recurso exclusivo de usar um único serviço entre regiões, já que não é uma instância ou solução baseada em dispositivo. Os detalhes do Balanceamento Global de carga com IP anycast do GCP estão disponíveis aqui.

    No exemplo acima, os endereços IP de todas as três instâncias da InterSystems IRIS recebem um Balanceador de carga global do GCP, e o tráfego será encaminhado somente para o membro espelho que for o espelho primário ativo, independentemente da zona ou região na qual está localizado.


    Cluster fragmentado

    A InterSystems IRIS inclui um amplo conjunto de funcionalidades para permitir escalabilidade de suas aplicações, que podem ser aplicadas de maneira independente ou conjunta, dependendo da natureza de sua carga de trabalho e dos desafios de desempenho específicos enfrentados. Uma dessas funcionalidades, a fragmentação, particiona os dados e o cache associado em diversos servidores, fornecendo escalabilidade flexível, barata e com bom desempenho para consultas e ingestão de dados, ao mesmo tempo em que maximiza o valor da infraestrutura por meio da utilização de recursos extremamente eficiente. Um cluster fragmentado da InterSystems IRIS pode proporcionar vantagens de desempenho significativas para diversas aplicações, mas especialmente para aquelas com cargas de trabalho que incluem um ou mais dos seguintes aspectos:

    • Ingestão de dados de alta velocidade ou alto volume, ou uma combinação das duas.
    • Conjuntos de dados relativamente grandes ou consultas que retornam grandes quantidades de dados, ou ambos.
    • Consultas complexas que realizam grandes quantidades de processamento de dados, como aquelas que buscam muitos dados no disco ou envolvem trabalho computacional significativo.

    Cada um desses fatores tem suas próprias influências no ganho potencial obtido com a fragmentação, mas pode haver mais vantagens quando há uma combinação deles. Por exemplo, uma combinação dos três fatores (grandes quantidades de dados ingeridos rapidamente, grandes conjuntos de dados e consultas complexas que recuperam e processam muitos dados) faz muitas das cargas de trabalho analíticas da atualidade excelentes candidatas para a fragmentação.

    Todas essas características estão relacionadas a dados, e a principal função da fragmentação da InterSystems IRIS é fornecer escalabilidade para grandes volumes de dados. Porém, um cluster fragmentado também pode incluir recursos para escalabilidade de volume de usuários, quando as cargas de trabalho que envolvem alguns ou todos esses fatores relacionados a dados também têm um altíssimo volume de consultas devido à grande quantidade de usuários. A fragmentação também pode ser combinada com escalabilidade vertical.

    Visão geral operacional

    O centro da arquitetura de fragmentação é o particionamento dos dados e do cache associado em vários sistemas. Um cluster fragmentado particiona fisicamente grandes tabelas de bancos de dados horizontalmente (ou seja, por linha) em diversas instâncias da InterSystems IRIS, chamadas denós de dados, enquanto permite às aplicações acessar de maneira transparente essas tabelas por qualquer nó e ainda ver todo o conjunto de dados como uma única união lógica. Essa arquitetura tem as seguintes vantagens:

    • Processamento paraleloas consultas são executadas em paralelo nos nós de dados, e os resultados são unidos, combinados e retornados à aplicação como resultados de consulta completos pelo nó ao qual a aplicação está conectada, aumentando consideravelmente a velocidade de execução em diversos casos.
    • Cache particionado: cada nó de dados tem seu próprio cache, exclusivo para a partição fragmentada dos dados da tabela fragmentada que ele armazena, em vez de um único cache da instância atendendo a todo o conjunto de dados, o que reduz bastante o risco de sobrecarregar o cache e forçar leituras no disco que degradam o desempenho.
    • Carregamento paralelo: os dados podem ser carregados nos nós de dados em paralelo, reduzindo o cache e a contenção de disco entre a carga de trabalho de ingestão e a carga de trabalho de consulta, e aumentando o desempenho de ambas.

    Os detalhes de cluster fragmentado da InterSystems IRIS estão disponíveis aqui.

    Elementos de fragmentação e tipos de instância

    Um cluster fragmentado consiste de pelo menos um nó de dados e, se necessário para requisitos específicos de desempenho ou carga de trabalho, uma quantidade opcional de nós computacionais. Esses dois tipos de nó oferecem blocos de construção simples com um modelo de escalabilidade simples, transparente e eficiente.

    Nós de dados

    Os nós de dados armazenam dados. No nível físico, os dados de tabelas fragmentadas[1] são espalhados em todos os nós de dados do cluster, e os dados de tabelas não fragmentadas são armazenados fisicamente somente no primeiro nó de dados. Essa diferença é transparente para os usuários, com uma única possível exceção: o primeiro nó pode ter um consumo de armazenamento um pouco maior que os outros, mas espera-se que essa diferença seja insignificante, já que os dados de tabelas fragmentadas costumam ser maiores que os dados de tabelas não fragmentadas em pelo menos uma ordem de grandeza.

    Os dados de tabelas fragmentadas podem ser rebalanceados no cluster quando necessário, em geral após adicionar novos nós de dados. Essa ação moverá "buckets" de dados entre os nós para deixar a distribuição de dados aproximadamente igual.

    No nível lógico, os dados de tabelas não fragmentadas e a junção de todos os dados das tabelas fragmentadas são visíveis de qualquer nó, então os clientes verão todo o conjunto de dados, independentemente de a qual nó estão conectados. Os metadados e o código também são compartilhados entre todos os nós de dados.

    O diagrama básico da arquitetura de um cluster fragmentado consiste simplesmente dos nós de dados que parecem uniformes em todo o cluster. As aplicações cliente podem se conectar a qualquer nó e usarão os dados como se eles fossem locais.


    [1] Por conveniência, o termo “dados das tabelas fragmentadas” é usado em todo o documento para representar os dados de “extensão” para qualquer modelo de dados com suporte a fragmentação e que estão marcados como fragmentados. Os termos “dados de tabelas não fragmentadas” e “dados não fragmentados” são usados para representar os dados que estão em uma extensão fragmentável não marcada desta forma ou para um modelo de dados que simplesmente não dá suporte a fragmentação ainda.

    Nós de dados

    Para cenários avançados em que é necessário ter baixas latências, possivelmente com uma chegada constante de dados, podem ser adicionados nós computacionais para fornecer uma camada de cache transparente para responder às consultas.

    Os nós computacionais armazenam dados em cache. Cada nó computacional está associado a um nó de dados, para o qual ele armazena em cache os dados das tabelas fragmentadas correspondentes e, além disso, ele também armazena em cache dados das tabelas não fragmentadas conforme necessário para responder às consultas.

    Como os nós computacionais não armazenam fisicamente dados e têm a função de dar suporte à execução de consultas, o perfil de hardware deles pode ser personalizado de acordo com essas necessidades, por exemplo, adicionando mais memória e CPI e mantendo o armazenamento no mínimo necessário. A ingestão é encaminhada para os nós de dados, seja por um driver (xDBC, Spark) ou implicitamente pelo código de gerenciamento de fragmentação quando o código da aplicação "crua" é executado em um nó computacional.


    Ilustrações do cluster fragmentado

    Existem várias combinações de implantação de um cluster fragmentado.  Os seguintes diagramas de alto nível são fornecidos para ilustrar os modelos de implantação mais comuns.  Esses diagramas não incluem os gateways e detalhes de rede e se concentram somente nos componentes do cluster fragmentado.

    Cluster fragmentado básico

    O diagrama abaixo é o cluster fragmentado mais simples, com quatro nós de dados implantados em uma única região e uma única zona.  Um Balanceador de carga global do GCP é usado para distribuir as conexões de clientes para qualquer um dos nós do cluster fragmentado.

    Neste modelo básico, não é fornecida resiliência ou alta disponibilidade além daquelas oferecidas pelo GCP para uma única máquina virtual e seu armazenamento SSD persistente.  São recomendados dois adaptadores de interface de rede separados para fornecer tanto isolamento de segurança da rede para as conexões de entrada dos clientes quanto isolamento de largura de banda entre o tráfego dos clientes e as comunicações do cluster fragmentado.

    Cluster fragmentado básico com alta disponibilidade

    O diagrama abaixo é o cluster fragmentado mais simples, com quatro nós de dados espelhados implantados em uma única região dividindo o espelho de cada nó entre zonas.  Um Balanceador de carga global do GCP é usado para distribuir as conexões de clientes para qualquer um dos nós do cluster fragmentado. 

    A alta disponibilidade é fornecida pelo uso do espelhamento de bancos de dados da InterSystems, que manterá um espelho replicado de maneira síncrona em uma zona secundária dentro da região.

    São recomendados três adaptadores de interface de rede separados para fornecer isolamento de segurança da rede para as conexões de entrada dos clientes, isolamento de largura de banda entre o tráfego dos clientes e as comunicações do cluster fragmentado, e o tráfego do espelhamento síncrono entre os pares de nó.

    Este modelo de implantação também agrega o Arbiter espelho conforme descrito em uma seção anterior deste documento.

    Cluster fragmentado com nós computacionais separados

    O seguinte diagrama expande o cluster fragmentado para simultaneidade maciça de usuários/consultas com nós computacionais separados e quatro nós de dados.  O pool de servidores de Cloud Load Balancer contém somente os endereços dos nós computacionais.  As atualizações e ingestões de dados continuarão a ser feitas diretamente nos nós de dados como antes para manter desempenho com latência baixíssima e evitar interferência e congestão de recursos entre as cargas de trabalho analíticas/de consultas e a ingestão de dados em tempo real.

    Com este modelo, pode ser feito um ajuste fino da alocação de recursos para escalabilidade de computação/consultas e ingestão de maneira independente, permitindo um uso ideal de recursos quando necessário de forma "just-in-time" e mantendo uma solução simples e econômica, em vez de gastar recursos desnecessariamente só para escalabilidade de computação ou dados. 

    Os nós computacionais fazem um uso bem direto do grupo de escalabilidade automática do GCP (também chamado de Autoscaling) para permitir a inclusão ou exclusão automática de instâncias de um grupo de instâncias gerenciado com base em aumento ou diminuição da carga. A escalabilidade automática funciona pela inclusão de mais instâncias ao grupo quando há mais carga (aumento de escalabilidade) e pela exclusão de instâncias quando são necessárias menos instâncias (diminuição de escalabilidade).

    Os detalhes de escalabilidade automática do GCP estão disponíveis aqui.

    A escalabilidade automática ajuda as aplicações em nuvem a tratar de maneira simples o aumento no tráfego e reduz o custo quando a necessidade de recursos diminui. Basta definir a política de escalabilidade automática, e a ferramenta de escalabilidade automática atua com base na carga mensurada.


    Operações de backup

    Existem várias opções disponíveis para operações de backup.  As três opções a seguir são viáveis para sua implantação do GCP com a InterSystems IRIS.

    As duas primeiras opções detalhas abaixo incorporam um procedimento do tipo instantâneo (snapshot) que envolve a suspensão das gravações do banco de dados no disco antes de criar o snapshot e, em seguida, a retomada das atualizações assim que o snapshot for bem-sucedido.

    As seguintes etapas de alto nível são realizadas para criar um backup limpo usando um dos métodos de snapshot:

    • Pausar gravações no banco de dados por meio da chamada de API de congelamento externo do banco de dados.
    • Criar snapshots dos discos de dados e do sistema operacional.
    • Retomar as gravações do banco de dados por meio da chamada da API de descongelamento externo.
    • Arquivos de instalação de backup para localização de backup

    Os detalhes das APIs de congelamento/descongelamento externos estão disponíveis aqui.

    Nota: não estão incluídos neste documento exemplos de script para backup. Porém, verifique periodicamente os exemplos publicados na InterSystems Developer Community.  www.community.intersystems.com

    A terceira opção é o backup on-line da InterSystems.  Esta é uma opção básica para implantações de pequeno porte com um caso de uso e interface bem simples.  No entanto, à medida que os bancos de dados aumentam de tamanho, os backups externos com tecnologia de snapshot são recomendados como uma melhor prática, com diversas vantagens, incluindo o backup de arquivos externos, tempos de restauração mais rápidos e uma visão corporativa de dados e ferramentas de gerenciamento. 

    Etapas adicionais, como verificações de integridade, podem ser adicionadas em intervalos periódicos para garantir um backup limpo e consistente.

    Os pontos de decisão sobre qual opção usar dependem dos requisitos operacionais e políticas de sua organização.  A InterSystems está disponível para discutir as várias opções com mais detalhes.

    Backup de snapshot de disco persistente do GCP

    As operações de backup podem ser arquivadas usando a API de linha de comando gcloud do GCP junto com os recursos das APIs de congelamento/descongelamento externos da InterSystems. Assim, é possível ter resiliência operacional 24/7 e a garantia de backups limpos regulares.  Os detalhes de gerenciamento, criação e automação de snapshots dos discos persistentes do GCP estão disponíveis aqui.

    Snapshots do Logical Volume Manager (LVM)

    Como alternativa, muitas das ferramentas de backup de terceiros disponíveis no mercado podem ser usadas implementando agentes de backup individuais na própria VM e aproveitando backups em nível de arquivo em conjunto com snapshots do Logical Volume Manager (LVM).

    Um dos principais benefícios desse modelo é ter a capacidade de fazer restaurações em nível de arquivo de VMs Windows ou Linux.  Alguns pontos a serem observados com esta solução são: como o GCP e a maioria dos outros provedores em nuvem IaaS não fornecem mídia de fita, todos os repositórios de backup são baseados em disco para arquivamento de curto prazo e têm a capacidade de aproveitar o armazenamento de baixo custo do tipo blob ou bucket para retenção de longo prazo (LTR).  É altamente recomendável usar este método para usar um produto de backup que suporte tecnologias de eliminação de duplicação e fazer o uso mais eficiente dos repositórios de backup baseados em disco.

    Alguns exemplos desses produtos de backup com suporte à nuvem incluem, mas não se limitam a: Commvault, EMC Networker, HPE Data Protector e Veritas Netbackup. 

    Nota: a InterSystems não valida ou endossa um produto de backup em detrimento do outro.  A responsabilidade de escolher um software de gerenciamento de backup é de cada cliente.

    Backup on-line

    Para implantações de pequeno porte, o recurso de backup on-line integrado também é uma opção viável.  Este utilitário de backup on-line de banco de dados da InterSystems faz backup de dados em arquivos de banco de dados, capturando todos os blocos nos bancos de dados e depois gravando a saída em um arquivo sequencial. Este mecanismo de backup proprietário foi projetado para não causar tempo de inatividade aos usuários do sistema em produção. Os detalhes do backup on-line estão disponíveis aqui.

    No GCP, após a conclusão do backup on-line, o arquivo de saída do backup e todos os outros arquivos em uso pelo sistema devem ser copiados para algum outro local de armazenamento fora da instância da máquina virtual.  O armazenamento de bucket/objeto é uma boa opção.

    Existem duas opções para usar um bucket de armazenamento do GCP. 

    • Usar as APIs de script gcloud diretamente para copiar e manipular os arquivos de backup on-line recém-criados (e outros arquivos não relacionados ao banco de dados).  Os detalhes estão disponíveis aqui.
    • Montar um bucket de armazenamento como um sistema de arquivo e usá-lo de maneira similar a um disco persistente, embora os buckets de armazenamento em nuvem sejam armazenamento de objetos.

    Os detalhes de como montar um bucket de armazenamento em nuvem usando o Cloud Storage FUSE estão disponíveis aqui.

    0
    0 1033
    Artigo Mikhail Khomenko · Nov. 23, 2020 21m read

    Imagine que você queira ver o que a tecnologia InterSystems pode oferecer em termos de análise de dados. Você estudou a teoria e agora quer um pouco de prática. Felizmente, a InterSystems oferece um projeto que contém alguns bons exemplos: Samples BI. Comece com o arquivo README, pulando qualquer coisa associada ao Docker, e vá direto para a instalação passo a passo. Inicie uma instância virtual, instale o IRIS lá, siga as instruções para instalar o Samples BI e, a seguir, impressione o chefe com belos gráficos e tabelas. Por enquanto, tudo bem. 

    Inevitavelmente, porém, você precisará fazer alterações.

    Acontece que manter uma máquina virtual sozinha tem algumas desvantagens e é melhor mantê-la com um provedor em nuvem. A Amazon parece sólida e você cria uma conta no AWS (gratuita para iniciar), lê que usar a identidade do usuário root para tarefas diárias é ruim e cria um usuário IAM normal com permissões de administrador.

    Clicando um pouco, você cria sua própria rede VPC, sub-redes e uma instância virtual EC2, e também adiciona um grupo de segurança para abrir a porta web IRIS (52773) e a porta ssh (22) para você. Repete a instalação do IRIS e Samples BI. Desta vez, usa o script Bash ou Python, se preferir. Mais uma vez, impressiona o chefe.

    Mas o movimento DevOps onipresente leva você a começar a ler sobre infraestrutura como código e você deseja implementá-la. Você escolhe o Terraform, já que ele é bem conhecido de todos e sua abordagem é bastante universal - adequada com pequenos ajustes para vários provedores em nuvem. Você descreve a infraestrutura em linguagem HCL e traduz as etapas de instalação do IRIS e Samples BI para o Ansible. Em seguida, você cria mais um usuário IAM para permitir que o Terraform funcione. Executa tudo. Ganha um bônus no trabalho.

    Gradualmente, você chega à conclusão de que, em nossa era de microsserviços, é uma pena não usar o Docker, especialmente porque a InterSystems lhe diz como. Você retorna ao guia de instalação do Samples BI e lê as linhas sobre o Docker, que não parecem complicadas:

    $ docker pull intersystemsdc/iris-community:2019.4.0.383.0-zpm
    $ docker run --name irisce -d --publish 52773:52773 intersystemsdc/iris-community:2019.4.0.383.0-zpm
    $ docker exec -it irisce iris session iris
    USER>zpm
    zpm: USER>install samples-bi

    Depois de direcionar seu navegador para ttp://localhost:52773/csp/user/_DeepSee.UserPortal.Home.zen?$NAMESPACE=USER, você vai novamente ao chefe e tira um dia de folga por um bom trabalho.

    Você então começa a entender que “docker run” é apenas o começo e você precisa usar pelo menos docker-compose. Não é um problema:

    $ cat docker-compose.yml
    version: "3.7"
    services:
      irisce:
        container_name: irisce
        image: intersystemsdc/iris-community:2019.4.0.383.0-zpm
        ports:
        - 52773:52773
    $ docker rm -f irisce # We don’t need the previous container
    $ docker-compose up -d

    Então, você instala o Docker e o docker-compose com o Ansible e, em seguida, apenas executa o contêiner, que fará o download de uma imagem se ainda não estiver presente na máquina. Em seguida, você instala Samples BI.

    Você certamente gosta do Docker, porque é uma interface simples e legal para várias coisas do kernel. Você começa a usar o Docker em outro lugar e geralmente inicia mais de um contêiner. E descobre que muitas vezes os contêineres devem se comunicar entre si, o que leva à leitura sobre como gerenciar vários contêineres. 

    E você chega ao Kubernetes

    Uma opção para mudar rapidamente de docker-compose para Kubernetes é usar o kompose. Pessoalmente, prefiro simplesmente copiar os manifestos do Kubernetes dos manuais e, em seguida, editá-los, mas o kompose faz um bom trabalho ao concluir sua pequena tarefa:

    $ kompose convert -f docker-compose.yml
    INFO Kubernetes file "irisce-service.yaml" created
    INFO Kubernetes file "irisce-deployment.yaml" created

    Agora você tem os arquivos de implantação e serviço que podem ser enviados para algum cluster do Kubernetes. Você descobre que pode instalar um minikube, que permite executar um cluster Kubernetes de nó único e é exatamente o que você precisa neste estágio. Depois de um ou dois dias brincando com a sandbox do minikube, você está pronto para usar uma implantação real e ao vivo do Kubernetes em algum lugar da nuvem AWS.

    Preparação

    Então, vamos fazer isso juntos. Neste ponto, faremos algumas suposições:

    Primeiro, presumimos que você tenha uma conta no AWS, saiba seu ID e não use credenciais de root. Você criou um usuário IAM (vamos chamá-lo de “my-user”) com direitos de administrador e apenas acesso programático e armazenou suas credenciais. Você também criou outro usuário IAM, chamado “terraform”, com as mesmas permissões:

    Em seu nome, o Terraform irá para sua conta no AWS e criará e excluirá os recursos necessários. Os amplos direitos de ambos os usuários são explicados pelo fato de que se trata de uma demonstração. Você salva as credenciais localmente para os dois usuários IAM:

    $ cat ~/.aws/credentials
    [terraform]
    aws_access_key_id = ABCDEFGHIJKLMNOPQRST
    aws_secret_access_key = ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890123
    [my-user]
    aws_access_key_id = TSRQPONMLKJIHGFEDCBA
    aws_secret_access_key = TSRQPONMLKJIHGFEDCBA01234567890123

    Observação: não copie e cole as credenciais acima. Eles são fornecidos aqui como um exemplo e não existem mais. Edite o arquivo ~/.aws/credentials e introduza seus próprios registros.

    Em segundo lugar, usaremos o ID do conta AWS fictícia (01234567890) para o artigo e a região AWS “eu-west-1.” Sinta-se à vontade para usar outra região.

    Terceiro, presumimos que você esteja ciente de que o AWS não é gratuito e que você terá que pagar pelos recursos usados.

    Em seguida, você instalou o utilitário AWS CLI para comunicação via linha de comando com o AWS. Você pode tentar usar o aws2, mas precisará definir especificamente o uso do aws2 em seu arquivo de configuração do kube, conforme descrito aqui.

    Você também instalou o utilitário kubectl para comunicação via linha de comando com AWS Kubernetes.

    E você instalou o utilitário kompose para docker-compose.yml para converter manifestos do Kubernetes.

    Finalmente, você criou um repositório GitHub vazio e clonou-o em seu host. Vamos nos referir ao seu diretório raiz como . Neste repositório, vamos criar e preencher três diretórios: .github/workflows/, k8s/, e terraform/.

    Observe que todo o código relevante é duplicado no repositório github-eks-samples-bi para simplificar a cópia e a colagem.

    Vamos continuar.

    Provisionamento AWS EKS

    Já conhecemos o EKS no artigo Implementando uma aplicação web simples baseado em IRIS usando o Amazon EKS. Naquela época, criamos um cluster semiautomático. Ou seja, descrevemos o cluster em um arquivo e, em seguida, iniciamos manualmente o utilitário eksctl de uma máquina local, que criou o cluster de acordo com nossa descrição. 

    O eksctl foi desenvolvido para a criação de clusters EKS e é bom para uma implementação de prova de conceito, mas para o uso diário é melhor usar algo mais universal, como o Terraform. Um ótimo recurso, Introdução ao AWS EKS, explica a configuração do Terraform necessária para criar um cluster EKS. Uma ou duas horas gastas para conhecê-lo não será uma perda de tempo.

    Você pode brincar com o Terraform localmente. Para fazer isso, você precisará de um binário (usaremos a versão mais recente para Linux no momento da redação do artigo, 0.12.20) e o usuário IAM “terraform” com direitos suficientes para o Terraform ir para o AWS. Crie o diretório /terraform/ para armazenar o código do Terraform:

    $ mkdir /terraform
    $ cd /terraform

    Você pode criar um ou mais arquivos .tf (eles são mesclados na inicialização). Basta copiar e colar os exemplos de código da Introdução ao AWS EKS e, em seguida, executar algo como:

    $ export AWS_PROFILE=terraform
    $ export AWS_REGION=eu-west-1
    $ terraform init
    $ terraform plan -out eks.plan

    Você pode encontrar alguns erros. Nesse caso, brinque um pouco com o modo de depuração, mas lembre-se de desligá-lo mais tarde:

    $ export TF_LOG=debug
    $ terraform plan -out eks.plan

    $ unset TF_LOG

    Esta experiência será útil, e muito provavelmente você terá um cluster EKS iniciado (use “terraform apply” para isso). Verifique no console do AWS:

    Limpe-o quando você ficar entediado:

    $ terraform destroy

    Em seguida, vá para o próximo nível e comece a usar o módulo Terraform EKS, especialmente porque ele é baseado na mesma introdução ao EKS. No diretório examples/ você verá como usá-lo. Você também  encontrará outros exemplos lá.

    Simplificamos um pouco os exemplos. Este é o arquivo principal em que os módulos de criação de VPC e de criação de EKS são chamados:

    $ cat /terraform/main.tf
    terraform {
      required_version = ">= 0.12.0"
      backend "s3" {
        bucket         = "eks-github-actions-terraform"
        key            = "terraform-dev.tfstate"
        region         = "eu-west-1"
        dynamodb_table = "eks-github-actions-terraform-lock"
      }
    }

    provider "kubernetes" {
      host                   = data.aws_eks_cluster.cluster.endpoint
      cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority.0.data)
      token                  = data.aws_eks_cluster_auth.cluster.token
      load_config_file       = false
      version                = "1.10.0"
    }

    locals {
      vpc_name             = "dev-vpc"
      vpc_cidr             = "10.42.0.0/16"
      private_subnets      = ["10.42.1.0/24", "10.42.2.0/24"]
      public_subnets       = ["10.42.11.0/24", "10.42.12.0/24"]
      cluster_name         = "dev-cluster"
      cluster_version      = "1.14"
      worker_group_name    = "worker-group-1"
      instance_type        = "t2.medium"
      asg_desired_capacity = 1
    }

    data "aws_eks_cluster" "cluster" {
      name = module.eks.cluster_id
    }

    data "aws_eks_cluster_auth" "cluster" {
      name = module.eks.cluster_id
    }

    data "aws_availability_zones" "available" {
    }

    module "vpc" {
      source               = "git::https://github.com/terraform-aws-modules/terraform-aws-vpc?ref=master"

      name                 = local.vpc_name
      cidr                 = local.vpc_cidr
      azs                  = data.aws_availability_zones.available.names
      private_subnets      = local.private_subnets
      public_subnets       = local.public_subnets
      enable_nat_gateway   = true
      single_nat_gateway   = true
      enable_dns_hostnames = true

      tags = {
        "kubernetes.io/cluster/${local.cluster_name}" = "shared"
      }

      public_subnet_tags = {
        "kubernetes.io/cluster/${local.cluster_name}" = "shared"
        "kubernetes.io/role/elb" = "1"
      }

      private_subnet_tags = {
        "kubernetes.io/cluster/${local.cluster_name}" = "shared"
        "kubernetes.io/role/internal-elb" = "1"
      }
    }

    module "eks" {
      source = "git::https://github.com/terraform-aws-modules/terraform-aws-eks?ref=master"
      cluster_name     = local.cluster_name
      cluster_version  = local.cluster_version
      vpc_id           = module.vpc.vpc_id
      subnets          = module.vpc.private_subnets
      write_kubeconfig = false

      worker_groups = [
        {
          name                 = local.worker_group_name
          instance_type        = local.instance_type
          asg_desired_capacity = local.asg_desired_capacity
        }
      ]

      map_accounts = var.map_accounts
      map_roles    = var.map_roles
      map_users    = var.map_users
    }

    Vejamos um pouco mais de perto o bloco "terraform" em main.tf:

    terraform {
      required_version = ">= 0.12.0"
      backend "s3" {
        bucket         = "eks-github-actions-terraform"
        key            = "terraform-dev.tfstate"
        region         = "eu-west-1"
        dynamodb_table = "eks-github-actions-terraform-lock"
      }
    }

    Aqui, indicamos que seguiremos a sintaxe não inferior ao Terraform 0.12 (muito mudou em comparação com as versões anteriores) e também que Terraform não deve armazenar seu estado localmente, mas sim remotamente, no S3 bucket. 

    É conveniente se o código do terraform possa ser atualizado de lugares diferentes por pessoas diferentes, o que significa que precisamos ser capazes de bloquear o estado de um usuário, então adicionamos um bloqueio usando uma tabela dynamodb. Leia mais sobre bloqueios na página State Locking (bloqueio de estado).

    Como o nome do bucket deve ser único em toda o AWS, o nome “eks-github-actions-terraform” não funcionará para você. Pense por conta própria e certifique-se de que ele ainda não foi usado (se sim, você receberá um erro NoSuchBucket):

    $ aws s3 ls s3://my-bucket
    An error occurred (AllAccessDisabled) when calling the ListObjectsV2 operation: All access to this object has been disabled
    $ aws s3 ls s3://my-bucket-with-name-that-impossible-to-remember
    An error occurred (NoSuchBucket) when calling the ListObjectsV2 operation: The specified bucket does not exist

    Tendo criado um nome, crie o bucket (usamos o usuário IAM “terraform” aqui. Ele tem direitos de administrador para que possa criar um bucket) e habilite o controle de versão para ele (o que lhe salvará em caso de um erro de configuração):

    $ aws s3 mb s3://eks-github-actions-terraform --region eu-west-1
    make_bucket: eks-github-actions-terraform
    $ aws s3api put-bucket-versioning --bucket eks-github-actions-terraform --versioning-configuration Status=Enabled
    $ aws s3api get-bucket-versioning --bucket eks-github-actions-terraform
    {
      "Status": "Enabled"
    }

    Com o DynamoDB, ser único não é necessário, mas você precisa criar uma tabela primeiro:

    $ aws dynamodb create-table                                                                                     \
      --region eu-west-1                                                                                                           \
      --table-name eks-github-actions-terraform-lock                                              \
      --attribute-definitions AttributeName=LockID,AttributeType=S                \
      --key-schema AttributeName=LockID,KeyType=HASH                                   \
      --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5

    Lembre-se de que, em caso de falha do Terraform, você pode precisar remover um bloqueio manualmente do console AWS. Mas tenha cuidado ao fazer isso.

    Com relação aos blocos do módulo eks/vpc em main.tf, a forma de referenciar o módulo disponível no GitHub é simples:

    git::https://github.com/terraform-aws-modules/terraform-aws-vpc?ref=master

    Agora vamos dar uma olhada em nossos outros dois arquivos Terraform (variables.tf e outputs.tf). O primeiro contém nossas variáveis Terraform:

    $ cat /terraform/variables.tf
    variable "region" {
      default = "eu-west-1"
    }

    variable "map_accounts" {
      description = "Additional AWS account numbers to add to the aws-auth configmap. See examples/basic/variables.tf for example format."
      type        = list(string)
      default     = []
    }

    variable "map_roles" {
      description = "Additional IAM roles to add to the aws-auth configmap."
      type = list(object({
        rolearn  = string
        username = string
        groups   = list(string)
      }))
      default = []
    }

    variable "map_users" {
      description = "Additional IAM users to add to the aws-auth configmap."
      type = list(object({
        userarn  = string
        username = string
        groups   = list(string)
      }))
      default = [
        {
          userarn  = "arn:aws:iam::01234567890:user/my-user"
          username = "my-user"
          groups   = ["system:masters"]
        }
      ]
    }

    A parte mais importante aqui é adicionar o usuário IAM “my-user” à variável map_users, mas você deve usar seu próprio ID de conta aqui no lugar de 01234567890.

    O que isto faz? Quando você se comunica com o EKS por meio do cliente kubectl local, ele envia solicitações ao servidor da API Kubernetes, e cada solicitação passa por processos de autenticação e autorização para que o Kubernetes possa entender quem enviou a solicitação e o que elas podem fazer. Portanto, a versão EKS do Kubernetes pede ajuda ao AWS IAM com a autenticação do usuário. Se o usuário que enviou a solicitação estiver listado no AWS IAM (apontamos seu ARN aqui), a solicitação vai para a fase de autorização, que o EKS processa sozinho, mas de acordo com nossas configurações. Aqui, indicamos que o usuário IAM “my-user” é muito legal (grupo “system: masters”).

    Por fim, o arquivo outputs.tf descreve o que o Terraform deve imprimir após concluir um job:

    $ cat /terraform/outputs.tf
    output "cluster_endpoint" {
      description = "Endpoint for EKS control plane."
      value       = module.eks.cluster_endpoint
    }

    output "cluster_security_group_id" {
      description = "Security group ids attached to the cluster control plane."
      value       = module.eks.cluster_security_group_id
    }

    output "config_map_aws_auth" {
      description = "A kubernetes configuration to authenticate to this EKS cluster."
      value       = module.eks.config_map_aws_auth
    }

    Isso completa a descrição da parte do Terraform. Voltaremos em breve para ver como vamos iniciar esses arquivos.

    Manifestos Kubernetes

    Até agora, cuidamos de onde iniciar a aplicação. Agora vamos ver o que executar. 

    Lembre-se de que temos o docker-compose.yml (renomeamos o serviço e adicionamos alguns rótulos que o kompose usará em breve) no diretório /k8s/:

    $ cat /k8s/docker-compose.yml
    version: "3.7"
    services:
      samples-bi:
        container_name: samples-bi
        image: intersystemsdc/iris-community:2019.4.0.383.0-zpm
        ports:
        - 52773:52773
        labels:
          kompose.service.type: loadbalancer
          kompose.image-pull-policy: IfNotPresent

    Execute o kompose e adicione o que está destacado abaixo. Exclua as anotações (para tornar as coisas mais inteligíveis):

    $ kompose convert -f docker-compose.yml --replicas=1
    $ cat /k8s/samples-bi-deployment.yaml
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      labels:
        io.kompose.service: samples-bi
      name: samples-bi
    spec:
      replicas: 1
      strategy:
        type: Recreate
      template:
        metadata:
          labels:
            io.kompose.service: samples-bi
        spec:
          containers:
          - image: intersystemsdc/iris-community:2019.4.0.383.0-zpm
            imagePullPolicy: IfNotPresent
            name: samples-bi
            ports:
            - containerPort: 52773
            resources: {}
            lifecycle:
              postStart:
                exec:
                  command:
                  - /bin/bash
                  - -c
                  - |
                    echo -e "write\nhalt" > test
                    until iris session iris < test; do sleep 1; done
                    echo -e "zpm\ninstall samples-bi\nquit\nhalt" > samples_bi_install
                    iris session iris < samples_bi_install
                    rm test samples_bi_install

            restartPolicy: Always

    Usamos a estratégia de atualização de Recriar, o que significa que o pod será excluído primeiro e depois recriado. Isso é permitido para fins de demonstração e nos permite usar menos recursos.
    Também adicionamos o postStart hook, que será disparado imediatamente após o início do pod. Esperamos até o IRIS iniciar e instalar o pacote samples-bi do repositório zpm padrão.
    Agora adicionamos o serviço Kubernetes (também sem anotações):

    $ cat /k8s/samples-bi-service.yaml
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        io.kompose.service: samples-bi
      name: samples-bi
    spec:
      ports:
      - name: "52773"
        port: 52773
        targetPort: 52773
      selector:
        io.kompose.service: samples-bi
      type: LoadBalancer

    Sim, vamos implantar no namespace "padrão", que funcionará para a demonstração.

    Ok, agora sabemos onde e o que queremos executar. Resta ver como.

    O fluxo de trabalho do GitHub Actions

    Em vez de fazer tudo do zero, criaremos um fluxo de trabalho semelhante ao descrito em Implantando uma solução InterSystems IRIS no GKE usando GitHub Actions. Desta vez, não precisamos nos preocupar em construir um contêiner. As partes específicas do GKE são substituídas pelas específicas do EKS. As partes em negrito estão relacionadas ao recebimento da mensagem de commit e ao uso dela em etapas condicionais:

    $ cat /.github/workflows/workflow.yaml
    name: Provision EKS cluster and deploy Samples BI there
    on:
      push:
        branches:
        - master

    # Environment variables.
    # ${{ secrets }} are taken from GitHub -> Settings -> Secrets
    # ${{ github.sha }} is the commit hash
    env:
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      AWS_REGION: ${{ secrets.AWS_REGION }}
      CLUSTER_NAME: dev-cluster
      DEPLOYMENT_NAME: samples-bi

    jobs:
      eks-provisioner:
        # Inspired by:
        ## https://www.terraform.io/docs/github-actions/getting-started.html
        ## https://github.com/hashicorp/terraform-github-actions
        name: Provision EKS cluster
        runs-on: ubuntu-18.04
        steps:
        - name: Checkout
          uses: actions/checkout@v2

        - name: Get commit message
          run: |
            echo ::set-env name=commit_msg::$(git log --format=%B -n 1 ${{ github.event.after }})

        - name: Show commit message
          run: echo $commit_msg

        - name: Terraform init
          uses: hashicorp/terraform-github-actions@master
          with:
            tf_actions_version: 0.12.20
            tf_actions_subcommand: 'init'
            tf_actions_working_dir: 'terraform'

        - name: Terraform validate
          uses: hashicorp/terraform-github-actions@master
          with:
            tf_actions_version: 0.12.20
            tf_actions_subcommand: 'validate'
            tf_actions_working_dir: 'terraform'

        - name: Terraform plan
          if: "!contains(env.commit_msg, '[destroy eks]')"
          uses: hashicorp/terraform-github-actions@master
          with:
            tf_actions_version: 0.12.20
            tf_actions_subcommand: 'plan'
            tf_actions_working_dir: 'terraform'

        - name: Terraform plan for destroy
          if: "contains(env.commit_msg, '[destroy eks]')"
          uses: hashicorp/terraform-github-actions@master
          with:
            tf_actions_version: 0.12.20
            tf_actions_subcommand: 'plan'
            args: '-destroy -out=./destroy-plan'
            tf_actions_working_dir: 'terraform'

        - name: Terraform apply
          if: "!contains(env.commit_msg, '[destroy eks]')"
          uses: hashicorp/terraform-github-actions@master
          with:
            tf_actions_version: 0.12.20
            tf_actions_subcommand: 'apply'
            tf_actions_working_dir: 'terraform'

        - name: Terraform apply for destroy
          if: "contains(env.commit_msg, '[destroy eks]')"
          uses: hashicorp/terraform-github-actions@master
          with:
            tf_actions_version: 0.12.20
            tf_actions_subcommand: 'apply'
            args: './destroy-plan'
            tf_actions_working_dir: 'terraform'

      kubernetes-deploy:
        name: Deploy Kubernetes manifests to EKS
        needs:
        - eks-provisioner
        runs-on: ubuntu-18.04
        steps:
        - name: Checkout
          uses: actions/checkout@v2

        - name: Get commit message
          run: |
            echo ::set-env name=commit_msg::$(git log --format=%B -n 1 ${{ github.event.after }})

        - name: Show commit message
          run: echo $commit_msg

        - name: Configure AWS Credentials
          if: "!contains(env.commit_msg, '[destroy eks]')"
          uses: aws-actions/configure-aws-credentials@v1
          with:
            aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
            aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
            aws-region: ${{ secrets.AWS_REGION }}

        - name: Apply Kubernetes manifests
          if: "!contains(env.commit_msg, '[destroy eks]')"
          working-directory: ./k8s/
          run: |
            aws eks update-kubeconfig --name ${CLUSTER_NAME}
            kubectl apply -f samples-bi-service.yaml
            kubectl apply -f samples-bi-deployment.yaml
            kubectl rollout status deployment/${DEPLOYMENT_NAME}

    É claro que, precisamos definir as credenciais do usuário "terraform" (retirá-las do arquivo ~/.aws/credentials), permitindo que o GitHub use seus segredos:

    Observe as partes destacadas do fluxo de trabalho. Elas nos permitirão destruir um cluster EKS empurrando uma mensagem de commit que contém a frase “[destroy eks]”. Observe que não executaremos "kubernetes apply" com essa mensagem de commit.
    Execute um pipeline, mas primeiro crie um arquivo .gitignore:

    $ cat /.gitignore
    .DS_Store
    terraform/.terraform/
    terraform/*.plan
    terraform/*.json

    $ cd
    $ git add .github/ k8s/ terraform/ .gitignore
    $ git commit -m "GitHub on EKS"
    $ git push

    Monitore o processo de implantação na aba "Actions" da página do repositório GitHub. Aguarde a conclusão com sucesso.

    Quando você executa um fluxo de trabalho pela primeira vez, leva cerca de 15 minutos na etapa “Terraform apply”, aproximadamente o mesmo tempo necessário para criar o cluster. Na próxima inicialização (se você não excluiu o cluster), o fluxo de trabalho será muito mais rápido. Você pode verificar isso:

    $ cd
    $ git commit -m "Trigger" --allow-empty
    $ git push

    É claro que seria bom verificar o que fizemos. Desta vez, você pode usar as credenciais do IAM “my-user” em seu computador:

    $ export AWS_PROFILE=my-user
    $ export AWS_REGION=eu-west-1
    $ aws sts get-caller-identity
    $ aws eks update-kubeconfig --region=eu-west-1 --name=dev-cluster --alias=dev-cluster
    $ kubectl config current-context
    dev-cluster

    $ kubectl get nodes
    NAME                                                                               STATUS   ROLES      AGE          VERSION
    ip-10-42-1-125.eu-west-1.compute.internal   Ready          6m20s     v1.14.8-eks-b8860f

    $ kubectl get po
    NAME                                                       READY        STATUS      RESTARTS   AGE
    samples-bi-756dddffdb-zd9nw    1/1               Running    0                      6m16s

    $ kubectl get svc
    NAME                   TYPE                        CLUSTER-IP        EXTERNAL-IP                                                                                                                                                         PORT(S)                    AGE
    kubernetes        ClusterIP               172.20.0.1                                                                                                                                                                                443/TCP                    11m
    samples-bi         LoadBalancer     172.20.33.235    a2c6f6733557511eab3c302618b2fae2-622862917.eu-west-1.elb.amazonaws.com    52773:31047/TCP  6m33s

    Vá para _http://a2c6f6733557511eab3c302618b2fae2-622862917.eu-west-1.elb.amazonaws.com:52773/csp/user/_DeepSee.UserPortal.Home.zen?$NAMESPACE=USER _(substitua o link pelo seu IP externo), então, digite “_system”, “SYS” e altere a senha padrão. Você deve ver vários painéis de Inteligência Empresarial (BI):

    Clique na seta de cada um para um mergulho mais profundo:

    Lembre-se, se você reiniciar um pod samples-bi, todas as suas alterações serão perdidas. Este é um comportamento intencional, pois esta é uma demonstração. Se você precisar de persistência, criei um exemplo no repositório github-gke-zpm-registry/k8s/statefulset.tpl.

    Quando terminar, basta remover tudo que você criou:

    $ git commit -m "Mr Proper [destroy eks]" --allow-empty
    $ git push

    Conclusão

    Neste artigo, substituímos o utilitário eksctl pelo Terraform para criar um cluster EKS. É um passo à frente para “codificar” toda a sua infraestrutura AWS.
    Mostramos como você pode facilmente implantar uma aplicação de demonstração com git push usando GitHub Actions e Terraform.
    Também adicionamos o kompose e um postStart hook de um pod à nossa caixa de ferramentas.
    Não mostramos a ativação do TLS neste momento. Essa é uma tarefa que realizaremos em um futuro próximo.

    0
    0 301
    Artigo Henrique Dias · Out. 26, 2020 3m read

    Fala pessoal!


    Quero dividir com vocês um projeto pessoal, que iniciou como um simples pedido no meu trabalho: 

    É possível saber quantas licenças Caché estamos utilizando? 

    Lendo outros artigos aqui na comunidade, eu encontrei este excelente artigo de David Loveluck 


    APM - Utilizando Caché History Monitor
    https://community.intersystems.com/post/apm-using-cach%C3%A9-history-monitor

    Então, utilizando o artigo de David como base, eu comecei a utilizar o Caché History Monitor e a exibir todas as informações.
    Quando me deparei com o seguinte dilema: Qual a melhor tecnologia de frontend que eu posso usar?

    0
    0 218