YAZONG 我的开源

Kubernetes(七)(7.1)定时任务迁移kubernetes

  , , ,
0 评论0 浏览

目的:让K8S定期的调度这个服务。把定时任务跑到K8S集群中。

类似于在Linux中的crontab。

相同的结构的项目在docker化和迁移K8S的过程中,它的流程都是一样的。

K8S调度方式

image.png

想把一个服务运行在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

image.png

#第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

image.png

制作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