【初心者向けハンズオン】GKE(Google Kuberenetes Engine)にJavaアプリデプロイ ~Step3:APコンテナ作成~

1. はじめに

本記事では、Kubernetes上にSpring Bootで構築したアプリを動作させるハンズオンをご紹介します。ひととおり実施して基本を理解すれば、ご自身で開発したアプリもKubernetes上で運用できるようになると思いますので、ぜひトライしてみて下さい。今回はStep2としてAPコンテナの作成方法をご説明します。

2. ハンズオン環境

作業端末:Windows11
Kubernetesクラスタ:GKE Autopilot
仮想サーバ:GCE(CentOS9)

オンプレでKuberntesインストールからやってみたいという方がいれば、下記を参考にして構築してもらえればと思います。
【初心者向け】Kubernetes学習向けのハンズオン(Linux(CentOS))

3. システム構成

Kubernetes上に構築するシステム構成を記載します。Web/AP、DBのシンプルなシステム構成で構築しています。AP PodについてはJavaが動作するDocker Imageをデプロイし、Executable Jarを起動することでアプリケーションを動作させます。

4. APコンテナの作成

4.1 Dockerイメージ作成
まず、Dockerイメージの作成、Docker Hubへのアップロードをしていきましょう。下記を参考に実施してみて下さい。
【初心者向けハンズオン】KubernetesでJava(Spring Boot)アプリデプロイ ~Step2:APコンテナ作成~

4.2 Docker Hubログイン
Docker Hub にログインしてイメージをダウンロードできるようにしましょう。

PS C:\Program Files\gke\manifest> docker login -u eeengineer1111
Password:
Login Succeeded
PS C:\Program Files\gke\manifest>

4.3 AP Pod作成
Dockerイメージの準備ができたので、AP Podを作成していきましょう。下記の通りdeployment向けのマニフェストを作成します。
imageの項目にDocker Hubに登録したイメージを指定して下さい。

PS C:\Program Files\gke\manifest> cat .\quizapp-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: quizapp
  name: quizapp
  namespace: quizapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: quizapp
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: quizapp
    spec:
      containers:
      - image: eeengineer1111/quizapp
        ports:
        - containerPort: 8080
        name: quizapp
        resources: {}
status: {}
PS C:\Program Files\gke\manifest>

deploymentのマニフェストを適用します。下記の通りquizappのPodのSTATUSがRunningになっていれば成功です。

PS C:\Program Files\gke\manifest> kubectl apply -f quizapp-deployment.yaml
Warning: autopilot-default-resources-mutator:Autopilot updated Deployment quizapp/quizapp: defaulted unspecified 'cpu' resource for containers [quizapp] (see http://g.co/gke/autopilot-defaults).
deployment.apps/quizapp created
PS C:\Program Files\gke\manifest> kubectl get pod -n quizapp
NAME                        READY   STATUS    RESTARTS   AGE
postgres-7667d96d7c-khrtv   1/1     Running   0          23m
quizapp-dfd69c89d-7tvl6     1/1     Running   0          4m59s
PS C:\Program Files\gke\manifest>

続いてquizappのserviceを作成します。Step3でIngress Gateway経由で接続する際に必要となりますので、この時点で作成しておきましょう。下記の通りマニフェストを作成してください。

PS C:\Program Files\gke\manifest> cat .\quizapp-service.yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: quizapp
  name: quizapp
  namespace: quizapp
spec:
  type: LoadBalancer
  ports:
  - name: https
    port: 443
    targetPort: 8080
    protocol: TCP
  selector:
    app: quizapp
status:
  loadBalancer: {}
PS C:\Program Files\gke\manifest>

serviceのマニフェストを適用します。下記の通りquizappのserviceが取得できれば成功です。EXTERNAL-IPが割り当てられるまで少し時間がかかるのでお待ちください。

PS C:\Program Files\gke\manifest> kubectl apply -f .\quizapp-service.yaml
service/quizapp created
PS C:\Program Files\gke\manifest>
PS C:\Program Files\gke\manifest> kubectl get svc -o wide -n quizapp
NAME       TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE   SELECTOR
postgres   LoadBalancer   34.118.227.19    34.133.217.102   5432:32100/TCP   40m   app=postgres
quizapp    LoadBalancer   34.118.235.150   34.44.154.70     443:31947/TCP    29s   app=quizapp
PS C:\Program Files\gke\manifest>

4.4 AP Podの動作確認
AP Podの動作確認をしていきましょう。まずはkubectl getコマンドに-o wideオプションをつけて、quizapp Podに直接アクセスするためのIPアドレスを取得します。

PS C:\Program Files\gke\manifest> kubectl get pod -o wide -n quizapp
NAME                        READY   STATUS    RESTARTS   AGE     IP           NODE                                       NOMINATED NODE   READINESS GATES
postgres-7667d96d7c-khrtv   1/1     Running   0          23m     10.99.0.20   gk3-quizapp-cluster-pool-2-92325431-klrn   <none>           <none>
quizapp-dfd69c89d-7tvl6     1/1     Running   0          5m22s   10.99.0.67   gk3-quizapp-cluster-pool-2-5e080215-lsfd   <none>           <none>
PS C:\Program Files\gke\manifest>

podのログを確認してみましょう。下記の通りSpring Bootアプリが正常に起動できていれば成功です!

PS C:\Program Files\gke\manifest> kubectl logs quizapp-dfd69c89d-7tvl6 -n quizapp

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.3.7)

2025-03-19T21:40:40.458Z  INFO 1 --- [  restartedMain] eeengineer.quizapp.QuizApplication       : Starting QuizApplication v1.0 using Java 21 with PID 1 (/app.jar started by root in /)
2025-03-19T21:40:40.484Z  INFO 1 --- [  restartedMain] eeengineer.quizapp.QuizApplication       : No active profile set, falling back to 1 default profile: "default"
2025-03-19T21:40:41.012Z  INFO 1 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2025-03-19T21:40:41.012Z  INFO 1 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2025-03-19T21:40:49.906Z  INFO 1 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2025-03-19T21:40:50.432Z  INFO 1 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 465 ms. Found 3 JPA repository interfaces.
2025-03-19T21:40:54.298Z  INFO 1 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
2025-03-19T21:40:54.355Z  INFO 1 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2025-03-19T21:40:54.355Z  INFO 1 --- [  restartedMain] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.34]
2025-03-19T21:40:54.465Z  INFO 1 --- [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2025-03-19T21:40:54.467Z  INFO 1 --- [  restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 13449 ms
2025-03-19T21:40:55.255Z  INFO 1 --- [  restartedMain] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
2025-03-19T21:40:55.515Z  INFO 1 --- [  restartedMain] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 1.0
2025-03-19T21:40:55.593Z  INFO 1 --- [  restartedMain] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
2025-03-19T21:40:56.892Z  INFO 1 --- [  restartedMain] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
2025-03-19T21:40:57.008Z  INFO 1 --- [  restartedMain] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2025-03-19T21:40:58.237Z  INFO 1 --- [  restartedMain] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection org.postgresql.jdbc.PgConnection@1caefc35
2025-03-19T21:40:58.240Z  INFO 1 --- [  restartedMain] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2025-03-19T21:40:58.380Z  WARN 1 --- [  restartedMain] org.hibernate.orm.deprecation            : HHH90000025: PostgreSQLDialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
2025-03-19T21:41:03.122Z  INFO 1 --- [  restartedMain] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
Hibernate:
    alter table if exists quiz
       alter column explain set data type varchar(255)
Hibernate:
    alter table if exists roles
       alter column roleid set data type bigint
Hibernate:
    alter table if exists users_roles
       alter column role_id set data type bigint
Hibernate:
    alter table if exists users_roles
       add constraint FKj6m8fwv7oqv74fcehir1a9ffy
       foreign key (role_id)
       references roles
Hibernate:
    alter table if exists users_roles
       add constraint FK2o0jvgh89lemvvo17cbqvdxaa
       foreign key (user_id)
       references users
2025-03-19T21:41:03.655Z  INFO 1 --- [  restartedMain] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2025-03-19T21:41:05.717Z  WARN 1 --- [  restartedMain] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2025-03-19T21:41:05.777Z  WARN 1 --- [  restartedMain] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with an AuthenticationProvider bean. UserDetailsService beans will not be used for username/password login. Consider removing the AuthenticationProvider bean. Alternatively, consider using the UserDetailsService in a manually instantiated DaoAuthenticationProvider.
2025-03-19T21:41:06.062Z  INFO 1 --- [  restartedMain] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
2025-03-19T21:41:08.868Z  INFO 1 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2025-03-19T21:41:09.031Z  INFO 1 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
2025-03-19T21:41:09.085Z  INFO 1 --- [  restartedMain] eeengineer.quizapp.QuizApplication       : Started QuizApplication in 33.059 seconds (process running for 62.163)
PS C:\Program Files\gke\manifest>

5. まとめ

APコンテナ作成のハンズオンは以上となります。Step2では個別のAP Podに対してアクセスできることを確認しました。Step3ではIngress経由でアクセスすることで、AP Podへのアクセスを振り分ける方法についてご紹介します。
【初心者向けハンズオン】GKE(Google Kuberenetes Engine)にJavaアプリデプロイ ~Step3:APコンテナ作成~

6. 参考文献

コメント