Oktetoを使用してKubernetesでアプリケーションを開発する方法

提供:Dev Guides
移動先:案内検索

著者は、 Write for DOnations プログラムの一環として、 Girls WhoCodeを選択して寄付を受け取りました。

序章

Okteto CLI は、Kubernetesで実行されるアプリケーションのローカル開発エクスペリエンスを提供するオープンソースプロジェクトです。 これを使用すると、ローカルIDEでコードを記述でき、ファイルを保存するとすぐに、変更をKubernetesクラスターにプッシュでき、アプリがすぐに更新されます。 このプロセス全体は、Dockerイメージをビルドしたり、Kubernetesマニフェストを適用したりする必要なしに実行されます。これには、かなりの時間がかかる場合があります。

このチュートリアルでは、Kubernetesネイティブアプリケーションを開発する際に、Oktetoを使用して生産性を向上させます。 まず、Kubernetesクラスターを作成し、それを使用して標準の「HelloWorld」アプリケーションを実行します。 次に、Oktetoを使用して、ローカルに何もインストールしなくても、アプリケーションを開発して自動的に更新します。

前提条件

このチュートリアルを開始する前に、次のものが必要です。

ステップ1—HelloWorldアプリケーションを作成する

「HelloWorld」プログラムは、Web開発における昔ながらの伝統です。 この場合、それはすべての要求に「HelloWorld」に応答する単純なWebサービスです。 Kubernetesクラスターを作成したので、Golangで「HelloWorld」アプリを作成し、それをKubernetesにデプロイするために使用するマニフェストを作成しましょう。

最初にホームディレクトリに移動します。

cd ~

次に、hello_worldという名前の新しいディレクトリを作成し、その中に移動します。

mkdir hello_world
cd hello_world

お気に入りのIDEまたはテキストエディタを使用して、main.goという名前で新しいファイルを作成して開きます。

nano main.go

main.goは、メッセージHello world!を返すGolangWebサーバーになります。 それでは、次のコードを使用しましょう。

main.go

package main

import (
    "fmt"
    "net/http"
)

func main() {
    fmt.Println("Starting hello-world server...")
    http.HandleFunc("/", helloServer)
    if err := http.ListenAndServe(":8080", nil); err != nil {
        panic(err)
    }
}

func helloServer(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello world!")
}

main.goのコードは次のことを行います。

  • Goソースファイルの最初のステートメントは、package名である必要があります。 実行可能コマンドは常にpackage mainを使用する必要があります。
  • importセクションは、コードが依存するパッケージを示します。 この場合、文字列操作にはfmtを使用し、HTTPサーバーにはnet/httpを使用します。
  • main関数は、バイナリへのエントリポイントです。 http.HandleFuncメソッドは、/パスへの要求を受信したときにhelloServer関数を呼び出すようにサーバーを構成するために使用されます。 http.ListenAndServeは、ポート8080のすべてのネットワークインターフェイスでリッスンするHTTPサーバーを起動します。
  • helloServer関数には、リクエストハンドラのロジックが含まれています。 この場合、リクエストへの応答としてHello world!を書き込みます。

Dockerイメージを作成し、Dockerレジストリにプッシュして、Kubernetesがイメージをプルしてアプリケーションを実行できるようにする必要があります。

お気に入りのIDEまたはテキストエディタでDockerfileという名前の新しいファイルを開きます。

nano Dockerfile

Dockerfileには、アプリケーションのDockerコンテナーを構築するために必要なコマンドが含まれています。 次のコードを使用してみましょう。

Dockerfile

FROM golang:alpine as builder
RUN apk --update --no-cache add bash
WORKDIR /app
ADD . .
RUN go build -o app

FROM alpine as prod
WORKDIR /app
COPY --from=builder /app/app /app/app
EXPOSE 8080
CMD ["./app"]

Dockerfileには、builderprodの2つのステージが含まれています。

  • builderステージには、Goビルドツールが含まれています。 ファイルのコピーとGoバイナリの構築を担当します。
  • prodステージが最終画像です。 削除されたOSとアプリケーションバイナリのみが含まれます。

これは従うべき良い習慣です。 アプリケーションとそれを実行するために必要なものだけが含まれているため、本番コンテナはより小さく、より安全になります。

コンテナイメージをビルドします(your_DockerHub_usernameをDockerHubユーザー名に置き換えます)。

docker build -t your_DockerHub_username/hello-world:latest

次に、DockerHubにプッシュします。

docker push your_DockerHub_username/hello-world:latest

次に、Kubernetesマニフェスト用の新しいフォルダを作成します。

mkdir k8s

Kubernetesマニフェストを使用するときは、アプリケーションをどのように実行するかをKubernetesに指示します。 今回は、deployationオブジェクトを作成します。 したがって、お気に入りのIDEまたはテキストエディタを使用して新しいファイルdeployment.yamlを作成します。

nano k8s/deployment.yaml

次のコンテンツでは、okteto/hello-world:latestDockerイメージを実行するKubernetesデプロイメントオブジェクトについて説明します。 このコンテンツを新しいファイルに追加しますが、この場合、imageラベルの後にリストされているoktetoyour_DockerHub_usernameに置き換えます。

〜/ hello_world / k8s / deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
spec:
  selector:
    matchLabels:
      app: hello-world
  replicas: 1
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
      - name: hello-world
        image: your_DockerHub_username/hello-world:latest
        ports:
        - containerPort: 8080

デプロイメントマニフェストには、次の3つの主要なセクションがあります。

  • metadataは、デプロイメントの名前を定義します。
  • replicasは、実行するコピーの数を定義します。
  • templateは、Kubernetesに何をデプロイし、どのラベルを追加するかを指示します。 この場合、okteto/hello-world:latestイメージを持ち、ポート8080でリッスンし、app: hello-worldラベルが付いた単一のコンテナーです。 このラベルは、selectorセクションで使用されているものと同じであることに注意してください。

ここで、アプリケーションにアクセスする方法が必要になります。 service オブジェクトを作成することで、Kubernetesでアプリケーションを公開できます。 それを行うためにマニフェストを使い続けましょう。 お気に入りのIDEまたはテキストエディタを使用して、service.yamlという名前の新しいファイルを作成します。

nano k8s/service.yaml

次のコンテンツは、hello-worldデプロイメントオブジェクトを公開するサービスについて説明しています。このオブジェクトは、内部でDigitalOceanロードバランサーを使用します。

k8s / service.yaml

apiVersion: v1
kind: Service
metadata:
  name: hello-world
spec:
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
      name: http
  selector:
    app: hello-world

サービスマニフェストには、次の4つの主要なセクションがあります。

  • metadataは、サービスに名前を付ける方法をKubernetesに指示します。
  • typeは、Kubernetesにサービスを公開する方法を指示します。 この場合、デジタルオーシャンロードバランサーを介して外部に公開されます。
  • portsラベルは、公開するポートと、それらをデプロイにマッピングする方法をKubernetesに指示します。 この場合、ポート80を外部に公開し、展開内のポート8080に転送します。
  • selectorは、トラフィックを転送する方法をKubernetesに指示します。 この場合、app: hello-worldラベルの付いたポッドはすべてトラフィックを受信します。

これで、「HelloWorld」アプリケーションをKubernetesにデプロイする準備が整いました。 次にこれを行います。

ステップ2—HelloWorldアプリケーションをデプロイする

このステップでは、「Hello World」アプリケーションをKubernetesにデプロイしてから、正しく機能していることを検証します。

アプリケーションをKubernetesにデプロイすることから始めます。

kubectl apply -f k8s

次の出力が表示されます。

Outputdeployment.apps "hello-world" created
service "hello-world" created

約1分後、アプリケーションのIPを取得できるようになります。 次のkubectlコマンドを使用して、サービスを確認します。

kubectl get service hello-world

Kubernetesサービスオブジェクトを一覧表示する次のような出力が表示されます。 EXTERNAL-IP列にあるアプリケーションのIPに注意してください。

OutputNAME          TYPE        CLUSTER-IP         EXTERNAL-IP       PORT(S)    AGE
hello-world   ClusterIP   your_cluster_ip   your_external_ip  8080/TCP   37s

ブラウザを開き、「HelloWorld」アプリケーションにリストされているyour_external_ipに移動します。 次の手順に進む前に、アプリケーションが稼働していることを確認してください。

この瞬間まで、Kubernetesを使用してアプリケーションを開発するためのかなり伝統的な方法をたどってきました。 今後は、アプリケーションのコードを変更する場合は常に、新しいDockerイメージをビルドしてプッシュし、そのイメージをKubernetesからプルする必要があります。 このプロセスにはかなりの時間がかかる場合があります。 Oktetoは、この開発の内部ループを合理化するように設計されました。 Okteto CLIを見て、それがどのように役立つかを見てみましょう。

ステップ3—OktetoCLIのインストール

Okteto CLIをインストールすることで、Kubernetes開発の生産性が向上します。 Oktetoコマンドラインインターフェースは、アプリケーションコードの変更をKubernetesで実行されているアプリケーションに同期できるオープンソースプロジェクトです。 前の手順で行ったように、コンテナーをコミット、ビルド、プッシュ、または再デプロイしてアプリケーションをテストしなくても、お気に入りのIDE、デバッガー、またはコンパイラーを引き続き使用できます。

MacOSまたはLinuxマシンにOktetoCLIをインストールするには、次のコマンドを実行します。

curl https://get.okteto.com -sSfL | sh

このコマンドを詳しく見てみましょう。

  • curlコマンドは、サーバーとの間でデータを転送するために使用されます。
  • -sフラグは、出力を抑制します。
  • -Sフラグはエラーを示します。
  • -fフラグを使用すると、HTTPエラーでリクエストが失敗します。
  • -Lフラグは、リクエストをリダイレクトに従わせます。
  • |オペレーターは、この出力をshコマンドにパイプします。このコマンドは、最新のoktetoバイナリをダウンロードしてローカルマシンにインストールします。

Windowsを実行している場合は、代わりに Webブラウザからファイルをダウンロードし、手動で$PATHに追加することができます。

Okteto CLIがインストールされると、「HelloWorld」アプリケーションを開発モードにする準備が整います。

ステップ4—HelloWorldアプリケーションを開発モードにする

Okteto CLIは、Kubernetesクラスターで実行されているアプリケーションをマシンにあるコードと交換するように設計されています。 そのために、OktetoはOktetoマニフェストファイルから提供された情報を使用します。 このファイルは、ローカルコードとスワップするKubernetesデプロイメントオブジェクトを宣言します。

お気に入りのIDEまたはテキストエディタを使用して、okteto.yamlという名前の新しいファイルを作成します。

nano okteto.yaml

デプロイメントオブジェクト名、使用するDockerベースイメージ、およびシェルを定義する基本的なマニフェストを作成しましょう。 後でこの情報に戻ります。 次のサンプルコンテンツファイルを使用します。

okteto.yaml

name: hello-world
image: okteto/golang:1
workdir: /app
command: ["bash"]

次のコマンドを実行して、アプリケーションを開発モードにする準備をします。

okteto up
Output ✓  Development environment activated
 ✓  Files synchronized
    Namespace: default
    Name:      hello-world

Welcome to your development environment. Happy coding!
default:hello-world /app>

okteto upコマンドは、「HelloWorld」アプリケーションを開発環境にスワップします。これは次のことを意味します。

  • Hello Worldアプリケーションコンテナーは、Dockerイメージokteto/golang:1で更新されます。 このイメージには、「Hello World」アプリケーションをビルド、テスト、デバッグ、および実行するために必要な開発ツールが含まれています。
  • ファイル同期サービスは、ローカルファイルシステムとアプリケーションポッドの間で変更を最新の状態に保つために作成されます。
  • 開発環境でリモートシェルが起動します。 これで、ローカルマシンにいるかのように、アプリケーションをビルド、テスト、および実行できます。
  • リモートシェルで実行するプロセスが何であれ、元の「Hello World」アプリケーションポッドと同じ着信トラフィック、同じ環境変数、ボリューム、またはシークレットを取得します。 これにより、非常に現実的な本番環境のような開発環境が実現します。

同じコンソールで、次のように、通常どおりに(Dockerイメージをビルドしてプッシュせずに)アプリケーションを実行します。

go run main.go
OutputStarting hello-world server...

アプリケーションを初めて実行するときに、Goは依存関係をダウンロードしてアプリケーションをコンパイルします。 以前と同じように、ブラウザを開いてアプリケーションのページを更新することにより、このプロセスが終了してアプリケーションをテストするのを待ちます。

これで、Kubernetesで直接開発を開始する準備が整いました。

ステップ5—Kubernetesで直接開発する

「HelloWorld」アプリケーションに変更を加えてから、これらの変更がKubernetesにどのように反映されるかを見てみましょう。

お気に入りのIDEまたはテキストエディタでmain.goファイルを開きます。 たとえば、別のコンソールを開いて、次のコマンドを実行します。

nano main.go

次に、応答メッセージをHello world from DigitalOcean!に変更します。

main.go

package main

import (
    "fmt"
    "net/http"
)

func main() {
    fmt.Println("Starting hello-world server...")
    http.HandleFunc("/", helloServer)
    if err := http.ListenAndServe(":8080", nil); err != nil {
        panic(err)
    }
}

func helloServer(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello world from DigitalOcean!")
}

ワークフローが変わるのはここです。 イメージをビルドしてコンテナを再デプロイして「HelloWorld」アプリケーションを更新する代わりに、Oktetoは変更をKubernetesの開発環境に同期します。

okteto upコマンドを実行したコンソールから、CTRL + Cを押して、go run main.goの実行をキャンセルします。 次に、アプリケーションを再実行します。

default:hello-world /app> go run main.go
OutputStarting hello-world server...

ブラウザに戻り、「HelloWorld」アプリケーションのページをリロードします。

コードの変更は、コミット、ビルド、プッシュを必要とせずに、Kubernetesに即座に適用されました。

結論

Okteto は、ボタンをクリックするだけで、Kubernetesクラスターをフル機能の開発プラットフォームに変換します。 このチュートリアルでは、 Okteto CLI をインストールして構成し、コードを入力するのと同じ速さでコードの変更をKubernetesで直接繰り返すようにしました。 これで、 Oktetoサンプルリポジトリにアクセスして、さまざまなプログラミング言語やデバッガーでOktetoを使用する方法を確認できます。

また、Kubernetesクラスタをチームと共有する場合は、同じクラスタで作業している他の開発者から分離されるように設定された安全なKubernetes名前空間へのアクセスを各メンバーに許可することを検討してください。 この優れた機能は、 DigitalOcean KubernetesMarketplaceOktetoAppによっても提供されます。