この記事は chillSAP 夏の自由研究2022、8/4の記事として執筆しています。
はじめに
この記事は、Kyma runtimeのCommunity Code Challengeをやってみたシリーズの2回目です。このシリーズでは、Kyma runtimeのCode Challengeに参加して、開発の方法やその裏の仕組みについてわかったことをまとめていきます。
Week2の課題
Week2の課題は以下のようになっています。
リンク:Week 2 (July 13th, 2022 - July 20th, 2022)
- フォークしたリポジトリの中に自分のサービスを作る(内容は簡単なものでよい。言語も問わない)
- DockerやPodmanなどの技術を使ってサービスをコンテナ化する
- deployment.yamlを書く
- 自分のサービスをKyma runtimeにデプロイする
Week2で学んだこと
1. Dockerイメージの作成とリポジトリへのプッシュ
Dockerイメージをどこのリポジトリに格納するかについて、私には2つのオプションがありました。
①GitHubのレジストリを使用する
②Docker Hubを使用する
元のリポジトリがGitHubのレジストリにイメージを上げていたため、これに倣って①の方法をとることにしました。この方法はローカル環境にDockerがインストールされていなくても使うことができます。
GitHubのレジストリにDockerイメージをアップロードする方法
GitHubのレジストリにDockerイメージをアップロードするには、GitHub Actionを使用します。元のリポジトリを見てみると、Actionsタブに"Build and Push Docker Image"というワークフローが定義されています。ワークフローはdocker_build_and_push.yml
というファイルで設定されています。
ファイルの中身を見たところ、サービスへのパスが直接書かれていたりしたのでそのまま流用はできなさそうでした。そこで、teched2020-developer-keynoteのリポジトリにあるワークフローを参考にすることにしました。こちらはDockerfileが格納されたファイルパスやリソースのパスをインプットで指定できるため、汎用的に使うことができます。
参考:Developer Keynote - SANDBOX component part 2 - CF & K8S
実施したこと
Dockerイメージをアップロードするために実施したことは以下です。
- ローカルでweek2のブランチを作る
- my-serviceフォルダを作成し、その中でサービスを定義(内容はserviceとほぼ同じ。Dockerfileは変更なし)
- .github/workflowsにimage-build-and-publish.ymlをコピーペースト
- GitHubにプッシュ
- "Run workflow"をクリックし、ブランチ(week2)、ディレクトリ(my-service)を指定してワークフローを実行
あとはdeployment.yamlにこのイメージを指定してデプロイするだけです。
2. ポートのマッピング
week2のdeployment.yamlはweek1のものとほとんど同じにしていたのですが、ポートだけ変えてみようと思い各ポートを8080
から8081
に変えてみました。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-service
labels:
app: my-service
spec:
replicas: 1
selector:
matchLabels:
app: my-service
template:
metadata:
labels:
app: my-service
spec:
containers:
- name: my-service
image: ghcr.io/miyasuta/sap-community-code-challenge-cloud-native/my-service:latest
imagePullPolicy: Always
ports:
- containerPort: 8081
resources:
limits:
ephemeral-storage: 256M
memory: 256M
cpu: 100m
requests:
cpu: 100m
ephemeral-storage: 256M
memory: 256M
imagePullSecrets:
- name: regcred
status: {}
---
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-service
ports:
- port: 8081
targetPort: 8081
protocol: TCP
---
apiVersion: gateway.kyma-project.io/v1alpha1
kind: APIRule
metadata:
name: my-service
spec:
gateway: kyma-gateway.kyma-system.svc.cluster.local
service:
name: my-service
port: 8081
host: my-service
rules:
- path: /.*
methods: ["GET"]
accessStrategies:
- handler: noop
config: {}
デプロイはできたものの、ブラウザからAPIにアクセスすると以下のエラーになりました。
upstream connect error or disconnect/reset before headers. reset reason: connection failure, transport failure reason: delayed connect error: 111
原因は、このサービスで使用しているポートは8080なのにcontainerPortに8081を指定していたためです。(process.env.PORT
にdeployment.yamlで指定したポートが入ってくれるのかなと思ったのですが、そうではないようです)
const express = require('express')
const app = express()
app.get('/', (req, res) => {
res.send(`Your Node.js service is running on port ${PORT}...`);
});
app.get('/hello/:communityID', (req, res) => {
res.send(`Hello Kyma, hello ${req.params.communityID}!`);
});
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Server listening on port ${PORT}...`);
});
ポート8080で動くサービスをポート8081から公開したい場合、以下の設定にする必要があります。他の人が提出した内容を見てこれに気づくことができました。
参考
以下のブログがポートのマッピングについて理解するのに役立ちました。
Kyma for Dymmies [2]: First Simple Microservice with Security