背景
雖然用了好幾年的kubernetes服務了。但是服務應用的類型一般都是deployments statefuset daemonset幾種類型,至於job cronjob確實是沒有怎麼用過。現在正好有一個php應用的服務需要每五分鐘執行一次,恰好可以去熟悉一個CronJob的使用!
首先還是複習一遍kubernetes 的workloads
參照:https://kubernetes.io/zh/docs/concepts/workloads/
- Deployment 和 ReplicaSet (替換原來的資源 ReplicationController)。 Deployment 很適合用來管理你的集羣上的無狀態應用,Deployment 中的所有 Pod 都是相互等價的,並且在需要的時候被換掉。
- StatefulSet 讓你能夠運行一個或者多個以某種方式跟蹤應用狀態的 Pods。 例如,如果你的負載會將數據作持久存儲,你可以運行一個 StatefulSet,將每個 Pod 與某個 PersistentVolume 對應起來。你在 StatefulSet 中各個 Pod 內運行的代碼可以將數據複製到同一 StatefulSet 中的其它 Pod 中以提高整體的服務可靠性。
- DaemonSet 定義提供節點本地支撐設施的 Pods。這些 Pods 可能對於你的集羣的運維是 非常重要的,例如作為網絡鏈接的輔助工具或者作為網絡 插件 的一部分等等。每次你向集羣中添加一個新節點時,如果該節點與某 DaemonSet 的規約匹配,則控制面會為該 DaemonSet 調度一個 Pod 到該新節點上運行。
- Job 和 CronJob。 定義一些一直運行到結束並停止的任務。Job 用來表達的是一次性的任務,而 CronJob 會根據其時間規劃反覆運行。
- 第三方工作負載資源,通過 定製資源定義(CRD)添加第三方工作負載資源
---分割符
Pods
當然了以上的工作負載都最終管理的對象都是Pod,所以Pod該放在那裏呢?_Pod_ 是可以在 Kubernetes 中創建和管理的、最小的可部署的計算單元.Pod 類似於共享名字空間和文件系統卷的一組 Docker 容器。
參照:https://kubernetes.io/zh/docs/concepts/workloads/pods/
Cronjob的第一次使用
明確一下需求
1. 鏡像 php7.4 以上 需要安裝gd mysql依賴
2. 每五分鐘運行一次
基礎鏡像構建
由於我php鏡像都是與nginx打包在一起的。且這個應用就算一個純php應用。就決定重新構建一個鏡像,參照dockerhub:https://registry.hub.docker.com/_/php
Dockerfile
FROM php:7.4-fpm
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng-dev \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) gd pdo_mysql mysqli
為了克服惰性,工作環境切換到linux了截圖不方便就不上圖了。鏡像倉庫使用了騰訊雲的個人版倉庫tcr(貌似前段時間都合併一起了,過去就是個人版倉庫)
構建鏡像,並推送基礎鏡像到基礎倉庫:
docker build -t ccr.ccs.tencentyun.com/laya-master/php:7.4-fpm .
docker push ccr.ccs.tencentyun.com/laya-master/php:7.4-fpm
jenkins pipeline流水線構建
流水線參照:https://duiniwukenaihe.blog.csdn.net/article/details/116661391
參照:stage 的單選多選問題
pipeline做when 判斷
when {
environment name: 'XXXX', value: 'true'
}
子項目文件夾下添加Dockerfile
FROM ccr.ccs.tencentyun.com/xxxx/php:7.4-fpm
ADD html /var/www/html
WORKDIR /var/www/html[
注:由於為這是git項目下增加了一個新的子文件目錄並不是新項目就不寫完整的pipeline只添加片段了!
1. 構建上傳鏡像到鏡像倉庫
stage('docker build worldmap-job') {
agent { label "build" }
when {
environment name: 'worldmap-job', value: 'true'
}
steps {
sh " cd worldmap-job&&docker build -t ccr.ccs.tencentyun.com/xxxx/worldmap-job:$data ."
withCredentials([usernamePassword(credentialsId: 'xxxx', passwordVariable: 'dockerPassword', usernameVariable: 'dockerUser')]) {
sh "docker login -u ${dockerUser} -p ${dockerPassword} ccr.ccs.tencentyun.com"
sh "docker push ccr.ccs.tencentyun.com/xxxx/worldmap-job:$data"
}
}
}
2. 部署應用
stage("develop worldmap-job") {
when {
environment name: 'worldmap-job', value: 'true'
}
steps {
sh "sed -e 's/{data}/$data/g' /home/jenkins/workspace/yaml/develop/worldmap-job.tpl > /home/jenkins/workspace/yaml/develop/worldmap-job.yaml"
sh "sed -e 's/{data}/$data/g' /home/jenkins/workspace/yaml/develop/worldmap-job.tpl > /home/jenkins/workspace/yaml/develop/worldmap-job.yaml"
sh "sudo kubectl apply -f /home/jenkins/workspace/yaml/develop/worldmap-job.yaml --namespace=develop"
sh "sudo kubectl apply -f /home/jenkins/workspace/yaml/develop/worldmap-job.yaml --namespace=develop"
}
}
注意我這裏格式可能跟一般用户不一樣,因為部署這裏為用了並行 parallel 。參照:https://duiniwukenaihe.blog.csdn.net/article/details/116661391
tpl模板文件
worldmap-job.tpl
apiVersion: batch/v1
kind: CronJob
metadata:
name: worldmap-job
spec:
schedule: "*/5 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: worldmap-job
image: ccr.ccs.tencentyun.com/xxxx/worldmap-job:{data}
imagePullPolicy: IfNotPresent
args:
- /usr/local/bin/php
- /var/www/html/DrawLandsMap.php
- run_job
- "6"
envFrom:
- configMapRef:
name: deploy
env:
- name: PHP_MEM_LIMIT
value: "256M"
resources:
requests:
memory: "256M"
cpu: "250m"
limits:
memory: "1024M"
cpu: "2000m"
imagePullSecrets:
- name: tencent
restartPolicy: OnFailure
關於幾點要注意的:
schedule schedule: "/5 *" ###5分鐘執行一次
imagePullPolicy imagePullPolicy: IfNotPresent ###imagePullPolicy自斷貌似三必須的,我copy deployments的配置過來改的開始沒有加這個貌似報錯了
args 執行腳本依然是 數要加引號強調
envFrom 是我引用了configmap中的變量
env 限制了php limit
sesources 做了資源限制
imagePullSecrets 鏡像倉庫secret
restartPolicy 容器重啓策略
now jenkins觸發構建。登陸kubernetes集羣驗證:
[root@k8s-master-01 develop]# kubectl get cronjob -n develop
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
worldmap-job */5 * * * * False 0 2m36s 28h
[root@k8s-master-01 develop]# kubectl get pods -n develop|grep world
worldmap-job-27357635-274hp 0/1 Completed 0 12m
worldmap-job-27357640-wb459 0/1 Completed 0 7m53s
worldmap-job-27357645-cndb4 0/1 Completed 0 2m53s
[root@k8s-master-01 develop]# kubectl get jobs --watch -n develop
NAME COMPLETIONS DURATION AGE
worldmap-job-27357635 1/1 11s 13m
worldmap-job-27357640 1/1 11s 8m43s
worldmap-job-27357645 1/1 12s 3m43s
貌似就是這樣的,只現實當前最新的3個job當然了有興趣的可以研究一下更改這個的數量?(successfulJobsHistoryLimit: 3) k可以修改一下。查看了一遍pod日誌是正常的。還有job5分鐘觸發的時間是0 5 10這樣依次的
一些自己想到的:
- cronjob要做資源的限制
- cronjob也可以掛載configmap
- 任務類型的應用可以嘗試應用job or cronjob
- 鏡像還是需要重新構建的,不同的應用。這樣可以減少鏡像的大小,減少漏洞的可能性