Windows下部署和使用Kubernetes

2022-02-22

docker kubernetes

经过一段时间折腾,终于可以在windows下顺利使用Kuberbetes了,不过期间经历了不少坑,需要记录一下。

首先,软件环境如下

  • Windows 11
  • Docker Desktop for Windows
  • wsl2

在windows下,wsl2是开发者的利器,让我们可以最大限度实现与原生Linux一致的体验,同时又相当完美的与windows集成。Docker Desktop对Windows的支持也是越来越好,特别是加入对wsl的支持,让我们可以在wsl中非常方便的使用docker的功能。Docker Desktop的容器有三种模式,包括wsl、Windows和Hyper-V,可以自行搜索区别,我们用的是wsl模式。

对于新手来说,wsl2的开启比较麻烦,不过经过几年时间,可以查到的资料也是非常多,这里就不详述了。Desktop for Windows的按照也很简单,我们重点说一下在kubernetes的安装。

在Docker Desktop for Windows中安装kubernetes有若干种方法,比较简单的是用KinD,这是在单一容器中安装了kubernetes需要的全部依赖,容器本身相当于一个node,后续的kubernetes相关的资源都会在这个容器中创建。这样的方式安装起来非常简单,基本上没花多少功夫就搞定了,但是实际上这只能算是一个实验版本的kubernetes,只能简单体验一下kubernetes的命令,没有实用价值。你会发现建的各种资源,特别是容器,在docker中是看不到的,这个没有细究,我估计是在KinD容器中又运行了一个docker环境,如果真的是这样的话,这肯定就只是一个学习环境了。

其实Docker Desktop for Windows本身就可以打开kubernetes支持,在设置里我们可以看到,但是简单的勾选是没有效果的,主要还是因为网络环境问题,后续遇到的所有问题都是因为网络环境问题,如果没有网络问题,确实简单勾选一下就可以了。勾选上kubernetes支持,会自动下载一系列依赖的镜像,这个过程我们可以通过设置registry-mirrors,或者手工下载。为 Docker daemon 配置镜像加速,参考阿里云镜像服务 或中科大镜像加速地址https://docker.mirrors.ustc.edu.cn,手工下载kubernetes依赖的镜像的话,阿里云的这个项目绝对需要参考一下:

https://github.com/AliyunContainerService/k8s-for-docker-desktop

这一步的目的就是下载kubernetes依赖的镜像,特别要注意的是注意版本,不同版本的Docker for Desktop的内置kubernetes版本也不同,依赖的各个镜像的版本也不同,稍有差异就会无法启动。

我们的kubernetes版本是v1.22.5,需要下载对应版本的镜像,在k8s-for-docker-desktop项目中找到对应的分支,在images.properties这个文件可以看到依赖的镜像及其版本:

k8s.gcr.io/pause:3.5=registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.5
k8s.gcr.io/kube-controller-manager:v1.22.5=registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.22.5
k8s.gcr.io/kube-scheduler:v1.22.5=registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.22.5
k8s.gcr.io/kube-proxy:v1.22.5=registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.22.5
k8s.gcr.io/kube-apiserver:v1.22.5=registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.22.5
k8s.gcr.io/etcd:3.5.0-0=registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.0-0
k8s.gcr.io/coredns/coredns:v1.8.4=registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.8.4
k8s.gcr.io/ingress-nginx/controller:v1.1.1=registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.1.1
k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1=registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1

看一下load_images.ps1脚本我们就能知道上面这个文件内容的含义,每一行是一个镜像的说明,格式是key=value,其中key是后面需要打的tag,也就是镜像的实际地址和版本,value是代理后的地址和版本,脚本先pull代理后的镜像,然后把原始的镜像url作为tag打在镜像上,最后删除之前代理的镜像。load_images.ps1脚本的内容我们可以看一下:

foreach($line in Get-Content .\images.properties) {
    $data = $line.Split('=')
    $key = $data[0];
    $value = $data[1];
    Write-Output "$key=$value"
    docker pull ${value}
    docker tag ${value} ${key}
    docker rmi ${value}
}

如果脚本运行有问题,可能是权限问题,实在不行,也可以手工执行docker命令去下载这些镜像。

kubernetes开启成功后,相关的容器会自动运行,如下图所示可以看到一系列的容器在运行。如果运行失败,或者一致在Starting的状态,不排除是有些镜像没有成功下载,仔细对比一下需要的镜像版本,确认无误后还不行的话可以Docker的Troubleshoot中清除数据后重启Docker再试试。

如果呈现出上面的界面,整个流程已经大功告成,接下来就可以使用kubernetes了。首先可以按照dashboard,参考网站https://github.com/kubernetes/dashboard,其中的安装命令是

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.0/aio/deploy/recommended.yaml

这个地址是需要翻墙的,但是实际上前面给的github网址是可以看到文件内容的,注意选择好版本,直接把文件内容复制下来就行。在此之前,我们还需要给kubernetes加上账号和角色。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
kubectl apply -f dashboard-adminuser.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard
kubectl apply -f dashboard-role-binding.yaml

最后还需要打开kubernetes的代理:

$kubectl proxy
Starting to serve on 127.0.0.1:8001

这样就可以将kubernetes的api暴露出来,如果打算让其他机器能访问,可以将127.0.0.1改成0.0.0.0。在浏览器输入以下地址就可以打开kubernetes的dashboard:

http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy

刚开始是这个页面,需要输入token,如果按前面的步骤加入了账号,就可以通过以下命令获取到token:

$ kubectl -n kubernetes-dashboard get secret $(kubectl -n kubernetes-dashboard get sa/admin-user -o jsonpath="{.secrets[0].name}") -o go-template="{{.data.token | base64decode}}"
eyJhbGciOiJSUzI1NiIsImtpZCI6InFyTVU2U2diSU5PVXowNTNyV19OSThpc09LVXhuT1pDS0ZFVDJORjJnZ00ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLTh0aHRuIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI5YTgyMzc1Yy1lZTQ0LTQ5YmYtODY5Yi0zNzI4YWM0NTI2OWIiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6YWRtaW4tdXNlciJ9.KcbFaJoN6odWCBVDpU5lIKvOcdjVnmcKEN3-lelWXV-Pfna6umN3NZMshDWDrrVN7XVXB19xMp8gr0B56CuT6hUyS0lpdGcza_Nr74uCISzEzCQJQLmkIt9gGrmwE6Fklp6v8dbvLlIfL1abfLEBPx3pIIM1Vp4RLbXV4uxUhbp1KB9IH1szKQfCxlPoX-4L5RffKZLWEjSZVozPduaavXMz5dH_BGgq_PFyZn_c6yLyMrzKJrC0__PTI7cNnSGcQz6xO_wOTHdQb9jB1UYpQjELms5GQV8oi8DB49nvLTOrcztJiU--_OWJOWNna0jmqZG50l1mjZGzRHpulu2Gbg

成功输入token后的dashboard界面是这样的:

 
阅读