前言

2021年,君不言容器技术则已,欲言容器则必称Docker,毫无疑问,它是当今最流行的容器技术之一,但是当我们面对海量的镜像与容器时,怎样快速精准的对海量容器进行管理和编排就又成了新的课题,此时,由Google开源的Kubernetes(读音[kubə’netis],业界也有称其k8s的,但k8s其实就是文盲版的Kubernetes,只是因为k和s之间有8个字母)就应时而生了,它是一个开源的用于多个主机虚拟成一个云平台后进行容器资源管理和应用编排引擎,致力于让部署容器化应用简单并且高效,提供了应用的全生命周期管理,如应用部署,规划,更新,维护等机制。本次我们尝试在Win10系统下,利用Kubernetes部署Gunicorn+Flask高可用Web集群项目。

安装Docker的俩种方式

一、 DockerDesktop(推荐)不需要开启Hyper-v可以和虚拟机兼容的

[点击下载安装包]

最新版系统(百度问客服自行解决)

所需文件

安装WSL2

步骤 1 - 启用适用于 Linux 的 Windows 子系统

需要先启用“适用于 Linux 的 Windows 子系统”可选功能,然后才能在 Windows 上安装 Linux 分发。

以管理员身份打开 PowerShell 并运行:

PowerShell复制

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

建议现在转到步骤 #2,更新到 WSL 2,但如果只想安装 WSL 1,现在可以重新启动计算机,然后继续执行步骤 6 - 安装所选的 Linux 发行版。 若要更新到 WSL 2,请等待重新启动计算机,然后继续执行下一步。

步骤 2 - 检查运行 WSL 2 的要求

若要更新到 WSL 2,需要运行 Windows 10。

  • 对于 x64 系统:版本 1903 或更高版本,采用 内部版本 18362 或更高版本。
  • 对于 ARM64 系统:版本 2004 或更高版本,采用 内部版本 19041 或更高版本。
  • 低于 18362 的版本不支持 WSL 2。 使用 Windows Update 助手更新 Windows 版本。

若要检查 Windows 版本及内部版本号,选择 Windows 徽标键 + R,然后键入“winver”,选择“确定”。 (或者在 Windows 命令提示符下输入 ver 命令)。 更新到“设置”菜单中的最新 Windows 版本

备注

如果运行的是 Windows 10 版本1903 或 1909,请在 Windows 菜单中打开“设置”,导航到“更新和安全性”,然后选择“检查更新”。 内部版本号必须是 18362.1049+ 或 18363.1049+,次要内部版本号需要高于 .1049。 阅读详细信息:WSL 2 即将支持 Windows 10 版本 1903 和 1909。 请参阅疑难解答说明

步骤 3 - 启用虚拟机功能

安装 WSL 2 之前,必须启用“虚拟机平台”可选功能。 计算机需要虚拟化功能才能使用此功能。

以管理员身份打开 PowerShell 并运行:

PowerShell复制

dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

重新启动 计算机,以完成 WSL 安装并更新到 WSL 2。

步骤 4 - 下载 Linux 内核更新包

  1. 下载最新包:

    备注

    如果使用的是 ARM64 计算机,请下载 ARM64 包。 如果不确定自己计算机的类型,请打开命令提示符或 PowerShell,并输入:systeminfo | find "System Type"

  2. 运行上一步中下载的更新包。 (双击以运行 - 系统将提示你提供提升的权限,选择“是”以批准此安装。)

安装完成后,请继续执行下一步 - 在安装新的 Linux 分发时,将 WSL 2 设置为默认版本。 (如果希望将新的 Linux 安装设置为 WSL 1,请跳过此步骤。)

备注

有关详细信息,请参阅 Windows 命令行博客上的文章对更新 WSL2 Linux 内核的更改

步骤 5 - 将 WSL 2 设置为默认版本

打开 PowerShell,然后在安装新的 Linux 发行版时运行以下命令,将 WSL 2 设置为默认版本:

PowerShell复制

wsl --set-default-version 2

步骤 6 - 安装所选的 Linux 分发

  1. 打开 Microsoft Store,并选择你偏好的 Linux 分发版。

    1

    单击以下链接会打开每个分发版的 Microsoft Store 页面:

  2. 在分发版的页面中,选择“获取”。

    2

首次启动新安装的 Linux 分发版时,将打开一个控制台窗口,系统会要求你等待一分钟或两分钟,以便文件解压缩并存储到电脑上。 未来的所有启动时间应不到一秒。

然后,需要为新的 Linux 分发版创建用户帐户和密码

image-20230830212347447

祝贺你!现已成功安装并设置了与 Windows 操作系统完全集成的 Linux 分发!

安装 Windows 终端(可选)

Windows 终端可启用多个选项卡(在多个 Linux 命令行、Windows 命令提示符、PowerShell 和 Azure CLI 等之间快速切换)、创建键绑定(用于打开或关闭选项卡、复制粘贴等的快捷方式键)、使用搜索功能,以及使用自定义主题(配色方案、字体样式和大小、背景图像/模糊/透明度)。 了解详细信息。

安装 Windows 终端

terminal

将分发版版本设置为 WSL 1 或 WSL 2

可打开 PowerShell 命令行并输入以下命令(仅在 Windows 内部版本 18362 或更高版本中可用),检查分配给每个已安装的 Linux 分发版的 WSL 版本:wsl -l -v

PowerShell复制

wsl --list --verbose

若要将分发版设置为受某一 WSL 版本支持,请运行:

PowerShell复制

wsl --set-version <distribution name> <versionNumber>

请确保将 <distribution name> 替换为你的分发版的实际名称,并将 <versionNumber> 替换为数字“1”或“2”。 可以随时更改回 WSL 1,方法是运行与上面相同的命令,但将“2”替换为“1”。

备注

从 WSL 1 更新到 WSL 2 可能需要几分钟才能完成,具体取决于目标分发版的大小。 如果从 Windows 10 周年更新或创意者更新运行 WSL 1 的旧(历史)安装,可能会遇到更新错误。 按照这些说明卸载并删除任何旧分发

如果 wsl --set-default-version 结果为无效命令,请输入 wsl --help。 如果 --set-default-version 未列出,则表示你的 OS 不支持它,你需要更新到版本 1903(内部版本 18362)或更高版本。

运行命令后如果看到此消息:WSL 2 requires an update to its kernel component. For information please visit https://aka.ms/wsl2kernel。 仍需要安装 MSI Linux 内核更新包。

此外,如果要使 WSL 2 成为你的默认体系结构,可以通过此命令执行该操作:

PowerShell复制

wsl --set-default-version 2

这会将安装的任何新分发版的版本设置为 WSL 2。

安装完成后 这时我们开启虚拟机发现是可以兼容的

在这里插入图片描述

二、普通安装

这里我们使用的就是Docker官方最新版3.1.0,内部集成的Kubernetes版本是1.19.3,在安装之前有两点要说明下,如果是Windows用户,需要确保系统版本为专业版:

img

第二,在专业版的基础上,开启系统的Hyper-v虚拟化功能:

img

双击安装包进行安装,默认安装在C盘目录,成功后,启动Docker-desktop,一般情况下,Docker很容易启动成功,

三、安装Kubernetes

但是Kubernetes往往会卡在启动界面,这是因为一些学术问题导致无法下载Kubernetes的依赖镜像,此时我们需要另辟蹊径,采用一些开源的三方库迂回帮我们下载这些镜像,这里推荐这个开源项目:https://github.com/AliyunContainerService/k8s-for-docker-desktop

最新版下载戳我

输入命令拉取项目:

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

进入项目的目录内,然后检查自己的Kubernetes版本号,该项目默认拉取的就是1.19.3的依赖镜像,如果您安装的Kubernetes是老版本,需要自行切换版本进行拉取操作:

如Kubernetes版本为 v1.18.8, 请使用下面命令切换 v1.18.8 分支 git checkout v1.18.8
如Kubernetes版本为 v1.18.6, 请使用下面命令切换 v1.18.6 分支 git checkout v1.18.6
如Kubernetes版本为 v1.18.3, 请使用下面命令切换 v1.18.3 分支 git checkout v1.18.3
如Kubernetes版本为 v1.16.5, 请使用下面命令切换 v1.16.5 分支 git checkout v1.16.5
如Kubernetes版本为 v1.15.5, 请使用下面命令切换 v1.15.5 分支 git checkout v1.15.5
如Kubernetes版本为 v1.15.4, 请使用下面命令切换 v1.15.4 分支 git checkout v1.15.4
如Kubernetes版本为 v1.14.8, 请使用下面命令切换 v1.14.8 分支 git checkout v1.14.8
如Kubernetes版本为 v1.14.7, 请使用下面命令切换 v1.14.7 分支 git checkout v1.14.7
如Kubernetes版本为 v1.14.6, 请使用下面命令切换 v1.14.6 分支 git checkout v1.14.6
如Kubernetes版本为 v1.14.3, 请使用下面命令切换 v1.14.3 分支 git checkout v1.14.3
如Kubernetes版本为 v1.14.1, 请使用下面命令切换 v1.14.1 分支 git checkout v1.14.1
如Kubernetes版本为 v1.13.0, 请使用下面命令切换 v1.13.0 分支 git checkout v1.13.0
如Kubernetes版本为 v1.10.11, 请使用下面命令切换 v1.10.11 分支 git checkout v1.10.11

下载完成进入k8s-for-docker-desktop.git执行

load_images.sh

执行后发现代理拉取Kubernetes依赖镜像:

C:\Users\wyx\Desktop\k8s-for-docker-desktop> load_images.sh

执行策略更改
执行策略可帮助你防止执行不信任的脚本。更改执行策略可能会产生安全风险,如 https:/go.microsoft.com/fwlink/?LinkID=135170
中的 about_Execution_Policies 帮助主题所述。是否要更改执行策略?
[Y] 是(Y)  [A] 全是(A)  [N] 否(N)  [L] 全否(L)  [S] 暂停(S)  [?] 帮助 (默认值为“N”): y
PS C:\Users\wyx> .\load_images.ps1
k8s.gcr.io/pause:3.2=registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2
3.2: Pulling from google_containers/pause
Digest: sha256:927d98197ec1141a368550822d18fa1c60bdae27b78b0c004f705f548c07814f
Status: Downloaded newer image for registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2
registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2
Untagged: registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2
Untagged: registry.cn-hangzhou.aliyuncs.com/google_containers/pause@sha256:927d98197ec1141a368550822d18fa1c60bdae27b78b0c004f705f548c07814f
k8s.gcr.io/kube-controller-manager:v1.19.3=registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.19.3
v1.19.3: Pulling from google_containers/kube-controller-manager
Digest: sha256:1ad35b623b9123c6aab99306ba5427e2829b36b378b9b80a6e988713ac5bffd4
Status: Downloaded newer image for registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.19.3
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.19.3
Untagged: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.19.3
Untagged: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager@sha256:1ad35b623b9123c6aab99306ba5427e2829b36b378b9b80a6e988713ac5bffd4

拉取结束后,执行命令查看镜像列表:

docker images

可以看到,针对Kubernetes1.19.3的基础镜像列表:

C:\Users\wyx>docker images
REPOSITORY                                                       TAG                                                     IMAGE ID       CREATED         SIZE
docker/desktop-kubernetes                                        kubernetes-v1.19.3-cni-v0.8.5-critools-v1.17.0-debian   bb2106081d17   2 months ago    285MB
k8s.gcr.io/kube-proxy                                            v1.19.3                                                 cdef7632a242   4 months ago    118MB
k8s.gcr.io/kube-scheduler                                        v1.19.3                                                 aaefbfa906bd   4 months ago    45.7MB
k8s.gcr.io/kube-apiserver                                        v1.19.3                                                 a301be0cd44b   4 months ago    119MB
k8s.gcr.io/kube-controller-manager                               v1.19.3                                                 9b60aca1d818   4 months ago    111MB
k8s.gcr.io/etcd                                                  3.4.13-0                                                0369cf4303ff   5 months ago    253MB
k8s.gcr.io/coredns                                               1.7.0                                                   bfe3a36ebd25   8 months ago    45.2MB
k8s.gcr.io/pause                                                 3.2                                                     80d28bedfe5d   12 months ago   683kB

在这里插入图片描述

Windows用户不需额外操作,直接重启Docker-desktop,并且点击开启Kubernetes服务:

随后,在命令行中键入命令:

kubectl version

如果能返回版本号说明安装和配置成功:

C:\Users\wyx>kubectl version
Client Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3", GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"clean", BuildDate:"2020-10-14T12:50:19Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"windows/amd64"}
Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3", GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"clean", BuildDate:"2020-10-14T12:41:49Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}

接下来,我们简单的部署一下Kubernetes容器,看看和Docker部署有何不同,先来看看Docker传统的部署方式,假设部署一台redis应用,首先拉取镜像:

docker pull redis

启动容器:

docker run -p 6380:6379 --name redis redis

使用redis客户端进行链接:

redis-cli -p 6380

返回数据库链接状态:

PS C:\Users\wyx> redis-cli -p 6380127.0.0.1:6380> pingPONG

没有任何问题,因为Docker直接操作的对象就是镜像和容器,而Kubernetes是基于Deployment来对集群的Pod和rs服务进行管理,每一个Deployment 都对应集群中的一次部署,所以Deployment是基本的 Kubernetes对象。

首先建立Deployment对象:

kubectl create deployment --image=redis redis

这里镜像还是使用刚才拉取的redis镜像,deployment别名设置为redis:

PS C:\Users\wyx> kubectl create deployment --image=redis redisdeployment.apps/redis created

创建成功后,启动rs服务:

kubectl expose deployment redis --port=6379 --name=redis-server

这里的端口号是pod中隔离容器的端口,而非主节点端口:

PS C:\Users\wyx> kubectl expose deployment redis --port=6379 --name=redis-serverservice/redis-server exposed

随后获取启动的pod列表:

kubectl get pods

我们知道pod是集群执行的最小单位,这里使用get pods来查看运行的pod:

PS C:\Users\wyx> kubectl get podsNAME                     READY   STATUS    RESTARTS   AGEredis-6749d7bd65-l8gnw   1/1     Running   0          64s

可以看到已经运行成功,最后需要将pod端口和主节点端口进行端口映射操作:

kubectl port-forward redis-6749d7bd65-l8gnw 6380:6379

这里的参数就是pod的name:

PS C:\Users\wyx> kubectl port-forward redis-6749d7bd65-l8gnw 6380:6379             Forwarding from 127.0.0.1:6380 -> 6379Forwarding from [::1]:6380 -> 6379Handling connection for 6380Handling connection for 6380

随后使用redis客户端进行链接:

PS C:\Users\Administrator> redis-cli -p 6380127.0.0.1:6380> pingPONG

这里就部署成功了,虽然流程上要比Docker直接部署要略微繁复一些,但是Kubernetes自带良好的伸缩和扩展以及高可用特性,一旦pod僵死或者宕机,可以自动生成新的pod的来实现高可用。

在这里插入图片描述

接下来尝试一些进阶操作,部署Gunicorn+Flask的Web应用,还记得之前的这篇文章:利用DockerHub在Centos7.7环境下部署Nginx反向代理Gunicorn+Flask独立架构 吗?里面详细阐述了如何使用Dockerfile打包镜像,这里我们拉取已经打包好的flask+gunicorn镜像:

四、Django

docker pull 515250339/mydjango

接着建立基于deployment的部署配置文件:deployment.yaml

apiVersion: v1
kind: Service
metadata:
  name: mydjango
spec:
  selector:
    app: mydjango
  ports:
  - protocol: "TCP"
    port: 8000
    targetPort: 8000
  type: LoadBalancer

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mydjango
spec:
  selector:
    matchLabels:
      app: mydjango
  replicas: 4
  template:
    metadata:
      labels:
        app: mydjango
    spec:
      containers:
      - name: mydjango
        image: 515250339/mydjango
        imagePullPolicy: Never
        ports:
        - containerPort: 8000

这个配置文件的含义是:将本地的myfalsk镜像作为Deployment基础镜像部署,集群运行四个pod来维持生产环境的服务保证,运行协议当然是TCP,主节点端口号和pod端口保持一致都是5000

然后执行命令启动服务:

kubectl apply -f deployment.yaml

查看服务状态:

C:\Users\wyx\Desktop>kubectl get pod
NAME                        READY   STATUS    RESTARTS   AGE
mydjango-7bd66b79c9-l72t7   1/1     Running   0          16s
mydjango-7bd66b79c9-lnv78   1/1     Running   0          16s
mydjango-7bd66b79c9-trf9f   1/1     Running   0          16s
mydjango-7bd66b79c9-wndd6   1/1     Running   0          16s

可以看到四台pod同时运行,访问网址:http://localhost:8000

没有问题,即使我们手动kill一台pod:

C:\Users\wyx\Desktop>kubectl delete pod mydjango-7bd66b79c9-l72t7
pod "mydjango-7bd66b79c9-l72t7" deleted
在这里插入图片描述

五、Flask

同理flask也是一样的流程

docker pull zcxey2911/myflask

接着建立基于deployment的部署配置文件:deployment.yaml

apiVersion: v1
kind: Service
metadata:
  name: myflask
spec:
  selector:
    app: myflask
  ports:
  - protocol: "TCP"
    port: 5000
    targetPort: 5000
  type: LoadBalancer

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myflask
spec:
  selector:
    matchLabels:
      app: myflask
  replicas: 4
  template:
    metadata:
      labels:
        app: myflask
    spec:
      containers:
      - name: myflask
        image: zcxey2911/myflask
        imagePullPolicy: Never
        ports:
        - containerPort: 5000

这个配置文件的含义是:将本地的myfalsk镜像作为Deployment基础镜像部署,集群运行四个pod来维持生产环境的服务保证,运行协议当然是TCP,主节点端口号和pod端口保持一致都是5000

然后执行命令启动服务:

kubectl apply -f deployment.yaml

查看服务状态:

C:\Users\wyx\Desktop>kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
myflask-dbcbcf9bf-6chj2   1/1     Running   0          87s
myflask-dbcbcf9bf-9qrzt   1/1     Running   0          5m21s
myflask-dbcbcf9bf-f4nqk   1/1     Running   0          5m21s
myflask-dbcbcf9bf-pbp6m   1/1     Running   0          5m21s
redis-6749d7bd65-r5r8g    1/1     Running   0          4h25m

可以看到四台pod同时运行,访问网址:http://localhost:5000

没有问题,即使我们手动kill一台pod:

C:\Users\wyx\Desktop> kubectl delete pod myflask-dbcbcf9bf-667rf
pod "myflask-dbcbcf9bf-667rf" deleted
在这里插入图片描述

可以看到集群立刻又会重新生成一个pod来维持服务稳定,这就是Docker原生容器所不具备的高可用特性。

关闭服务

kubectl delete -f deployment.yaml

可以看到服务已经关闭

C:\Users\wyx\Desktop>kubectl delete -f deployment.yaml
service "myflask" deleted
deployment.apps "myflask" deleted
C:\Users\wyx\Desktop>kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE

结语:未来已来,将至已至,在21世纪的第二个十年里,阿里、字节跳动、腾讯、百度等中国互联网行业巨擘们,都在加紧深耕容器领域,而Kubernetes也是这些大厂未来的战略核心。有了Kubernetes,我们就可以将整个大规模的服务器对计算资源抽象化通过一个个容器进行自动化且细致化管理,将最终的应用服务交还给用户,而用户则并不需要关心容器本身。