[A-00225]簡単なマイクロサービスを作る(2)

前回はpod同士での通信を行いましたが、今回は1つのpodにあるコンテナ間での通信を行います。

・ServiceAを作る

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.example</groupId>
	<artifactId>service-a</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>service-a</name>

	<properties>
		<java.version>21</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
			<version>3.4.1</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<version>3.4.1</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<version>3.4.1</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<version>3.4.1</version>
				<configuration>
					<executable>true</executable>
				</configuration>
				<executions>
					<execution>
						<goals>
							<goal>repackage</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>

</project>
FROM openjdk:21

VOLUME /tmp
ADD target/service-a-0.0.1-SNAPSHOT.jar service-a.jar

EXPOSE 8181

ENTRYPOINT ["java","-jar","service-a.jar"]
spring:
  application:
    name: service-a
  main:
    banner-mode: "off"
server:
  port: 8181
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ServiceAApplication {

	public static void main(String[] args) {
		SpringApplication.run(ServiceAApplication.class, args);
	}

}
package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ServiceAController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello from ServiceA.";
    }
}

上記をDocker buildしてローカルのDocker Hubに登録しておきます。

docker build ./ -t service-a:latest

・ServiceBを作る

ServiceAの接続先(終端)のServiceBを作ります。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.example</groupId>
	<artifactId>service-b</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>service-b</name>

	<properties>
		<java.version>21</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
			<version>3.4.1</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<version>3.4.1</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<version>3.4.1</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<version>3.4.1</version>
				<configuration>
					<executable>true</executable>
				</configuration>
				<executions>
					<execution>
						<goals>
							<goal>repackage</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>

</project>
FROM openjdk:21

VOLUME /tmp
ADD target/service-b-0.0.1-SNAPSHOT.jar service-b.jar

EXPOSE 8282

ENTRYPOINT ["java","-jar","service-b.jar"]
spring:
  application:
    name: service-b
  main:
    banner-mode: "off"
server:
  port: 8282
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ServiceBApplication {

	public static void main(String[] args) {
		SpringApplication.run(ServiceBApplication.class, args);
	}

}
package com.example.demo;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {
    
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class ServiceBController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/call-service-a")
    public String callServiceA() {
        return restTemplate.getForObject("http://localhost:8181/hello", String.class);
    }
}

上記を作成し、docker buildします。

docker build ./ -t application-b:latest

次にkubernetesでapplyするためのyamlファイルを作成します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: service
spec:
  replicas: 1
  selector:
    matchLabels:
      app: service
  template:
    metadata:
      labels:
        app: service
    spec:
      containers:
      - name: service-a
        image: service-a:latest
        imagePullPolicy: IfNotPresent
        # 下記は入れても入れなくてもどっちでも良い
        # ports:
        # - containerPort: 8181
      - name: service-b
        image: service-b:latest
        imagePullPolicy: IfNotPresent
        # 下記は入れても入れなくてもどっちでも良い
        # ports:
        # - containerPort: 8282
---
apiVersion: v1
kind: Service
metadata:
  name: service-svc
spec:
  selector:
    app: service
  ports:
  - port: 8282
    targetPort: 8282
  type: LoadBalancer

上記をapplyして接続します。

kubectl apply -f service_deployment.yml

k8sのloadbalancerは8282ポートで穴を開けてますのでcurlして通信します。

curl http://localhost:8282/call-a-service

レスポンスが返ってきたらOKです。

・Appendix

参考文献はこちら

https://docs.spring.io/spring-cloud-kubernetes/reference/examples.html

https://github.com/salaboy/s1p_docs?tab=readme-ov-file

https://medium.com/@chnwsw01/spring-cloud-kubernetes-79c4a81e089b

https://github.com/nicolaka/netshoot

https://parasmani300.medium.com/deploying-microservices-on-kubernetes-with-spring-cloud-gateway-and-google-oauth2-0-security-8eb707ee3176

https://github.com/Parasmani300/cloud-accounts

https://stackoverflow.com/questions/52838330/spring-boot-maven-plugin-not-generating-executable-jar

https://qiita.com/studio_meowtoon/items/9c07e20b4124d8c5f972

https://docs.oracle.com/cd/F33069_01/orchestration/kubectl-delete.html

https://sysdig.com/blog/kubernetes-errimagepull-imagepullbackoff

https://kubernetes.io/ja/docs/tutorials/stateless-application/expose-external-ip-address

https://qiita.com/yuanying/items/704a173033410d882eea

https://qiita.com/m2mtu/items/dcb02e9ee2f34b78ead7

https://cloud.spring.io/spring-cloud-kubernetes/reference/html

https://kubernetes.io/docs/tasks/configure-pod-container/translate-compose-kubernetes

https://qiita.com/saleo_2764/items/a15e32e2f9c7a75b74c2

https://stackoverflow.com/questions/48247437/spring-boot-docker-microservices-resttemplate-exception

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

*