20200804のdockerに関する記事は14件です。

JenkinsとKubernetesでCIパイプラインを構築

JenkinsとKubernetesを連携させてCIパイプラインを構築する時に、一番悩むの点は、いろいろな方法があるために、何を選択して良いか解らない。そして、実際に実装を進めると、様々な問題が発覚して、時間がかかってしまうことがある。

Jenkinsのプラグインで、Dockerに関するものだけでも約20種類、Kubernetesの関係するもので 約17種類もある。しかも、これらが問題なく動作するという保証も無い。筆者が経験したケースでは、資料が作られた時期から時間が経過すると共にプラグインが更新され、新たな問題が生じてしまい、動作しなくなっているなどがあった。そして、ドキュメントは、Jenkinsに詳しいエンジニア向けに書かれているために、普段触り慣れないJenkins初心者には難解な内容となっていることもある。

そして、Kubernetes上でJenkinsを動作させる場合にも問題が多い。最近のKubernetesのバージョンではコンテナランタイム環境としてContainerdが使用されDockerデーモンが導入されていない。そのため、dockerコマンドを使ったビルドをKubenetesクラスタで、コンテナを簡単にビルドすることができない。DinDやKanikoとなどの環境が必要となる。

そこで、今回は、Jenkinsで、Kubernetesにデプロイするビルドパイプラインを構築するための最短策として試してみた。

構築方針

JenkinsのCI環境を簡単かつ迅速に使用可能な状態とするために、以下の方針に基づいて構築することにした。

  • Jenkinsは最新バージョンを使用して、脆弱性リスクを最小化する。
  • プラグインの使用は最小に抑え、プラグインの障害に遭遇する可能性を低くする
  • コンテナのビルド環境は、有償サポートが受けられる Docker Enterprise に置き換えが可能となる構成とする。

上記の理由から、Kubernetes上でJenkinsを動かさず、仮想サーバー上でJenkinsサーバー構築する。

システム構成

Jenkinsはマスターと、Buildエージェント2台で構築する。

ss-1.png

クラウドを利用しないエコな環境として、VagrantとAnsibleで環境を構築するコードを書いた。https://github.com/takara9/vagrant-jenkins
この環境の起動方法は、このリポジトリのREADME.mdの書いておいたので、クローンしてvagrant upすれば、3台のサーバーが環境が整った形で起動するので、あとは、Jenkinsのユーザー画面からプラグインを追加して、Git,Docker,Kubernetesクラスタの認証情報などを設定することで、実際に連携した操作が可能である。

ビルドパイプライン

Jenkinsパイプラインのリファレンスは、https://www.jenkins.io/doc/book/pipeline/ にあるので、パイプラインの説明は、ざっくり見ておくと良い。そして、ここで利用するビルドパイプラインのサンプルコードを GitHub https://github.com/takara9/jenkins-play-1 に置いてあるでの、このコードで動作を説明する。

プラグインを追加インストールは実質的に無しである。Blue Ocean は見やすいフロー図とログを表示してくれるので、メインストリームで使うことはないが、入れておく。このJenkinsパイプラインは、4つのステージからなる。

  • GiHubからソースコードのクローン
  • コンテナイメージのビルド
  • コンテナレジストリへプッシュ
  • K8sクラスタへのデプロイ

この流れを順番に見ていく。

最初のステージは、GitHubからクローンする。この記述に関する詳細はJenkinsのデフォルトで導入される Gitプラグイン (https://www.jenkins.io/doc/pipeline/steps/git/) のドキュメントを参照すれば、認証が必要なケースでの書き方がわかる。

    stages {
        stage('GiHubからソースコードのクローン') {
            steps {
                git 'https://github.com/takara9/jenkins-play-1'
            }
        }

2番目のステージは、コンテナのビルドステージを見ていく。この中でdocker.buildに関する記述は、Docker Pipelineプラグイン (https://docs.cloudbees.com/docs/admin-resources/latest/plugins/docker-workflow#docker-workflow-sect-build) によるものだ。このリンクには、docker.で始まるDockerコマンドに関する解説があるので、参照すると良い。

        stage('コンテナイメージのビルド') {
            steps {
                script {
                    dockerImage = docker.build registry + ":$BUILD_NUMBER"
                }
            }
        }

3番目のステージは、DockerHub レジストリへ、イメージを登録する部分である。 そこで、DockerHubのAPIのURLアドレスと、認証情報を指定する。認証情報には、DockerHubのユーザー名とパスワードが登録してあり、そのキーとなるのが、"dockerhub"である。これは事前に、「Jenkinsの管理」->「Manage Credential」から登録しておく。dockerImageは前段のステージから引き継がれるように、environmentの中で初期化しておかなければならない。

        stage('コンテナレジストリへプッシュ') {
            steps {
                script {
                    docker.withRegistry("https://index.docker.io/v1/","dockerhub") {
                        dockerImage.push()
                    }
                }
            }
        }

最終ステップは、Kubenetesへのデプロイである。ここでは、kubernetes-cdを使う予定であったが、このプラグイン jackson2-api-plugin が必要とするモジュール のバージョンアップによって動作しない状態になっていた。これはJENKINS-62995 Version 2.11.1 breaking kubernetes deployment somehowに挙げられているが、執筆本日(8月4日現在)Open状態である。 この修正をまっていられないので、Jenkinsのサーバーとビルドエージェントに、kubectlコマンドをインストールして、Jenkinsの認証情報にkubeconfigのファイルを登録して、シェルで実行することにした。

        stage('K8sクラスタへのデプロイ') {
            steps {
                script {
                       sh 'kubectl cluster-info --kubeconfig $KUBECONFIG'
                       sh 'sed s/__BUILDNUMBER__/$BUILD_NUMBER/ myweb.yaml > deploy_myweb.yaml'
                       sh 'kubectl apply -f deploy_myweb.yaml --kubeconfig $KUBECONFIG'
                       //kubernetesDeploy(configs: "myweb.yaml", kubeconfigId: "mykubeconfig")
                }
            }
        }

この中でJenkins組み込みの環境変数 $BUILD_NUMBER を使っている。この環境変数の説明や他の種類については、このURL( https://wiki.jenkins.io/display/JENKINS/Building+a+software+project) を参照すると良い。また、$KUBECONFIGはJenkinsの認証情報管理から登録したkubeconfigのファイルである。

以下に、全体のJenkinsfileを掲示しておく。

pipeline {
    // 前提条件 Jenkinsサーバーにdocker, kubectl コマンドが導入されていること
    //
    environment {
        registry = "docker.io/maho/myweb"
        dockerImage = ""
        KUBECONFIG = credentials('kubeconfig')
    }

    agent any

    stages {
        stage('GiHubからソースコードのクローン') {
            steps {
                git 'https://github.com/takara9/jenkins-play-1'
            }
        }
        stage('コンテナイメージのビルド') {
            steps {
                script {
                    dockerImage = docker.build registry + ":$BUILD_NUMBER"
                }
            }
        }
        stage('コンテナレジストリへプッシュ') {
            steps {
                script {
                    docker.withRegistry("https://index.docker.io/v1/","dockerhub") {
                        dockerImage.push()
                    }
                }
            }
        }
        stage('K8sクラスタへのデプロイ') {
            steps {
                script {
                       //sh 'echo $KUBECONFIG'
                       sh 'kubectl cluster-info --kubeconfig $KUBECONFIG'
                       sh 'sed s/__BUILDNUMBER__/$BUILD_NUMBER/ myweb.yaml > deploy_myweb.yaml'
                       sh 'kubectl apply -f deploy_myweb.yaml --kubeconfig $KUBECONFIG'
                       //kubernetesDeploy(configs: "myweb.yaml", kubeconfigId: "mykubeconfig")
                }
            }
        }
    }
}

動作確認

ジョブ jenkins-play-1を選択して、「ビルド実行」をクリックすると一連のパイプラインが実行される。スクリーンショットを見てわかる通り、GitHubのクローンから、Kubernetesのデプロイまで成功した。

ss-2.png

新規ジョブの作成

順番が前後するが、新規ジョブの登録について、書き残しておく。

「新規ジョブ作成」から次の画面に遷移して、パイプラインを選択して、OKボタンをクリック。

ss-3.png

プロジェクトの高度な設定で、SCMの項目でGitを選択、URLをいれる。

ss-4.png

Gitリポジトリの更新でビルド開始

今回のJenkinsはオンプレミス上に構築しているので、GitHubのWebhookを受けることができない。そこで、5分間隔でGitHubの更新をポーリングする。そして、変更が発見されたら、ビルドを開始すると設定にする。それにはジョブのリストから選択して、設定の中のビルドトリガーに以下のような設定を施す。これで、少し間をおくことになるが、git push 後に、自動的にビルドが開始される。

ss-5.png

コンテナによる実行

ビルドステップを、Dockerコンテナ上で動作させることができる。 「新規ジョブ作成」->「パイプライン」でスクリプトを選択して、次のように記述する。この例では、shは agentで指定されたコンテナで動作することになる。

pipeline {
    agent {
        docker { image 'node:14-alpine' }
    }
    stages {
        stage('Test') {
            steps {
                sh 'node --version'
            }
        }
    }
}

ここに挙げた例以外にも、ステップ単位にコンテナを変更する方法など、解説があるので、このURL (https://www.jenkins.io/doc/book/pipeline/docker/) を参照すると良い。

まとめ

Jenkinsのクラスタ上で、追加のプラグインをほとんど使わずに、また、バグを避けながら、ソースコードからコンテナのビルド、Kubernetesクラスタへのデプロイまでを実現することができた。

Jenkinsは優れたツールで小規模から大規模なソフトウェアのビルドに適用することができるので、広範囲なプロジェクトにも適用できると思う。このJenkinsは前進のHudsonから数えて10年が経過したツールで、プラグインが数多く開発されてきた。そのためか、情報が溢れて、どこから手を付けて良いかわからない状態が感じられる。

今回は基本に立ち返り、拡張を考えた簡単な構成で検証した。しかし、これからJenkinsは、仮想サーバー上で動かすべきか、それとも、Kubernetes上でコンテナとして動かすべきか選択を考えなければならない。 Jenkinsはソフトウェア製品開発にとって、基幹業務システム的な無くてはならない存在になっており、開発現場では延々とジョブを実行して、レポートを生成し続けている。そのようなシステムをKubernetes/ OpenShift で動かすメリットについて良く考えなければならない。 Kubernetes / OpneShift を利用することで、運用管理面と可用性で格段に改善できる。

一方で、Tekton やArgoなど、最初からコンテナで動かすことを前提に設計された新しいアーキテクチャのCIツールも登場してきているが、Jenkinsと比較すると成長段階といった印象と受ける。そのため、長期で考えた人材育成やスキル蓄積において検証を手掛ける必要がある。

その他、雑感

OpenShiftとの連携

OpenShiftのプラグインは、このURL(https://plugins.jenkins.io/ui/search?query=openshift) からリストしてみることができる。
また、OpenShift4でJenkinsを動かす概要について、このURL (https://www.openshift.com/blog/deploy-jenkins-pipelines-in-openshift-4-with-openshift-container-storage-4) の記事が参考になる。

Jenkinsの簡単インストール

Red Hatが推進するOperator Hubには、Jenkins Oprerator が登録されている。それだけでなく、Helm チャートにも登録がある。

IBM Cloud ROKS/IKSでの利用

第二世代VPC環境が東京データセンターで利用できるようになっている。Jenkins、Kubernetes そして OpenShiftも、この新しいVPC上で利用可能だ。しかも、Terraform のIBM Cloudプラグインも整っているので、コードを適用するだけで、一気にインフラを構築することが可能だ。システム構成がコード化されていれば、クラウドのポータルを時間をかけて操作することなく、コードを適用するだけで、必要な数だけ、揃えることも可能である。

Jenkinsの役割的な特性上、Kubernetes/ OpenShiftクラスタは、Jenkinsの周りにテストと本番配信環境として成長していくように思う。そうすと、TerraformとAnsibleを使って、Jenkinsをすぐに構築して提供でき、安定的に運用できる環境でも良いのでは無いかとも思う。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unsupported config option for services service: ‘app’ エラー

docker-compose.yml を書き換えた時にでたエラー

Unsupported config option for services service: ‘app’

原因として、docker-compose が古いらしい

最新のバージョンに変更する必要がある

curl -L “https://github.com/docker/compose/releases/download/バージョン指定/docker-compose-$(uname -s)-$(uname -m)” -o /usr/local/bin/docker-compose

最新のバージョンを見るには こちらから

完了:relaxed:

参考記事:
https://qiita.com/takepan/items/172302ecb1ead91c0cab

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

一時クレデンシャルを発行するローカルIMDSを作った

はじめに

AWSを使う上でクレデンシャルをEC2インスタンス上(~/.aws/credentials)に保存したり
プログラムの設定ファイルに指定することは、セキュリティ上の観点から推奨されません。
(というかアクセスキーを発行すること自体がセキュリティリスクになります)
通常は、IAMロールをEC2に紐づけてIMDS(インスタンスメタデータサービス)から一時的な
クレデンシャルを取得してAWSリソースにアクセスにすると思います。

この一時クレデンシャルを提供するのが、IMDS(後述)と呼ばれるサービスですが、
ローカルで動くIMDSもどきを作ってみたので、その紹介です。

インスタンスメタデータサービス(IMDS)とは

このページを抜粋

インスタンスメタデータサービス(IMDS)は、一時的な認証情報へのアクセスを提供することで
クラウドユーザーにとって大きなセキュリティ上の課題を解決し、手動またはプログラムによって
インスタンスに機密認証情報をハードコードしたり、配布したりする必要をなくしました。
EC2 インスタンスにアタッチされた IMDS は、特別な「リンクローカル」の IP アドレス 
169.254.169.254 で接続され、インスタンスで実行中のソフトウェアだけがアクセスできます。
アプリケーションは IMDS にアクセスして、インスタンス、ネットワーク、およびストレージに関する
メタデータを利用できます。
また、IMDSは、インスタンスにアタッチされている IAM ロール による AWS 認証情報を使用
できるようにします。

簡単に言うと、EC2上でaws sdkを使ったプログラムやaws cliコマンドを実行すると、
http://169.254.169.254/latest/meta-data/iam/security-credentials/{iamrole}
にリクエストを送信してクレデンシャルを取得し、その認証情報を使ってAWSリソースを操作します。

処理イメージ

imds.png

レスポンス例

一時セキュリティ認証情報
{
  "Code" : "Success",
  "LastUpdated" : "2020-08-04T06:34:37Z",
  "Type" : "AWS-HMAC",
  "AccessKeyId" : "ASIA4KYQ77T7MF27ET2B",
  "SecretAccessKey" : "Q8vJapXly4HA1~~",
  "Token" : "IQoJb3JpZ2lu~~",
  "Expiration" : "2020-08-04T12:38:26Z"
}

ローカルIMDSとは

有効期限が切れない間隔で定期的にsts.assumeRoleして一時クレデンシャルを取得して
それをリンクローカルアドレス(169.254.169.254)へのhttpリクエストの結果として返すDocker
コンテナです。

使い方

前提)
・スイッチロール元アカウントID:111111111111 / ユーザ名:miyaz@sencorp
・スイッチロール先アカウントID:222222222222 / ロール名:Dev

スイッチロール先IAMロールの信頼関係に下記を指定

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111111111111:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringLike": {
          "sts:RoleSessionName": "${aws:username}"
        }
      }
    }
  ]
}

スイッチロール元アカウントのクレデンシャルをローカルの ~/.aws/credentialsにセット

[default]
aws_access_key_id=~~~
aws_secret_access_key=~~~

docker-compose.ymlを作成

docker-compose.yml
version: '3.8'

services:
  app:
    image: centos:7
    tty: true

## 既存のdocker-compose.ymlで使いたい場合はここ以降をコピペでOK(RoleArnは書き換え要)
  imds:
    image: miyaz/local-imds:latest
    volumes:
      - ~/.aws:/root/.aws
    environment:
      IMDS_ROLE_ARN: "arn:aws:iam::222222222222:role/Dev"
    networks:
      default:
        ipv4_address: 169.254.169.254

networks:
  default:
    ipam:
      config:
        - subnet: 169.254.169.0/24

実行する

以下の例では、centos7にawscliを入れて aws s3 ls を実行する手順です。
ちなみにimdsはエラーメッセージ以外は何もログ出力しません(念の為)

docker-compose up -d
docker-compose exec app bash
yum -y install awscli
aws s3 ls

解説

imdsコンテナがIMDSの役割を持っています。
~/.awsをボリューム共有するので、スイッチロール可能なクレデンシャルが指定され
ている必要があります。

環境変数[IMDS_ROLE_ARN]に権限を引き受けるロールを指定します。
IMDS_ROLE_ARN: "arn:aws:iam::{AccountId}:role/{IamRole}"

スイッチロール元クレデンシャルのプロファイル名がdefaultでなければ、
環境変数[IMDS_SOURCE_PROFILE]で指定できます。

imdsが169.254.169.254というIPで動くので、そこからクレデンシャルを取得する
appコンテナが169.254.169.0/24のIPを持っていればOK。
ymlファイルに記載のdefaultのコメントアウトを外すと通常はdefaultネットワークを
使いつつ、クレデンシャル取得時のみ169.254.169.0/24ネットワークを使います。

ちなみに、この設定は入れた方がいいと思ったので、roleSessionNameに自動的に
スイッチロール元のIAMユーザ名が入るようにしています。

ローカルIMDSのコードはこちら

どこで使えるか?

うーん、あまり有用な使い道は思いつかないですが、、強いて言えばということで。

AWSパートナー経由で契約している場合などOrganizationsが使えない場合はスイッチ
ロール運用している会社が多いと思います。
その場合にはログイン専用アカウントのみにIAMユーザを作成し、ログイン後スイッチロール
して他のアカウントのマネジメントコンソールにアクセスしていると思います。

で、開発しているアプリ(gitリポジトリ)とAWSアカウントが紐づいている場合、新たに
参加した開発者にはスイッチロール用クレデンシャルを伝えて .aws/configに追記してもらうと思います。

~/.aws/configに追記する例
[profile hoge-dev]
region=ap-northeast-1
role_arn=arn:aws:iam::222222222222:role/Dev
source_profile=default
role_session_name=miyaz@sencorp

アプリのコードベースにあるdocker-compose.ymlに予めRole名が記載されて
いれば、これを伝達する必要がなくなって手間削減!!(無理やりw

まとめ

思いついたので試してみたら動いた!!
て感じで、あまり運用上有用な使い方はなさそうですが、仕組みの理解は進みました\(^o^)/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

# Docker Rails6 Nginx Puma Mysql環境をDockerとは別階層に作りたかっただけ

はじめに

  • DockerでRails環境を作る必要があり、ネットにはいくらでも記事は載っているのでそれを見て真似ようと思ったのが発端です。
  • 最終的にできたものはRails6 + Nginx + Puma + Mysqlです。使ってみる
  • Mac OS
  • 以下のような階層にdockerと分けた構成にしたかった。
root
├ docker
│   ├ workspace
│   │   └ Dockerfileなど
│   ├ mysql
│   │   └ Dockerfileなど
│   ├ nginx
│   │   └ Dockerfileなど
│   └ docker-compose.yml
│      
├ src
    ├ app
    │   └ ...
    ├ config
        └ ...
...

多くのサイトではdocker配下にsrcを置いている構成になりますが、自分の場合はその関係になっていないことに注意してください。

なぜdockerとsrcを別の(並列した)階層にしたかったのか

完全に主観ですが、開発するときにrailsのフレームワークをいじっているのに、その階層にdocker関連のファイルがあることが許せませんでした。整頓したかっただけです。

なぜ詰まったのか

他のサイトの内容でやると以下のような現象が起きました。

  • とあるライブラリがありませんみたいなエラーが出る。
Could not find public_suffix-4.0.5 in any of the sources

たったこれだけなのですが、めちゃくちゃ詰まりました。

原因

多くのサイトはDockerfileが以下のような記述になっています。

Dockerfile
FROM ruby:2.5.1

# リポジトリを更新し依存モジュールをインストール
RUN apt-get update -qq && \
    apt-get install -y build-essential \
                       nodejs

# ルート直下にwebappという名前で作業ディレクトリを作成(コンテナ内のアプリケーションディレクトリ)
RUN mkdir /webapp
WORKDIR /webapp

# ホストのGemfileとGemfile.lockをコンテナにコピー
ADD Gemfile /webapp/Gemfile
ADD Gemfile.lock /webapp/Gemfile.lock

# bundle installの実行
RUN bundle install

# ホストのアプリケーションディレクトリ内をすべてコンテナにコピー
ADD . /webapp

webappは私の構成でいうsrcのことです。
この書き方では私のように並列しているディレクトリ構成にはできないので注意してください。このGemfileの構成は以下のようになっています。

Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 6'

これ並列にしている都合上、docker-compose upする度にこのほとんど何もないGemfileでbundle installされることになります。そうすると、コンテナ側にあったGemfileが古いもので上書きされることになり、うまくRailsが起動しない原因となります。

どうすれば良いのか

解決策のDockerfileの構造です。

Dockerfile
ARG RUBY_VERSION

FROM ruby:${RUBY_VERSION}

RUN curl https://deb.nodesource.com/setup_12.x | bash
RUN curl https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

RUN apt-get update -qq && \
    apt-get install -y build-essential \ 
                       libpq-dev \        
                       nodejs \
                       yarn \
                       vim

RUN mkdir /var/www
WORKDIR /var/www

################## ここが大事!! ################
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
##############################################

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]

このようにして、ENTRYPOINTでシェルスクリプトを起動するようにします。entrypoint.shは以下のようになります。

entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f tmp/pids/server.pid


if [ ! -e Gemfile ]; then
    ls
    echo "初回"
    echo "source 'https://rubygems.org'" > Gemfile
    echo "gem 'rails', '~> 6'" >> Gemfile
    echo "" > Gemfile.lock
    bundle install
    rails new . --force --database=mysql
fi;



# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

これだけだとコンテナにGemfileが永続化されないので、docker-compose.ymlに以下のように記述します。

docker-compose.yml
### Workspace app server ################################################
  workspace:
    build:
      context: ./workspace
      args:
        - RUBY_VERSION=${RUBY_VERSION}
    volumes:
        - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}${APP_CODE_CONTAINER_FLAG}
        - ${APP_CODE_PATH_HOST}/bundle:${WORKSPACE_BUNDLE_SOURCE}
    ports:
      - "3000:3000"
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    depends_on:
      - mysql

ここのvolumeでコンテナをホストのsrcでマウントします。このようにすることで、Gemfileが古いもので上書きされてしまう心配はなくなりました。

bundle installが毎回走ってしまうのでは?

本記事とは少しそれますが、/usr/local/bundleをマウントしないと毎回bundle installする必要が出て、起動にかなり時間がかかるので注意してください。

RailsとDockerを分けてすっきりさせたい人

作ったものをGithubにあげました。やり方もREADME.mdに書いたので数分で構築できると思います。

終わりに

かなり少数派かもしれませんが、dockerのディレクトリと分けたいと思っている方には役立ってくれるかなと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Django on Dockerの環境づくりの記事を見ながら構築してたら途中でERROR: for django Cannot start service django: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"/usr/src/app/entrypoint.sh\": permission denied": unknownと出たので解決した

エラー内容

ERROR: for django  Cannot start service django: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"/usr/src/app/entrypoint.sh\": permission denied": unknown

環境

Mac OS Catalina 10.15.4

経緯

DockerでDjangoの開発環境を再構築!!!!

を参考にDjango REST Frameworkの環境を構築していた所、Djangoの環境をDocker上にcomposeしようとしたら以上のエラー内容が出てきたのでメモ用に記事を書いておきます。

状況としては、DjangoとpostgreSQL、nginxのDockerfileを書いた後にentrypoinst.shを作成し、DjangoディレクトリのDockerfile

backend/containers/django/Dockerfile
# これ
COPY ./entrypoint.sh /usr/src/app/entrypoint.sh

COPY . /usr/src/app/

# これ
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]

のコメントアウトを消して再び

$ docker-compose up -d --build

コマンドを叩くと冒頭のエラーが出ました。

手っ取り早い解決策としては

Error: Starting container process caused “exec: \”/docker-entrypoint.sh\“: permission denied”

この記事を参考にしました。
エラー内容的にも権限が与えられていないのが原因とはわかっていたのですが、早く解決するためにググりました。

結論としてはDjangoディレクトリで

$ chmod 755 entrypoint.sh

で権限を与え、再び

$ docker-compose up -d --build

してあげると無事にDockerfileの変更が反映されます。

Dockerはいざ自分で触ると分からないことが多くて触るだけでも勉強になりますね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VultrでKUSANAGI Runs on Dockerが動くまで(その3)

前回のおさらい

前回の記事『VultrでKUSANAGI Runs on Dockerが動くまで(その2)』ではVPC環境であるVultrKUSANAGI RoD環境を構築しWordpressをインストールするところまで確認しました。
今回はWordpressの設定を変えていきたいと思います。

動作環境など

  • Ubuntu 20.04
  • docker 19.03.12
  • docker-compose 1.26.2
$ docker-compose ps
       Name                     Command                 State                          Ports                     
-----------------------------------------------------------------------------------------------------------------
kusanagi01_config    docker-entrypoint.sh wp -- ...   Restarting                                                 
kusanagi01_db        docker-entrypoint.sh mysqld      Up                                                         
kusanagi01_ftp       /bin/sh -c /docker-entrypo ...   Up                                                         
kusanagi01_httpd     /docker-entrypoint.sh /usr ...   Up           0.0.0.0:8080->8080/tcp, 0.0.0.0:8443->8443/tcp
kusanagi01_php       /usr/local/bin/docker-entr ...   Up  

変更するWordpress周りの設定

  1. KUSANAGIパスワードの省略
  2. フォルダのパーミッションの変更(やらなくても大丈夫かも)

1. KUSANAGIパスワードの省略

KUSANAGIはセキュリティのためテーマやプラグインをインストールする際に以下のようにKUSANAGIパスワードを聞かれます。KUSANAGIパスワードはプロビジョニング時に指定していなければインストールディレクトリの.kusanagi.wpに記載があります。
img03.JPG

毎回パスワードを聞かれないようにするためには、wp-config.phpのFS_METHODをftpextからdirectに変更します。
KUSANAGI RoDの場合はローカルのファイルを修正し、kusanagiコマンドでコンテナにコピーする形になります。

$HOME/kusanagi01/contents/wp-config.php
#define('FS_METHOD', 'ftpext');
define('FS_METHOD', 'direct');          ここを変更
define('FTP_HOST', 'localhost');
define('FTP_USER', 'kusanagi');
#define('FTP_PASS', '*****');

以下のコマンドでコンテナにコピーします。エラー出るけど気にしなくて大丈夫です。

$ cd $HOME/kusanagi01
$ kusanagi-docker config push
chown: unknown user/group kusanagi:www
ERROR: Failed.

コンテナにログインしてファイルがアップされているか確認します。ftpコンテナにシェルアクセスして確認します。

ホスト上で実行
$ docker-compose exec ftp sh

以下、ftpコンテナ
/ # ls -al /home/kusanagi/kusanagi01/
total 28
drwxr-xr-x    6 kusanagi 1001          4096 Jul 26 03:15 .
drwxr-xr-x    3 kusanagi 1001          4096 Jul 26 03:29 ..
drwxr-x---    5 kusanagi 1001          4096 Jul 23 14:01 DocumentRoot
drwxr-xr-x    2 kusanagi 1001          4096 Jul 16 10:24 settings
drwxr-xr-x    2 kusanagi 1001          4096 Jul 18 13:56 tools
drwxr-xr-x    4 kusanagi 1001          4096 Jul 16 10:24 wp-config-sample
-r--r-----    1 kusanagi 1001          3345 Jul 26 03:15 wp-config.php

/ # cat /home/kusanagi/kusanagi01/wp-config.php |grep FS_
#define('FS_METHOD', 'ftpext');
define('FS_METHOD', 'direct');

2. フォルダのパーミッション変更(やらなくても大丈夫かも)

※以下の記述はやらなくても大丈夫かもしれません。
KUSANAGIパスワードとは別の問題でデフォルト状態だとフォルダに書き込み権限がなくて色々うまくいきません。
img04.JPG

ftpコンテナにシェルアクセスしてフォルダに権限を付与します。ftpコンテナだけrootでログインできるので何か変更する場合はftpコンテナを使います。
色々試した結果、以下のパーミッションでうまく動きました。きっとこれで大丈夫かと思います。
※kusanagi-docker configu pushをすると設定が元に戻るので要注意

  • DocumentRootを750から755に変更
  • DocumentRoot/wp-content配下のuploadsを755から775に変更
  • DocumentRoot/wp-content配下のuploads以外は755のまま
  • DocumentRoot/wp-content配下のlanguagesは750のまま
ホスト上で実行
$ docker-compose exec ftp sh

以下、ftpコンテナ
/ # cd /home/kusanagi/kusanagi01/
/home/kusanagi/kusanagi01 # chmod 755 DocumentRoot/
/home/kusanagi/kusanagi01 # cd DocumentRoot/
/home/kusanagi/kusanagi01/DocumentRoot # chmod -R 775 uploads/
/home/kusanagi/kusanagi01/DocumentRoot # ls -al /home/kusanagi/kusanagi01/DocumentRoot/wp-content/
total 36
drwxr-xr-x    8 kusanagi 1001          4096 Jul 18 13:56 .
drwxr-xr-x    5 kusanagi 1001          4096 Jul 23 14:01 ..
-rw-r--r--    1 kusanagi 1001            28 Jul 18 13:55 index.php
drwxr-x---    4 kusanagi 1001          4096 Jul 18 13:55 languages
drwxr-xr-x    3 kusanagi 1001          4096 Jul 16 10:24 mu-plugins
drwxr-xr-x    4 kusanagi 1001          4096 Jul 26 09:06 plugins
drwxr-xr-x    7 kusanagi 1001          4096 Jul 26 09:05 themes
drwxr-xr-x    2 kusanagi 1001          4096 Jul 26 09:06 upgrade
drwxrwxr-x    3 kusanagi 1001          4096 Jul 23 14:38 uploads

これでまともにWordpressが動くようになりました。
Wordpressに好きなテーマインストールしてカスタマイズして使い倒してください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

NextcloudのOnlyOfficeとECSのコンテナを統合する方法

今回は、NextcloudOnlyOfficeAlibaba Cloud Elastic Compute Service (ECS)インスタンスのコンテナと連携させる方法を見ていきます。

本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

By Colince Azeye, Alibaba Cloud Tech Share Author. Tech Shareは、クラウドコミュニティ内で技術的な知識やベストプラクティスを共有することを奨励するAlibaba Cloudのインセンティブプログラムです。

今回の記事では、Alibaba Cloud Elastic Compute Service (ECS)インスタンスでNextcloudのOnlyOfficeとコンテナを統合する方法を見ていきたいと思います。

しかし、始める前に、このチュートリアルの各コンポーネントを簡単に紹介します。Nextcloudの詳細については、代わりにECSにNextcloudをインストールする方法についてのこちらの記事を参考にしていただければと思いますので、今のところは割愛させていただきます。

Wikipediaによると、Nextcloudはファイルホスティングサービスを作成・利用するためのクライアント・サーバ・ソフトウェアのスイートです。機能的にはDropboxに似ていますが、Nextcloudは無料でオープンソースなので、誰でもプライベートサーバーにインストールして運用することができます。

OnlyOfficeは、豊富な機能を備えた包括的なオープンオフィス、クラウドベースのオフィスおよび生産性スイートです。以前はTeamLab Officeと呼ばれていたこのソフトウェアは、オンラインドキュメントエディタ、CRM、ドキュメントおよびプロジェクト管理ツールのコア要素を持つ統合プラットフォームをユーザーに提供しています。

Spreedは、フリーのオープンソース(AGPL)のWebRTCオーディオ/ビデオ通話・会議サーバで、ブラウザ同士がピアツーピアで会話できるようにします。Spreedを使用すると、Nextcloudをインストールしたブラウザから、リッチな音声、ビデオ、テキストチャットを使って安全に通信することができます。

Dockerコンテナは、その場で作成して特定のアプリケーションや環境をデプロイすることができる標準化されたユニットです。概念的には仮想化技術に似ていますが、オペレーティングシステムがコンテナから抽象化されている点が大きな違いです。

ECS(Elastic Compute Service)は、物理サーバよりもシンプルで効率的な管理モードを備えた、弾力的な処理能力を特徴とするコンピューティングサービスの一種である。

全てをまとめる

NextcloudとOnlyofficeをECSで利用する目的を見てみましょう。オンライン資産を最新の状態に保ちながら、オフィスでのコラボレーションやプライベート共有のためのツールを必要としている組織を想像してみてください。Nextcloudは人との接続、チャット、データ共有、コラボレーションを可能にし、OnlyofficeはオンラインドキュメントエディタでNextcloudの連絡先との作業、CRMでの顧客管理を可能にします。Spreedは、あなたのNextcloud上で簡単に電話会議を持つことができるようになります。さらに、コンテナを使用してすべてを実行することで、アプリ開発の柔軟性が高まり、システムの軽量化にもつながります。

前提条件

  • 有効なAlibaba Cloudアカウントが必要です。まだお持ちでない場合は、無料トライアルにサインアップすることができます。
  • Ubuntu 16.04を実行しているAlibaba Cloud ECSインスタンス。
  • ルートアクセスまたはルートアクセスを持つユーザー(sudoグループ内)。
  • 有効なドメイン名(これはオプションですが、トラフィックを暗号化したい場合は必要です)。

ステップ1:システムをアップデートしてアップグレードします。この2つのコマンドを実行することで作業が完了します。

apt-get update
apt-get updgrade

ステップ2: nginxサーバーのインストール

apt-get install nginx

nginx の状態を確認して、動作していることを確認します。確認方法は主に2つあります。

  • service nginx status" コマンドを使用する。

image.png

  • ブラウザでECSインスタンスのパブリックIPアドレスを入力します。

image.png

ステップ3:Dockerをインストール:

apt-get install docker.io

dockerのインストール状況はもちろん、dockerのバージョンも確認できます。

service docker status
docker -v

image.png

上の画像のように、私のECSではdockerが実行されており、バージョンは1.6.2になっています。

ステップ4: docker-composeをインストール:

sudo curl -L https://github.com/docker/compose/releases/download/1.17.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

docker-compose をダウンロードして /usr/local/bin に入れます。フォルダの中に入って、docker-composeに実行権を与えます。

chmod +x docker-compose.

image.png

イメージの中には、docker composeをインストールするために使用するすべてのステップがあります。そして最後のコマンドで彼のバージョンを確認すると、私の場合は1.17.1になっています。

Step 5: システム起動時に自動起動するようにします。

Service docer reload

ステップ 6: githupレポをクローンした後、フォルダの中に入り、コマンドを入力します。

- cd docker-only-office-nextcloud
- git submodule update -remote

image.png

画像の中には、すべてのコマンドと結果を見ることができます docker-onlyoffice-nextcloudをクローンするために入力します。

ステップ 7: nextcloud-onlyofficeのデプロイ

今すぐコマンドを入力してください: docker-compose up -d to start container in .yml file

image.png

スクリーンショットを見ると、dockerコンテナが正常に起動したことがわかります。ブラウザでIPアドレスを入力すると、nextcloudのインターフェイスが表示されます。

image.png

注意: 上記の手順をすべて完了しても、パブリックIPアドレスを入力しても何も表示されない場合は、トラフィックがブロックされている可能性があります。つまり、特定のポートでのトラフィックを許可する必要があります。そのためには、ECSのセキュリティグループとルールを設定する必要があります。

  • Rule direction:Ingressを入力
  • Action: 許可を入力
  • Custom port Range:80/80を入力
  • Authorization Objects:0.0.0.0.0/0を入力します。
  • 説明を入力してOKを押します。

カスタムポート範囲 43/43 を指定して、上記の手順を繰り返します。

このチュートリアルを動作させるためには、ポート 80 と 43 からのトラフィックを許可しなければなりません。また、ポート80と43の両方について上記と同じ手順を繰り返す必要がありますが、ルールの方向をEgressに変更します。

完了したら、Nextcloudサーバーに再度アクセスします。

image.png

これがルールを作成するためのインターフェースです。ここでは、データベースとしてSQLiteを使用することを想定してみましょう。管理者ユーザー名と管理者パスワードを入力します。クリックして設定を終了します。

image.png

ご覧のように、最初の設定には管理者認証を入力する必要があります。数分後、あなたはあなたのウェルカムページにリダイレクトされます。

image.png

さて、ECS上でNextcloudをどのように設定したかというと、追加ボタンをクリックするとOnlyOfficeが表示されません。そこで設定するためには、CLI上でdocker-onlyoffice-nextcloudフォルダの中に立つ必要があります。その中で、bash set-configuration.shというコマンドを入力します。

しかし、OnlyOfficeが動作するためには信頼できるドメインが必要なので、その前に有効なドメイン名にパブリックIPアドレスをアタッチする必要があります。ドメイン名の設定後、以下のように表示されるはずです。

image.png

image.png

ステップ8. スプレードのインストール

Spreed WebRTCとNextcloudを同じオリジンで動作させる必要があります。つまり、SpreedとNextcloudは同じプロトコルスキーム、同じドメイン、同じポートを使ってアクセスすることができます。

Nextcloudにアクセスして、右上にある「A」のロゴを見つけます。それをクリックして、アプリをクリックします。インストールされているアプリ、アクティブなアプリ、アップデートを含むアプリのすべてのカテゴリが表示されます。今度はApp bundlesをクリックして、"talk "を探して、それをインストールするためにクリックします。

注:あなたはアプリのバンドルで話を見つけることができませんでした場合は、ちょうど上記の検索バーに "話 "を入力し、エンターキーを押します。

image.png

さて、プラットフォーム上にいない人と話したい場合はどうしますか?URLで外部のチャット参加者を招待することができます。このチャットは、ユーザーが通話から離れても開かれたままで、参加者がメッセージ、リンク、メモを簡単に交換することができます。また、パスワードで公開グループチャットを保護することもできます。

これで完了です。

結論

これが終わるまでに、私たちはAlibaba Cloud ECS上に完全なコンテナ化されたSaaSサービスを設定しました。このチュートリアルがお役に立てたことを願っています。

アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Xulu:DockerのリモートAPI不正アクセス脆弱性を利用した悪意のあるコンテナのデプロイ

Alibaba Cloudは最近、DockerのリモートAPI不正アクセス脆弱性を悪用して悪意のあるコンテナを展開するマイニングボットネット「Xulu」を検出しました。

本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

今月初め、DockerのリモートAPI不正アクセス脆弱性を悪用して悪意のあるDockerコンテナを被害者ホストにデプロイするマイニングボットネットを検出しました。ボットネットのマイニングでユーザー名として機能することから、このボットネットを「Xulu」と命名しました。

XuluはDockerを狙った最初のボットネット事例ではありませんが、他のボットネットとは異なり、自ら他のホストをスキャンするのではなく、OSINT(オープンソースインテリジェンス)の技術を利用し、初段を動的に検索して獲物となりうるリストを探し出します。

また、制御サーバーをTorネットワークに配置しており、ボットネットの邪悪な裏工作員を隠そうとしているのかもしれません。

image.png

Moneroを採掘する悪質なDockerイメージ

コンテナとは、コードとそのすべての依存関係をパッケージ化したソフトウェアの標準的な単位であり、アプリケーションがあるコンピューティング環境から別のコンピューティング環境へと迅速かつ確実に実行されるようにします。

docker.comのこの定義は、dockerコンテナとは何かを説明しています。今日では、マイクロサービスの人気が高まるにつれ、多くの企業がアプリケーションのデプロイにコンテナを使用しています。しかし、そのセキュリティは見落とされがちで、Dockerサービスは悪用されやすいターゲットになりかねません。

Xuluのボットネットイベントを掘り下げてみると、悪意のある「zoolu2/auto」のdockerイメージを持つコンテナが、侵害されたホスト上に作成されていることに気付きました。

image.png

コンテナには以下のプロセスが実行されています。

image.png

採掘プロセスを区別するのは簡単です。

/toolbin/darwin -o us-east.cryptonight-hub.miningpoolhub.com:20580 -u xulu.autodeploy -p x --currency monero -i 0 -c conf.txt -r 

miningpoolhub .comはユーザーの公開支払いデータを提供していないため、脅威となる行為者がcryptojackingからどれだけの経済的利益を得ているかはわかりません。

ボットネットの伝播と持続性

Xulu ボットネットは OSINT 技術と Tor ネットワークを使って増殖しています。

まず最初に、ボットネットは http://wg6kw72fqds5n2q2x6qjejenrskg6i3dywe7xrcselhbeiikoxfrmnqd.onion を制御サーバとして使用します。接尾辞の「.onion」は、Torネットワークを介して到達可能な匿名のオニオンサービス(別名「隠されたサービス」)であることを示しています。

image.png

ボットネットはまた、/toolbin/shodaemonをメインのデーモンプロセスとして実行しています。

image.png

スクリプトからは、まずリモートファイル http://wg6kw72fqds5n2q2x6qjejenrskg6i3dywe7xrcselhbeiikoxfrmnqd.onion/shodan.txt とローカルファイル /toolbin/hcode.txt の内容を組み合わせて /search.txt を生成していることがわかります。

image.png

image.png

各ファイルには shodan のクエリのリストが含まれており、それらは /toolbin/shodan によって読み込まれて送信されます。

クエリは、インターネット上で開かれているDockerポート(2375)を持つホストのipsを返します。すべてが脆弱ではありませんが、脅威のアクターはshodanの情報を利用することで大量のスキャン作業を省くことができます。

image.png

重複を削除した後、侵害されたホストは、収集した各IPに "docker run "コマンドを送信します。その後、zoolu2/autoの悪意のあるコンテナは、DockerリモートAPI不正アクセスの脆弱性を持つ新しいホストにデプロイされます。

image.png

さらに、ボットネットは http://wg6kw72fqds5n2q2x6qjejenrskg6i3dywe7xrcselhbeiikoxfrmnqd.onion/bnet1.txt からスクリプトをダウンロードして実行し、永続化を図っています。

image.png

攻撃の規模とセキュリティの推奨

https://hub.docker.com では、前述の悪意のあるドッカーイメージが 10k 回以上ダウンロードされています。

image.png

Xuluボットネットの作者は、ボットネットの亜種を積極的に開発しているようです。

image.png

このイベントはDockerユーザーのCaprico1さんも観測しており、DockerのGitHubで議論されています。

image.png

https://github.com/docker/hub-feedback/issues/1809

この記事が公開される頃には、Dockerのエンジニアによってzoolu2のアカウントが無効化されています。

image.png

悪意のある侵入やマイニングの犠牲者にならないために、以下のような推奨事項があります。

  • 内部利用のためのサービス(Dockerなど)はインターネットに公開しないこと。適切な ACL やその他の認証技術を使用して、信頼できるユーザーからのアクセスのみを許可します。
  • 隠されたサービスは多くのボットネットによって利用されているので、頻繁に利用しないユーザーは、以下のようなトリックを使って、隠されたサービスとの間でパケットをドロップすることができます: echo -e "η0.0.0.0.0 .onion" >> /etc/hosts このコマンドは、隠されたサービスとの間のトラフィックをシンクホール(リダイレクト)します。
  • クラウドファイアウォールは攻撃を防ぐのに便利です。Alibaba Cloud Firewallをおすすめする理由は、脅威の検知、ブロック、分析ができるからです。AI技術を味方につけて、侵入や悪意のあるマイニングから守ることができます。
  • アリババクラウドマネージドセキュリティサービスを利用することで、アリババのセキュリティスペシャリストの専門知識を利用して、マルウェアのクリーンアップや設定の改善、全体的なセキュリティ強化を支援してもらうことができます。組織のセキュリティに不安を感じている方は、ぜひ一度試してみてはいかがでしょうか。

IOC

サーバーを制御:

http://wg6kw72fqds5n2q2x6qjejenrskg6i3dywe7xrcselhbeiikoxfrmnqd.onion

URL:

http://wg6kw72fqds5n2q2x6qjejenrskg6i3dywe7xrcselhbeiikoxfrmnqd.onion/bnet1.txt
http://wg6kw72fqds5n2q2x6qjejenrskg6i3dywe7xrcselhbeiikoxfrmnqd.onion/shodan.txt

Pool:

us-east.cryptonight-hub.miningpoolhub.com:20580

Md5:

c29dfe75862b6aed91bec4ffc7b20b9c 

参照

https://twitter.com/Suprn8/status/1129877707897081856

https://www.alibabacloud.com/blog/dockerkiller-threat-analysis-first-instance-of-batch-attack-and-exploitation-of-docker-services_593947

https://www.docker.com/resources/what-container

アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Polarisを用いてKubernetesのベストプラクティスを3分でチェックする

Kubernetesにおけるベストプラクティスを取り巻く流れ

Kubernetesが成熟してきたことと、DevとOpsの責任範囲分離などの背景があり
アプリケーションエンジニアもKubernetesを扱う場面が増えてきたという話をちらほら耳にする。
ここで、Kubernetesわかるマンにとっては朝飯まであったYAMLをこねこねする作業を、誰でも行うような動きが加速しており、今後もこの状態が続いていくと想像できる。

特にKubernetesのセキュリティ観点に目を向けると、CNCFが新たにKubernetesのセキュリティに特化した新試験を近日公開することもあり、Kubernetesを用いた開発をより均質化・安定化させていく動きがみられる。
https://training.linuxfoundation.org/ja/certification/certified-kubernetes-security-specialist/

ここでは、手元のKubernetesクラスタがベストプラクティスに沿っているかを手軽に確認できるツールである、Polarisを紹介する。

Polarisの機能概要

FairwindsのPolarisは、クラスターの円滑な運用を維持する。様々なチェックを実行して、Kubernetesポッドとコントローラがベストプラクティスに沿っていることを確認し、将来的な問題を回避することに役立てられる。Polarisは、下記の3つのモードで実行できる。

ここではダッシュボードについて取り上げ、まとめにてValidating Webhook, CLI toolについて触れる。

  • ダッシュボード
  • Validating Webhook
  • CLI tool

FairwindsOps/polaris

Dashboard Quick Start

クラスタの用意
ここは環境に合わせて用意ください。ここではkindを用いた例で説明します。

  kind create cluster

porarisをダッシュボードとしてデプロイし、ダッシュボード Serviceをホストにポートフォワード

  kubectl apply -f https://github.com/FairwindsOps/polaris/releases/latest/download/dashboard.yaml
  kubectl port-forward --namespace polaris svc/polaris-dashboard 8080:80

以上で、polarisが動作している状態になります。
※port-forwardコマンドのタイミングが早すぎると、Pod起動前にポートフォワードが試行されエラーが返ります。

動作確認

localhost:8080にブラウザでアクセスすると、polarisのダッシュボードを確認できる

Untitled.png

5つのカテゴリごとにテスト結果のパーセンテージが表示される

  • Health Check:
  • Images
  • Networking
  • Resources
  • Security

Untitled 1.png

HealthCheck

HelathCheckのテストはシンプルで、下記のページに示されている通りReadinessProbeとLivenessProbeが定義されていなければ失敗する。デフォルトはWarningとしている

Images

Imagesのテストも下記に示されている2点のテストを行っている。

イメージのタグが指定されていないかlatestの場合に失敗する。デフォルトはdanger

イメージのpullPolicyがAlwaysじゃない場合に失敗する。デフォルトはignore

Networking

hostNetworkやhostPortが設定されている場合に失敗する。デフォルトはWarning

Resources

Resource Requests/LimitsがCPU, Memoryそれぞれに定義されていなければ失敗する。デフォルトはdanger

Security

下記の通り、特にホストマシンに影響を与える部分がdangerとなっている。

Untitled 2.png

Namespace内のKind別にテスト結果を確認できる

polaris以外に特に何も動かしていないクラスタのため、Kindにデフォルトで入っているlocal-path-storageとkube-system, polaris用のnamespaceが表示されている。

Untitled 3.png

kube-system namespace上のkindnetというDaemonsetに焦点を当ててみる。

Daemonsetから生成されるkindnet-cni コンテナに対して、危険なCapabilityを持っているというdangerアラートが出ている。CNIなのでこれは仕方ないが。

Untitled 4.png

まとめ

Polarisを使うことで、Kubernetesクラスタがベストプラクティスに沿っているかを手軽に検証することができる。

今回紹介していないが、KubernetesのAdmission ControllerにValidating Webhookとして組み込むことで、dangerと判定されるマニフェストが適用される場合に、それを自動的に拒否する仕組みにも対応している。

また、CLIとしても動作するためCI/CDのパイプラインに組み込み、dangerやwarningなどの閾値を設定することでCI/CDパイプラインを停止させる仕組みにも対応している。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

既存のRailsアプリの開発環境にDockerを導入する手順【Rails, MySQL, Docker】

こんにちは.
今回は, 既存のRailsアプリの開発環境にDockerを導入する手順をまとめてみました.
まだまだ勉強不足ですので, 修正点・改善点等ございましたら, ご指摘いただけますと幸いです.

事前準備

環境

Ruby:2.5.3
Rails:5.2.4.3
MySQL:5.6
Docker:19.03.8
docker-compose:1.25.4

手順

1. ルートディレクトリにDockerfile,docker-compose.ymlを追加

add_file.png

既存のRailsアプリのルートディレクトリ直下にDockerfiledocker-compose.ymlを作成します.
以下, それぞれのファイルの中身です.

Dockerfile

Dockerfile
FROM ruby:2.5.3
RUN apt-get update && apt-get install -y \
    build-essential \
    nodejs
WORKDIR /kakeibo
COPY Gemfile Gemfile.lock /kakeibo/
RUN bundle install
  • FROM ruby:2.5.3の部分についてはアプリのRubyのバージョンに合わせる.
  • RUN apt-get update && apt-get install -y ~で必要なパッケージをインストールする.
  • WORKDIR /kakeiboでコンテナ内にフォルダを作成.
  • COPY Gemfile Gemfile.lock /kakeibo/でコンテナ内にGemfileとGemfile.lockをコピーした後, bundle installを実行する.

docker-compose.yml

docker-compose.yml
version: '3'

volumes:
  mysql-data:

services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    ports:
      - '3000:3000'
    volumes:
      - '.:/kakeibo'
    tty: true
    stdin_open: true
    depends_on:
      - db
    links:
      - db

  db:
    image: mysql:5.6
    volumes:
      - 'mysql-data:/var/lib/mysql'
    environment:
      - 'MYSQL_ROOT_PASSWORD=password'

Dockerfiledocker-compose.ymlの中身の詳しい説明はこちらの記事にわかりやすくまとめられていました.

2. config/database.ymlを編集

config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: db

development:
  <<: *default
  database: kakeibo_development

config/database.ymlpasswordhostをdocker-compose.ymlで設定した値に合わせます.

3. コンテナ起動

terminal
$ docker-compose build
$ docker-compose up -d
$ docker-compose exec web rails db:create
$ docker-compose exec web rails db:migrate

これで http://localhost:3000 にアクセスすると無事にアプリが表示されるはずです.

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsアプリの開発環境をDockerで構築する手順【Rails, MySQL, Docker】

こんにちは.
今回は, Railsアプリの開発環境をDockerで構築する手順をまとめてみました.
まだまだ勉強不足ですので, 修正点・改善点等ございましたら, ご指摘いただけますと幸いです.

事前準備

環境

Ruby: 2.5.8
Rails: 5.2.4.3
MySQL: 5.7.31
Docker: 19.03.8
Docker Compose: 1.25.4

手順

1. プロジェクトのルートディレクトリを作成

terminal
$ mkdir test-app

初めに, プロジェクトのルートディレクトリを作成します.

2. ルートディレクトリ直下にファイルを追加

terminal
$ cd test-app
$ touch Dockerfile docker-compose.yml Gemfile Gemfile.lock

作成したルートディレクトリの直下にDockerfile, docker-compose.yml, Gemfile, Gemfile.lockの4つのファイルを作成します.
それぞれのファイルの中身は以下のようになります. (Gemfile.lockは空のままにします.)

Dockerfile
FROM ruby:2.5
RUN apt-get update && apt-get install -y \
    build-essential \
    nodejs
WORKDIR /test-app
COPY Gemfile Gemfile.lock /test-app/
RUN bundle install
docker-compose.yml
version: '3'

volumes:
  mysql-data:

services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    ports:
      - '3000:3000'
    volumes:
      - '.:/test-app'
    tty: true
    stdin_open: true
    depends_on:
      - db
    links:
      - db

  db:
    image: mysql:5.7
    volumes:
      - 'mysql-data:/var/lib/mysql'
    environment:
      - 'MYSQL_ROOT_PASSWORD=test-app'
Gemfile
source 'https://rubygems.org'
gem 'rails', '~>5.2'

3. コンテナ内にRailsのセットアップを行う

terminal
$ docker-compose run --rm web rails new . --force --database=mysql --skip-bundle --skip-test

webのコンテナ内でrails newを実行します.
今回はテストにRSpecを使用する予定でしたので, --skip-testも追加しています.

4. 作成されたconfig/database.ymlを編集

Railsのセットアップにより作成されたconfig/database.ymlを以下のように編集します.

config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: test-app   #docker-compose.ymlのMYSQL_ROOT_PASSWORDの値を設定する
  host: db   #docker-compose.ymlのservice名と合わせる

development:
  <<: *default
  database: test-app_development

5. コンテナの起動

terminal
$ docker-compose up --build -d
$ docker-compose run --rm web rails db:create

これで, http://localhost:3000 にアクセスすると, Railsのホーム画面が表示されるはずです.

rails_home_pic.png

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【2020年夏】VSCode で作る Docker 開発環境

前書き

今までスペックの低いコーディング環境だったので、EC2 に環境作って開発してたんですが、多少メモリに余裕のあるコーディング環境が用意できたので、Docker を使用した環境に移行することにしました。

が、思ったより、環境作るのに遠回りしたので、メモ書きを残しときます。

要するに「公式読め!」って記事です。たどり着ければ終了なので、ただのリンク集です。

最初に見るべきサイト

公式の記事です。
Developing inside a Container - code.visualstudio.com
remote - overview から読んだ方がよいかもしれません。

環境構築自体は、ドキュメントに従って作るだけなので、ドキュメント読み慣れてる人なら問題は起こらないと思います。
設定のポイントは.devcontainer/にできるDockerfiledevcontainer.jsonです。

Dockerfiledevcontainer.json

Remote-Containers: Add Development Container Configuration Files...を叩いた後、上記の 2 ファイルが、初期ファイルとして作成されます。
これを自身の環境用に改修していきます。

改修時に参照すべきは以下です。
microsoft / vscode-dev-containers

「Sample projects」って項目がありますが、参照すべきはそちらでは無く、vscode-dev-containers/containers/ のようです。使いたいテンプレートを clone できないのがちょっとメンドイ。
全体を clone してそこからコピーしろということのようです。

devcontainer.jsonの書式は、以下に従ってください。
devcontainer.json reference - code.visualstudio.com

これで大体必要なリンクは載せられたと思います。
まだ、実際の開発に使用していないので、いったん記事としてはここまでです。
どんどん作って壊して効率よく開発していきましょ!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

コンテナのアクセスが遅いと感じたので

コンテナにアクセスしてブラウザに表示するまでが遅くて不便だったので
対策をメモ

docker-compose.yml
web:
    image: nginx:alpine
    container_name: nginx
    ports:
      - '9400:80'
    depends_on: 
      - app
    volumes: 
      - ./default.conf:/etc/nginx/conf.d/default.conf:delegated
      - .:/var/www/html:delegated
  app:
    build: ./php
    container_name: php
    volumes: 
      - .:/var/www/html:delegated
    depends_on: 
      - mysql

volumeにdelegateオプションを付与

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerコンテナを止めずにapache2を再起動する方法【php7-apache】

結論

下記コマンドでreloadさせれば、変更を有効化できます。

$ /etc/init.d/Apache2 reload

環境

Docker for Windows 19.03.8
DockerImage php:7.4-apache

背景

Dockerでローカル環境構築中に困りました。
普段CentOSで開発していると、設定ファイル変更後に有効化させる際、下記のコマンドをたたきたくなるところですが、
この場合コンテナごと停止してしまいます。

systemctl apache2[httpd] restart

コンテナを止めずに設定変更の有効化をするには下記のコマンドをたたきましょう。

$ /etc/init.d/Apache2 reload
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む