让我们构建最简单的Java Spring Boot应用程序,将其包装在Docker容器中,然后在K8s pod中使用该容器,该容器由K8s部署进行编排并通过服务公开。服务由两个pod和一个简单的负载平衡器提供支持,可以根据应用程序的需求轻松扩展。
项目结构:
├── Dockerfile ├── build.gradle ├── gradle │ └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── k8s │ └── depl.yaml ├── settings.gradle └── src └── main └── java └── hello ├── App.java └── HelloWorldCtrl.java
|
App.java是应用入口:
package hello;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication public class App {
public static void main(String[] args) { SpringApplication.run(App.class, args); }
}
|
上面的代码包含创建Spring Boot应用程序所需的最少代码。
下面HelloWorldCtrl.java包含一个简单的控制器,其映射的根路径(“/”),并返回问候语的字符串:
package hello;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RequestMapping;
@RestController public class HelloWorldCtrl {
@RequestMapping("/") public String index() { return "Greetings from Spring Boot!"; }
}
|
构建应用程序
我正在使用Gradle作为构建工具。该build.gradle文件也是最小文件,由以下几行组成:
plugins { id 'org.springframework.boot' version '2.3.3.RELEASE' id 'io.spring.dependency-management' version '1.0.8.RELEASE' id 'java' }
group = 'com.test' version = '0.0.1-SNAPSHOT' sourceCompatibility = '1.8'
repositories { mavenCentral() }
dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' }
|
创建K8s资源
为了创建K8s部署,我们需要一个Docker映像/镜像。让我们在我们的代码中添加以下几行Dockerfile:
FROM gradle:jdk10
COPY --chown=gradle:gradle . /app WORKDIR /app RUN gradle build
EXPOSE 8080 WORKDIR /app
CMD java -jar build/libs/gs-spring-boot-0.1.0.jar
|
Docker文件中的步骤:
- 将项目复制到 /app
- 使用Gradle构建项目
- 使用上一步的结果运行应用程序
现在,我们可以构建映像并推送到中心:
docker build -t marounbassam/hello-spring . docker push marounbassam/hello-spring
|
K8s的部署很简单。
它由部署和服务组成:apiVersion: extensions/v1beta1 kind: Deployment metadata: name: hello-world spec: replicas: 2 template: metadata: labels: app: hello-world visualize: "true" spec: containers: - name: hello-world-pod image: marounbassam/hello-spring ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: labels: visualize: "true" name: hello-world-service spec: selector: app: hello-world ports: - name: http protocol: TCP port: 8080 targetPort: 8080 type: ClusterIP
|
部署Deployment部分定义了Pod的两个副本,这些副本将运行根据image属性中指定的映像构建的容器。
服务Service部分是类型的ClusterIP(默认的Kubernetes服务)。它为我们提供了群集中其他应用程序可以访问的服务。
在集群中创建资源:
kubectl create -f <yaml_file>
|
+---------------------+ | hello-world-service | | | | 10.15.242.210 | +---------O-----------+ | +-------------O--------------------------O | | +---------O-----------+ +---------O-----------+ | pod 1 | | pod 2 | | | | | | hello-world | | hello-world | +---------------------+ +---------------------+
|
安装集群
$ kubectl get pods NAME READY STATUS RESTARTS AGE hello-world-5bb87c95-6h4kh 1/1 Running 0 7h hello-world-5bb87c95-bz64v 1/1 Running 0 7h $ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-world-service ClusterIP 10.15.242.210 <none> 8080/TCP 5s kubernetes ClusterIP 10.15.240.1 <none> 443/TCP 7h $ kubectl exec -it hello-world-5bb87c95-6h4kh bash $ (inside the pod) curl 10.15.242.210:8080 $ (inside the pod) Greetings from Spring Boot!
|
我们可以看到服务器已启动并且正在pod内运行。根据您的云提供商,您可以设置服务类型LoadBalancer并从集群外部访问应用程序。