【03】Kubernets:K8S 操作入门

时间:2021-06-18 05:26:30

写在前面的话

经过上一节,我们顺利将 K8S 集群搭建了起来,在其中我也简单的谈了一下关于 K8S 的网络。那么这一节我们主要谈谈如何来简单的使用 K8S 的命令。当然这些命令有很多,我们只是通过一个小例子来操作讲解。是不全面的。

但是其实更多的目的是为了介绍一种方法。在后期的应用中,我们也会和 docker 一样,慢慢的摒弃掉这种纯手敲命令的形式,而且换成更为直观的资源清单(yaml 文件)的形式。

而且本章节我们会好好谈谈在 K8S 中非常重要的几个概念中的一部分,主要包括:Pod 和 Service 部分。

至于控制器 Controller 这些内容,我们会在更后边的时候详讲。

关于 Pod

我们一直都在说,Pod 是 K8S 能够调度的最小单元。那啥是 Pod?

Pod 其实是一个容器集,由 1 个甚至多个容器组成,它们的关系属于紧密到不宜分割。一个 Pod 内的所有容器都运行在同一个节点上。

我们可以做个比喻,把一个学校比作 K8S,我们每个人就像一个容器,那么一个班就是一个 Pod,同专业多个班一起组成 Service,学校一般调度都是调度的专业,当然他也可以调度某个班。但我们可以假设他不会有事没事专门去调度某个学生。

同一组的 Pod 共享 networks / uts / storage / volumes,通过 IPC 机制进行通讯。跨 Pod 的容器需要外部网络插件实现通信,每一个 Pod 有一个属于自己的 IP,此时容器就不再有自己的 IP 了。

对于 K8S 而言,最初和最终的目的都是为了运行 Pod,至于其他一些组件,其目的还是为了服务运行 Pod。

Pod 可以分为两类:自主式 Pod 和控制器管理的 Pod

此时我们再回头来看用户访问 K8S 的服务就可以这样理解:

用户访问的其实是某个提供服务的 Pod,请求先是到达宿主机(Node IP)的对应端口,然后将其转发给指定的 Service(Cluster IP),然后通过 kube-proxy 的 ipvs 规则再度将其转发到指定的 Pod(Pod IP)。当然到达 Pod 仍然会有相应的规则访问到 Pod 内的指定容器。

在我们使用集群的时候,还是建议在 K8S 集群外部再度加一层作为 Load Balance,同时辅以 Keepalive 实现高可用。

至于如果我们想隔离 Pod,只需要采用不同的名称空间(Namespace)就行。

关于 Service

当请求到达宿主机(Node IP)的时候,请求是无法直接到达 Pod 的,而且还可能是多个 Pod 的情况。

所以我们需要在这一个或者多个 Pod 前面再给它加一层,用来提供一个固定的访问端点(Cluster IP)。

通过标签选择器(Label selector)让 Pod 和这个访问端点(Service)进行绑定,就能实现 Service 网络和 Pod 网络的通信。

但我们最终目的还是实现宿主机 Node 网络和 Service 网络通信,这就需要 K8S 一个附件(DNS)来实现。具体细节就不多讲,我们大致知道这些原理就行。

【03】Kubernets:K8S 操作入门

你可能会有学习 docker 容器时一样的疑问,后端 Pod 说不定就重构了,IP 变了,岂不意味这我们需要关注 Service 的配置?

这是完全没有必要的,我们提到了 Service 网络到 Pod 网络是通过 Label selector 标签选择器绑定,这意味着,只要你标签不变,无论怎么更新,Service 上面的解析地址永远是对的。

同理,我们在 Node *问 Service 网络也不需要有这些担心,因为这里也不是直接通过 IP 访问,而且通过特定的名称。

最后需要记住,每组 Pod 应用都该拥有自己单独的 Service 进行调度。

关于 Controller

我们这里只是简单的先让大家知道有控制器这个东西,至于更加详细的关于各种控制器的功能,会在之后特定的资源清单的时候详解。

那么,啥是控制器(Controller)?

我们之前在第一节讲 Master 组成的时候说过,Master 由 Controller-manager / Scheduler / APIServer 组成,那时候说过,Controller-manager 是集群中进行统一资源管理的东西。那么 Controller 的作用就是管理 Pod 的运行规则。

在 K8S 中常见的 Controller 有以下几种:

1. ReplicationController

2. RelicaSet

3. Deployment(我们当前用的最多的,也是默认的)

4. StatefulSet

5. DeamonSet

6. Job,Cronjob

K8S 命令提示不全

这里单独提一下,当我们手敲 K8S 命令的时候,很多时候需要去 --help 看参数命令,这显然不方便,我们这里提供一个能够让我们 tab 键提示命令的配置。注意,第一配置后需要登出再次登录让环境生效。

yum install -y bash-completion
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc

K8S 命令

我们可以通过 kubectl -h 查看到 K8S 支持的命令,这里我做个简单的整理说明:

参数 说明
create 从文件或者输入创建
run 在集群中运行一个指定的镜像(几乎没用了)
expose 创建 Service
set 给对象设置一个指定的特征
explain 查看资源的文档(重要,帮助查参数)
get 获取资源信息(用的最多)
edit 直接编辑资源运行状态
delete 通过文件或者其他删除资源
rollout 主要用于版本升级和版本回滚(重要)
scale 直接更新资源的副本数量
autoscale 自动调整资源的副本数量
certificate 修改 certificate 资源
cluster-info 显示集群信息
top 显示系统资源使用情况
cordon 标记 node 为 unschedulable
uncordon 标记 node 为 schedulable
taint 更新 node 的 taints
describe 显示指定资源的详情(实用)
logs 输出容器在 pod 中的日志(重要,用于排错)
attach 进入到一个运行中的 container
exec 在一个 container 中执行一个命令
port-forward 端口转发
proxy 运行一个 proxy 到 Kubernetes API server
cp 复制
auth Inspect authorization
diff Diff live version against would-be applied version
apply 通过文件名或输入对资源进行配置(非常重要)
patch 更新资源的 field(s)
replace 通过文件或者输入换一个资源
wait Experimental: Wait for a specific condition on one or many resources
convert 在不同的 API versions 转换配置文件
kustomize Build a kustomization target from a directory or a remote url
label 更新在这个资源上的标签
annotate 更新一个资源的注解
completion Output shell completion code for the specified shell (bash or zsh)
api-resources Print the supported API resources on the server
api-versions Print the supported API versions on the server, in the form of "group/version"
config 修改 kubeconfig 文件
plugin Provides utilities for interacting with plugins
version 输出 client 和 server 的版本信息

有些没有翻译或者标记的,要么用的比较少,要么现阶段意义不大。

示例:增删查改一个 Nginx Pod

我们通过一个示例,看看整个过程中我们用到了那些命令。

【1】创建一个 Nginx Pod:

kubectl run nginx-demo --image=nginx:1.14-alpine --port=80 --replicas=1

结果如图:

【03】Kubernets:K8S 操作入门

这里简单的对命令进行一个说明:

我们通过 run 运行一个 deployment 控制器取名为 nginx-demo,并通过 --image 指定了镜像版本,--port 说明了服务端口,只是说明,并不能暴露端口,--replicas 指明了副本运行数量。

在命令执行过程中会有一个提示,不用在意,我们只需要看到下面 created,表明这个服务是创建成功的。

【2】查看 deployment 信息:

# 获取存在的 deployment
kubectl get deployment # 查看指定 deployment 信息
kubectl get deployment nginx-demo -o wide # 查看指定 deployment 详细的信息
kubectl describe deployment nginx-demo

结果如图:

【03】Kubernets:K8S 操作入门

这里有两个点需要知道,一是 -o wide,这个是显示更多信息,除此之外还有 -w,这个是动态显示,有点像 linux 的 top 命令。

另外一个就是 describe 命令的作用,该命令能够帮我排查启动过程中的错误,非常实用。

【3】查看 Pod 信息同理:

# 查看有哪些  pod
kubectl get pods # 查看指定 pod
kubectl get pods nginx-demo-549b77b6c5-5nwhz -o wide # 查看指定 pod 详细信息
kubectl describe pods nginx-demo-549b77b6c5-5nwhz

结果如图:

【03】Kubernets:K8S 操作入门

我们能够看到该 Pod 运行的节点与分配到的 IP 地址。

【4】集群内访问测试 Pod:

curl 10.1.2.2

结果如图:

【03】Kubernets:K8S 操作入门

可以看到集群内部是可以直接访问到 Pod 网段并访问到 Pod 的服务的。但是集群外部不行。

【5】让外部网络也能访问到 Nginx:

之前我们说过,想让外部访问,我们必须把在 Pod 外面再套一层 Service,让 Service 和宿主机之间做 DNS 解析。

所以我们来创建一个 Service:

kubectl expose deployment nginx-demo --name=nginx-svc --port=80 --target-port=80 --type=NodePort

这个命令可以看成,我们将名为 nginx-demo 的 deployment 的 80 端口暴露出去,并给这个 service 取名为 nginx-svc。

至于 type 的意义,后面我们会详细的讲解。

【6】查看创建的 Service:

# 查看有哪些 Service
kubectl get svc # 查看指定 Service
kubectl get svc nginx-svc -o wide

我们这里把 services 简写成 svc,方便使用。这种事情在 K8S 中很常见。结果如图:

【03】Kubernets:K8S 操作入门

可以看到,我们的服务被映射成为 32118 端口,这个端口是一个大于 的随机端口。

可以使用集群中任意节点 IP + 32118 端口访问到 Nginx:

【03】Kubernets:K8S 操作入门

【7】查看日志:

kubectl logs nginx-demo-549b77b6c5-5nwhz

结果如图:

【03】Kubernets:K8S 操作入门

【8】集群管理(扩容和缩减)

# 扩容成3个
kubectl scale deployment nginx-demo --replicas=3 # 查看
kubectl get deployment nginx-demo -o wide

结果如图:

【03】Kubernets:K8S 操作入门

同理,如果要减少节点数,只需要将 replicas 减小就行。

【9】版本升级与回滚:

首先来看下版本升级,其实际就是将镜像的版本做变更:

kubectl set image deployment nginx-demo nginx-demo=nginx:1.15-alpine --record

查看更新后结果:

kubectl describe deployment nginx-demo

结果如图:

【03】Kubernets:K8S 操作入门

此时,我们可以查看我们升级过的版本:

kubectl rollout history deployment nginx-demo

结果如图:

【03】Kubernets:K8S 操作入门

因为有了这个东西,我们回滚版本就有了两种选择,一是回滚上个版本,一是回滚指定版本:

# 回滚上个版本
kubectl rollout undo deployment nginx-demo # 回滚指定版本
kubectl rollout undo deployment nginx-demo --to-revision=2

--to-reversion 指定的数字就是通过 history 看到的编号。

【10】最后就是删除操作:

删除 Pod:

kubectl delete pod nginx-demo-76844fcc4d-49hf2

结果如图:

【03】Kubernets:K8S 操作入门

可以看到删除成功了,但是并没有意义,因为 K8S 会再给我启动一个新的,这就是 K8S 的自愈能力。

删除 deployment:

kubectl delete deployment nginx-demo

结果如图:

【03】Kubernets:K8S 操作入门

得到的结论是,deployment 删除,pod 也就跟着删除。

删除 Service:

kubectl delete svc nginx-svc

结果如图:

【03】Kubernets:K8S 操作入门

小结

我们这里提到的其实就是一小部分命令和参数,后续还会有很多,这得再之后用到的时候才方便详细讲解,后面也不会再以命令为主。

但这并不意味着这些基础的命令我们可以不知道,这些属于我们学习 K8S 的基础。