WSL + Docker:Windows桌面上的Kubernetes

s: 努诺杜卡莫 Docker船长和WSL海盗船; 伊霍尔·德沃雷茨基(Ihor Dvoretskyi),开发倡导者,云原生计算基金会

介绍

Windows 10和WSL2的新功能,还是Docker和Kubernetes的新功能?欢迎来到这篇博客文章,我们将从头开始在Docker中安装Kubernetes 迷你库.

为什么在Windows上使用Kubernetes?

在过去的几年中,Kubernetes成为事实上的标准平台,用于在分布式环境中运行容器化服务和应用程序。尽管存在各种各样的发行版和安装程序来在云环境(公共,私有或混合)或裸机环境中部署Kubernetes,但仍然需要在本地(例如,在开发人员的工作站上)部署和运行Kubernetes。 。

Kubernetes最初被设计为在Linux环境中部署和使用。但是,许多用户(不仅是应用程序开发人员)使用Windows OS作为其日常驱动程序。当微软透露WSL- 适用于Linux的Windows子系统,Windows和Linux环境之间的界线变得越来越不明显。

此外,WSL带来了几乎无缝地在Windows上运行Kubernetes的功能!

下面,我们将简要介绍如何安装和使用各种解决方案在本地运行Kubernetes。

先决条件

由于我们将解释如何安装KinD,因此我们将不对KinD依赖项的安装进行过多介绍。

但是,以下是所需的先决条件及其版本/通道的列表:

  • 操作系统:Windows 10 version 2004,Build 19041
  • 启用WSL2
    • In order to install the distros as WSL2 by default, once WSL2 installed, run the command wsl.exe --set-default-version 2 in Powershell
  • 从Windows应用商店安装了WSL2发行版-使用的发行版是Ubuntu-18.04
  • Windows版Docker桌面,稳定的频道-使用的版本为2.2.0.4
  • [可选]从Windows应用商店安装的Microsoft终端
    • 打开Windows应用商店,然后在搜索中键入“ Terminal”,这(通常)是第一个选项

Windows Store终端

就是这样。对于Windows的Docker桌面,无需进行任何配置,因为我们将在下一部分中对其进行说明。

WSL2:首次联系

安装完所有组件后,我们可以从“开始”菜单启动WSL2终端,然后键入“ Ubuntu”以搜索应用程序和文档:

开始菜单搜索

找到后,单击名称,它将在运行Ubuntu bash shell的情况下启动默认的Windows控制台。

像任何普通的Linux发行版一样,您需要创建一个用户并设置一个密码:

User-Password

[可选]更新 sudoers

As we are working, normally, on our local computer, it might be nice to update the sudoers 和 set the group %sudo to be password-less:

# Edit the sudoers with the visudo command
sudo visudo

# Change the %sudo group to be password-less
%sudo   ALL=(ALL:ALL) NOPASSWD: ALL

# Press CTRL+X to exit
# Press Y to save
# Press Enter to confirm

visudo

更新Ubuntu

在转到Docker桌面设置之前,让我们更新系统并确保我们在最佳条件下启动:

# Update the repositories 和 list of the packages available
sudo apt update
# Update the system based on the packages installed > the "-y" will approve the change automatically
sudo apt upgrade -y

apt-update-upgrade

Docker Desktop:使用WSL2更快

在进入设置之前,让我们做一个小测试,它将真正显示与Docker Desktop的新集成有多酷:

# Try to see if the docker cli 和 daemon are installed
docker version
# Same for kubectl
kubectl version

kubectl-error

你有错吗完善!这实际上是个好消息,所以现在让我们继续进行设置。

Docker Desktop设置:启用WSL2集成

首先,如果情况并非如此,请先启动适用于Windows的Docker桌面。打开Windows开始菜单,然后键入“ docker”,单击名称以启动应用程序:

docker-start

现在,您应该在时钟附近看到Docker图标以及其他任务栏图标:

docker-taskbar

现在单击Docker图标并选择设置。将会出现一个新窗口:

docker-settings-general

默认情况下,WSL2集成处于不活动状态,因此请单击“启用基于WSL 2的实验引擎”,然后单击“应用并重新启动”:

docker-settings-wsl2

该功能在幕后的作用是在WSL2中创建两个新发行版,其中包含并运行所有必需的后端套接字,守护程序以及CLI工具(请阅读:docker和kubectl命令)。

尽管如此,此第一个设置仍不足以在我们的发行版中运行命令。如果我们尝试,我们将和以前有同样的错误。

为了对其进行修复,并最终能够使用命令,我们还需要告诉Docker桌面将其自身“附加”到我们的发行版:

docker-resources-wsl

现在,让我们回到WSL2终端,看看是否可以(最终)启动命令:

# Try to see if the docker cli 和 daemon are installed
docker version
# Same for kubectl
kubectl version

docker-kubectl-success

Tip: if nothing happens, restart Docker Desktop 和 restart the WSL process in Powershell: Restart-Service LxssManager 和 launch a new Ubuntu session

和成功!现在完成了基本设置,我们转到了KinD的安装。

种类:Kubernetes在容器中变得简单

现在,我们已经安装,配置了Docker,并且最后的测试运行良好。

However, if we look carefully at the kubectl command, it found the "Client Version" (1.15.5), but it didn't find any server.

这是正常现象,因为我们没有启用Docker Kubernetes集群。因此,让我们安装KinD并创建我们的第一个集群。

而且,由于始终需要提及源,因此我们将(部分)遵循 类官方网站:

# Download the latest version of 类
curl -Lo ./kind //github.com/kubernetes-sigs/kind/releases/download/v0.7.0/kind-linux-amd64
# Make the binary executable
chmod +x ./kind
# Move the binary to your executable path
sudo mv ./kind /usr/local/bin/

kind-install

类:第一个集群

我们准备创建第一个集群:

# Check if the KUBECONFIG is not set
echo $KUBECONFIG
# Check if the .kube directory is created > if not, no need to create it
ls $HOME/.kube
# Create the cluster 和 give it a name (optional)
kind create cluster --name wslkind
# Check if the .kube has been created 和 populated with files
ls $HOME/.kube

kind-cluster-create

提示:如您所见,终端已更改,因此所有的漂亮图标都将显示

集群已成功创建,并且因为我们使用的是Docker Desktop,所以网络已全部设置为可以“按原样”使用。

So we can open the Kubernetes master URL in our Windows browser:

kind-browser-k8s-master

这是带有WSL2后端的Windows版Docker桌面的真正优势。 Docker确实实现了惊人的集成。

种类:计数1-2-3

我们的第一个集群已创建,它是“常规”单节点集群:

# Check how many nodes it created
kubectl get nodes
# Check the services for the whole cluster
kubectl get all --all-namespaces

kind-list-nodes-services

尽管这对于大多数人来说已经足够了,但让我们利用最酷的功能之一,多节点集群:

# Delete the existing cluster
kind delete cluster --name wslkind
# Create a config file for a 3 nodes cluster
cat << EOF > kind-3nodes.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
  - role: worker
  - role: worker
EOF
# Create a new cluster with the config file
kind create cluster --name wslkindmultinodes --config ./kind-3nodes.yaml
# Check how many nodes it created
kubectl get nodes

kind-cluster-create-multinodes

提示:根据我们运行“获取节点”命令的速度,可能不是所有节点都准备就绪,请等待几秒钟然后再次运行,一切都应准备就绪

就是这样,我们创建了一个三节点集群,如果再看一次服务,我们将看到几个现在具有三个副本的集群:

# Check the services for the whole cluster
kubectl get all --all-namespaces

wsl2-kind-list-services-multinodes

类:我可以看到一个不错的仪表板吗?

在命令行上工作总是一件好事,而且很有见识。但是,在处理Kubernetes时,我们可能希望在某些时候有一个直观的概览。

为此, Kubernetes仪表板 项目已创建。安装和首次连接测试非常快,所以让我们开始吧:

# Install the Dashboard application into our cluster
kubectl apply -f //raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc6/aio/deploy/recommended.yaml
# Check the resources it created based on the new namespace created
kubectl get all -n kubernetes-dashboard

kind-install-dashboard

当它使用ClusterIP(读取:内部网络地址)创建服务时,如果在Windows浏览器中键入URL,则无法访问该服务:

kind-browse-dashboard-error

那是因为我们需要创建一个临时代理:

# Start a kubectl proxy
kubectl proxy
# Enter the URL on your browser: http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

kind-browse-dashboard-success

Finally to login, we can either enter a Token, which we didn't create, or enter the kubeconfig file 从 our Cluster.

If we try to login with the kubeconfig, we will get the error "Internal error (500): 没有 t enough data to create auth info structure". This is due to the lack of credentials in the kubeconfig file.

因此,为避免您遇到相同的错误,让我们按照 推荐的RBAC方法.

让我们打开一个新的WSL2会话:

# Create a new ServiceAccount
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
EOF
# Create a ClusterRoleBinding for the ServiceAccount
kubectl apply -f - <<EOF
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
EOF

kind-browse-dashboard-rbac-serviceaccount

# Get the Token for the ServiceAccount
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')
# Copy the token 和 copy it into the Dashboard login 和 press "Sign in"

kind-browse-dashboard-login-success

成功!让我们还列出我们的节点:

kind-browse-dashboard-browse-nodes

出现一个漂亮而有光泽的三个节点。

迷你库:来自世界各地的Kubernetes

现在,我们已经安装,配置了Docker,并且最后的测试运行良好。

However, if we look carefully at the kubectl command, it found the "Client Version" (1.15.5), but it didn't find any server.

这是正常现象,因为我们没有启用Docker Kubernetes集群。因此,让我们安装Minikube并创建我们的第一个集群。

而且,由于始终需要提及源,因此,我们将(部分)遵循 Kubernetes.io网站:

# Download the latest version of 迷你库
curl -Lo minikube //storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
# Make the binary executable
chmod +x ./minikube
# Move the binary to your executable path
sudo mv ./minikube /usr/local/bin/

minikube-install

迷你库:更新主机

If we follow the how-to, it states that we should use the --driver=none flag in order to run 迷你库 directly on the host 和 Docker.

不幸的是,运行Kubernetes v 1.18时,我们会收到关于“ conntrack”的错误提示:

# Create a minikube one node cluster
minikube start --driver=none

minikube-start-error

提示:如您所见,终端已更改,因此所有的漂亮图标都将显示

因此,让我们通过安装缺少的软件包来解决此问题:

# Install the conntrack package
sudo apt install -y conntrack

![minikube-install-conntrack](/ images / blog / 2020-05-21-wsl2-dockerdesktop-k8s / wsl2-minikube-install conntrack.png)

让我们尝试再次启动它:

# Create a minikube one node cluster
minikube start --driver=none
# We got a permissions error > try again with sudo
sudo minikube start --driver=none

minikube-start-error-systemd

好的,这个错误云过去是有问题的。幸运的是,我们有一个解决方案

迷你库:启用SystemD

为了在WSL2上启用SystemD,我们将应用 剧本丹尼尔·莱韦林.

我邀请您阅读完整的博客文章,以及他如何提出解决方案,以及他为解决多个问题而进行的各种迭代。

简而言之,以下是命令:

# Install the needed packages
sudo apt install -yqq daemonize dbus-user-session fontconfig

minikube-systemd-packages

# Create the start-systemd-namespace script
sudo vi /usr/sbin/start-systemd-namespace
#!/bin/bash

SYSTEMD_PID=$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')
if [ -z "$SYSTEMD_PID" ] || [ "$SYSTEMD_PID" != "1" ]; then
    export PRE_NAMESPACE_PATH="$PATH"
    (set -o posix; set) | \
        grep -v "^BASH" | \
        grep -v "^DIRSTACK=" | \
        grep -v "^EUID=" | \
        grep -v "^GROUPS=" | \
        grep -v "^HOME=" | \
        grep -v "^HOSTNAME=" | \
        grep -v "^HOSTTYPE=" | \
        grep -v "^IFS='.*"$'\n'"'" | \
        grep -v "^LANG=" | \
        grep -v "^LOGNAME=" | \
        grep -v "^MACHTYPE=" | \
        grep -v "^NAME=" | \
        grep -v "^OPTERR=" | \
        grep -v "^OPTIND=" | \
        grep -v "^OSTYPE=" | \
        grep -v "^PIPESTATUS=" | \
        grep -v "^POSIXLY_CORRECT=" | \
        grep -v "^PPID=" | \
        grep -v "^PS1=" | \
        grep -v "^PS4=" | \
        grep -v "^SHELL=" | \
        grep -v "^SHELLOPTS=" | \
        grep -v "^SHLVL=" | \
        grep -v "^SYSTEMD_PID=" | \
        grep -v "^UID=" | \
        grep -v "^USER=" | \
        grep -v "^_=" | \
        cat - > "$HOME/.systemd-env"
    echo "PATH='$PATH'" >> "$HOME/.systemd-env"
    exec sudo /usr/sbin/enter-systemd-namespace "$BASH_EXECUTION_STRING"
fi
if [ -n "$PRE_NAMESPACE_PATH" ]; then
    export PATH="$PRE_NAMESPACE_PATH"
fi
# Create the enter-systemd-namespace
sudo vi /usr/sbin/enter-systemd-namespace
#!/bin/bash

if [ "$UID" != 0 ]; then
    echo "You need to run $0 through sudo"
    exit 1
fi

SYSTEMD_PID="$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')"
if [ -z "$SYSTEMD_PID" ]; then
    /usr/sbin/daemonize /usr/bin/unshare --fork --pid --mount-proc /lib/systemd/systemd --system-unit=basic.target
    while [ -z "$SYSTEMD_PID" ]; do
        SYSTEMD_PID="$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')"
    done
fi

if [ -n "$SYSTEMD_PID" ] && [ "$SYSTEMD_PID" != "1" ]; then
    if [ -n "$1" ] && [ "$1" != "bash --login" ] && [ "$1" != "/bin/bash --login" ]; then
        exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
            /usr/bin/sudo -H -u "$SUDO_USER" \
            /bin/bash -c 'set -a; source "$HOME/.systemd-env"; set +a; exec bash -c '"$(printf "%q" "$@")"
    else
        exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
            /bin/login -p -f "$SUDO_USER" \
            $(/bin/cat "$HOME/.systemd-env" | grep -v "^PATH=")
    fi
    echo "Existential crisis"
fi
# Edit the permissions of the enter-systemd-namespace script
sudo chmod +x /usr/sbin/enter-systemd-namespace
# Edit the bash.bashrc file
sudo sed -i 2a"# Start or enter a PID namespace in WSL2\nsource /usr/sbin/start-systemd-namespace\n" /etc/bash.bashrc

minikube-systemd-files

最后,退出并启动新的会话。您 不要 需要停止WSL2,一个新的会话就足够了:

minikube-systemd-enabled

迷你库:第一个集群

我们准备创建第一个集群:

# Check if the KUBECONFIG is not set
echo $KUBECONFIG
# Check if the .kube directory is created > if not, no need to create it
ls $HOME/.kube
# Check if the .minikube directory is created > if yes, delete it
ls $HOME/.minikube
# Create the cluster with sudo
sudo minikube start --driver=none

In order to be able to use kubectl with our user, 和 not sudo, 迷你库 recommends running the chown command:

# Change the owner of the .kube 和 .minikube directories
sudo chown -R $USER $HOME/.kube $HOME/.minikube
# Check the access 和 if the cluster is running
kubectl cluster-info
# Check the resources created
kubectl get all --all-namespaces

minikube-start-fixed

The cluster has been successfully created, 和 迷你库 used the WSL2 IP, which is great for several reasons, 和 one of them is that we can open the Kubernetes master URL in our Windows browser:

minikube-browse-k8s-master

And the real strength of WSL2 integration, the port 8443 once open on WSL2 distro, it actually forwards it to Windows, so instead of the need to remind the IP address, we can also reach the Kubernetes master URL via localhost:

minikube-browse-k8s-master-localhost

迷你库:我可以看到一个不错的仪表板吗?

在命令行上工作总是一件好事,而且很有见识。但是,在处理Kubernetes时,我们可能希望在某些时候有一个直观的概览。

为此,Minikube嵌入了 Kubernetes仪表板。有了它,运行和访问仪表板非常简单:

# Enable the Dashboard service
sudo minikube dashboard
# Access the Dashboard 从 a browser on Windows side

minikube-browse-dashboard

The command creates also a proxy, which means that once we end the command, by pressing CTRL+C, the Dashboard will no more be accessible.

Still, if we look at the namespace kubernetes-dashboard, we will see that the service is still created:

# Get all the services 从 the dashboard namespace
kubectl get all --namespace kubernetes-dashboard

minikube-dashboard-get-all

Let's edit the service 和 change it's type to LoadBalancer:

# Edit the Dashoard service
kubectl edit service/kubernetes-dashboard --namespace kubernetes-dashboard
# Go to the very end 和 remove the last 2 lines
status:
  loadBalancer: {}
# Change the type 从 ClusterIO to LoadBalancer
  type: LoadBalancer
# Save the file

minikube-dashboard-type-loadbalancer

再次检查Dashboard服务,让我们通过LoadBalancer访问Dashboard:

# Get all the services 从 the dashboard namespace
kubectl get all --namespace kubernetes-dashboard
# Access the Dashboard 从 a browser on Windows side with the URL: localhost:<port exposed>

minikube-browse-dashboard-loadbalancer

结论

显然,我们还有很长的路要走,因为我们可以实现一些LoadBalancing和/或其他服务(存储,入口,注册表等)。

关于WSL2上的Minikube,因为它需要启用SystemD,我们可以将其视为要实施的中间级别。

因此,通过两种解决方案,什么是“最适合您”?两者都有各自的优点和不便之处,因此,仅从我们的角度进行概述:

标准迷你库
在WSL2上安装很容易
多节点没有
外挂程式手动安装
坚持不懈是的,但不是为
备择方案K3dMicrok8s

我们希望您能真正体会到不同组件之间的集成:WSL2-Docker桌面-KinD / 迷你库。这样,您就可以在Windows和WSL2上使用KinD和/或Minikube为您的Kubernetes工作流提供一些想法,甚至更好的答案。

很快再见,以了解Kubernetes海洋的其他冒险活动。

no野 & 伊荷尔