一、概述
日常使用K8S部署新的应用,拷贝一份已有的应用的ymal文件来修改,说实在,咱也不知道为啥这么改,大佬说只要删除一些无用的配置,再修改一些属性就可以了,然后一些网络就通过界面配置配置就OK了,日子过得那是十分舒适。突然某一天,有一个项目的K8S平台改版了,UI焕然一新。这把我整的有点蒙了,其实还是学艺不精,不懂得K8S的精髓。在适应这个平台的过程中发现,不管平台UI如何变化,其中最核心的k8s的api的内容并未发生变化,因此才开始下定决心学习一下k8s的api。
开发人员接触的api其实不多,从我工作中接触的来讲,主要是deployment、service以及configMap这三个。
先把这些啃完,应该够用80%的场景了,其他使用UI来配置配置应该就OK。
本次采用yml文件结合注解的方式来详细学习每一个标签的定义。
二、适合人群
适合有一定使用K8S平台经验的人员。
三、API样例学习
3.1 deployment的ymal文件
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: app-name
labels:
name: app-name
spec:
#标签匹配,注意这里的标签匹配与spec.template.metadata.labels中定义的标签要一致
selector:
matchLabels:
app-label: app-label
#策略定义,描述如何将现有 Pod 替换为新 Pod
strategy:
type: RollingUpdate #取值可以是 “Recreate” 或 “RollingUpdate”。默认为 RollingUpdate
rollingUpdate: #仅当 type = RollingUpdate 时才出现
maxSurge: 1 #超出预期的 Pod 数量之后可以调度的最大 Pod 数量或者百分比,百分比默认25%
maxUnavailable: 1 #更新期间可能不可用的最大 Pod 数量或者百分比,百分比默认25%
#定义POD的数量
replicas: 2
template:
#定义POD的元数据,主要用来定义POD的标签,可以有多个
metadata:
labels:
app-label: app-label
spec:
#调度约束,这里主要是反亲和,避免POD多个副本在同一个节点机器上
affinity:
#反亲和配置
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
#每个集群节点的机器都有kubernetes.io/hostname这个标签,通过命令查看kubectl describe node 192.168.0.212
#在集群中所有的节点(需要包含topologyKey中定义的label标签)范围内,如果这个节点机器没有包含任何标签为app-label,value为app-label的POD,那么这台机器可以部署这个POD
#否则该机器不能部署这个POD
#由于每台机器都有kubernetes.io/hostname这个标签,因此这里相当于是集群内所有节点机器
- labelSelector:
matchLabels:
app-label: app-label
topologyKey: kubernetes.io/hostname
#定义容器的内容,可以有多个,使用ymal数组方式定义
containers:
# 镜像地址定义
- image: demo/nginx:1.22.0
#POD名称
name: my-nginx
#定义资源分配,其中requests是初始资源,limits是最大资源,定义了cpu和内存两个参数
resources:
#requests若未定义,则默认值为 limits 值
requests:
cpu: "20m"
memory: "55M"
limits:
cpu: 2
memory: 2Gi
terminationMessagePath: /dev/termination-log #挂载到容器文件系统的一个路径,容器终止消息写入到该路径下的文件中。默认为当前值。
terminationMessagePolicy: File #指示应如何填充终止消息。字段值 File 将使用 terminateMessagePath 的内容来填充成功和失败的容器状态消息。 默认为当前值。
#定期探针容器活跃度。如果探针失败,容器将重新启动。
livenessProbe:
tcpSocket:
port: 80
#容器启动后启动存活态探针之前的秒数
initialDelaySeconds: 20
#探针超时的秒数。默认为 1 秒。最小值为 1。
timeoutSeconds: 1
#探针的执行周期(以秒为单位)。默认为 10 秒。最小值为 1。
periodSeconds: 20
#探针成功后的最小连续失败次数,超出此阈值则认为探针失败。默认为 3。最小值为 1。
failureThreshold: 3
#探针失败后最小连续成功次数,超过此阈值才会被视为探针成功。默认为 1。
successThreshold: 1
#定期探测容器服务就绪情况。如果探针失败,容器将被从服务端点中删除。
readinessProbe:
tcpSocket:
port: 80
#容器启动后启动存活态探针之前的秒数
initialDelaySeconds: 20
#探针超时的秒数。默认为 1 秒。最小值为 1。
timeoutSeconds: 1
#探针的执行周期(以秒为单位)。默认为 10 秒。最小值为 1。
periodSeconds: 20
#探针成功后的最小连续失败次数,超出此阈值则认为探针失败。默认为 3。最小值为 1。
failureThreshold: 3
#探针失败后最小连续成功次数,超过此阈值才会被视为探针成功。默认为 1。
successThreshold: 1
#容器内的环境变量定义
env:
- name: APP_NAME
value: nginx
- name: APP_VERSION
value: '1.0'
ports:
- containerPort: 80
name: my-nginx-port
volumeMounts:
#容器内应安装卷的路径和名称,一种是挂载文件夹,一种是挂载文件
- mountPath: /data
name: data
- mountPath: /home/nginxapp/nginx/conf/nginx.conf
name: conf
subPath: nginx.conf
#节点选择器,选择节点机器包含标签node: nginx-node的机器
nodeSeletor:
node: nginx-node
volumes:
#引用了名称为conf的配置字典configMap
- name: conf #volume的名称
configMap:
defaultMode: 420 #配置文件的权限,420对应的二进制位为110 100 100
items:
- key: nginx.conf
path: nginx.conf
name: conf-nginx #配置字典的名称
- name: data #volume的名称
hostPath:
path: /home/nodeapp/data #定义节点机器上的路径信息
type: "" #一般定义为空
restartPolicy: Always
imagePullPolicy: Always
3.2 service的ymal文件
kind: Service
apiVersion: v1
metadata:
name: my-nginx-service
spec:
selector:
app-label: app-label
#type 确定 Service 的公开方式。默认为 ClusterIP。 有效选项为 ExternalName、ClusterIP、NodePort 和 LoadBalancer。
#ClusterIP 为端点分配一个集群内部 IP 地址用于负载均衡。
#NodePort 建立在 ClusterIP 之上,并在每个节点上分配一个端口
type: ClusterIP
#支持 “ClientIP” 和 “None”。用于维护会话亲和性。 启用基于客户端 IP 的会话亲和性。必须是 ClientIP 或 None。默认为 None。
#需要会话保持选择ClientIP
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800 # ClientIP 类型会话的维系时间秒数,默认值为 10800(3 小时)。
ports:
- name: tcp-80-80
port: 80 #Service 将公开的端口
targetPort: 80 #在 Service 所针对的 Pod 上要访问的端口号或名称
protocol: TCP #此端口的 IP 协议。支持 “TCP”、“UDP” 和 “SCTP”。默认为 TCP。
3.3 configMap的ymal文件
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap
labels:
app: myapplication
data:
my-key: my-value
application.properties: | #这里的竖线是保留如下每一行的换行符号
jdbc.url=xxxx
jdbc.username=mysql
jdbc.password=pwd
四、我的最佳实践推荐
4.1 合并多个API
对于运维人员来说,希望多个yml一起执行,因此可以通过---分隔符将多个API合并到一个文件中。
顺序为configMap-》deployment-》service
4.2 应用无状态
针对新的应用,推荐应用是无状态的,且配置文件应支持单独放到一个独立的文件夹下,这样部署最方便。 已有的系统最好也将配置文件放到单独的文件夹下进行改造。