Skaffold:让K8S开发工作变得简单
Skaffold:讓K8S開發工作變得簡單
本文介紹在開發過程中,Skaffold自動化build和deploy應用到K8S集群。
Skaffold是由Google發布的命令行工具,專注于促進K8S應用的持續deployment。自動化building和deploying到k8s集群的任務,可以讓開發者專注于編寫代碼。Skaffold是不是很有趣呢,讓我們來仔細觀察一下吧。
簡介
2019年11月份,Skaffold普遍可用的版本發布了,承諾自動化開發工作流程,以此來節省開發者的時間。那么,Skaffold提供哪些功能呢?
- 當你開發的時候,檢測代碼的變動
- 基于你的Dockerfile或者Jib自動化build和創建你的artifacts(也就是Docker image)
- 給artifacts打tag
- 把artifacts發布/部署到你的kubernetes集群
為了熟悉Skaffold,我們使用minikube來運行一個本地的K8S集群,部署K8S的命令行工具kubectl。
更深入了解Skaffold,建議讀者去官方網站去查看文檔和例子。本文使用的源代碼都在github是可見的。
先決條件
開始之前,我們需要安裝minikube,kubectl和Skaffold,OS版本是Ubuntu 18.04
安裝Minikube
Minikube(1.6.2)的安裝工作在Linux上非常簡單。如果使用Windows操作系統,請查詢我們的過往文章,操作步驟還是非常復雜,未來可能會有所改善。
首先,檢查我們的OS是否開啟了虛擬化支持
$ egrep -q 'vmx|svm' /proc/cpuinfo && echo yes || echo no yes命令的輸出是yes,我們不需要額外執行命令了。
下載并安裝minikube
$ curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_1.6.2.deb && sudo dpkg -i minikube_1.6.2.deb啟動minikube
$ minikube start minikube v1.6.2 on Ubuntu 18.04 Automatically selected the 'virtualbox' driver (alternates: [none]) Downloading VM boot image ... > minikube-v1.6.0.iso.sha256: 65 B / 65 B [--------------] 100.00% ? p/s 0s > minikube-v1.6.0.iso: 150.93 MiB / 150.93 MiB [-] 100.00% 8.44 MiB p/s 18s Creating virtualbox VM (CPUs=2, Memory=2000MB, Disk=20000MB) ... Preparing Kubernetes v1.17.0 on Docker '19.03.5' ... Downloading kubelet v1.17.0 Downloading kubeadm v1.17.0 Pulling images ... Launching Kubernetes ... Waiting for cluster to come online ... Done! kubectl is now configured to use "minikube"安裝Kubectl
Kubectl的安裝手冊可以在kubernetes官網查看。對于LinuxOS,我們需要執行下面的步驟,使用kubectl version命令可以確認是否安裝成功。
$ curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl $ chmod +x ./kubectl $ sudo mv ./kubectl /usr/local/bin/kubectl $ kubectl version Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.0", GitCommit:"70132b0f130acc0bed193d9ba59dd186f0e634cf", GitTreeState:"clean", BuildDate:"2019-12-07T21:20:10Z", GoVersion:"go1.13.4", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.0", GitCommit:"70132b0f130acc0bed193d9ba59dd186f0e634cf", GitTreeState:"clean", BuildDate:"2019-12-07T21:12:17Z", GoVersion:"go1.13.4", Compiler:"gc", Platform:"linux/amd64"}安裝Skaffold
Skaffold的安裝文檔可以在官網查看。安裝方法非常和kubectl非常類似。
$ curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 $ chmod +x skaffold $ sudo mv skaffold /usr/local/bin $ skaffold version v1.1.0創建Demo應用
我們將會創建一個簡單的Spring Boot demo應用。我們使用Spring MVC,創建一個REST endpoint,將會返回一個歡迎信息。
我們的Pom包含了下面的依賴關系和插件
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>其中的HelloController包含一個方法,返回歡迎信息和執行的主機地址。
@RestController public class HelloController { @RequestMapping("/hello") public String hello() { StringBuilder message = new StringBuilder("Hello Skaffold!"); try { InetAddress ip = InetAddress.getLocalHost(); message.append(" From host: " + ip); } catch (UnknownHostException e) { e.printStackTrace(); } return message.toString(); } }使用Skaffold
現在我們已經完成了所有的準備,是時候開始使用Skaffold了。現在,我們故意遺漏一些Skaffold需要的重要配置,這可以讓我們來檢查報錯信息和解決方法。
生成skaffold.yaml
Skaffold需要一個skaffold.yaml文件,包含你需要使用的開發工作流程。可以在你的項目目錄里使用init命令來自動生成。
$ skaffold init FATA[0000] one or more valid Kubernetes manifests is required to run skaffoldSkaffold init并不會為我們創建k8s的mainfest文件,我們需要手動創建。
我們將會使用kubectl工具來創建k8s的部署文件。我們把Kubectl命令的輸出復制到deployment.yaml文件中。 命令行參數 –dry-run 可以確保部署并沒有被執行, -oyaml參數會輸出配置文件,我們可以從中復制內容。
$ kubectl create deployment myskaffoldplanet --image=docker.io/mydeveloperplanet/myskaffoldplanet --dry-run -oyaml apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: myskaffoldplanet name: myskaffoldplanet spec: replicas: 1 selector: matchLabels: app: myskaffoldplanet strategy: {} template: metadata: creationTimestamp: null labels: app: myskaffoldplanet spec: containers: - image: docker.io/mydeveloperplanet/myskaffoldplanet name: myskaffoldplanet resources: {} status: {}再次執行skaffold init命令,返回新的錯誤
$ skaffold init FATA[0000] one or more valid builder configuration (Dockerfile or Jib configuration) must be present to build images with skaffold; please provide at least one build config and try again or run `skaffold init --skip-build`上面的報錯是可以預見的,因為我們并沒有提供Dockerfile或者Jib配置。使用我們在之前的文章中提到的方法,我們使用Jib。添加Jib Maven插件到我們的pom中。這一次我們不提供認證,因為我們并不會把docker鏡像提交給docker倉庫。
<plugin> <groupId>com.google.cloud.tools</groupId> <artifactId>jib-maven-plugin</artifactId> <version>1.8.0</version> <configuration> <!-- openjdk:11.0.5-jre --> <from> <image>openjdk@sha256:b3e19d27caa8249aad6f90c6e987943d03e915bbf3a66bc1b7f994a4fed668f6</image> </from> <to> <image>docker.io/${docker.image.prefix}/${project.artifactId}</image> <tags> <tag>${project.version}</tag> </tags> </to> <container> <mainClass>com.mydeveloperplanet.myskaffoldplanet.MySkaffoldPlanetApplication</mainClass> <user>nobody</user> </container> </configuration> </plugin>為了使用Jib,我們需要在skaffold命令中加入參數: –XxenableJibInit
$ skaffold init --XXenableJibInit apiVersion: skaffold/v2alpha1 kind: Config metadata: name: myskaffoldplanet build: artifacts:- image: docker.io/mydeveloperplanet/myskaffoldplanet jib: {} deploy: kubectl: manifests:- k8s/deployment.yaml Do you want to write this configuration to skaffold.yaml? [y/n]: y Configuration skaffold.yaml was written You can now run [skaffold build] to build the artifacts or [skaffold run] to build and deploy or [skaffold dev] to enter development mode, with auto-redeploySkaffold持續發布
為了配合skaffold dev命令做實驗,我們已經做好了所有配置。這將會掃描我們的項目,一旦有變更,便會自動build和部署到我們的K8S集群中。執行下面的命令
$ skaffold dev我們的應用正在被build部署到K8S集群中。操作可以在minikube的dashboard里觀察。
minikube dashboard因為并沒有創建service的緣故,現在還不能調用我們的URL。我們通過NodePort方式映射端口8080。使用kubectl命令生成service yaml文件,復制內容(忽略label)到文件service.yaml到k8s的目錄:
$ kubectl expose deployment myskaffoldplanet --type=NodePort --port=8080 --dry-run -oyamlapiVersion: v1 kind: Service metadata: creationTimestamp: null labels: app: myskaffoldplanet app.kubernetes.io/managed-by: skaffold-v1.1.0 skaffold.dev/builder: local skaffold.dev/cleanup: "true" skaffold.dev/deployer: kubectl skaffold.dev/docker-api-version: "1.40" skaffold.dev/run-id: c8fc23d2-85f5-453a-bc22-19f4a9ec88a6 skaffold.dev/tag-policy: git-commit skaffold.dev/tail: "true" name: myskaffoldplanet spec: ports: - port: 8080 protocol: TCP targetPort: 8080 selector: app: myskaffoldplanet type: NodePort status: loadBalancer: {}還有,把service.yaml文件作為mainfest文件添加到skaffold.yaml文件:
deploy: kubectl: manifests:- k8s/deployment.yaml - k8s/service.yamlSkaffold會迅速觀察到這些變化,自動創建服務??梢栽赟kaffold console輸出中得到確認:
Starting deploy... - deployment.apps/myskaffoldplanet configured - service/myskaffoldplanet created Watching for changes...使用Kubectl來確認服務已經被創建:
$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 443/TCP 24h myskaffoldplanet NodePort 10.96.65.87 8080:30272/TCP 42sNodePort已經被分配給30272端口。我們現在可以引用我們的Rest endpoint:
$ curl $(minikube ip):30272/hello Hello Skaffold! From host: myskaffoldplanet-76f44959c9-tcvw5/172.17.0.6在HelloController中修改歡迎致辭:
StringBuilder message = new StringBuilder(“Hello there, Skaffold!”);
再一次地,改動自動被Skaffold識別,后臺進程中,我們的應用正在被build和部署。我們再一次調用URL:
$ curl $(minikube ip):30272/hello Hello there, Skaffold! From host: myskaffoldplanet-54b59fb785-hczn8/172.17.0.7我們也可以使用skaffold up命令來基于需求部署應用:
$ skaffold run ... Starting deploy... - deployment.apps/myskaffoldplanet created - service/myskaffoldplanet created You can also run [skaffold run --tail] to get the logsTroubleshooting
之前執行skaffold dev和skaffold run命令遇到的報錯如下:
rpc error: code = Unknown desc = Error response from daemon: pull access denied for mydeveloperplanet/myskaffoldplanet, repository does not exist or may require 'docker login': denied: requested access to the resource is denied解決方案:把下面的內容加入到skaffold.yaml文件。
build: local: push: false artifacts: - image: docker.io/mydeveloperplanet/myskaffoldplanet jib: {}結論
本文中,我們觀察了開發環境中Skaffold自動build和部署應用給K8S集群的過程。本文的內容僅僅是稍微觀察Skaffold提供的功能,但是skaffold確實讓人印象深刻。Skaffold絕對是值得使用和后續觀察的。
原文鏈接:https://dzone.com/articles/skaffold-k8s-development-made-easy
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的Skaffold:让K8S开发工作变得简单的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: kubectl更换镜像命令
- 下一篇: linux vscode设置在集成终端中