K8S互动教程2-部署一个应用

本文是《浅入浅出k8s实战-k8s初体验篇的第三篇 》

此文为提取大纲,按照互动教程进行分享教学用。另补充一些知识点,和关联操作。

原文:

目标

  • 了解应用 Deployments
  • 使用 kubectl 在 Kubernetes 上部署您的第一个应用程序
  • 熟悉常用的 kubectl 命令

操作内容

  • kubectl 基础,查看 k8s 集群基本信息

  • 命令方式部署应用

  • 获取应用信息

    Kubernetes Deployments

  • 创建一个 Deployment,实际是在集群中创建 Deployment 配置,或者说把配置应用到集群中

  • Deployment 指示 K8S 如何去创建和更新应用程序实例

  • Kubernetes master 会将上述应用程序实例调度到集群中的各个 Node。

  • Kubernetes Deployment Controller 会持续监视这些实例,如果托管它的 Node 不可用或被删除,则 Deployment Controller 将替换原实例为集群中其他 Node 上的新实例。(自愈机制)


互动教程

Kubectl 基础

kubectl 命令通常的格式是 kubectl action resource 。就是 kubectl 后跟动作/命令,紧接着是要操作的资源。而资源由类型和名称定义。详细可以参照另一篇文章Kubectl 命令参考
每一个命令都可以通过 --help 获得更多的信息,比如 kubectl get --help , get 是我们要经常用的命令。

首先,通过 kubectl version 看一下我们的 kubectl 版本信息和他所对应的集群版本信息。
通过 kubectl get nodes 看一下集群里面的节点信息。

我们这节要操作的资源是 Deployment ,所以我们可以先通过 kubectl get deployment ,如果你看过我们上面提到的Kubectl 命令参考,你就知道,命令中的 deployment 属于资源类型,它的大小写,单复数并不重要。在我们集群中有了 Deployment 类型的资源后(下面的操作就会告诉你如何创建),你可以通过 kubectl get deploymentkubectl get deploymentskubectl get deploykubectl get Deployment 等获得一样的效果。
如果你是新的集群,你应该看到 no resources found 提示,否则可能已经有一些资源存在了。记得后面的命令自己修改名字来避免重复。

部署一个应用

kubectl run 命令可以创建一个 Deployment 来管理容器。其常用的命令格式是:

1
2
kubectl run NAME --image=image [--env="key=value"] [--port=port] [--replicas=replicas] [--dry-run=bool]
[--overrides=inline-json] [--command] -- [COMMAND] [args...] [options]

参数大多根据名字就能理解,主要的两个参数,NAME 是 Deployment 的名字, --image 指定镜像。进一步理解你肯定记得 --help 大法。

我们接下来通过 kubectl run 运行一个容器 registry.cn-hangzhou.aliyuncs.com/khan/whoami

这是一个可以输出 Http 请求信息的 docker 镜像,后面我们会经常使用。
其输出信息如下:

1
2
3
4
5
6
7
8
9
Hostname :  6e0030e67d6a
IP : 127.0.0.1
IP : ::1
IP : 172.17.0.27
IP : fe80::42:acff:fe11:1b
GET / HTTP/1.1
Host: 0.0.0.0:32769
User-Agent: curl/7.35.0
Accept: */*

OK,启动这个镜像:

1
kubectl run first-deploy-whoami --image=registry.cn-hangzhou.aliyuncs.com/khan/whoami:1.0 --port=80

我们可能会看到如下的提示信息:

1
2
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/first-deploy-whoami created

最后是提示创建成功,然而成功提示的上面的是什么呢。容我埋个伏笔,我们稍后再解释。

成功启动容器后,我们可以通过 kubectl get deployments 来查看刚刚创建的资源。你应该能看到这样的输出:

1
2
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
first-deploy-whoami 1/1 1 1 6s

查看你的应用

容器化的应用运行在集群内部(Kubernetes 集群中,我们称之为 Pod,是最小的调度单元),使用的是集群内部的网络。这个网通通常默认是私有的隔离的,对同一个Kubernetes 集群内部其他的容器和服务可见,但是集群外并不可以。当我们使用 kubectl 的时候,我们是通过一个 API 端点和集群进行通信。这个 API 端点是需要额外的认证和配置的,用外部工具如 curl 或浏览器等没有权限。

后续,我们会在互动教程4中来看如何通过其他的方式把应用(Pod)暴露到 kubernetes 集群之外。此节我们先通过 API 的本地 proxy 来实现。

kube proxy 命令能够创建一个本地的代理,转发通信请求到集群的私有网络。control-C可以关闭这个代理。
我们启动这个代理,默认情况下是绑定到 8001 端口,我们可以改为其他段扣,此处指定 8081:

1
kubectl proxy --port 8081

然后我们通过 http://localhost:8081 就可以访问到这个服务器信息,其会返回 JSON 格式的接口列表信息。可以通过 [http://localhost:8081/version](http://localhost:8081/version) 访问到版本号信息,和我们 kubectl version 拿到的服务器信息一致。

API Server 会自动地为每个 Pod 创建一个基于 Pod 名称的可访问端点。首先,我们需要获取这个 Pod 的名称。将其存储到上下文变量 POD_NAME 中,由于上一个命令行正在运行 proxy,我们打开新的命令行运行:

1
POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')

现在,我们可以通过 Http 请求来访问这个pod:

1
curl http://localhost:8081/api/v1/namespaces/default/pods/$POD_NAME/proxy/

应该可以输出如下的信息:

1
2
3
4
5
6
7
8
9
10
Hostname: first-deploy-whoami-68dd7db55-bpr52
IP: 127.0.0.1
IP: 172.17.0.2
GET / HTTP/1.1
Host: localhost:8081
User-Agent: curl/7.58.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 127.0.0.1, 192.168.99.1
X-Forwarded-Uri: /api/v1/namespaces/default/pods/first-deploy-whoami-68dd7db55-bpr52/proxy/

你也可以通过浏览器访问 http://localhost:8081/api/v1/namespaces/default/pods/ 可以看到所有 pod,然后将名称复制下来,组成同样的链接访问。

在上面的信息中,我们可以看到, X-Forwarded-ForX-Forwarded-Uri 两个应用收到的请求头表名这是一个通过代理的访问。

结束你的应用

可以通过 kubectl delete 命令删除我们刚刚的 Deployment:

1
kubectl delete deployment fisrt-deploy-whoami

命令简单易懂,就不再解释了。

补充

回到上面我们埋下的伏笔, kubectl runDEPRECATED 的信息。其文档中有说明

1
2
 --generator='': The name of the API generator to use, see
http://kubernetes.io/docs/user-guide/kubectl-conventions/#generators for a list.

实际上, --generator 是指示 kubectl run 命令最终生成什么资源。用不用的生成器,生成的资源就不同。目前(1.14.2)默认生成器是 deployment/apps.v1
我们可以访问 https://kubernetes.io/docs/reference/kubectl/conventions/#generators 查看所有的生成器。
如果切换为如下的命令,将不再有提示,但请注意命令执行后的描述,而且,执行这条命令并不会和同名的 deployment 冲突,之前的 deployment删除和不删除都无印象。你能知道为什么以及如何查看新生产的资源吗?

1
kubectl run first-deploy-whoami --image=registry.cn-hangzhou.aliyuncs.com/khan/whoami:1.0 --port=80 --generator=run-pod/v1
谢谢鼓励