4-K8S 部署Java应用及应用程序生命周期管理
1、在kubernetes中部署应用程序流程
准备项目源码-->编译构建-->产出war包,打包到镜像中-->推送到镜像仓库
获取源代码是开发人员提交代码的代码托管地址,有Git、SVN、Gitlab等
镜像分类
1、基础镜像:如centos、Ubuntu等 2、环境镜像:如JDK、Python、go 3、项目镜像:是将项目打包到里面,基于环境镜像去打包
为什么自己构建镜像?
1、特殊环境配置 2、容易排查故障 3、标准化 4、更安全一些
制作Java镜像
1、安装编译基础环境
yum install -y java-1.8.0-openjdk maven
修改加速下载位置(更换下载源)添加如下内容
vim /etc/maven/settings.xml
152 <mirror> 153 <id>mirrorId</id> 154 <mirrorOf>repositoryId</mirrorOf> 155 <name>Human Readable Name for this Mirror.</name> 156 <url>http://my.repository.com/repo/path</url> 157 </mirror> 158 --> 159 <mirror> 160 <id>aliyun</id> 161 <name>aliyun</name> 162 <url>http://maven.aliyun.com/nexus/content/groups/public/</url> 163 <mirrorOf>central</mirrorOf> 164 </mirror>165 </mirrors>
2、编译构建
首先在其他机器上安装数据库,
yum install -y mariadb-server systemctl start mariadb.service && systemctl enable mariadb.service mysql_secure_installation 初始化数据库信息
在创建镜像这台机器上拷贝数据库文件到数据库机器上
scp /root/tomcat-java-demo-master/db/tables_ly_tomcat.sql root@192.168.10.112:/
登录数据库创建数据库、导入数据、创建用户授权可以连接的用户
mysql -uroot -p123456 create database test; use test; source /tables_ly_tomcat.sql; create user `test`@'%' identified by '123456'; grant all privileges on test.* to 'test'@'%'; flush privileges; select host,user from mysql.user;
开始构建产出war包
yum install -y git git clone https://github.com/lizhenliang/tomcat-java-demo.git cd tomcat-java-demo-master/ #进入项目目录 vim /root/tomcat-java-demo-master/src/main/resources/application.yml #编辑数据库连接地址 mvn clean package -D maven.skip.test=true #开始构建 ls /root/tomcat-java-demo-master/target/ly-simple-tomcat-0.0.1-SNAPSHOT.war #查看构建好的镜像
编写Dockerfile
vim /root/tomcat-java-demo-master/Dockerfile
FROM tomcat:8 LABEL maintainer fage #RUN rm -rf /usr/local/tomcat/webapps/* ADD target/*.war /usr/local/tomcat/webapps/ROOT.war
注意修改实际环境的数据库地址,否则无法连接到数据库
构建项目镜像
docker build -t java-demo:v1 .
docker images|grep java
推送到镜像仓库,可以搭建私有仓库和公有仓库harbor、registry、hub公有仓库等
搭建完成登录上传
docker login #输入账号、密码 docker tag java-demo:v1 xxxx/java-demo:v1 docker push xxxx/java-demo:v1
使用deployment部署Java应用
deployment功能
1、部署无状态应用 2、管理pod和replicaset 3、具有上部署、副本设定、滚动升级、回滚等功能 4、提供声明式更新,例如只更新一个image 应用场景:web服务、微服务
命令行部署方式(直接部署到集群)
1、部署过程
kubectl delete deploy web && kubectl delete svc web kubectl create deployment web --image=lizhenliang/java-demo kubectl get pods,svc kubectl describe pod web-6b9c78c94f-smcdr #可以查看到详细过程和信息
2、发布访问端口(等于创建service)
kubectl expose deployment web --port=80 --target-port=8080 --type=NodePort --name=web #发布控制器接口,暴露应用服务端口 kubectl get pods,svc -o wide #查看详细信息 kubectl get ep #查看负载均衡
测试访问
Pod与container的关系
container在集群上管理和运行容器的对象 通过label-selector(标签)相关联 Pod通过控制器实现营业的运维、伸缩、滚动升级等
编辑控制器以及控制器中的资源
kubectl create deployment deployment web2 --image=lizhenliang/java-demo --dry-run=client -o yaml > deployment.yaml #生成yaml文件
vim deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: web2 spec: replicas: 1 selector: matchLabels: project: demo #这里的标签必须跟service标签对应上 app: java #这里的标签必须跟service标签对应上 template: metadata: labels: project: demo #这里的标签必须跟service标签对应上 app: java #这里的标签必须跟service标签对应上 spec: containers: - name: web image: lizhenliang/java-demo ports: - containerPort: 8080
编辑配置service文件
kubectl expose deployment web2 --port=80 --target-port=8080 --dry-run=client -o yaml > servive.yaml #生成service的yaml
vim service.yaml
apiVersion: v1 kind: Service metadata: name: web2 spec: selector: project: demo #这里的标签必须跟deployment标签对应上 app: java #这里的标签必须跟deployment标签对应上 ports: - name: default protocol: TCP port: 80 #提供给外部访问的接口 targetPort: 8080 #容器内部管控 type: NodePort
生效配置
kubectl apply -f deployment.yaml kubectl apply -f service.yaml kubectl get pods,svc
应用升级、弹性伸缩、回滚、删除
应用升级
kubectl set image deployment web nginx=nginx:1.16 kubectl set image deployment web java-demo=tomcat:8 --record=true #记录版本号历史命令(方便回滚) 查看升级状态 kubectl rollout status deployment web
弹性伸缩
kubectl scale deployment web --replicas=10 #设定副本数量为10
kubectl autoscale deployment web --min=10 --max=15 --cpu-percent=80 #当podCPU使用率达到80%自动添加副本数量
kubectl get hpa #查看到pod资源使用情况
查看hpa前提:
1、部署metrics-server
2、部署pod要设置requests,如下配置
apiVersion: apps/v1 kind: Deployment metadata: name: web2 spec: replicas: 1 selector: matchLabels: project: demo app: java template: metadata: labels: project: demo app: java spec: containers: - name: web image: lizhenliang/java-demo ports: - containerPort: 8080 resources: requests: cpu: 500m limits: cpu: 1
回滚
kubectl rollout history deployment web #查看升级历史版本 kubectl rollout undo deployment web #直接回滚到上个版本 kubectl rollout undo deployment web --to-revision=2 #指定版本进行回滚
删除
kubectl delete deploy web kubectl delete svc web
应用程序生命周期管理
Pod对象:pod设计思想、应用自修复、init container、静态pod
Pod对象存在的意义: Pod为亲密性应用而存在
亲密性应用场景:
两个应用之间发生文件交互 两个应用需要通过127.0.0.1或者socket通信(典型组合:nginx+php) 两个应用需要发生频繁的调用
Pod基本概念
最小部署单元 一组容器的集合 一个pod中的容器共享网络命名空间 Pod是短暂的
Pod对象:容器分类
Infrastructure Container:基础容器,维护整个pod网络空间 Initcontainers:初始化同期,先于业务容器开始执行 Containers:与业务容器并行启动
Pod对象:应用自修复(重启策略+健康检查)
重启策略:
Always:当容器终止退出后,总是重启容器,默认策略。 适用场景:nginx、mysql等长期运行的程序 配置位置为container同级 OnFailure:当容器异常退出(退出状态码0)时才重启容器。 适用场景:定时任务 Never:当容器终止退出,从不重启容器 适用场景:临时任务
健康检查两种类型
LivenessProbe(存活检查) 如果检测失败,将杀死容器,根据pod的restartPolicy来操作 ReadinessProbe(就绪检查) 如果检查失败,kubernetes会把pod从server endpoints(负载均衡)中剔除 与镜像位置同级
支持以下三种检测方法
httpGet:发送HTTP请求,返回200-400范围状态码为成功 exec: 执行shell命令返回状态码是0为成功 tcpsocket:发起TCP Socket建立成功
httpGet方式
apiVersion: apps/v1 kind: Deployment metadata: labels: app: web name: web spec: replicas: 1 selector: matchLabels: app: web strategy: {} template: metadata: labels: app: web spec: restartPolicy: Always #重启策略,默认Always containers: - image: nginx name: nginx resources: {} livenessProbe: #可以同时使用,不同维度的检查 httpGet: path: /index.html port: 80 initialDelaySeconds: 5 #第一次启动pod多少秒后执行健康检查 periodSeconds: 5 #健康检查周期(5秒) readinessProbe: #可以同时使用,不同维度的检查 httpGet: path: /index.html port: 80 initialDelaySeconds: 5 #启动pod多少秒后执行健康检查 periodSeconds: 5 #健康检查周期(5秒)
应用生效
kubectl apply -f pods.yaml
演示重启pod过程
kubectl exec -it web4-547f8789f5-vgh4l bash rm -f /usr/share/nginx/html/index.html
查看pod状态,过10秒左右就会自动重启
kubectl get pods
再次进入到容器中查看
exec方式
apiVersion: apps/v1 。。。跟上面的一样忽略部分 spec: restartPolicy: Always containers: - image: nginx name: nginx resources: {} livenessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 5 periodSeconds: 5
tcpSocket 方式
apiVersion: v1 。。。。忽略部分 spec: restartPolicy: Always continers: - Images: lizhenliang/java-demo name: java-demo livenessProbe: tcpSocket: port: 8080 initiaIDelaySeconds: 30 periodSeconds: 20
Pod对象:init container
Init container:
1、基本支持所有普通容器特征 2、优先于普通容器执行 不支持健康检查,只用于初始化
应用场景
1、 控制普通容器启动,初始化容器后才会启动业务容器
2、 初始化配置,例如下载应用配置文件(镜像等)、注册信息等
初始化容器让配置文件放到容器中:使用数据卷共享
cat init-conttainers.yaml
apiVersion: v1 kind: Pod metadata: name: init-demo spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: workdir mountPath: /usr/share/nginx/html initContainers: #优先执行 - name: install image: busybox command: - wget - "-O" - "/work-dir/index.html" - http://kubernetes.io volumeMounts: - name: workdir mountPath: "/work-dir" dnsPolicy: Default #数据共享配置 volumes: - name: workdir emptyDir: {}
生效文件
kubectl apply -f init-container.yaml kubectl get pods
查看分配到那个节点
kubectl get pods -o wide
Pod对象:静态Pod
静态pod:固定在某个node上面,由kubelet管理生成一种pod,无法使用控制器
在kubelet配置文件启用静态pod
vim /var/lib/kubelet/config.yaml ... staticPodPath: /etc/kunernetes/manifests #指定静态pod位置 ...
将部署的pod yaml放到该目录会由kubelet自动创建,默认是启用的
静态Pod特点:
1、yaml只能是pod,不能使用控制器 2、pod是由kubelet拉起的,只管理当前节点上yaml 3、kubelet会定期扫描静态pod目录 /etc/kubernetes/manifests/ 根据目录下的yaml启动或删除pod,删除yaml就等于删除pod
在节点上写好yaml文件即可,在master节点会自动创建pod,由kubelet自动拉起
在master上查看
kubelet会定时扫描/etc/kubernetes/mamfests/目录下的文件