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 deployment , kubectl get deployments , kubectl get deploy , kubectl 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-For 和 X-Forwarded-Uri 两个应用收到的请求头表名这是一个通过代理的访问。

结束你的应用

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

1
kubectl delete deployment fisrt-deploy-whoami

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

补充

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

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
谢谢鼓励