docker安装windows_windows 上安装 k8s 管理的开发环境的步骤
最终安装的结果如下图所示第一步:安装 WSL 2Install Windows Subsystem for Linux (WSL) on Windows 10这一步就获得了 ubuntu 20.04 on WSL2第二步:安装 windows terminalhttps://www.microsoft.com/en-us/p/windows-terminal/9n0dx20hk701安装了 win
最终安装的结果如下图所示
第一步:安装 WSL 2
Install Windows Subsystem for Linux (WSL) on Windows 10
这一步就获得了 ubuntu 20.04 on WSL2
第二步:安装 windows terminal
https://www.microsoft.com/en-us/p/windows-terminal/9n0dx20hk701
安装了 windows terminal 就可以直接进入 ubuntu 20.04 on WSL2
修改 terminal 设置可以把默认的 profile 设置为 ubuntu 20.04
第三步:安装 vscode
Visual Studio Code - Code Editing. Redefined
vscode 安装在 windows 主机上。这个 vscode 就是开发时用的图形界面,直接跑在 windows 本地。相比虚拟机方案,开发环境的窗口和微信qq等窗口,可以更方便的切换。
第四步:安装 vscode remote wsl
安装完插件就可以选择安装的 ubuntu 20.04,进入这个环境编辑代码
这一步就获得了在 vscode 中编辑 ubuntu 20.04 里的文件的能力。编辑代码,git push/pull 的问题就解决了。在这个 WSL 连接了的 vscode 下,启动 terminal,就是在 ubuntu 20.04 下的 terminal
第五步:安装 docker daemon
安装 docker 解决的是进程启动的问题。我不希望直接在 WSL 上直接启动进程,而是希望像生产环境那样,进程都由 kubernetes 启动,服务之间的域名服务发现都是由 kubernetes 管理。所以要先安装一个 docker
sudo apt install docker.io
在 ubuntu 20.04 下,用 apt 安装好了 docker daemon 之后,docker 是没有启动的。因为 WSL2 是没有 systemd 的,没有 service 的概念。所以需要创建一个 shell 脚本来启动 docker daemon:
$ cat ~/start-docker.sh
mkdir /sys/fs/cgroup/systemd ; mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd ; dockerd
$ chmod +x ~/start-docker.sh
启动 dockerd 前要做的操作是为了 workaround 这个 bug:https://github.com/microsoft/WSL/issues/4189
启动需要执行 sudo ~/start-docker.sh。启动之后执行 docker run --rm -it ubuntu:20.04 bash 可以验证是不是启动成功了。
第六步:让 windows 可以访问 ubuntu 下的 docker daemon
上一步安装的 docker daemon 是跑在 ubuntu 20.04 on WSL 里的。如何让 windows 的 powershell 也可以 docker ps 呢?解决办法就是让 docker daemon 监听到 tcp 端口上,然后把 windows 下的 docker context 设置为连接所监听的 tcp 端口。这需要以下步骤
- 改变 docker daemon 的监听端口
- 安装 docker 客户端到 windows 主机上
- 给 windows 设置 docker context,以连接到 ubuntu 下的 docker daemon
下面分别来做这三个步骤。
$ cat /etc/docker/daemon.json
{
"registry-mirrors": [],
"debug": false,
"tls": false,
"hosts": ["tcp://127.0.0.1:10086", "unix:///var/run/docker.sock"]
}
修改 ubuntu 里的 daemon.json 配置,打开额外的 tcp 监听端口。如果你有阿里云的 docker hub 镜像账号,填入上面的 registry-mirrors 里可以加快 docker pull image 的速度。
然后给 windows 安装 docker 客户端。目前没有专门的 docker 客户端安装文件,只能把完整的 docker desktop https://www.docker.com/products/docker-desktop 给安装上。但是并不启动 docker desktop 的服务,仅仅使用 C:Program FilesDockerDockerresourcesbin 这个目录下给我们安装好的 docker.exe 和 kubectl.exe 来分别作为 docker 客户端和 kubernetes 的客户端。
docker 可以有多个 context,我本地的 docker context 如下
PS C:Usersnctao> docker context ls
NAME DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR
default Current DOCKER_HOST based configuration npipe:./pipe/docker_engine https://10.82.0.206:6443 (my-runtime) swarm
qa01 tcp://10.82.0.206:10086
wsl * tcp://127.0.0.1:10086
添加 docker context 使用如下命令
PS C:Usersnctao> docker context create wsl --docker "host=tcp://127.0.0.1:10086"
切换到刚刚添加的 docker context
PS C:Usersnctao> docker context use wsl
wsl
Current context is now "wsl"
如果配置正常,在 windows 的 powershell 下,也可以用 docker run --rm -it ubuntu:20.04 bash 启动一个容器。
第七步:让 vscode 可以访问 ubuntu 下的 docker daemon
安装 vscode docker 插件
安装好之后,在 vscode 里也可以切换使用的 docker context。进入 command pallet(默认就是 ctrl+alt+p),输入 Docker Contexts: Use
在左边选择小鲸鱼图标,就可以看到 docker 上运行中的容器了。
选择运行中的 container 可以 attach vscode,也就是像前面的 vscode remote wsl 一样,直接编辑运行中容器的文件,以及在容器中执行 terminal 命令。
注意上图里的左下角的绿色背景的文字,说明 vscode 已经 attach 进去了。如果前面没有安装 docker desktop,这一步是不会成功的,因为这一步依赖了 docker desktop 提供的 docker.exe 这个命令。
除了 attach vscode,也可以只运行一个命令行。
第八步:安装 kubernetes
docker 的主要用途是 docker build,用于构建镜像的。所有的容器启动,我使用 kubernetes 来执行。kubernetes 给 docker 增加了一个基于 yaml 文件的声明,批量启动容器的能力。但是官方的 kubernetes 安装非常麻烦,所以我们使用一个更简单的 k3s 版本
https://github.com/rancher/k3s/releases/latest
访问上面的 url,手工下载 k3s 这个可执行文件。然后启动 k3s
sudo ./k3s server --docker
这样一条命令,就获得了一个 kubernetes 环境了(前提是你已经用 clash windows 配置了全局的kx上网)。
启动好了之后,我们要活得这个新启动的 k8s cluster 的访问配置。
$ cat /etc/rancher/k3s/k3s.yaml
cat: /etc/rancher/k3s/k3s.yaml: Permission denied
普通用户是没有权限的。所以要换 sudo 执行
$ sudo cat /etc/rancher/k3s/k3s.yaml
[sudo] password for taowen:
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJWekNCL3FBREFnRUNBZ0VBTUFvR0NDcUdTTTQ5QkFNQ01DTXhJVEFmQmdOVkJBTU1HR3N6Y3kxelpYSjIKWlhJdFkyRkFNVFU1TURrNU5qazBOekFlRncweU1EQTJNREV3TnpNMU5EZGFGdzB6TURBMU16QXdOek0xTkRkYQpNQ014SVRBZkJnTlZCQU1NR0dzemN5MXpaWEoyWlhJdFkyRkFNVFU1TURrNU5qazBOekJaTUJNR0J5cUdTTTQ5CkFnRUdDQ3FHU000OUF3RUhBMElBQlBEV0VHdUFzT1VDb2s2a1BjWUhRQTJ6amxydjZXRDFFcXRWQ1Q1NytROGwKVVltU2pHNEVkaGZ1RDBoYWU5QlhmRk5jVkg1OFNzZjU2aFl5WFI5RXU1V2pJekFoTUE0R0ExVWREd0VCL3dRRQpBd0lDcERBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUFvR0NDcUdTTTQ5QkFNQ0EwZ0FNRVVDSVFDOUkxbUY5VmFMCktPd0tzS3kraUhCaW5CS0ptc3lXOVR6Yzc5NDN3SVR0eWdJZ1lNTnlpUThqOE9zN0ZJcWtFRWpqR3ZvQ0hHakwKTmJ4REhLTjJURTM2RVdFPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
server: https://127.0.0.1:6443
name: default
contexts:
- context:
cluster: default
user: default
name: default
current-context: default
kind: Config
preferences: {}
users:
- name: default
user:
password: 08421f93e9499bae83f02de0f6e8d00b
username: admin
然后把这个配置复制到你自己的目录下,例如 ~/.kube/config
KUBECONFIG=~/.kube/config ./k3s kubectl get nodes
如果一切 ok,上面这条命令可以正常执行。为了方便,建立一个符号链接
$ ln -s k3s /usr/bin/kubectl
这样全局就有 kubectl 命令了
第九步:让 windows 可以访问 kubernetes
因为前面那一步,kubernetes 已经默认监听到了 127.0.0.1:6443 端口了。所以 windows 下不存在网络访问不到的问题。所以仅仅需要搞定 KUBECONFIG 文件的问题,就可以让 windows 也访问 kubernetes 了
PS C:Usersnctao> type .kube/config
类似的,把 C:Usersnctao.kubeconfig 这个配置文件搞出来(nctao换成你自己的windows用户名)。内容和前面的 ~/.kube/config 一样。
因为 windows 和 wsl 的文件系统时联系在一起的,所以可以搞个符号链接
$ ls -alh ~/.kube/config
-rwxrwxrwx 1 taowen taowen 7.3K Jun 6 21:47 /home/taowen/.kube/config
然后在 windows 下应该就可以访问了
PS C:Usersnctao> kubectl get nodes
第十步:让 vscode 可以访问 kubernetes
安装 kubernetes 插件
设置 kubeconfig
和 docker 一样,也可以 attach vscode
除了在 docker 里用 debug 模式启动进程,一般并不需要这么去做。在本地开很多个 vscode 窗口并不方便。更实用的是 terminal 这个菜单项
如果安装了 tabulous 这个插件,每个 terminal 都会做为一个tab出现在 status bar 上
第十一步:标准的 devcontainer
除了用 k8s+docker 启动生产环境的 docker image,也可以启动一个空的 os 做为开发环境来用。先在 vscode wsl 环境下连上 k8s
上图中有两个重点:
- 左下角说明了我们当前是在 wsl 里
- kubeconfig 设置为 ~/.kube/config 这个和 windows 模式下的 vscode 是不同的。否则 kubernetes 插件会找不到 k8s
然后在这样的 vscode 窗口内,我们希望做到两件事情:
- 编辑 wsl 环境下的文件:也就是 vscode 的文件编辑的是 wsl 环境下的文件系统。这个是 vscode remote wsl 本来就支持的功能。
- 用 k8s 执行进程,但是使用的是 wsl 环境下的文件:也就是 vscode 窗口里的 terminal 是连到了 k8s 启动的容器里。这个通过 kubernetes 插件,选择 pod 之后右键 terminal 就可以实现了。
那么就只剩下了,如何让 k8s container 访问 wsl 的文件系统了
apiVersion: apps/v1
kind: Deployment
metadata:
name: trillion
spec:
selector:
matchLabels:
app: trillion
strategy:
type: Recreate
template:
metadata:
labels:
app: trillion
spec:
securityContext:
runAsUser: 1004
runAsGroup: 1004
volumes:
- name: home-volume
hostPath:
path: /home/vscode
type: Directory
- name: docker-sock-volume
hostPath:
path: /var/run/docker.sock
type: File
containers:
- image: ubuntu:20.04
imagePullPolicy: Never
image: taowen/go-dev
args:
- -c
- 'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done'
command:
- /bin/bash
name: trillion
resources:
limits:
memory: "4Gi"
volumeMounts:
- mountPath: "/home/vscode"
name: home-volume
- mountPath: "/var/run/docker.sock"
name: docker-sock-volume
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
上面这份配置有几个重点:
- hostNetwork 这个保证了容器不会在一个隔离的网路内,而是直接用 wsl 自身的网络。这样就让访问容器里绑定的网络服务非常方便。
- dnsPolicy 为 ClusterFirstWithHostNet 使得即便在 hostNetwork 的情况下,仍然会由 k8s 的 dns 来解析域名。否则,一个容器就无法访问其他容器暴露的 service 域名了。
- mountPath 这个实现了 wsl 和 k8s container 之间互相访问文件系统,实际上就是 bind mount。
- docker.sock,因为把 docker.sock 也 bind mount 进去了,所以在容器里也可以执行 docker build 命令
- runAsUser 和 runAsGroup 这两个 uid 和 gid 要设置为 WSL 下相同的 uid 和 gid,这样可以避免 bind mount 的文件的权限问题。
- type: Recreate 这个设置也是必须的。否则重启容器默认的策略是新建新的,然后删掉旧的。因为我们用的是 hostNetwork,并没有 pod 之间的 ip 隔离,每个 pod 的 ip 是一样的,起新的不停旧的自然就端口冲突了。Recreate 就会先停旧的,再起新的。
- command 和 args,这个是让容器启动起来之后不会退出。这样才能一直跑在那里,给我们用 vscode 连进去的机会。
至此我们就把一个非常接近生产环境的 kubernetes,部署到了 windows 笔记本上。甚至开发调试本身,也是基于 kubernetes 来做的。docker 镜像打包启动变成了日常开发路径上的一部分,而不是仅仅在上线前才被迫去做的事情。有这个基础,可以进而有两个更高级的模式:
- 在 windows 笔记本上跑整个生产环境的所有镜像:只要内存够,整个生产环境,包括数据库都可以一键部署 kubectl apply 就行了
- 把开发环境搬到机房里去:本地可以跑 kubernetes,机房里当然也能跑。我们可以把开发用的容器直接跑在机房里,然后用 kubernetes 插件连进去。
更多推荐
所有评论(0)