Skaffold是一个为kubernetes上的应用开发提供CD支持的命令行工具。使用skaffold,你可以方便的将本地代码部署到kubernetes上进行测试。通过 skaffold.yaml ,你可以管理项目的构建(build)和部署(deploy)过程。同时,也可以定义多套方案(profile),每套方案对应不同的构建(build)和部署(deploy)过程,根据不同场景选择。
core -- 项目跟路径
core/chart -- helm chart路径
core/src -- 源码路径
core/src/main
core/src/main/java
core/src/main/resources -- 配置文件路径
core/src/main/resources/a.txt -- sync测试文件
core/build.gradle
core/kubernetes-cloud-boot.yml -- 项目在kubernetes上的部署文件
core/b.txt -- sync测试文件
core/Dockerfile -- Dockerfile文件
core/skaffold.yaml -- skaffold配置文件
软件安装比较简单,需要用到的kubectl、helm、skaffold都是可直接运行的二进制文件,docker安装也比较简单,步骤不再赘述~
- Skaffold的几乎所有操作都集中在
skaffold.yaml
文件上,编辑好skaffold.yaml
文件,执行skaffold命令即可- Skaffold的使用方法按照官方文档的结构和顺序来记录~
#####2.3.1.1、使用jib构建
plugins {
id 'java'
id "org.springframework.boot" version "2.1.2.RELEASE"
id 'com.google.cloud.tools.jib' version '1.0.0'
}
group 'com.chenlei.boot'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.1.2.RELEASE'
}
jib {
container {
useCurrentTimestamp = true
jvmFlags = ['-Dfile.encoding=UTF-8']
}
from {
image = '192.168.101.88:5000/distroless/java:latest'
}
to {
image = "192.168.101.88:5000/${project.name}:${version}"
}
}
apiVersion: skaffold/v1beta3
kind: Config
build:
artifacts:
- image: registry.kube.com/skaffold/cloud-boot # 结果镜像名称,镜像会被直接push
jibGradle: {} # 使用jib进行镜像构建,不指定时,默认为docker,可选值:docker、bazel、jibMaven、jibGradle
skaffold build
命令chenleis-MacBook-Pro:core chenlei$ pwd
/Users/chenlei/IdeaProjects/cloud-boot/core
chenleis-MacBook-Pro:core chenlei$ skaffold build
Starting build...
Building [registry.kube.com/skaffold/cloud-boot]...
Setting image creation time to current time; your image may not be reproducible.
Containerizing application to registry.kube.com/skaffold/cloud-boot:32571c3a0984c909399a82de148b002c...
Base image '192.168.101.88:5000/distroless/java' does not use a specific image digest - build may not be reproducible
Container entrypoint set to [java, -Dfile.encoding=UTF-8, -cp, /app/resources:/app/classes:/app/libs/*, com.chenlei.boot.Application]
Built and pushed image as registry.kube.com/skaffold/cloud-boot:32571c3a0984c909399a82de148b002c
Executing tasks:
[==============================] 100.0% complete
BUILD SUCCESSFUL in 1s
3 actionable tasks: 1 executed, 2 up-to-date
WARN[0001] Using digest instead of git commit: Running [git rev-parse --short HEAD]: stdout , stderr: fatal: not a git repository (or any of the parent directories): .git
, err: exit status 128: exit status 128
2019/01/31 13:33:26 existing blob: sha256:23a2c449a14a49f421bbbc339650e391bb237722ff1972c8761d26bb7932ec76
2019/01/31 13:33:26 existing blob: sha256:269521def953f8e22145983d8496b281bc1ecc258c07b45ef253af7d79b98216
2019/01/31 13:33:26 existing blob: sha256:2fd31c99b7a960c959aa54c84592526608e523884b14c9feda3570d379ccadb5
2019/01/31 13:33:26 existing blob: sha256:d5b96a299f00c11666a7ee1504a693b36076c1bdac3355594cbca6d530826abe
2019/01/31 13:33:26 existing blob: sha256:027c4c64f3fea95b3ee06f48ad0248e2f2b3448ed2acbf88ddbc725ab172bf0b
2019/01/31 13:33:26 existing blob: sha256:3e010093287c245d72a774033b4cddd6451a820bfbb1948c97798e1838858dd2
2019/01/31 13:33:26 existing blob: sha256:6c82fff81a84c0d8cda17fcaf21357459d3ffa25917fd1975437a17a6408b008
2019/01/31 13:33:27 registry.kube.com/skaffold/cloud-boot:dirty-94f9919: digest: sha256:94f99190d23f22742b082fb4e93938321d29c2f4a15fcfb3f2c1c4ca32d05282 size: 1243
Build complete in 1.675632469s
Starting test...
Test complete in 18.573µs
registry.kube.com/skaffold/cloud-boot -> registry.kube.com/skaffold/cloud-boot:dirty-94f9919
结果镜像的名称由skaffold.yaml文件决定,而非build.gradle文件
FROM 192.168.101.88:5000/dmcop2/java:8
MAINTAINER leichen.china@gmail.com
ADD ./src/main/resources/a.txt /
ADD ./b.txt /
CMD sleep infinity
apiVersion: skaffold/v1beta3
kind: Config
build:
artifacts:
- image: registry.kube.com/skaffold/cloud-boot
local:
push: true # 决定在镜像文件构建完成后是否执行push操作
skaffold build
命令构建镜像介绍以上两种,GCB和Kaniko没有用过,后面后机会用到再补充~
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
app: cloud-boot
name: cloud-boot
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: cloud-boot
template:
metadata:
labels:
app: cloud-boot
spec:
containers:
- name: cloud-boot
image: registry.kube.com/skaffold/cloud-boot:dirty-d940460 # 默认的镜像tag样式
imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
name: tcp
注意:因为没有指定tag,skaffold会生成默认的tag,在部署时需要注意,后面有更方便的处理方式~
apiVersion: skaffold/v1beta3
kind: Config
build: # build部分与deploy部分是独立的,可以随意组合
artifacts:
- image: registry.kube.com/skaffold/cloud-boot
local:
push: true
deploy:
kubectl:
manifests:
- kubernetes-cloud-boot.yml
flags:
apply:
- --force=true
- --grace-period=0
skaffold dev
或者 skaffold run
Dev模式下,当你修改项目文件时,skaffold会在自动重新打包并部署,run模式下需要执行 skaffold delete
删除之前的部署。
注意:
- 在dev模式下的重新部署类似重新执行
kubectl apply -f ....
,至于pod是否会重建,取决于kubernetes~,下文介绍的效果可能是你想要的~- 本地需要能够执行运行kubectl命令,且配置好kubeconfig
apiVersion: skaffold/v1beta3
kind: Config
build:
artifacts:
- image: registry.kube.com/skaffold/cloud-boot
jibGradle: {}
deploy:
helm:
releases:
- name: cloud-boot
chartPath: chart
setValues:
image.repository: registry.kube.com/skaffold/cloud-boot
image.tag: dirty-d940460
image.pullPolicy: "Always"
skaffold dev
或者 skaffold run
注意:
- 本地需要能直接运行helm命令,且做好相应配置
上面提到过,在默认情况下,skaffold会自动生成镜像的tag。下面的内容介绍如何自定义tag生成规则。
默认的tag生成策略,取值为 Git commit ID,对应的skaffold.yaml内容如下:
apiVersion: skaffold/v1beta3
kind: Config
build:
artifacts:
- image: registry.kube.com/skaffold/cloud-boot
jibGradle: {}
tagPolicy:
gitCommit: {}
apiVersion: skaffold/v1beta3
kind: Config
build:
artifacts:
- image: registry.kube.com/skaffold/cloud-boot
jibGradle: {}
tagPolicy:
sha256: {}
使用sha256的好处:每次生成的镜像的tag都不一样,所以每次部署之后,kubernetes都会重建pod~
apiVersion: skaffold/v1beta3
kind: Config
build:
artifacts:
- image: registry.kube.com/skaffold/cloud-boot
tagPolicy:
envTemplate:
template: "{{ .IMAGE_NAME }}:{{ .IMAGE_TAG }}"
local:
push: false
skaffold build
chenleis-MacBook-Pro:core chenlei$ export IMAGE_TAG=v1
chenleis-MacBook-Pro:core chenlei$ skaffold build
apiVersion: skaffold/v1beta3
kind: Config
build:
artifacts:
- image: registry.kube.com/skaffold/cloud-boot
tagPolicy:
dateTime:
format: "2006-01-02"
timezone: "UTC"
local:
push: false
注意:
format
的完整格式为2006-01-02_15-04-05.999_MST
在dev模式下,使用sync可以在某些文件发生改变时,直接将文件复制到容器内,从而省掉制作镜像的步骤,提供效率。这对于静态文件来说,非常有用。
apiVersion: skaffold/v1beta3
kind: Config
build:
artifacts:
- image: registry.kube.com/skaffold/cloud-boot
sync:
'**/*.txt': /
tagPolicy:
sha256: {}
local:
push: false
deploy:
kubectl:
manifests:
- kubernetes-cloud-boot.yml
在dev模式下,sync可以有效的提高效率,但是skaffold目前任处于快速高发节点,存在很对bug,我进行上述练习时,发现仅b.txt文件被同步,但是a.txt文件无法同步~
略
上面的内容主要定义了build和deploy两部分,可以控制构建和部署过程。通常,在实际工作中,我们需要在不同的环境下发布和测试应用,为此,可以定义多个不同的profile,例如:
apiVersion: skaffold/v1beta3
kind: Config
profiles:
- name: p1
build:
artifacts:
- image: registry.kube.com/skaffold/cloud-boot
tagPolicy:
dateTime:
format: "2006-01-02"
timezone: "UTC"
local:
push: true
deploy:
kubectl:
manifests:
- kubernetes-cloud-boot.yml
- name: p2
build:
artifacts:
- image: registry.kube.com/skaffold/cloud-boot
jibGradle: {}
tagPolicy:
sha256: {}
deploy:
helm:
releases:
- name: cloud-boot
chartPath: chart
setValueTemplates:
image.repository: "{{ .IMAGE_NAME }}"
image.tag: "{{ .DIGEST }}"
image.pullPolicy: "Always"
在执行 skaffold dev
或者 skaffold run
时,通过参数 -p
或者 --profile
来指定
主要用来测试容器内文件的结构是否完整,比如:检测文件是否存在
前面的内容中,我们留下了一个问题:根据tagPolicy每次生成的镜像名称不一致,那么我们在部署应用的时候,就需要每次调整镜像名称。此时可以使用内置的模版变量来引用实际的值,例如:
apiVersion: skaffold/v1beta3
kind: Config
build:
artifacts:
- image: registry.kube.com/skaffold/cloud-boot
tagPolicy:
sha256: {}
deploy:
helm:
releases:
- name: cloud-boot
chartPath: chart
setValueTemplates: # 使用内置变量必须使用setValueTemplates
image.repository: "{{ .IMAGE_NAME }}"
image.tag: "{{ .DIGEST }}"
image.pullPolicy: "Always"
- 目前能使用内置变量的字段仅有:
build.tagPolicy.envTemplate.template
和deploy.helm.releases.setValueTemplates
- 目前内置的变量有:
IMAGE_NAME
、DIGEST