20190607のdockerに関する記事は10件です。

一足遅れて Kubernetes を学び始める - 15. セキュリティ -

ストーリー

  1. 一足遅れて Kubernetes を学び始める - 01. 環境選択編 -
  2. 一足遅れて Kubernetes を学び始める - 02. Docker For Mac -
  3. 一足遅れて Kubernetes を学び始める - 03. Raspberry Pi -
  4. 一足遅れて Kubernetes を学び始める - 04. kubectl -
  5. 一足遅れて Kubernetes を学び始める - 05. workloads その1 -
  6. 一足遅れて Kubernetes を学び始める - 06. workloads その2 -
  7. 一足遅れて Kubernetes を学び始める - 07. workloads その3 -
  8. 一足遅れて Kubernetes を学び始める - 08. discovery&LB その1 -
  9. 一足遅れて Kubernetes を学び始める - 09. discovery&LB その2 -
  10. 一足遅れて Kubernetes を学び始める - 10. config&storage その1 -
  11. 一足遅れて Kubernetes を学び始める - 11. config&storage その2 -
  12. 一足遅れて Kubernetes を学び始める - 12. リソース制限 -
  13. 一足遅れて Kubernetes を学び始める - 13. ヘルスチェックとコンテナライフサイクル -
  14. 一足遅れて Kubernetes を学び始める - 14. スケジューリング -
  15. 一足遅れて Kubernetes を学び始める - 15. セキュリティ -

前回

一足遅れて Kubernetes を学び始める - 14. スケジューリング -では、AffinityなどでPodのスケジューリングについて学習しました。今回は、セキュリティについて学習します。

サービスアカウント

Podで実行するためのプロセスを制御するために割り振られるアカウントのことをサービスアカウントというそうです。

sample-serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sample-serviceaccount
  namespace: default
imagePullSecrets:
  - name: hogehoge

これをapplyしてみます。

pi@raspi001:~/tmp $ k apply -f sample-serviceaccount.yaml
pi@raspi001:~/tmp $ k get serviceaccounts sample-serviceaccount -o yaml
...
secrets:
- name: sample-serviceaccount-token-4xhgm

サービスアカウントが作成されました。また、imagePullSecretsの内容がsecretsに登録されました。(sample-serviceaccount-token-4xhgm)
imagePullSecretsはprivateなdockerレジストリに使います。

pi@raspi001:~/tmp $ k get secrets sample-serviceaccount-token-4xhgm -o yaml
apiVersion: v1
data:
  ca.crt: ...
  namespace: ZGVmYXVsdA==
  token: ...
kind: Secret
metadata:
  annotations:
    kubernetes.io/service-account.name: sample-serviceaccount
    kubernetes.io/service-account.uid: 4bd076da-8854-11e9-af26-b827eb8ccd80
  creationTimestamp: "2019-06-06T12:12:04Z"
  name: sample-serviceaccount-token-4xhgm
  namespace: default
  resourceVersion: "584634"
  selfLink: /api/v1/namespaces/default/secrets/sample-serviceaccount-token-4xhgm
  uid: 4bfbe8bb-8854-11e9-af26-b827eb8ccd80
type: kubernetes.io/service-account-token

認証に必要なtokenが登録されていますね。

RBAC (Role Based Access Control)

RBACは、さきほど作成したサービスアカウントと、どういった操作を許可するのかを定めたRoleを紐付け(RoleBinding)して、権限管理をします。1つのRoleに対して複数のサービスアカウントをRoleBindingできます。

RBACは、2つのレベルがあり、1つはNamespaceレベルで、もう一つはクラスタレベルがあります。
設定範囲がクラスタの方が大きい感じです。(namespace横断して設定する場合はクラスタレベルにする)

  • RoleとClusterRole
  • RoleBindingとClusterRoleBinding

操作の種類ですが、どのDeploymentやDaemonSetのようなリソースに対して下記のものがあります。

* 全ての処理
create 作成
delete 削除
get 取得
list 一覧取得
update 更新
patch 一部変更
watch 変更の追従

KubernetesのRBACについて

今回はKubernetes道場 20日目 - Role / RoleBinding / ClusterRole / ClusterRoleBindingについてを参考に進めます。

新しく作ったサービスアカウントでコンテキストを作成し、そのアカウントからPod情報を取得できるか試してみます。
そのためには、サービスアカウントの認証情報を通しておく必要があります。
※ RoleとClusterRoleに大きな違いはないため、Roleを試します。

pi@raspi001:~/tmp $ TOKEN=$(k get secret/sample-serviceaccount-token-jd279 -o json | jq -r .data.token)
pi@raspi001:~/tmp $ DECODE_TOKEN=$(echo -n $TOKEN | base64 -d)
pi@raspi001:~/tmp $ k config set-credentials sample-serviceaccount --token $DECODE_TOKEN

では、コンテキスト(sample-sa-context)を作成して、それを使用します。

pi@raspi001:~/tmp $ k config set-context sample-sa-context --user sample-serviceaccount --cluster kubernetes
pi@raspi001:~/tmp $ k config use-context sample-sa-context
pi@raspi001:~/tmp $ k config get-contexts
CURRENT   NAME                          CLUSTER      AUTHINFO                NAMESPACE
          kubernetes-admin@kubernetes   kubernetes   kubernetes-admin
*         sample-sa-context             kubernetes   sample-serviceaccount

新たに作成したサービスアカウントでPodの情報が取得できるか試してみます。

pi@raspi001:~/tmp $ k get po
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:default:sample-serviceaccount" cannot list resource "pods" in API group "" in the namespace "default"

Errorになりました。sample-serviceaccountは何もRoleをバインドしていないからですね。
では、RoleBindingしていきます。

元に戻ります。

pi@raspi001:~/tmp $ k config use-context kubernetes-admin@kubernetes
sample-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: sample-role
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
sample-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: sample-rolebinding
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: sample-role
subjects:
- kind: ServiceAccount
  name: sample-serviceaccount
  namespace: default
pi@raspi001:~/tmp $ k apply -f sample-role.yaml
pi@raspi001:~/tmp $ k apply -f sample-rolebinding.yaml

では、もう一度試してみます。

pi@raspi001:~/tmp $ k config use-context sample-sa-context
pi@raspi001:~/tmp $ k get po
NAME                                      READY   STATUS    RESTARTS   AGE
...

おお、取得できました!
もとに戻しておきます。

pi@raspi001:~/tmp $ k config use-context kubernetes-admin@kubernetes

SecurityContext

コンテナに対してセキュリティ設定をすることができます。
例えば、Capabilitiesの追加・削除、実行するユーザ、グループの変更、ファイルのReadOnly化などができるそうです。

sample-capabilities.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-capabilities
spec:
  containers:
    - name: nginx-container
      image: nginx:1.12
      securityContext:
        capabilities:
          add: ["SYS_ADMIN"]
          drop: ["AUDIT_WRITE"]

applyし、中身を確認してみます。

pi@raspi001:~/tmp $ k apply -f sample-capabilities.yaml
pi@raspi001:~/tmp $ k exec -it sample-capabilities /bin/bash
root@sample-capabilities:/# apt update && apt install libcap2-bin
root@sample-capabilities:/# capsh --print | grep Current
Current: = cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_sys_admin,cap_mknod,cap_setfcap+eip
root@sample-capabilities:/# exit

cap_sys_adminが増えてますね。audit_writeは見つかりません。
そもそも、どんな種類があるのか分からなかったので、こちらを参考にしました。

PodSecurityContext

Pod(全てのコンテナ)に対してセキュリティ設定をすることができます。
例えば、実行するユーザやグループの制御、root実行を拒否したり、カーネルパラメータを上書きすることもできます。

sample-runuser.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-runuser
spec:
  securityContext:
    runAsUser: 99
    # runAsGroup: 99
    supplementalGroups:
    - 1001
    - 1002
  containers:
    - name: centos-container
      image: centos:7
      command: ["/bin/sleep", "3600"]

では、applyしています。

pi@raspi001:~/tmp $ k apply -f sample-runuser.yaml
pi@raspi001:~/tmp $ k exec -it sample-runuser -- id
uid=99(nobody) gid=99(nobody) groups=99(nobody),1001,1002
pi@raspi001:~/tmp $ k exec -it sample-runuser -- ps aux | grep sleep
nobody       1  0.0  0.0   2032   372 ?        Ss   14:02   0:00 /bin/sleep 3600

実行したユーザがnobody(99)に変更されていますね。また、supplementalGroupsで、プライマリGIDに指定のGIDを追加することができます。

そのほか

PodSecurityPolicyや、NetworkPolicy、そして認証、認可のAdmissionControlというものもあるそうです。

お片付け

pi@raspi001:~/tmp $ k delete -f sample-serviceaccount.yaml -f sample-role.yaml -f sample-rolebinding.yaml -f sample-capabilities.yaml -f sample-runuser.yaml
pi@raspi001:~/tmp $ k config delete-context sample-sa-context

最後に

主にRBACについて学習しました。
複数人で開発する際は、コンテキストを分けて開発を進めるのが良いみたいですね。
今回で取り組んだように、誰がどの権限を持っているかをRBACで管理できるので、
必要以上の権限を与えられて事故るようなことは少なくなりますね。
(といっても、まだ個人でしか使ってないので分かりませんが...)

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

dockerのコンテナとイメージを削除する

未来電子テクノロジー株式会社でインターンをしている大学一回生です。
プログラミングの実務をしている先輩から、不要なdockerのコンテナとイメージを削除すると容量をかなり空けることができるとの情報をいただいたので、実行してみました。

基本操作

コンテナの削除

動いているコンテナの確認

$ docker ps

停止しているコンテナの確認

$ docker ps -a

コンテナの削除

$ docker rm コンテナID

イメージの削除

存在するイメージの確認

$ docker images

イメージの削除

$ docker rmi イメージID

イメージの削除でエラーが出た時の対処法

1.コンテナー>イメージの順に削除しているか確認

2.以下のコマンドで強制的に削除する

$ docker rmi -f イメージID

まとめ

プログラミング初心者なのでこんな簡単な操作にも詰まってしまいました。
けど、これでdockerを整理することができました。
なにか誤りがあればご指摘ください。

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

Visual Studioの謎のDockerfile

FROM mcr.microsoft.com/dotnet/core/runtime:2.2-stretch-slim AS base
WORKDIR /app


FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src
COPY ["hoge-server/hoge-server.csproj", "hoge-server/"]
RUN dotnet restore "hoge-server/hoge-server.csproj"
COPY . .
WORKDIR "/src/hoge-server"
RUN dotnet build "hoge-server.csproj" -c Release -o /app

FROM build AS publish
RUN dotnet publish "hoge-server.csproj" -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "hoge-server.dll"]

 こんなファイルなんですけど、これを普通にたたくとバグるんですよね。

Step 7/17 : COPY ["hoge-server/hoge-server.csproj", "hoge-server/"]
ERROR: Service 'hoge-server' failed to build: COPY failed: stat /var/lib/docker/tmp/docker-builder655807069/hoge-server/hoge-server.csproj: no such file or directory

あたりまえだけどファイルの指定位置がおかしい。Dockerfileがhoge-serverディレクトリの中にあるのに、hoge-serverディレクトリの中を見に行くみたいなことになってるんですよね。一旦上のディレクトリにDockerfileを持ち上げてるような動きをしてる。で、ためしにもちあげて実行すると普通にうごくんですよね。

なので同じDockerfileを二つ置いて運用しています。いやーなんでこんな仕様になってるのか教えてくれ~

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

Liberty on Docker(ubuntu)

websphere-libertyを日本語化してみた。
Dockerfileを以下としました。

FROM websphere-liberty:19.0.0.5-kernel as builder
ENV DEBCONF_NOWARNINGS yes

FROM websphere-liberty:19.0.0.5-kernel
USER root
RUN apt-get update \
    && apt-get -y install language-pack-ja \
    && update-locale LANG=ja_JP.UTF-8
ENV LANG ja_JP.UTF-8

USER 1001
RUN /opt/ibm/wlp/bin/installUtility install --acceptLicense defaultServer \
    && /opt/ibm/wlp/bin/securityUtility createSSLCertificate --server=defaultServer --password=test1234

EXPOSE 9080 9443

CMD ["/opt/ibm/wlp/bin/server", "run", "defaultServer"]

最初、apt-getする際、rootにしなかったのでエラーになった。websphere-libertyはユーザdefault(idは1001)で動くよう作られているんですね。また、createSSLCertificateを実行するとき、パスワードが短かったので怒られました。。
サイズの差は以下の通りです。

REPOSITORY                                 TAG                      IMAGE ID            CREATED              SIZE
websphere-liberty                          19.0.0.5-kernelJP        ff1fd694c225        About a minute ago   410MB
websphere-liberty                          19.0.0.5-kernel          30e139ebfe3e        9 days ago           344MB
websphere-liberty                          19.0.0.5-microProfile2   8acc64c44c06        6 days ago           459MB

動かすとこんな感じです。

IBM J9 VM バージョン 8.0.5.36 - pxa6480sr5fp36-20190510_01(SR5 FP36) (ja_JP) で、defaultServer (WebSphere Application Server 19.0.0.5/wlp-1.0.28.cl190520190522-2227) を起動しています
[AUDIT   ] CWWKE0001I: サーバー defaultServer が起動されました。
[AUDIT   ] CWWKE0100I: この製品は、開発使用向け、および限定的な実動使用向けにライセンスが交付されています。 全ライセン ス条項は以下で表示可能です: https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/license/base_ilan/ilan/19.0.0.5/lafiles/ja.html
[AUDIT   ] CWWKG0093A: 構成ドロップイン・リソースを処理中です: /opt/ibm/wlp/usr/servers/defaultServer/configDropins/defaults/keystore.xml
[警告      ] CWWKF0009W: サーバーは、いずれのフィーチャーもインストールするようには構成されていません。
[AUDIT   ] CWWKF0011I: defaultServer サーバーは、Smarter Planet に対応する準備ができました。defaultServer サーバーは 0.546 秒で始動しました。

別画面でexecし、dateコマンドを叩いた。

C:\Windows\System32>docker exec -it pensive_germain bash
default@63e96552ede9:/$ ls
bin   config  etc   lib              lib64    licenses  media  opt     proc  run   srv  tmp  var
boot  dev     home  lib.index.cache  liberty  logs      mnt    output  root  sbin  sys  usr
default@63e96552ede9:/$ date
2019年  6月  7日 金曜日 08:31:06 UTC
default@63e96552ede9:/$

UTCのままですね。JSTに変えてみます

C:\kazu>docker run -it -u 0 --rm websphere-liberty:19.0.0.5-kernelJP bash
root@6be8a5c31c11:/# date
2019年  6月  7日 金曜日 08:57:37 UTC
root@6be8a5c31c11:/# apt-get install tzdata
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下のパッケージが新たにインストールされます:
  tzdata
アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 15 個。
167 kB のアーカイブを取得する必要があります。
この操作後に追加で 2,867 kB のディスク容量が消費されます。
取得:1 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 tzdata all 2019a-0ubuntu0.16.04 [167 kB]
167 kB を 1秒 で取得しました (103 kB/s)
debconf: delaying package configuration, since apt-utils is not installed
以前に未選択のパッケージ tzdata を選択しています。
(データベースを読み込んでいます ... 現在 5888 個のファイルとディレクトリがインストールされています。)
.../tzdata_2019a-0ubuntu0.16.04_all.deb を展開する準備をしています ...
tzdata (2019a-0ubuntu0.16.04) を展開しています...
tzdata (2019a-0ubuntu0.16.04) を設定しています ...
debconf: unable to initialize frontend: Dialog
debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (Can't locate Term/ReadLine.pm in @INC (you may need to install the Term::ReadLine module) (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.22.1 /usr/local/share/perl/5.22.1 /usr/lib/x86_64-linux-gnu/perl5/5.22 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.22 /usr/share/perl/5.22 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base .) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 7.)
debconf: falling back to frontend: Teletype

Current default time zone: 'Etc/UTC'
Local time is now:      Fri Jun  7 08:57:56 UTC 2019.
Universal Time is now:  Fri Jun  7 08:57:56 UTC 2019.
Run 'dpkg-reconfigure tzdata' if you wish to change it.

root@6be8a5c31c11:/# ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
root@6be8a5c31c11:/# date
2019年  6月  7日 金曜日 17:58:12 JST
root@6be8a5c31c11:/#

これらを踏まえて、Dockerfileを変更しました。

FROM websphere-liberty:19.0.0.5-kernel as builder
ENV DEBCONF_NOWARNINGS yes

FROM websphere-liberty:19.0.0.5-kernel
USER root
RUN apt-get update \
    && apt-get -y install language-pack-ja tzdata \
    && update-locale LANG=ja_JP.UTF-8 \
    && ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
ENV LANG ja_JP.UTF-8

USER 1001
RUN /opt/ibm/wlp/bin/installUtility install --acceptLicense defaultServer \
    && /opt/ibm/wlp/bin/securityUtility createSSLCertificate --server=defaultServer --password=test1234

EXPOSE 9080 9443

CMD ["/opt/ibm/wlp/bin/server", "run", "defaultServer"]

Dockerfileを変更し、再度ビルド後、動かします。

C:\kazu>docker run -it --rm websphere-liberty:19.0.0.5-kernelJP bash
default@c3b72744f090:/$ date
2019年  6月  7日 金曜日 23:28:32 JST
default@c3b72744f090:/$

ちゃんど、JSTになっています。

ベースをkernelにしたので、インストールされるfeatureはありません。server.xmlを修正して、インストールしようかな。

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

Docker環境ゴミ掃除3選

Docker使ってると気づいたらディスクがいっぱいになってたことありませんか?

私はあります。
そのたびに要らなくなったイメージを探して、消して、使ってないボリューム探して、消して、とかやってたのですが、つらくなってきたのでゴミ掃除的なコマンドを使うようになりました( docker system prune とかね)。

でも、実はこのコマンドだけじゃ全てのゴミを掃除できません。
Docker環境には他にも色んなゴミが眠ってて、ある程度ヘビーに使おうとすると他の方法も組み合わせて使う必要があります。
ただし、消してはいけないデータも意図せず消してしまう危険もあるので、状況に応じて適切な方法でゴミ掃除しましょう。

本記事の読者として、以下のような方を想定しています。

  • Dockerを使ったことがある
  • イメージやコンテナなどの用語をとりあえず知っている

Dockerの資材

Dockerコンテナ周りの主な資材は以下があり、それぞれ使わなくなるとゴミができます。

資材 ゴミの例
イメージ もう使わなくなったコンテナのイメージや古いイメージなど。
コンテナ もう使わなくなって停止したコンテナなど。
ボリューム コンテナが停止/削除されてアンマウントされたボリュームなど。
ネットワーク もう使わなくなったネットワークなど。

図にすると以下のような感じです。

qiita_image.png

大事な点として、アプリエラーで停止しちゃったけど調査のために残しておきたいコンテナとか、
アンマウントしたけど運用データが入っているため残しておきたいボリュームなど、
運用によってゴミではないものもあります。

そのため、どのゴミ掃除コマンドでどこまで掃除されるか、をきちんと理解して使用する必要があります。

ゴミ掃除コマンド

dockerのコマンドでpruneオプションが使えるものがいくつかあり、それらをゴミ掃除コマンドと呼んでいます。

いろいろありますが、基本的には以下があれば私は大丈夫だと思います。

  • 【コマンド1】 docker system prune [-f]
  • 【コマンド2】 docker image prune -a [-f]
  • 【コマンド3】 docker volume prune [-f]

シチュエーション

以下に、シチュエーションごとに使うとよいゴミ掃除コマンドを紹介します。
ただし、停止状態のコンテナも消えるため、コンテナでエラーが発生して停止したコンテナを調査する場合などは実行してはいけません。

a. コンテナ置き換えのあと

とりあえず以下のコマンドを順番に打っとけば大丈夫です。
-f を付けると確認なしで実行されます。

  • 【コマンド1】 docker system prune [-f]
  • 【コマンド2】 docker image prune -a [-f]

これを実行すると以下が削除されます。

  • すべての未使用コンテナ(停止状態など)
  • すべての未使用ネットワーク(どのコンテナにも接続されていないものなど)
  • どのコンテナのベースにもなっていないすべてのイメージ

(docker system pruneExtended descriptiondocker image pruneExtended description を参照)

qiita_image_a.png

ボリュームは削除されないので運用データが消える心配はありません。
使っていないコンテナとかネットワークは、使う時にまた作ればいいので大丈夫。

アプリのバージョンアップなどでイメージが更新されたら、
新イメージでコンテナを作り直します。
すると、旧イメージが残るため、docker image prune で消しています。

b. サービスを停止してDocker上の全ての資材を削除するとき

[a. コンテナ置き換えのあと]のコマンドの後に、docker volume pruneも実行するとよいです。

  • 【コマンド1】 docker system prune [-f]
  • 【コマンド2】 docker image prune -a [-f]
  • 【コマンド3】 docker volume prune [-f]

これを実行すると以下が削除されます。

  • すべての未使用コンテナ(停止状態など)
  • すべての未使用ネットワーク(どのコンテナにも接続されていないものなど)
  • どのコンテナのベースにもなっていないすべてのイメージ
  • マウントされていないすべてのボリューム

(docker volume pruneExtended description を参照)

qiita_image_b.png

サービス停止時は、ボリュームに入った運用データも不要になります(どこかにバックアップはするかもしれませんが)。
したがって、コンテナ停止削除後、docker volume prune でボリュームも削除しています。

以上!

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

REDASH7でクエリが実行出来ない問題の解消

REDASH6からREDASH7へ移行しました。
無事にアップデート出来たと思ったのですが、クエリー作成画面で「Execute」をクリックしたのですが
何も結果が表示されない問題が発生しました。
解消方法までの手順を纏めました。

Dockerのログを確認

Dockerのログを確認します。
コンテナのログは以下のコマンドで表示出来ます。

# docker ps
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS                         NAMES
9e306be1ae43        redash/nginx:latest          "nginx -g 'daemon of…"   6 hours ago         Up 6 hours          0.0.0.0:80->80/tcp, 443/tcp   redash_nginx_1
56ede752534b        redash/redash:7.0.0.b18042   "/app/bin/docker-ent…"   6 hours ago         Up 6 hours          0.0.0.0:5000->5000/tcp        redash_server_1
613adc931afc        redis:3.0-alpine             "docker-entrypoint.s…"   6 hours ago         Up 6 hours          6379/tcp                      redash_redis_1
198297742e8c        redash/redash:7.0.0.b18042   "/app/bin/docker-ent…"   6 hours ago         Up 6 hours          5000/tcp                      redash_worker_1
207215d21524        postgres:9.5.6-alpine        "docker-entrypoint.s…"   6 hours ago         Up 6 hours          5432/tcp                      redash_postgres_1

workerコンテナで実行されているはずなのでworkerコンテナのログを確認します。

# docker logs redash_worker_1

「Execute」でSQL実行時に「InvalidToken」の文字列が出力されている事を発見。

どうやらdocker-compose.ymlのworker設定に「REDASH_COOKIE_SECRET」が入っていない事が原因の模様。
workerの設定に以下を追加し、コンテナ再起動。

docker-compose.yml
    REDASH_COOKIE_SECRET: veryverysecret
# docker-compose -f docker-compose.yml down
# docker-compose -f docker-compose.yml up -d

これで無事解消されました。

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

全文検索サーバを構築した話 その2(docker構築詳細編)

その1ではざっくりと全文検索サーバ構築の経緯と構築環境について記載しました。
その2ではもう少し掘り下げて環境構築のメモを記載します。(ほぼWebエビデンス)

OS環境

OSバージョン

$ cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)

カーネルバージョン

$ uname -a
Linux [ホスト名] 3.10.0-957.12.2.el7.x86_64 #1 SMP Tue May 14 21:24:32 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

dockerインストール

dockerはCentOS標準のdockerをyumでインストールしました。

$ sudo yum -y install docker

インストール:
  docker.x86_64 2:1.13.1-96.gitb2f74b2.el7.centos

依存性関連をインストールしました:
  PyYAML.x86_64 0:3.10-11.el7
  atomic-registries.x86_64 1:1.22.1-26.gitb507039.el7.centos
  audit-libs-python.x86_64 0:2.8.4-4.el7
  checkpolicy.x86_64 0:2.5-8.el7
  container-selinux.noarch 2:2.95-2.el7_6
  container-storage-setup.noarch 0:0.11.0-2.git5eaf76c.el7
  containers-common.x86_64 1:0.1.35-2.git404c5bd.el7.centos
  device-mapper-event.x86_64 7:1.02.149-10.el7_6.7
  device-mapper-event-libs.x86_64 7:1.02.149-10.el7_6.7
  device-mapper-persistent-data.x86_64 0:0.7.3-3.el7
  docker-client.x86_64 2:1.13.1-96.gitb2f74b2.el7.centos
  docker-common.x86_64 2:1.13.1-96.gitb2f74b2.el7.centos
  libaio.x86_64 0:0.3.109-13.el7
  libcgroup.x86_64 0:0.41-20.el7
  libsemanage-python.x86_64 0:2.5-14.el7
  libyaml.x86_64 0:0.1.4-11.el7_0
  lvm2.x86_64 7:2.02.180-10.el7_6.7
  lvm2-libs.x86_64 7:2.02.180-10.el7_6.7
  oci-register-machine.x86_64 1:0-6.git2b44233.el7
  oci-systemd-hook.x86_64 1:0.1.18-3.git8787307.el7_6
  oci-umount.x86_64 2:2.3.4-2.git87f9237.el7
  policycoreutils-python.x86_64 0:2.5-29.el7_6.1
  python-IPy.noarch 0:0.75-6.el7
  python-backports.x86_64 0:1.0-8.el7
  python-backports-ssl_match_hostname.noarch 0:3.5.0.1-1.el7
  python-ipaddress.noarch 0:1.0.16-2.el7
  python-pytoml.noarch 0:0.1.14-1.git7dea353.el7
  python-setuptools.noarch 0:0.9.8-7.el7
  setools-libs.x86_64 0:3.3.8-4.el7
  subscription-manager-rhsm-certificates.x86_64 0:1.21.10-3.el7.centos
  yajl.x86_64 0:2.0.4-4.el7

完了しました!

dockerサービス自動起動設定

$ sudo systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.

dockerサービス起動と確認

$ sudo systemctl start docker
$ sudo systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since 金 2019-06-07 14:42:00 JST; 23s ago
     Docs: http://docs.docker.com
 Main PID: 20950 (dockerd-current)
   CGroup: /system.slice/docker.service
           tq20950 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --defau...
           mq20958 /usr/bin/docker-containerd-current -l unix:///var/run/docker/libcontainerd/docker-containerd.sock ...

Fessのイメージを取得する

$ sudo docker pull codelibs/fess:latest
Trying to pull repository docker.io/codelibs/fess ...
latest: Pulling from docker.io/codelibs/fess
e79bb959ec00: Pull complete
d4b7902036fe: Pull complete
1b2a72d4e030: Pull complete
de423484a946: Pull complete
9ce08128c662: Pull complete
53b0cf80b370: Pull complete
52bd533f444d: Pull complete
f39d9fa4825b: Pull complete
ffbf2fa304a8: Pull complete
560b4917ad19: Pull complete
b19453126120: Pull complete
3e02eca524a0: Pull complete
5145f1f6b740: Pull complete
9c0519ef74ee: Pull complete
Digest: sha256:f8c9818af2035b2b5489756c609bf973f8cc02c460874f4f9e5e8672f7c105c9
Status: Downloaded newer image for docker.io/codelibs/fess:latest

Fessのdockerコンテナを作成する

dockerのコンテナ名は、"全文検索"を英訳すると"Full text search"となるため、頭文字を取って"fts"にしました。
また、メインサービスがfessになるため、ポート指定してつながなくても良いようにホストの80番ポートをコンテナ内の
fessの8080ポートにマッピングしています。

$ sudo docker run -d -p 80:8080 --name fts codelibs/fess:latest
c266e8c6c14d2514a60d987d1beb4c6c5a187b2ba5142a6087a464fc3261b17b

コンテナのタイムゾーンを変更する

コンテナ内のOS環境の標準タイムゾーンがUTCのため、日本時間のJSTに変更します。

$ sudo docker exec -it fts rm /etc/localtime
$ sudo docker exec -it fts ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# 時間確認
$ sudo docker exec -it fts date
Fri Jun  7 15:01:10 JST 2019
$ sudo docker exec -it fts ls -l /etc/localtime
lrwxrwxrwx 1 root root 30 Jun  7 15:00 /etc/localtime -> /usr/share/zoneinfo/Asia/Tokyo

Fess動作確認

curlで80番ポートにHTTPしてヘッダが読めるか確認します。

$ curl --head http://localhost
HTTP/1.1 200
Set-Cookie: JSESSIONID=4937956A71BB0E6DE7D7B974BB39D7F0; Path=/; HttpOnly
Pragma: no-cache
Cache-Control: no-cache, no-store
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Date: Fri, 07 Jun 2019 06:08:41 GMT

ブラウザ動作確認

fessスクリーンショット.PNG
ブラウザでアクセスしてFessのページが表示されればOK。

まとめ

こんな感じで非常に簡単にFessによる全文検索サーバの環境が構築できます。
実際やっていただければわかりますが、イメージのダウンロード時間を除けばものの数分でFessが
利用できる環境を構築することができます。

おまけ

割愛しておりますが、selinuxを無効、firewalldの停止をしております。
selinuxとfirewalldを有効にして利用する場合はもうひと手間手順が必要かもしれません…
その辺は別の詳しい方に聞いてください…(弱気)

次回こそ、PDF変換手順の説明を書きます!

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

Docker初心者が学ぶならこの順番が分かりやすかった

はじめに

この記事の内容は以下の方向けです。
・Dockerって何?って人
・学び始めたけどいまいちピンってこない人

あくまでも学習の取っ掛かりに過ぎないと思ってください。
それ以外の人にはあまり有益な情報は無いと思いますので、
回れ右をして私より有能なエンジニアの記事を探してください。

結論

コンテナ、Docker Compose、Docker Fileの順で学ぶのが分かりやすい!!

なぜそうなったのか

資料は探してみたけどDockerの成り立ちとか概念とかばっかり...
そういうものは最終的に書き方のリファレンスなって理解が進まない...
自分はそんなのが知りたいわけじゃない...
といった私の経験から出た結論が

image.png

というわけで重要点です。
コンテナ
Docker Compose
Docker File

私は上記の3点がDockerを理解するうえで最低限なポイントと感じました。
そしてこの順序で学習していくと今までこんがらがっていたところがするすると紐解けました。


以下は上記の重要点をまとめたものとなります。
学習の参考資料としてお使いください。

コンテナ

OSSであるDocker上で動く環境一つの単位です。
基本はOS、ミドルウェア、アプリケーションで構成された環境のことを指します。

コンテナのイメージ
image.png

そして、このコンテナをDocker Engine上に複数配置して環境を構築します。

Dockerによる環境構築のイメージ
image.png

Docker Compose

Dockerの初期学習をした方の中にはこういった経験をした人はありませんでしたか?

image.png

これは非常にめんどくさい!!
できればボタン一つ、コマンド一つで環境の立ち上げや終了をしてほしいと思うのがエンジニアの心情だと思います。

そこで登場するのがDocker Composeです。
image.png

Docker Composeはymlファイルという定義ファイルを記述しコマンドを実行すると定義ファイルに書かれた内容(複数のコンテナの作成や作成時の環境変数など)を人の代わりにやってくれる優れものなのです。

Docker File

Docker FileとはDockerイメージを作るため情報を記載したファイルです。
※Dockerイメージとはコンテナを作る際のレシピみたいなものです。
 コンテナはDockerイメージを元に作成されます。

DockerFileとコンテナの関係性
image.png

既存のDocker Imageにカスタマイズを施すために使用することが主たる使用方法です。
例えば、公開されているLinux系OSのDocker Imageをベースにほかのパッケージやアプリを入れたオリジナルの環境を作る時などに使用します。

まとめ

今までの開発環境のセッティングが石器時代に感じるぐらい
簡単に環境がセッティングできる素晴らしさ知ったらもう手放せませんね。
image.png

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

ojichatをSlackに流す

最近ojichatが流行ってますね。
普段会社の勤怠はSlackに投稿してるんですが、あまりに自分の遅刻が多く自分のメッセージで埋まるので、ojichatを流すことにしました。

https://github.com/naomichi-y/ojichat-slack-bot

Screen Shot 2019-06-07 at 9.50.22.png

和む。

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

gcc on Docker

gccの最新版をビルドしてみます。
alpine gccのDockerfileを使用します。

FROM alpine as alpine

ARG GCC_VERSION
ENV GCC_VERSION=${GCC_VERSION}

FROM alpine as builder
RUN apk add --quiet --no-cache \
            build-base \
            binutils \
            dejagnu \
            isl-dev \
            make \
            mpc1-dev \
            mpfr-dev \
            texinfo \
            zlib-dev

RUN wget -q https://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/gcc-${GCC_VERSION}.tar.gz && \
    tar -xzf gcc-${GCC_VERSION}.tar.gz && \
    rm -f gcc-${GCC_VERSION}.tar.gz

WORKDIR /gcc-${GCC_VERSION}

RUN ./configure \
        --prefix=/usr/local \
        --build=$(uname -m)-alpine-linux-musl \
        --host=$(uname -m)-alpine-linux-musl \
        --target=$(uname -m)-alpine-linux-musl \
        --with-pkgversion="Alpine ${GCC_VERSION}" \
        --enable-checking=release \
        --disable-fixed-point \
        --disable-libmpx \
        --disable-libmudflap \
        --disable-libsanitizer \
        --disable-libssp \
        --disable-libstdcxx-pch \
        --disable-multilib \
        --disable-nls \
        --disable-symvers \
        --disable-werror \
        --enable-__cxa_atexit \
        --enable-default-pie \
        --enable-languages=c,c++ \
        --enable-shared \
        --enable-threads \
        --enable-tls \
        --with-linker-hash-style=gnu \
        --with-system-zlib
RUN make --silent -j $(nproc) && \
    make --silent -j $(nproc) install-strip && \
    gcc -v

FROM alpine
RUN apk add --quiet --no-cache \
            autoconf \
            automake \
            binutils \
            cmake \
            file \
            git \
            gmp \
            isl \
            libc-dev \
            libtool \
            make \
            mpc1 \
            mpfr3 \
            musl-dev \
            pkgconf \
            zlib-dev

COPY --from=builder /usr/local/ /usr/
RUN ln -s /usr/bin/gcc /usr/bin/cc

WORKDIR /src

ビルドは以下で行います。

docker build --build-arg GCC_VERSION=9.1.0 -t kazu_gcc:9.1.0 .

今、あるイメージは以下となります。

C:\Windows\System32>docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
kazu_gcc             9.1.0               549b309e4863        7 hours ago         251MB
websphere-liberty    19.0.0.5-javaee8    517f9afc2361        5 days ago          502MB
websphere-liberty    19.0.0.5-kernel     30e139ebfe3e        9 days ago          344MB
kazu_gcc             10.0.0              6aa1e6ab2515        2 weeks ago         1.73GB
ubuntu               19.10               3f269de19be1        3 weeks ago         76.1MB
alpine               3.9.4               055936d39205        3 weeks ago         5.53MB
alpine               latest              055936d39205        3 weeks ago         5.53MB
busybox              1.30.1              64f5d945efcc        4 weeks ago         1.2MB
busybox              latest              64f5d945efcc        4 weeks ago         1.2MB
debian               stretch-slim        92d2f0789514        4 weeks ago         55.3MB
n0madic/alpine-gcc   9.1.0               db86eea6352b        4 weeks ago         251MB

せっかくなので、実行環境を作って動かしてみた。

hello.c
#include <stdio.h>

void main(void) {
  printf("Hello, world!\n");
}

実行環境構築用のDockerfileを用意する。

FROM kazu_gcc:9.1.0 as builder

COPY hello.c /src
RUN gcc /src/hello.c -o hello

FROM scratch
ADD busybox-1.30.1.tar.gz /
COPY --from=builder /src/hello /bin/
CMD ["/bin/hello"]

ビルドは以下となります。

C:\kazu>docker build -f DockerfileExec -t kazu_gcc:exec .
Sending build context to Docker daemon  1.428MB
Step 1/7 : FROM kazu_gcc:9.1.0 as builder
 ---> 549b309e4863
Step 2/7 : COPY hello.c /src
 ---> d6e9031c5ce2
Step 3/7 : RUN gcc /src/hello.c -o hello
 ---> Running in 336708e08b1b
Removing intermediate container 336708e08b1b
 ---> 38e88000f53e
Step 4/7 : FROM scratch
 --->
Step 5/7 : ADD busybox-1.30.1.tar.gz /
 ---> b4f683bb4898
Step 6/7 : COPY --from=builder /src/hello /bin/
 ---> 5d35e1204bbf
Step 7/7 : CMD ["/bin/hello"]
 ---> Running in 8ad465f15370
Removing intermediate container 8ad465f15370
 ---> 8e34b180254c
Successfully built 8e34b180254c
Successfully tagged kazu_gcc:exec
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
C:\kazu>

後は出来上がったイメージを動かします。

C:\kazu>docker run -it --rm kazu_gcc:exec
Hello, world!

C:\kazu> 

当然、実行用のイメージサイズは小さいです。

REPOSITORY                                 TAG                  IMAGE ID            CREATED             SIZE
kazu_gcc                                   exec                 8e34b180254c        30 minutes ago      1.44MB
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む