-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDocker_dia7_K8S
540 lines (408 loc) · 26.2 KB
/
Docker_dia7_K8S
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
O que iremos ver hoje?
Hoje é dia de falar sobre dois resources muito importantes para o Kubernetes, o StatefulSet e o Service. Vamos mostrar como criar e administrar StatefulSets para que você possa criar aplicações que precisam manter a identidade do Pod e persistir dados em volumes locais. Caos bem comuns de uso de StatefulSets são bancos de dados, sistemas de mensageria e sistemas de arquivos distribuídos.
Outra peça super importante que iremos falar hoje é sobre o Service. O Service é um objeto que permite que você expor uma aplicação para o mundo externo. Ele é responsável por fazer o balanceamento de carga entre os Pods que estão sendo expostos e também por fazer a resolução de nomes DNS para os Pods que estão sendo expostos. Temos diversos tipos de Services e iremos falar sobre eles hoje.
Então esteja preparado para uma viajem muito interessante sobre esses dois recursos que são muito importantes para o Kubernetes e para o dia a dia de uma pessoa que trabalha com ele.
============================================
O que é um StatefulSet?
Os StatefulSets são uma funcionalidade do Kubernetes que gerencia o deployment e o scaling de um conjunto de Pods, fornecendo garantias sobre a ordem de deployment e a singularidade desses Pods.
Diferente dos Deployments e Replicasets que são considerados stateless (sem estado), os StatefulSets são utilizados quando você precisa de mais garantias sobre o deployment e scaling. Eles garantem que os nomes e endereços dos Pods sejam consistentes e estáveis ao longo do tempo.
Quando usar StatefulSets?
Os StatefulSets são úteis para aplicações que necessitam de um ou mais dos seguintes:
Identidade de rede estável e única.
Armazenamento persistente estável.
Ordem de deployment e scaling garantida.
Ordem de rolling updates e rollbacks garantida.
Algumas aplicações que se encaixam nesses requisitos são bancos de dados, sistemas de filas e quaisquer aplicativos que necessitam de persistência de dados ou identidade de rede estável.
E como ele funciona?
Os StatefulSets funcionam criando uma série de Pods replicados. Cada réplica é uma instância da mesma aplicação que é criada a partir do mesmo spec, mas pode ser diferenciada por seu índice e hostname.
Ao contrário dos Deployments e Replicasets, onde as réplicas são intercambiáveis, cada Pod em um StatefulSet tem um índice persistente e um hostname que se vinculam a sua identidade.
Por exemplo, se um StatefulSet tiver um nome giropops e um spec com três réplicas, ele criará três Pods: giropops-0, giropops-1, giropops-2. A ordem dos índices é garantida. O Pod giropops-1 não será iniciado até que o Pod giropops-0 esteja disponível e pronto.
A mesma garantia de ordem é aplicada ao scaling e aos updates.
O StatefulSet e os volumes persistentes
Um aspecto chave dos StatefulSets é a integração com Volumes Persistentes. Quando um Pod é recriado, ele se reconecta ao mesmo Volume Persistente, garantindo a persistência dos dados entre as recriações dos Pods.
Por padrão, o Kubernetes cria um PersistentVolume para cada Pod em um StatefulSet, que é então vinculado a esse Pod para a vida útil do StatefulSet.
Isso é útil para aplicações que precisam de um armazenamento persistente e estável, como bancos de dados.
O StatefulSet e o Headless Service
Para entender a relação entre o StatefulSet e o Headless Service, é preciso primeiro entender o que é um Headless Service.
No Kubernetes, um serviço é uma abstração que define um conjunto lógico de Pods e uma maneira de acessá-los. Normalmente, um serviço tem um IP e encaminha o tráfego para os Pods. No entanto, um Headless Service é um tipo especial de serviço que não tem um IP próprio. Em vez disso, ele retorna diretamente os IPs dos Pods que estão associados a ele.
Agora, o que isso tem a ver com os StatefulSets?
Os StatefulSets e os Headless Services geralmente trabalham juntos no gerenciamento de aplicações stateful. O Headless Service é responsável por permitir a comunicação de rede entre os Pods em um StatefulSet, enquanto o ` gerencia o deployment e o scaling desses Pods.
Aqui está como eles funcionam juntos:
Quando um StatefulSet é criado, ele geralmente é associado a um Headless Service. Ele é usado para controlar o domínio DNS dos Pods criados pelo StatefulSet. Cada Pod obtém um nome de host DNS que segue o formato: <pod-name>.<service-name>.<namespace>.svc.cluster.local. Isso permite que cada Pod seja alcançado individualmente.
Por exemplo, se você tiver um StatefulSet chamado giropops com três réplicas e um Headless Service chamado nginx, os Pods criados serão giropops-0, giropops-1, giropops-2 e eles terão os seguintes endereços de host DNS: giropops-0.nginx.default.svc.cluster.local, giropops-1.nginx.default.svc.cluster.local, giropops-2.nginx.default.svc.cluster.local.
Essa combinação de StatefulSets com Headless Services permite que aplicações stateful, como bancos de dados, tenham uma identidade de rede estável e previsível, facilitando a comunicação entre diferentes instâncias da mesma aplicação.
Bem, agora que você já entendeu como isso funciona, eu acho que já podemos dar os primeiros passos com o StatefulSet.
=======================================================
Vamos criar o nosso primeiro StatefulSet via yaml é claro, salvamos ele com o nome "statefulset-nginx.yaml"
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx
spec:
serviceName: "nginx"
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: http
volumeMounts:
- name: nginx-persistent-storage
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: nginx-persistent-storage
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
Após criar o mesmo vamos executar ele com o comando
kubectl apply -f statefulset-nginx.yaml
Após isso ele foi criando um pods de cada vez, seguinte o padrão statefulset
root@obi-System-Product-Name:~/k8s/day06# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-0 1/1 Running 0 45s
nginx-1 1/1 Running 0 31s
nginx-2 1/1 Running 0 17s
também foi criado os PVC
root@obi-System-Product-Name:~/k8s/day06# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
nginx-persistent-storage-nginx-0 Bound pvc-62397f5e-ebb8-4d83-86ee-1ad3e2e41440 1Gi RWO standard 2m1s
nginx-persistent-storage-nginx-1 Bound pvc-098768be-d029-418e-be91-c7f966d53159 1Gi RWO standard 107s
nginx-persistent-storage-nginx-2 Bound pvc-62aa5510-f671-4f57-b204-00dd4f9da811 1Gi RWO standard 93s
E os PV
root@obi-System-Product-Name:~/k8s/day06# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-098768be-d029-418e-be91-c7f966d53159 1Gi RWO Delete Bound default/nginx-persistent-storage-nginx-1 standard 112s
pvc-62397f5e-ebb8-4d83-86ee-1ad3e2e41440 1Gi RWO Delete Bound default/nginx-persistent-storage-nginx-0 standard 2m7s
pvc-62aa5510-f671-4f57-b204-00dd4f9da811 1Gi RWO Delete Bound default/nginx-persistent-storage-nginx-2 standard 97s
root@obi-System-Product-Name:~/k8s/day06# kubectl get statefulset
NAME READY AGE
nginx 3/3 2m37s
kubectl describe statefulset nginx
Name: nginx
Namespace: default
CreationTimestamp: Tue, 13 Aug 2024 21:32:34 -0300
Selector: app=nginx
Labels: <none>
Annotations: <none>
Replicas: 3 desired | 3 total
Update Strategy: RollingUpdate
Partition: 0
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts:
/usr/share/nginx/html from nginx-persistent-storage (rw)
Volumes: <none>
Node-Selectors: <none>
Tolerations: <none>
Volume Claims:
Name: nginx-persistent-storage
StorageClass:
Labels: <none>
Annotations: <none>
Capacity: 1Gi
Access Modes: [ReadWriteOnce]
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 7m35s statefulset-controller create Claim nginx-persistent-storage-nginx-0 Pod nginx-0 in StatefulSet nginx success
Normal SuccessfulCreate 7m35s statefulset-controller create Pod nginx-0 in StatefulSet nginx successful
Normal SuccessfulCreate 7m21s statefulset-controller create Claim nginx-persistent-storage-nginx-1 Pod nginx-1 in StatefulSet nginx success
Normal SuccessfulCreate 7m21s statefulset-controller create Pod nginx-1 in StatefulSet nginx successful
Normal SuccessfulCreate 7m7s statefulset-controller create Claim nginx-persistent-storage-nginx-2 Pod nginx-2 in StatefulSet nginx success
Normal SuccessfulCreate 7m6s statefulset-controller create Pod nginx-2 in StatefulSet nginx successful
root@obi-System-Product-Name:~/k8s/day06#
Agora vamos criar o service para comunicação entre a galera, headless, e claro via yaml, com o nome "nginx-headless-svc.yaml"
apiVersion: v1
kind: Service
metadata:
name: nginx-headless
labels:
apps: ngnix
spec:
ports:
- port: 80
name: http
clusterIP: None
selector:
app: nginx
kubectl apply -f nginx-headless-svc.yaml
root@obi-System-Product-Name:~/k8s/day06# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 24h
nginx-headless ClusterIP None <none> 80/TCP 16s
root@obi-System-Product-Name:~/k8s/day06# vim nginx-headless-svc.yaml
root@obi-System-Product-Name:~/k8s/day06#
Apos isso acesso um dos pods o nginx-0 criado e alteramos e criamos o index.html dentro da pasta /usr/share/nginx/html
kubectl exec -ti nginx-0 -- bash
echo "giro-0" > index.html
Saímos do 0 e acessamos o 1
kubectl exec -ti nginx-1 -- bash
Dentro deles demos um curl no index do 0
curl nginx-0.nginx.default.svc.cluster.local (Nome do pod, nome do serviço, namespace default, serviço)
root@nginx-1:/# curl nginx-0.nginx.default.svc.cluster.local
giro-0
=================================================================
Hj vamos falar de sevices.
Services
Os Services no Kubernetes são uma abstração que define um conjunto lógico de Pods e uma política para acessá-los. Eles permitem que você exponha uma ou mais Pods para serem acessados por outros Pods, independentemente de onde eles estejam em execução no cluster.
Os Services são definidos usando a API do Kubernetes, normalmente através de um arquivo de manifesto YAML.
Tipos de Services
Existem quatro tipos principais de Services:
ClusterIP (padrão): Expõe o Service em um IP interno no cluster. Este tipo torna o Service acessível apenas dentro do cluster.
NodePort: Expõe o Service na mesma porta de cada Node selecionado no cluster usando NAT. Torna o Service acessível de fora do cluster usando :.
LoadBalancer: Cria um balanceador de carga externo no ambiente de nuvem atual (se suportado) e atribui um IP fixo, externo ao cluster, ao Service.
ExternalName: Mapeia o Service para o conteúdo do campo externalName (por exemplo, foo.bar.example.com), retornando um registro CNAME com seu valor.
Como os Services funcionam
Os Services no Kubernetes fornecem uma abstração que define um conjunto lógico de Pods e uma política para acessá-los. Os conjuntos de Pods são determinados por meio de seletores de rótulo (Label Selectors). Embora cada Pod tenha um endereço IP único, esses IPs não são expostos fora do cluster sem um serviço.
Sempre é bom reforçar a importância dos Labels no Kubernetes, pois eles são a base para a maioria das operações no Kubernetes, então cuide com carinho dos seus Labels.
Os Services e os Endpoints
Como eu já disse, os Services no Kubernetes representam um conjunto estável de Pods que fornecem determinada funcionalidade. A principal característica dos Services é que eles mantêm um endereço IP estável e uma porta de serviço que permanecem constantes ao longo do tempo, mesmo que os Pods subjacentes sejam substituídos.
Para implementar essa abstração, o Kubernetes usa uma outra abstração chamada Endpoint. Quando um Service é criado, o Kubernetes também cria um objeto Endpoint com o mesmo nome. Esse objeto Endpoint rastreia os IPs e as portas dos Pods que correspondem aos critérios de seleção do Service.
Por exemplo, quando você cria um Service automaticamente é criado os EndPoints que representam os Pods que estão sendo expostos pelo Service.
Vamos começar.
Vamos criar um deploymento simples
kubectl create deployment nginx --image nginx --port 80
root@obi-System-Product-Name:~/k8s/day06# kubectl expose deployment nginx
service/nginx exposed
root@obi-System-Product-Name:~/k8s/day06# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 19m
nginx ClusterIP 10.96.151.144 <none> 80/TCP 8s
root@obi-System-Product-Name:~/k8s/day06#
Vamos testar
kubectl run -it --rm debug --image busybox --restart Never -- sh
Dentro do buysbox vamos testar
/ # wget -O- 10.96.151.144
Connecting to 10.96.151.144 (10.96.151.144:80)
writing to stdout
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
- 100% |****************************************************************| 615 0:00:00 ETA
written to stdout
/ #
Após esse teste vamos deletar o service criado
kubeclt delete svc nignx
Agora vamos criar um service no modo NodePort
root@obi-System-Product-Name:~/k8s/day06# kubectl expose deployment nginx --type NodePort
service/nginx exposed
root@obi-System-Product-Name:~/k8s/day06# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 25m
nginx NodePort 10.96.157.86 <none> 80:30023/TCP 6s
root@obi-System-Product-Name:~/k8s/day06#
===========================================
Yaml para criar serviços
LoadBalancer
apiVersion: v1
kind: Service
metadata:
name: nginx-loadbalancer
labels:
app: nginx
enc: env
spec:
selector:
app: nginx
ports:
- port: 80
name: http
targetPort: 80
type: LoadBalancer
NodePort
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
labels:
app: nginx
enc: env
spec:
selector:
app: nginx
ports:
- port: 80
name: http
targetPort: 80
nodePort: 32000
type: NodePort
ClusterIp (Padrão)
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx-deployment01
name: nginx-deployment01
spec:
replicas: 3
selector:
matchLabels:
app: nginx-deployment01
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nginx-deployment01
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
name: http
========================================================
Criando um Service
Para criar um Service precisamos utilizar o comando:
kubectl expose deployment MEU_DEPLOYMENT --port=80 --type=NodePort
Perceba que no comando acima estamos criando um Service do tipo NodePort, ou seja, o Service será acessível de fora do cluster usando :.
Estamos ainda passando o parâmetro --port=80 para que o Service seja exposto na porta 80.
Ahhh, e não podemos esquecer de passar o nome do Deployment que queremos expor, no caso acima, estamos expondo o Deployment com o nome MEU_DEPLOYMENT. Estamos criando um Service para um Deployment, mas também podemos criar um Service para um Pod, um ReplicaSet, um ReplicationController ou até mesmo para outro Service.
Sim, para outro Service!
A criação de um serviço baseado em outro serviço é menos comum, mas existem algumas situações em que isso pode ser útil.
Um bom exemplo seria quando você quer mudar temporariamente o tipo de serviço de um ClusterIP para um NodePort ou LoadBalancer para fins de troubleshooting ou manutenção, sem alterar a configuração do serviço original. Nesse caso, você poderia criar um novo serviço que expõe o serviço ClusterIP, realizar suas tarefas e, em seguida, excluir o novo serviço, mantendo a configuração original intacta.
Outro exemplo é quando você quer expor o mesmo aplicativo em diferentes contextos, com diferentes políticas de acesso. Por exemplo, você pode ter um serviço ClusterIP para comunicação interna entre microserviços, um serviço NodePort para acesso a partir da rede interna de sua organização, e um serviço LoadBalancer para acesso a partir da internet. Nesse caso, todos os três serviços poderiam apontar para o mesmo conjunto de Pods, mas cada um deles forneceria um caminho de acesso diferente, com diferentes políticas de segurança e controle de acesso.
No entanto, esses são casos de uso bastante específicos. Na maioria dos cenários, você criaria serviços diretamente para expor Deployments, StatefulSets ou Pods.
Vamos criar alguns Services para que você entenda melhor como eles funcionam e no final vamos para um exemplo mais completo utilizando como Deployment o Giropops-Senhas!
ClusterIP
Para criar um serviço ClusterIP via kubectl, você pode usar o comando kubectl expose conforme mostrado abaixo:
kubectl expose deployment meu-deployment --port=80 --target-port=8080
Este comando criará um serviço ClusterIP que expõe o meu-deployment na porta 80, encaminhando o tráfego para a porta 8080 dos Pods deste deployment.
Para criar um serviço ClusterIP via YAML, você pode usar um arquivo como este:
apiVersion: v1
kind: Service # Tipo do objeto, no caso, um Service
metadata:
name: meu-service
spec:
selector: # Seleciona os Pods que serão expostos pelo Service
app: meu-app # Neste caso, os Pods com o label app=meu-app
ports:
- protocol: TCP
port: 80 # Porta do Service
targetPort: 8080 # Porta dos Pods
Este arquivo YAML irá criar um serviço que corresponde aos Pods com o label app=meu-app, e encaminha o tráfego da porta 80 do serviço para a porta 8080 dos Pods. Perceba que estamos usando o selector para definir quais Pods serão expostos pelo Service.
Como não especificamos o campo type, o Kubernetes irá criar um Service do tipo ClusterIP por padrão.
Simples demais, não?
NodePort
Para criar um serviço NodePort via CLI, você pode usar o comando kubectl expose com a opção --type=NodePort. Por exemplo:
kubectl expose deployment meu-deployment --type=NodePort --port=80 --target-port=8080
Já para criar um serviço NodePort via YAML, você pode usar um arquivo como este:
apiVersion: v1
kind: Service
metadata:
name: meu-service
spec:
type: NodePort # Tipo do Service
selector:
app: meu-app
ports:
- protocol: TCP
port: 80 # Porta do Service, que será mapeada para a porta 8080 do Pod
targetPort: 8080 # Porta dos Pods
nodePort: 30080 # Porta do Node, que será mapeada para a porta 80 do Service
Aqui estamos especificando o campo type como NodePort, e também estamos especificando o campo nodePort, que define a porta do Node que será mapeada para a porta 80 do Service. Vale lembrar que a porta do Node deve estar entre 30000 e 32767, e quando não especificamos o campo nodePort, o Kubernetes irá escolher uma porta aleatória dentro deste range. :)
LoadBalancer
O Service do tipo LoadBalancer é uma das formas mais comuns de expor um serviço ao tráfego da internet no Kubernetes. Ele provisiona automaticamente um balanceador de carga do provedor de nuvem onde seu cluster Kubernetes está rodando, se houver algum disponível.
Para criar um serviço LoadBalancer via CLI, você pode usar o comando kubectl expose com a opção --type=LoadBalancer.
kubectl expose deployment meu-deployment --type=LoadBalancer --port=80 --target-port=8080
Caso queira criar um serviço LoadBalancer via YAML, você pode usar um arquivo como este:
apiVersion: v1
kind: Service
metadata:
name: meu-service
spec:
type: LoadBalancer
selector:
app: meu-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
Nada novo aqui, somente o fato que estamos pedindo para o Kubernetes criar um Service do tipo LoadBalancer.
ê deseja expor um serviço a ser acessado externamente por usuários ou sistemas que não estão dentro do seu cluster Kubernetes. Este tipo de serviço pode ser considerado quando:
Provedores de nuvem: Seu cluster Kubernetes está hospedado em um provedor de nuvem que suporta balanceadores de carga, como AWS, GCP, Azure, etc. Nesse caso, quando um serviço do tipo LoadBalancer é criado, um balanceador de carga é automaticamente provisionado no provedor de nuvem.
Tráfego externo: Você precisa que sua aplicação seja acessível fora do cluster. O LoadBalancer expõe uma IP acessível externamente que encaminha o tráfego para os pods do serviço.
É importante lembrar que o uso de LoadBalancers pode ter custos adicionais, pois você está usando recursos adicionais do seu cloud provider. Portanto, é sempre bom verificar os custos associados antes de implementar. ;)
ExternalName
O tipo de serviço ExternalName é um pouco diferente dos outros tipos de serviço. Ele não expõe um conjunto de Pods, mas sim um nome de host externo. Por exemplo, você pode ter um serviço que expõe um banco de dados externo, ou um serviço que expõe um serviço de e-mail externo.
O tipo ExternalName é útil quando você deseja:
Criar um alias para um serviço externo: Suponha que você tenha um banco de dados hospedado fora do seu cluster Kubernetes, mas você deseja que suas aplicações dentro do cluster se refiram a ele pelo mesmo nome, como se estivesse dentro do cluster. Nesse caso, você pode usar um ExternalName para criar um alias para o endereço do banco de dados.
Abstrair serviços dependentes do ambiente: Outro uso comum para ExternalName é quando você tem ambientes diferentes, como produção e desenvolvimento, que possuem serviços externos diferentes. Você pode usar o mesmo nome de serviço em todos os ambientes, mas apontar para diferentes endereços externos.
Infelizmente ele é pouco usado por conta da falta de conhecimento das pessoas, mas com você não será assim, não é mesmo? :)
Vamos criar um exemplo de ExternalName usando o kubectl expose:
kubectl create service externalname meu-service --external-name meu-db.giropops.com.br
Onde estamos passando como parâmetro o nome do serviço, e o endereço externo que queremos expor para o cluster.
Agora, caso você queira criar um ExternalName via YAML, você pode usar um arquivo como este:
apiVersion: v1
kind: Service
metadata:
name: meu-service
spec:
type: ExternalName
externalName: meu-db.giropops.com.br
Aqui estamos especificando o campo type como ExternalName, e também estamos especificando o campo externalName, que define o endereço externo que queremos expor para o cluster, nada de outro mundo. :)
Ahhh, e lembre-se que o ExternalName não tem suporte para selectors ou ports, pois ele não expõe um conjunto de Pods, mas sim um nome de host externo.
E lembre-se parte 2, o ExternalName aceita um nome de host válido de acordo com o DNS (RFC-1123), que pode ser um nome de domínio ou um endereço IP.
Verificando os Services
Agora que já criamos alguns Services, está na hora de aprender como ver os detalhes deles.
Para visualizar os Services em execução no seu cluster Kubernetes na namespace default, você pode usar o comando kubectl get services. Esse comando listará todos os Services, junto com informações básicas como o tipo de serviço, o endereço IP e a porta.
kubectl get services
Caso queira pegar os Services de uma namespace específica, você pode usar o comando kubectl get services -n . Por exemplo:
kubectl get services -n kube-system
Para visualizar os Services em todas as namespaces, você pode usar o comando kubectl get services --all-namespaces ou kubectl get services -A.
kubectl get services -A
Para visualizar os detalhes de um Service específico, você pode usar o comando kubectl describe service, passando o nome do Service como parâmetro. Por exemplo:
kubectl describe service meu-service
Verificando os Endpoints
Os Endpoints são uma parte importante dos Services, pois eles são responsáveis por manter o mapeamento entre o Service e os Pods que ele está expondo.
Sabendo disso, bora aprender como ver os detalhes dos Endpoints.
Primeira coisa, para visualizar os EndPoints de determinado Service, você pode usar o comando abaixo:
kubectl get endpoints meu-service
Para visualizar os EndPoints de todos os Services, você pode usar o comando abaixo:
kubectl get endpoints -A
Agora, para ver os detalhes de um Endpoints específico, é simples como voar, basta usar o comando abaixo:
kubectl describe endpoints meu-service
Removendo um Service
Agora que já vimos muita coisa sobre os Services, vamos aprender como removê-los.
Para remover um Service via CLI, você pode usar o comando kubectl delete service, passando o nome do Service como parâmetro. Por exemplo:
kubectl delete service meu-service
Para remover um Service via YAML, você pode usar o comando kubectl delete, passando o arquivo YAML como parâmetro. Por exemplo:
kubectl delete -f meu-service.yaml