众所周知的事实是,使用Kubernetes开发应用程序很麻烦。这就是为什么围绕它开发生态系统,以便开发人员可以专注于对他们最重要的事情,即编写代码的原因。在本文中,我将介绍由Google开发的另一种工具Skaffold 。
那么到底什么是脚手架?
Skaffold处理构建,推送和部署应用程序的工作流程。- Skaffold.dev
它试图解决什么问题?
如前所述,使用Kubernetes开发应用程序并非易事。这就是Skaffold发挥作用的地方,因为它简化了在Kubernetes上运行的应用程序的开发和部署。它管理着整个工作流程,在本地或在远程Kubernetes集群上开发和部署应用程序时,您会获得即时反馈。
以下是使用Skaffold的一些好处。
Lightweight
它仅是一个客户端实用程序,因此无需设置群集或进行任何维护。
容易分享
在您的团队成员之间共享是毫不费力的,因为您只需要执行以下操作即可开始:
git clone skaffold run
易于发展
为了使您的应用程序甚至在本地容器化,您必须做很多事情。对于本地开发,您可能需要在Kubernetes上进行构建,推送和部署应用程序之类的操作。并且有不同的命令集(docker blah,kubectl blah blah等)以及用于工作流的每个阶段的工具。有了Skaffold,您只有一个神奇的命令,skaffold run or skaffold dev而且您很聪明。这并不意味着您不必依赖那些需要将应用程序构建和部署到Kubernetes的工具。只需运行一个命令,开发就会容易得多。
好的。足够的理论,让我们开始吧。
Spring Boot应用程序剖析
在本教程中,我将使用一个Spring Boot应用程序,当通过/statesREST端点访问该应用程序时,该应用程序将显示印度各州及其首都。该应用程序使用内存中的H2数据库,该数据库在应用程序的开头插入行并将其保存在内存中。源代码可在此处获得。
先决条件
对于此演示,必须安装以下内容:
我使用过macOS,但是您可以使用任何喜欢的操作系统或有使用经验的操作系统。我已经提到过Minikube和kubetcl安装是可选的,因为如果您已经安装了Docker桌面,则可以使用其他博客文章中提到的步骤来启用Kubernetes 。
如果您不想在安装过程中闲逛,则可以跳过上述步骤,而改用Google Cloud Shell,它可以从浏览器提供开发人员就绪的环境。我已经在文章末尾介绍了这一点。
脚手架入门 要开始使用Skaffold,您需要一个skaffold.yaml文件。为此,我们可以运行以下命令。
Skaffold
skaffold.yaml
skaffold init
但是,您会收到以下错误消息。
skaffold init 2 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`
该错误似乎是不言自明的。它告诉我们Skaffold正在项目中寻找Dockerfile或Jib配置。
Skaffold当前支持以下构建器:
with the --XXenableJibInit flag
--XXenableBuildpacksInit
XML格式
<plugin> <groupId>com.google.cloud.tools</groupId> <artifactId>jib-maven-plugin</artifactId> <version>2.7.0</version> <configuration> <from> <image>gcr.io/distroless/java:11</image> </from> <to> <image>docker.io/my-docker-id/my-app</image> </to> </configuration> </plugin>
启用Jib支持
根据官方文件:
skaffold init还可以识别Maven和Gradle项目,并将自动建议jib建造者。当前,jib工件检测默认情况下处于禁用状态,但可以使用标志启用--XXenableJibInit。 现在运行skaffold init与--XXenableJibInit.然而,它会与下面的错误再次失败。
skaffold init --XXenableJibInit one or more valid Kubernetes manifests are required to run skaffold
由于我们尚未创建Kubernetes清单(部署,pod,服务等),并且Skaffold存在已知问题,因此我们必须使用以下kubectl命令手动创建它们,以解决此错误,
创建部署:
kubectl create deployment states --image=docker.io/hiashish/indian-states --dry-run -oyaml apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: states name: states spec: replicas: 1 selector: matchLabels: app: states strategy: {} template: metadata: creationTimestamp: null labels: app: states spec: containers: - image: docker.io/hiashish/indian-states name: indian-states resources: {} status: {}
创建服务:
kubectl expose deployment states --type=NodePort --port=8080 --dry-run -oyaml apiVersion: v1 kind: Service metadata: creationTimestamp: null labels: app: states name: states spec: ports: - port: 8080 protocol: TCP targetPort: 8080 selector: app: states type: NodePort status: loadBalancer: {}
现在,我们已经创建了部署和服务。请确保将以上命令的输出复制到目录中的YAML文件中k8s。
现在运行 skaffold init --XXenableJibInit
skaffold init --XXenableJibInit apiVersion: skaffold/v2beta10 kind: Config metadata: name: indian-states build: artifacts: - image: docker.io/hiashish/indian-states jib: project: com.example:indian-states deploy: kubectl: manifests: - k8s/mydeployment.yaml - k8s/myservice.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-redeploy
最后,skaffold.yaml创建一个文件。
使用skaffold dev命令 现在,我们已经完成了必需的设置,以开始持续构建和部署Kubernetes应用程序。现在,我们只需运行以下命令即可在本地启动CI / CD工作流程。
skaffold dev
skaffold dev Listing files to watch... - docker.io/hiashish/indian-states Generating tags... - docker.io/hiashish/indian-states -> docker.io/hiashish/indian-states:31ff588-dirty Checking cache... - docker.io/hiashish/indian-states: Found Locally Tags used in deployment: - docker.io/hiashish/indian-states -> docker.io/hiashish/indian-states:43f7c470a60b876c7579ed3041b64024b774e9808851ad83b6817701d0188cc5 Starting deploy... - deployment.apps/states created - service/states created Waiting for deployments to stabilize... - deployment/states is ready. Deployments stabilized in 3.986641128s Press Ctrl+C to exit Watching for changes... [indian-states] [indian-states] . ____ _ __ _ _ [indian-states] /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ [indian-states] ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ [indian-states] \\/ ___)| |_)| | | | | || (_| | ) ) ) ) [indian-states] ' |____| .__|_| |_|_| |_\__, | / / / / [indian-states] =========|_|==============|___/=/_/_/_/ [indian-states] :: Spring Boot :: (v2.4.0) [indian-states] [indian-states] 2020-12-07 12:31:57.906 INFO 1 --- [ main] c.e.i.IndianStatesApplication : Starting IndianStatesApplication using Java 11.0.6 on states-7c55b8d5b6-vx5hq with PID 1 (/app/classes started by root in /) [indian-states] 2020-12-07 12:31:57.924 INFO 1 --- [ main] c.e.i.IndianStatesApplication : No active profile set, falling back to default profiles: default [indian-states] 2020-12-07 12:32:00.127 INFO 1 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JDBC repositories in DEFAULT mode. [indian-states] 2020-12-07 12:32:00.175 INFO 1 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 24 ms. Found 0 JDBC repository interfaces. [indian-states] 2020-12-07 12:32:01.969 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) [indian-states] 2020-12-07 12:32:02.015 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] [indian-states] 2020-12-07 12:32:02.016 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.39] [indian-states] 2020-12-07 12:32:02.242 INFO 1 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext [indian-states] 2020-12-07 12:32:02.243 INFO 1 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4107 ms [indian-states] 2020-12-07 12:32:03.449 INFO 1 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... [indian-states] 2020-12-07 12:32:04.078 INFO 1 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. [indian-states] 2020-12-07 12:32:04.880 INFO 1 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' [indian-states] 2020-12-07 12:32:05.939 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' [indian-states] 2020-12-07 12:32:06.002 INFO 1 --- [ main] c.e.i.IndianStatesApplication : Started IndianStatesApplication in 9.688 seconds (JVM running for 11.632)
如您所见,该应用程序现已构建并部署到本地Kubernetes集群。我们首先必须NodePort使用kubectl命令来检查应用程序的本地访问应用程序。
kubectl get all NAME READY STATUS RESTARTS AGE pod/states-7c55b8d5b6-vx5hq 1/1 Running 0 5m47s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 21h service/states NodePort 10.110.135.236 <none> 8080:30925/TCP 5m47s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/states 1/1 1 1 5m48s NAME DESIRED CURRENT READY AGE replicaset.apps/states-7c55b8d5b6 1 1 1 5m48s
该NodePort分配给我们的应用程序是30925.让我们调用/states我们的应用程序的REST端点,并看看会发生什么。
curl localhost:30925/states [{"name":"Andra Pradesh","capital":"Hyderabad"},{"name":"Arunachal Pradesh","capital":"Itangar"},{"name":"Assam","capital":"Dispur"},{"name":"Bihar","capital":"Patna"},{"name":"Chhattisgarh","capital":"Raipur"},{"name":"Goa","capital":"Panaji"},{"name":"Gujarat","capital":"Gandhinagar"},{"name":"Haryana","capital":"Chandigarh"},{"name":"Himachal Pradesh","capital":"Shimla"},{"name":"Jharkhand","capital":"Ranchi"},{"name":"Karnataka","capital":"Bangalore"},{"name":"Kerala","capital":"Thiruvananthapuram"},{"name":"Madhya Pradesh","capital":"Bhopal"},{"name":"Maharashtra","capital":"Mumbai"},{"name":"Manipur","capital":"Imphal"},{"name":"Meghalaya","capital":"Shillong"},{"name":"Mizoram","capital":"Aizawi"},{"name":"Nagaland","capital":"Kohima"},{"name":"Orissa","capital":"Bhubaneshwar"},{"name":"Rajasthan","capital":"Jaipur"},{"name":"Sikkim","capital":"Gangtok"},{"name":"Tamil Nadu","capital":"Chennai"},{"name":"Telangana","capital":"Hyderabad"},{"name":"Tripura","capital":"Agartala"},{"name":"Uttaranchal","capital":"Dehradun"},{"name":"Uttar Pradesh","capital":"Lucknow"},{"name":"West Bengal","capital":"Kolkata"},{"name":"Punjab","capital":"Chandigarh"}]
看起来很棒!
让我们做一个小的代码更改,看看Skaffold是否可以重新触发整个工作流程。我将replicas在部署YAML文件中从1更改为2,看看Skaffold是否可以使用增加的来重新部署应用程序replicas。
已重新部署应用程序:
Tags used in deployment: - docker.io/hiashish/indian-states -> docker.io/hiashish/indian-states:43f7c470a60b876c7579ed3041b64024b774e9808851ad83b6817701d0188cc5 Starting deploy... - deployment.apps/states configured Waiting for deployments to stabilize... - deployment/states is ready. Deployments stabilized in 4.032230153s Watching for changes... [indian-states] [indian-states] . ____ _ __ _ _ [indian-states] /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ [indian-states] ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ [indian-states] \\/ ___)| |_)| | | | | || (_| | ) ) ) ) [indian-states] ' |____| .__|_| |_|_| |_\__, | / / / / [indian-states] =========|_|==============|___/=/_/_/_/ [indian-states] :: Spring Boot :: (v2.4.0) [indian-states]
现在,replicaset使用再次检查我们的应用程序kubectl。
kubectl get all NAME READY STATUS RESTARTS AGE pod/states-7c55b8d5b6-br9zx 1/1 Running 0 20s pod/states-7c55b8d5b6-vx5hq 1/1 Running 0 16m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 21h service/states NodePort 10.110.135.236 <none> 8080:30925/TCP 16m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/states 2/2 2 2 16m NAME DESIRED CURRENT READY AGE replicaset.apps/states-7c55b8d5b6 2 2 2 16m
如您所见,重新部署后,副本数增加到了2个,这是预期的。
skaffold runCommand
这类似于skaffold dev,但是主要区别在于中描述的工作流程skaffold.yaml 仅执行一次。建议将其用于生产工作流程。
使用Cloud Shell
如果您在本地安装了所有必需的依赖项(Docker,Minikube,Skaffold),那就很好了。否则,您可以通过使用Google的Cloud Shell复制本地Kubernetes环境来跳过安装部分,就像我在先决条件部分中所述的那样。Cloud Shell提供了基于浏览器的终端/ CLI和编辑器,并且预先安装了Skaffold,Minikube和Docker,并且它是免费的。只需运行以下命令即可。确保Docker和Minikube在Cloud Shell环境中启动并运行。
git clone https://github.com/yrashish/indian-states
如您在上面看到的,我们还可以在Cloud Shell中运行Spring Boot应用程序,并获得了预期的输出。
原文链接:http://codingdict.com