共计 14969 个字符,预计需要花费 38 分钟才能阅读完成。
从一个零碎的上线说起
即便是一个最简略的零碎,从代码到线上,从运维到降级都要经验以下生命周期
- 前端代码编译(不同线上环境抉择不同配置)
- 前端代码打包
- 后端代码编译(不同线上环境抉择不同配置)
- 后端代码打包
- 搭建 nginx 部署前端代码
- 搭建 tomcat 部署后端代码
- 前端利用集群
- 后端利用集群
- 配置负载平衡
- 利用监控
- 故障重启
- 滚动降级
- 利用回滚
- 弹性伸缩
- 零碎运维交接
这些步骤如果都是人工来做,每一步都存在危险
- 代码编译(编译程序版本不统一,遗记批改配置文件,生产跑测试的配置)
- 环境搭建(不同环境受限网络环境,操作系统版本等差别,同样的程序在不同环境中可能体现不统一)
- 负载配置(增加节点须要人工操作,节点故障无奈进行故障转移)
- 利用监控(人工监控不事实)
- 故障重启(无奈进行人工操作,人工滞后于故障)
- 滚动降级(无奈进行人工操作)
- 利用回滚(须要在计划层面上预留回滚机制,比方保留之前版本的部署包)
- 弹性伸缩(无奈进行人工操作)
- 运维交接(每个零碎都须要交接,代码仓库,打包办法,部署步骤,重启步骤,降级步骤等)
咱们在运维交接过程中碰到十分多代码与线上运行不统一,存在代码失落问题,有可能是之前运维的共事部署后没有提交最新代码,工夫久了代码就找不到,特地是对于长时间没有更新的零碎,咱们无奈保障目前的代码就是最新的代码,代码不统一对运维是灾难性的,总之一句话就是
人是不牢靠的
现实的状况下,开发提交完代码,所有就与他无关
- 不必由开发人员个人电脑进行编译,编译应该是对立的平台,对立的环境,对立的规范
- 环境不能搭建两次,就像你写两边
得帆
,就算写上几千几万次,你无奈找到两次齐全一样的 - 集群是自动化的,什么意思呢,集群应该是一个配置项在那,而不是咱们须要针对单机和集群采取齐全不一样的装置形式,部署形式
- 监控是自动化,多样化,可配置,借助图表可能疾速判断零碎问题
- 弹性伸缩也要自动化,可能依据零碎负载状况主动进行伸缩
- 故障重启,利用回滚都是自动化,可能主动重启,部署失败可能主动回滚
- 交接是标准化,所有零碎的交接都是一个模板
kubernetes 解决了什么问题
- 保障环境完全一致
- 提供集群配置
- 故障重启
- 弹性伸缩
jenkins 解决了什么问题
- 线上编译,打包,部署
prometheus 解决了什么问题
- 监控
- 预警
- 告诉
如果能做到以上这些自动化,那么交接的内容就是,如果启动这个流程
- 某我的项目流水线
所有的扭转源于 docker
任何事物的倒退都须要标准化,今人早在两千多年前就意识到标准化的重要性,秦始皇对立六国后履行 车同轨书文同文
就是一种标准化,自此中华名族才实现了真正意义上的大一统。聪慧的 IT 人也在标准化上提出了各种计划
- W3C 规范制订了互联网规范,从此互联网进入高速倒退阶段
- JDBC 规范让程序员从适配不同数据库的噩梦中解脱
- J2EE 规范让 java 成为了最风行的后端开发语言
- TCP/IP 协定奠定了互联网的根底
- 等等
规范说白了就是对事物的极致形象,那么一个利用的形象是什么呢,利用有太多属性了,拍脑袋就能够列举很多
- 编程语言不一样
- 运行环境不一样
- 依赖不同的第三方零碎
- 打包编译的形式不一样
- 部署形式不一样
- 重启的形式不一样,systemctl 想实现这个指标
- 等等
而且这种差异性都不是小问题,都是刀刀要命的大问题,如果不解决利用都无奈失常运行,如果真的硬要形象那么只会导致利用变得更加的简单,聪慧的程序员从集装箱中找到了灵感,货物和利用有很多共通的中央
- 大小不一样
- 体积不一样
- 运输工具不一样
- 装载形式不一样
- 卸载形式不一样
生物的多样性能力让咱们这个星球变得生机勃勃,但多样性也导致了标准化的艰难,人类很聪慧,设计出了集装箱零碎
咱们只运集装箱,你们本人想方法把获取装到集装箱
咱们把利用装到 docker 中就跟咱们把货物装到集装箱,那么对利用的治理就变为对 docker 的治理,跟集装箱一样,对货物的治理就变为对集装箱的治理,事件就变得简略多了。
事实上,早在 docker 之前,咱们就在摸索标准化,比方虚拟机,拷贝虚拟机也能实现相似 docker 的性能,那为什么这种计划没有流行起来呢,因为虚拟机太重了,货车装羽毛,效率太低了,docker 相比虚拟机有很多劣势
- 轻量级,docker 自身占系统资源极少
- 启动快,指的是 docker 自身启动很快,相比虚拟机而言
- 易迁徙,docker 实质就是一个 dockerfile 的文本文件,虚拟机动不动就是好几个 G
- 好治理,只需把握大量命令就能治理利用
对于没有接触过 docker 的同学,你能够了解为超轻量级虚拟机,尽管 docker 和虚拟机有实质的区别,但能够让你对 docker 有个初步的印象。
为什么还有 kubernetes
实际上,在没有 kubernetes 呈现之前,尽管 docker 热度很高,然而很少有企业在生产中真正用起来,因为 docker 解决了大问题,但小问题还有很多
- 官网没有治理界面,不敌对
- 无奈跨主机通信,导致无奈大规模应用
- 没有监控机制,无奈监控利用状态
- 短少下层服务,docker 只提供基础设施
- 短少编排服务,即一个零碎往往须要编写多个 dockerfile,尽管前面有 composer,但这是后话
- 短少大公司背书
说到底,docker 解决了利用部署,利用运维这两个大问题,然而利用治理,利用编排,利用监控,弹性伸缩等等这些和利用相干的问题还没解决,kubernetes 的呈现才真正意义上实现了大一统,自此 docker 才真正施展出其微小威力。
从这张图能够看出,kubernetes 就是一个 docker 的管理系统,在架构上处于 docker 之上,利用之下,往上能够为利用赋能,提供利用多种 IT 资源,往下,能够调度 docker,实现利用的对立治理。kubernetes 能为利用提供什么呢,其实就是开篇提到的那些利用开发过程中的问题都能在 kubernetes 中找到解决方案,比方
- 提供 Deployment 解决利用部署的问题
- 提供 Service 解决利用负载的问题
- 提供 ConfigMap 解决不同环境配置的问题
- 提供 Ingress 解决利用拜访的问题
- 提供 PersistentVolume 解决利用存储问题
- 等等
根本你能想到在开发中碰到的非业务问题都能在 kubernetes 中找到解决方案,kubernetes 就像一个利用的小镇一样,为利用提供各种所需资源
五分钟搭建一个 kubernetes 环境
这部分内容次要目标是打消大家对 kubernetes 的恐怖,不要感觉 kubernetes 很简单,kubernetes 刚公布时的确装置起来比拟麻烦,然而近几年有很多计划让 kubernetes 装置变得非常简单,只需一行命令就能实现装置
- 设置主机名
# 配置主机名
hostnamectl set-hostname k1
#增加 hosts
172.16.8.49 k1
172.16.8.50 k2
#创立用户
groupadd docker
useradd -g docker rke
passwd rke
#配置互信
ssh-keygen
ssh-copy-id rke@k2
- 装置 docker
yum install docker
systemctl start docker
- 装置 kubernetes
# 下载 rke
https://github.com/rancher/rke/releases
# cluster.yml
nodes:
- address: k1
internal_address: k1
role: [controlplane,etcd]
hostname_override: k1
user: rke
- address: k2
internal_address: k2
role: [worker]
hostname_override: k2
user: rke
services:
kubelet:
extra_args:
max-pods: "10000"
kube-api:
service_node_port_range: "1-65535"
authentication:
strategy: x509
authorization:
mode: rbac
# 执行 rke up
./rke_linux-amd64 up
- 装置 kubectl
wget https://storage.googleapis.com/kubernetes-release/release/v1.20.5/bin/linux/amd64/kubectl
install -o rke -g docker -m 0755 kubectl /usr/local/bin/kubectl
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k1 Ready controlplane,etcd 6m53s v1.20.8
k2 Ready worker 6m52s v1.20.8
- 装置 rancher
docker run --privileged -d --restart=unless-stopped -p 8080:80 -p 4443:443 rancher/rancher
kubernetes 架构
总架构
组件
- master:k8s 主节点,负责资源的治理和利用的调度,通常不部署利用
- node:k8s 从节点,负责运行利用
- API Server:资源管制接口,对 k8s 所有资源的操作都须要通过 API Server,API Server 只运行在 master 节点
- etcd:集群数据库,集群的数据都保留在 etcd 中,etcd 是一个高性能分布式 key-value 数据库
- kubelet:kubelet 运行在每一个 node 上的,负责接管 master 的调度信息,将利用部署到 node 上,并且定时上报利用到状态和节点状态为 master 调度决策提供参考数据
- kube-proxy:你能够了解为一个 nginx(实际上底层实现就是用 nginx),负责利用的代理
- Kube scheduler:调度器,负责决定 pod 运行在哪个节点上
- controller manager:保障利用能达到用户冀望程度,比方利用设置正本为 2,那么 controller 确保该利用随时随刻都有 2 个正本
这些组件确保了利用在 kubernetes 上
- 最正当的部署
- 挂了能重启
- 资源不够可扩大
罕用资源
POD
- Kubernetes 治理的最小单元
- 一个 POD 就是一个 docker 的镜像实例
- 所有的 kuberntes 操作都是围绕 POD 进行的
- 如果把 docker 治理的利用形容为乌合之众,一群散兵,那么 kubernetes 就是正规军,有制度,有阶层,有分工,
- 够把这群散兵治理好,一个 POD 就是一个散兵,不论分工再怎么简单,命令终归是要达到底层。
- 能够定义各种策略,比方必须保障同一时间多少个 POD 运行,保障利用“死不了”,kubernetes 会主动部署新的 POD 以满足要求
Deployment
- 多个 POD 汇合
- 能够了解为一个零碎所需所有 POD 的汇合
- 方便管理,能够对一组 POD 进行操作
Service
- 对外提供对立地址
- 作用相似于 Nginx,能够作为反向代理
ConfigMap
- 零碎的配置文件
- 不同环境间应该仅有配置环境的差别,configmap 的设计实现了以上指标
- configmap 最终是给 POD 应用的
Ingress
- 使利用能通过域名进行路由,作用相似 nginx servername
kubectl 根本命令
# 查看所有节点
kubectl get nodes
NAME STATUS ROLES AGE VERSION
k1 Ready controlplane,etcd 22h v1.20.8
k2 Ready worker 22h v1.20.8
# 查看所有的 pod
kubectl get pods --all-namespaces
# 查看指定命名空间下 pod
kubectl get pods -n poc
# 获取所有资源
kubectl get all --all-namespaces
# 获取所有反对的资源类型
kubectl api-resources
一个 spring boot 部署示例
代码
@RestController
@RequestMapping("example")
public class ExampleController {@GetMapping("header")
public Map header(HttpServletRequest request) {Enumeration<String> headerNames = request.getHeaderNames();
Map<String, String> headers = new HashMap<>();
while (headerNames.hasMoreElements()) {String name = headerNames.nextElement();
headers.put(name, request.getHeader(name));
}
return headers;
}
}
代码逻辑很简略,将申请头信息全副打印进去,没有数据库连贯
Dockerfile
FROM openjdk:8-jdk-alpine
MAINTAINER definesys.com
VOLUME /tmp
ADD kubernetes-demo-1.0-SNAPSHOT.jar app.jar
RUN echo "Asia/Shanghai" > /etc/timezone
EXPOSE 8080
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-Dfile.encoding=UTF-8","-Duser.timezone=Asia/Shanghai", "-jar","app.jar"]
构建镜像
docker build -t 172.16.81.92:8000/poc/kubernetes-example:v1.0 .
docker push 172.16.81.92:8000/poc/kubernetes-example:v1.0
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: kubernetes-example
tier: backend
name: kubernetes-example
namespace: poc
spec:
replicas: 1
selector:
matchLabels:
app: kubernetes-example
tier: backend
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: kubernetes-example
tier: backend
spec:
containers:
- image: 172.16.81.92:8000/poc/kubernetes-example:v2.0
imagePullPolicy: IfNotPresent
name: kubernetes-example
ports:
- containerPort: 8080
protocol: TCP
resources: {}
dnsPolicy: ClusterFirst
schedulerName: default-scheduler
status: {}
通过 kubectl 进行部署
kubectl apply -f app-deployment.yml
如果只有 deployment 的话,只能在容器内进行拜访,咱们能够启动一个 busybox 的容器,在该容器内用 curl 命令进行测试
➜ curl http://10.42.1.30:8080/example/header
{"host":"10.42.1.30:8080","user-agent":"curl/7.30.0","accept":"*/*"}
busybox 是一些 linux 工具集的容器
这种拜访形式存在很多问题
- 在 k8s 中,ip 是变动的,因为 k8s 会依据环境的变动对利用进行调度,所以就算你不降级,利用也可能会被重新部署
- 单点问题,如果有多个正本就无奈通过单个利用 ip 进行拜访
- 负载问题,如果有多个正本就必然面临负载问题
那么解决下面这些问题的计划就是 Service
Service
在传统开发中,咱们如果部署了多个正本,也就是集群,那么咱们会在集群后面部署一个反向代理,比方 nginx,不仅能够做代理还能够做负载平衡,在 k8s 中,咱们不须要独自再去搭建这么一个反向代理服务器和负载平衡,k8s 中的 Service 资源就能够实现需求。
apiVersion: v1
kind: Service
metadata:
name: kubernetes-example-svc
namespace: poc
spec:
ports:
- name: app-port
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: kubernetes-example
tier: backend
type: ClusterIP
通过 kubectl 进行部署
kubectl apply -f app-svc.yaml
留神到 Service 的类型 type: ClusterIP
表明这还是一个集群外部的 ip,无奈通过内部进行拜访,但这个 Service 解决了负载平衡和反向代理的问题,在其余利用中能够通过名称 service 名称进行拜访,比方
➜ curl http://kubernetes-example-svc:8080/example/header
{"host":"kubernetes-example-svc:8080","user-agent":"curl/7.30.0","accept":"*/*"}
那如何解决内部拜访的问题呢,有两种计划,咱们先介绍第一种
apiVersion: v1
kind: Service
metadata:
name: kubernetes-example-svc
namespace: poc
spec:
ports:
- name: app-port
port: 8080
protocol: TCP
targetPort: 8080
nodePort: 18080
selector:
app: kubernetes-example
tier: backend
type: NodePort
NodePort
类型的 Service 能够在主机上间接开始口,作用相似 docker 中的 -p
参数,通过指定 nodeport 能够在内部通过 主机 ip:nodePort
形式进行拜访
➜ curl http://k2:18080/example/header
{"host":"k2:18080","user-agent":"curl/7.29.0","accept":"*/*"}
有同学可能会问,如果有多台主机,是不是还要做一层负载,答案是的,你能够用 F5 也能够用 nginx,上面介绍另外一种形式Ingress
Ingress
通过 nodePort 裸露服务的形式存在几个重大的问题
- 端口难以治理,如果服务多,每个服务一个端口,还要自行保护端口和服务的映射关系,十分麻烦
- 通过在主机上
挖孔
形式,在实现上就不优雅
为了解决 NodePort 的问题,于是有了 Ingress,Ingress 通过域名进行路由,也就是能够给每个 service 指定域名,通过域名进行拜访就能路由到相应的 service 上,所有的流量都是通过 kube-proxy 进行转发,因而无需在主机上开始口
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: 500m
nginx.ingress.kubernetes.io/proxy-connect-timeout: "300"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
name: kubernetes-example-svc-ingress
namespace: poc
spec:
rules:
- host: kubernetes-example.definesys.com
http:
paths:
- backend:
serviceName: kubernetes-example-svc
servicePort: app-port
kubernetes-example.definesys.com
指定了域名,通过 serviceName 匹配 service 名称,通过 Ingress 咱们能够间接用域名拜访,当然,这个域名须要加到 dns 零碎中,如果有多个节点,能够做 dns 负载也能够再做一层 nginx 负载,如果是本人本地测试,能够间接配置 hosts 文件就能够间接拜访
ConfigMap
ConfigMap 是 kubernetes 中十分蠢才的设计方案,介绍 ConfigMap 之前咱们想一个问题 生产环境的 war 包和测试环境的 war 包区别在什么
,答案是配置文件,配置文件决定了利用的环境属性,利用能够分为两局部,一部分是程序,一部分是配置文件,依照 docker 的准则,测试和生产只能是配置文件不一样,程序应该是齐全一样的,也就是说,同一个镜像,在测试环境运行的时候应该用的是测试环境的配置文件,在生产环境运行时应该用的是生产环境的配置文件,如果是 docker,咱们能够通过挂载卷实现
# 测试
docker run -v /data/dev/application.properties:/u01/webapps/application.properties -d app
#生产
docker run -v /data/prod/application.properties:/u01/webapps/application.properties -d app
在 kubernetes 中,能够通过 ConfigMap 实现,ConfigMap 也是一个 key-value 构造的文件
一个 jenkins 的 configmap 文件局部内容
apiVersion: v1
data:
apply_config.sh: |-
mkdir -p /usr/share/jenkins/ref/secrets/;
echo "false" > /usr/share/jenkins/ref/secrets/slave-to-master-security-kill-switch;
cp -n /var/jenkins_config/config.xml /var/jenkins_home;
cp -n /var/jenkins_config/jenkins.CLI.xml /var/jenkins_home;
cp -n /var/jenkins_config/hudson.model.UpdateCenter.xml /var/jenkins_home;
config.xml: |-
<?xml version='1.0' encoding='UTF-8'?>
<hudson>
<disabledAdministrativeMonitors/>
<version></version>
<numExecutors>0</numExecutors>
<mode>NORMAL</mode>
....
hudson.model.UpdateCenter.xml: |-
<?xml version='1.1' encoding='UTF-8'?>
<sites>
<site>
<id>default</id>
<url>https://updates.jenkins.io/update-center.json</url>
</site>
</sites>
jenkins.CLI.xml: |-
<?xml version='1.1' encoding='UTF-8'?>
<jenkins.CLI>
<enabled>false</enabled>
</jenkins.CLI>
plugins.txt: ""
kind: ConfigMap
metadata:
name: jenkins
namespace: poc
data 局部定义的就是 ConfigMap 的数据局部,留神到这个文件 data 中的 key 都是文件名,是的,每个 key 都能够以文件的模式挂载到容器内,文件的内容就是 value,咱们将之前的代码批改下
@RestController
@RequestMapping("example")
public class ExampleController {@Value("${kubernetes.demo.env.name:}")
private String envName;
@GetMapping("header")
public Map header(HttpServletRequest request) {Enumeration<String> headerNames = request.getHeaderNames();
Map<String, String> headers = new HashMap<>();
while (headerNames.hasMoreElements()) {String name = headerNames.nextElement();
headers.put(name, request.getHeader(name));
}
headers.put("envName", envName);
return headers;
}
}
代码注入了配置文件里的配置我的项目kubernetes.demo.env.name
- 筹备configMap.yaml
apiVersion: v1
data:
application.properties: kubernetes.demo.env.name=dev
kind: ConfigMap
metadata:
name: example-configmap
namespace: poc
- kubectl 导入到 kubernetes 中
kubectl apply -f configMap.yaml
- 批改利用的 Dockerfile 抉择从指定门路下读取配置文件
FROM openjdk:8-jdk-alpine
MAINTAINER definesys.com
VOLUME /tmp
ADD kubernetes-demo-1.0-SNAPSHOT.jar app.jar
RUN echo "Asia/Shanghai" > /etc/timezone
EXPOSE 8080
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-Dfile.encoding=UTF-8","-Duser.timezone=Asia/Shanghai", "-Dspring.config.location=/app/", "-jar","app.jar"]
减少了 --spring.config.location=/u01/config/application.properties
启动参数
从新构建镜像
docker build -t 172.16.81.92:8000/poc/kubernetes-example-configmap:v1.0 .
- 批改 Deployment,将 ConfigMap 挂载到容器内
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: kubernetes-example
tier: backend
name: kubernetes-example
namespace: poc
spec:
replicas: 1
selector:
matchLabels:
app: kubernetes-example
tier: backend
strategy:
type: RollingUpdate
template:
metadata:
labels:
app: kubernetes-example
tier: backend
spec:
containers:
- image: 172.16.81.92:8000/poc/kubernetes-example-configmap:v1.0
imagePullPolicy: IfNotPresent
name: kubernetes-example
volumeMounts:
- mountPath: /app/
name: configmap-data
ports:
- containerPort: 8080
protocol: TCP
resources: {}
dnsPolicy: ClusterFirst
volumes:
- name: configmap-data
configMap:
name: example-configmap
schedulerName: default-scheduler
status: {}
Jenkins
一个利用的部署须要至多筹备以下几个 yaml 配置文件
- Deployment
- Service
- Ingress
如果是手写不仅效率低,易于出错,也难以治理,也不倡议将配置文件放在我的项目中,起因有以下几个
- 每个我的项目都须要 copy 一份配置进行批改,繁琐
- 如果不懂 k8s 会减少其学习老本
- 如果 k8s 降级,配置文件有可能须要跟着变动,就须要批改所有的配置文件
咱们须要一个工具帮忙咱们实现配置文件的生成并且部署到 kubernetes 环境中,Jenkins 能够帮忙咱们实现一系列的自动化操作
#!/bin/bash
set -e
v_app_name=kubernetes-example
v_module=.
v_app_host=kubernetes-example.definesys.com
v_k8s_namespace=poc
#v_app_name=$appName
#v_module=$module
#v_app_host=${v_app_name}.fuyaogroup.com
#v_k8s_namespace='fone-application'
v_app_version=`date +"%Y%m%d%H%M%S"`
v_harbor_prefix='172.16.81.92:8000/poc/'
if ["$v_app_host" == ""]; then
v_app_host=${v_app_name}.definesys.com
fi
echo "app name ====>"$v_app_name
echo "app version ====>"$v_app_version
echo "module ====>"$v_module
echo "workspace ====>"$WORKSPACE
echo "profile ====>"$v_profile
echo "app host ====>"$v_app_host
v_workspace=$WORKSPACE/workspace
mkdir -p $v_workspace
cd $v_module
mvn clean package -Dmaven.test.skip
#长期寄存 jar 包目录
v_build_directory_name=build
v_build_directory=$v_workspace/$v_build_directory_name
v_app_jar=target/*.jar
v_app_jar=`basename target/*.jar`
rm -rf $v_build_directory
mkdir -p $v_build_directory
cp -rf target/$v_app_jar $v_build_directory
cd $v_build_directory
#v_app_name=${v_app_jar%.*}
#v_app_name=${v_app_name%-*}
echo "app jar name =====>"$v_app_jar
echo "app name =====>"$v_app_name
#docker 镜像构建
v_image_tag=$v_harbor_prefix$v_app_name:$v_app_version
cat 1>Dockerfile <<EOF
FROM openjdk:8-jdk-alpine
MAINTAINER definesys.com
VOLUME /tmp
ADD $v_app_jar app.jar
RUN echo "Asia/Shanghai" > /etc/timezone
EXPOSE 8080
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-Dfile.encoding=UTF-8","-Duser.timezone=Asia/Shanghai", "-jar","app.jar"]
EOF
docker build -t $v_image_tag . -f Dockerfile
docker push $v_image_tag
docker rmi -f $v_image_tag
#部署 kubernetes
cat 1>app-deployment.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
generation: 1
labels:
app: $v_app_name
tier: backend
name: $v_app_name
namespace: $v_k8s_namespace
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 2
selector:
matchLabels:
app: $v_app_name
tier: backend
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: $v_app_name
tier: backend
spec:
containers:
- image: $v_image_tag
imagePullPolicy: IfNotPresent
name: $v_app_name
ports:
- containerPort: 8080
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
# dnsConfig:
# searches:
# - k2-infrastructure.svc.cluster.local
restartPolicy: Always
imagePullSecrets:
- name: harbor-registry
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
status: {}
---
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
name: ${v_app_name}-svc
namespace: $v_k8s_namespace
spec:
ports:
- name: app-port
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: $v_app_name
tier: backend
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: 500m
nginx.ingress.kubernetes.io/proxy-connect-timeout: "300"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
creationTimestamp: null
generation: 1
name: ${v_app_name}-svc-ingress
namespace: $v_k8s_namespace
spec:
rules:
- host: $v_app_host
http:
paths:
- backend:
serviceName: ${v_app_name}-svc
servicePort: app-port
status:
loadBalancer: {}
EOF
kubectl apply -f app-deployment.yaml --record