Executando aplicativos de terceiros em contêineres
Para executar seus próprios aplicativos no Junos OS Evolved, você tem a opção de implantá-los como um contêiner Docker. O contêiner é executado no Junos OS Evolved, e os aplicativos são executados no contêiner, mantendo-os isolados do sistema operacional host. Os contêineres são instalados em uma partição separada montada em /var/extensões. Os contêineres persistem em reinicializações e atualizações de software.
Os contêineres Docker não são integrados ao Junos OS Evolved, eles são criados e gerenciados inteiramente através do Linux usando comandos Docker. Para obter mais informações sobre contêineres e comandos Docker, veja a documentação oficial do Docker: https://docs.docker.com/get-started/
Os contêineres têm limites padrão para os recursos que podem usar do sistema:
-
Storage – O tamanho da partição /var/extensões é orientado por plataforma: 8GB ou 30% do tamanho total de /var, o que for menor.
-
Memory – Os contêineres não têm limite padrão de memória física. Isso pode ser mudado.
-
CPU – Os contêineres não têm limite padrão de CPU. Isso pode ser mudado.
Você pode modificar os limites de recursos em contêineres, se necessário. Veja modificação dos limites de recursos para contêineres.
Implantação de um contêiner Docker
Para implantar um contêiner Docker:
Gerenciamento de um contêiner Docker
Os contêineres Docker são gerenciados por meio do fluxo de trabalho padrão do Docker Linux. Use os docker ps
comandos , ps
ou top
Linux para mostrar quais contêineres Docker estão sendo executados, e use comandos Docker para gerenciar os contêineres. Para obter mais informações sobre os comandos Docker, veja: https://docs.docker.com/engine/reference/commandline/cli/
Os recursos de alta disponibilidade do Junos OS Evolved não são suportados para aplicativos personalizados em contêineres Docker, se um aplicativo tem funcionalidade de alta disponibilidade, então você deve executar o aplicativo em cada RE para garantir que ele possa se sincronizar. Esse aplicativo precisará ter a lógica de negócios necessária para se gerenciar e se comunicar com todas as instâncias.
Habilitação de Netlink ou PacketIO em um contêiner
Você precisa fornecer argumentos adicionais aos comandos Docker se o seu contêiner exigir recursos extras como Netlink ou PacketIO. Você também precisará habilitar o nlsd
serviço para habilitar a funcionalidade do Netlink em determinadas versões. O exemplo a seguir mostra como ativar recursos de Netlink ou PacketIO para um contêiner adicionando argumentos a um comando Docker:
Crie um volume persistente de nome somente para leitura ao iniciar os serviços Docker. A montagem do
jnet
volume irá montar bibliotecas necessárias necessárias para a funcionalidade PacketIO e Netlink em portas WAN/dados:--mount source=jnet,destination=/usr/evo
Compartilhe o namespace de rede e IPC do host com o contêiner. Os contêineres que exijam funcionalidade de PacketIO e Netlink nas portas WAN/dados precisarão estar no namespace de rede de host e IPC:
--network=host --ipc=host
Inicie automaticamente o contêiner após a reinicialização do sistema:
--restart=always
Habilite o recurso de administrador líquido, que é exigido pelas bibliotecas Netlink e PacketIO:
--cap-add=NET_ADMIN
Habilite as variáveis ambientais necessárias para Netlink e PacketIO em portas WAN/dados:
--env-file=/run/docker/jnet.env
Monte o dispositivo jtd0 do host até o contêiner para ajudar com o PacketIO:
--device=/dev/jtd0
Monte o diretório do host /dev/shm no contêiner para Netlink e PacketIO em portas WAN/dados:
-v /dev/shm:/dev/shm
Se o gerenciamento de grupo multicast for exigido pelo aplicativo de contêiner, monte o diretório /dev/mcgrp do host até o contêiner:
-v /dev/mcgrp:/dev/mcgrp
Após a versão 24.1R1 do Junos OS Evolved, os contêineres no namespace da rede de host que desejam ter resolução de DNS precisarão passar a opção
--dns ::1
para odocker run
comando. Isso não é necessário para o Junos OS Evolved versão 23.4 e anterior:--dns ::1
Se o seu contêiner exigir processamento relacionado ao Netlink, você também precisa habilitar o processo de API assíncrono (
nlsd
Netlink) no Junos OS Evolved com a seguinte configuração CLI:[edit] user@host# set system processes nlsd enable
Os aplicativos nativos de Linux ou baseados em contêiner que exigem funcionalidade PacketIO e Netlink devem ser vinculados dinamicamente. Recomendamos o uso de contêineres Docker baseados no Ubuntu, pois eles são os únicos contêineres que são oficialmente qualificados pela Juniper Networks. Os contêineres baseados em Ubuntu devem usar o glibc
compatível com o Junos Evolved OS glibc
base.
Selecionando um VRF para um contêiner Docker
Para o Junos OS Evolved Releases 23.4R1 e anteriores, os contêineres herdam o roteamento virtual e o encaminhamento (VRF) do processo Docker. Para executar contêineres em um VRF distinto, uma instância de processo Docker precisa ser iniciada no VRF correspondente. A docker@vrf.service
instância permite iniciar um processo no VRF correspondente. Se o VRF não estiver especificado, o VRF fica inadimplente em vrf0
.
A docker.service
rede funciona vrf:none
por padrão.
Para o Junos OS Evolved Releases 24.1R1 e posteriores, recomendamos vincular uma tarefa específica dentro do contêiner a um Linux VRF específico usando o ip vrf exec task
comando. Isso exige que o contêiner seja iniciado com a opção --privileged
, e o contêiner precisa ter uma versão compatível da instalação iproute2
. O contêiner também deve compartilhar o namespace da rede com o host. Você também pode usar a opção SO_BINDTODEVICE
de tomada para vincular o soquete para uma tarefa ou aplicativo específico dentro do contêiner a um dispositivo VrF Linux específico, nesse caso iproute2
não é necessário.
O ip vrf show
comando lista todos os VRFs linux disponíveis. Se você optar por vincular os soquetes para uma tarefa dentro do contêiner a um VRF usando iproute2
, recomendamos reescrever algumas variáveis de env usando --env-file=/run/docker-vrf0/jnet.env
, para libnli.so
que não seja pré-carregado para evitar que interfira iproute2
.
Você pode lançar um contêiner e vincular o soquete associado à tarefa do contêiner ao vrf vrf0
padrão com os seguintes comandos:
[vrf:none] user@host:~# docker -H unix:///run/docker-vrf0.sock run --rm -it –-privileged --network=host --ipc=host --cap-add=NET_ADMIN --mount source=jnet,destination=/usr/evo --device=/dev/jtd0 -v /dev/mcgrp:/dev/mcgrp -v /dev/shm:/dev/shm --env-file=/run/docker-vrf0/jnet.env --dns ::1 debian:stretch bash # explicitly preload libsi.so and avoid libnli.so. Bind ping’s socket to vrf0 (default) VRF [vrf:none] user@host: my-container/# LD_PRELOAD=libsi.so.0 ip vrf exec vrf0 ping 1.2.3.4
Com essa abordagem, diferentes tomadas associadas a diferentes tarefas dentro do contêiner podem ser associadas a diferentes VRFs em vez de todos os tomadas vinculados a apenas um VRF.
O processo Docker para um VRF específico ouve o socket correspondente localizado em /run/docker-vrf.sock.
Este é o VRF, como visto no Linux e não no Junos OS Evolved VRF. O utilitário evo_vrf_name
(disponível a partir do Junos OS Evolved release 24.1) pode ser usado para encontrar o Linux VRF que corresponde a um Junos OS Evolved VRF.
O cliente Docker é associado ao processo docker específico da VRF usando os seguintes argumentos:
--env-file /run/docker-vrf/jnet.env --host unix:///run/docker-vrf.sock or export DOCKER_HOST=unix:///run/docker-vrf.sock
Por exemplo, para executar um contêiner vrf0
, insira os seguintes argumentos e comandos Docker:
[vrf:none] user@host:~# docker -H unix:///run/docker-vrf0.sock run --rm -it --network=host --ipc=host --cap-add=NET_ADMIN --mount source=jnet,destination=/usr/evo --device=/dev/jtd0 -v /dev/mcgrp:/dev/mcgrp -v /dev/shm:/dev/shm --env-file=/run/docker-vrf0/jnet.env --dns ::1 debian:stretch ip link 1002: et-01000000000: BROADCAST,MULTICAST,UP mtu 1514 state UP qlen 1 link/ether ac:a:a:18:01:ff brd ff:ff:ff:ff:ff:ff 1001: mgmt-0-00-0000: BROADCAST,MULTICAST,UP mtu 1500 state UP qlen 1 link/ether 50:60:a:e:08:bd brd ff:ff:ff:ff:ff:ff 1000: lo0_0: LOOPBACK,UP mtu 65536 state UP qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
Um contêiner só pode ser associado a um único VRF.
Modificação dos limites de recursos para contêineres
Os limites padrão de recursos para contêineres são controlados por um arquivo localizado em /etc/extensões/platform_attributes. Você verá o texto a seguir ao abrir este arquivo:
## Edit to change upper cap of total resource limits for all containers. ## applies only to containers and does not apply to container runtimes. ## memory.memsw.limit_in_bytes = EXTENSIONS_MEMORY_MAX_MIB + EXTENSIONS_MEMORY_SWAP_MAX_MIB:-0 ## please start extensions-cglimits.service to apply changes to CPU and Memory values here ## please restart var-extensions.mount to apply changes to partition resize here ## make sure the docker daemon is stopped before changing mount size ## For changing EXTENSIONS_FS_DEVICE_SIZE_MIB, please also remove file rm /var/extensions_fs ## make sure to create a backup before partition resize ## check current defaults, after starting extensions-cglimits.service ## $ /usr/libexec/extensions/extensions_cglimits get ## you can also set current values like this as an alternative to starting extensions-cglimits.service ## $ /usr/libexec/extensions/extensions_cglimits set ## if you set one of the memory values, set the other one as well – mandated by cgroup ## device size limit will be ignored once extensionsfs device is created #EXTENSIONS_FS_DEVICE_SIZE_MIB= #EXTENSIONS_CPU_QUOTA_PERCENTAGE= #EXTENSIONS_MEMORY_MAX_MIB= #EXTENSIONS_MEMORY_SWAP_MAX_MIB=
Para alterar os limites de recursos para contêineres, adicione valores às EXTENSIONS
entradas na parte inferior do arquivo. Certifique-se de fazer isso antes de iniciar o processo Docker.
-
EXTENSIONS_FS_DEVICE_SIZE_MIB=
controla o espaço máximo de armazenamento que os contêineres podem usar. Digite o valor em megabytes. O valor padrão é de 8000 ou 30% do tamanho total de /var, o que for menor. Certifique-se de adicionar esta entrada antes de iniciar o processo Docker pela primeira vez. Se você precisar alterar esse valor mais tarde, você precisará excluir a partição existente, o que pode levar à perda de dados nesta partição. Se essa partição de armazenamento precisar ser alterada após o início do serviço Docker, então o processo Docker precisa ser interrompido primeiro com osystemctl stop docker
comando, e a partição existente pode ser excluída usando osystemctl stop var-extensions.mount
comando seguido pelorm /var/extensions_fs
comando. Assim que este atributo for alterado, inicie o processo Docker novamente e a nova partição com o tamanho especificado será criada. Você também pode reiniciarvar-extensions.mount
com osystemctl restart var-extensions.mount
comando para obter o mesmo resultado. Sugerimos fazer um backup da partição para evitar perder dados importantes. Não recomendamos aumentar esse valor além de 30% da partição /var , pois isso pode afetar a função normal do Junos OS Evolved. -
EXTENSIONS_CPU_QUOTA_PERCENTAGE=
controla o uso máximo de CPU que os contêineres podem usar. Digite um valor como porcentagem do uso da CPU. O valor padrão é de 20%, mas pode variar dependendo da plataforma. -
EXTENSIONS_MEMORY_MAX_MIB=
controla a quantidade máxima de memória física que os contêineres podem usar. Digite o valor em megabytes. O valor padrão é de 2000, mas pode variar dependendo da plataforma. Se isso precisar ser modificado, o valorEXTENSIONS_MEMORY_SWAP_MAX_MIB=
de swap também deve ser especificado. Observe que o Linuxcgroup
não permite que valores insensatos sejam definidos para limites de memória e CPU. Se o conjunto de valores não se refletir nacgroup
razão mais provável é que os valores estejam errados (possivelmente muito altos ou muito baixos). -
EXTENSIONS_MEMORY_SWAP_MAX_MIB=
controla a quantidade máxima de memória de troca que os contêineres podem usar. Digite o valor em megabytes. O valor padrão é de 15% do espaço de swap disponível, mas pode variar dependendo da plataforma. Ambos eEXTENSION_MEMORY_MAX_MIB=
EXTENSIONS_MEMORY_SWAP_MAX_MIB=
devem ser definidos se ambos estiverem sendo modificados. O valor recomendado para swap é de 15% deEXTENSION_MEMORY_MAX_MIB=
. O valor realcgroup
para swap seriaEXTENSION_MEMORY_MAX_MIB
+EXTENSIONS_MEMORY_SWAP_MAX_MIB
.
Por padrão, estes são definidos em valores específicos da plataforma, por isso recomendamos definir os valores antes de iniciar os contêineres.
Antes de modificar os limites de recursos para contêineres, esteja ciente dos requisitos de CPU e memória para a escala que você tem a oferecer em sua configuração. Tenha cuidado ao aumentar os limites de recursos para contêineres para evitar que eles causem uma tensão em seu sistema.