Kubernetes(一)认识 kubernetes
Kubernets(二)部署非高可用Kubernetes集群的环境准备
Kubernets(三)部署非高可用Kubernetes集群-通过阿里云源安装 kubeadm、kubelet 和 kubectl
Kubernets(四)创建集群
Kubernetes(五)揭开 kubeadm 的神秘面纱
Kubernetes(六)第一个kubernetes 对象
yum install bash-completion
echo 'source <(kubectl completion bash)' >>~/.bashrc
之后退出当前终端,重新连接登录
kubernetes 推荐使用 配置文件 运行一个或者多个容器,当然也支持命令行方式。
配置文件可以是:
yaml 文件比较易读,因此后面都会使用 yaml 风格的文件去描述一个 kubernetes 对象的各种属性。
即:把容器的定义、参数、配置,统统记录在一个 YAML 文件中,然后用这样一句指令把它运行起来:
kubectl apply -f 你的配置文件
这样的好处是,可以很好的记录下 kubernetes 都运行了什么。
下面是一个运行 nginx 容器的例子
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.8
ports:
- containerPort: 80
保存以上内容到一个 .yml
结尾的文件中, 这里用的是 nginx.yml
像这样的一个 YAML 文件,对应到 Kubernetes 中,就是一个 API Object(API 对象)。当你为这个对象的各个字段填好值并提交给 Kubernetes 之后,Kubernetes 就会负责创建出这些对象所定义的容器或者其他类型的 API 资源。
要运行它,执行如下命令:
kubectl apply -f nginx.yml
执行了 kubectl apply -f nginx.yml
之后,
接着,在接下来的时间内可以反复运行如下命令,以便观察是否符合我们预期。
运行此容器的节点会先下载容器的镜像,因此不一定会立刻就绪
kubectl get pods -l app=nginx
下图是还未创建好的状态
其中的 NAME 字段就是容器名称的一部分,其中最后的 5 位字符唯一标识了一个容器。我们可以利用最后 5 个字符去运行它们的节点过滤出来。
而下图是创建好并处于运行的状态
稍后片刻,假如一直没有看到 READY 字段的值为 1/1
,可以使用如下命令查看某个容器的运行于那个节点以及发生的事件等信息。
kubectl describe pods nginx-deployment-64c9d67564-hdp8k
信息输出的比较多,一般我们会观察最后输出的 Events:
字段下面的内容。
下面的内容最后一行的 Pulling image
表示容器使用的镜像正在下载。
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m1s default-scheduler Successfully assigned default/nginx-deployment-64c9d67564-hdp8k to k8s-node3
Normal Pulling 119s kubelet Pulling image "nginx:1.8"
从上面的事件信息中的第一行可以看出此容器运行于哪个节点。
下面的内容表示容器已经成功运行了
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 3m9s default-scheduler Successfully assigned default/nginx-deployment-64c9d67564-hdp8k to k8s-node3
Normal Pulling 3m7s kubelet Pulling image "nginx:1.8"
Normal Pulled 14s kubelet Successfully pulled image "nginx:1.8" in 2m53.318464042s
Normal Created 14s kubelet Created container nginx
Normal Started 14s kubelet Started container nginx
加参数 --force --grace-period=0,grace-period表示过渡存活期,默认30s,在删除POD之前允许POD慢慢终止其上的容器进程,从而优雅退出,0表示立即终止POD
kubectl -n <name-space> delete po <your-pod-name> --force --grace-period=0
再来看看刚才的那个 YAML 文件内容
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.8
ports:
- containerPort: 80
其实上面这样一个 YAML 文件中定义的都是 Kubernetes API 对象。
在 Kubernetes 系统中,Kubernetes 对象 是持久化的实体。
Kubernetes 使用这些实体去表示整个集群的状态。
特别地,它们描述了如下信息:
Kubernetes 对象是 “目标性记录” —— 一旦创建对象,Kubernetes 系统将持续工作以确保对象存在。
通过创建对象,本质上是在告知 Kubernetes 系统,所需要的集群工作负载看起来是什么样子的, 这就是 Kubernetes 集群的 期望状态(Desired State)。
几乎每个 Kubernetes 对象包含两个嵌套的对象字段,它们负责管理对象的配置: 对象 spec(规约) 和 对象 status(状态) 。
按照惯例,kubernetesapi 将对象的期望状态的规范与当前对象的状态区分开来。
该规范是对所需状态的完整描述,包括用户提供的配置设置、系统扩展的默认值以及其他生态系统组件(如调度器)创建后初始化或以其他方式更改的属性,并与API对象一起保存在稳定存储中。
对于具有 spec 的对象,你必须在创建对象时设置其内容,描述你希望对象所具有的特征: 期望状态(Desired State) 。
例如如下所述:
spec 是静态的,是存在于 YAML 文件中的。
status 描述了对象在系统中的 当前状态(Current State),它是由 Kubernetes 系统和组件 设置并更新的。
在大多数情况下,用户不需要对此进行更改。
使用如下命令可获取:
kubectl get pods 具体的一个容器名称 -o yaml
在任何时刻,Kubernetes 控制平面 都一直积极地管理着对象的实际状态,以使之与期望状态相匹配。
部署或发布对象的新版本时,“spec” 会立即更新并可用。
随着时间的推移,系统将使“status”与“spec”保持一致。
无论以前版本如何,系统都将朝着最新的“spec”前进。换言之,如果一个值在一次输入中从2变为5,然后在另一次输入中又变回3,则在将“status”变为3之前,系统不需要在5处“触底”。换句话说,系统的行为是基于级别的,而不是基于边缘的。这使得在存在遗漏的中间状态更改时能够实现健壮的行为。
在想要创建的 Kubernetes 对象对应的 .yaml 文件中,需要配置如下的字段:
你也需要提供对象的 spec 字段。
对象 spec 的精确格式对每个 Kubernetes 对象来说是不同的,包含了特定于该对象的嵌套字段。
kubectl explain pod
kubectl explain deployment
kubectl explain deployment.spec
kubectl explain deployment.spec.template
Kubernetes API 参考 能够帮助我们找到任何我们想创建的对象的 spec 格式。
例如:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.8
ports:
- containerPort: 80
apiVersion
指定 Kubernetes API 的版本
metadata
API 对象的元数据,它也是我们从 Kubernetes 里找到这个对象的主要依据。都是 key-value 的形式,这部分的内容大部分的 API 对象都一样。
kind
指定了这个 API 对象的类型(Type)这里的类型是 Deployment。
Deployment 就是负责在 Pod 定义发生变化时,对每个副本进行滚动更新(Rolling Update)。
spec
就是对具体的 API 对象进行详细描述。这部分每个 API 对象都有自己的特征,所以内容也不一样。
selector
是一个选择器,对需要调度的目标对象进行筛选。
是针对 spec.template.metadata.labels
下定义的键值对进行筛选的。
replicas
指定副本的个数
template
定义 Pod 的具体长什么样子
containers
定义关于 Pod 中容器的相关属性
修改 nginx.yml 文件中的 image:
部分的值:
由原来的:
image: nginx:1.8
修改为:
image: nginx:1.9
之后执行如下命令进行生效
kubectl apply -f nginx.yml
在接下来的几分钟时间内,可以间歇性的反复使用如下命令来观察整个更新的过程(被调度的节点会依次执行下载镜像,运行容器的动作)。
kubectl get pods
kubectl describe pods
通过上面的更新示例,相信你可以体会到:
Kubernetes 会根据 YAML 文件的内容变化,自动进行具体的处理。
而这个流程的好处是,它有助于帮助开发和运维人员,围绕着可以版本化管理的 YAML 文件,而不是“行踪不定”的命令行进行协作,从而大大降低开发人员和运维人员之间的沟通成本。
在整个版本演进的过程中,还可以使用 git diff
命令观察其中某两次版本的演进内容。
所以说,如果通过容器镜像,我们能够保证应用本身在开发与部署环境里的一致性的话,那么现在,Kubernetes 项目通过这些 YAML 文件,就保证了应用的“部署参数”在开发与部署环境中的一致性。
而当应用本身发生变化时,开发人员和运维人员可以依靠容器镜像来进行同步;当应用部署参数发生变化时,这些 YAML 文件就是他们相互沟通和信任的媒介。
kubectl delete -f nginx.yml