在Windows的WSL2 Ubuntu Docker Kind环境中亲身体验Docker和Kubernetes

这篇文章的内容 (zhè de

本文适合那些在大致理解了Docker和Kubernetes的整体框架后,想要在Windows环境下创建一个简易的容器编排环境,并体验其运作的人。只要有Windows10及以上版本的环境,建立和配置环境,包括样例的运作确认等,如果没有特别的问题,大约两小时左右就可以完成。虽然可以仅仅通过复制粘贴本文执行(如果没有遇到任何问题),但在遇到某些麻烦的情况下可能需要一些Linux知识,所以略有Linux经验的人会更适合。(※直接将本文复制粘贴可能会使得实施成为可能,但遇到问题可能需要Linux知识)

整理了缺乏Docker和Kubernetes知识的本地应用程序开发人员参与项目时进行的实践操作内容。由于无法立即使用云环境,使用WSL2、Ubuntu22.04、Docker和Kind(在Docker中运行Kubernetes)进行配置,以便在每台Windows机器上能够对组件进行大致理解和操作,并通过在容器之间进行本地卷共享的示例进行解释。为了尽量减少干扰操作,省略了可能产生的噪音,请同时努力进行信息检索。

我在开头已经写过了,请首先大致了解一下Docker和Kubernetes的基本概念,可以是一些关于它们的通用解释。以下是关于Docker和Kubernetes的解释链接。可能还有其他更易懂的解释。

Docker解释链接:https://www.redhat.com/ja/topics/containers/what-is-docker
Kubernetes解释链接:https://www.redhat.com/ja/topics/containers/what-is-kubernetes

下面是WSL的概观链接。
Windows Subsystem for Linux (WSL) 是什么?:https://learn.microsoft.com/ja-jp/windows/wsl/faq

在Windows中安装WSL2、Docker、Kind、kubectl。

成员们使用了Windows 11和Windows 10,但在所有步骤中没有任何差异。
有关所需组件的安装,请参考这篇链接文章(虽然已经是从Docker Desktop到…)中的步骤。
此次我们使用的是Ubuntu 22.04版本。

完成安装了上述链接中提到的kind(在Docker中的Kubernetes),请回到本文。

テキストファイル編集

知ってるようで知らない人も多いので今一度確認してほしいのですが、、
Docker や Kubernetes のユーザー設定ファイルは基本的に全てテキストファイルです。後々の不要なトラブルを避けるために、YAMLファイルなどテキストファイルの改行コードは Linux標準の LF のみでファイル保存するよう心掛けてください。Windows のメモ帳は改行コードが Windows標準の CRLF で保存されるため、改行コードを選択できるエディターアプリ(サクラエディタなど)の使用をお勧めします。Linux の中で vi を使うのであれば問題ありませんが、、折角 WSL2 で ファイルアクセスが容易ですので GUI のエディターを使いたいところです。
Windows WSL2 環境ではファイルエクスプローラーから Ubuntu のファイルに直接アクセスできるため大変便利です。(ファイルエクスプローラーに ¥¥wsl$ と直接入力すればアクセスできます。この記事のコピーではなく、円円wslドル と直接手入力してください。ショートカットを作っておくと便利です)
さらに、テキストファイル中の日本語を、コメントとしてではなくデータとしてテキストファイルに記述する場合は、文字コードを UTF-8 BOM なしで保存してください。

自分でビルドしたコンテナを run させる

書き込みと読み取りそれぞれの役割を担当するコンテナ2つを run させてローカルに作成したボリューム上のファイルを共有するサンプルを動かしてみましょう。

以降の手順で作成するファイルは、全て同じディレクトリに置き、コマンドもそのディレクトリで実行してください。特に意図がなければ、/home/ユーザー名 の下にファイルを作成してください。

Docker コンテナをビルドするために Dockerファイルと呼ばれる定義ファイルを作成します。コンテナを2つ作るため2つの Dockerファイルを作ります。
以下の Dockerファイルでは ubuntu のベースコンテナイメージにユーザーシェルを組み込み、コンテナ run 時にはそのユーザーシェルが呼び出されるように定義しています。

# ファイル名:mywriter.txt
FROM ubuntu

ADD mywriter.sh /mywriter.sh
RUN chmod +x /mywriter.sh

CMD ["/mywriter.sh", "/mywork"]
# ファイル名:myreader.txt
FROM ubuntu

ADD myreader.sh /myreader.sh
RUN chmod +x /myreader.sh

CMD ["/myreader.sh", "/mywork"]

上記 Dockerファイル中に定義しているユーザーシェル2つ(現在時刻をファイルに書き込むシェルと、ファイルの内容を表示するシェル)を作成します。以下のシェルは改行コードを必ず LF のみで保存してください。改行コードが CRLF の場合は動作しません。

# ファイル名:mywriter.sh
#!/bin/bash

export TZ=JST-9
mkdir $1
count=0

while true
do
  count=`expr $count + 1`
  if [ $count -gt 30 ]; then
    date +"%Y/%m/%d %p %I:%M:%S" > $1/log.txt
    count=0
  else
    date +"%Y/%m/%d %p %I:%M:%S" >> $1/log.txt
  fi
  sleep 1
done
# ファイル名:myreader.sh
#!/bin/bash

export TERM=linux

while true
do
  tail -n 5 $1/log.txt
  sleep 1
done

创建所需的文件后,构建容器。

# コンテナイメージのビルド
docker build -t mywriter:001 -f mywriter.txt .
docker build -t myreader:001 -f myreader.txt .

# ローカルに存在するコンテナイメージの表示
docker images

REPOSITORY     TAG       IMAGE ID       CREATED       SIZE
mywriter       001       a900d412314a   1 hours ago   77.8MB
myreader       001       5669d29bd494   1 hours ago   77.8MB

容器映像已经构建好了。
那么让我们来运行容器试试看。

# 事前に共有用のボリュームの作成
docker volume create myvolume

# バックグラウンドオプションで writerコンテナを run
docker run -d --rm --volume myvolume:/mywork mywriter:001

# フォアグラウンドオプションで readerコンテナを run
docker run -it --rm --volume myvolume:/mywork myreader:001

可以确认,在正常运行情况下,writer容器将每秒写入当前时间,而reader容器将在标准输出中显示这个时间。

当运行容器时,我尽量保持选项的最小化。比如,在每个容器中挂载一个共享卷,或者区分-d和-it选项的差异,最后指定容器镜像名称等等,即使是没有接触过容器的人也可以想象到一些。请您自行详细调查选项的细节。

我会显示正在运行的容器。请使用Ctrl + c结束在前台运行的reader容器。

# コンテナの表示
docker ps

CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS     NAMES
4a9658e6abe0   mywriter:001   "/mywriter.sh /mywork"   7 minutes ago   Up 7 minutes             flamboyant_kapitsa

可以看出,Writer容器尚未运行。
顺便说一句,在运行容器时,可以使用–name选项为容器指定任意名称,如果省略,则Docker引擎将自动分配名称,以形容词和科学家等人名的组合形式命名,以确保在此环境下唯一。实际值可以在Docker的源代码中找到。可以感受到开发者的一些趣味心思呢。。

关闭writer容器。

# コンテナの停止
docker stop flamboyant_kapitsa
    または
docker stop 4a9658e6abe0

# コンテナの表示
docker ps

CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS

在操作特定容器的命令中,您需要指定容器名称或容器 ID,就像前面提到的那样。
可以使用 docker ps 命令来确认所有容器已经停止运行。

コンテナはいつ終了するのでしょうか?
コンテナイメージをビルドする際に使用する Dockerファイル中の CMD(または ENTRYPOINT 違いは検索してください)に記述されたコマンド(コマンドは1個のみ記述が可能)が完了した時点で run されたコンテナは自動的に終了します。または docker stop、docker rm -f などのコマンドで強制的にコンテナを終了させる事も可能です。

在 Kubernetes 上运行容器

接下来,我们将确认在容器编排环境下的运行情况。目前,容器的运行不仅仅局限于诸如Docker等容器引擎,而且在容器编排环境如Kubernetes下的运行已经变得很普遍。在本文中,我们将使用Kind(在Docker中运行的Kubernetes)作为Kubernetes的简单验证工具。

请不厌其烦地多次阅读下面的解释,并在大致了解Kubernetes整体以及容器与Pod之间关系后再继续。

首先创建Kubernetes集群。

# 最小構成でクラスターを作成
kind create cluster

使用以上命令将生成一个仅由被称为控制平面的主节点组成的集群。通常情况下,集群的配置是拥有主节点和用于运行容器的工作节点,但在像Kind这样的简易环境中,仅使用主节点也可以验证容器。此外,如果使用kind创建集群,默认的集群名称将为”kind”,但如果希望识别集群,可以指定任意名称来生成集群。

目前在商业环境中,云供应商公开的环境中,通常使用只允许用户操作工作节点,而不公开主节点的形式。

确认节点。

# 作成されたノードの確認
kubectl get nodes

NAME                 STATUS   ROLES           AGE   VERSION
kind-control-plane   Ready    control-plane   10m   v1.27.3

在使用Kubernetes环境中,我们经常使用kubectl命令。使用kind命令可以生成或删除节点,而对于已经存在的集群内节点或Pod等操作,则使用Kubernetes的kubectl命令。当在实际的云环境中操作时,会有各种不同的命令存在,如果不注意各个命令的层级和组件,容易混淆,所以请务必理解每个命令的含义。在Kubernetes环境中,我们经常使用kubectl命令,因此请确保熟悉它的选项和用法。

让我们将Pod部署到我们创建的集群中。
我们要定义用于部署Pod的YAML文件。该文件描述了一个包含两个容器的Pod。您可以看到,与在仅Docker环境中运行时相比,我们在YAML中也定义了卷等内容。
有些人可能会觉得YAML描述太复杂,不擅长处理。但是,这次的内容非常简单和易懂,所以请大致浏览一下,并努力完成到最后。

# ファイル名:mypod.yml
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  restartPolicy: Never

  volumes:
  - name: myvolume
    emptyDir: {}

  containers:
  - name: mr1
    image: myreader:001
    volumeMounts:
    - name: myvolume
      mountPath: /mywork

  - name: mw1
    image: mywriter:001
    volumeMounts:
    - name: myvolume
      mountPath: /mywork

上述的 YAML 中的 kind: Pod 描述,并不是指 Kubernetes in Docker(Kind),而是指在种类的意义上,它是一种常见的 Kubernetes YAML 描述。

在启动 Pod 之前,需要将容器镜像传输至集群中。

# 2つのコンテナイメージをクラスターに転送する
kind load docker-image mywriter:001 myreader:001

现在我们终于来试试运行 Pod。

# Pod の YAML定義をクラスターに適用する
kubectl apply -f mypod.yml

如果上述的 YAML 应用没有问题,Pod 将在集群内(即在主节点上)运行。
检查 Pod 的状态。

# Pod の表示
kubectl get pods -o wide

NAME    READY   STATUS    RESTARTS   AGE   IP           NODE                 NOMINATED NODE   READINESS GATES
mypod   2/2     Running   0          10s   10.244.0.5   kind-control-plane   <none>           <none>

2つのコンテナを含む Pod が Running になりました。

Pod内のコンテナが動作しているかを確認するため readerコンテナのログを表示します。

# Pod の名前とコンテナの名前を指定してログを表示
kubectl logs mypod -c mr1

Dockerだけの環境と同様に、writerコンテナがファイルに書き込んだ内容を readerコンテナが標準出力に出しているのを確認できると思います。
もし timeoutでログが表示できない場合は、WSL2 を完全に停止させることで解決する事があります。以降に記述している Pod の削除、クラスターの削除を行い、Ubuntu を exit して Windows のコマンドライン(管理者で実行)で、wsl –shutdown を実行してから、Ubuntu を再起動し、再度導入以降の手順を試行してみてください。

Pod を削除します。

# Pod の削除
kubectl delete pod mypod

# Pod の表示
kubectl get pods -o wide

先ほどと同じ Pod を表示するコマンドで削除された事が分かります。
最後に kindコマンドでクラスターも削除します。

# クラスターの削除
kind delete cluster

以上是本文的全部步骤的结束。

Docker や Kubernetes の実際の動きが何となくでも理解できたとともに、色々と疑問に感じた事や、さらにもっと試したい事が出てきたのではないでしょうか。
Pod はいつ終わるの?とか、コンテナの起動順序の制御は?とか、勝手に再起動されるの?とか、このケースは Pod に向いてないのでは?(Job が良いのでは?)とか、コンテナ間で共有メモリーとか使えるの?とか、ソケット通信アプリは使えるの?(ポートのサービス定義は本稿では入れられなかったですね・・)などなど。。でも検索すれば大抵の事は見つかると思います。

概述

実際のプロジェクトではクラウド環境を使う事になると思いますが、コンテナイメージの作成、コンテナの単体動作、Kubernetes 上の Pod での動作などコンテナオーケストレーション環境の基本的な仕組みや流れを初心者が学習したい時に、いきなりクラウド環境で試してしまうと、さらにクラウドの知識を要求されてしまい、自分で入力しているコマンドがどのレイヤーのどのコンポーネントに作用しているのか理解が追い付かずに混乱しているメンバーを度々見かけてきました。
コンテナ、Kubernetes にあまり触れるタイミングがなかった方々の第一歩として、大まかな流れを理解するために本稿がその一助となれば幸いです。

请确保仅在本文中提供了最基本的命令,并且请您自行调查并实际尝试了解这些命令的含义和相关命令。

广告
将在 10 秒后关闭
bannerAds