20190503のMacに関する記事は9件です。

住所(address)

インタネットを支える、MACアドレス、IPアドレス、ドメイン名に関する資料を収集。

順次IEEE文書、RFC等との関連を追記予定。

MACアドレス(Media Access Control address)

(今更)Linux で HW(MAC)アドレスを取得する方法
https://qiita.com/p_cub/items/b0b4351c52c876aaa095

MACアドレスの設定
https://qiita.com/yamori813/items/1687b068017d08358153

[memo]MACアドレス取得 android
https://qiita.com/an_emerald/items/6b89bbc421b6b963fe8b

Raspberry PiのMACアドレス
https://qiita.com/kanpapa/items/417a1c9cec6f1308b86e

IPアドレス(internet protocol address)

macのメニューバーにIPアドレスを表示させる
https://qiita.com/msrks/items/6b308fe7bc3e85839a84

自分のIPをterminalで調べる
https://qiita.com/sebeckawamura/items/d401e90016aec8a27bad

IPアドレスから国や都市を判別する (GeoIP)
https://qiita.com/bezeklik/items/927e1c52c8c0aefb1f06

IPv4アドレスはどうして今でももらえるの?
https://qiita.com/maech/items/ac16e59915b6bed3ed29

LAN内で利用されているIPアドレスを調べる
https://qiita.com/zanjibar/items/b3110aef26fd26c230b9

文字名(domain name)

Raspberry PiでDNSサーバーを立てる
https://qiita.com/msrks/items/20207ea1bab05e6ffb93

.io ドメインがおかしくなったので dig で調べてみた(2016/10/28)
https://qiita.com/MasahitoShinoda/items/40cd312fabc6db604b39

Dockerで権威DNSサーバーのNSDを動かす
https://qiita.com/ohhara_shiojiri/items/39cb9c3a632676c7b33d

Dockerで権威DNSサーバーのPowerDNSを動かす
https://qiita.com/ohhara_shiojiri/items/1705f0045b8d860f771d

Route 53でローカルDNSを構築する
https://qiita.com/keitakn/items/4dbf03280868891f551b

関連(related)

MACアドレスとIPアドレスの違い
https://qiita.com/cironaga/items/6a0c909e31f986c9f825

文書履歴(document history)

ver. 0.01 初稿 20190504
ver. 0.02 資料追記 20190505
ver. 0.03 資料追記 20190507

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

metaタグを用いたリダイレクト機能で躓いた件

#概要
HTMLにおける<meta>タグを使用した
リダイレクト機能をテストした際に
指定URLに飛ばずに四苦八苦し記録です。

背景

基礎からのMySQLを進める途中、
まさにその基礎勉強に飽き飽きし、
PHPの学習に飛んだ時の話です。

phpの話に入ったばかりの課題が
表題の件でした。
(最初にやることじゃなくね…?)

開発環境

MacOS Mojave
PHP 7.1.23
Apache 2.4.39
使用ブラウザ Safari

内容

初期に書いたコードは以下の通りでした。
文法は「基礎からのMySQL」に基づいていますが、
ちょっとだけアレンジしています。

test.php
<?php
print "<head>";
print " <meta http-equiv='refresh' content=5; URL='http://www.softbank.jp/'>";
print "</head>";
print "<body>";
print "5秒後にソフトバンクのページへ移動します";
print "</body>";
?>

何とも言えないクソコードですね。
出力結果を見てみましょう。

5秒後にソフトバンクのページへ移動します

↓5秒後…

5秒後にソフトバンクのページへ移動します

ページは変わらず、永遠と5秒ずつ同じページを
更新し続けています。
書籍の説明では、5秒後に
指定したURL先にジャンプするはずなのですが…

対処

ググりにググり、リダイレクト機能について調査
しましたが、ほとんどのサイトが上記の記述で
説明されていました。

ところが、ある一つのサイトだけ
違った記述方法でした。

その記述方法を用いて訂正したコードを
下記に示します。

test.php
<?php
print "<head>";
//シングルクオートの位置が違う
print " <meta http-equiv='refresh' content='5; URL=http://www.softbank.jp/'>";
print "</head>";
print "<body>";
print "5秒後にソフトバンクのページへ移動します";
print "</body>";
?>

訂正前はURLのみをシングルクオートで囲っていましたが

訂正前
<meta http-equiv='refresh' content=5; URL='http://www.softbank.jp/'>

訂正後はcontentで指定する秒数の前からシングルクオートで
囲っています。

訂正後
<meta http-equiv='refresh' content='5; URL=http://www.softbank.jp/'>

結果、出力は以下の通りになりました。

5秒後にソフトバンクのページへ移動します

↓5秒後…

(ソフトバンクホームページ)

成功しましたね。

結局何が原因なの?

現時点で分かっていません。
教えてエロい人。

参考書籍

基礎からのMySQL
参考サイト

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

Deep learning AMIのUbuntu 16.04.6 LTSにデスクトップ環境を構築してMacから繋ぐ

はじめに

基本的に、AWS EC2上のUbuntu16.04にデスクトップ環境を構築してMacからつなぐと同じですが、
2019/05/03現在、同様のプロセスでいくつか躓いたので、情報共有です。

やりたいこと

  • AWSのDeep learning AMIUbuntu 16.04.6LTSにデスクトップ環境を構築してMacから繋ぐこと
  • Deep Learning AMI (Ubuntu) Version 22.0:ami-06868a6ddab784c28

うまくいかなかった点

  1. その1
$ sudo sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config

とすると、

sudo: unable to resolve host ip-●●●-●●-●-●●●

となってしまった。解決するためには、

$ sudo sh -c 'echo ●●●.●●.●.●●● $(hostname) >> /etc/hosts'

とすればよい。ただし、ip-●●●-●●-●-●●●ではなく、●●●.●●.●.●●●とすることに注意です。

ご参考:
- https://tech.librastudio.co.jp/index.php/2017/03/09/post-1322/
- https://qiita.com/ogomr/items/89e19829eb8cc08fcebb
- https://stackoverflow.com/questions/33441873/aws-error-sudo-unable-to-resolve-host-ip-10-0-xx-xx/33443018

  1. その2
$ sudo apt install xrdp xfce4 xfce4-goodies tightvncserver

とすると、

E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource temporarily unavailable)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another process using it?

となってしまった。解決するためには、

$ sudo killall apt apt-get

とすれば良い。詳細は参考リンクをご確認ください。

ご参考:
- https://askubuntu.com/questions/1109982/e-could-not-get-lock-var-lib-dpkg-lock-frontend-open-11-resource-temporari

まとめ

以上をまとめると、AWS EC2上のUbuntu16.04にデスクトップ環境を構築してMacからつなぐで紹介されているプロセス
に2行だけ追記して、上から実行していくだけ。素晴らしい記事を書いていただいてありがとうございます、、、!

sudo apt update && sudo apt upgrade

sudo sh -c 'echo ●●●.●●.●.●●● $(hostname) >> /etc/hosts'

sudo sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config

sudo /etc/init.d/ssh restart

sudo passwd ubuntu

sudo killall apt apt-get
sudo apt install xrdp xfce4 xfce4-goodies tightvncserver

echo xfce4-session> /home/ubuntu/.xsession

sudo cp /home/ubuntu/.xsession /etc/skel

sudo sed -i '0,/-1/s//ask-1/' /etc/xrdp/xrdp.ini

sudo service xrdp restart

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

ショートカットキー一覧 ~mac編~

macのショートカットキーを自分用にまとめます。
思い出したら更新していきます。

<command>

command+c = copy
command+x = cut
command+v = paste
command+s = save
command+z = back
command+数字 = タブ切り替え

<option>

optino+z = Ω
option+x = √
option+b = ∫
option+w = ∑

<control>

control+a = キャレットを左端に移動
control+a = キャレットを右端に移動
control+f = キャレットを一つ進める
control+d = delete

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

MacでWindowsからのテキストをiconvで一括変換する

ほんと大した話ではないのだけど、何故か検索するとnkfしか出てこないから。
macで直下のディレクトリすべてのcppファイルをcp932からutf8に変換するだけのスクリプトです。

find . -type f | grep "\.cpp$" | xargs -t -I{} sh -c "iconv -f cp932 -t utf8 {} > {}.utf8.cpp"

https://gist.github.com/bhind/b85cb780fb349647654436645f1f03af

以上、解散!!

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

一足遅れて Kubernetes を学び始める - 05. workloads その1 -

ストーリー

  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 -

前回

一足遅れて Kubernetes を学び始める - 04. kubectl -では、kubenetesのCLIツールkubectlを学習しました。
今回は、目玉機能であるworkloadsについて学習します。

workloads

Kubernetesには、下記のようにリソースの種類が存在します。
今回は、Workloadsを学習します。

リソースの分類 内容
Workloadsリソース コンテナの実行に関するリソース
Discovery&LBリソース コンテナを外部公開するようなエンドポイントを提供するリソース
Config&Storageリソース 設定・機密情報・永続化ボリュームなどに関するリソース
Clusterリソース セキュリティやクォータなどに関するリソース
Metadataリソース リソースを操作する系統のリソース

KubernetesのWorkloadsリソース(その1)

Workloadsには、下記8つの種類があります。
* Pod
* ReplicationController
* ReplicaSet
* Deployment
* DaemonSet
* StatefulSet
* Job
* CronJob

Pod,ReplicationController,ReplicaSet,Deploymentまでを見ていきます。

Pod

コンテナを1つ以上含めた最小単位のリソース。
Pod毎にIPアドレスが振られる。ボリュームは共有。
基本的に、Podにコンテナを詰め込めるのではなく、「分離できるなら、分離する」方針がマイクロサービスとして良いそうです。
さっそく、動かしてみます。

alias k=kubectl

sample-2pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-2pod
spec:
  containers:
    - name: nginx-container
      image: nginx:1.12
    - name: redis-container
      image: redis:3.2
pi@raspi001:~/tmp $ k apply -f . --prune --all
pod/sample-2pod created
pi@raspi001:~/tmp $ k get pod sample-2pod
NAME          READY   STATUS    RESTARTS   AGE
sample-2pod   2/2     Running   0          101s

期待通り複数のコンテナが動いていますね。(READY 2/2)
execで中に入る場合、どうなるのでしょうか。

pi@raspi001:~/tmp $ k exec -it sample-2pod /bin/sh
Defaulting container name to nginx-container.
Use 'kubectl describe pod/sample-2pod -n default' to see all of the containers in this pod.
#

なるほど、デフォルトのコンテナ(containersの最初になる)に入るみたいです。
redis-containerに入る場合は、

pi@raspi001:~/tmp $ k exec -it sample-2pod -c redis-container /bin/sh
# redis-cli
127.0.0.1:6379> exit
#

-cでコンテナを指定するだけみたいです。
他にもありますが、長くなりそうなので切り上げます。

ReplicaSet, ReplicationController

レプリカという名前だけあって、Podを複製するリソース。
過去の経緯からReplicationControllerからReplicaSetへ名前変更があったため、ReplicaSetを使うことが推奨

さっそく、動かしてみます。

sample-rs.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: sample-rs
spec:
  replicas: 3
  selector:
   matchLabels:
    app: sample-app
  template:
   metadata:
    labels:
     app: sample-app
   spec:
    containers:
      - name: nginx-container
        image: nginx:1.12
      - name: redis-container
        image: redis:3.2
pi@raspi001:~/tmp $ k apply -f . --prune --all
replicaset.apps/sample-rs created
pod/sample-2pod unchanged
pi@raspi001:~/tmp $ k get pods
NAME              READY   STATUS              RESTARTS   AGE
sample-2pod       2/2     Running             0          20m
sample-rs-ghkcc   2/2     Running             0          103s
sample-rs-nsc5b   0/2     ContainerCreating   0          103s
sample-rs-wk7vl   0/2     ContainerCreating   0          103s

確かに、replica3つ(sample-rs)で、それぞれコンテナが2つ(READY 2/2)作れていますね。
書いて気になるのは、 podのapiVersionは、v1に対して、replicaSetのapiVersionは、 apps/v1というちょっと違うのが気になりましたので、調べてみたところ、Kubernetesの apiVersion に何を書けばいいかという記事を見つけました。
Coreとなる機能は、v1で良いみたいです。

Kubernetesの目玉機能であるオーケストレーションの機能であるセルフヒーリングを試してみます。

pi@raspi001:~/tmp $ k get pods
NAME              READY   STATUS    RESTARTS   AGE
sample-2pod       2/2     Running   0          29m
sample-rs-ghkcc   2/2     Running   0          11m
sample-rs-nsc5b   2/2     Running   0          11m
sample-rs-wk7vl   2/2     Running   0          11m
pi@raspi001:~/tmp $ k delete pod sample-rs-wk7vl
pod "sample-rs-wk7vl" deleted
pi@raspi001:~/tmp $ k get pods
NAME              READY   STATUS              RESTARTS   AGE
sample-2pod       2/2     Running             0          30m
sample-rs-ghkcc   2/2     Running             0          11m
sample-rs-gq2hs   0/2     ContainerCreating   0          13s
sample-rs-nsc5b   2/2     Running             0          11m

おー、ContainerCreatingされています。良いですね〜。
ちなみに、気になったのはnode自体が故障してダウンした場合は、どうなるのでしょうか。試してみます。

pi@raspi001:~/tmp $ k get pods -o=wide
NAME              READY   STATUS    RESTARTS   AGE    IP            NODE       NOMINATED NODE   READINESS GATES
sample-2pod       2/2     Running   0          32m    10.244.1.25   raspi002   <none>           <none>
sample-rs-ghkcc   2/2     Running   0          13m    10.244.1.26   raspi002   <none>           <none>
sample-rs-gq2hs   2/2     Running   0          114s   10.244.1.27   raspi002   <none>           <none>
sample-rs-nsc5b   2/2     Running   0          13m    10.244.2.15   raspi003   <none>           <none>

raspi003の電源を落としてみます。

worker(raspi003)に移動

~ $ slogin pi@raspi003.local
pi@raspi003.local's password:
pi@raspi003:~ $ sudo shutdown now
sudo: unable to resolve host raspi003
Connection to raspi003.local closed by remote host.
Connection to raspi003.local closed.
~ $

master(raspi001)に移動

pi@raspi001:~/tmp $ k get nodes
NAME       STATUS     ROLES    AGE     VERSION
raspi001   Ready      master   5d16h   v1.14.1
raspi002   Ready      worker   5d16h   v1.14.1
raspi003   NotReady   worker   4d21h   v1.14.1
pi@raspi001:~/tmp $ k get pods -o=wide
NAME              READY   STATUS    RESTARTS   AGE     IP            NODE       NOMINATED NODE   READINESS GATES
sample-2pod       2/2     Running   0          35m     10.244.1.25   raspi002   <none>           <none>
sample-rs-ghkcc   2/2     Running   0          17m     10.244.1.26   raspi002   <none>           <none>
sample-rs-gq2hs   2/2     Running   0          5m38s   10.244.1.27   raspi002   <none>           <none>
sample-rs-nsc5b   2/2     Running   0          17m     10.244.2.15   raspi003   <none>           <none>

ん? raspi003で動いている? 数十秒後... :thinking:

pi@raspi001:~/kubernetes-perfect-guide/samples/chapter05/tmp $ k get pods -o=wide
NAME              READY   STATUS        RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
sample-2pod       2/2     Running       0          40m   10.244.1.25   raspi002   <none>           <none>
sample-rs-ghkcc   2/2     Running       0          22m   10.244.1.26   raspi002   <none>           <none>
sample-rs-gq2hs   2/2     Running       0          10m   10.244.1.27   raspi002   <none>           <none>
sample-rs-nsc5b   2/2     Terminating   0          22m   10.244.2.15   raspi003   <none>           <none>
sample-rs-p2jsc   2/2     Running       0          53s   10.244.1.28   raspi002   <none>           <none>

おー、期待通り raspi003にあるpodが消えて、raspi002に作り直されました。sample-rs-nsc5bはnodeが落ちちゃっているので、消すこともできず残り続けます。

少し待ち時間が長いような?

Kubernetesはクラスタで障害があったとき、どういう動きをするのかという記事によれば、kube-controller-managerが検知して、kube-schedulerが正しい数に揃えているみたいです。数十秒待たされたのは、検知の間隔のせいでしょうか。

kube-controller-managerのオプションで、--attach-detach-reconcile-sync-period duration Default: 1m0sとあります。1分間隔なのですかね。

特定Nodeでは動かさないようにしたい

「特定のnodeには動かさないで!」みたいな要望を叶えれるのでしょうか。 :thinking:

Assigning Pods to Nodesによると、nodeSelectorフィールドでアサインされるnodeを指定できるそうです。(除外ではなく、指定)
ただし、Editing nodeSelector doesn't rearrange pods in ReplicaSetによると、それはreplicaSetではなく、deploymentで行うべきとのことです。replicaSetで動くかどうか、念の為試してみます。

まず、先程落としたraspi003を電源を入れ直して起動させます。
その後、master(raspi001)に移動。

pi@raspi001:~/tmp $ k label nodes raspi002 type=AWS
node/raspi002 labeled
pi@raspi001:~/tmp $ k label nodes raspi003 type=GCP
node/raspi003 labeled
pi@raspi001:~/tmp $ k get nodes -L type
NAME       STATUS   ROLES    AGE     VERSION   TYPE
raspi001   Ready    master   5d17h   v1.14.1
raspi002   Ready    worker   5d17h   v1.14.1   AWS
raspi003   Ready    worker   4d21h   v1.14.1   GCP
pi@raspi001:~/tmp $ k get pods -o=wide
NAME              READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
sample-2pod       2/2     Running   0          75m   10.244.1.25   raspi002   <none>           <none>
sample-rs-ghkcc   2/2     Running   0          56m   10.244.1.26   raspi002   <none>           <none>
sample-rs-gq2hs   2/2     Running   0          44m   10.244.1.27   raspi002   <none>           <none>
sample-rs-p2jsc   2/2     Running   0          35m   10.244.1.28   raspi002   <none>           <none>

sample-rsは、全てraspi002で動いているので、下記を試してみます。

  1. sample-rsはraspi002でのみ動くよう設定
  2. raspi002をシャットダウン

その結果、「sample-rsはraspi002が動いていないので、セルフヒーリングしない」ことを期待とします。

sample-rs.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: sample-rs
spec:
  replicas: 3
  selector:
   matchLabels:
    app: sample-app
  template:
   metadata:
    labels:
     app: sample-app
   spec:
    containers:
      - name: nginx-container
        image: nginx:1.12
      - name: redis-container
        image: redis:3.2
    nodeSelector:
        type: AWS
pi@raspi001:~/tmp $ k apply -f . --prune --all
replicaset.apps/sample-rs configured
pod/sample-2pod unchanged

nodeSelectorを追加しました。
今回は単純な指定なのでこれで良いですが、より柔軟に指定したい場合はnodeAffinityを使うそうです。

worker(raspi002)に移動

~ $ slogin pi@raspi002.local
pi@raspi002.local's password:
pi@raspi002:~ $ sudo shutdown now
sudo: unable to resolve host raspi002
Connection to raspi002.local closed by remote host.
Connection to raspi002.local closed.
~ $

数十秒待つ...
結果は...!

master(raspi001)に移動

pi@raspi001:~/tmp $ k get nodes -L type
NAME       STATUS     ROLES    AGE     VERSION   TYPE
raspi001   Ready      master   5d17h   v1.14.1
raspi002   NotReady   worker   5d17h   v1.14.1   AWS
raspi003   Ready      worker   4d22h   v1.14.1   GCP
pi@raspi001:~/tmp $ k get pods -o=wide
NAME              READY   STATUS        RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
sample-2pod       2/2     Terminating   0          89m   10.244.1.25   raspi002   <none>           <none>
sample-rs-4srpp   0/2     Pending       0          36s   <none>        <none>     <none>           <none>
sample-rs-6mgcr   0/2     Pending       0          37s   <none>        <none>     <none>           <none>
sample-rs-ghkcc   2/2     Terminating   0          71m   10.244.1.26   raspi002   <none>           <none>
sample-rs-gq2hs   2/2     Terminating   0          59m   10.244.1.27   raspi002   <none>           <none>
sample-rs-lc225   0/2     Pending       0          36s   <none>        <none>     <none>           <none>
sample-rs-p2jsc   2/2     Terminating   0          49m   10.244.1.28   raspi002   <none>           <none>

期待通りでした。つまり、sample-rsはraspi002以外で作り直せないので、Pending,Terminating状態です。
また、単純なpodであるsample-2podはreplicaSetではないので、セルフヒーリングされずにTerminatingになっています。
面白いですね。これ。

Deployment

複数のReplicaSetを管理。
ReplicaSetにない「ローリングアップデート、ロールバック」機能が存在。
PodやReplicaSetではなく、Deploymentが最も推奨されるリソース種類。

ReplicaSetでは、指定したコンテナイメージを更新した場合(アップデート)、どうなるのでしょうか。すべて更新されるのか、一部だけなのでしょうか。試してみます。

sample-2pod-replica.yamlのnginxイメージを1.12から1.13に更新しました。

pi@raspi001:~/tmp $ k get all
NAME                  READY   STATUS    RESTARTS   AGE
pod/sample-rs-4srpp   2/2     Running   0          7h14m
pod/sample-rs-6mgcr   2/2     Running   0          7h14m
pod/sample-rs-lc225   2/2     Running   0          7h14m

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   6d

NAME                        DESIRED   CURRENT   READY   AGE
replicaset.apps/sample-rs   3         3         3       8h
pi@raspi001:~/tmp $ k apply -f . --prune --all
replicaset.apps/sample-rs configured
pod/sample-2pod created
pi@raspi001:~/tmp $ k describe replicaset sample-rs
Name:         sample-rs
...
  Containers:
   nginx-container:
    Image:        nginx:1.13
...

replicasetのマニュフェストは更新されました。

pi@raspi001:~/tmp $ k describe pod sample-rs-4srpp
Name:               sample-rs-4srpp
...
  nginx-container:
    Container ID:   docker://9160f550ee9d9bbcd1a5c990ca95389b2b39aff6688bcd933c99fe93b1968b99
    Image:          nginx:1.12
...

podは変化なしのようです。
では、Deploymentを使ってみます。

sample-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
        - name: nginx-container
          image: nginx:1.12
          ports:
            - containerPort: 80
pi@raspi001:~/tmp $ k apply -f . --prune --all --record
replicaset.apps/sample-rs configured
pod/sample-2pod configured
deployment.apps/sample-deployment created

--recordをつけることで、履歴を保持することができます。ロールバックに使います。

pi@raspi001:~/tmp $ k get all
NAME                                    READY   STATUS    RESTARTS   AGE
pod/sample-2pod                         2/2     Running   0          12m
pod/sample-deployment-6cd85bd5f-4whgn   1/1     Running   0          119s
pod/sample-deployment-6cd85bd5f-js2sw   1/1     Running   0          119s
pod/sample-deployment-6cd85bd5f-mjt77   1/1     Running   0          119s
pod/sample-rs-4srpp                     2/2     Running   0          7h28m
pod/sample-rs-6mgcr                     2/2     Running   0          7h28m
pod/sample-rs-lc225                     2/2     Running   0          7h28m

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   6d1h

NAME                                READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/sample-deployment   3/3     3            3           2m

NAME                                          DESIRED   CURRENT   READY   AGE
replicaset.apps/sample-deployment-6cd85bd5f   3         3         3       2m
replicaset.apps/sample-rs                     3         3         3       8h

sample-deploymentが、deployment,replicaset,podを作成しました。

では、sample-deploymentのnginxコンテナを1.12から1.13に更新してみます。

sample-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
        - name: nginx-container
          image: nginx:1.13
          ports:
            - containerPort: 80
pi@raspi001:~/tmp $ k apply -f . --prune --all --record
replicaset.apps/sample-rs unchanged
pod/sample-2pod unchanged
deployment.apps/sample-deployment configured
pi@raspi001:~/tmp $ k get pod
NAME                                 READY   STATUS              RESTARTS   AGE
sample-2pod                          2/2     Running             0          15m
sample-deployment-6cd85bd5f-js2sw    1/1     Running             0          4m53s
sample-deployment-6cd85bd5f-mjt77    1/1     Running             0          4m53s
sample-deployment-7dfb996c6b-gh2cg   0/1     ContainerCreating   0          21s
sample-deployment-7dfb996c6b-m4wrd   1/1     Running             0          38s
sample-rs-4srpp                      2/2     Running             0          7h31m
sample-rs-6mgcr                      2/2     Running             0          7h31m
sample-rs-lc225                      2/2     Running             0          7h31m

おー、deploymentのpodが作り変わっていっています。これがローリングアップデートです。
ローリングアップデートは、spec.template以下が更新されると変化したとみなすそうです。
また、ロールバックは、rolloutコマンドで実施できますし、revision指定で戻すこともできます。
しかし、基本的にはマニュフェストを戻してapplyすべきです。

アップデート戦略というものがあり、デフォルトはRollingUpdateです。過不足分のPod考慮した更新戦略になります。
アップデート中に許容される不足分と超過分を設定できます。
他の戦略として、Recreate戦略があります。こちらは、全て同時に作り直しになります。ですので、一時的にアクセス不可になってしまいます。

1つ不安に感じたものとして、「フロントエンドのバージョンを1から2にアップデートしたら、バージョン1のコンテナにアクセスしたユーザがバージョン2のコンテナに遷移したら大丈夫なのかな :thinking: 」と思いました。しかし、これはローリングアップデートに限った話ではないので、それは考えないこととしました。ちゃんと設計すれば良い話ですね。

ちなみに、マニュフェストを書かずにdeploymentができます。k run sample-deployment-cli --image nginx:1.12 --replicas 3 --port 80です。お試しなら、便利ですね。

お片付け

試しに、pruneで削除しています。

pi@raspi001:~/tmp $ ls
sample-2pod-replica.yaml  sample-2pod.yaml  sample-deployment.yaml
pi@raspi001:~/tmp $ mv sample-2pod-replica.yaml sample-2pod-replica.yaml.org
pi@raspi001:~/tmp $ mv sample-deployment.yaml sample-deployment.yaml.org
pi@raspi001:~/tmp $ k apply -f . --all --prune
pod/sample-2pod configured
deployment.apps/sample-deployment pruned
replicaset.apps/sample-rs pruned
pi@raspi001:~/tmp $ k get all
NAME              READY   STATUS    RESTARTS   AGE
pod/sample-2pod   2/2     Running   0          30m

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   6d1h

んー、こうすると消せるのですが、どうしても1ファイル残してしまいます...。
すべてorgにすると、k apply -f .が失敗しますし...。

pi@raspi001:~/tmp $ k delete pod sample-2pod
pod "sample-2pod" deleted

結局、こうしました...。

おわりに

思った以上に、ReplicaSetにハマってしまいました。
次は、残りのworkloadsを試します。
次回はこちらです。

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

Raspberry PiでDockerを動かす

DockerCon19にてDockerのARM対応が話されていたので、ラズパイ向けのイメージをMacでクロスコンパイルして見ることにしました。
ちなみに、元々ARM自体には対応していましたが今回のカンファレンスの話だとクロスコンパイルとDockerHubでのマルチアーキテクチャ対応がメインかと思います。

Raspberry PiにDockerをインストール

まずは、ラズパイにDockerをインストールします。
Raspbianを使ってるのでこちらに記載がある通りapt-getで入れます。

$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
$ docker -v
Docker version 18.09.0, build 4d60db4

ラズパイ側の準備はこれで完了です。

Docker Desktop(β)のインストール

19.03.0からバックエンドでqemuを利用してMacでもlinux/amd64のみならずlinux/arm/v7linux/arm64、さらにはwindows/amd64がビルドできるようになりました。
ただし、19.03はまだベータ版なので、以下のURLからDocker Desktop for Mac Communityのベータ版を入れる必要があります。

https://beta.docker.com/

$ docker -v
Docker version 19.03.0-beta3, build c55e026

上記のように19.03がインストールされていれば成功です。

Dockerfileの作成

Dockerfileの作成をします。なんでも良いのですが、以前作った「Raspberry PIでデスクトップ環境無しでChromiumを起動する」の内容をDockerイメージにしてみます。

FROM debian:buster

RUN apt-get update && \
    apt-get install -y xinit matchbox-window-manager xterm chromium && \
    apt-get -y --purge autoremove && \
    rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY run.sh /app/run.sh
CMD ["./run.sh"]

run.shは以下の通り。

#!/bin/sh

xinit matchbox-window-manager &
chromium --no-sandbox -kiosk "http://www.youtube.com"

Raspbianを使う必要はないので普通にDebianを使用しています。
重要なのはDockerHubの公式を見れば分かると思うのですがこの公式イメージがArmに対応しているということです。

001.png

Dockerは実行環境または指定されたオプションに従って適切なCPUアーキテクチャのイメージを落とします。
Dockerfile内でapt-get等もしていますがこれも元イメージが同じなので特に意識することなくx86とARMが切り替わります。
これによって動作確認は高速なx86で行って同じDockefileを編集なしにARM版のモジュールを作成することができます。

ARMイメージのビルド

ではARM版のビルドを行います。具体的には--platformを指定します。

$ docker buildx build -t koduki/rpi-chrome --platform linux/arm/v7 --push .

開発版のbuildkitの機能を使うためにbuildxを指定しています。また、ラズパイはarmv7なのでlinux/arm/v7をplatformに指定しています。

詳細に関しては下記を参照してください。
https://github.com/docker/buildx#building-multi-platform-images

今回はlinux/arm/v7しか指定していませんが、マルチプラットフォームのイメージを作りたい場合は下記のようにDriverをdocker-containerに変更し、,で区切ることで複数モジュールのビルド/Pushができるようになります。

$ docker buildx create --driver docker-container --name multibuild
$ docker buildx use multibuild
$ docker buildx build -t koduki/rpi-chrome --platform linux/amd64,linux/arm/v7 --push .

Raspberry Piでコンテナを実行する

実行するに当たって特に特別な事はありませんがラズパイ上で実行してみます。

$ docker run -it koduki/rpi-chrome uname -a
Linux cd4a0c8248fb 4.14.98-v7+ #1200 SMP Tue Feb 12 20:27:48 GMT 2019 armv7l GNU/Linux

通常通りDockerHubから落として実行されます。この時にARM向けのモジュールを登録しておけば適切に選択され上記のように実行されますあ、arm64とかamd64とかしか登録してないと当然実行時にエラーになるのでご注意ください。

では、Chromeを起動してみましょう。

$ docker run -it -e DISPLAY=:0 --privileged koduki/rpi-chrome

少しサボってprivilegedを渡しています。これはGPUを叩くためです。
また、同じく:0をDISPLAYとして環境変数に渡しています。

まとめ

「ラズパイでDocker動かしてなんの意味あるの?」と言われそうですがデプロイの管理がやはり楽になります。Dockerで配布して終わりになるので。ラズパイ側でaptとか不要!
あと、ラズパイ側が究極的にはかなり薄くできるのでIoT的にも良いんじゃないかと。

19.03.0はビルドが高速化されたり今回のクロスプラットフォームビルドなど、かなり新機能が盛りだくさんなのでもうちょっと追っていきたいと思います。
それではHappy Hacking!

参考

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

MAMP上でsimpleSAMLphpのSPとIdPを構築する

はじめに

MAMPとは何か、等については次節のリンクで説明しているので割愛します。simpleSAMLphpは簡単に言うとシングルサインオンを実装するためのオープンソースソフトウェアです。ネットに転がっているサイトではだいたいVMを使って実装されておりMAMPを使った実装は見かけたことがなかったこと、およびSPとIdP両方についてひとつのサイトで説明しているものが少ないことから記事にしてみました。

わざわざ当サイトを見に来るような人はおそらくsimpleSAMLphpやSP・IdPといった知識は十二分に持っていらっしゃると思ったので説明ははしょっています。

環境
OS:macOS Mojave(バージョン10.14.1)
MAMP:Version 5.3(367)
PHP:Version 7.3.1
SimpleSAMLphp:Version 1.17.2

※MAMPのApacheのバージョンはどこから確認できるかわかりませんでした…。わかりましたら追記いたします。

MAMPのWebサーバー構築

下記記事参照
https://qiita.com/come340/items/6cb175918075f398a41a

simpleSAMLphpのインストール

https://simplesamlphp.org/download
から最新のものをダウンロード
VMならwgetコマンドを使うといいけれど今回はMAMP(すなわちMacOS上)でやるので普通にダウンロードします。

ダウンロードしたtarファイル(simplesamlphp-X.X.X.tar.gz)は/Applications/MAMP/htdocsに置いて展開します。

筆者は複数のSPおよびIdPを構築したかったのでとりあえず展開したファイルは置いておいてSP・IdPごとにコピーしました。

simpleSAMLphpの設定

ここはSP・IdPともに同様の設定を行うので、とりあえずSPについて説明します。
先に展開したsimplesSAMLphpのファイルをコピーしてsaml_sp1と名前をつけました。(これは何でもいいです。)

複数のローカルホストをたてられるように設定変更

/Applications/MAMP/apache/httpd.confを編集

httpd.conf
# Virtual hosts
#Include /Applications/MAMP/conf/apache/extra/httpd-vhosts.conf

からコメントアウトを削除。

httpd.conf
# Virtual hosts
Include /Applications/MAMP/conf/apache/extra/httpd-vhosts.conf

ローカルホストの設定

/Applications/MAMP/conf/apache/extra/httpd-vhost.confを編集
最終行の後に追加して以下を記述

httpd-vhost.conf
# SimpleSAMLphp SP1
Listen 8001
<VirtualHost *:8001>
    SetEnv SIMPLESAMLPHP_CONFIG_DIR /Applications/MAMP/htdocs/saml_sp1/config

    DocumentRoot "/Applications/MAMP/htdocs/saml_sp1/www"
    ServerName saml_sp1.local:8001
    Alias /simplesaml "/Applications/MAMP/htdocs/saml_sp1/www"

    <Directory "/Applications/MAMP/htdocs/saml_sp1/www">
            <IfModule mod_authz_core.c>
            # For Apache 2.4:
            Require all granted
            AllowOverride All
            </IfModule>
    </Directory>
</VirtualHost>

8001はポート番号、設定したいローカルホストごとに異なる番号を振り分けるとよいです。
simpleSAMLphpの設定について調べているといろんなサイトで似たような設定の仕方が記述されていますが、コピペしないでちゃんと自分のホストとの整合性を確認したほうがいいと思います。チェックすべきポイントは

  • SetEnv
  • DocumentRoot
  • Alias
  • <Directory "">

あたりだと思います。Aliasは詳しくは説明しませんが/simplesamlの所だけは変えてしまうとうまくいかないのでそのままにしましょう。

ここまで設定できたらMAMPのStop ServersおよびStart Serversを押してサーバーを再起動のち、ブラウザに"localhost:8001"を入力してみたら以下のようなページが表示されるはずです。

スクリーンショット 2019-05-02 15.34.28.png

adminユーザパスワード設定

これは下記記事を参考に
https://qiita.com/haya43/items/c74d2710cd9b57d2cbb4

/Applications/MAMP/htdocs/saml_sp1/config/config.phpを編集

config.php
'auth.adminpassword' => 'test',

シークレットソルトを設定。下記コマンドでランダム文字列を生成。

tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' </dev/urandom | dd bs=32 count=1 2>/dev/null;echo

VMで動かしたときはこれでよかったのですが、Macのターミナルではtr: Illegal byte sequenceというエラーを吐いてうまくいかなかったので調べてみたところ、以下コマンドでうまくいきました。

LC_CTYPE=C tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' </dev/urandom | dd bs=32 count=1 2>/dev/null;echo

生成した文字列をコピーしてconfig.phpをさらに編集

config.php
'secretsalt' => '(生成した文字列)',

再びlocalhost:8001にブラウザからアクセスして管理者でログインできるか確認しましょう。

IdPの設定

筆者はIdPのポート番号は8011にしています。上記の設定で利用していたファイル名saml_sp1に当たるものはsaml_idp1としています。ブラウザから見るときはlocalhost:8011でアクセスします。

saml20-idpを有効化する

config.php
'enable.saml20-idp' => true,

SimpleSAMLphp設定ページの設定タブでSAML 2.0 IdPに緑のチェックマークがついているか確認しましょう。

自己証明書を作る

cdコマンドで/Applications/MAMP/htdocs/saml_idp1/cert配下に行きます。
以下コマンドで証明書を作成。

openssl req -newkey rsa:2048 -new -x509 -days 3652 -nodes -out server.crt -keyout server.pem

いろいろ聞かれますが、以下のように答えます。割と適当なので問題あればご指摘ください。

Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Tokyo
Locality Name (eg, city) []:(空白)
Organization Name (eg, company) [Internet Widgits Pty Ltd]:(空白)
Organizational Unit Name (eg, section) []:(空白)
Common Name (e.g. server FQDN or YOUR name) []:saml_idp1.local
Email Address []:(空白)

これで/cert配下にserver.crtとserver.pemが作成されます。一応lsコマンドで確認するといいです。デフォルトの設定でserver.crtとserver.pemというものが書かれているはずなのでその他のファイルは編集せずこのまま使えます。
もし異なる名称で作成した場合、metadata/saml20-idp-hosted.phpを編集します。

saml20-idp-hosted.php
    'privatekey' => '(設定した名称).pem',
    'certificate' => '(設定した名称).crt',

SPの設定

SPでもサーバー証明書を作成

/Applications/MAMP/htdocs/saml_sp1/certに移動して以下コマンド実行。あんまり意味があるかわかりませんが出力ファイルの名称をsaml_sp1.local.crt、saml_sp1.local.pemのように変えています。

openssl req -newkey rsa:2048 -new -x509 -days 3652 -nodes -out saml_sp1.local.crt -keyout saml_sp1.local.pem

IdPの設定時と同様に質問に答えていきます。Common Nameだけはsaml_sp1.localに変えておきます。

/Applications/MAMP/htdocs/saml_sp1/config/authsources.phpを編集

authsources.php
 'default-sp' => [
        'saml:SP',

        'privatekey' => 'saml_sp1.local.pem', # 追記
        'certificate' => 'saml_sp1.local.crt', # 追記

        // The entity ID of this SP.
        // Can be NULL/unset, in which case an entity ID is generated based on the metadata URL.
        'entityID' => 'http://localhost:8001', # 変更

        // The entity ID of the IdP this SP should contact.
        // Can be NULL/unset, in which case the user will be shown a list of available IdPs.
        'idp' => 'http://localhost:8011/simplesaml/saml2/idp/metadata.php', # 変更

        // The URL to the discovery service.
        // Can be NULL/unset, in which case a builtin discovery service will be used.

(以下省略)

entityIDは設定しているSPへのアクセスに利用しているURLに当たるもの(?)を、idpはIdPのエンティティIDを入力します。エンティティIDはIdP側のSimpleSAMLの設定ページの連携タブにある、SAML2.0 IdPメタデータの欄にあるEntity IDを入力しています。privatekeyとcertificateの欄はデフォルトでは書いていないので自分で追記します。

IdP・SPのメタデータ登録

IdPのメタデータをSPに登録

IdPの設定ページで'連携'タブを開き、SAML 2.0 IdPメタデータの欄から'メタデータを表示'を押してもらうと以下のような画面が表示されます。
スクリーンショット 2019-05-03 13.02.20.png
このメタデータXMLフォーマットをコピーして、今度はSPの設定ページに行きます。(IdPのページでもできる気がしますがなんとなくその方が良さそうなのでSP側でやります。)
'連携'タブを開いてツールの'XMLをSimpleSAMLphpメタデータに変換'をクリック。メタデータパーザの入力枠内に先程コピーしたXMLデータを入力し'パース'ボタンを押します。するとXMLフォーマットをSimpleSAMLphpのメタデータフォーマットに変換してくれるので再びコピー。

次に、/saml_sp1/metadata/saml20-idp-remote.phpを編集。先程コピーしたものをそのままペーストすれば良いです。

saml20-idp-remote.php
<?php
/**
 * SAML 2.0 remote IdP metadata for SimpleSAMLphp.
 *
 * Remember to remove the IdPs you don't use from this file.
 *
 * See: https://simplesamlphp.org/docs/stable/simplesamlphp-reference-idp-remote
 */

$metadata['http://localhost:8011/simplesaml/saml2/idp/metadata.php'] = array (
  'entityid' => 'http://localhost:8011/simplesaml/saml2/idp/metadata.php',
  'contacts' =>
  array (
  ),
  'metadata-set' => 'saml20-idp-remote',
  'SingleSignOnService' =>
  array (
    0 =>
    array (
      'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
      'Location' => 'http://localhost:8011/simplesaml/saml2/idp/SSOService.php',
    ),
  ),
(以下省略)

'<?php'のPHPタグをつけるのを忘れずに。(筆者は忘れていてエラーを吐かれました)

SPのメタデータをIdPに設定

SPへの設定と同様に、SPのXMLメタデータを変換しコピーします。こちらでは変換されたメタデータが'shib13-sp-remote'と'saml20-sp-remote'の二種類出てくるのでここでは後者を使用します。
/saml_idp1/metadata/saml20-sp-remote.phpを編集します。こちらも先程と同様にコピーしたものをそのままペーストします。PHPタグも忘れずに。

saml20-sp-remote.php
<?php
$metadata['http://localhost:8001'] = array (
  'entityid' => 'http://localhost:8001',
  'contacts' =>
  array (
  ),
  'metadata-set' => 'saml20-sp-remote',
  'AssertionConsumerService' =>
  array (
    0 =>
    array (
      'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
      'Location' => 'http://localhost:8001/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp',
      'index' => 0,
    ),
    1 =>
    array (
      'Binding' => 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post',
      'Location' => 'http://localhost:8001/simplesaml/module.php/saml/sp/saml1-acs.php/default-sp',
      'index' => 1,
    ),
(以下省略)

IdPの設定ではさらに、認証モジュールの設定をします。詳しくは公式文書の3番を読んでください。
https://simplesamlphp.org/docs/stable/simplesamlphp-idp
今回はこの例にならってexampleauthモジュールを使用します。

・モジュールの有効化

cd /Applications/MAMP/htdocs/saml_idp1/
touch modules/exampleauth/enable

・/saml_idp1/config/authsources.phpを編集
以下のユニット前後のコメントアウト(/*, */)を削除

authsources.php
'example-userpass' => [
        'exampleauth:UserPass',

        // Give the user an option to save their username for future login attempts
        // And when enabled, what should the default be, to save the username or not
        //'remember.username.enabled' => false,
        //'remember.username.checked' => false,

        'student:studentpass' => [
            'uid' => ['test'],
            'eduPersonAffiliation' => ['member', 'student'],
        ],
        'employee:employeepass' => [
            'uid' => ['employee'],
            'eduPersonAffiliation' => ['member', 'employee'],
        ],
    ],

これで、IdPにユーザが登録されます。studentユーザはユーザID'test'、パスワード'studentpass'で、employeeユーザはユーザID'employee'、パスワード'employeepass'でログインできるようになります。

接続テスト

SP側のテスト

SP側の設定ページで'認証'タブを開いて'設定されている認証元をテスト'をクリック。default-spを選択してユーザ名、パスワードを入力。うまくいけば以下のような画面が表示されます。
スクリーンショット 2019-05-03 13.31.43.png

IdP側のテスト

SP同様に'設定されている認証元をテスト'をクリック。default-spまたはexample-userpassを選択するとSP側同様の画面が表示されます。

終わりに

書きたいことを全部まとめて書いてしまったため長くなってしまいましたが、とりあえずここまででなんとなくSPとIdPを動かせるようになると思います。筆者自身MAMPもシングルサインオンもド初心者ですのでなにか問題がありましたらご指摘いただけると幸いです。実際の運用についても今後追記できたらいいなと思っております。

本記事の投稿に当たって以下のサイトを参考にさせていただきました。
https://suer.hatenablog.com/entry/2015/11/20/141941

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

kubectlで「Unable to connect to the server」

Docker for Macで以前インストールしたKubernetesでクラスタ情報を取得しようとしたら

$ kubectl cluster-info
Kubernetes master is running at https://localhost:6443

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
Unable to connect to the server: EOF

というエラーが発生した。また、Docker for Macのメニューから「Preferences」で設定画面を開くと、以下のキャプチャのようにKubernetes is startingのままrunningの状態に遷移しなかった。

スクリーンショット 2019-05-03 10.07.08.png

以下のキャプチャようにDocker for Macの設定画面から利用できるリソースの上限を変更して、数分待ったら、Kubernetes is runningの状態に遷移した。

スクリーンショット 2019-05-03 11.24.27.png

参考

[helm] elasticsearchをinstallしたらkubectlが「Unable to connect to the server:」しか返さなくなった

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