Kubernetes deployment模板

说明

官方文档里面的deployment样例比较简单

实际上deployment的配置选项非常的多

这里做一下记录

Dockerfile

1
2
3
FROM openjdk:8-jre-slim

ADD ./demo.jar /home/demo.jar

模板

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
# 定义APP环境变量
apiVersion: v1
kind: ConfigMap
metadata:
# 定义配置文件的名称
name: java-app-configmap
# 定义运行在哪个命名空间
namespace: default
labels:
# 定义标签,后面可以通过标签选择器筛选
app: java-app
data:
# 定义数据库连接地址和端口
DB_HOST: "mysql-svc.default.svc.cluster.local"
DB_PORT: "3306"
---
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: java-app
# 定义运行在哪个命名空间
namespace: default
labels:
app: java-app
spec:
selector:
matchLabels:
app: java-app
# 设置副本数量
replicas: 1
template:
metadata:
labels:
app: java-app
spec:
# 禁止自动挂载kubernetes的ServiceAccount
# 理解为禁止app通过kubernetes内建的ServiceAccount访问kubernetes集群
automountServiceAccountToken: false
# 从镜像库拉镜像时使用用户名密码认证
imagePullSecrets: []
# 定义亲和性,调整调度策略
affinity:
# 容器反亲和性
podAntiAffinity:
# preferredDuringSchedulingIgnoredDuringExecution
# 优先部署在满足条件的节点,如不满足则忽略条件继续调度
preferredDuringSchedulingIgnoredDuringExecution:
# 这里定义亲和规则
# 调度时会检查候选节点上是否有带有app=java-app的app,权重为100
# 这里定义的是AntiAffinity,效果为同一个app在同一个节点上是互斥的
# 实现同一个app不会集中在同一个节点
# 极端情况下,节点数量不够,无法满足条件时,会忽略prefer规则,按照正常流程调度
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- java-app
# 这里是作用域,没啥事不用调
topologyKey: "kubernetes.io/hostname"
weight: 100
# 配置Pod挂载的卷和名字
volumes:
# 这里定义Pod可以挂载哪些volume,容器挂载的volume要在这里定义好才可以使用
- name: timezone-volume
# 定义宿主机文件路径
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
# 容器初始化操作
initContainers:
# 用于检测数据库就绪状态
# 检查条件为数据库服务器端口是否可达
- name: wait-for-db
image: busybox:1.28
imagePullPolicy: IfNotPresent
envFrom:
# 这里从configmap里面获取环境变量
- configMapRef:
name: java-app-configmap
# 这里是容器初始化时,通过循环检查数据库是否就绪
command:
- /bin/sh
- -c
- "until nc -zv $(DB_HOST) $(DB_PORT) -w1; do echo 'waiting for db'; sleep 1; done"
# 启动容器
containers:
# 业务容器
- name: java-app
image: java-app:v1
# 镜像拉取策略
# IfNotPresent 如果没有就拉镜像
# Always 总是拉镜像,即使节点本地有镜像
# Nerver 不拉镜像
imagePullPolicy: IfNotPresent
# 定义容器资源需求
resources:
# 资源限制,超过限值会被杀掉
limits:
# 限制CPU用量
# 1个核心的CPU等于1000m,这样多个容器是通过CPUShare共享CPU计算资源
# 如果直接写数字(1、2、3)这样的话,会被认为是将容器独占CPU核心
cpu: "1500m"
# 限制容器最大内存用量
# 内存为不可压缩资源,超过限制会因为Out-Of-Memory被杀掉
# jdk-8u131+以上的版本可以通过强制检查Linux cgroup配置
memory: "2Gi"
# Pod调度时会参考这里的资源需求调度
requests:
# 限制CPU用量
# 1个核心的CPU等于1000m,这样多个容器是通过CPUShare共享CPU计算资源
# 如果直接写数字(1、2、3)这样的话,会被认为是将容器独占CPU核心
cpu: "100m"
memory: "2Gi"
env:
# 这里定义JAVA_OPTS来让jvm启动时自动识别容器资源限值,然后计算出匹配的运行参数
# -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap开启openjdk8的实验特性以正确识别docker资源限值
# -XX:MaxRAMFraction默认值为4,即Heapsize为内存的25%,这里设置为2,即Heapsize为内存的50%
# 可以通过-Xmx来指定jvm可使用的最大堆
- name: JAVA_OPTS
value: "-Xmx1800m"
# value: "-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=2"
# 这里使用kubernetes的downwardAPI获取Pod的信息
# 对于某些APP需要获取Pod自身信息时可以直接调用环境变量
# Pod所在宿主机名字
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
# Pod所在宿主机IP地址
- name: NODE_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
# Pod名字
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
# PodIP地址
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
envFrom:
# 这里直接从configmap里面获取环境变量
# 可以在command字段里面使用
# 具体定义了哪些环境变量,可以在configmap那里看到
- configMapRef:
name: java-app-configmap
# 设置容器工作目录
workingDir: /home
# 设置容器启动命令和参数
command:
- /usr/bin/java
- -Djava.security.egd=file:/dev/./urandom
- -Duser.timezone=Asia/Shanghai
- -Xloggc:logs/gc.log
- -jar
- /home/demo.jar
# 定义容器端口
ports:
# 这里定义的端口别名可以在其他地方直接调用
- name: http
# 定义容器运行时监听的端口,需要与Service的targetPort对应
containerPort: 8080
protocol: TCP
# 定义容器存活探针
livenessProbe:
# 使用TCP端口探测
tcpSocket:
# 定义检查端口,可以写端口别名,也可以写端口号
port: 8080
# 容器初始化完成后延迟检测,单位秒
# 防止app启动时间过久导致被k8s判断为fail直接干掉
initialDelaySeconds: 60
# 检测频率
periodSeconds: 10
# 定义容器就绪探针
readinessProbe:
# 使用HTTP GET请求
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: readinessProbe
value: k8s
# 容器初始化完成后延迟检测,单位秒
# 防止app启动时间过久导致被k8s判断为fail直接干掉
initialDelaySeconds: 60
# 检测频率
periodSeconds: 10
# 把定义好的数据卷挂载到容器里面
volumeMounts:
- name: timezone-volume
# 这里用于配置容器的时区为Asia/Shanghai
mountPath: /etc/localtime