1.安装kubernetes-cli:

brew install keubernetes-cli

2.安装minikube

brew cask install minikube

3.安装其它依赖工具,如docker for mac、virtualbox等,因为以前就装过所以不记命令了

4.启动minukube

minikube start

然后问题来了,它会卡在

Starting cluster components…

这时查看log

minikube logs

会显示大堆error:

1
2
3
4
5
6
7
8
9
Jul 23 06:15:30 minikube kubelet[2738]: E0723 06:15:30.994778 2738 pod_workers.go:186] Error syncing pod 3afaf06535cc3b85be93c31632b765da ("kube-addon-manager-minikube_kube-system(3afaf06535cc3b85be93c31632b765da)"), skipping: failed to "CreatePodSandbox" for "kube-addon-manager-minikube_kube-system(3afaf06535cc3b85be93c31632b765da)" with CreatePodSandboxError: "CreatePodSandbox for pod \"kube-addon-manager-minikube_kube-system(3afaf06535cc3b85be93c31632b765da)\" failed: rpc error: code = Unknown desc = failed pulling image \"k8s.gcr.io/pause-amd64:3.1\": Error response from daemon: Get https://k8s.gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)" 
Jul 23 06:15:31 minikube kubelet[2738]: E0723 06:15:31.005991 2738 remote_runtime.go:92] RunPodSandbox from runtime service failed: rpc error: code = Unknown desc = failed pulling image "k8s.gcr.io/pause-amd64:3.1": Error response from daemon: Get https://k8s.gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
Jul 23 06:15:31 minikube kubelet[2738]: E0723 06:15:31.006091 2738 kuberuntime_sandbox.go:54] CreatePodSandbox for pod "etcd-minikube_kube-system(6ea1c8f36a099856b01bf7d16652758c)" failed: rpc error: code = Unknown desc = failed pulling image "k8s.gcr.io/pause-amd64:3.1": Error response from daemon: Get https://k8s.gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
Jul 23 06:15:31 minikube kubelet[2738]: E0723 06:15:31.006160 2738 kuberuntime_manager.go:646] createPodSandbox for pod "etcd-minikube_kube-system(6ea1c8f36a099856b01bf7d16652758c)" failed: rpc error: code = Unknown desc = failed pulling image "k8s.gcr.io/pause-amd64:3.1": Error response from daemon: Get https://k8s.gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
Jul 23 06:15:31 minikube kubelet[2738]: E0723 06:15:31.006250 2738 pod_workers.go:186] Error syncing pod 6ea1c8f36a099856b01bf7d16652758c ("etcd-minikube_kube-system(6ea1c8f36a099856b01bf7d16652758c)"), skipping: failed to "CreatePodSandbox" for "etcd-minikube_kube-system(6ea1c8f36a099856b01bf7d16652758c)" with CreatePodSandboxError: "CreatePodSandbox for pod \"etcd-minikube_kube-system(6ea1c8f36a099856b01bf7d16652758c)\" failed: rpc error: code = Unknown desc = failed pulling image \"k8s.gcr.io/pause-amd64:3.1\": Error response from daemon: Get https://k8s.gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)"
Jul 23 06:15:31 minikube kubelet[2738]: I0723 06:15:31.410180 2738 kubelet_node_status.go:271] Setting node annotation to enable volume controller attach/detach
Jul 23 06:15:31 minikube kubelet[2738]: I0723 06:15:31.412318 2738 kubelet_node_status.go:82] Attempting to register node minikube
Jul 23 06:15:31 minikube kubelet[2738]: E0723 06:15:31.412572 2738 kubelet_node_status.go:106] Unable to register node "minikube" with API server: Post https://localhost:8443/api/v1/nodes: dial tcp 127.0.0.1:8443: getsockopt: connection refused
Jul 23 06:15:31 minikube kubelet[2738]: E0723 06:15:31.655753 2738 reflector.go:205] k8s.io/kubernetes/pkg/kubelet/config/apiserver.go:47: Failed to list *v1.Pod: Get https://localhost:8443/api/v1/pods?fieldSelector=spec.nodeName%3Dminikube&limit=500&resourceVersion=0: dial tcp 127.0.0.1:8443: getsockopt: connection refused

乍一看有点摸不着头脑,还以为它自己有问题,连不上自己的api服务器
但是看到pulling image XXX Error之类的提示后,立即意识到这可能是网络问题,需要的image没有被拉下来,相应功能自然启动不了

所谓网络问题,其实就是被墙了,k8s.gcr.io浏览器也打不开

开上代理再运行,

http_proxy=XXX https_proxy=XXX minikube start

会发现还是卡在这里,仍然是这个报错
有些不解,试试手动来拉这个image

http_proxy=XXX https_proxy=XXX docker pull k8s.gcr.io/pause-amd64:3.1

却又是没问题的,很快就拉下来了!
而且如果用docker images查看当前已有的images,这个pause-amd64:3.1也赫然在列,既然本地都有了,为何还要再去下载呢?

不禁陷入深思,一顿搜索之后,猛然醒悟:

minikube的逻辑是创建一个vm,在这个vm里去运行k8s需要的各种docker image

所以:
1、我们在命令行上添加的http_proxy变量,只是影响当前命令本身,不可能使在vm里执行的其它命令也走代理。
2、在主机上运行的docker images查看的只是主机上已下载的images,并不是vm里的,vm里启动的docker自然还要再去下载

想通了原因,那么首先做个测试,

minikube ssh

进到vm里,然后修改/etc/systemd/system/docker.service.d/http-proxy.conf这个文件:

[Service]
Environment=“HTTP_PROXY=https://proxy.example.com:443/”
Environment=“HTTPS_PROXY=https://proxy.example.com:443/”

重新启动docker daemon:

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

这时可以发现代理的流量监测已经噌噌地往上冒,达到几MB/s
说明vm内的docker已经开始连上gcr在下载image了!
等它下载完,主机上卡住的minikube start命令也顺利过去了,
最终minikube也正常启动起来了,以下命令打开web控件面板:

minikube dashboard


后记:

虽然通过手动修改vm中的docker配置文件设置了代理,但毕竟繁琐,如果minikube重装(或是换参数重启了),vm似乎都被重置,这个过程又要手动做一遍!
其实在minikube本来就有一个命令行参数来设置新建的vm中docker所属环境变量:

$ minikube start --docker-env HTTP_PROXY=${http_proxy} --docker-env HTTPS_PROXY=${https_proxy} --docker-env NO_PROXY=192.168.99.0/24

这样新建出来的vm,它的docker配置文件里就自带了这些环境变量,可以ssh进去查看,也可以用相关命令直接显示:

minikube ssh – systemctl show docker -–property=Environment --no-pager

另外,如果要给容器内的程序设置代理,可在docker run中指定参数

docker container run
-e HTTP_PROXY=http://username:password@proxy2.domain.com
-e HTTPS_PROXY=http://username:password@proxy2.domain.com
myimage


再记:

问题刚出现的时候着Starting cluster components这句话到处搜,特别是github的issue上,却得到很多误导的答案
比如什么加选项–bootstrapper=localkube,甚至–vm-driver=hyperkit等等,也许当时某个版本是有这类问题并且表现出相同的错误信息
但那些问题不一定就是自己碰到的问题,最终解决问题还是去看log,分析一下实际出错的环节,再加以一些排除法测试手段。


关联知识

  1. systemctl是一套新的linux服务程序管理工具,从最早的/etc/init.d到service,现在又到了systemctl了,是时候补充学习一下了。
  2. 参考:https://docs.docker.com/config/daemon/systemd/#httphttps-proxy
  3. 参考:https://stackoverflow.com/questions/43728355/kubernetes-pods-not-starting-running-bind-the-proxy/43757872#43757872
  4. 参考:https://stackoverflow.com/questions/47827496/how-to-configure-docker-container-proxy