見出し画像

oc new-app golangでServiceが作成されなかったので調査した話

経緯

SHIFTグループ会社の株式会社システムアイでインフラエンジニアやSREの仕事をしている川野です。

少し前に実際に試していて気づいたのですが、OpenShiftクラスタに組み込まれているコンテナレジストリにあるgolangイメージを使って oc new-app コマンドでアプリケーションをデプロイしようとしたところ、Serviceが作成されませんでした。それに対し、他のイメージ(php,java,python,ruby等)を使ってデプロイするとServiceが作成されたので、この差異について疑問を持ち調べてみました。

※実際に実行したコマンド出力は以下の通りになります。

$ oc new-app php --dry-run
--> Found image 3919673 (6 weeks old) in image stream "openshift/php" under tag "7.4-ubi8" for "php"

    Apache 2.4 with PHP 7.4
    -----------------------
    PHP 7.4 available as container is a base platform for building and running various PHP 7.4 applications and frameworks. PHP is an HTML-embedded scripting language. PHP attempts to make it easy for developers to write dynamically generated web pages. PHP also offers built-in database integration for several commercial and non-commercial database management systems, so writing a database-enabled webpage with PHP is fairly simple. The most common use of PHP coding is probably as a replacement for CGI scripts.

    Tags: builder, php, php74, php-74


--> Creating resources ...
    deployment.apps "php" created (dry run)
    service "php" created (dry run)
--> Success (dry run)
$ oc new-app golang --dry-run
--> Found image a190a3b (15 months old) in image stream "openshift/golang" under tag "1.14.7-ubi8" for "golang"

    Go 1.14.7
    ---------
    Go Toolset available as a container is a base platform for building and running various Go applications and frameworks. Go is an easy to learn, powerful, statically typed language in the C/C++ tradition with garbage collection, concurrent programming support, and memory safety features.

    Tags: builder, golang, golang114, rh-golang114, go


--> Creating resources ...
    deployment.apps "golang" created (dry run)
--> Success (dry run)

環境

以下のような環境で調査しました。

$ oc version
Client Version: 4.9.15
Server Version: 4.9.13
Kubernetes Version: v1.22.3+e790d7f

調べてみる

以下引用文は、Red Hat 公式ドキュメントの「表2.2 new-app 出力オブジェクト」の「Serviceオブジェクト」の説明です。

new-app コマンドは、インプットイメージで公開ポートを検出しようと試みます。公開されたポートで数値が最も低いものを使用して、そのポートを公開するサービスを生成します。

ドキュメントをみる限りでは、new-appコマンドで指定されたイメージの公開ポートを検出しようと試みるそうです。

公開ポートがあればServiceを作成するし、なければ作成しないってこと・・・?

つづいて、ImageStreamTagを確認してみます。

$ oc -nopenshift describe istag/php:latest | grep -i expose
Exposes Ports:  8080/tcp, 8443/tcp
        io.openshift.expose-services=8080:http
$ oc -nopenshift describe istag/golang:latest | grep -i expose
Exposes Ports:  <none>
        io.openshift.expose-services=

確かにgolangイメージでは公開ポートは設定されていないようでした。

続いて実際に使われているDockerfileを調べてみます。
ImageStreamTagのdescriptionからでもイメージ名やdigest値を追えますが、ImageStreamのdescriptionの方がわかりやすい?かもしれません。

$ oc -nopenshift describe is/php
Name:           php
Namespace:      openshift
Created:        8 hours ago
Labels:         samples.operator.openshift.io/managed=true
Annotations:        openshift.io/display-name=PHP
            openshift.io/image.dockerRepositoryCheck=2022-01-26T23:35:14Z
            samples.operator.openshift.io/version=4.9.13
Image Repository:   image-registry.openshift-image-registry.svc:5000/openshift/php
Image Lookup:       local=false
Unique Images:      3
Tags:           5

7.4-ubi8 (latest)
  tagged from registry.redhat.io/ubi8/php-74:latest
    prefer registry pullthrough when referencing this tag

  Build and run PHP 7.4 applications on UBI 8. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/s2i-php-container/blob/master/7.4/README.md.
  Tags: builder, php
  Supports: php:7.4, php
  Example Repo: https://github.com/sclorg/cakephp-ex.git

  * registry.redhat.io/ubi8/php-74@sha256:34f2d80adac5a8aeb65c045e3a8c1caea56d53704d8d5cddec588c9008ceb5ea
      8 hours ago

7.3
  tagged from registry.redhat.io/rhscl/php-73-rhel7:latest
    prefer registry pullthrough when referencing this tag

  Build and run PHP 7.3 applications on RHEL 7. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/s2i-php-container/blob/master/7.3/README.md.
  Tags: builder, php, hidden
  Supports: php:7.3, php
  Example Repo: https://github.com/sclorg/cakephp-ex.git

  * registry.redhat.io/rhscl/php-73-rhel7@sha256:06e7d909830c4fd48b31baba7d5cff2c23c73fb268996f69559393c6a9007d74
      8 hours ago

7.3-ubi8
  tagged from registry.redhat.io/ubi8/php-73:latest
    prefer registry pullthrough when referencing this tag

  Build and run PHP 7.3 applications on UBI 8. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/s2i-php-container/blob/master/7.3/README.md.
  Tags: builder, php
  Supports: php:7.3, php
  Example Repo: https://github.com/sclorg/cakephp-ex.git

  * registry.redhat.io/ubi8/php-73@sha256:0365b13ccf86a3c448255baf645439730f3883c8dbc55d4f93b66d3c9f02c98a
      8 hours ago

7.3-ubi7
  tagged from registry.redhat.io/ubi7/php-73:latest
    prefer registry pullthrough when referencing this tag

  Build and run PHP 7.3 applications on UBI 7. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/s2i-php-container/blob/master/7.3/README.md.
  Tags: builder, php
  Supports: php:7.3, php
  Example Repo: https://github.com/sclorg/cakephp-ex.git

  * registry.redhat.io/ubi7/php-73@sha256:06e7d909830c4fd48b31baba7d5cff2c23c73fb268996f69559393c6a9007d74
      8 hours ago

上記のイメージ名やdigest値を元に調べたDockerfileが以下なのですが、EXPOSEされています。

FROM ubi8/s2i-base:rhel8.5

# This image provides an Apache+PHP environment for running PHP
# applications.

EXPOSE 8080
EXPOSE 8443

# Description
# This image provides an Apache 2.4 + PHP 7.4 environment for running PHP applications.
(以下略)

参照:Red Hat Ecosystem Catalog

これに対してgolangではどうでしょうか。
phpと同じようにImageStreamを調べます。

$ oc -nopenshift describe is/golang
Name:           golang
Namespace:      openshift
Created:        8 hours ago
Labels:         samples.operator.openshift.io/managed=true
Annotations:        openshift.io/display-name=Go
            openshift.io/image.dockerRepositoryCheck=2022-01-26T23:35:08Z
            samples.operator.openshift.io/version=4.9.13
Image Repository:   image-registry.openshift-image-registry.svc:5000/openshift/golang
Image Lookup:       local=false
Unique Images:      2
Tags:           3

1.14.7-ubi8 (latest)
  tagged from registry.redhat.io/ubi8/go-toolset:1.14.7
    prefer registry pullthrough when referencing this tag

  Build and run Go applications on UBI 8. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/golang-container/blob/master/README.md.
  Tags: builder, golang, go
  Supports: golang
  Example Repo: https://github.com/sclorg/golang-ex.git

  * registry.redhat.io/ubi8/go-toolset@sha256:59a74d581df3a2bd63ab55f7ac106677694bf612a1fe9e7e3e1487f55c421b37
      8 hours ago

1.13.4-ubi7
  tagged from registry.redhat.io/ubi7/go-toolset:1.13.4
    prefer registry pullthrough when referencing this tag

  Build and run Go applications on UBI 7. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/golang-container/blob/master/README.md.
  Tags: builder, golang, go
  Supports: golang
  Example Repo: https://github.com/sclorg/golang-ex.git

  * registry.redhat.io/ubi7/go-toolset@sha256:64fced5004d1d0a7d2028abc0963b2afdfaf5de45fd5b3faa2965164539fbaff
      8 hours ago

以下がDockerfileになりますが、予想通りEXPOSEされていないことがわかります。

FROM ubi8/s2i-base:rhel8.3

ENV NAME=golang \
    GO_MAJOR_VERSION=1 \
    GO_MINOR_VERSION=14 \
    CONTAINER_NAME="rhel8/go-toolset"

# Define the VERSION environment variable in a separate step, so we can
# re-use the GO_MAJOR_VERSION and GO_MINOR_VERSION variables. 
ENV VERSION=$GO_MAJOR_VERSION.$GO_MINOR_VERSION.7 \
    SUMMARY="Platform for building and running Go Applications" \
    DESCRIPTION="Go Toolset available as a container is a base platform for \
building and running various Go applications and frameworks. \
Go is an easy to learn, powerful, statically typed language in the C/C++ \
tradition with garbage collection, concurrent programming support, and memory safety features."

LABEL summary="$SUMMARY" \
      description="$DESCRIPTION" \
      io.k8s.description="$DESCRIPTION" \
      io.k8s.display-name="Go $VERSION" \
      io.openshift.tags="builder,golang,golang${GO_MAJOR_VERSION}${GO_MINOR_VERSION},rh-golang${GO_MAJOR_VERSION}${GO_MINOR_VERSION},go" \
      com.redhat.component="go-toolset-container" \
      com.redhat.license_terms="https://www.redhat.com/en/about/red-hat-end-user-license-agreements#UBI" \
      name="$CONTAINER_NAME" \
      version="$VERSION"

RUN INSTALL_PKGS="go-toolset" && \
    yum install -y --setopt=tsflags=nodocs $INSTALL_PKGS && \
    rpm -V $INSTALL_PKGS && \
    yum clean all -y

# Copy the S2I scripts from the specific language image to $STI_SCRIPTS_PATH.
COPY ./s2i/bin/ $STI_SCRIPTS_PATH

COPY ./root/ /

RUN chown -R 1001:0 $STI_SCRIPTS_PATH && chown -R 1001:0 $APP_ROOT

USER 1001

# Set the default CMD to print the usage of the language image.
CMD $STI_SCRIPTS_PATH/usage

参照:Red Hat Ecosystem Catalog

結論

どういう背景があるのか知りませんが、なぜかgolangだけDockerfileでEXPOSEしておらず、これが原因でnew-appの処理によりServiceが作成されないようです。

golangではアプリケーションレイヤーでListenするようにするお作法などあったりするんでしょうか。。
ひとまず、golangイメージを使うときにはこの辺り注意するようにします。

備考

  • new-appのログについて

oc new-app golang --dry-run --loglevel=7という感じでloglevelを指定して詳細なログ出力ができますが、あまりみても意味なさそうでした。

  • golangイメージを使ってService作るとき

他のテンプレートを参考にしたりしてマニフェストを作ってからでもできますが、Webコンソールからだと以下のようにチェックするだけで簡単にできます。この場合は、ServiceとRouteも作成されます。

――――――――――――――――――――――――――――――――――

執筆者プロフィール:川野 孝(システムアイ)
ゲーム事業の自社開発企業で3年間SREとして、GCP/AWS上のインフラストラクチャのTerraform/Ansibleを使った運用改善やGKEを使ったKubernetesアーキテクチャの構築、スクラム開発などを経験。
RGAではそれらの経験を生かし、OpenShiftやCI/CD設計構築、スクラムの導入などの関連する業務に従事。

【ご案内】
ITシステム開発やITインフラ運用の効率化、高速化、品質向上、その他、情シス部門の働き方改革など、IT自動化導入がもたらすメリットは様々ございます。

IT業務の自動化にご興味・ご関心ございましたら、まずは一度、IT自動化の専門家リアルグローブ・オートメーティッド(RGA)にご相談ください!

お問合せは以下の窓口までお願いいたします。

【お問い合わせ窓口】
窓口:rga@systemi.co.jp
URL: https://rg-automated.jp