ためすう
kubesec を使ってみる (kubernetes)
2021-01-03やったこと
Secret リソースを暗号化するため、kubesec を使ってみます。
確認環境
$ k version
Client Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.2", GitCommit:"c97fe5036ef3df2967d086711e6c0c405941e14b", GitTreeState:"clean", BuildDate:"2019-10-15T19:18:23Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3", GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"clean", BuildDate:"2020-10-14T12:41:49Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}
調査
インストール
kubesec のインストール
$ curl -sSL https://github.com/shyiko/kubesec/releases/download/0.9.2/kubesec-0.9.2-darwin-amd64 \
> -o kubesec && chmod a+x kubesec && sudo mv kubesec /usr/local/bin/
Password:
$ kubesec --version
0.9.2
gpg のインストール
$ brew install gpg
$ gpg --version
gpg (GnuPG) 2.2.25
libgcrypt 1.8.7
(省略)
暗号化
secret-hoge.yaml
apiVersion: v1
kind: Secret
metadata:
name: first-kubesec
type: Opaque
data:
AAA: MTIz
BBB: NDU2
CCC: YWJj
$ gpg --gen-key
pub rsa3072 2020-12-27 [SC] [有効期限: 2022-12-27]
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
※ 鍵はxに変換してあります。
標準出力
$ kubesec encrypt --key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx secret-hoge.yaml
ファイル書き換え
$ kubesec encrypt -i --key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx secret-hoge.yaml
※ 出力結果は省略します。
復号化
$ kubesec decrypt secret-hoge.yaml
apiVersion: v1
data:
AAA: MTIz
BBB: NDU2
CCC: YWJj
kind: Secret
metadata:
name: first-kubesec
type: Opaque
参考
ServiceのClusterIPを使ってみる (kubernetes)
2021-01-03やったこと
Service の ClusterIP を使ってみます。
確認環境
$ k version
Client Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.2", GitCommit:"c97fe5036ef3df2967d086711e6c0c405941e14b", GitTreeState:"clean", BuildDate:"2019-10-15T19:18:23Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3", GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"clean", BuildDate:"2020-10-14T12:41:49Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}
調査
first-cluster-ip.yaml
apiVersion: v1
kind: Service
metadata:
name: my-cluster-ip
spec:
type: ClusterIP
ports:
- name: "hoge"
protocol: "TCP"
port: 8080
targetPort: 80
selector:
app: sample5
sample5.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
replicas: 3
selector:
matchLabels:
app: sample5
template:
metadata:
labels:
app: sample5
spec:
containers:
- name: nginx-container
image: nginx:1.17
$ k apply -f sample5.yaml -f first-cluster-ip.yaml
deployment.apps/my-deployment created
service/my-cluster-ip created
$ k get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-deployment-5f9fb9cfc8-69w6v 1/1 Running 0 24s 10.1.0.221 docker-desktop <none> <none>
my-deployment-5f9fb9cfc8-c25mg 1/1 Running 0 24s 10.1.0.223 docker-desktop <none> <none>
my-deployment-5f9fb9cfc8-m5qnk 1/1 Running 0 24s 10.1.0.222 docker-desktop <none> <none>
$ k get service my-cluster-ip
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-cluster-ip ClusterIP 10.109.253.129 <none> 8080/TCP 6m32s
※ 同じクラスタ内のコンテナからアクセス
$ curl -v http://10.109.253.129:8080
何回かアクセスを繰り返すと、アクセスが振り分けられていることが分かります。
$ k logs -f my-deployment-5f9fb9cfc8-69w6v
10.1.0.1 - - [28/Dec/2020:16:10:22 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.0" "-"
10.1.0.1 - - [28/Dec/2020:16:17:02 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.0" "-"
10.1.0.1 - - [28/Dec/2020:16:17:04 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.0" "-"
$ k logs -f my-deployment-5f9fb9cfc8-c25mg
10.1.0.1 - - [28/Dec/2020:16:04:48 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.0" "-"
10.1.0.1 - - [28/Dec/2020:16:10:27 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.0" "-"
10.1.0.1 - - [28/Dec/2020:16:11:02 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.0" "-"
10.1.0.1 - - [28/Dec/2020:16:17:06 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.0" "-"
$ k logs -f my-deployment-5f9fb9cfc8-m5qnk
10.1.0.1 - - [28/Dec/2020:16:04:38 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.0" "-"
10.1.0.1 - - [28/Dec/2020:16:17:03 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.0" "-"
参考
ConfigMap を使ってみる (kubernetes)
2021-01-02やったこと
ConfigMap を使ってみます。
確認環境
$ k version
Client Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.2", GitCommit:"c97fe5036ef3df2967d086711e6c0c405941e14b", GitTreeState:"clean", BuildDate:"2019-10-15T19:18:23Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3", GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"clean", BuildDate:"2020-10-14T12:41:49Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}
調査
今回は Volume マウントを使って情報を渡します。
ConfigMap の作成
hoge.yaml
aaa:
bbb: 999
ccc:
ddd: 888
$ k create configmap --save-config my-configmap --from-file=hoge.yaml
configmap/my-configmap created
$ k get cm
NAME DATA AGE
my-configmap 1 32s
Pod に Volume マウントしてファイルを渡す
sample3.yaml
apiVersion: v1
kind: Pod
metadata:
name: first-configmap
spec:
containers:
- name: nginx-container
image: nginx:1.17
volumeMounts:
- name: my-tmp-volume
mountPath: /tmp
volumes:
- name: my-tmp-volume
configMap:
name: my-configmap
items:
- key: hoge.yaml
path: hoge_new.yaml
$ k apply -f sample3.yaml
pod/first-configmap created
$ k get pod
NAME READY STATUS RESTARTS AGE
first-configmap 1/1 Running 0 5s
コンテナからファイルを読み込む。
$ k exec -it first-configmap -- cat /tmp/hoge_new.yaml
aaa:
bbb: 999
ccc:
ddd: 888
環境変数を使ってみる (kubernetes)
2021-01-01やったこと
環境変数をコンテナに渡してみます。
確認環境
$ k version
Client Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.2", GitCommit:"c97fe5036ef3df2967d086711e6c0c405941e14b", GitTreeState:"clean", BuildDate:"2019-10-15T19:18:23Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3", GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"clean", BuildDate:"2020-10-14T12:41:49Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}
調査
sample.yaml
apiVersion: v1
kind: Pod
metadata:
name: first-env
spec:
containers:
- name: nginx-container
image: nginx:1.17
env:
- name: MY_GREETING
value: "Warm greetings to"
- name: MY_MEM_REQUEST
valueFrom:
resourceFieldRef:
containerName: nginx-container
resource: requests.memory
マニフェストの適用 + 環境変数の確認
$ k apply -f sample.yaml
pod/first-env created
$ k exec -it first-env -- env | grep "MY_"
MY_GREETING=Warm greetings to
MY_MEM_REQUEST=0
参考
Job を使ってみる (kubernetes)
2021-01-01やったこと
Job を使ってみます。
確認環境
$ k version
Client Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.2", GitCommit:"c97fe5036ef3df2967d086711e6c0c405941e14b", GitTreeState:"clean", BuildDate:"2019-10-15T19:18:23Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3", GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"clean", BuildDate:"2020-10-14T12:41:49Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}
調査
job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(20)"]
restartPolicy: Never
backoffLimit: 4
parallelism: 3
completions: 10
$ k apply -f job.yaml
job.batch/pi created
$ k get pods --watch
NAME READY STATUS RESTARTS AGE
pi-7x8sv 0/1 ContainerCreating 0 6s
pi-k6mxv 0/1 ContainerCreating 0 6s
pi-tg6cx 0/1 ContainerCreating 0 6s
pi-7x8sv 0/1 Completed 0 108s
pi-8gbgj 0/1 Pending 0 0s
pi-8gbgj 0/1 Pending 0 0s
pi-8gbgj 0/1 ContainerCreating 0 0s
pi-k6mxv 0/1 Completed 0 110s
pi-dtbll 0/1 Pending 0 0s
pi-dtbll 0/1 Pending 0 0s
pi-dtbll 0/1 ContainerCreating 0 0s
pi-tg6cx 0/1 Completed 0 119s
pi-cl6fx 0/1 Pending 0 0s
pi-cl6fx 0/1 Pending 0 0s
pi-cl6fx 0/1 ContainerCreating 0 0s
pi-8gbgj 0/1 Completed 0 17s
... (省略)
Job 終了後の結果
$ k get jobs
NAME COMPLETIONS DURATION AGE
pi 10/10 2m34s 11m
参考
tcpdump を使ってみる (Unix)
2020-12-31やったこと
man tcpdump
より抜粋
tcpdump - dump traffic on a network
調査
前準備
詳細手順は省きます。webサーバーを用意します。
Webブラウザから何度かアクセス
# tcpdump port 80 -n -s 0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
10:40:39.662780 IP 172.26.0.1.35166 > 172.26.0.2.80: Flags [P.], seq 3330495538:3330495993, ack 2594564324, win 501, options [nop,nop,TS val 1108626414 ecr 3836588442], length 455: HTTP: GET / HTTP/1.1
10:40:39.663229 IP 172.26.0.2.80 > 172.26.0.1.35166: Flags [P.], seq 1:181, ack 455, win 501, options [nop,nop,TS val 3836620070 ecr 1108626414], length 180: HTTP: HTTP/1.1 304 Not Modified
10:40:39.663375 IP 172.26.0.1.35166 > 172.26.0.2.80: Flags [.], ack 181, win 501, options [nop,nop,TS val 1108626415 ecr 3836620070], length 0
pcap に書き出して、 Wireshark でみる
# tcpdump port 80 -n -s 0 -w hoge.pcap
hoge.pcap を TCPストリームで確認した例
GET / HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:83.0) Gecko/20100101 Firefox/83.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: ja,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1
If-Modified-Since: Tue, 15 Dec 2020 13:59:38 GMT
If-None-Match: "11111111-264"
Cache-Control: max-age=0
HTTP/1.1 304 Not Modified
Server: nginx/1.19.6
Date: Tue, 29 Dec 2020 10:49:14 GMT
Last-Modified: Tue, 15 Dec 2020 13:59:38 GMT
Connection: keep-alive
If-None-Match: "11111111-264"
おまけ
利用したオプション
-n Don't convert addresses (i.e., host addresses, port numbers, etc.) to names.
-w file
Write the raw packets to file rather than parsing and printing them out. They can later be printed with the -r option. Standard output is used if file is ``-''.
-s snaplen
StatefulSet を使ってみる (kubernetes)
2020-12-31やったこと
StatefulSet を使ってみます。
確認環境
$ k version
Client Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.2", GitCommit:"c97fe5036ef3df2967d086711e6c0c405941e14b", GitTreeState:"clean", BuildDate:"2019-10-15T19:18:23Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3", GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"clean", BuildDate:"2020-10-14T12:41:49Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}
調査
StatefulSetは下記の1つ以上の項目を要求するアプリケーションにおいて最適です。
- 安定した一意のネットワーク識別子
- 安定した永続ストレージ
- 規則的で安全なデプロイとスケーリング
- 規則的で自動化されたローリングアップデート
first-stateful.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: my-statefulset
spec:
serviceName: nginx
replicas: 2 # by default is 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx # .spec.selector.matchLabelsの値と一致する必要があります
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx-container
image: nginx:1.17
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes:
- ReadWriteOnce
storageClassName: "my-storage-class"
resources:
requests:
storage: 1Gi
$ k apply -f first-stateful.yaml
statefulset.apps/my-statefulset created
$ k get statefulsets
NAME READY AGE
my-statefulset 2/2 12m
$ k get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-statefulset-0 1/1 Running 0 11m 10.1.0.180 docker-desktop <none> <none>
my-statefulset-1 1/1 Running 0 11m 10.1.0.181 docker-desktop <none> <none>
$ k get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-0ec2bcbb-1a20-46b0-8930-5fe48601a180 1Gi RWO Delete Bound default/www-my-statefulset-1 hostpath 12m
pvc-dc6cf56f-2e32-4d53-ad5e-9fa0fd9bc365 1Gi RWO Delete Bound default/www-my-statefulset-0 hostpath 12m
$ k get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
www-my-statefulset-0 Bound pvc-dc6cf56f-2e32-4d53-ad5e-9fa0fd9bc365 1Gi RWO hostpath 12m
www-my-statefulset-1 Bound pvc-0ec2bcbb-1a20-46b0-8930-5fe48601a180 1Gi RWO hostpath 12m
永続ボリュームの動作を確認
# ファイルを設置する
$ k exec -it my-statefulset-0 -- ls /usr/share/nginx/html
$ k exec -it my-statefulset-0 -- touch /usr/share/nginx/html/hoge
$ k exec -it my-statefulset-0 -- ls /usr/share/nginx/html
hoge
# Pod を削除する
$ k delete pod my-statefulset-0
pod "my-statefulset-0" deleted
$ k get pods
NAME READY STATUS RESTARTS AGE
my-statefulset-0 1/1 Running 0 47s
my-statefulset-1 1/1 Running 0 16m
# my-statefulset-0 でファイルがあることを確認する
$ k exec -it my-statefulset-0 -- ls /usr/share/nginx/html
hoge
参考
DaemonSet を使ってみる (kubernetes)
2020-12-30やったこと
DaemonSet を使ってみます。
確認環境
$ k version
Client Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.2", GitCommit:"c97fe5036ef3df2967d086711e6c0c405941e14b", GitTreeState:"clean", BuildDate:"2019-10-15T19:18:23Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3", GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"clean", BuildDate:"2020-10-14T12:41:49Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}
調査
DaemonSet は全て(またはいくつか)のNodeが単一のPodのコピーを稼働させることを保証します。
sample4.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: my-daemon-first
spec:
selector:
matchLabels:
app: sample4
template:
metadata:
labels:
app: sample4
spec:
containers:
- name: nginx-container
image: nginx:1.16
マニフェストの適用
$ k apply -f sample4.yaml
daemonset.apps/my-daemon-first created
$ k get pods
NAME READY STATUS RESTARTS AGE
my-daemon-first-fghkd 1/1 Running 0 22s
$ k get ds
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
my-daemon-first 1 1 1 1 1 <none> 11m
$ k get pods
NAME READY STATUS RESTARTS AGE
my-daemon-first-fghkd 1/1 Running 0 59s
sample4.yaml を編集します。
image: nginx:1.17
更新を適用する
$ k apply -f sample4.yaml
daemonset.apps/my-daemon-first configured
$ k get ds
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
my-daemon-first 1 1 1 0 1 <none> 12m
$ k get pods
NAME READY STATUS RESTARTS AGE
my-daemon-first-fghkd 1/1 Terminating 0 114s
// しばらくした後
$ k get pods
NAME READY STATUS RESTARTS AGE
my-daemon-first-nnfnm 1/1 Running 0 35s
更新戦略
$ k get ds -o jsonpath="{.items[0].spec.updateStrategy}"
map[rollingUpdate:map[maxUnavailable:1]
maxUnavailable=1 より、Terminateされてから新しいPodが起動したことが分かります。
参考
strings を使ってみる (Unix)
2020-12-30やったこと
strings
を使ってみます。
man strings
より抜粋
NAME strings - find the printable strings in a object, or other binary, file
オブジェクトや、バイナリ、ファイルから、表示できる文字を表示してくれます。
調査
ls コマンドのバイナリを引数に渡してみます。
ファイル判別
$ file /bin/ls
/bin/ls: Mach-O 64-bit executable x86_64
strings 実行
$ strings /bin/ls
$FreeBSD: src/bin/ls/cmp.c,v 1.12 2002/06/30 05:13:54 obrien Exp $
@(#) Copyright (c) 1989, 1993, 1994
The Regents of the University of California. All rights reserved.
$FreeBSD: src/bin/ls/ls.c,v 1.66 2002/09/21 01:28:36 wollman Exp $
(省略)
sortをする (Go)
2020-12-29やったこと
Goでsortパッケージを使ってみます。
調査
package main
import (
"fmt"
"runtime"
"sort"
)
func main() {
fmt.Println("確認環境: ", runtime.Version())
people := []struct {
Name string
Age int
}{
{"Gopher", 7},
{"Alice", 55},
{"Vera", 24},
{"Bob", 75},
}
sort.Slice(people, func(i, j int) bool { return people[i].Age < people[j].Age })
fmt.Println("By age 昇順:", people)
sort.Slice(people, func(i, j int) bool { return people[i].Age > people[j].Age })
fmt.Println("By age 降順:", people)
p := []int {7, 55, 24, 75}
sort.Slice(p, func(i, j int) bool { return p[i] < p[j] })
fmt.Println(p)
}
出力結果
確認環境: go1.15.6
By age 昇順: [{Gopher 7} {Vera 24} {Alice 55} {Bob 75}]
By age 降順: [{Bob 75} {Alice 55} {Vera 24} {Gopher 7}]
[7 24 55 75]