前面我们讲解了Dockerfile基础命令、编写Dockerfile,因为整个DevOps CI/CD过程所涉及的知识面比较多,所以本节我们则开始总结Kubernetes(K8S) yaml模版配置,当我们比较熟悉Kubernetes(K8S) yaml模版内容时候,那最终在编写gitlab-ci.yml文件时候就游刃有余了!
Kubernetes Service&Deployment
# 版本号
apiVersion: v1
# Kubernetes资源类型,服务类型
kind: Service
# 元数据
metadata:
# 该资源Service类型的名称
name: {{.appName}}
# 该资源Service所属的命名空间
namespace: {{.namespace}}
# 自定义的标签列表,key-value键值对
labels:
app: {{.appName}}
# 该Service资源详细定义
spec:
#该Service访问的类型,NodePort类型可以对外暴露,让外部访问这个集群
type: NodePort
# 该Service对外暴露的端口列表
ports:
# Service服务监听的端口,Service在集群内部暴露的端口
- port: 80
# 端口名称/标示类型
name: http
# 需要转发到pod的端口号,需要与容器监听端口一致,不然会导致访问不到
# 它用来确定提供该服务的容器所暴露的端口号,即具体业务的进程在容器内的targetPort上提供TCP/IP
# 内部端口映射到Pod暴露出的端口
targetPort: {{.contrainerPort}}
# 对外暴露的端口号,如果不指定则随机生成一个端口号
nodePort: {{.nodePort}}
# 标签选择器配置,将具有以下标签的Pod都归属于当前Service管理
selector:
#指定label中app: {{.appName}}的Pod归属于当前Service
app: {{.appName}}
#这个代表一个yaml模版配置中包含多个Kubernetes资源类型,所以用 --- 进行分割
#kind: Deployment、kind: Service ......
---
#版本号,可以通过 kubectl api-versions 命令进行获取当前支持的版本
apiVersion: extensions/v1beta1
#Kubernetes资源类型,部署应用类型,为ReplicaSet和Pod的创建提供一种声明式的定义方法
#无需手动创建ReplicaSet/Replication Controller和Pod,使用Deployment支持滚动升级和回滚等特性
kind: Deployment
#该资源元数据
metadata:
#该资源名称,决定了Pod的显示名称
name: {{.appName}}
#该资源所属的命名空间
namespace: {{.namespace}}
#该资源的详细定义
spec:
# 指定运行的Pod数量,它会根据selector来进行选择,会将选择到的Pod维持在{{.replicas}}个的数目量
replicas: {{.replicas}}
# 主要用于滚动升级Deployment,Kubernetes在等待设置的时间后才进行升级
# 如果没有设置该值,Kubernetes会认为该容器启动起来后就提供服务了
# 所以需要设置一个间隔时间,用来指定Pod可用状态的最小秒数
minReadySeconds: {{.minReadySeconds}}
# 更新策略/升级策略
# 指定新Pod替换旧Pod的策略,type为rollingUpdate为使用滚动更新的方式更新Pod
strategy:
#默认为滚动升级
type: RollingUpdate
rollingUpdate:
maxSurge: 2 # 滚动升级中,容器副本的最大数量,运行比replicas总共多多少个 pod
maxUnavailable: 1 # 滚动升级中,允许的最大不可用的pod个数
# set类型的选择器
# 还有一个matchExpressions
# 类似下面的配置方式
# matchExpressions:
# - {key: app, operator: In, value: [nginx]}
# 指明哪个pod被管理,这里我们指定了app: {{.appName}}
selector:
matchLabels:
app: {{.appName}}
# 扩容时创建Pod的模板
template:
#元数据
metadata:
#标签列表
labels:
app: {{.appName}}
version: "{{.version}}"
spec:
# K8S将会给应用发送SIGTERM信号,用来优雅地关闭应用,默认为30秒
terminationGracePeriodSeconds: 30
#优先级最高,先于其他容器启动,主要做一些初始化配置工作
initContainers:
- name: skywalking-agent
command:
- cp
- '-r'
- /skywalking/agent/
- /data/agents/skywalking/
# pod中的容器列表
containers:
# 容器名称
- name: {{.appName}}
# 容器镜像名称
image: {{.image}}:{{.version}}
# 获取镜像的策略,其中有Always,IfNotPresent,Never
# Always=>每次都会重新下载镜像
# IfNotPresent=>如果本地又镜像则使用,否则下载镜像
# Never=>仅使用本地镜像
imagePullPolicy: IfNotPresent
# 容器启动命令列表,不指定会使用镜像打包时的启动命令
command: ["java", "-jar", "-Xms{{.request_memory}}m", "-Xmx{{.limit_memory}}m", "server.jar"]
# 容器启动命令时的参数列表
args: ["--spring.profiles.active={{.env}}"]
# 资源限制和资源请求的设置
resources:
# 通常我们会把request设置为一个比较小的数值,这个值根据项目情况而定,需求限制,也叫软限制
requests:
memory: {{.request_memory}}Mi
#最大限制,也叫硬限制,通常requests和limits要一起配置,避免资源使用不合理出现问题
limits:
memory: {{.limit_memory}}Mi
# 对Pod内容器健康检查的设置,当探测几次无反应后,将会自动重启该容器
# livessProbe: 用于判断容器是否存活(running),如果livessProbe探针探测到不健康,则kubelet会杀掉该容器,并根据容器的重启策略做相应的处理,不配置的话K8S会认为一直是Success
# 其中有exec、httpGet、tcpSocket这3种配置
# exec: 在容器内部执行一个命令,如果该命令返回码为0,则表明容器健康
# httpGet: 通过容器的IP地址、端口号及路径通过用httpGet方法,如果响应的状态码stateCode大于等于200且小于400则认为容器健康
# tcpSocket: 通过容器的IP地址和端口执行tcpSocket检查,如果能够建立tcpSocket连接,则表明容器健康
# 判断是否存活,不存活则重启容器
livenessProbe:
httpGet:
# 健康检查路径,也就是应用的健康检查路径
path: {{.checkHealthPath}}
# 端口号
port: {{.contrainerPort}}
scheme: HTTP
# 容器首次启动后首次进行健康检查的时间,秒/单位
initialDelaySeconds: 60
# 对容器健康检查等待响应时间的超时时间设置
timeoutSeconds: 5
# 将康检查成功后,最少连续将康检查成功多少次才被认定成功
successThreshold: 1
# 将康检查失败后,最少连续将康检查失败多少次才被认定为失败
failureThreshold: 5
# redinessProbe: 用于判断容器是否启动完成(ready),可以接收请求,如果该探针探测到失败,则Pod状态会被修改。Endpoint Controller将从Service的Endpoint中删除包含该容器的所在Pod的Endpoint
# kubernetes 判断容器是否启动成功,否可以接受外部流量
readinessProbe:
httpGet:
# 健康检查路径,也就是应用的健康检查路径
path: {{.checkHealthPath}}
# 端口号
port: {{.contrainerPort}}
scheme: HTTP
#容器启动后第一次执行探测是需要等待多少秒
initialDelaySeconds: 30
#探测超时时间,默认1秒,最小1秒。
timeoutSeconds: 5
#最少连续成功次数之后才为成功
successThreshold: 1
#最少连续失败次数之后才为失败
failureThreshold: 5
# 容器需要暴露的端口号列表
ports:
# 端口的名称
- name: http
# 容器需要监听的端口
containerPort: {{.contrainerPort}}
# pull镜像时使用的secret名称,以name:secretkey格式指定
imagePullSecrets:
- name: {{.registry}}
通过代码块,可以看出整个模版配置是比较复杂的,可以结合着注释信息来看各个配置的作用,其中在代码块中,也许会看到很多诸如这样的写法{{.appName}}
这样的写法是用了GoLang中的模版语法,因为我们替换模版配置也是基于GoLang现有的模版库。GoLang实现的模版库会放到后续的章节进行讲解,大家也可以在网上搜索GoLang Yaml模版解析库,自己实现也行。
扩展事项
本节我们的K8S yaml模版是基于Kubernetes Service这个资源来进行的总结,该Service访问的类型有ClusterIP、NodePort、LoadBalancer等类型,默认的为ClusterIP类型
- ClusterIP:只能通过集群的内部 IP 暴露服务,服务只能够在集群内部可以访问
- NodePort:通过每个Node节点上的IP与静态端口spec. nodePort: {{.nodePort}} 暴露服务,NodePort服务会路由调用到ClusterIP服务,这样我们就可以对外提供服务了。
- LoadBalancer:这个负载均衡服务基本我们不会涉及到,这个一般使用在诸如
nginx-ingress-controller
这样的容器组,本质也就是在NodePort的基础之上多了一步LoadBalancer过程,用户发起的请求会先到LoadBalancer,最终LoadBalancer会转发到NodePort服务。
当然我们在定义Kubernetes Service资源类型时候,一般都会配套定义Kubernetes Deployment资源类型,比如我们的网关项目。
有疑问加站长微信联系(非本文作者)