docker-composeでK3sを試してみた

# K3s を試すログ兼メモ

## docker-composeで立ち上げ

```docker-compose.yaml
version: '3'
services:
  k3s_1:
    image: rancher/k3s:v0.2.0-amd64
    environment:
      TZ: Asia/Tokyo
```

→ エラー出ました。

```console
Creating k3s-test_k3s_1_1 ... done
Attaching to  k3s-test_k3s_1_1
k3s_1_1  | time="2019-03-15T01:04:42.032302900Z" level=fatal msg="--token is required"
k3s-test_k3s_1_1 exited with code 1
```

トークンを渡す必要があるみたいですね。

## ちゃんと公式を確認する
そのものがありました。ただし、バージョンが0.1.0で、古い。
https://github.com/rancher/k3s/blob/master/docker-compose.yml

```docker-compose.yaml
version: '3'
services:
  k3s_master:
    image: rancher/k3s:v0.2.0-amd64
    command:
      - server
      - --disable-agent
    environment:
      TZ: Asia/Tokyo
      K3S_CLUSTER_SECRET: somethingtotallyrandom
      K3S_KUBECONFIG_OUTPUT: /output/kubeconfig.yaml
      K3S_KUBECONFIG_MODE: 666
    volumes:
      - k3s-server:/var/lib/rancher/k3s
      - .:/output
    expose:
      - '6443'
    ports:
      - '6443:6443'
  k3s_node:
    image: rancher/k3s:v0.2.0-amd64
    tmpfs:
      - /run
      - /var/run
    privileged: true
    command:
      - agent
    environment:
      TZ: Asia/Tokyo
      K3S_URL: https://k3s_master:6443
      K3S_CLUSTER_SECRET: somethingtotallyrandom
volumes:
  k3s-server: {}
```
これで、 `docker-compose up`してあげたら、何となくたちあがってきたっぽい。よしよし。

つまづきポイントとしては、Docker for MacでKubernetesを有効にしてたので、ポートが干渉してしまったぐらいですかね。

カレントディレクトリに、kubeconfig.yamlが吐き出されているので、この情報を使ってローカルのk3sに接続できます。
K8sであることには変わらないので、ちゃんと設定してあげれば通常のkubectlでも使えます。

serviceを3つに増やして、ノードを取得してみたらこんな感じに。

```console
$ kubectl get nodes
NAME           STATUS   ROLES    AGE    VERSION
0b161bf99dc6   Ready    <none>   4m3s   v1.13.4-k3s.1
4b6046ba72b5   Ready    <none>   4m3s   v1.13.4-k3s.1
af38d79798ed   Ready    <none>   4m3s   v1.13.4-k3s.1
```

## デプロイしてみる
nginxがデプロイできるか試します。

```manifest.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.3-alpine
        ports:
        - containerPort: 80
```

これを、`kubectl apply -f manifest.yaml` でデプロイすると、

```console
$ kubectl get pods
NAME                           READY   STATUS    RESTARTS   AGE
nginx-6c7b58b644-cvzsl         1/1     Running   0          15m
nginx-6c7b58b644-sgbb7         1/1     Running   0          15m
```

こんな感じになりました。どっちもRunningですね。動いていそうな雰囲気。

## 動作確認

クラスタにポートフォワードして、Podにアクセスします。

`kubectl port-forward pod/nginx-6c7b58b644-sgbb7 30080:80`
 
これで、 `http://127.0.0.1:30080` にアクセスすると。。。

<img width="593" alt="スクリーンショット 2019-03-15 11.59.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/77225/2584fb39-b8fa-9fa0-7c24-58b52c795e00.png">

```console
$ stern '.*'
+ nginx-6c7b58b644-cvzsl › nginx
+ nginx-6c7b58b644-sgbb7 › nginx
nginx-6c7b58b644-sgbb7 nginx 127.0.0.1 - - [15/Mar/2019:02:55:49 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" "-"
```

という感じで、ちゃんと動いてますね。

## サービスを通してアクセスしてみる(ClusterIP)

今度は、サービスを作って、それ経由でアクセスしてみます。

以下を追記して、`kubectl apply -f manifest.yaml`を実行します。

```manifest.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
    - name: http
      port: 80
```

```console
$ kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)        AGE
kubernetes   ClusterIP      10.43.0.1       <none>         443/TCP        165m
nginx        ClusterIP      10.43.255.247   <none>         80/TCP         11m
```
できてますね。


`kubectl port-forward service/nginx 30080:80`で、サービスに対してポートフォワードをします。

これで、 `http://127.0.0.1:30080` にアクセスすると。。。

```console
$ stern '.*'
+ nginx-6c7b58b644-cvzsl › nginx
+ nginx-6c7b58b644-sgbb7 › nginx
nginx-6c7b58b644-sgbb7 nginx 127.0.0.1 - - [15/Mar/2019:04:53:07 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" "-"
```

ということで、アクセスできました。

**要確認** ところが、何度アクセスしてもアクセスがもう一個のnginxに振り分けられないので、なんでだっけ、という感じです。確か、GKEではClusterIPでも分散されていたと思うんだけど...。
ExternalIPを振らないで作るLoadBalancerの話だったかもしれない。。。

## サービスを通してアクセスしてみる(LoadBalancer)

今度は、ロードバランサにしてみます。

```manifest.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-lb
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
    - name: http
      port: 80
```

```console
$ kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)        AGE
kubernetes   ClusterIP      10.43.0.1       <none>         443/TCP        166m
nginx        ClusterIP      10.43.255.247   <none>         80/TCP         12m
nginx-lb     LoadBalancer   10.43.55.69     192.168.96.2   80:32355/TCP   62s
```

できてますね。外部IP（といってもローカルだけど）が振られているので、外から繋がります！
ただ、Docker上で動かしているので、この外 = Docker内という、大変ややこしい・・・。

Docker上から、確認してみます。

```console
$ docker run -it --rm --network=k3s-test_default  alpine:3.9 wget -O - http://192.168.96.2/
Connecting to 192.168.96.2 (192.168.96.2:80)
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
-                    100% |********************************|   612  0:00:00 ETA
```

でてますね。

```console
$ stern '.*'
+ nginx-6c7b58b644-cvzsl › nginx
+ nginx-6c7b58b644-sgbb7 › nginx
+ svclb-nginx-lb-7b459cb68c-zl4mq › http
svclb-nginx-lb-7b459cb68c-zl4mq http + trap exit TERM INT
svclb-nginx-lb-7b459cb68c-zl4mq http + cat /proc/sys/net/ipv4/ip_forward
svclb-nginx-lb-7b459cb68c-zl4mq http + '[' 1 '!=' 1 ]
svclb-nginx-lb-7b459cb68c-zl4mq http + iptables -t nat -I PREROUTING '!' -s 10.43.55.69/32 -p TCP --dport 80 -j DNAT --to 10.43.55.69:80
svclb-nginx-lb-7b459cb68c-zl4mq http + iptables -t nat -I POSTROUTING -d 10.43.55.69/32 -p TCP -j MASQUERADE
svclb-nginx-lb-7b459cb68c-zl4mq http + '[' '!' -e /pause ]
svclb-nginx-lb-7b459cb68c-zl4mq http + mkfifo /pause
nginx-6c7b58b644-cvzsl nginx 10.42.2.8 - - [15/Mar/2019:05:07:05 +0000] "GET / HTTP/1.1" 200 612 "-" "Wget" "-"
nginx-6c7b58b644-sgbb7 nginx 10.42.2.8 - - [15/Mar/2019:05:07:07 +0000] "GET / HTTP/1.1" 200 612 "-" "Wget" "-"
```

ちゃんと、分散もされてるっぽいですね。

```console
$ kubectl get pods
NAME                              READY   STATUS    RESTARTS   AGE
nginx-6c7b58b644-cvzsl            1/1     Running   0          20m
nginx-6c7b58b644-sgbb7            1/1     Running   0          20m
svclb-nginx-lb-7b459cb68c-7wqv7   0/1     Pending   0          9m26s
svclb-nginx-lb-7b459cb68c-zl4mq   1/1     Running   0          9m26s
```

一つPendingになってるのは微妙に気になりますが...。

# さいご

とりあえず、K3sでクラスタ作って、実際にデプロイしてみて、を一通りやってみました。
あとは、Raspberry Pi 3で試してみたりとか、x86とarmの混成クラスタとか作ってみたいですね。

（一部、ログを再構成してあるので、時間とかAGEとかで整合性が取れていない箇所があります。)