Deployments是在Kubernetes 1.2版本增加的特性,作为对于pod的控制,Deployments实现了声明式的应用发布和升级,保证了应用的高可用性和快速回滚的能力。在Kubernetes 1.8时相关API移至apps/v1beta2,在Kubernetes 1.9中整合至apps/v1,随着环境中的Kubernetes的升级,原有API的废弃导致Deployment的相应yaml文件需要修改,这篇文章以旧版的Prometheus的Deployment的修改为例,介绍Deployments修改需要注意的事项。
本文示例中准备了Kubernetes 1.17的环境,环境的准备方法可参考如下Easyapck下的Ansible一键脚本。
[root@host131 ansible]# kubectl version
Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.0", GitCommit:"70132b0f130acc0bed193d9ba59dd186f0e634cf", GitTreeState:"clean", BuildDate:"2019-12-07T21:20:10Z", GoVersion:"go1.13.4", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.0", GitCommit:"70132b0f130acc0bed193d9ba59dd186f0e634cf", GitTreeState:"clean", BuildDate:"2019-12-07T21:12:17Z", GoVersion:"go1.13.4", Compiler:"gc", Platform:"linux/amd64"}
[root@host131 ansible]#
[root@host131 ansible]# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
192.168.163.131 Ready 18m v1.17.0 192.168.163.131 CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 docker://18.9.7
[root@host131 ansible]#
如下是Deployment在beta1阶段的Yaml文件示例
[root@host131 prometheus]# cat prometheus-deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: prometheus-deployment
namespace: monitoring
spec:
replicas: 1
template:
metadata:
labels:
app: prometheus-server
spec:
containers:
- name: prometheus
image: prom/prometheus:v2.12.0
args:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus/"
ports:
- containerPort: 9090
volumeMounts:
- name: prometheus-config-volume
mountPath: /etc/prometheus/
- name: prometheus-storage-volume
mountPath: /prometheus/
volumes:
- name: prometheus-config-volume
configMap:
defaultMode: 420
name: prometheus-server-conf
- name: prometheus-storage-volume
emptyDir: {}
[root@host131 prometheus]#
Yaml文件中所需要的命名空间ConfigMap等其他准备也事前已经准备:
[root@host131 prometheus]# kubectl get ns |grep monitoring
monitoring Active 3m18s
[root@host131 prometheus]# kubectl get clusterrole |grep prometheus
prometheus 3m1s
[root@host131 prometheus]# kubectl get clusterrolebindings |grep prometheus
prometheus 3m7s
[root@host131 prometheus]# kubectl get cm -n monitoring
NAME DATA AGE
prometheus-server-conf 2 93s
[root@host131 prometheus]#
从上述extensions/v1beta1到apps/v1,Deployment需要进行如下修改:
在Kubernetes 1.17下直接使用使用上述Yaml文件进行Deployment的创建,首先会提示如下错误信息:
[root@host131 prometheus]# kubectl create -f prometheus-deployment.yaml
error: unable to recognize "prometheus-deployment.yaml": no matches for kind "Deployment" in version "extensions/v1beta1"
[root@host131 prometheus]#
原因很简单,在这个版本中,extensions/v1beta1中已经没有Deployment了,已经被移除了,只能使用apps/v1了,然后做如下修改
[root@host131 prometheus]# cp prometheus-deployment.yaml prometheus-deployment.yaml.org
[root@host131 prometheus]# vi prometheus-deployment.yaml
[root@host131 prometheus]# diff prometheus-deployment.yaml prometheus-deployment.yaml.org
1c1
< apiVersion: apps/v1
---
> apiVersion: extensions/v1beta1
[root@host131 prometheus]#
修改apiVersion之后,再次执行kubectl create命令进行Deployment的创建,会得到如下错误信息提示:
[root@host131 prometheus]# kubectl create -f prometheus-deployment.yaml
error: error validating "prometheus-deployment.yaml": error validating data: ValidationError(Deployment.spec): missing required field "selector" in io.k8s.api.apps.v1.DeploymentSpec; if you choose to ignore these errors, turn validation off with --validate=false
[root@host131 prometheus]#
原因也非常清晰,Deployment.spec中需要添加selector选择器,使用Kubernetes自带的帮助文档进行确认Deployment.spec.selector的写法
[root@host131 prometheus]# kubectl explain Deployment.spec.selector
KIND: Deployment
VERSION: apps/v1
RESOURCE: selector
对配置文件进行如下修改
[root@host131 prometheus]# vi prometheus-deployment.yaml
[root@host131 prometheus]# diff prometheus-deployment.yaml prometheus-deployment.yaml.org
1c1
< apiVersion: apps/v1
---
> apiVersion: extensions/v1beta1
8,10d7
< selector:
< matchLabels:
< app: prometheus-server
[root@host131 prometheus]# cat prometheus-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus-deployment
namespace: monitoring
spec:
replicas: 1
selector:
matchLabels:
app: prometheus-server
template:
metadata:
labels:
app: prometheus-server
spec:
containers:
- name: prometheus
image: prom/prometheus:v2.12.0
args:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus/"
ports:
- containerPort: 9090
volumeMounts:
- name: prometheus-config-volume
mountPath: /etc/prometheus/
- name: prometheus-storage-volume
mountPath: /prometheus/
volumes:
- name: prometheus-config-volume
configMap:
defaultMode: 420
name: prometheus-server-conf
- name: prometheus-storage-volume
emptyDir: {}
[root@host131 prometheus]#
既然是matchLabels,当然就需要设定相应的Label,这里添加了Deployment.spec.selector,实际上此Label需要和template里面的Label一致,这里之所以定义为app: prometheus-server也是因为为了和template已经存在的Label保持一致,这样就可以成功的进行创建了
[root@host131 prometheus]# kubectl create -f prometheus-deployment.yaml
deployment.apps/prometheus-deployment created
[root@host131 prometheus]# kubectl get pods -n monitoring
NAME READY STATUS RESTARTS AGE
prometheus-deployment-5c4f4f5779-vvr6h 1/1 Running 0 9m17s
[root@host131 prometheus]# kubectl get deployment -n monitoring
NAME READY UP-TO-DATE AVAILABLE AGE
prometheus-deployment 1/1 1 1 13m
[root@host131 prometheus]#
如果两者不一致的情况下,也会提示错误信息,比如这里我们特意将Label改成不一致
[root@host131 prometheus]# kubectl delete -f prometheus-deployment.yaml
deployment.apps "prometheus-deployment" deleted
[root@host131 prometheus]# cp prometheus-deployment.yaml prometheus-deployment.yaml.test
[root@host131 prometheus]# vi prometheus-deployment.yaml.test
[root@host131 prometheus]# diff prometheus-deployment.yaml prometheus-deployment.yaml.test
10c10
< app: prometheus-server
---
> app: prometheus-test
[root@host131 prometheus]#
不一致的情况下就会明确的提示,Deployment的selector和spec.template.metadata.labels不一致。
[root@host131 prometheus]# kubectl create -f prometheus-deployment.yaml.test
The Deployment "prometheus-deployment" is invalid: spec.template.metadata.labels: Invalid value: map[string]string{"app":"prometheus-server"}: `selector` does not match template `labels`
[root@host131 prometheus]#