ウェビナーシリーズ

この記事は、Kubernetesを使用したCI/CDの実行に関するウェビナーシリーズを補足するものです。 このシリーズでは、アプリケーションの構築、テスト、デプロイにクラウドネイティブのアプローチを採用する方法について説明し、リリース管理、クラウドネイティブツール、サービスメッシュ、Kubernetesで使用できるCI/CDツールについて説明します。 これは、CI/CDのベストプラクティスとKubernetesをワークフローに統合することに関心のある開発者や企業を支援するように設計されています。

このチュートリアルには、シリーズの最初のセッションであるKubernetesでCI/CDを実行するためのビルディングブロックの概念とコマンドが含まれています。

序章

container を使い始めている場合は、ビルド、テスト、およびデプロイメントを自動化する方法を知りたいと思うでしょう。 これらのプロセスにCloudNative アプローチを採用することで、適切なインフラストラクチャAPIを活用して、アプリケーションを自動化された方法でパッケージ化およびデプロイできます。

自動化を行うための2つの構成要素には、コンテナーイメージコンテナーオーケストレーターがあります。 昨年かそこらで、Kubernetesがコンテナオーケストレーションのデフォルトの選択肢になりました。 CI / CD with Kubernetes シリーズのこの最初の記事では、次のことを行います。

  • Docker Buildah 、およびKanikoを使用してコンテナーイメージをビルドします。
  • Terraform を使用してKubernetesクラスターをセットアップし、DeploymentsServicesを作成します。
  • カスタムリソースを使用してKubernetesクラスターの機能を拡張します。

このチュートリアルを終了すると、Docker、Buildah、Kanikoでビルドされたコンテナイメージと、デプロイ、サービス、カスタムリソースを備えたKubernetesクラスターが完成します。

このシリーズの今後の記事では、Kubernetesのパッケージ管理、 JenkinsXSpinnakerなどのCI/CDツール、サービスメッシュ、GitOpsなどの関連トピックについて説明します。

前提条件

  • root以外のユーザーアカウントを持つUbuntu16.04サーバー。 ガイダンスについては、 Ubuntu16.04を使用した初期サーバーセットアップのチュートリアルに従ってください。
  • Dockerがサーバーにインストールされています。 インストール手順については、 Ubuntu16.04にDockerをインストールして使用する方法のステップ1と2に従ってください。
  • DockerHubアカウント。 Docker Hubの使用を開始するための概要については、これらの手順を参照してください。
  • DigitalOceanアカウントと個人用アクセストークン。 アクセストークンを取得するには、これらの手順を参照してください。
  • コンテナとDockerに精通していること。 詳細については、ウェビナーシリーズ:コンテナ入門を参照してください。
  • Kubernetesの概念に精通していること。 詳細については、Kubernetesの概要を参照してください。

ステップ1—DockerとBuildahを使用してコンテナイメージを構築する

コンテナイメージは、コンテナの作成と実行に使用できる独自のアプリケーションコード、ランタイム、および依存関係を持つ自己完結型のエンティティです。 さまざまなツールを使用してコンテナイメージを作成できます。このステップでは、DockerとBuildahの2つを使用してコンテナを構築します。

Dockerfilesを使用したコンテナイメージの構築

Dockerは、コンテナーイメージをアセンブルするために必要なコマンドを含むテキストファイルであるDockerfileから命令を読み取ることにより、コンテナーイメージを自動的に構築します。 docker image buildコマンドを使用すると、Dockerfileで提供されるコマンドライン命令を実行する自動ビルドを作成できます。 イメージをビルドするときは、Dockerfileを使用してビルドコンテキストも渡します。Dockerfileには、環境を作成し、コンテナーイメージでアプリケーションを実行するために必要なファイルのセットが含まれています。

通常、Dockerfileとビルドコンテキストのプロジェクトフォルダーを作成します。 demoというフォルダーを作成して開始します。

  1. mkdir demo
  2. cd demo

次に、demoフォルダー内にDockerfileを作成します。

  1. nano Dockerfile

次のコンテンツをファイルに追加します。

〜/ demo / Dockerfile
FROM ubuntu:16.04

LABEL MAINTAINER [email protected]

RUN apt-get update \
    && apt-get install -y nginx \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
    && echo "daemon off;" >> /etc/nginx/nginx.conf

EXPOSE 80
CMD ["nginx"]

このDockerfileは、Nginxを実行するためのイメージを構築する一連の命令で構成されています。 ビルドプロセス中、ubuntu:16.04がベースイメージとして機能し、nginxパッケージがインストールされます。 CMD命令を使用して、コンテナーの起動時にデフォルトのコマンドになるようにnginxも構成しました。

次に、docker image buildコマンドを使用して、現在のディレクトリ(。)をビルドコンテキストとして使用して、コンテナイメージをビルドします。 このコマンドに-tオプションを渡すと、イメージにnkhare/nginx:latestという名前が付けられます。

  1. sudo docker image build -t nkhare/nginx:latest .

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

Output
Sending build context to Docker daemon 49.25MB Step 1/5 : FROM ubuntu:16.04 ---> 7aa3602ab41e Step 2/5 : MAINTAINER [email protected] ---> Using cache ---> 552b90c2ff8d Step 3/5 : RUN apt-get update && apt-get install -y nginx && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && echo "daemon off;" >> /etc/nginx/nginx.conf ---> Using cache ---> 6bea966278d8 Step 4/5 : EXPOSE 80 ---> Using cache ---> 8f1c4281309e Step 5/5 : CMD ["nginx"] ---> Using cache ---> f545da818f47 Successfully built f545da818f47 Successfully tagged nginx:latest

これでイメージが作成されました。 次のコマンドを使用して、Dockerイメージを一覧表示できます。

  1. docker image ls
Output
REPOSITORY TAG IMAGE ID CREATED SIZE nkhare/nginx latest 4073540cbcec 3 seconds ago 171MB ubuntu 16.04 7aa3602ab41e 11 days ago

これで、nkhare/nginx:latestイメージを使用してコンテナーを作成できます。

ProjectAtomic-Buildahを使用したコンテナイメージの構築

Buildahは、 Project Atomic によって開発されたCLIツールで、 Open Container Initiative(OCI)準拠のイメージをすばやく構築します。 OCIは、業界のベストプラクティスを標準化するために、コンテナランタイムとイメージの仕様を提供します。

Buildahは、作業コンテナーまたはDockerfileのいずれかからイメージを作成できます。 Dockerデーモンを使用せずにユーザースペースで完全にイメージを構築でき、buildlistpushtagなどのイメージ操作を実行できます。 このステップでは、ソースからBuildahをコンパイルし、それを使用してコンテナーイメージを作成します。

Buildahをインストールするには、パッケージやパッケージのセキュリティなどを管理できるツールなど、必要な依存関係が必要になります。 次のコマンドを実行して、これらのパッケージをインストールします。

  1. cd
  2. sudo apt-get install software-properties-common
  3. sudo add-apt-repository ppa:alexlarsson/flatpak
  4. sudo add-apt-repository ppa:gophers/archive
  5. sudo apt-add-repository ppa:projectatomic/ppa
  6. sudo apt-get update
  7. sudo apt-get install bats btrfs-tools git libapparmor-dev libdevmapper-dev libglib2.0-dev libgpgme11-dev libostree-dev libseccomp-dev libselinux1-dev skopeo-containers go-md2man

buildahソースコードをコンパイルしてパッケージを作成するため、Goもインストールする必要があります。

  1. sudo apt-get update
  2. sudo curl -O https://storage.googleapis.com/golang/go1.8.linux-amd64.tar.gz
  3. sudo tar -xvf go1.8.linux-amd64.tar.gz
  4. sudo mv go /usr/local
  5. sudo echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.profile
  6. source ~/.profile
  7. go version

インストールが成功したことを示す次の出力が表示されます。

Output
go version go1.8 linux/amd64

これで、buildahソースコードを取得して、runcバイナリとともにパッケージを作成できます。 runcは、OCIコンテナーランタイムの実装であり、Buildahコンテナーを実行するために使用します。

次のコマンドを実行して、runcおよびbuildahをインストールします。

  1. mkdir ~/buildah
  2. cd ~/buildah
  3. export GOPATH=`pwd`
  4. git clone https://github.com/containers/buildah ./src/github.com/containers/buildah
  5. cd ./src/github.com/containers/buildah
  6. make runc all TAGS="apparmor seccomp"
  7. sudo cp ~/buildah/src/github.com/opencontainers/runc/runc /usr/bin/.
  8. sudo apt install buildah

次に、/etc/containers/registries.confファイルを作成して、コンテナレジストリを構成します。

  1. sudo nano /etc/containers/registries.conf

次のコンテンツをファイルに追加して、レジストリを指定します。

/etc/containers/registries.conf

# This is a system-wide configuration file used to
# keep track of registries for various container backends.
# It adheres to TOML format and does not support recursive
# lists of registries.

# The default location for this configuration file is /etc/containers/registries.conf.

# The only valid categories are: 'registries.search', 'registries.insecure',
# and 'registries.block'.

[registries.search]
registries = ['docker.io', 'registry.fedoraproject.org', 'quay.io', 'registry.access.redhat.com', 'registry.centos.org']

# If you need to access insecure registries, add the registry's fully-qualified name.
# An insecure registry is one that does not have a valid SSL certificate or only does HTTP.
[registries.insecure]
registries = []

# If you need to block pull access from a registry, uncomment the section below
# and add the registries fully-qualified name.
#
# Docker only
[registries.block]
registries = []

registries.conf構成ファイルは、レジストリまたはドメイン部分を含まないイメージ名を完成させるときに参照する必要があるレジストリを指定します。

次に、https://github.com/do-community/rsvpapp-webinar1リポジトリをビルドコンテキストとして使用して、次のコマンドを実行してイメージをビルドします。 このリポジトリには、関連するDockerfileも含まれています。

  1. sudo buildah build-using-dockerfile -t rsvpapp:buildah github.com/do-community/rsvpapp-webinar1

このコマンドは、https://github.com/do-community/rsvpapp-webinar1リポジトリで使用可能なDockerfilleからrsvpapp:buildahという名前のイメージを作成します。

画像を一覧表示するには、次のコマンドを使用します。

  1. sudo buildah images

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

Output
IMAGE ID IMAGE NAME CREATED AT SIZE b0c552b8cf64 docker.io/teamcloudyuga/python:alpine Sep 30, 2016 04:39 95.3 MB 22121fd251df localhost/rsvpapp:buildah Sep 11, 2018 14:34 114 MB

これらの画像の1つは、作成したばかりのlocalhost/rsvpapp:buildahです。 もう1つのdocker.io/teamcloudyuga/python:alpineは、Dockerfileのベースイメージです。

イメージをビルドしたら、DockerHubにプッシュできます。 これにより、将来の使用のために保存することができます。 まず、コマンドラインからDockerHubアカウントにログインする必要があります。

  1. docker login -u your-dockerhub-username -p your-dockerhub-password

ログインが成功すると、DockerHubのクレデンシャルを含むファイル~/.docker/config.jsonが取得されます。 次に、そのファイルをbuildahで使用して、イメージをDockerHubにプッシュできます。

たとえば、作成したばかりの画像をプッシュする場合は、authfileとプッシュする画像を引用して、次のコマンドを実行できます。

  1. sudo buildah push --authfile ~/.docker/config.json rsvpapp:buildah docker://your-dockerhub-username/rsvpapp:buildah

次のコマンドを使用して、結果のイメージをローカルのDockerデーモンにプッシュすることもできます。

  1. sudo buildah push rsvpapp:buildah docker-daemon:rsvpapp:buildah

最後に、作成したDockerイメージを見てください。

  1. sudo docker image ls
Output
REPOSITORY TAG IMAGE ID CREATED SIZE rsvpapp buildah 22121fd251df 4 minutes ago 108MB nkhare/nginx latest 01f0982d91b8 17 minutes ago 172MB ubuntu 16.04 b9e15a5d1e1a 5 days ago 115MB

予想どおり、buildahを使用してエクスポートされた新しいイメージrsvpapp:buildahが表示されます。

これで、DockerとBuildahの2つの異なるツールを使用してコンテナイメージを構築した経験があります。 次に、Kubernetesを使用してコンテナのクラスタを設定する方法について説明します。

ステップ2—kubeadmとTerraformを使用してDigitalOceanにKubernetesクラスターをセットアップする

DigitalOceanでKubernetesを設定するにはさまざまな方法があります。 たとえば、 kubeadm を使用してKubernetesを設定する方法の詳細については、 Ubuntu18.04でKubeadmを使用してKubernetesクラスターを作成する方法をご覧ください。

このチュートリアルシリーズでは、アプリケーション開発にクラウドネイティブのアプローチを採用する方法について説明しているため、クラスターをセットアップするときにこの方法を適用します。 具体的には、kubeadmと Terraform を使用してクラスターの作成を自動化します。これは、インフラストラクチャの作成と変更を簡素化するツールです。

個人用アクセストークンを使用して、Terraformを使用してDigitalOceanに接続し、3台のサーバーをプロビジョニングします。 これらのVM内でkubeadmコマンドを実行して、1つのマスターノードと2つのワーカーを含む3ノードのKubernetesクラスターを作成します。

Ubuntuサーバーで、 SSHキーのペアを作成します。これにより、VMへのパスワードなしのログインが可能になります。

  1. ssh-keygen -t rsa

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

Output
Generating public/private rsa key pair. Enter file in which to save the key (~/.ssh/id_rsa):

ENTERを押して、キーペアをホームディレクトリの~/.sshディレクトリに保存するか、別の宛先を入力します。

次に、次のプロンプトが表示されます。

Output
Enter passphrase (empty for no passphrase):

この場合、パスワードなしでENTERを押すと、ノードへのパスワードなしのログインが有効になります。

キーペアが作成されたことの確認が表示されます。

Output
Your identification has been saved in ~/.ssh/id_rsa. Your public key has been saved in ~/.ssh/id_rsa.pub. The key fingerprint is: SHA256:lCVaexVBIwHo++NlIxccMW5b6QAJa+ZEr9ogAElUFyY root@3b9a273f18b5 The key's randomart image is: +---[RSA 2048]----+ |++.E ++o=o*o*o | |o +..=.B = o | |. .* = * o | | . =.o + * | | . . o.S + . | | . +. . | | . ... = | | o= . | | ... | +----[SHA256]-----+

次のコマンドを実行して公開鍵を取得します。これにより、公開鍵が端末に表示されます。

  1. cat ~/.ssh/id_rsa.pub

これらの指示に従って、このキーをDigitalOceanアカウントに追加します。

次に、Terraformをインストールします。

  1. sudo apt-get update
  2. sudo apt-get install unzip
  3. wget https://releases.hashicorp.com/terraform/0.11.7/terraform_0.11.7_linux_amd64.zip
  4. unzip terraform_0.11.7_linux_amd64.zip
  5. sudo mv terraform /usr/bin/.
  6. terraform version

Terraformのインストールを確認する出力が表示されます。

Output
Terraform v0.11.7

次に、次のコマンドを実行して、Kubernetesクラスターと通信するCLIツールであるkubectlをインストールし、ユーザーのホームディレクトリに~/.kubeディレクトリを作成します。

  1. sudo apt-get install apt-transport-https
  2. curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
  3. sudo touch /etc/apt/sources.list.d/kubernetes.list
  4. echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
  5. sudo apt-get update
  6. sudo apt-get install kubectl
  7. mkdir -p ~/.kube

~/.kubeディレクトリを作成すると、構成ファイルをこの場所にコピーできるようになります。 このセクションの後半でKubernetesセットアップスクリプトを実行したら、これを実行します。 デフォルトでは、kubectlCLIは~/.kubeディレクトリで構成ファイルを探してクラスターにアクセスします。

次に、このチュートリアルのサンプルプロジェクトリポジトリのクローンを作成します。このリポジトリには、インフラストラクチャを設定するためのTerraformスクリプトが含まれています。

git clone https://github.com/do-community/k8s-cicd-webinars.git

Terrafromスクリプトディレクトリに移動します。

  1. cd k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/

SSH公開鍵のフィンガープリントを取得します。

  1. ssh-keygen -E md5 -lf ~/.ssh/id_rsa.pub | awk '{print $2}'

次のような出力が表示され、強調表示された部分がキーを表します。

Output
MD5:dd:d1:b7:0f:6d:30:c0:be:ed:ae:c7:b9:b8:4a:df:5e

キーはここに表示されているものとは異なることに注意してください。

指紋を環境変数に保存して、Terraformが使用できるようにします。

  1. export FINGERPRINT=dd:d1:b7:0f:6d:30:c0:be:ed:ae:c7:b9:b8:4a:df:5e

次に、DOパーソナルアクセストークンをエクスポートします。

  1. export TOKEN=your-do-access-token

次に、~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/プロジェクトディレクトリを見てください。

  1. ls
Output
cluster.tf destroy.sh files outputs.tf provider.tf script.sh

このフォルダには、Terraformを使用してKubernetesクラスタをデプロイするために必要なスクリプトと設定ファイルが含まれています。

script.shスクリプトを実行して、Kubernetesクラスターのセットアップをトリガーします。

  1. ./script.sh

スクリプトの実行が完了すると、作成したKubernetesクラスターを使用するようにkubectlが構成されます。

kubectl get nodesを使用してクラスターノードを一覧表示します。

  1. kubectl get nodes
Output
NAME STATUS ROLES AGE VERSION k8s-master-node Ready master 2m v1.10.0 k8s-worker-node-1 Ready <none> 1m v1.10.0 k8s-worker-node-2 Ready <none> 57s v1.10.0

これで、Ready状態の1つのマスターノードと2つのワーカーノードができました。

Kubernetesクラスタを設定すると、コンテナイメージを構築するための別のオプションであるGoogleのKanikoを探索できるようになります。

ステップ3—Kanikoを使用してコンテナイメージを構築する

このチュートリアルの前半で、DockerfilesとBuildahを使用してコンテナイメージを構築しました。 しかし、Kubernetesで直接コンテナイメージを構築できるとしたらどうでしょうか。 Kubernetes内でdocker image buildコマンドを実行する方法はいくつかありますが、これはネイティブのKubernetesツールではありません。 イメージをビルドするにはDockerデーモンに依存する必要があり、クラスター内のポッドの1つで実行する必要があります。

Kanikoというツールを使用すると、既存のKubernetesクラスターでDockerfileを使用してコンテナーイメージを構築できます。 このステップでは、Kanikoを使用してDockerfileでコンテナーイメージを構築します。 次に、このイメージをDockerHubにプッシュします。

イメージをDockerHubにプッシュするには、DockerHubのクレデンシャルをKanikoに渡す必要があります。 前の手順では、Docker Hubにログインし、ログイン資格情報を使用して~/.docker/config.jsonファイルを作成しました。 この構成ファイルを使用してKubernetesConfigMap オブジェクトを作成し、Kubernetesクラスター内にクレデンシャルを保存してみましょう。 ConfigMapオブジェクトは、構成パラメーターを格納し、それらをアプリケーションから切り離すために使用されます。

~/.docker/config.jsonファイルを使用してdocker-configというConfigMapを作成するには、次のコマンドを実行します。

  1. sudo kubectl create configmap docker-config --from-file=$HOME/.docker/config.json

次に、~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/ディレクトリにpod-kaniko.ymlというポッド定義ファイルを作成できます(ただし、どこにでも移動できます)。

まず、~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/ディレクトリにいることを確認します。

  1. cd ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/

pod-kaniko.ymlファイルを作成します。

  1. nano pod-kaniko.yml

次のコンテンツをファイルに追加して、ポッドをデプロイしたときに何が起こるかを指定します。 ポッドのargsフィールドのyour-dockerhub-usernameは、必ず独自のDockerHubユーザー名に置き換えてください。

〜/ k8s-cicd-webinars / webinar1 / 2-kubernetes / 1-Terraform / pod-kaniko.yaml
apiVersion: v1
kind: Pod
metadata:
  name: kaniko
spec:
  containers:
  - name: kaniko
    image: gcr.io/kaniko-project/executor:latest
    args: ["--dockerfile=./Dockerfile",
            "--context=/tmp/rsvpapp/",
            "--destination=docker.io/your-dockerhub-username/rsvpapp:kaniko",
            "--force" ]
    volumeMounts:
      - name: docker-config
        mountPath: /root/.docker/
      - name: demo
        mountPath: /tmp/rsvpapp
  restartPolicy: Never
  initContainers:
    - image: python
      name: demo
      command: ["/bin/sh"]
      args: ["-c", "git clone https://github.com/do-community/rsvpapp-webinar1.git /tmp/rsvpapp"] 
      volumeMounts:
      - name: demo
        mountPath: /tmp/rsvpapp
  restartPolicy: Never
  volumes:
    - name: docker-config
      configMap:
        name: docker-config
    - name: demo
      emptyDir: {}

この構成ファイルには、ポッドがデプロイされたときに何が起こるかが記述されています。 まず、 Initコンテナーは、Dockerfile https://github.com/do-community/rsvpapp-webinar1.gitを含むGitリポジトリーを、demoという共有ボリュームに複製します。 Initコンテナーは、アプリケーションコンテナーの前に実行され、アプリケーションコンテナーから実行するのが望ましくないユーティリティやその他のタスクを実行するために使用できます。 アプリケーションコンテナkanikoは、Dockerfileを使用してイメージをビルドし、ConfigMapボリュームdocker-configに渡したクレデンシャルを使用して、結果のイメージをDockerHubにプッシュします。

kanikoポッドを展開するには、次のコマンドを実行します。

  1. kubectl apply -f pod-kaniko.yml

次の確認が表示されます。

Output
pod/kaniko created

ポッドのリストを取得します。

  1. kubectl get pods

次のリストが表示されます。

Output
NAME READY STATUS RESTARTS AGE kaniko 0/1 Init:0/1 0 47s

数秒待ってから、kubectl get podsを再度実行して、ステータスを更新します。

  1. kubectl get pods

次のように表示されます。

Output
NAME READY STATUS RESTARTS AGE kaniko 1/1 Running 0 1m

最後に、kubectl get podsをもう一度実行して、最終的なステータスを更新します。

  1. kubectl get pods
Output
NAME READY STATUS RESTARTS AGE kaniko 0/1 Completed 0 2m

この一連の出力は、Initコンテナーが実行され、demoボリューム内のGitHubリポジトリーのクローンを作成したことを示しています。 その後、Kanikoビルドプロセスが実行され、最終的に終了しました。

ポッドのログを確認します。

  1. kubectl logs kaniko

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

Output
time="2018-08-02T05:01:24Z" level=info msg="appending to multi args docker.io/your-dockerhub-username/rsvpapp:kaniko" time="2018-08-02T05:01:24Z" level=info msg="Downloading base image nkhare/python:alpine" . . . ime="2018-08-02T05:01:46Z" level=info msg="Taking snapshot of full filesystem..." time="2018-08-02T05:01:48Z" level=info msg="cmd: CMD" time="2018-08-02T05:01:48Z" level=info msg="Replacing CMD in config with [/bin/sh -c python rsvp.py]" time="2018-08-02T05:01:48Z" level=info msg="Taking snapshot of full filesystem..." time="2018-08-02T05:01:49Z" level=info msg="No files were changed, appending empty layer to config." 2018/08/02 05:01:51 mounted blob: sha256:bc4d09b6c77b25d6d3891095ef3b0f87fbe90621bff2a333f9b7f242299e0cfd 2018/08/02 05:01:51 mounted blob: sha256:809f49334738c14d17682456fd3629207124c4fad3c28f04618cc154d22e845b 2018/08/02 05:01:51 mounted blob: sha256:c0cb142e43453ebb1f82b905aa472e6e66017efd43872135bc5372e4fac04031 2018/08/02 05:01:51 mounted blob: sha256:606abda6711f8f4b91bbb139f8f0da67866c33378a6dcac958b2ddc54f0befd2 2018/08/02 05:01:52 pushed blob sha256:16d1686835faa5f81d67c0e87eb76eab316e1e9cd85167b292b9fa9434ad56bf 2018/08/02 05:01:53 pushed blob sha256:358d117a9400cee075514a286575d7d6ed86d118621e8b446cbb39cc5a07303b 2018/08/02 05:01:55 pushed blob sha256:5d171e492a9b691a49820bebfc25b29e53f5972ff7f14637975de9b385145e04 2018/08/02 05:01:56 index.docker.io/your-dockerhub-username/rsvpapp:kaniko: digest: sha256:831b214cdb7f8231e55afbba40914402b6c915ef4a0a2b6cbfe9efb223522988 size: 1243

ログから、kanikoコンテナーがDockerfileからイメージを構築し、DockerHubアカウントにプッシュしたことがわかります。

これで、Dockerイメージをプルできます。 必ずyour-dockerhub-usernameをDockerHubのユーザー名に置き換えてください。

  1. docker pull your-dockerhub-username/rsvpapp:kaniko

プルの確認が表示されます。

Output
kaniko: Pulling from your-dockerhub-username/rsvpapp c0cb142e4345: Pull complete bc4d09b6c77b: Pull complete 606abda6711f: Pull complete 809f49334738: Pull complete 358d117a9400: Pull complete 5d171e492a9b: Pull complete Digest: sha256:831b214cdb7f8231e55afbba40914402b6c915ef4a0a2b6cbfe9efb223522988 Status: Downloaded newer image for your-dockerhub-username/rsvpapp:kaniko

これで、Kubernetesクラスターが正常に構築され、クラスター内から新しいイメージが作成されました。 展開サービスの説明に移りましょう。

ステップ4—Kubernetesのデプロイとサービスを作成する

Kubernetes Deployments を使用すると、アプリケーションを実行できます。 デプロイメントはポッドに望ましい状態を指定し、ロールアウト全体で一貫性を確保します。 このステップでは、~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/ディレクトリにdeployment.ymlという名前のNginx デプロイメントファイルを作成して、Nginxデプロイメントを作成します。

まず、ファイルを開きます。

  1. nano deployment.yml

次の構成をファイルに追加して、Nginxデプロイメントを定義します。

〜/ k8s-cicd-webinars / webinar1 / 2-kubernetes / 1-Terraform / deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

このファイルは、ポート80nginxコンテナーを実行する3つのポッドを作成するnginx-deploymentという名前のデプロイメントを定義します。

デプロイメントをデプロイするには、次のコマンドを実行します。

  1. kubectl apply -f deployment.yml

デプロイメントが作成されたことの確認が表示されます。

Output
deployment.apps/nginx-deployment created

展開を一覧表示します。

  1. kubectl get deployments
Output
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 3 3 3 3 29s

nginx-deploymentデプロイメントが作成され、ポッドの目的の数と現在の数が同じであることがわかります:3

デプロイメントが作成したポッドを一覧表示するには、次のコマンドを実行します。

  1. kubectl get pods
Output
NAME READY STATUS RESTARTS AGE kaniko 0/1 Completed 0 9m nginx-deployment-75675f5897-nhwsp 1/1 Running 0 1m nginx-deployment-75675f5897-pxpl9 1/1 Running 0 1m nginx-deployment-75675f5897-xvf4f 1/1 Running 0 1m

この出力から、必要な数のポッドが実行されていることがわかります。

アプリケーションのデプロイを内部および外部に公開するには、Serviceと呼ばれるKubernetesオブジェクトを作成する必要があります。 各サービスはServiceTypeを指定します。これは、サービスの公開方法を定義します。 この例では、 NodePort ServiceTypeを使用します。これにより、各ノードの静的ポートでサービスが公開されます。

これを行うには、~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom/ディレクトリにservice.ymlというファイルを作成します。

  1. nano service.yml

次のコンテンツを追加して、サービスを定義します。

〜/ k8s-cicd-webinars / webinar1 / 2-kubernetes / 1-Terrafrom / service.yml
kind: Service
apiVersion: v1
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  type: NodePort
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30111

これらの設定は、サービスnginx-serviceを定義し、ポッドのポート80をターゲットにすることを指定します。 nodePortは、アプリケーションが外部トラフィックを受け入れるポートを定義します。

サービスをデプロイするには、次のコマンドを実行します。

  1. kubectl apply -f service.yml

確認が表示されます:

Output
service/nginx-service created

サービスを一覧表示します。

  1. kubectl get service

次のリストが表示されます。

Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5h nginx-service NodePort 10.100.98.213 <none> 80:30111/TCP 7s

サービスnginx-serviceはポート30111で公開されており、ノードの任意のパブリックIPでアクセスできるようになりました。 たとえば、http://node_1_ip:30111またはhttp://node_2_ip:30111に移動すると、Nginxの標準のウェルカムページに移動します。

デプロイメントをテストしたら、デプロイメントとサービスの両方をクリーンアップできます。

  1. kubectl delete deployment nginx-deployment
  2. kubectl delete service nginx-service

これらのコマンドは、作成したデプロイメントとサービスを削除します。

デプロイメントとサービスを使用したので、カスタムリソースの作成に移りましょう。

ステップ5—Kubernetesでカスタムリソースを作成する

Kubernetesは、限定的ですが本番環境に対応した機能と機能を提供します。 ただし、カスタムリソース機能を使用して、Kubernetesのオファリングを拡張することは可能です。 Kubernetesでは、リソースは、APIオブジェクトのコレクションを格納するKubernetesAPIのエンドポイントです。 たとえば、ポッドリソースにはポッドオブジェクトのコレクションが含まれます。 カスタムリソースを使用すると、ネットワーク、ストレージなどのカスタムオファリングを追加できます。 これらの追加は、いつでも作成または削除できます。

カスタムオブジェクトの作成に加えて、コントロールプレーンでKubernetes Controller コンポーネントのサブコントローラーを使用して、オブジェクトの現在の状態が目的の状態と等しくなるようにすることもできます。 Kubernetesコントローラーには、指定されたオブジェクトのサブコントローラーがあります。 たとえば、 ReplicaSet は、目的のポッドカウントの一貫性を維持するためのサブコントローラーです。 カスタムリソースをコントローラーと組み合わせると、リソースの目的の状態を指定できる真の宣言型APIが得られます。

このステップでは、カスタムリソースと関連オブジェクトを作成します。

カスタムリソースを作成するには、最初に~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom/ディレクトリにcrd.ymlというファイルを作成します。

  1. nano crd.yml

次のカスタムリソース定義(CRD)を追加します。

〜/ k8s-cicd-webinars / webinar1 / 2-kubernetes / 1-Terrafrom / crd.yml
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: webinars.digitalocean.com
spec:
  group: digitalocean.com
  version: v1
  scope: Namespaced
  names:
    plural: webinars
    singular: webinar
    kind: Webinar
    shortNames:
    - wb

crd.ymlで定義されているCRDを展開するには、次のコマンドを実行します。

  1. kubectl create -f crd.yml

リソースが作成されたことの確認が表示されます。

Output
customresourcedefinition.apiextensions.k8s.io/webinars.digitalocean.com created

crd.ymlファイルは、新しいRESTfulリソースパス/apis/digtialocean.com/v1/namespaces/*/webinarsを作成しました。 namesセクションにリストしたように、webinarswebinarWebinar、およびwbを使用してオブジェクトを参照できるようになりました。 CustomResourceDefinitionの。 次のコマンドを使用して、RESTfulリソースを確認できます。

  1. kubectl proxy & curl 127.0.0.1:8001/apis/digitalocean.com

注:前提条件でサーバーの初期設定ガイドに従った場合、このテストを機能させるには、ポート8001へのトラフィックを許可する必要があります。 次のコマンドを使用して、このポートへのトラフィックを有効にします。

  1. sudo ufw allow 8001

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

Output
HTTP/1.1 200 OK Content-Length: 238 Content-Type: application/json Date: Fri, 03 Aug 2018 06:10:12 GMT { "apiVersion": "v1", "kind": "APIGroup", "name": "digitalocean.com", "preferredVersion": { "groupVersion": "digitalocean.com/v1", "version": "v1" }, "serverAddressByClientCIDRs": null, "versions": [ { "groupVersion": "digitalocean.com/v1", "version": "v1" } ] }

次に、webinar.ymlというファイルを開いて、新しいカスタムリソースを使用するためのオブジェクトを作成します。

  1. nano webinar.yml

次のコンテンツを追加して、オブジェクトを作成します。

〜/ k8s-cicd-webinars / webinar1 / 2-kubernetes / 1-Terrafrom / webinar.yml
apiVersion: "digitalocean.com/v1"
kind: Webinar
metadata:
  name: webinar1
spec:
  name: webinar
  image: nginx

次のコマンドを実行して、これらの変更をクラスターにプッシュします。

  1. kubectl apply -f webinar.yml

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

Output
webinar.digitalocean.com/webinar1 created

kubectlを使用してwebinarオブジェクトを管理できるようになりました。 例えば:

  1. kubectl get webinar
Output
NAME CREATED AT webinar1 21s

これで、webinar1というオブジェクトができました。 コントローラがあった場合、それはオブジェクトの作成をインターセプトし、定義された操作を実行します。

カスタムリソース定義の削除

カスタムリソースのすべてのオブジェクトを削除するには、次のコマンドを使用します。

  1. kubectl delete webinar --all

次のように表示されます。

Output
webinar.digitalocean.com "webinar1" deleted

カスタムリソース自体を削除します。

  1. kubectl delete crd webinars.digitalocean.com

削除されたことの確認が表示されます。

Output
customresourcedefinition.apiextensions.k8s.io "webinars.digitalocean.com" deleted

削除後は、curlコマンドで以前にテストしたAPIエンドポイントにアクセスできなくなります。

このシーケンスは、Kubernetesコードを変更せずにKubernetes機能を拡張する方法の概要です。

ステップ6—Kubernetesクラスターを削除する

Kubernetesクラスタ自体を破棄するには、~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafromフォルダのdestroy.shスクリプトを使用できます。 次のディレクトリにいることを確認してください。

  1. cd ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom

スクリプトを実行します。

  1. ./destroy.sh

このスクリプトを実行することにより、TerraformがDigitalOcean APIと通信し、クラスター内のサーバーを削除できるようになります。

結論

このチュートリアルでは、さまざまなツールを使用してコンテナイメージを作成しました。 これらのイメージを使用すると、任意の環境でコンテナーを作成できます。 また、Terraformを使用してKubernetesクラスターをセットアップし、アプリケーションをデプロイして公開するためのデプロイオブジェクトとサービスオブジェクトを作成しました。 さらに、カスタムリソースを定義することで、Kubernetesの機能を拡張しました。

これで、Kubernetes上にCI / CD環境を構築するための強固な基盤ができました。これについては、今後の記事で説明します。