目的:让K8S定期的调度这个服务。把定时任务跑到K8S集群中。
类似于在Linux中的crontab。
相同的结构的项目在docker化和迁移K8S的过程中,它的流程都是一样的。
K8S调度方式
想把一个服务运行在K8S中,必须要先有个镜像。得先有一个基础镜像,然后要考虑如何把服务放到基础镜像中,弄清服务运行起来所有的相关文件,要把这些文件全部找出来放到一起,然后放到基础镜像中,那么就可以通过Dockerfile去构建镜像了。
制作K8S镜像,首先得分析一下这个业务,看看是怎么来做服务发现的,服务之间互相调用的时候,该以什么样的方式服务发现,策略,确认好,那么就可以配置K8S的配置文件了,配置写好之后就可以去调度了。
源码:cronjob
源码下载地址:”https://git.imooc.com/coding-335/mooc-k8s-demo”
package com.mooc.demo.cronjob;
import java.util.Random;
public class Main {
public static void main(String args[]) {
Random r = new Random();
int time = r.nextInt(20)+10;
System.out.println("I will working for "+time+" seconds!");
try{
Thread.sleep(time*1000);
}catch (Exception e) {
e.printStackTrace();
}
System.out.println("All work is done! Bye!");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mooc</groupId>
<artifactId>cronjob-demo</artifactId>
<version>1.0-SNAPSHOT</version>
</project>
把服务做到镜像中
#第1步:搞定基础镜像
#查询java的服务镜像地址:”https://hub.docker.com/”
[root@node-1 ~]# docker pull openjdk:8-jre-alpine
[root@node-1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
openjdk 8-jre-alpine f7a292bbb70c 3 years ago 84.9MB
[root@node-1 ~]# docker tag openjdk:8-jre-alpine hub.mooc.com/kubernetes/openjdk:8-jre-alpine
[root@node-1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
openjdk 8-jre-alpine f7a292bbb70c 3 years ago 84.9MB
hub.mooc.com/kubernetes/openjdk 8-jre-alpine f7a292bbb70c 3 years ago 84.9MB
#要确保node-3的harbor正常运行。
#可以在node-3的harbor控制台看到,要注意hub.mooc.com代理的是node-3的harbor,而node-2的harbor没开启服务,所以node-3和node-2现在并不是互通的。
[root@node-1 ~]# docker push hub.mooc.com/kubernetes/openjdk:8-jre-alpine
#第2步:搞定服务运行的相关文件
[root@node-1 ~]# mkdir -p /root/mooc-k8s-demo/cronjob-demo
[root@node-1 ~]# cd /root/mooc-k8s-demo/cronjob-demo
#在mooc-k8s-demo目录中上传了mooc-k8s-demo的GIT上的文件,自己maven打包。
[root@node-1 cronjob-demo]# java -jar cronjob-demo-1.0-SNAPSHOT.jar
-bash: java: command not found
[root@node-1 cronjob-demo]# java -jar cronjob-demo-1.0-SNAPSHOT.jar
no main manifest attribute, in cronjob-demo-1.0-SNAPSHOT.jar
#那么作为一个classpath加进来,找主函数的入口。
[root@node-1 cronjob-demo]# java -cp cronjob-demo-1.0-SNAPSHOT.jar com.mooc.demo.cronjob.Main
I will working for 20 seconds!
All work is done! Bye!
#第3步:构建镜像-DockerFile
[root@node-1 cronjob-demo]# cat Dockerfile
#基础镜像
FROM hub.mooc.com/kubernetes/openjdk:8-jre-alpine
#把程序(cronjob-demo-1.0-SNAPSHOT.jar要指定当前目录位置,不能指定服务器绝对目录)加载到基础镜像里,设置某个目录,这里是根目录中。
COPY cronjob-demo-1.0-SNAPSHOT.jar /cronjob-demo.jar
#运行。java命令。指定classpath。classpath的jar包。类名。
ENTRYPOINT ["java", "-cp", "/cronjob-demo.jar", "com.mooc.demo.cronjob.Main"]
#指定一个名字,构建一个镜像。注意这最后有个点。
[root@node-1 cronjob-demo]# docker build -t cronjob:v1 .
#测试镜像
[root@node-1 cronjob-demo]# docker run -it cronjob:v1
I will working for 27 seconds!
----
[root@node-1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
#只可在运行过程中看到这一行效果
994bf032bd96 cronjob:v1 "java -cp /cronjob-d¡" 3 seconds ago Up 2 seconds jovial_volhard
----
All work is done! Bye!
[root@node-1 ~]# docker ps
#上面运行完,查看docker进程就不会再有cronjob的运行镜像了。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
#把这个镜像打个tag放到harbor仓库中
[root@node-1 cronjob-demo]# docker tag cronjob:v1 hub.mooc.com/kubernetes/cronjob:v1
[root@node-1 cronjob-demo]# docker push hub.mooc.com/kubernetes/cronjob:v1
[root@node-1 cronjob-demo]# docker images|grep cronjob
REPOSITORY TAG IMAGE ID CREATED SIZE
cronjob v1 de144742e70a 6 minutes ago 84.9MB
hub.mooc.com/kubernetes/cronjob v1 de144742e70a 6 minutes ago 84.9MB
制作K8S服务并调度
#第1步:服务发现策略
这里没网络,没接口,那么不需要服务发现。
#第2步:编写K8S配置文件
[root@node-1 cronjob-demo]# mkdir -p /root/mooc-k8s-demo/configs
[root@node-1 cronjob-demo]# cd ../configs/
[root@node-1 configs]# pwd
[root@node-1 configs]# cat cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: cronjob-demo
spec:
schedule: "*/1 * * * *"
successfulJobsHistoryLimit: 3
suspend: false
concurrencyPolicy: Forbid
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
metadata:
labels:
app: cronjob-demo
spec:
restartPolicy: Never
containers:
- name: cronjob-demo
image: hub.mooc.com/kubernetes/cronjob:v1
#配置containerd可以443访问harbor
[root@node-2/3 ~]# vim /etc/containerd/config.toml
#修改102行属性下的内容
102 [plugins."io.containerd.grpc.v1.cri".registry]
103 [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
104 [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
105 endpoint = ["https://registry-1.docker.io"]
#在105行下加入新内容
106 [plugins."io.containerd.grpc.v1.cri".registry.mirrors."hub.mooc.com"]
107 endpoint = ["http://hub.mooc.com"]
108 [plugins."io.containerd.grpc.v1.cri".registry.configs]
109 [plugins."io.containerd.grpc.v1.cri".registry.configs."hub.mooc.com".tls]
110 insecure_skip_verify = true
111 [plugins."io.containerd.grpc.v1.cri".registry.configs."hub.mooc.com".auth]
112 username="pusher"
113 password="Pusher12345"
#这里只需重启node-3的harbor,因为node-2的harbor已经停掉了。
#当重启docker/containerd的时候,harbor要先停掉再开开。
[root@node-3 harbor]# docker-compose stop
#重启containerd
[root@node-2/3 ~]# systemctl status containerd
[root@node-2/3 harbor]# systemctl restart containerd
[root@node-2/3 ~]# systemctl status containerd
#重启harbor
[root@node-3 harbor]# docker-compose up -d
#检查进程
[root@node-2/3 ~]# crictl ps
[root@node-2/3 ~]# docker ps
[root@node-2 harbor]# netstat -lntup|grep 443
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 8054/nginx: master
tcp6 0 0 :::443 :::* LISTEN 8054/nginx: master
[root@node-2 harbor]# netstat -lntup|grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 8054/nginx: master
tcp6 0 0 :::80 :::* LISTEN 8054/nginx: master
[root@node-3 harbor]# netstat -lntup|grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2390/docker-proxy
tcp6 0 0 :::80 :::* LISTEN 2395/docker-proxy
[root@node-3 harbor]# netstat -lntup|grep 443
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 2363/docker-proxy
tcp6 0 0 :::443 :::* LISTEN 2369/docker-proxy
#第3步:运行K8S服务
#创建cronjob.yaml
[root@node-1 configs]# kubectl apply -f cronjob.yaml
cronjob.batch/cronjob-demo created
#得等一分钟
[root@node-1 configs]# kubectl get cronjob
#这里调度一次了,不断执行看到不同的效果。
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
cronjob-demo */1 * * * * False 1 22s 68s
[root@node-1 configs]# kubectl get pods -o wide -n default
cronjob-demo-1668156660-qn8g8 1/1 Running 0 13s 10.200.139.122 node-3 <none> <none>
#再
[root@node-3 harbor]# crictl ps -a|grep cronjob
589b32c9aabd4 de144742e70a1 48 seconds ago Exited cronjob-demo 0 9cb795b6aebf6
[root@node-3 harbor]# crictl logs 589b32c9aabd4
#要注意的是这里只能输出RUNNNIG状态的POD的结果值。
I will working for 23 seconds!
All work is done! Bye!
停服务(可选)
#为节约资源,这里把cronjob.yaml停掉
[root@node-1 configs]# kubectl delete -f cronjob.yaml
cronjob.batch "cronjob-demo" deleted
[root@node-1 configs]# kubectl get pods -o wide -n default
[root@node-1 configs]# kubectl get cronjob
No resources found in default namespace.
解析:cronjob.yaml
[root@node-1 configs]# cat cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: cronjob-demo
spec:
schedule: "*/1 * * * *"
successfulJobsHistoryLimit: 3
suspend: false
concurrencyPolicy: Forbid
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
metadata:
labels:
app: cronjob-demo
spec:
restartPolicy: Never
containers:
- name: cronjob-demo
image: hub.mooc.com/kubernetes/cronjob:v1
Kind:类型CronJob;
Schedule与Linux的crontab表达式一致;
3success成功的历史限制个数:定时任务在运行结束时有个退出值,退出值是0表示成功,非0表示失败,跟Linux的普通运行程序规则一致。这里的限制意思:保存程序运行的现场,保存3份;程序运行的现场:POD,每调度请求POD之后,就算程序运行结束了,并不会把POD删除,而是会保留下来,而是保留最近的三个;
Suspend:false。是否停止。True相当于cronjob并不会真正的调度起来,而是只是把其编辑一下保存好了。False,会立即按照schedule去调度。
Policy:并行策略。定时任务跟普通任务不同,会运行也会停止,运行的时间不一定运行多长,如果每分钟运行一次,其中一个任务运行了3分钟,这个时候后边运行的任务,后边来的任务是一块来运行,还是把前面的任务顶掉,还是排队不允许同步,所以这里有个策略。
1failed跟3success对应。
jobTemplate:跟之前配置的Deployment很像,需要注意restartPollicy重启策略,此属性必须要有,没有默认值,当程序运行失败后,是否需要重启。
containers:指定的名字和镜像。
标题:Kubernetes(七)(7.1)定时任务迁移kubernetes
作者:yazong
地址:https://blog.llyweb.com/articles/2022/11/11/1668161978949.html