当前位置: 首页 > 工具软件 > Skaffold > 使用案例 >

Skaffold使用简介

景承教
2023-12-01

Skaffold使用简介

1、简介

Skaffold是一个为kubernetes上的应用开发提供CD支持的命令行工具。使用skaffold,你可以方便的将本地代码部署到kubernetes上进行测试。通过 skaffold.yaml ,你可以管理项目的构建(build)和部署(deploy)过程。同时,也可以定义多套方案(profile),每套方案对应不同的构建(build)和部署(deploy)过程,根据不同场景选择。

2、使用方法

2.1、环境说明

  • Skaffold version: v0.21.1
  • Operating system: macOS 10.14.3 Darwin Kernel Version 18.2.0
  • Kubernetes version: v1.13.0
  • Kubectl version: v1.10.11
  • Helm version: Client: v2.12.3、Server: v2.12.1
  • 项目结构说明:
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配置文件

2.2、软件安装

软件安装比较简单,需要用到的kubectl、helm、skaffold都是可直接运行的二进制文件,docker安装也比较简单,步骤不再赘述~

2.3、使用指南

  • Skaffold的几乎所有操作都集中在skaffold.yaml文件上,编辑好skaffold.yaml文件,执行skaffold命令即可
  • Skaffold的使用方法按照官方文档的结构和顺序来记录~

2.3.1、Using builders

#####2.3.1.1、使用jib构建

  • 使用gradle + jib进行编译、打包、制作镜像,先看一下build.gradle文件的内容:
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}"
    }
}
  • 这里我们先使用skaffold进行build,deploy放在下面描述,skaffold.yaml文件的内容:
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文件

2.3.1.2、使用docker构建
  • Dockerfile文件内容
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
  • Skaffold.yaml文件内容
apiVersion: skaffold/v1beta3
kind: Config
build:
  artifacts:
    - image: registry.kube.com/skaffold/cloud-boot
  local:
    push: true       # 决定在镜像文件构建完成后是否执行push操作
  • 执行 skaffold build 命令

构建镜像介绍以上两种,GCB和Kaniko没有用过,后面后机会用到再补充~

2.3.2、Using deployers

2.3.2.1、使用kubectl部署
  • 使用kubectl需要编写对应的部署描述文件,比如:kubernetes-cloud-boot.yml,文件内容如下:
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,在部署时需要注意,后面有更方便的处理方式~

  • Skaffold.yaml文件内容
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
2.3.2.2、使用helm部署
  • Skaffold.yaml文件内容
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命令,且做好相应配置

2.3.3、Using taggers

上面提到过,在默认情况下,skaffold会自动生成镜像的tag。下面的内容介绍如何自定义tag生成规则。

2.3.3.1、使用gitCommit

默认的tag生成策略,取值为 Git commit ID,对应的skaffold.yaml内容如下:

apiVersion: skaffold/v1beta3
kind: Config
build:
  artifacts:
    - image: registry.kube.com/skaffold/cloud-boot
      jibGradle: {}
  tagPolicy:
    gitCommit: {}
2.3.3.2、使用sha256
apiVersion: skaffold/v1beta3
kind: Config
build:
  artifacts:
    - image: registry.kube.com/skaffold/cloud-boot
      jibGradle: {}
  tagPolicy:
    sha256: {}

使用sha256的好处:每次生成的镜像的tag都不一样,所以每次部署之后,kubernetes都会重建pod~

2.3.3.3、使用环境变量
  • Skaffold.yaml文件内容
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
2.3.3.4、使用时间戳
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

2.3.4、Using file sync

在dev模式下,使用sync可以在某些文件发生改变时,直接将文件复制到容器内,从而省掉制作镜像的步骤,提供效率。这对于静态文件来说,非常有用。

  • skaffold.yml文件内容
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文件无法同步~

2.3.5、Using port forwarding

2.3.6、Using profiles

上面的内容主要定义了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 来指定

2.3.7、Using testers

主要用来测试容器内文件的结构是否完整,比如:检测文件是否存在

2.3.8、Using templated fields

前面的内容中,我们留下了一个问题:根据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.templatedeploy.helm.releases.setValueTemplates
  • 目前内置的变量有:IMAGE_NAMEDIGEST

3、注意事项

  • 使用Jib + skaffold时,结果镜像的名称由skaffold决定

4、参考资料

 类似资料: