Docker Desktop for Windows にて Kubernetes を有効化出来ないとき

 

Docker Desktop から Kubernetes を起動しようとすると、ぐるぐるが終わらずにスタック状態となる場合があります。

PowerShell上から

Get-Content C:\Users\foo\appdata\local\Docker\log.txt -wait -tail 0

でログを観察してみると、

[12:48:25.326][GoBackendProcess ][Info ] external: POST /events 200 \”Go-http-client/1.1\” \”\
[12:48:26.340][ApiProxy ][Info ] cannot list nodes: Get https://kubernetes.docker.internal:6443/api/v1/nodes: x509: certificate signed by unknown authority

のような感じで延々繰り返していることがわかります。

cannot list nodes: Get https://kubernetes.docker.internal:6443/api/v1/nodes: EOF

の場合もあります。

これを解決してみます。

手順

  1. Docker Desktop for Windows をアンインストール

  2. C:\Users\foo\.kube を削除

  3. Hyper-Vを無効化(OS再起動が要求されるので再起動します)

  4. C:\Windows\System32\drivers\etc\hosts に kubernetes.docker.internal を追加
    127.0.0.1       kubernetes.docker.internal
  5. 管理者権限コマンドプロンプトにて
    netsh int ipv4 add excludedportrange protocol=tcp startport=6443 numberofports=1
    を行い、6443/tcpを予約

  6. Hyper-Vを有効化(OS再起動が要求されるので再起動します)

  7. 管理者権限コマンドプロンプトにて
    netsh int ipv4 show excludedportrange protocol=tcp
    を行い、6443/tcpが除外予約されていることを確認

  8. Docker Desktop for Windows をインストール

  9. Docker Desktop for Windows を起動し、必要な設定を行う
    ※この時点ではまだ Kubernetes を有効化しません

  10. Proxy配下でない時は15.に

  11. Proxy配下の時は、GUI上にてProxy/noProxyとDNSを設定


  12. Docker Desktop for Windows を一旦終了

  13. Proxy配下の時は、C:\Users\foo\.docker\config.json にProxy/noProxyを設定
    config.jsonの例
    {
      "auths":
      {
        "https://index.docker.io/v1/":{}
      },
      "credsStore":"desktop",
      "proxies":
      {
        "default":
        {
          "httpProxy":"http://yourid%40yourdomain:yourpass@proxy-ip:proxy-port",
          "httpsProxy":"http://yourid%40yourdomain:yourpass@proxy-ip:proxy-port",
          "noProxy":"127.0.0.1,localhost,*.internal,*.local,your-docker-subnet/24"
        }
      },
      "stackOrchestrator":"swarm"
    }
  14. Docker Desktop for Windows を起動

  15. ログの監視を開始
    Get-Content C:\Users\foo\appdata\local\Docker\log.txt -wait -tail 0
  16. Kubernetes を有効化


  17. https://kubernetes.docker.internal:6443/api/v1/nodes:… が出続けますが、しばらくすると消えます
    [10:12:29.091][GoBackendProcess  ][Info   ] adding tcp forward from 127.0.0.1:6443 to 127.0.0.1:6443
    [10:12:29.098][LinuxWSL2Engine   ][Info   ] time="2020-07-31T01:12:29Z" level=info msg="adding tcp forward from 127.0.0.1:6443 to 127.0.0.1:6443"
    [10:12:29.098][GoBackendProcess  ][Info   ] external: POST /forwards/expose/port 200 \"Go-http-client/1.1\" \"\
    [10:12:29.099][ApiProxy          ][Info   ] waiting for kube-system pods
    [10:12:29.100][GoBackendProcess  ][Info   ] external: POST /events 200 \"Go-http-client/1.1\" \"\
    [10:12:29.100][ApiProxy          ][Info   ] waiting for node to be ready
    [10:12:29.100][GoBackendProcess  ][Info   ] external: POST /events 200 \"Go-http-client/1.1\" \"\
    [10:12:30.129][ApiProxy          ][Info   ] cannot list nodes: Get https://kubernetes.docker.internal:6443/api/v1/nodes: EOF
    :
    :
    [10:13:56.923][ApiProxy          ][Info   ] Cluster is ready
    :
    :
    [10:13:56.924][GoBackendProcess  ][Info   ] external: POST /events 200 \"Go-http-client/1.1\" \"\
    [10:13:56.924][ApiProxy          ][Info   ] waiting for system pods
    [10:13:56.924][GoBackendProcess  ][Info   ] external: POST /events 200 \"Go-http-client/1.1\" \"\
    [10:13:59.945][ApiProxy          ][Info   ] 0/3 system pods running, found labels  but still waiting for labels k8s-app=kube-dns, component=kube-controller-manager, component=kube-apiserver...
    :
    :
    [10:14:56.953][GoBackendProcess  ][Info   ] external: POST /events 200 \"Go-http-client/1.1\" \"\
    [10:14:57.956][ApiProxy          ][Info   ] 3/3 system pods running
    [10:14:57.957][GoBackendProcess  ][Info   ] external: POST /events 200 \"Go-http-client/1.1\" \"\
    [10:14:57.976][ApiProxy          ][Info   ] installing compose-on-kubernetes and storage-provisioner
    :
    :
    [10:15:00.870][GoBackendProcess  ][Info   ] external: POST /events 200 \"Go-http-client/1.1\" \"\
    [10:15:00.871][ApiProxy          ][Info   ] 0/2 system pods running, found labels  but still waiting for labels component=storage-provisioner, component=vpnkit-controller...
    :
    :
    [10:15:12.064][GoBackendProcess  ][Info   ] internal: GET /forwards/list 200 \"Go-http-client/1.1\" \"\
    [10:15:12.880][ApiProxy          ][Info   ] 2/2 system pods running
    [10:15:12.888][GoBackendProcess  ][Info   ] external: POST /events 200 \"Go-http-client/1.1\" \"\
    :
    :
    [10:15:23.985][ApiProxy          ][Info   ] kubernetes is up and running
  18. GUI上の表示が Kubernetes running となったら、動作確認
    C:\>kubectl get nodes
    NAME             STATUS   ROLES    AGE   VERSION
    docker-desktop   Ready    master   86m   v1.16.6-beta.0

  19. \(^o^)/

以上です。

BranchCacheを停めてみる

 

WSL2上でDockerコンテナを -p 80:80 で建てたときに、http://localhost/ で接続出来ない時の対処法です。

80/tcpを塞いでいるのがBranchCacheサービスの場合で、単純にサービスを停めただけでは復活してしまう場合に本手法が使えるかと思います。


対処前の状態

C:\>netstat -ano | findstr :80
TCP 0.0.0.0:80 0.0.0.0:0
:
:


対処方法

  1. services.mscを起動し、BranchCacheサービスを停止/無効化します
  2. gpedit.mscを起動し、ローカルコンピューターポリシー→コンピューターの構成→管理用テンプレート→ネットワーク→BranchCache→BranchCacheを有効にする、に進み、無効を選択、適用します
  3. OSを再起動します

  4. netstat -ano | findstr :80 にて、80/tcpが空いていることを確認下さい

以上です。

docker: Error response from daemon: cgroups: cannot find cgroup mount destination: unknown.

 

WSL2(Ubuntu)上でのDockerコンテナ起動時にcgroupのエラーが出るときがあります。

root@hoge:~# docker run –name web -d -p 10080:80 nginx:alpine
docker: Error response from daemon: cgroups: cannot find cgroup mount destination: unknown.
root@hoge:~#

ハードコーディングしても問題無い場合は、次のスクリプトを適当な名前で/etc/profile.dに置いて下さい。

root@hoge:~# cat /etc/profile.d/hoge.sh
#!/bin/sh
PASSWORD=suでrootになれるパスワード
if [ ! -d /sys/fs/cgroup/systemd ]; then
  echo $PASSWORD | sudo -S mkdir /sys/fs/cgroup/systemd 2>/dev/null
fi
mountpoint -q /sys/fs/cgroup/systemd || echo $PASSWORD | sudo -S mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd

パスワードを残したく無い場合で、手打ちで対応出来る場合は、次のコマンドをWSL2起動の都度、叩いて下さい。

sudo mkdir /sys/fs/cgroup/systemd
mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd

Dockerコンテナのresolv.confやhostnameの変更が有効にならない

 

単純に/etc/resolv.confを変更しても、暫くすると、

# cat /etc/resolv.conf
# This configuration is written to the config.iso
nameserver 192.168.65.1

な状態に戻ってしまいます。

この場合、docker run に –dns=使いたいDNSサーバのIPアドレス オプションを付けて起動して下さい(ハードコードになりますので、違う環境に持って行く場合は注意)。

また、このときにProxyの内側の環境でコンテナの構築を行う必要がある場合は、環境変数や各種設定ファイル内でProxyサーバをFQDNではなくIPアドレスで指定してあげて下さい。

また、/etc/hostnameを変更しても、暫くすると元に戻ってしまいます。
ここも、docker run に –hostname=設定したいホスト名 オプションを付けて起動して下さい。

rsyslogとsshが動いているコンテナを作ってみる

 

某SNMP Managerなサーバを作るための準備として、rsyslogとsshが動いているCentOS7なコンテナを作ってみました。

仕様

  • タイムゾーンはJST
  • rootでsshアクセス可能
  • rootのパスワードはhogehoge

※listen.confの変更と、ssh-keygenに触れている資料が見付けられるまでの間、嵌まりました。


手順

# カレントフォルダにDockerfileとsupervisord.confを置きます

# コンテナ作成
docker build -t template .

# コンテナ起動(ssh用ポートを10022としています)
docker run -d --name test -p 10022:22 template

# コンソールに接続
docker exec -it test /bin/bash

Dockerfile

FROM centos:7

RUN yum -y update \
    && rm -f /etc/localtime \
    && ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
    && yum -y install rsyslog passwd openssh-server openssh-clients initscripts \
    && yum -y install https://centos7.iuscommunity.org/ius-release.rpm \
    && yum -y install python36u python36u-devel python36u-libs python36u-pip python36u-setuptools \
    && yum -y install supervisor \
    && sed 's/$ModLoad imjournal/# $ModLoad imjournal/' -i /etc/rsyslog.conf \
    && sed 's/$OmitLocalLogging on/$OmitLocalLogging off/' -i /etc/rsyslog.conf \
    && sed 's/$IMJournalStateFile imjournal.state/# $IMJournalStateFile imjournal.state/' -i /etc/rsyslog.conf \
    && sed 's/$SystemLogSocketName/# $SystemLogSocketName/' -i /etc/rsyslog.d/listen.conf \
    && mkdir /var/run/sshd \
    && echo 'root:hogehoge' | chpasswd \
    && sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config \
    && sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd \
    && echo "export VISIBLE=now" >> /etc/profile \
    && /usr/bin/ssh-keygen -A

COPY supervisord.conf /etc/supervisord.conf

EXPOSE 22

CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]

supervisord.conf

[unix_http_server]
file=/tmp/supervisor.sock   ; the path to the socket file

[supervisord]
logfile=/tmp/supervisord.log ; main log file; default $CWD/supervisord.log
logfile_maxbytes=50MB        ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=10           ; # of main logfile backups; 0 means none, default 10
loglevel=info                ; log level; default info; others: debug,warn,trace
pidfile=/tmp/supervisord.pid ; supervisord pidfile; default supervisord.pid
nodaemon=true                ; start in foreground if true; default false
minfds=1024                  ; min. avail startup file descriptors; default 1024
minprocs=200                 ; min. avail process descriptors;default 200

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket

[program:sshd]
command=/usr/sbin/sshd -D -e
autostart=true
autorestart=true
startretries=3

[program:rsyslog]
command=/usr/sbin/rsyslogd -n -c5
autostart=true
autorestart=true
stdout_logfile=/var/log/messages
stderr_logfile=/var/log/messages
redirect_stderr=true