O desenvolvimento de aplicativos geralmente não fica estagnado. Como parte do ciclo de vida do desenvolvimento de software, você constrói novas funcionalidades, corrige bugs e implanta as mudanças no cluster Kubernetes como parte do processo de release. Na prática, enviamos uma nova imagem para o Docker registry encapsulando as mudanças realizadas para que elas possam ser executas em um container. Por padrão, o Deployment faz um roll out(lança) de uma nova imagem de container usando a estratégia zero-downtime(sem interrupções) atualizando os Pods um a um. A figura abaixo mostra o processo de rolling update em um Deployment que controla duas réplicas da versão 1.2.3 para 2.0.0.

Figure 6-5. Rolling update of Pods managed by a Deployment

Figure 6-5. Rolling update of Pods managed by a Deployment

Todo Deployment mantém um registro com o histórico de rollouts(process of introducing a new feature). Dentro do histórico, uma nova versão de um rollout é chamada de revision. Antes de experimentar o rollout de uma nova revision na prática, vamos inspecionar o estado inicial do Deployment my-deploy. O comando abaixo mostra a revision 1, que representa a criação do Deployment com as suas definições.

# Listando revisions
$ kubectl rollout history deployment my-deploy
	deployment.apps/my-deploy 
	REVISION  CHANGE-CAUSE
	1         <none>

# Detalhando última revision
$ kubectl rollout history deployments my-deploy --revision=1
	deployment.apps/my-deploy with revision #1
	Pod Template:
	  Labels:       app=my-deploy
	        pod-template-hash=79fbb965cd
	  Containers:
	   nginx:
	    Image:      nginx:1.14.2

No próximo passo, nós vamos atualizar a imagem do container usado pelo Deployment, de nginx:1.14.2 para nginx:1.19.2. Para fazer isso, edite o live object.

# Para definir o VIM como editor padrão de live objects
# execute o seguinte comando: export EDITOR=vim
#
$ kubectl edit deployments.apps my-deploy
	# Please edit the object below. Lines beginning with a '#' will be ignored,
	# and an empty file will abort the edit.
	# If an error occurs while saving this file will be
	# reopened with the relevant failures.
	#
	apiVersion: apps/v1
	kind: Deployment
	metadata:
		(...)
	  labels:
	    app: my-deploy
	    section: 06-pod-design
	  name: my-deploy
	  namespace: develop
		(...)
	(...)
		(...)
	    spec:
	      containers:
	      **- image: nginx:1.14.2  ### Altere a Versão do NGINX para 1.19.2###**
	        imagePullPolicy: IfNotPresent
	        name: nginx

**deployment.apps/my-deploy edited**

Agora o rollout history mostra a revision 1 e revision 2. Quando mudamos o Pod template de um Deployment —por exemplo, atualizando a imagem— um novo ReplicaSet é criado. O Deployment migrará gradualmente os Pods do antigo ReplicaSet para o novo ReplicaSet.

# Listando revisions
$ kubectl rollout history deployment my-deploy        
	deployment.apps/my-deploy 
	REVISION  CHANGE-CAUSE
	1         <none>
	2         <none>

# Detalhando última revision
$ kubectl rollout history deployments my-deploy --revision=2
	deployment.apps/my-deploy with revision #2
	Pod Template:
	  Labels:       app=my-deploy
	        pod-template-hash=79d96d9545
	  Containers:
	   nginx:
	    Image:      nginx:1.19.2

Além da edição do live object também podemos utilizar o comando set image para atualizar a imagem do container utilizado no Deployment.

# kubectl set image deployment <deployment-name> <container-name>=<image-name>
$ kubectl set image deployment my-deploy nginx=nginx:1.20.2
	deployment.apps/my-deploy image updated

Novamente o rollout history é atualizado, agora ele também exibe a revision 3.

# Listando revisions
$ kubectl rollout history deployment my-deploy             
	deployment.apps/my-deploy 
	REVISION  CHANGE-CAUSE
	1         <none>
	2         <none>
	3         <none>

# Detalhando última revision
$ kubectl rollout history deployments my-deploy --revision=3
	deployment.apps/my-deploy with revision #3
	Pod Template:
	  Labels:       app=my-deploy
	        pod-template-hash=58ddd7b585
	  Containers:
	   nginx:
	    Image:      nginx:1.20.2

<aside> 💡 Por padrão, o Deployment persiste no máximo 10 revisions no seu histórico. Podemos alterar este limite definindo valor do spec.revisionHistoryLimit

</aside>

A estratégia rolling update garante que a aplicação sempre estará disponível para os usuários finais. Esta abordagem implica que duas versões da mesma aplicação estarão disponíveis durante o processo de atualização. É possível alterar a estratégia de update de um Deployment fornecendo um valor diferente para o atributo strategy.type. Por exemplo, o valor Recreate mata todos os Pods e então recria novos Pods com a última revision, causando um potencial downtime para os consumidores. Outras estratégia como blue-green ou canary deployments podem ser configuradas embora estejam além do escopo deste livro.

Documentação Kubernetes

Deployment

Referência de campos para objeto Deployment.

Blue/Green Deployments in Kubernetes: A Quick Guide