由于国内的网络环境特殊,在本地使用 minikube
时遇到了 service 创建好后,一直无法运行的问题。查阅了网上很多资料后,找到一个笨拙的解决办法,先在此做个记录,以后再验证其他方案。
此方案需要具备以下先行条件:
在 shell 中 export http_proxy
, https_proxy
, HTTP_PROXY
, HTTPS_PROXY
和 ALL_PROXY
等环境变量,指向科学上网的本地 ip 和 port。
Ubuntu 16.04 已经支持 snap 包管理工具,可以直接通过官网的教程安装:
sudo snap install kubectl --classic
如果使用 oh-my-zsh
配置环境,只需要在 ~/.zshrc
的 plugins
中添加 kubectl
就可以在终端下使用更加友好的补齐和提示操作,包括后面会写到的 docker
。
minikube
依赖虚拟机,这里使用开源的 virtualbox
,直接使用 apt
工具安装即可:
sudo apt install -y virtualbox
直接使用 minikube
release 页面中的教程安装:
curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.25.2/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
最好安装 17.03 版本之后的 Docker,不然在后面的运行过程中会有个讨厌的 warning(go 1.7 or later)。安装新版的 Docker 可以参考官方页面,提取如下过程:
$ sudo apt-get remove docker docker-engine docker.io
$ sudo apt-get update
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce
$ sudo usermod -aG docker your-user
如果上述设置的代理环境变量未起作用,还可参考此种方式使用 systemctl
设置 docker daemon
进程的 Environment。
在所有的上述环境配置好后,按照 Running Kubernetes Locally via Minikube 教程中的命令执行,在 kubectl get pod
后,hello-minikube 的 Status 始终是 Creating,不能到达 Running。
使用 kubectl describe pod hello-minikue
描述看到 Failed create pod sandbox 的 Error。Google 一番之后,看到 GitHub 上的这个 issue。其中说到导致该问题的原因为 minikube VM 中的网络问题导致其内部的 docker 无法正确 pull 到以下的 image:
gcr.io/google_containers/kubernetes-dashboard-amd64:v1.8.0
gcr.io/k8s-minikube/storage-provisioner:v1.8.0
gcr.io/k8s-minikube/storage-provisioner:v1.8.1
gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.5
gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.14.5
gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.14.5
gcr.io/google_containers/kubernetes-dashboard-amd64:v1.6.3
gcr.io/google-containers/kube-addon-manager:v6.4-beta.2
gcr.io/google_containers/pause-amd64:3.0
只需要在 minikube VM 中下载下来上面的这些镜像便能正确运行 k8s 中的 pod。
再搜寻 1 2 3 4 等答案后,依然无法解答 minikube VM 中 docker 代理的设置问题。最后只能是采用了一个迂回的方式:
$ docker save ImageTag -o /path/to/mount_dir/output.file
$ minikube mount /path/to/mount_dir:/VM/mount_dir
$ minikube ssh
> sudo docker load -i /VM/mount_dir/output.file
> docker images
$ docker save imageNameGoesHere | pv | (eval $(minikube docker-env) && docker load)
kubectl
使用 VM 中的 image,参考该回答在 kubectl run
的最后添加 --image-pull-policy=Never
参数;kubectl get pod
检查是否是 Running 状态;minikube service svc-name --url
经过上述的一番折腾,本地的一个 k8s 实验总算测试通过。网络问题往往是分布式系统搭建过程中需要耗费很大精力关注的点,尤其在这样一个特殊的环境下。因为 minikube 和 kubectl 在命令行下不会默认输出错误信息,有时会让人产生大功告成的假象,需要多借助 kubectl describe
和 kubectl logs
命令分析原因,同时也可以尝试打开 minikube 的 debug 级别的 log:minikube start --logtostderr --loglevel=0
查找潜在问题。