O autor selecionou a Open Internet/Free Speech para receber uma doação como parte do programa Write for DOnations.
O Kubernetes é um sistema de orquestração de contêiner de código aberto. Ele permite que você crie, atualize e escale contêineres sem se preocupar com o tempo de inatividade.
Para executar um aplicativo PHP, o Nginx age como um proxy para o PHP-FPM. A transformação em contêiner dessa configuração em um único contêiner pode ser um processo complicado, mas o Kubernetes ajudará a gerenciar ambos os serviços em contêineres separados. Ao usar o Kubernetes, é permitido que você mantenha seus contêineres reutilizáveis e intercambiáveis, e não será necessário reconstruir sua imagem do contêiner sempre que houver uma nova versão do Nginx ou do PHP.
Neste tutorial, você implantará um aplicativo PHP 7 em um cluster do Kubernetes com o Nginx e o PHP-FPM funcionando em contêineres separados. Você também aprenderá como manter seus arquivos de configuração e código de aplicativo fora da imagem do contêiner usando o sistema de armazenamento de blocos da DigitalOcean. Esta abordagem permitirá a reutilização da imagem do Nginx para qualquer aplicativo que precise de um servidor Web/proxy passando um volume de configuração, ao invés de reconstruir a imagem.
Neste passo, serão criados os serviços PHP-FPM e Nginx. Um serviço permite o acesso a um conjunto de pods de dentro do cluster. Os serviços dentro de um cluster podem se comunicar diretamente através dos seus nomes, sem a necessidade de endereços IP. O serviço PHP-FPM permitirá o acesso aos pods do PHP-FPM, enquanto o serviço Nginx permitirá o acesso aos pods do Nginx.
Como os pods do Nginx irão servir de proxy para os pods do PHP-FPM, será necessário dizer ao serviço como encontrá-los. Ao invés de usar endereços IP, você tirará proveito da descoberta automática do serviço do Kubernetes para usar nomes legíveis para rotear pedidos para o serviço apropriado.
Para criar o serviço, você criará um arquivo de definição de objeto. Cada definição de objeto do Kubernetes é um arquivo YAML que contém pelo menos os seguintes itens:
apiVersion
: a versão da API do Kubernetes à qual a definição pertence.kind
: o objeto do Kubernetes que este arquivo representa. Por exemplo, um pod
ou service
.metadata
: contém o name
do objeto junto com quaisquer labels
que você queira aplicar a ele.spec
: contém uma configuração específica dependendo do tipo de objeto que está sendo criado, como a imagem do contêiner ou as portas das quais o contêiner será acessível.Primeiro, você criará um diretório para manter suas definições de objeto do Kubernetes.
Pelo SSH vá até seu master node e crie o diretório definitions
que irá manter suas definições de objeto do Kubernetes.
- mkdir definitions
Navegue até o diretório recém-criado definitions
:
- cd definitions
Crie seu serviço PHP-FPM criando um arquivo php_service.yaml
:
- nano php_service.yaml
Defina kind
como Service
para especificar que este objeto é um serviço:
...
apiVersion: v1
kind: Service
Nomeie o serviço php
, já que ele fornecerá acesso ao PHP-FPM:
...
metadata:
name: php
Você agrupará logicamente objetos diferentes com rótulos. Neste tutorial, você usará os rótulos para agrupar os objetos em “camadas”, como frontend ou backend. Os pods do PHP serão executados por trás deste serviço, então você dará o rótulo de tier: backend
.
...
labels:
tier: backend
Um serviço determina quais pods acessar usando os rótulos selector
. Um pod que corresponda a esses rótulos será atendido, independentemente de se o pod tenha sido criado antes ou após o serviço. Você adicionará rótulos para seus pods mais tarde no tutorial.
Use o rótulo tier: backend
para atribuir o pod à camada backend. Você também adicionará o rótulo app: php
para especificar que este pod executa o PHP. Adicione esses dois rótulos após a seção metadata
.
...
spec:
selector:
app: php
tier: backend
Em seguida, especifique a porta usada para acessar este serviço. A porta 9000
será usada neste tutorial. Adicione-a ao arquivo php_service.yaml
em spec
:
...
ports:
- protocol: TCP
port: 9000
Seu arquivo final php_service.yaml
se parecerá com isso:
apiVersion: v1
kind: Service
metadata:
name: php
labels:
tier: backend
spec:
selector:
app: php
tier: backend
ports:
- protocol: TCP
port: 9000
Pressione CTRL + o
para salvar o arquivo e, depois, CTRL + x
para sair do nano
.
Agora que criou a definição de objeto para seu serviço, para executar o serviço você usará o comando kubectl apply
junto com o argumento -f
e especificará seu arquivo php_service.yaml
.
Crie seu serviço:
- kubectl apply -f php_service.yaml
Este resultado confirma a criação do serviço:
Outputservice/php created
Verifique se seu serviço está funcionando:
- kubectl get svc
Você verá seu serviço PHP-FPM funcionando:
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10m
php ClusterIP 10.100.59.238 <none> 9000/TCP 5m
Existem vários tipos de serviço que o Kubernetes suporta. Seu serviço php
usa o tipo padrão de serviço, o ClusterIP
. Este tipo de serviço atribui um IP interno e torna o serviço acessível apenas a partir de dentro do cluster.
Agora que o serviço PHP-FPM está pronto, você criará o serviço Nginx. Crie e abra um novo arquivo chamado nginx_service.yaml
com o editor:
- nano nginx_service.yaml
Este serviço irá atingir os pods do Nginx, então você irá chamá-lo de nginx
. Um rótulo tier: backend
também será adicionado, já que ele pertence à camada backend:
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
tier: backend
De forma similar ao serviço php,
mire nos pods com os rótulos seletores app: nginx
e tier: backend
. Torne este serviço acessível na porta 80, a porta padrão HTTP.
...
spec:
selector:
app: nginx
tier: backend
ports:
- protocol: TCP
port: 80
O serviço Nginx estará acessível publicamente na Internet do endereço IP público do seu Droplet. O your_public_ip
pode ser encontrado no seu painel na nuvem DigitalOcean. Em spec.externalIPs
, adicione:
...
spec:
externalIPs:
- your_public_ip
Seu arquivo nginx_service.yaml
se parecerá com isto:
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
tier: backend
spec:
selector:
app: nginx
tier: backend
ports:
- protocol: TCP
port: 80
externalIPs:
- your_public_ip
Salve e feche o arquivo. Crie o serviço Nginx:
- kubectl apply -f nginx_service.yaml
Você verá o seguinte resultado quando o serviço estiver funcionando:
Outputservice/nginx created
Você pode ver todos os serviços em funcionamento executando:
- kubectl get svc
Você verá tanto os serviços PHP-FPM como os serviços Nginx listados no resultado:
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13m
nginx ClusterIP 10.102.160.47 your_public_ip 80/TCP 50s
php ClusterIP 10.100.59.238 <none> 9000/TCP 8m
Note, se quiser excluir um serviço, execute:
- kubectl delete svc/service_name
Agora que você criou seus serviços PHP-FPM e Nginx, será necessário especificar onde armazenar seu código de aplicativo e arquivos de configuração.
O Kubernetes fornece plug-ins de armazenamento diferentes que podem criar o espaço de armazenamento para seu ambiente. Neste passo, será instalado o plug-in de armazenamento da DigitalOcean para criar o armazenamento de bloco na DigitalOcean. Assim que a instalação for concluída, será adicionada uma classe de armazenamento chamada do-block-storage
que você usará para criar seu armazenamento de bloco.
Primeiro, você irá configurar um objeto segredo do Kubernetes para armazenar seu token de API da DigitalOcean. Os objetos segredo são usados para compartilhar informações sensíveis, como chaves SSH e senhas, com outros objetos do Kubernetes dentro do mesmo namespace. Os namespaces fornecem uma maneira de separar seus objetos do Kubernetes logicamente.
Abra um arquivo chamado secret.yaml
com o editor:
- nano secret.yaml
Você irá nomear seu segredo digitalocean
e adicioná-lo ao namespace kube-system``.
O namespace kube-system
é o nome padrão de namespace para serviços internos do Kubernetes e é usado também pelo plug-in de armazenamento da DigitalOcean para inicializar vários componentes.
apiVersion: v1
kind: Secret
metadata:
name: digitalocean
namespace: kube-system
Ao invés de uma chave spec
, um segredo usa uma chave data
ou stringData
para reter as informações necessárias. O parâmetro data
retém os dados na base64 codificados que são automaticamente decodificados quando recuperados. O parâmetro stringData
retém dados não codificados que são automaticamente codificados durante a criação ou atualizações e não gera os exibe os dados ao recuperar os segredos. Você usará o stringData
neste tutorial por conveniência.
Adicione o access-token
como stringData
:
...
stringData:
access-token: your-api-token
Salve e saia do arquivo.
Seu arquivo secret.yaml
se parecerá com isso:
apiVersion: v1
kind: Secret
metadata:
name: digitalocean
namespace: kube-system
stringData:
access-token: your-api-token
Crie o segredo:
- kubectl apply -f secret.yaml
Você verá este resultado após a criação do segredo:
Outputsecret/digitalocean created
Você pode ver o segredo com o seguinte comando:
- kubectl -n kube-system get secret digitalocean
O resultado será semelhante a este:
OutputNAME TYPE DATA AGE
digitalocean Opaque 1 41s
O tipo Opaque
significa que este segredo é apenas de leitura, que é o padrão para os segredos stringData
. Você pode ler mais sobre isso nas Especificações de design do segredo. O campo DATA
mostra o número de itens armazenados neste segredo. Neste caso, ele mostra 1
porque você tem uma única chave armazenada.
Agora que seu segredo está funcionando, instale o plug-in de armazenamento de bloco da DigitalOcean:
- kubectl apply -f https://raw.githubusercontent.com/digitalocean/csi-digitalocean/master/deploy/kubernetes/releases/csi-digitalocean-v0.3.0.yaml
Você verá um resultado similar ao seguinte:
Outputstorageclass.storage.k8s.io/do-block-storage created
serviceaccount/csi-attacher created
clusterrole.rbac.authorization.k8s.io/external-attacher-runner created
clusterrolebinding.rbac.authorization.k8s.io/csi-attacher-role created
service/csi-attacher-doplug-in created
statefulset.apps/csi-attacher-doplug-in created
serviceaccount/csi-provisioner created
clusterrole.rbac.authorization.k8s.io/external-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/csi-provisioner-role created
service/csi-provisioner-doplug-in created
statefulset.apps/csi-provisioner-doplug-in created
serviceaccount/csi-doplug-in created
clusterrole.rbac.authorization.k8s.io/csi-doplug-in created
clusterrolebinding.rbac.authorization.k8s.io/csi-doplug-in created
daemonset.apps/csi-doplug-in created
Agora que você instalou o plug-in de armazenamento da DigitalOcean, é possível criar o armazenamento de bloco para reter seu código de aplicativo e arquivos de configuração.
Com seu segredo funcionando e o plug-in de armazenamento de bloco instalado, você está pronto para criar seu Volume Persistente. Um Volume Persistente, ou PV, é o armazenamento de bloco de um tamanho específico que vive independentemente do ciclo de vida de um pod. Usar um Volume Persistente permitirá que você gerencie ou atualize seus pods sem se preocupar em perder o código do seu aplicativo. Um Volume Persistente é acessado usando um PersistentVolumeClaim
, ou PVC, que monta o PV no caminho necessário.
Abra um arquivo chamado code_volume.yaml
com seu editor:
- nano code_volume.yaml
Nomeie o code
do PVC adicionando os seguintes parâmetros e valores ao seu arquivo:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: code
A spec
para um PVC contém os seguintes itens:
accessModes
que variam com o caso de uso. Esses são:
ReadWriteOnce
— monta o volume como leitura-escrita por um único nóReadOnlyMany
— monta o volume como apenas leitura por muitos nósReadWriteMany
— monta o volume como leitura-escrita por muitos nósresources
— o espaço de armazenamento que você precisaO armazenamento de bloco da DigitalOcean é montado apenas em um único nó, então você irá definir o accessModes
para ReadWriteOnce
. Este tutorial irá guiá-lo na adição de uma pequena quantidade de códigos do aplicativo, então 1GB de uso será o bastante neste caso. Se você planeja armazenar uma maior quantidade de código ou dados no volume, é possível modificar o parâmetro storage
para satisfazer seus requisitos. Você pode aumentar a quantidade de armazenamento após a criação do volume, mas a redução do disco não é suportada.
...
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
Em seguida, especifique a classe de armazenamento que o Kubernetes usará para fornecer os volumes. Você usará a classe do-block-storage
criada pelo plug-in de armazenamento de bloco da DigitalOcean.
...
storageClassName: do-block-storage
Seu arquivo code_volume.yaml
se parecerá com isto:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: code
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: do-block-storage
Salve e saia do arquivo.
Crie o code
PersistentVolumeClaim usando o kubectl
:
- kubectl apply -f code_volume.yaml
O resultado a seguir diz que o objeto foi criado com sucesso e você está pronto para montar seu PVC de 1GB como um volume.
Outputpersistentvolumeclaim/code created
Para ver os Volumes Persistentes (PV) disponíveis:
- kubectl get pv
Você verá seu PV listado:
OutputNAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-ca4df10f-ab8c-11e8-b89d-12331aa95b13 1Gi RWO Delete Bound default/code do-block-storage 2m
Os campos acima são uma visão geral do seu arquivo de configuração, exceto para o Reclaim Policy
e Status
. O Reclaim Policy
define o que é feito com o PV após o acesso do PVC for deletado. O Delete
remove o PV do Kubernetes assim como a infraestrutura da DigitalOcean. Você pode aprender mais sobre o Reclaim Policy
e Status
na documentação PV do Kubernetes.
Você criou um Volume Persistente usando o plug-in de armazenamento de bloco da DigitalOcean com sucesso. Agora que seu Volume Persistente está pronto, você criará seus pods usando uma implantação.
Neste passo, você aprenderá como usar uma implantação para criar seu pod PHP-FPM. Implantações fornecem uma maneira uniforme de criar, atualizar e gerenciar pods usando o ReplicaSets. Se uma atualização não funcionar como esperado, uma implantação irá mudar automaticamente seus pods para uma imagem anterior.
A chave da implantação spec.selector
listará os rótulos dos pods que irá gerenciar. Ela também usará a chave template
para criar os pods necessários.
Este passo também irá introduzir o uso dos contêineres de inicialização. Os Init Containers executam um ou mais comandos antes dos contêineres regulares especificados na chave template
do pod. Neste tutorial, seu contêiner de inicialização trará um arquivo de amostra index.php
do GitHub Gist usando o wget
. Este é o conteúdo do arquivo de amostra:
<?php
echo phpinfo();
Para criar sua implantação, abra um novo arquivo chamado php_deployment.yaml
com seu editor:
- nano php_deployment.yaml
Esta implantação irá gerenciar seus pods PHP-FPM. Assim, você irá nomear o objeto de implantação como php
. Os pods pertencem à camada backend, então a implantação será agrupada neste grupo usando o rótulo tier: backend
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: php
labels:
tier: backend
Para a spec
da implantação, serão especificadas quantas cópias deste pod serão criadas usando o parâmetro replicas
. O número de replicas
irá variar dependendo das suas necessidades e recursos disponíveis. Você criará uma réplica neste tutorial:
...
spec:
replicas: 1
Esta implantação irá gerenciar pods que correspondam aos rótulos app: php
e tier: backend
. Sob a chave selector
, adicione:
...
selector:
matchLabels:
app: php
tier: backend
Em seguida, a spec
da implantação exige o template
para a definição de objeto do seu pod. Este modelo definirá as especificações para criação do pod. Primeiro, serão adicionados rótulos que foram especificados para os selectors
de serviço php
e os matchLabels
da implantação. Adicione app: php
e tier: backend
em template.metadata.labels
:
...
template:
metadata:
labels:
app: php
tier: backend
Um pod pode ter vários contêineres e volumes, mas cada um precisará de um nome. Você pode montar volumes de modo seletivo para um contêiner ao especificar um caminho de montagem para cada volume.
Primeiro, especifique os volumes que seus contêineres irão acessar. Você criou um PVC chamado code
para reter seu código do aplicativo, então chame este volume de code
também. Em spec.template.spec.volumes
, adicione o seguinte:
...
spec:
volumes:
- name: code
persistentVolumeClaim:
claimName: code
Em seguida, especifique o contêiner que você quer executar neste pod. Você pode encontrar uma variedade de imagens na loja do Docker, mas neste tutorial você usará a imagem php:7-fpm
.
Em spec.template.spec.containers
, adicione o seguinte:
...
containers:
- name: php
image: php:7-fpm
Em seguida, serão montados os volumes aos quais o contêiner exige acesso. Este contêiner executará seu código PHP, então ele precisará de acesso ao volume code
. Você também usará o mountPath
para especificar /code
como o ponto de montagem.
Em spec.template.spec.containers.volumeMounts
, adicione:
...
volumeMounts:
- name: code
mountPath: /code
Agora que você montou seu volume, será necessário colocar seu código do aplicativo no volume. Você pode ter usado anteriormente o FTP/SFTP ou clonado o código em uma conexão via protocolo SSH para fazer isso, mas este passo irá mostrar como copiar o código usando um contêiner de inicialização.
Dependendo da complexidade do seu processo de configuração, você pode usar um único initContainer
para executar um script que constrói seu aplicativo, ou usar um initContainer
por comando. Certifique-se de que os volumes são montados no initContainer
.
Neste tutorial, será usado um único contêiner de inicialização com o busybox
para baixar o código. O busybox
é uma pequena imagem que contém o utilitário wget
que você usará para fazer isso.
Em spec.template.spec
, adicione seu initContainer
e especifique a imagem busybox
:
...
initContainers:
- name: install
image: busybox
Seu contêiner de inicialização precisará de acesso ao volume code
para que ele possa baixar o código naquele local. Em spec.template.spec.initContainers
, monte o volume code
no caminho /code
:
...
volumeMounts:
- name: code
mountPath: /code
Cada contêiner de inicialização precisa executar um command
. Seu contêiner de inicialização usará o wget
para baixar o código do Github para o diretório de trabalho /code
. A opção -O
dá ao arquivo baixado um nome e você irá nomear este arquivo index.php
.
Nota: Certifique-se de confiar no código que você está fazendo o pull. Antes de fazer o pull dele para seu servidor, inspecione o código fonte para garantir que você se sinta confortável com o que o código faz.
Sob o contêiner install
em spec.template.spec.initContainers
, adicione estas linhas:
...
command:
- wget
- "-O"
- "/code/index.php"
- https://raw.githubusercontent.com/do-community/php-kubernetes/master/index.php
Seu arquivo final php_deployment.yaml
se parecerá com isso:
apiVersion: apps/v1
kind: Deployment
metadata:
name: php
labels:
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: php
tier: backend
template:
metadata:
labels:
app: php
tier: backend
spec:
volumes:
- name: code
persistentVolumeClaim:
claimName: code
containers:
- name: php
image: php:7-fpm
volumeMounts:
- name: code
mountPath: /code
initContainers:
- name: install
image: busybox
volumeMounts:
- name: code
mountPath: /code
command:
- wget
- "-O"
- "/code/index.php"
- https://raw.githubusercontent.com/do-community/php-kubernetes/master/index.php
Salve o arquivo e saia do editor.
Crie a implantação PHP-FPM com o kubectl
:
- kubectl apply -f php_deployment.yaml
Você verá o seguinte resultado após a criação da implantação:
Outputdeployment.apps/php created
Para resumir, essa implantação irá começar baixando as imagens especificadas. Então, solicitará o PersistentVolume
do seu PersistentVolumeClaim
e executará seus initContainers
em série. Assim que terminar, os contêiners executarão e montarão os volumes
no ponto de montagem especificado. Assim que todos esses passos estiverem completos, seu pod estará em funcionamento.
Você pode ver sua implantação executando:
- kubectl get deployments
Você verá o resultado:
OutputNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
php 1 1 1 0 19s
Este resultado pode ajudar você a compreender o estado atual da implantação. Uma Deployment
é um dos controladores que mantêm um estado desejado. O template
que você criou especifica que o estado DESIRED
terá 1 replicas
do pod chamado php
. O campo CURRENT
indica quantas réplicas estão funcionando, e isso deve corresponder ao estado DESIRED
. Você pode ler sobre os campos restantes na documentação de implantações do Kubernetes.
Você pode ver os pods que essa implantação iniciou com o seguinte comando:
- kubectl get pods
O resultado deste comando varia dependendo de quanto tempo passou desde a criação da implantação. Se você executá-lo pouco após a criação, o resultado se parecerá com isso:
OutputNAME READY STATUS RESTARTS AGE
php-86d59fd666-bf8zd 0/1 Init:0/1 0 9s
As colunas representam as seguintes informações:
Ready
: o número de replicas
que está funcionando neste pod.Status
: o status do pod. Init
indica que os contêineres de inicialização estão em funcionamento. Neste resultado, 0 de 1 contêineres de inicialização terminaram de executar.Restarts
: quantas vezes este processo foi reiniciado para iniciar o pod. Este número aumentará se algum dos seus contêineres de inicialização falhar. A implantação irá reiniciar até chegar no estado desejado.Dependendo da complexidade dos seus scripts de inicialização, pode levar alguns minutos para o status mudar para podInitializing
:
OutputNAME READY STATUS RESTARTS AGE
php-86d59fd666-lkwgn 0/1 podInitializing 0 39s
Isso significa que os contêineres de inicialização finalizaram e os contêineres estão inicializando. Se você executar o comando quando todos os contêineres estiverem funcionando, verá a mudança de status do pod para Running
.
OutputNAME READY STATUS RESTARTS AGE
php-86d59fd666-lkwgn 1/1 Running 0 1m
Agora, seu pod está funcionando com sucesso. Se seu pod não iniciar, você pode depurá-lo com os comandos a seguir:
- kubectl describe pods pod-name
- kubectl logs pod-name
- kubectl logs pod-name container-name
Seu código do aplicativo está montado e o serviço PHP-FPM está agora pronto para lidar com conexões. Agora, você pode criar sua implantação do Nginx.
Neste passo, será usado um ConfigMap para configurar o Nginx. Um ConfigMap retém suas configurações em um formato de valor de chave que você pode referenciar em outras definições de objeto do Kubernetes. Esta abordagem dará a você a flexibilidade de reutilização ou de alternar a imagem com uma versão diferente do Nginx caso necessário. Ao atualizar o ConfigMap, serão replicadas automaticamente as alterações em qualquer pod montado nele.
Crie um arquivo nginx_configMap.yaml
para seu ConfigMap com seu editor:
- nano nginx_configMap.yaml
Nomeie o ConfigMap nginx-config
e agrupe-o no micro serviço tier: backend
:
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
labels:
tier: backend
Em seguida, adicione o data
para o ConfigMap. Nomeie a chave config
e adicione o conteúdo do seu arquivo de configuração do Nginx como o valor. Você pode usar a configuração exemplo do Nginx deste tutorial.
Como o Kubernetes pode rotear pedidos para o host apropriado para um serviço, você pode digitar o nome do seu serviço PHP-FPM no parâmetro fastcgi_pass
ao invés de seu endereço IP. Adicione o seguinte ao seu arquivo nginx_configMap.yaml
:
...
data:
config : |
server {
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root ^/code^;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
Seu arquivo nginx_configMap.yaml
se parecerá com isto:
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
labels:
tier: backend
data:
config : |
server {
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /code;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
Salve o arquivo e saia do editor.
Crie o ConfigMap:
- kubectl apply -f nginx_configMap.yaml
Você verá o seguinte resultado:
Outputconfigmap/nginx-config created
Você terminou de criar seu ConfigMap e agora pode construir sua implantação do Nginx.
Inicie abrindo um novo arquivo nginx_deployment.yaml
no editor:
- nano nginx_deployment.yaml
Nomeie a implantação nginx
e adicione o rótulo tier: backend
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
tier: backend
Especifique que você quer uma replicas
na spec
da implantação. Esta implantação irá gerenciar pods com rótulos app: nginx
e tier: backend
. Adicione os parâmetros e valores a seguir:
...
spec:
replicas: 1
selector:
matchLabels:
app: nginx
tier: backend
Em seguida, adicione o pod template
. Você precisa usar os mesmos rótulos que adicionou para o selector.matchLabels
da implantação. Adicione o seguinte:
...
template:
metadata:
labels:
app: nginx
tier: backend
Forneça ao Nginx acesso ao code
PVC que criou mais cedo. Em spec.template.spec.volumes
, adicione:
...
spec:
volumes:
- name: code
persistentVolumeClaim:
claimName: code
Os pods podem montar um ConfigMap como um volume. Especificar um nome de arquivo e chave criará um arquivo com seu valor como conteúdo. Para usar o ConfigMap, defina path
como nome do arquivo que irá reter o conteúdo da key
. Você quer criar um arquivo site.conf
a partir da config
da chave. Em spec.template.spec.volumes
, adicione o seguinte:
...
- name: config
configMap:
name: nginx-config
items:
- key: config
path: site.conf
Aviso: Se um arquivo não for especificado, o conteúdo da key
substituirá o mountPath
do volume. Isso significa que se um caminho não for especificado explicitamente, você perderá todo o conteúdo na pasta de destino.
Em seguida, você irá especificar a imagem da qual irá criar seu pod. Este tutorial usará a imagem nginx:1.7.9
por motivos de estabilidade, mas você pode encontrar outras imagens do Nginx na loja do Docker. Além disso, torne o Nginx disponível na porta 80. Em spec.template.spec
adicione:
...
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
O Nginx e o PHP-FPM precisam acessar o arquivo no mesmo caminho, então monte o volume code
em /code
:
...
volumeMounts:
- name: code
mountPath: /code
A imagem nginx:1.7.9
irá carregar automaticamente quaisquer arquivos de configuração no diretório /etc/nginx/conf.d
. Ao montar o volume config
neste diretório, será criado o arquivo /etc/nginx/conf.d/site.conf
. Em volumeMounts
, adicione o seguinte:
...
- name: config
mountPath: /etc/nginx/conf.d
Seu arquivo nginx_deployment.yaml
se parecerá com isto:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: nginx
tier: backend
template:
metadata:
labels:
app: nginx
tier: backend
spec:
volumes:
- name: code
persistentVolumeClaim:
claimName: code
- name: config
configMap:
name: nginx-config
items:
- key: config
path: site.conf
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
volumeMounts:
- name: code
mountPath: /code
- name: config
mountPath: /etc/nginx/conf.d
Salve o arquivo e saia do editor.
Crie a implantação Nginx:
- kubectl apply -f nginx_deployment.yaml
O resultado a seguir indica que sua implantação foi criada:
Outputdeployment.apps/nginx created
Liste suas implantações com este comando:
- kubectl get deployments
Você verá as implantações do Nginx e do PHP-FPM:
OutputNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx 1 1 1 0 16s
php 1 1 1 1 7m
Liste os pods gerenciados por ambas as implantações:
- kubectl get pods
Você verá os pods que estão em funcionamento:
OutputNAME READY STATUS RESTARTS AGE
nginx-7bf5476b6f-zppml 1/1 Running 0 32s
php-86d59fd666-lkwgn 1/1 Running 0 7m
Agora que todos os objetos do Kubernetes estão ativos, é possível visitar o serviço Nginx no seu navegador.
Liste os serviços em execução:
- kubectl get services -o wide
Obtenha o IP externo para seu serviço Nginx:
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 39m <none>
nginx ClusterIP 10.102.160.47 your_public_ip 80/TCP 27m app=nginx,tier=backend
php ClusterIP 10.100.59.238 <none> 9000/TCP 34m app=php,tier=backend
No seu navegador, visite seu servidor digitando http://your_public_ip
. Você verá o resultado do php_info()
e terá confirmado que seus serviços do Kubernetes estão funcionando.
Neste guia, você transformou em contêiner os serviços PHP-FPM e Nginx para gerenciá-los independentemente. Esta abordagem não só irá melhorar a escalabilidade do seu projeto conforme for crescendo, como também permitirá que você use recursos de maneira eficiente. Você também armazenou seu código do aplicativo em um volume para que você possa atualizar facilmente seus serviços no futuro.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!