- 投稿日:2019-03-02T22:52:48+09:00
Dockerコマンド チュートリアル
Dockerの基本的な操作方法を記載しておく。GUIツールを利用してみたが、やはりCLIのほうがうまく動作するためCLIでの操作を推奨する。Dockerを扱う上での必須理解項目は「イメージ」、「コンテナ」である。
1.基本的な操作
イメージの検索
DockerHubからイメージをキーワード検索する。
$ docker search centos NAME DESCRIPTION STARS OFFICIAL AUTOMATED centos The official build of CentOS. 3500 [OK] jdeathe/centos-ssh CentOS-6 6.9 x86_64 / CentOS-7 7.3.1611 x8... 77 [OK]イメージの取得
イメージ名:タグ名を指定して取得する。タグ名を明記しない場合は「latest」が付与される。
$ docker pull centos:latest latest: Pulling from library/centos d5e46245fe40: Pull complete Digest:sha256:aebf12af704307dfa0079b3babdca8d7e8ff6564696882bcb5d11f1d461f9ee9 Status: Downloaded newer image for centos:latestPC上に保存されているイメージを表示
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos latest 3bee3060bfc8 12 days ago 193 MB
PC上に保存されているイメージを削除
$ docker rmi 3bee3060bfc8 Untagged: centos:latest Untagged: centos@sha256:aebf12af704307dfa0079b3babdca8d7e8ff6564696882bcb5d11f1d461f9ee9 Deleted: sha256:3bee3060bfc81c061ce7069df35ce090593bda584d4ef464bc0f38086c11371d Deleted: sha256:dc1e2dcdc7b6ff86d785fa16cf97464d263d04346a191c57b5ca8a66b4155861
イメージの起動
方法1はexitするとコンテナが終了してしまう。方法2はexitしてもコンテナが終了しない方法である。ただし、方法1の場合でも「Ctrl+p,Ctrl+q」によりコンテナから脱出かつコンテナは終了しない。
方法1
$ docker run -it centos:latest /bin/bash [root@2fe147e75dc9 /]# uname -a Linux 2fe147e75dc9 4.9.27-moby #1 SMP Thu May 11 04:01:18 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux [root@2fe147e75dc9 /]# cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core)方法2
$ docker run -itd centos:latest 4a82a4ec72bf1b28b2abe84da1b4995c23cf4aa74f32364bb3e81d75db14dd45起動しているコンテナを確認する
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5c304f72c6d6 centos:latest "/bin/bash" 3 minutes ago Up 3 minutes起動しているコンテナを停止させる
$ docker stop 5c304f72c6d6 5c304f72c6d6
起動しているコンテナを再起動させる
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 048697b53b77 centos:latest "/bin/bash" 19 seconds ago Up 16 seconds lucid_franklin $ docker restart 048697b53b77 048697b53b77 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 048697b53b77 centos:latest "/bin/bash" About a minute ago Up 9 seconds lucid_franklinコンテナに接続する
5で紹介したイメージがコンテナの場合バージョン。
方法1はexitするとコンテナが終了してしまうため、「Ctrl+p,Ctrl+q」すること。方法2はexitしても終了しない。方法1
$ docker attach 048697b53b77
方法2
$ docker exec -it 82f647b208ea /bin/bash [root@82f647b208ea /]# exit exit $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 82f647b208ea centos:latest "/bin/bash" 30 seconds ago Up 28 seconds nifty_wright2.少し高度な操作
ポートのマッピング
基本
$ docker run -d -p 8080:80 <image_name> -it /bin/bashIPアドレスも指定
$ docker run -d -p 192.168.0.219:8080:80 <image_name>ボリュームのマッピング
$ docker run -d -v /tmp/:/mnt/ <image_name>コンテナのイメージ化
$ docker commit <Container ID> <image_name>:<tag>
実用的なイメージの起動方法
$ docker run -it -p 8000:8000 -v /tmp/006_log/01_arena/:/var/log/cowrie/ splunk:latestイメージのエクスポート
$ docker save <image_name>:<tag_name> > <filename> $ docker save --output <filename> <image_name>:<tag_name> $ docker save -o <filename> <image_name>:<tag_name>イメージのインポート
$ docker load < <filename> $ docker load --input <file_name>
- 投稿日:2019-03-02T22:28:47+09:00
メモリ512MBで動く軽量Kubernetes!k3sをDocker上で試してみた→失敗
記事を書いたきっかけ
Publickeyの記事を読んで気になったので、動かしてみたくなって、実際に動かしてみた。
「k3sとは何か?」に関しては、記事を読んでもらうのが良いと思う。Kubernetesをわずか40MBのシングルバイナリとして軽量かつシンプルにした新ディストリビューション「k3s」登場。Rancher Labsがオープンソースで公開 - Publickey
とりあえずはk3sが動く環境を整えてみるが目標。
...が、手元のPCの環境を汚したくなくて、Dockerの中でk3sを動かそうとしたところ、執筆時点では失敗...
素直に、クリーンな物理マシンかVMでやれば動かせるかも?
どなたかトライして成功したらコメント下さい...概要
- k3sの公式リポジトリ rancher/k3s (2019/03/02時点)の手順を参考に実践。
- ただし、手元のPCに本家Kubernetesがインストール済みで、環境を汚したくなかったので、Dockerのコンテナの中で動かす方法をお試し。
マシン環境(ホストマシン)
# OS $ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=18.04 DISTRIB_CODENAME=bionic DISTRIB_DESCRIPTION="Ubuntu 18.04.2 LTS" # Docker $ docker version Client: Version: 18.09.3 API version: 1.39 Go version: go1.10.8 Git commit: 774a1f4 Built: Thu Feb 28 06:53:11 2019 OS/Arch: linux/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 18.09.3 API version: 1.39 (minimum version 1.12) Go version: go1.10.8 Git commit: 774a1f4 Built: Thu Feb 28 05:59:55 2019 OS/Arch: linux/amd64 Experimental: false動かしてみる
まずは公式リポジトリのソースをチェックアウトから...と思ったけど、このリポジトリ、けっこう重い...
なので、今回やりたい手順(Running in Docker (and docker-compose)で必要そうな
docker-compose.yml
だけダウンロードした。curl -L "https://raw.githubusercontent.com/rancher/k3s/master/docker-compose.yml" -o docker-compose.yml公式手順の通り、クラスタを立ち上げ。
$ docker-compose up --scale node=3 ...(略)... # 結構なメッセージ量に紛れてエラーっぽいメッセージがチラホラ...んー?クラスタの状態を確認。
$ kubectl --kubeconfig kubeconfig.yaml get node NAME STATUS ROLES AGE VERSION 164b688fd280 Ready <none> 118s v1.13.3-k3s.6 3a7ad8d03bed Ready <none> 119s v1.13.3-k3s.6 5b48d23be7ea Ready <none> 118s v1.13.3-k3s.6動いていそう...?
だけどPodが全然動いて無い...$ kubectl --kubeconfig kubeconfig.yaml get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-7748f7f6df-ps6jb 1/1 Running 0 3m50s kube-system helm-install-traefik-lzkgw 0/1 CrashLoopBackOff 4 3m50s失敗だ...これ...
さらなる失敗談(恥の上塗りとも言う)
k3sの公式リポジトリの教え(Running in Docker (and docker-compose)に従う前に、「シングルバイナリで簡単にインストールできるなら、
ubuntu:18.04
のイメージ使っていけるはず!」と思って、試した時の話。そもそも、コンテナでの起動オプションとか調べずに突っ走ったことが原因な気もするけど、あれ〜?ってなった。
インストール
まずは
ubuntu:18.04
のイメージを起動し、空の環境を用意する。$ docker run -it ubuntu:18.04 root@6e9a76a9bbe3:/#curlコマンドを使って、k3sをダウンロードする。
# curlコマンドが無いので、先にインストール # (iproute2は後で使う) root@6e9a76a9bbe3:/# apt-get update && apt-get install -y curl iproute2 ...(略)... # k3sをGitHubからダウンロード root@6e9a76a9bbe3:/# curl -L "https://github.com/rancher/k3s/releases/download/v0.1.0/k3s" -o /usr/local/bin/k3s ...(略)... # 実行権限を付与 root@6e9a76a9bbe3:/# chmod +x /usr/local/bin/k3s # 確認 root@6e9a76a9bbe3:/# k3s --help NAME: k3s - Kubernetes, but small and simple USAGE: k3s [global options] command [command options] [arguments...] VERSION: dev (HEAD) COMMANDS: server Run management server agent Run node agent kubectl Run kubectl crictl Run crictl help, h Shows a list of commands or help for one command GLOBAL OPTIONS: --debug Turn on debug logs --help, -h show help --version, -v print the version動いていそう。
せっかくなので、Master-Node構成を取るべく、同じ要領でもう1つコンテナを立ち上げ、k3sをインストールしておく。
クラスタ立ち上げ
k3s公式リポジトリのQuick Startの内容をそのままを実行してみる。
コンテナの中では、sudo
が要らないので、そこだけ注意。# 以下は失敗(後述) root@6e9a76a9bbe3:/# k3s server & [1] 2775 root@6e9a76a9bbe3:/# INFO[0000] Preparing data dir /var/lib/rancher/k3s/data/4df430e1473d0225734948e562863c82f20d658ed9c420c77e168aec42eccdb5 INFO[2019-03-02T12:18:36.307868926Z] Starting k3s v0.1.0 (91251aa) ...(略)... [1]+ Exit 255 k3s server
kubeadm init
と似た感じでメッセージ出力された...と思ったけど、止まってるー!?k3sの公式リポジトリに置いてあるdocker-compose.ymlを覗いてみると、
version: '3' services: server: image: rancher/k3s:v0.1.0 command: server --disable-agent # ...(略)...おっと何やら
--disable-agent
というオプションが必要そう。root@6e9a76a9bbe3:/# k3s server --disable-agent & [1] 2821 root@6e9a76a9bbe3:/# INFO[2019-03-02T12:21:49.330150358Z] Starting k3s v0.1.0 (91251aa) ...(略)... INFO[2019-03-02T12:21:49.815062892Z] k3s is up and running今度は動いてそう...?
root@6e9a76a9bbe3:/# k3s kubectl get node No resources found.んー?
まぁ、一旦無視してNodeを追加してみる。Node追加のコマンドのフォーマットは下記の通り。
k3s agent --server https://<Master IP>:6443 --token <Token>
<Master IP>
はiproute2パッケージで入れたip
コマンドで確認。root@6e9a76a9bbe3:/# ip address show eth0 5: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
<Token>
は/var/lib/rancher/k3s/server/node-token
に格納されているそう。root@6e9a76a9bbe3:/# cat /var/lib/rancher/k3s/server/node-token K10bf48c01ba01fe012bcb74ada31b6baabb0a82269af8a2d68c9160a1faf95a68a::node:1902f272fd82f0798cf7a99e0ee64e18
長いけど、全部かな?
Node用に立ち上げたもう一方のコンテナで、Node追加コマンドを実行。# これも失敗(後述) root@b303f31b9a67:/# k3s agent --server https://172.17.0.2:6443 --token K10bf48c01ba01fe012bcb74ada31b6baabb0a82269af8a2d68c9160a1faf95a68a::node:1902f272fd82f0798cf7a99e0ee64e18 INFO[0000] Preparing data dir /var/lib/rancher/k3s/data/4df430e1473d0225734948e562863c82f20d658ed9c420c77e168aec42eccdb5 INFO[2019-03-02T12:41:02.093092358Z] Starting k3s agent v0.1.0 (91251aa) INFO[2019-03-02T12:41:02.590974830Z] Logging containerd to /var/lib/rancher/k3s/agent/containerd/containerd.log INFO[2019-03-02T12:41:02.591223430Z] Running containerd -c /var/lib/rancher/k3s/agent/etc/containerd/config.toml -a /run/k3s/containerd/containerd.sock --state /run/k3s/containerd --root /var/lib/rancher/k3s/agent/containerd INFO[2019-03-02T12:41:02.591501029Z] Waiting for containerd startup: rpc error: code = Unavailable desc = all SubConns are in TransientFailure, latest connection error: connection error: desc = "transport: Error while dialing dial unix /run/k3s/containerd/containerd.sock: connect: no such file or directory" WARN[2019-03-02T12:41:03.595279617Z] failed to write value 1 at /proc/sys/net/bridge/bridge-nf-call-iptables: open /proc/sys/net/bridge/bridge-nf-call-iptables: no such file or directory WARN[2019-03-02T12:41:03.595424541Z] failed to write value 1 at /proc/sys/net/ipv4/ip_forward: open /proc/sys/net/ipv4/ip_forward: read-only file system INFO[2019-03-02T12:41:03.600671376Z] Connecting to wss://172.17.0.2:6443/v1-k3s/connect INFO[2019-03-02T12:41:03.600777136Z] Connecting to proxy url="wss://172.17.0.2:6443/v1-k3s/connect" WARN[2019-03-02T12:41:03.610703830Z] Disabling CPU quotas due to missing cpu.cfs_period_us INFO[2019-03-02T12:41:03.610955979Z] Running kubelet --healthz-bind-address 127.0.0.1 --read-only-port 0 --allow-privileged=true --cluster-domain cluster.local --kubeconfig /var/lib/rancher/k3s/agent/kubeconfig.yaml --eviction-hard imagefs.available<5%,nodefs.available<5% --eviction-minimum-reclaim imagefs.available=10%,nodefs.available=10% --fail-swap-on=false --cgroup-driver cgroupfs --root-dir /var/lib/rancher/k3s/agent/kubelet --cert-dir /var/lib/rancher/k3s/agent/kubelet/pki --seccomp-profile-root /var/lib/rancher/k3s/agent/kubelet/seccomp --cni-conf-dir /var/lib/rancher/k3s/agent/etc/cni/net.d --cni-bin-dir /var/lib/rancher/k3s/data/4df430e1473d0225734948e562863c82f20d658ed9c420c77e168aec42eccdb5/bin --cluster-dns 10.43.0.10 --container-runtime remote --container-runtime-endpoint unix:///run/k3s/containerd/containerd.sock --address 127.0.0.1 --anonymous-auth=false --client-ca-file /var/lib/rancher/k3s/agent/client-ca.pem --hostname-override b303f31b9a67 --cpu-cfs-quota=false Flag --allow-privileged has been deprecated, will be removed in a future version W0302 12:41:03.611511 2828 server.go:194] WARNING: all flags other than --config, --write-config-to, and --cleanup are deprecated. Please begin using a config file ASAP. INFO[2019-03-02T12:41:03.625252893Z] waiting for node b303f31b9a67: nodes "b303f31b9a67" not found W0302 12:41:03.626363 2828 proxier.go:480] Failed to read file /lib/modules/4.15.0-45-generic/modules.builtin with error open /lib/modules/4.15.0-45-generic/modules.builtin: no such file or directory. You can ignore this message when kube-proxy is running inside container without mounting /lib/modules W0302 12:41:03.629437 2828 proxier.go:493] Failed to load kernel module ip_vs with modprobe. You can ignore this message when kube-proxy is running inside container without mounting /lib/modules W0302 12:41:03.633111 2828 proxier.go:493] Failed to load kernel module ip_vs_rr with modprobe. You can ignore this message when kube-proxy is running inside container without mounting /lib/modules W0302 12:41:03.637358 2828 proxier.go:493] Failed to load kernel module ip_vs_wrr with modprobe. You can ignore this message when kube-proxy is running inside container without mounting /lib/modules W0302 12:41:03.637778 2828 proxier.go:493] Failed to load kernel module ip_vs_sh with modprobe. You can ignore this message when kube-proxy is running inside container without mounting /lib/modules W0302 12:41:03.638181 2828 proxier.go:493] Failed to load kernel module nf_conntrack_ipv4 with modprobe. You can ignore this message when kube-proxy is running inside container without mounting /lib/modules W0302 12:41:03.642478 2828 node.go:103] Failed to retrieve node info: nodes "b303f31b9a67" not found I0302 12:41:03.642508 2828 server_others.go:148] Using iptables Proxier. F0302 12:41:03.642619 2828 server.go:377] unable to create proxier: can't set sysctl net/ipv4/conf/all/route_localnet: open /proc/sys/net/ipv4/conf/all/route_localnet: read-only file system同じくk3sの公式リポジトリのdocker-compose.ymlを覗いてみると、
version: '3' services: # ...(略)... node: image: rancher/k3s:v0.1.0 tmpfs: - /run - /var/run privileged: true # ...(略)...
tmpfs
とprivileged
が必要そう。
Node用のコンテナは作り直し...$ docker run -it --mount type=tmpfs,destination=/run --mount type=tmpfs,destination=/var/run --privileged ubuntu:18.04 root@f0b7efd14ae8:/# apt-get update && apt-get install -y curl iproute2 ...(略)... root@f0b7efd14ae8:/# curl -L "https://github.com/rancher/k3s/releases/download/v0.1.0/k3s" -o /usr/local/bin/k3s ...(略)... root@f0b7efd14ae8:/# chmod +x /usr/local/bin/k3s気を取り直して、もう一度Node追加をトライ。
# これも失敗 root@f0b7efd14ae8:/# k3s agent --server https://172.17.0.2:6443 --token K10bf48c01ba01fe012bcb74ada31b6baabb0a82269af8a2d68c9160a1faf95a68a::node:1902f272fd82f0798cf7a99e0ee64e18 ...(略)... ...(以下が繰り返し出力)... E0302 12:55:40.162851 2808 kuberuntime_manager.go:677] createPodSandbox for pod "coredns-7748f7f6df-rk9g5_kube-system(ca04369a-3ce5-11e9-9c1c-0242ac110002)" failed: rpc error: code = Unknown desc = failed to start sandbox container: failed to create containerd task: failed to mount rootfs component &{overlay overlay [workdir=/var/lib/rancher/k3s/agent/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/18/work upperdir=/var/lib/rancher/k3s/agent/containerd/io.containerd.snapshotter.v1.overlここで断念。
- 投稿日:2019-03-02T22:28:47+09:00
メモリ512MBで動く軽量Kubernetes!k3sをDocker上で試してみた
記事を書いたきっかけ
Publickeyの記事を読んで気になったので、動かしてみたくなって、実際に動かしてみた。
「k3sとは何か?」に関しては、記事を読んでもらうのが良いと思う。Kubernetesをわずか40MBのシングルバイナリとして軽量かつシンプルにした新ディストリビューション「k3s」登場。Rancher Labsがオープンソースで公開 - Publickey
とりあえずはk3sが動く環境を整えてみるが目標。
概要
- k3sの公式リポジトリ rancher/k3s (2019/03/02時点)の手順を参考に実践。
- ただし、手元のPCに本家Kubernetesがインストール済みで、環境を汚したくなかったので、Dockerのコンテナの中で動かす方法をお試し。
マシン環境(ホストマシン)
# OS $ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=18.04 DISTRIB_CODENAME=bionic DISTRIB_DESCRIPTION="Ubuntu 18.04.2 LTS" # Docker $ docker version Client: Version: 18.09.3 API version: 1.39 Go version: go1.10.8 Git commit: 774a1f4 Built: Thu Feb 28 06:53:11 2019 OS/Arch: linux/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 18.09.3 API version: 1.39 (minimum version 1.12) Go version: go1.10.8 Git commit: 774a1f4 Built: Thu Feb 28 05:59:55 2019 OS/Arch: linux/amd64 Experimental: false動かしてみる
まずは公式リポジトリのソースをチェックアウトから...と思ったけど、このリポジトリ、けっこう重い...
なので、今回やりたい手順(Running in Docker (and docker-compose)で必要そうな
docker-compose.yml
だけダウンロードした。curl -L "https://raw.githubusercontent.com/rancher/k3s/master/docker-compose.yml" -o docker-compose.yml公式手順の通り、クラスタを立ち上げ。
$ docker-compose up --scale node=3 ...(略)... # 結構なメッセージ量に紛れてエラーっぽいメッセージがチラホラ...んー?クラスタの状態を確認。
$ kubectl --kubeconfig kubeconfig.yaml get node NAME STATUS ROLES AGE VERSION 164b688fd280 Ready <none> 118s v1.13.3-k3s.6 3a7ad8d03bed Ready <none> 119s v1.13.3-k3s.6 5b48d23be7ea Ready <none> 118s v1.13.3-k3s.6動いていそう...?
だけどPodが全然動いて無い...$ kubectl --kubeconfig kubeconfig.yaml get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-7748f7f6df-ps6jb 1/1 Running 0 3m50s kube-system helm-install-traefik-lzkgw 0/1 CrashLoopBackOff 4 3m50s失敗だ...これ...
ログの内容を見ると、コンテナ内からカーネルモジュールが読み込めてない〜というようなエラーだったので、
docker-compose.yml
にオプションを追加。version: '3' services: server: # ...(略)... node: # ...(略)... volumes: - /lib/modules:/lib/modules cap_add: - ALL volumes: k3s-server: {}これでトライしてみる。
$ docker-compose up --scale node=3 ...(略)... # 相変わらずエラーっぽいメッセージがチラホラ...んー?ただクラスタの状態的には動いてそう。
$ kubectl --kubeconfig kubeconfig.yaml get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-7748f7f6df-rvz5z 1/1 Running 0 3m19s kube-system helm-install-traefik-nmr75 1/1 Running 0 3m18s $ kubectl --kubeconfig kubeconfig.yaml get nodes NAME STATUS ROLES AGE VERSION 1a9985426a91 Ready <none> 71s v1.13.3-k3s.6 5a3963d09b0c Ready <none> 70s v1.13.3-k3s.6 6ec3ef89103f Ready <none> 69s v1.13.3-k3s.6とりあえずは動いてそう。
ちなみに...本家Kubernetesだと、
get nodes
の結果でMasterも表示されますが、今回は表示されませんね。そういう仕様なのでしょうか...?# コンテナはMasterを含めて4つ起動 $ docker-compose ps Name Command State Ports ------------------------------------------------------------------------------ k3s_node_1 /bin/k3s agent Up k3s_node_2 /bin/k3s agent Up k3s_node_3 /bin/k3s agent Up k3s_server_1 /bin/k3s server --disable- ... Up 0.0.0.0:6443->6443/tcp念ため動作確認
確認のため、下記のマニフェストを使って、Podを1つ動かしてみる。
apiVersion: v1 kind: Pod metadata: name: sample-pod spec: containers: - name: nginx-container image: nginx ports: - containerPort: 80カレントに
kubeconfig.yaml
が吐かれるので、それを使う。$ kubectl --kubeconfig kubeconfig.yaml apply -f sample-pod.yaml pod/sample-pod created $ kubectl --kubeconfig kubeconfig.yaml get pods NAME READY STATUS RESTARTS AGE sample-pod 1/1 Running 0 100s動いてそう!
...まぁ、ロクに機能を動かしていないので、実際は不具合が起こりそうですが、とりあえずお試できる環境は手に入りました。失敗談
k3sの公式リポジトリの教え(Running in Docker (and docker-compose)に従う前に、「シングルバイナリで簡単にインストールできるなら、
ubuntu:18.04
のイメージ使っていけるはず!」と思って、試した時の話。そもそも、コンテナでの起動オプションとか調べずに突っ走ったことが原因な気もするけど、あれ〜?ってなった。
どなたかトライして成功したらコメント下さい。インストール
まずは
ubuntu:18.04
のイメージを起動し、空の環境を用意する。$ docker run -it ubuntu:18.04 root@6e9a76a9bbe3:/#curlコマンドを使って、k3sをダウンロードする。
# curlコマンドが無いので、先にインストール # (iproute2は後で使う) root@6e9a76a9bbe3:/# apt-get update && apt-get install -y curl iproute2 ...(略)... # k3sをGitHubからダウンロード root@6e9a76a9bbe3:/# curl -L "https://github.com/rancher/k3s/releases/download/v0.1.0/k3s" -o /usr/local/bin/k3s ...(略)... # 実行権限を付与 root@6e9a76a9bbe3:/# chmod +x /usr/local/bin/k3s # 確認 root@6e9a76a9bbe3:/# k3s --help NAME: k3s - Kubernetes, but small and simple USAGE: k3s [global options] command [command options] [arguments...] VERSION: dev (HEAD) COMMANDS: server Run management server agent Run node agent kubectl Run kubectl crictl Run crictl help, h Shows a list of commands or help for one command GLOBAL OPTIONS: --debug Turn on debug logs --help, -h show help --version, -v print the version動いていそう。
せっかくなので、Master-Node構成を取るべく、同じ要領でもう1つコンテナを立ち上げ、k3sをインストールしておく。
クラスタ立ち上げ
k3s公式リポジトリのQuick Startの内容をそのままを実行してみる。
コンテナの中では、sudo
が要らないので、そこだけ注意。# 以下は失敗(後述) root@6e9a76a9bbe3:/# k3s server & [1] 2775 root@6e9a76a9bbe3:/# INFO[0000] Preparing data dir /var/lib/rancher/k3s/data/4df430e1473d0225734948e562863c82f20d658ed9c420c77e168aec42eccdb5 INFO[2019-03-02T12:18:36.307868926Z] Starting k3s v0.1.0 (91251aa) ...(略)... [1]+ Exit 255 k3s server
kubeadm init
と似た感じでメッセージ出力された...と思ったけど、止まってるー!?k3sの公式リポジトリに置いてあるdocker-compose.ymlを覗いてみると、
version: '3' services: server: image: rancher/k3s:v0.1.0 command: server --disable-agent # ...(略)...おっと何やら
--disable-agent
というオプションが必要そう。root@6e9a76a9bbe3:/# k3s server --disable-agent & [1] 2821 root@6e9a76a9bbe3:/# INFO[2019-03-02T12:21:49.330150358Z] Starting k3s v0.1.0 (91251aa) ...(略)... INFO[2019-03-02T12:21:49.815062892Z] k3s is up and running今度は動いてそう...?
root@6e9a76a9bbe3:/# k3s kubectl get node No resources found.んー?
まぁ、一旦無視してNodeを追加してみる。Node追加のコマンドのフォーマットは下記の通り。
k3s agent --server https://<Master IP>:6443 --token <Token>
<Master IP>
はiproute2パッケージで入れたip
コマンドで確認。root@6e9a76a9bbe3:/# ip address show eth0 5: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
<Token>
は/var/lib/rancher/k3s/server/node-token
に格納されているそう。root@6e9a76a9bbe3:/# cat /var/lib/rancher/k3s/server/node-token K10bf48c01ba01fe012bcb74ada31b6baabb0a82269af8a2d68c9160a1faf95a68a::node:1902f272fd82f0798cf7a99e0ee64e18
長いけど、全部かな?
Node用に立ち上げたもう一方のコンテナで、Node追加コマンドを実行。# これも失敗(後述) root@b303f31b9a67:/# k3s agent --server https://172.17.0.2:6443 --token K10bf48c01ba01fe012bcb74ada31b6baabb0a82269af8a2d68c9160a1faf95a68a::node:1902f272fd82f0798cf7a99e0ee64e18 INFO[0000] Preparing data dir /var/lib/rancher/k3s/data/4df430e1473d0225734948e562863c82f20d658ed9c420c77e168aec42eccdb5 INFO[2019-03-02T12:41:02.093092358Z] Starting k3s agent v0.1.0 (91251aa) INFO[2019-03-02T12:41:02.590974830Z] Logging containerd to /var/lib/rancher/k3s/agent/containerd/containerd.log INFO[2019-03-02T12:41:02.591223430Z] Running containerd -c /var/lib/rancher/k3s/agent/etc/containerd/config.toml -a /run/k3s/containerd/containerd.sock --state /run/k3s/containerd --root /var/lib/rancher/k3s/agent/containerd INFO[2019-03-02T12:41:02.591501029Z] Waiting for containerd startup: rpc error: code = Unavailable desc = all SubConns are in TransientFailure, latest connection error: connection error: desc = "transport: Error while dialing dial unix /run/k3s/containerd/containerd.sock: connect: no such file or directory" WARN[2019-03-02T12:41:03.595279617Z] failed to write value 1 at /proc/sys/net/bridge/bridge-nf-call-iptables: open /proc/sys/net/bridge/bridge-nf-call-iptables: no such file or directory WARN[2019-03-02T12:41:03.595424541Z] failed to write value 1 at /proc/sys/net/ipv4/ip_forward: open /proc/sys/net/ipv4/ip_forward: read-only file system INFO[2019-03-02T12:41:03.600671376Z] Connecting to wss://172.17.0.2:6443/v1-k3s/connect INFO[2019-03-02T12:41:03.600777136Z] Connecting to proxy url="wss://172.17.0.2:6443/v1-k3s/connect" WARN[2019-03-02T12:41:03.610703830Z] Disabling CPU quotas due to missing cpu.cfs_period_us INFO[2019-03-02T12:41:03.610955979Z] Running kubelet --healthz-bind-address 127.0.0.1 --read-only-port 0 --allow-privileged=true --cluster-domain cluster.local --kubeconfig /var/lib/rancher/k3s/agent/kubeconfig.yaml --eviction-hard imagefs.available<5%,nodefs.available<5% --eviction-minimum-reclaim imagefs.available=10%,nodefs.available=10% --fail-swap-on=false --cgroup-driver cgroupfs --root-dir /var/lib/rancher/k3s/agent/kubelet --cert-dir /var/lib/rancher/k3s/agent/kubelet/pki --seccomp-profile-root /var/lib/rancher/k3s/agent/kubelet/seccomp --cni-conf-dir /var/lib/rancher/k3s/agent/etc/cni/net.d --cni-bin-dir /var/lib/rancher/k3s/data/4df430e1473d0225734948e562863c82f20d658ed9c420c77e168aec42eccdb5/bin --cluster-dns 10.43.0.10 --container-runtime remote --container-runtime-endpoint unix:///run/k3s/containerd/containerd.sock --address 127.0.0.1 --anonymous-auth=false --client-ca-file /var/lib/rancher/k3s/agent/client-ca.pem --hostname-override b303f31b9a67 --cpu-cfs-quota=false Flag --allow-privileged has been deprecated, will be removed in a future version W0302 12:41:03.611511 2828 server.go:194] WARNING: all flags other than --config, --write-config-to, and --cleanup are deprecated. Please begin using a config file ASAP. INFO[2019-03-02T12:41:03.625252893Z] waiting for node b303f31b9a67: nodes "b303f31b9a67" not found W0302 12:41:03.626363 2828 proxier.go:480] Failed to read file /lib/modules/4.15.0-45-generic/modules.builtin with error open /lib/modules/4.15.0-45-generic/modules.builtin: no such file or directory. You can ignore this message when kube-proxy is running inside container without mounting /lib/modules W0302 12:41:03.629437 2828 proxier.go:493] Failed to load kernel module ip_vs with modprobe. You can ignore this message when kube-proxy is running inside container without mounting /lib/modules W0302 12:41:03.633111 2828 proxier.go:493] Failed to load kernel module ip_vs_rr with modprobe. You can ignore this message when kube-proxy is running inside container without mounting /lib/modules W0302 12:41:03.637358 2828 proxier.go:493] Failed to load kernel module ip_vs_wrr with modprobe. You can ignore this message when kube-proxy is running inside container without mounting /lib/modules W0302 12:41:03.637778 2828 proxier.go:493] Failed to load kernel module ip_vs_sh with modprobe. You can ignore this message when kube-proxy is running inside container without mounting /lib/modules W0302 12:41:03.638181 2828 proxier.go:493] Failed to load kernel module nf_conntrack_ipv4 with modprobe. You can ignore this message when kube-proxy is running inside container without mounting /lib/modules W0302 12:41:03.642478 2828 node.go:103] Failed to retrieve node info: nodes "b303f31b9a67" not found I0302 12:41:03.642508 2828 server_others.go:148] Using iptables Proxier. F0302 12:41:03.642619 2828 server.go:377] unable to create proxier: can't set sysctl net/ipv4/conf/all/route_localnet: open /proc/sys/net/ipv4/conf/all/route_localnet: read-only file system同じくk3sの公式リポジトリのdocker-compose.ymlを覗いてみると、
version: '3' services: # ...(略)... node: image: rancher/k3s:v0.1.0 tmpfs: - /run - /var/run privileged: true # ...(略)...
tmpfs
とprivileged
が必要そう。
Node用のコンテナは作り直し...$ docker run -it --mount type=tmpfs,destination=/run --mount type=tmpfs,destination=/var/run --privileged ubuntu:18.04 root@f0b7efd14ae8:/# apt-get update && apt-get install -y curl iproute2 ...(略)... root@f0b7efd14ae8:/# curl -L "https://github.com/rancher/k3s/releases/download/v0.1.0/k3s" -o /usr/local/bin/k3s ...(略)... root@f0b7efd14ae8:/# chmod +x /usr/local/bin/k3s気を取り直して、もう一度Node追加をトライ。
# これも失敗 root@f0b7efd14ae8:/# k3s agent --server https://172.17.0.2:6443 --token K10bf48c01ba01fe012bcb74ada31b6baabb0a82269af8a2d68c9160a1faf95a68a::node:1902f272fd82f0798cf7a99e0ee64e18 ...(略)... ...(以下が繰り返し出力)... E0302 12:55:40.162851 2808 kuberuntime_manager.go:677] createPodSandbox for pod "coredns-7748f7f6df-rk9g5_kube-system(ca04369a-3ce5-11e9-9c1c-0242ac110002)" failed: rpc error: code = Unknown desc = failed to start sandbox container: failed to create containerd task: failed to mount rootfs component &{overlay overlay [workdir=/var/lib/rancher/k3s/agent/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/18/work upperdir=/var/lib/rancher/k3s/agent/containerd/io.containerd.snapshotter.v1.overlここで断念。
- 投稿日:2019-03-02T17:19:09+09:00
docker-compose で PHP7.2 + Apache + MySQL + phpMyAdmin 環境を構築
Docker の学習メモです。
本記事でのコンテナ作成は全て Docker Hub の image を使用して行なっています。
Dockerfile からのイメージ作成はまた今度。ディレクトリ構造
. ├── docker-compose.yml └── html │ └── index.php └── php.inidocker-compose.yml
docker-compose.ymlversion: '3' services: php: image: php:7.2-apache volumes: - ./php.ini:/usr/local/etc/php/php.ini - ./html:/var/www/html ports: - 8080:80 mysql: image: mysql:5.7 volumes: - ./mysql:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_DATABASE=test - MYSQL_USER=test - MYSQL_PASSWORD=test phpmyadmin: image: phpmyadmin/phpmyadmin environment: - PMA_ARBITRARY=1 - PMA_HOST=mysql - PMA_USER=test - PMA_PASSWORD=test links: - mysql ports: - 4040:80 volumes: - ./phpmyadmin/sessions:/sessionsindex.php
html/index.php<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>php7.2-apache</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <?php phpinfo(); ?> </body> </html>php.ini
php.ini[Date] date.timezone = "Asia/Tokyo" [mbstring] mbstring.internal_encoding = "UTF-8" mbstring.language = "Japanese"現在のコンテナ稼働状況を確認
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
稼働中のコンテナが存在していないため、何も表示されない。
コンテナの作成と開始
$ docker-compose up -d Creating network "php72-apache_default" with the default driver Creating php72-apache_mysql_1 ... done Creating php72-apache_php_1 ... done Creating php72-apache_phpmyadmin_1 ... doneコンテナの稼働状況を確認する。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 120e4b86b987 phpmyadmin/phpmyadmin "/run.sh supervisord…" About a minute ago Up About a minute 9000/tcp, 0.0.0.0:4040->80/tcp php72-apache_phpmyadmin_1 bf42cd71d3d4 php:7.2-apache "docker-php-entrypoi…" About a minute ago Up About a minute 0.0.0.0:8080->80/tcp php72-apache_php_1 699f32a6424e mysql:5.7 "docker-entrypoint.s…" About a minute ago Up About a minute 3306/tcp, 33060/tcp php72-apache_mysql_1PHP の確認
ローカルの html/index.php の内容を変更すると反映される。
MySQL + phpMyAdmin の確認
サービスの停止
docker-compose.yml に記載されているサービスのコンテナが全て停止される。
$ docker-compose stop Stopping php72-apache_phpmyadmin_1 ... done Stopping php72-apache_php_1 ... done Stopping php72-apache_mysql_1 ... doneコンテナの稼働状況を確認する。
停止しているコンテナを表示する為に-a
オプションを使用します。$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 120e4b86b987 phpmyadmin/phpmyadmin "/run.sh supervisord…" 3 minutes ago Exited (0) 11 seconds ago php72-apache_phpmyadmin_1 bf42cd71d3d4 php:7.2-apache "docker-php-entrypoi…" 3 minutes ago Exited (0) 11 seconds ago php72-apache_php_1 699f32a6424e mysql:5.7 "docker-entrypoint.s…" 3 minutes ago Exited (0) 11 seconds ago php72-apache_mysql_1サービスの開始
docker-compose.yml に記載されているサービスのコンテナが稼働する。
あらかじめ、コンテナが作成されている必要がある。$ docker-compose start Starting php ... done Starting mysql ... done Starting phpmyadmin ... done$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 120e4b86b987 phpmyadmin/phpmyadmin "/run.sh supervisord…" 8 minutes ago Up 10 seconds 9000/tcp, 0.0.0.0:4040->80/tcp php72-apache_phpmyadmin_1 bf42cd71d3d4 php:7.2-apache "docker-php-entrypoi…" 8 minutes ago Up 11 seconds 0.0.0.0:8080->80/tcp php72-apache_php_1 699f32a6424e mysql:5.7 "docker-entrypoint.s…" 8 minutes ago Up 12 seconds 3306/tcp, 33060/tcp php72-apache_mysql_1コンテナの削除
docker-compose.yml に記載されているサービスのコンテナを停止、コンテナとネットワークが削除される。
$ docker-compose down Stopping php72-apache_phpmyadmin_1 ... done Stopping php72-apache_php_1 ... done Stopping php72-apache_mysql_1 ... done Removing php72-apache_phpmyadmin_1 ... done Removing php72-apache_php_1 ... done Removing php72-apache_mysql_1 ... done Removing network php72-apache_default$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 投稿日:2019-03-02T15:37:10+09:00
Docker SDK for Goでコンテナのログをtailしてみる
こんにちわ
最近DockerのTUI Clientを作っていて、SDKでハマっていたところがあるので、
自分の備忘録として記事に残します。2019/03/02 追記
HTTP/2の多重化ストリームと書きましたが、
Dockerは独自のフレームを定義してるのでHTTP/2ではなかったです。すいません。Docker SDKとは
普段Dockerを使っている方なら知っていると思いますが、
Dockerコマンドは実はDocker Engine APIを叩いているだけです。
そのAPIを叩く部分をラッピングして使いやすくしたのでSDKです。公式SDKはGoとPythonしかない様ですが、REST APIなのである程度自作はできると思います。
https://docs.docker.com/develop/sdk/本日は、GoのDocker SDKを使ったコンテナログをtailする時に躓くポイントについて話していきます。
コマンドでコンテナログをtailする
普通にコマンドを実行するとこんな感じになります。
$ docker container logs -f mysql Initializing database 2019-02-07T03:53:08.512874Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details). 2019-02-07T03:53:09.514164Z 0 [Warning] InnoDB: New log files created, LSN=45790 2019-02-07T03:53:09.647195Z 0 [Warning] InnoDB: Creating foreign key constraint system tables. 2019-02-07T03:53:09.716490Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: e24f13bf-2a8b-11e9-897a-0242ac180003. 2019-02-07T03:53:09.718579Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened. 2019-02-07T03:53:09.719975Z 1 [Warning] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option. 2019-02-07T03:53:12.975444Z 1 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode. 2019-02-07T03:53:12.975490Z 1 [Warning] 'user' entry 'mysql.session@localhost' ignored in --skip-name-resolve mode. 2019-02-07T03:53:12.975499Z 1 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode. 2019-02-07T03:53:12.976376Z 1 [Warning] 'db' entry 'performance_schema mysql.session@localhost' ignored in --skip-name-resolve mode. 2019-02-07T03:53:12.976406Z 1 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode. 2019-02-07T03:53:12.976691Z 1 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode. 2019-02-07T03:53:12.977023Z 1 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode. 2019-02-07T03:53:12.977056Z 1 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode. Database initialized Initializing certificates Generating a RSA private key ...これをSDKを使って同じ事をします。
SDKを使った場合
SDKでは
ContainersLogs
って関数が用意されていて、
それにcontext、コンテナID、オプションを渡すと、レスポンスが返ってきます。
そのレスポンスはdocker側が用意しているdocker/docker/pkg/stdcopy.StdCopy
を使用して、標準・エラーに出力します。package main import ( "context" "log" "os" "github.com/docker/docker/api/types" "github.com/docker/docker/client" "github.com/docker/docker/pkg/stdcopy" ) func run() int { c, err := client.NewClientWithOpts(client.WithVersion("1.39")) if err != nil { return 1 } r, err := c.ContainerLogs(context.Background(), "657814ba450f", types.ContainerLogsOptions{ ShowStdout: true, ShowStderr: true, Follow: true, }) if err != nil { log.Println(err) return 1 } _, err = stdcopy.StdCopy(os.Stdout, os.Stderr, r) if err != nil { log.Println(err) return 1 } return 0 } func main() { os.Exit(run()) }ソースはこれだけですが、ちょっとストリーム多重化も関連してくるため、
その知識がないとつまずく方もいるかと思いますので、つまずきポイントについて解説していきます。躓きポイント
ContainerLogs
を使用すると多重化ストリームのレスポンスが返ってきます。
コンテナへのアタッチもこの原理で動いています。
多重化ストリームとは一つのコネクション上で、
複数のHTTPリクエスト&レスポンスのやり取りを行うことができる仕組みとしてHTTP/2で導入されたものです。
詳しくはこちらの資料にわかりやすくまとめてあるので、興味ある方は読んでみてください。すいません、間違えました。
Dockerでは自前で多重化ストリームを定義していました。
したがってHTTP/2は関係ないです。
ただ、多重化ストリームの考え方同じなはずなので、図のイメージで問題ないと思います。Docker側で定められたフレーム定義に従って、
レスポンスを適切に処理して標準・エラー出力しないと、
正しい文字列を得られなくて、先頭に変な文字がついてたりします。Y2019-03-01T07:14:51.672442Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active. Z2019-03-01T07:14:51.673425Z 0 [Note] InnoDB: 5.7.24 started; log sequence number 12440262 E2019-03-01T07:14:51.673943Z 0 [Note] Plugin 'FEDERATED' is disabled. g2019-03-01T07:14:51.674929Z 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool 2019-03-01T07:14:51.717753Z 0 [Note] Found ca.pem, server-cert.pem and server-key.pem in data directory. Trying to enable SSL support using them. N2019-03-01T07:14:51.728152Z 0 [Warning] CA certificate ca.pem is self signed. U2019-03-01T07:14:51.730623Z 0 [Note] Server hostname (bind-address): '*'; port: 3306 82019-03-01T07:14:51.730701Z 0 [Note] IPv6 is available. @2019-03-01T07:14:51.730720Z 0 [Note] - '::' resolves to '::'; H2019-03-01T07:14:51.730740Z 0 [Note] Server socket created on IP: '::'.Docker側が定めたフレーム定義はこちらになります。
header := [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}STREAM_TYPEは
- 0:stdin
- 1:stdout
- 2:stderr
となっています。
1なら、os.Stdout
に出力すると言った制御が必要です。続いて、
SIZE1, SIZE2, SIZE3, SIZE4
はビッグエンディアン1としてコンコードされた4バイトデータです。
こちらは、ストリームのフレーム(データの部分)の長さになります。公式SDKでは以下のロジックで正しくデータを取得できると書いてあります。
- Read 8 bytes.
- Choose stdout or stderr depending on the first byte.
- Extract the frame size from the last four bytes.
- Read the extracted size and output it on the correct output.
- Goto 1.
上記のロジックに従って、自前で制御するとこんな感じになります。
hdr := make([]byte, 8) for { _, err := r.Read(hdr) if err != nil { log.Fatal(err) } var w io.Writer switch hdr[0] { case 1: w = os.Stdout case 2: w = os.Stderr default: // error handling } count := binary.BigEndian.Uint32(hdr[4:]) dat := make([]byte, count) _, err = r.Read(dat) fmt.Fprint(w, string(dat)) }ただ、自前で実装しなくてもDockerが用意している
github.com/docker/docker/pkg/stdcopy.StdCopy(dstout, dsterr io.Writer, src io.Reader)
を使えば簡単に標準・エラー出力できます。まとめ
今回のようなストリーム型レスポンスを扱う上で、
HTTPの多重化ストリームの仕組みとエンディアンについて知識が必要になってきます。
これらの知識がなかったので、ちんぷんかんぷんでした。やっとのこと理解できたので、忘れないうちに記事にしました。
今後DockerのSDKを使って何かつくおうと思っている方にとって、何か役に立てればと思います。
エンディアンはCPUによってデータをメモリ上に格納する方法が異なるります。推測になってしまうが、おそらくDocker側はビッグエンディアンに統一させているようです。 ↩
- 投稿日:2019-03-02T15:26:31+09:00
LinuxマシンのサービスをDockerに移行するスクリプトを書いた
実行中のLinuxマシンからDockerのベースイメージを生成するスクリプトを書いてみました。
https://github.com/hidakanoko/vm2container
このスクリプトは指定されたパッケージの依存性を解決して、パッケージに含まれるコマンドを実行する(プロセスを起動する)のに必要なファイルを集めてDockerのベースイメージを作ります。
RPMを使ったシステムなら動くはずですが、今のところCentOS7でしかテストしていません...
実用性は低いような気がしますが、古いマシンをDockerに乗せ換えてとりあえず延命したいようなケースでは役に立つかも?
使い方
スクリプトのダウンロード
# git clone https://github.com/hidakanoko/vm2container.git Cloning into 'vm2container'... remote: Enumerating objects: 131, done. remote: Counting objects: 100% (131/131), done. remote: Compressing objects: 100% (79/79), done. remote: Total 131 (delta 68), reused 99 (delta 44), pack-reused 0 Receiving objects: 100% (131/131), 34.22 KiB | 0 bytes/s, done. Resolving deltas: 100% (68/68), done.Helpの表示
# cd vm2container/ # bin/v2c -h usage: vm2container [-h] [-p PACKAGE] [-s] [-l] [-a] [-d DIRECTORY] [-v VERBOSE] Create docker image from running full Linux environment. optional arguments: -h, --help show this help message and exit -p PACKAGE, --package PACKAGE -s, --showDeps -l, --listFiles -a, --createArchive -d DIRECTORY, --directory DIRECTORY -v VERBOSE, --verbose VERBOSE ERROR, WARN, INFO, DEBUGパッケージの依存関係をツリー表示する
-p <PACKAGE>
で起動したいコマンドを含むパッケージを指定します。下記サンプルでは/usr/sbin/httpd
を起動するためhttpd
パッケージを指定しています。
-s
で指定されたパッケージの依存関係を表示します。# bin/v2c -p httpd -s * Resolving dependency for httpd... done! INFO: Total 115 package(s) found httpd shadow-utils audit-libs libcap-ng glibc glibc-common libselinux pcre glibc [*] libstdc++ libgcc glibc [*] libgcc [*] glibc [*] libsepol glibc [*] bash ncurses-libs libstdc++ [*] libgcc [*] ncurses-base glibc [*] glibc [*] bash [*] tzdata glibc [*] nss-softokn-freebl (...omit) INFO: [*]=Child dependencies are omitted as already described above.依存性ツリーの中で同じパッケージが繰り返し現れるため、表示済のパッケージの依存関係は省略されます。(末尾に"[*]"がついているパッケージ)
プロセスの起動に必要なファイルを一覧表示する
-l
で指定されたパッケージと、その依存パッケージに含まれるすべてのファイルを一覧表示します。(rpm -ql
で得られるもの)# bin/v2c -p httpd -l * Resolving dependency for bash... done! INFO: Total 41 package(s) found * Creating file list of 1 package(s) and its dependent packages... done! / /bin /bin/egrep /bin/fgrep /bin/grep /bin/sed /etc /etc/DIR_COLORS /etc/DIR_COLORS.256color /etc/DIR_COLORS.lightbgcolor /etc/GREP_COLORS /etc/X11 (...omit) /usr/share/man/ay/man7 (not found) /usr/share/man/ay/man7x (not found) /usr/share/man/ay/man8 (not found) (...omit) /var/run /var/run/setrans /var/spool /var/spool/lpd /var/spool/mail /var/tmp /var/yp INFO: Total 18684 file(s) found, however 13176 file(s) are not present in the file systemパッケージのファイルリストに含まれているものの、ファイルシステム内に存在しないファイルは末尾に"(not found)"がついています。
ユーザーが削除したファイルや、ghostファイルはすでにファイルシステムに存在しないためこのように表示しています。Dockerのイメージを作成する
-a
でDockerイメージを作成します。Webコンテンツとhttpdのユーザー設定ファイルを含めるため
-d <DIRECTORY>
オプションで/var/www/htmlと/etc/httpd/conf.dをアーカイブに含めるよう指定しています。# ./bin/v2c -p httpd -d /var/www/html -d /etc/httpd/conf.d -a * Resolving dependency for httpd... done! INFO: Total 115 package(s) found * Creating file list of 1 package(s) and its dependent packages... done! INFO: Total 23237 file(s) found, however 13193 file(s) are not present in the file system * Creating archive... done! INFO: Archive created in /tmp/archive.tgzDockerイメージとしてインポートする
生成したアーカイブはそのままDockerにインポートして、ベースイメージとして利用できます。
コンテナ起動時にパラメータを省略できるよう、エントリーポイントとコマンドパラメーターを含めています。
# docker image import /tmp/archive.tgz v2c-httpd:20190302 -c "ENTRYPOINT [\"/usr/sbin/httpd\"]" -c "CMD [\"-DFOREGROUND\"]" sha256:7908fb6eb6f50618c688a51556b0348de5948fe0a855aa32b515a74182ca1bbeコンテナを起動する
# docker run -d --rm -p 8080:80 v2c-httpd:20190302 32409c65c9c5ed96103333461eda513fe1d7c9b842dfc4ad17e22258e155e9e6ブラウザで http://DOCKERHOST:8080/ にアクセスするとApacheのTest Pageが表示されます。
/var/www/htmlに何かコンテンツを置いているのであればそれにアクセスすることもできます。ざっくりとした仕組み
Dockerはnamespaceやcgroupなどの技術を使って作成したサンドボックス内でプロセスを起動する技術です。そのためイメージの中に必要なファイルがそろっていればプロセスを起動できるはずです。
Dockerのドキュメントにベースイメージの作り方がありますが、これはdebootstrapでパッケージを展開してアーカイブで固めているだけです。
https://docs.docker.com/develop/develop-images/baseimages/
つまり逆に考えれば、実行中の環境でパッケージの依存性を解決して必要なファイルをすべて集めればDockerイメージを作ることが出来るはずです。(という思いつきからこのスクリプトを組んでみました)
v2c
コマンドはパッケージの依存ツリーを解決して(rpm -q --requires
,rpm -q --whatprovides
など)、依存パッケージのファイルをすべて集めて(rpm -ql
)、tgzに固めています。前述のとおりDockerのベースイメージは基本的に必要なライブラリやコマンド、設定ファイルをtarで固めただけなので、このイメージはそのままベースイメージとしてインポート可能です。
TODO
- パッケージに含まれるドキュメントファイルを除外できるようにする
- DEBパッケージ対応
- ベースイメージ + レイヤーイメージを作れるようにする。例えばベースイメージにはコアパッケージを含めておいて、レイヤーイメージにWebサーバーやMariaDBを起動するためのファイルを含めるような感じ。
- 投稿日:2019-03-02T10:47:46+09:00
10分でLinuxのGitLab環境(Docker)を構築してAndroiStudioのソースをPushする
〇この記事について
Linux(Ubuntu)環境で、Docker-Composeに設定を登録し、Docker(仮想環境ツール)を起動して、簡単にローカルのGitLab環境を構築し、Androidのソースを保存するまでの設定方法を記載します。
別にAndroidだけじゃなくて他のソースだろうと管理できますが、一応AndroidStudioで実際にPushする設定まで含めます。今回はDockerにGitLab公式のイメージがあり、それを利用します。
Dockerって使わなくても直接OSにGitLabインストールすればいいんじゃない?という人もいるかもしれませんが、両方試してみて、Dockerのほうが明らかに管理が楽でした。
コマンドで簡単にGitLabに適した環境が丸ごとダウンロードできてしまう!ソフトウェアのアップデートが簡単にできてしまう!バックアップも簡単!時代の流れは完全にDocker!と思わせるほどです。Docker-Composeに関しても、Dockerのコマンドをメモっておいてそれを叩けば利用しなくてもよいのですが、Dockerを管理していくならあると便利です。(というかほぼ必須です)
コマンドと公式URLを書いた10分コースと詳細も追加した3時間コースを用意したので好きなほうを読んでください。
〇環境
・OS
Ubuntu 18.04.2 LTS
・Docker
18.09.2
・Docker-Compose
1.23.2
・gitlab-ce
11.7.5
・git
2.17.1
・AndroidStudio
3.3〇10分で構築する方法
Dockerの設定
・[公式]Get Docker CE for Ubuntu
https://docs.docker.com/install/linux/docker-ce/ubuntu/・前提ソフトウェアのインストール
sudo -E apt-get install -y apt-transport-https ca-certificates curl software-properties-common・GPG公開鍵をインストール
sudo -E curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -・aptリポジトリの設定
[x86_64](他のCPUなら公式参照)
sudo -E add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"・Dockerのインストール
sudo -E apt-get install -y docker-ce・Docker内プロキシの設定
sudo mkdir /etc/systemd/system/docker.service.d
sudo vi /etc/systemd/system/docker.service.d/http-proxy.confhttp-proxy.conf[Service] Environment="HTTP_PROXY=http://yyyyy:3128/"sudo systemctl daemon-reload
sudo systemctl restart dockerDocker-Composeの設定
・[公式]Install Docker Compose
https://docs.docker.com/compose/install/・[公式]Install GitLab using docker-compose
https://docs.gitlab.com/omnibus/docker/#install-gitlab-using-docker-compose・ダウンロード
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose・権限変更
sudo chmod +x /usr/local/bin/docker-compose・dockerと連携するGitLabファイルの保存場所作成
mkdir /docker
mkdir /docker/gitlab/
mkdir /docker/gitlab/config
mkdir /docker/gitlab/logs
mkdir /docker/gitlab/data・docker-compose.ymlの作成
docker-compose.ymlgitlab: image: 'gitlab/gitlab-ce:latest' restart: always hostname: 'xxxxx.co.jp' environment: GITLAB_OMNIBUS_CONFIG: | external_url 'http://xxxxx.co.jp:10080/gitlab/' gitlab_rails['time_zone'] = 'Asia/Tokyo' ports: - '10080:10080' - '10443:443' - '10022:22' volumes: - '/docker/gitlab/config:/etc/gitlab' - '/docker/gitlab/logs:/var/log/gitlab' - '/docker/gitlab/data:/var/opt/gitlab'・イメージのダウンロード、docker起動
docker-compose up -d gitlabGitLabの設定
・初回ログイン
http://xxxxx.co.jp:10080/gitlab/
にアクセス
Username: root
Password: 5iveL!fe・Registerからアカウント作成
・プロジェクトの作成
(AndroidStudioならInitialize repository with a READMEはしないように)・CloneボタンのURLをコピー
[http://xxxxx.co.jp:11080/gitlab/user/test.git]AndroidStudioの設定
・プロジェクト作成
・バージョンコントロールをGitに設定
VCS → Enable Version Control Integration [Git]・プロジェクトをadd,commit
ソースツリーを[Android] → [Project]に変更
ルートディレクトリを右クリックして、[Git] → [Add]
同じく[Git] → [Commit Directory]・プロジェクトをpush
VCS → Git → Push
[Define remote]をクリックするとURLを入力できるので
Cronでコピーした[http://xxxxx.co.jp:11080/gitlab/user/test.git]
を入力。
その際にユーザー登録したIDとパスワードを聞かれるので入力。GitLabで表示確認
http://xxxxx.co.jp:10080/gitlab/
にアクセスしてプロジェクトにソースが反映されているのを確認。〇3時間で構築する方法
Dockerについて
Linuxで動作する仮想環境ですが、
バーチャルボックスなどと違いOSはインストールせずに既存のOSの上に乗っかる形になるので、
隔離された環境が、容易に作成、コピー、バックアップができ、
公式が作った環境を簡単にダウンロード、アップデートできるのが魅力です。
公式のイラスト通り、船(OS)の上にコンテナ(仮想環境)を積んでいくという印象ですね。
Dockerのインストール
・[公式]Get Docker CE for Ubuntu
https://docs.docker.com/install/linux/docker-ce/ubuntu/・前提ソフトウェアのインストール
sudo -E apt-get install -y apt-transport-https ca-certificates curl software-properties-common・GPG公開鍵をインストール
GNU Privacy Guard 暗号化ソフトで生成される公開鍵
パッケージが正しい配布先のものかどうかのチェックなどに利用
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -・aptリポジトリの設定
[x86_64](他のCPUなら公式参照)
sudo -E add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"・Dockerのインストール
sudo -E apt-get install -y docker-ce
ちなみに CE(コミュニティエディション)とEE(エンタープライズエディション)がありCEは無償版です。sudo mkdir /etc/systemd/system/docker.service.d
sudo vi /etc/systemd/system/docker.service.d/http-proxy.confhttp-proxy.conf[Service] Environment="HTTP_PROXY=http://yyyyy:3128/"sudo systemctl daemon-reload
sudo systemctl restart dockerDocker-Composeについて
Docker-Composeはファイルに設定した内容で、Dockerのイメージをダウンロード、コンテナを起動でき、管理が容易になるというものです。
複数のDockerが結びつく場合により便利になります。Docker-Composeの設定
・[公式]Install GitLab using docker-compose
https://docs.gitlab.com/omnibus/docker/#install-gitlab-using-docker-compose・ダウンロード
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose・権限変更
sudo chmod +x /usr/local/bin/docker-compose・Dockerと連携するGitLabファイルの保存場所作成
Dockerは簡単に削除、アップデートすることがあるので、重要ファイルはDocker外に保存します。
mkdir /docker
mkdir /docker/gitlab/
mkdir /docker/gitlab/config
mkdir /docker/gitlab/logs
mkdir /docker/gitlab/data・docker-compose.ymlの作成
docker-compose.ymlgitlab: image: 'gitlab/gitlab-ce:latest' restart: always hostname: 'xxxxx.co.jp' environment: GITLAB_OMNIBUS_CONFIG: | external_url 'http://xxxxx.co.jp:10080/gitlab/' gitlab_rails['time_zone'] = 'Asia/Tokyo' ports: - '10080:10080' - '10443:443' - '10022:22' volumes: - '/docker/gitlab/config:/etc/gitlab' - '/docker/gitlab/logs:/var/log/gitlab' - '/docker/gitlab/data:/var/opt/gitlab'保存ディレクトリやymlの作成場所は管理しやすければ、どこでもよいです。
テスト環境が必要でしたらportsやvolumesをずらせば、簡単に複製できます。・docker-compose.ymlの説明
image:
Dockerのイメージ(元データ)です。
一から自分で作成して、gitlabを入れてもよいのですが、
公式がgitlabを動かすのに最適なイメージを用意してくれています。
https://hub.docker.com/r/gitlab/gitlab-ce/
他にもイメージを利用したければこちらで検索。
https://hub.docker.com/search/?q=&type=image
'gitlab/gitlab-ce:latest'はgitlab-ceの最新版という意味で、イメージを更新すれば、最新版にアップデートしていくことも容易です。restart:
alwaysにすれば、マシンの再起動時、dockerデーモンの再起動時に再起動してくれますenvironment:
gitlabの環境変数を事前に指定できます。
後からでも/etc/gitlab/gitlab.rbを編集して
gitlab-ctl reconfigure
gitlab-ctl restart
でも反映されます。
しかし、手動の変更はコンテナを作り直すたびに初期化されるので、できれば避けたいところです。ports:
実際のポートとDocerのポートを結び付けています。
10022番ポートに来たら、Docerの22番ポートにつなぎます、という意味です。
なぜGitLabを80で動かさないかというと、GitLabのCronのURLがどうしても80で動かして10080と表示できるように設定できなかったため、
仕方なくDocker内でもHTTPを10080ポートにしました。
HTTPを80で動かしたい人は10080と記載されているところを全部直せばできます。volumes:
重要フォルダをDocker外に結び付けてDockerを削除しても設定やログがそのまま残るようにしています。
つまりこれらのバックアップさえあればよいということで管理が楽ですね。・イメージのダウンロード、docker起動
docker-compose up -d gitlab
dockerの起動ですが、イメージがない場合はダウンロードしてきてくれます。ちなみにDocker-Composeを使わず手動で叩くとこんな感じです。
docker run --detach \
--hostname XXXXX.co.jp \
--publish 10443:443 --publish 10080:10080 --publish 10022:22 \
--name gitlab \
--restart always \
--volume /docker/gitlab/config:/etc/gitlab \
--volume /docker/gitlab/logs:/var/log/gitlab \
--volume /docker/gitlab/data:/var/opt/gitlab \
gitlab/gitlab-ce:latest・イメージ確認
docker images・コンテナ確認
docker ps -a・コンテナに入る
docker exec -it gitlab /bin/bashGitLabの設定
・初回ログイン
http://xxxxx.co.jp:10080/gitlab/
にアクセス・パスワード変更
初回パスワードを入力して、適当に変更
Username: root
Password: 5iveL!fe・Registerからアカウント作成
作成したアカウントの下にプロジェクトを作成していきます。・プロジェクトの作成
Initialize repository with a READMEをしてしまうと、一度PullしないといけなくなりAndroidStudioの場合は面倒なことになってしまいます。・CloneボタンのURLをコピー
[http://xxxxx.co.jp:11080/gitlab/user/test.git]AndroidStudioの設定
・プロジェクト作成(既存であればそれでよいです)
・バージョンコントロールをGitに設定
VCS → Enable Version Control Integration [Git]・プロジェクトをadd,commit
ソースツリーを[Android] → [Project]に変更
ルートディレクトリを右クリックして、[Git] → [Add]
同じく[Git] → [Commit Directory]add,commitする方法は複数あるのでやりやすい方法で行ってください。
・プロジェクトをpush
VCS → Git → Push
[Define remote]をクリックするとURLを入力できるので
Cronでコピーした[http://xxxxx.co.jp:11080/gitlab/user/test.git]
を入力。
その際にユーザー登録したIDとパスワードを聞かれるので入力。
他にもSSHのキーを登録してアクセスする方法もあります。GitLabで表示確認
http://xxxxx.co.jp:10080/gitlab/
にアクセスしてプロジェクトにソースが反映されているのを確認。
- 投稿日:2019-03-02T10:04:58+09:00
Ubuntu向けLinuxカーネルのdebパッケージ作成 (+perf, ftrace)
Ubuntu向けのLinuxカーネル関連debパッケージであるlinux-image, linux-headersに加えてlinux-tools(perf等が含まれる)を作成するための手順/スクリプトについて整理しています。
最新Linuxカーネルをビルドして適用したものの、カーネルバージョンの不一致によりperf, ftrace等を利用できず困ってる人向けです。
背景
Linuxカーネルはバージョンが上がる度に様々な機能、バグフィックス、最適化が加わります。また、パフォーマンスチューニングや解析のために必要なカーネル周りのメトリクス・ツール周りも積極的に強化されるため、新しいLinuxカーネルを積極的に導入&検証する方も多いと思います。
しかし新しいLinuxカーネルをビルドして適用した場合、perf, ftrace等のカーネル周りのイベント等を監視するためのツールもカーネルのバージョンに合わせて更新しなければ利用できなくなります。
apt/yum等のレポジトリに登録されているLinuxカーネルの場合、基本的にそのカーネルバージョンに対応するパッケージ(ex. linux-tools)が提供されているため特に問題はありません。
しかしそれ以外の手段(ex. Linux本家のソースコード、Ubuntu mailine ppa)でLinuxカーネルを適用する場合、perf, ftrace等がデフォルトでは含まれていなかったり、これらを含めるために結構色々な知識や試行錯誤が必要となることが多いです。Linuxカーネルの最新版を適用しても、perf, ftraceを利用できなければ解析や検証の幅が極めて狭くなってしまいます。
このため本記事では以下のものを利用して、linux-image, linux-headers等のdebパッケージに加えてlinux-toolsのdebパッケージを作成するための「Dockerを活用した手順/スクリプト」について記載しています。
- Linux本家のLinuxカーネル ソースコード
- Ubuntu mainline ppaのパッチファイル
前提
- ビルドマシン環境の前提
- Ubuntu 16.04 or 18.04
- Docker 18.09 (おそらく17.xxでも問題なし)
- ビルド実施者の前提
- Linuxカーネルのビルド、コンフィグ設定、インストール等ができることを想定。
- perf, ftrace等のツールの重要性を理解している。
- プロダクト環境等に導入する場合は、事前に十分な検証を行ったり、リスク評価を行ったりする必要があると十分に理解していることを想定。
ビルド手順
下記gistに手順および資材ファイルを載せています。
https://gist.github.com/yoichiwo7/70f81429813c5ec32cc620a950495b3e
手順はgistのREADME.mdにも記載していますが、簡単に日本語で記載しておきます:
gistにある
Dockerfile
とbuild-kernel-with-perf.sh
を同じディレクトリにダウンロードします。ダウンロードしたディレクトリにcdして、下記コマンドを実行してカーネルビルド用のDockerイメージを作成します。何故Dockerを使っているかは簡単に後ろの節で説明しています。
docker build -t kernel-build .Dockerイメージを作成後、Dockerコンテナを起動してカーネルをビルドします。コマンドの最後のパラメータはLinuxカーネルのバージョンなので、ビルドしたい適切なバージョンに適宜変更してください。
ちなみにLinuxカーネルのビルドには数時間レベルの時間がかかるので注意しましょう。
TARGET_KERNEL_VERSION="4.20.13" docker run \ --rm \ -u $(id -u):$(id -g) \ -v $PWD:/Output \ kernel-build $TARGET_KERNEL_VERSIONビルドが完了すると、同じディレクトリ配下に*.debのLinuxカーネル関連のdebパッケージが配置された状態となります。debパッケージは以下のコマンドでインストールすることができます。(インストール順は重要です)
dpkg -i linux-headers-* dpkg -i linux-modules-* linux-image-* dpkg -i linux-tools-*(補足) ビルド用Dockerイメージを使う理由
Linuxカーネルの各種debパッケージをビルドをするためには様々なUbuntuパッケージが必要となります。さらにUbuntuの16.04/18.04とかDesktop/Serverでも微妙に必要なパッケージ条件が異なる可能性があります。
このためDockerを使わずに様々なバージョンのUbuntu環境でカーネルビルドを実施すると、どうしても試行錯誤を繰り返しがちですし、Ubuntu環境自体に色々なパッケージがインストールされて汚れてしまいます。そして色々入れ過ぎたり設定したりした結果、何が正しいビルド条件なのかが把握できなくなることも珍しくはありません。
このため本手順ではカーネルビルド用のDockerイメージ(ベースイメージをubuntu 18.04に固定)を作成することで「より確実かつ環境を汚さず」にビルドを実施できるようにしています。
- 投稿日:2019-03-02T02:47:22+09:00
neo4jとgremlin-serverをdockerで構築
docker-compose.yml
ポイント
- neo4jの永続化のためのマウント
- gremlinの設定ファイルを変更するためのマウント
docker-composer.ymlversion: "3.3" services: neo4j: image: neo4j ports: - "7474:7474" volumes: - ./neo4j-data:/data gremlin-server: image: tinkerpop/gremlin-server depends_on: - neo4j ports: - "8182:8182" volumes: - ./gremlin-conf:/conf/gremlin-serverの設定ファイル
gremlin-server-neo4j.yamlとneo4j-empty.propertiesの二種類のみを使う。
ただし、前者のファイルは特にいじらないので、置くだけ。ポイント
- HAモードで起動(dockerで同時起動なので、embeddedモードは無理?未検証)
- 一つのneo4jコンテナしか立てないので、neo4jホストのアドレスは種類問わず全て"neo4j" 。
(補足:docker-compose.ymlのdepends_onでneo4jを設定しているので、gremlin-serverから同じ名称で参照できる。たしか、Hostsファイルにneo4jの情報を書いてくれてたはず。)
neo4j-empty.propertiesgremlin.graph=org.apache.tinkerpop.gremlin.neo4j.structure.Neo4jGraph gremlin.neo4j.directory=/tmp/neo4j.server1 gremlin.neo4j.conf.ha.server_id=1 gremlin.neo4j.conf.ha.initial_hosts=neo4j gremlin.neo4j.conf.ha.host.coordination=neo4j gremlin.neo4j.conf.ha.host.data=neo4j gremlin.neo4j.conf.dbms.auto_index.nodes.enabled=true gremlin.neo4j.conf.dbms.auto_index.relationships.enabled=true最後に
docker-compose up -d
で立ち上げて終了。
gremlin-serverに対してクエリを投げればneo4jに保存される。参考
gremlin-serverのHAモードについて
http://tinkerpop.apache.org/docs/current/reference/#_high_availability_configuration
- 投稿日:2019-03-02T01:04:27+09:00
Dockerでのデータベース環境構築in Spring boot(IntellJ)
Spring boot + dockerでデータベース連携するぞ!
初記事。
ご指摘たくさんください。Spring bootでポートフォリオを作ろうと思った時にdockerでのDB構築に手間取ったのでメモ。
今回のゴール
サンプルプロジェクトにてdockerを用いて構築したデータベース(Mysql)の値を画面へ出力する
・対象読者...
docker初心者
or
開発経験の浅い(1、2年)エンジニア今回注力する観点
・dockerfileの作成の仕方
・docker上に作成したMySQL環境とspring bootプロジェクトの連携※dockerの概念などはザックリ説明→とりあえずdockerとアプリケーションを連携するところまで
dockerとは
@kotaro-drさんの記事を載せさせていただきます。
【図解】Dockerの全体像を理解する -前編-
┗ドキュメントが綺麗で初学者でもかなりわかりやすい
【図解】Dockerの全体像を理解する -中編-
┗中編の最初にはデータベースの永続化にも関わってくるデータ管理の話が出てくるので今回は最低そこまでチラ見すればOKです。
ついでに後編も載せておきます。
【図解】Dockerの全体像を理解する -後編-なぜdockerなのか
・Vurtualboxよりも軽量である←テーマと焦点がズレるため詳しくは割愛。
・開発環境をすぐに用意できる
┗「この端末では動くのに自分の端末では動かない。」ということがなくなる。
┗知り合いに質問したりteratailなどのQAサービスで質問したりするときに自分の今の環境をそのまま相手に渡すことができ、回答が返って来やすくなる。
※今回はローカルマシンにIntelliJとJavaが入っていることを前提に進めます。Javaをdockerに含めることもできますが今回の観点を
「dockerでのMysql環境の構築とアプリケーションとの連携」としているため。
IntelliJとJavaのインストールについては以下に載せます。
■IntelliJ
IntelliJ -for mac
IntelliJ -for Windows
■Java11
Java -for mac
Java -for Windows早速やってみよう
■環境情報
言語:Java(jdk11)
FW:Spring boot
IDE:IntelliJ
※今回、IDEをIntelliJにしてみました。操作感はほぼeclipseと同じですが、UIがなんかいい感じ。今では世界シェアはeclipseを抜いているとかいないとか。。。
まずはプロジェクトを簡単に作ってみたいと思います。
その前にIntelliJにjdkのパスを登録します。以下リンク内で、【Javaプロジェクトの作り方】を検索すると出てきます。
JDKの登録今回作成するプロジェクトのtreeです。(画像ですみません)
今までリンクばかりでしたが、そろそろ自分の言葉を出していきたいと思います。
プロジェクトの作成
今回はデータベースの値を全て出す簡単なモノを作ります。
というか見ればわかるレベルなので3分クッキングパターンで、出来たものが以下になります。
docker(github)
※要所でコメントを入れていますのでもし解釈が間違っている等ありましたらご指摘頂けると助かります。
application.properties
についてspring.datasource.url=jdbc:mysql://localhost:3306/demo?characterEncoding=UTF-8&serverTimezone=JST #//demoが今回のデータベース名 spring.datasource.username=root //ユーザ名 spring.datasource.password=p@ssw0rd //パスワード spring.jpa.hibernate.ddl-auto=update //アプリケーション起動時に、Entityに対応するテーブルがなければ作成こちらはデータベース連携に必要な最低限の設定です。のちに作成するdocker-compose.ymlの内容と合わせる必要がありますので注意してください。
dockerfileの作成
今回はsrcと同じ階層にdockerというフォルダを作成しその中に関連ファイルを作っていこうと思います。
場所についての記述が見つけられなかったため特に指定はないと認識しています。fockerfileFROM mysql:8.0 #dockerhubより取得するイメージを指定 RUN /bin/cp -f /etc/localtime /etc/localtime.org RUN /bin/cp -f /usr/share/zoneinfo/Asia/Tokyo /etc/localtime COPY ./my.cnf /etc/mysql/conf.d/ RUN mkdir -p /var/log/mysql RUN chown mysql.mysql /var/log/mysqlCOPY:コマンドの左側がローカル側、右側がdockerイメージ側のことを書いております。
RUN:対象のイメージにインストールされているコマンドを実行できるdocker-compose.ymlversion: '3' services: mysql: build: ./mysql environment: - MYSQL_DATABASE=demo - MYSQL_ROOT_USER=root - MYSQL_ROOT_PASSWORD=p@ssw0rd - TZ=Japan volumes: - ./initdb.d:/docker-entrypoint-initdb.d - ./dbdata:/var/lib/mysql ports: - "3306:3306"↑コロン(:)で区切られている場合
・左側がホスト側、右側がコンテナ側のパスを表す
・初期データ投入→initdb.dディレクトリに最初に読み込むsqlファイルを入れる
永続化→dbdataに処理をするごとにデータ相当のファイルがどんどん入ってくる
docker-composeを起動させよう
プロジェクト上のdocker-compose.ymlを右クリックし「再生」をします。
すると、さっき書いたdockerfile
やdocker-compose.yml
を解釈してせっせか環境構築が始まります。
以下のように'Compose: docker' has been deployed successfully.
と出たら完成です。
では早速、データベースが出来上がっているかコンテナに入って確認してみます。
ターミナル(Windowsの場合はコマンドプロンプト)でプロジェクトのディレクトリへ移動します。
その中で
docker ps
コマンドで現在のコンテナの稼働状況を確認します。
実行後が下図です
mysqlのイメージができていることがわかります。
起動にはこちらのCONTAINER IDもしくはNAMESを使います。今回はCONTAINER IDを使って起動してみます。
docker exec -it 【CONTAINER ID】 bash
でコンテナに入ります。
root@37c06170b19b:/#
こんな感じのターミナル(コマンドプロンプト)になっていれば入れています。
この画面よりrootユーザでMysqlへ接続します。
mysql -u root
今回はパスワードをp@ssw0rd
としてます。
以下のようにmysqlへ接続
use demo
で今回のサンプルデータベースを指定。あとは適当にsqlをうって確認します。初期データとしてはuser
テーブルが入っていますので。
select * from user;
テーブルの中身を確認できました。あとは自分のショボいサンプルプロジェクトを
DockerApplication
から実行すると...
以下のようにデータベースとの連携に成功しました。
このようにdockerを使えば環境ごと相手に渡すことができるのでわざわざ相手にデータベースのセットアップやデータの投入をさせずに済みます。
dockerの知識はまだまだ浅いですが、これからどんどん使われていく事になると思いますので、積極的に使っていきたいものです。次回は、Spring bootで認証画面を試してみたいと思います。
- 投稿日:2019-03-02T00:02:30+09:00
Rails要らず、CGIとRubyでソースコードをフローチャートにするツール作成
きっかけは怠惰なお気持ちでした。ということで、こんなの作ってみました。よかったら、ご覧ください。
要は、フォームに入力されたRubyのソースコードを、フローチャートにしてくれる、というもの。
具体的には、以下のソースコードが
class Worker def initialize(hungry:) @hungry = hungry end def next_action if hungry? :eat else :work end end def hungry? @hungry end endこんな画像になって出てくる。
ソースコードのフローチャート化のために、RubyのGemvisualize_rubyとグラフ描画してくれるGraphvizを使っています。きっかけは怠惰なお気持ちでした(T_T)
- 業務の中で仕様書になっていないソースコードを読んで、読んで、理解して、フローチャートにして、要件詰めて、また読んでが面倒に思えた。
- 読むだけなら、まだいいんですが、他の人と共有とかを考えると可視化していく必要があった
- 1回ならいいんだけれど、いろんなところでそれが発生していた
- どんどん変化していく類のものだったときに、仕様書にしてもメンテされない
あと普段Railsを使うことが多いのですが、乳離というか、Rails離れもしたいというお気持ちでした
- Railsにはいつもお世話になっており、細かいことを気にしなくても、ワタシが気持ちよく働ける環境を作ってくれています
- が、いっぽうで、それゆえに根本的なRubyという言語やWebサービスがどう動いているのかの理解が浅いままになっちゃているな、とも思うようになった。
- ミニマムでやりたいことだけをやるとしたときに、なにがあればいいんだろうかっていうのも知りたかった。恥ずかしながら、たぶんRailsなしでは飛べない小鳥ですので。
フローチャートに自動でしてくれるやついないかなって探していたら、街角でばったり出くわしたのがvisualize_rubyでした。
- 有り難いと思いながら、卑屈な人間なので
- 簡単に自分の環境で実装ができたのですが、環境依存とかで設定が面倒だなって思い
- コンソールからイジルの、絶対みんなできないよ〜って思い
そうだ!環境に依存しないDockerでRailsを使わない(CGIとRuby)でブラウザからフォーム入力ができて、描画してくれるツールを作ってみようと決心したのでした。
こちらが該当のリポジトリ、名付けてVisualizeSrc!!
ざっくり取り上げると、以下のような構成で作ってみました。詳細な中身はリポジトリをご覧ください。基本的には、リポジトリを各人のローカル開発環境にpullしてもらって、ビルドしてもらえればlocalhostのport80で動くような設定をしています。ファイル構成
/var配下の処理スクリプト達 ├── www │ ├── cgi-bin │ │ ├── Gemfile │ │ ├── Gemfile.lock │ │ ├── result.rb ...フォームから値を受け取ってモジュールに渡す │ │ ├── source_code.png ...作成される画像データ │ │ └── visualize_mod.rb ...画像を作るモジュール │ └── html │ └── form.cgi ...フォームから入力値を受け取る /etc配下の設定ファイル達 ├── conf │ ├── httpd.conf ... PortやAliasの設定 ├── conf.d │ ├── cgi-enabled.conf ... CIGでRubyファイルが処理できるように設定 ちなみにrbenvを使って管理しており、Gemは以下のパスへ /usr/local/rbenv/versions/2.3.8/lib/ruby/gems/2.3.0/gems/環境
- Dockerfile - CENTOS:7 - Apache - 変更した設定(Dockerでイメージビルドするときに差し替えました) - httpd.conf - cgi-enabled.conf - Ruby:2.3.8 - 使ったライブラリ - parser - visualize_ruby - 詳細はDockerfileを!使い方はこんな感じ。
1. 該当リポジトリを各環境へpull
git pull https://github.com/taishinagasaki/visualize_src.git2. Docker imageの作成
docker build -t repository_name/image_name:tag_name . --no-cache=true3. できたイメージを確認
docker images4. dockerのイメージは以下の特権モードで起動する。ポートは80と80を繋げる。
docker run --privileged -d -p 80:80 --name container_name repository_name/image_name:tag_name /sbin/init5. containerが立ち上がっていることを確認する。statusがUPになればOK。
docker start <container_id>6. 立ち上がっていればcontainer idを指定して起動
docker exec -it <container_id> /bin/bash7. apacheの起動
systemctl start httpd8. apacheの起動を確認
systemctl start httpd9. ブラウザから
localhost/form.cgi
へアクセス
使い方は該当リポジトリのREADME.mdに記載しております。各工程と、助けてくれた資料達
作業内容 資料名 ApacheのインストールからCGI設定まで Apache httpd : インストール設定 RubyをCGIで動かす設定まで Apache httpd : Ruby を利用する フォーム入力値をRubyファイルで受け取る [Linux][Ruby]ApacheでRubyのCGIを動かす方法 Dockerでsystemctlを使えるようにする CentOS 7のDockerコンテナ内でsystemdを使ってサービスを起動する Dockerでイメージ作ってコンテナを立ち上げる Dockerコマンドメモ
ハマったこと
Shebangという、インタプリタの指定にハマってしまいました。
シバンまたはシェバン (英: shebang) とはUNIXのスクリプトの #! から始まる1行目のこと。起動してスクリプトを読み込むインタプリタを指定する。
恥ずかしながらShebagの存在すら知らず、インストールしたgemを一括で取り込むためにrequire 'bundler/setup'を実行しても延々とエラーが出続ける、というもので、これに関してはデバッグ方法もわからずでした。ググってもなかなかなく、根本的な理解がなってないな〜ということを改めて知りました。
また後日、投稿したいと思います。
[追記: 2019/03/02] `require': cannot load such fileエラーをインタプリタ指定から探る ~ファイル1行目のshebang設定~...shebang設定について言及まだできてないこと/TODO
- Web化してもいいかなっておもったんですがセキュリティ周りの設定が間に合わず(怖かったので)、またの機会に持ち越しとしました。
- DockerfileのCMD複数指定を実現する。
- CMDでshell scriptを指定してあげるとできるとおもっていたが、できず。
- どうにかやってみたい。
- VIMで環境を整えたい。
学び
- Railsから離れたり、いつも使っている高機能エディタから離れることでより根本理解が深まった印象。
- MW(Apache)やOS層も普段は殆ど触らないので勉強することが多かった。
- 実はQiita投稿も初めてなので、その他「初めて」が多くてよかった。
次にやりたいこと
- TODOを潰す
- Dappに触ってみる
お読み頂きありがとうございました。
なにか間違っていたり、ベターな方法がある場合はご教示いただけると幸いです。