前言
经过前面几篇文章的实战案例,相信我们对k8s是如何部署应用也有了一定的了解。虽然部署的模板并不一定是最优的,但是基本上能解决大多数应用的部署问题。本文会着重讲解一下前几篇文章用到的Kubernetes 对象。
常用对象详解
当创建 Kubernetes 对象时,必须提供对象的规约,用来描述该对象的期望状态,以及关于对象的一些基本信息(例如名称)。 当使用 Kubernetes API 创建对象时(或者直接创建,或者基于
kubectl
),API 请求必须在请求体中包含 JSON 格式的信息。 大多数情况下,需要在 .yaml 文件中为kubectl
提供这些信息。kubectl
在发起 API 请求时,将这些信息转换成 JSON 格式。
必需字段
在想要创建的 Kubernetes 对象对应的 .yaml
文件中,需要配置如下的字段:
-
apiVersion
- 创建该对象所使用的 Kubernetes API 的版本 -
kind
- 想要创建的对象的类型- ConfigMap
- PersistentVolume
- PersistentVolumeClaim
- Deployment
- Service
- Ingress
- StorageClass(存储类,本文新增)
-
metadata
- 帮助识别对象唯一性的数据,包括一个name
字符串、UID 和可选的namespace
ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-cm
namespace: mldong-test
data:
a.conf: |-
server {
listen 80;
server_name a.mldong.com;
location / {
root /usr/share/nginx/html/a;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
b.conf: |-
server {
listen 80;
server_name b.mldong.com;
location / {
root /usr/share/nginx/html/b;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
在该例中:
- 将在命名空间
mldong-test
,由.metadata.namespace
字段指示。 - 创建名为
nginx-cm
的ConfigMap
,由.metadata.name
字段指示。 - 创建了两个配置文件
a.conf
和b.conf
,由.data
字段指示,key-value
的方式,key对应的是文件名,value对应的是文件内容 - 定义好的
ConfigMap
可由Deployment
的.template.spec.volumes[].name
指定
PersistentVolume
PersistentVolume(PV)用于为用户和管理员提供如何提供和消费存储的API,PV由管理员在集群中提供的存储。它就像Node一样是集群中的一种资源。PersistentVolume 也是和存储卷一样的一种插件,但其有着自己独立的生命周期。PersistentVolumeClaim (PVC)是用户对存储的请求,类似于Pod消费Node资源,PVC消费PV资源。Pod能够请求特定的资源(CPU和内存),声明请求特定的存储大小和访问模式。PV是一个系统的资源,因此没有所属的命名空间。
生命周期
- 供应(Provisioning):即PV的创建,可以直接创建PV(静态方式),也可以使用StorageClass动态创建
- 绑定(Binding):将PV分配给PVC
- 使用(Using):Pod通过PVC使用该Volume
- 释放(Releasing):Pod释放Volume并删除PVC
- 回收(Reclaiming):回收PV,可以保留PV以便下次使用,也可以直接从云存储中删除
apiVersion: v1
kind: PersistentVolume
metadata:
name: nginx-pv
labels:
alicloud-pvname: nginx-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
csi:
driver: nasplugin.csi.alibabacloud.com
volumeHandle: nginx-pv
volumeAttributes:
server: "9fdd94bf87-wfq66.cn-zhangjiakou.nas.aliyuncs.com"
path: "/"
vers: "3"
storageClassName: nas
在该例中:
- 创建名为
nginx-pv
的PersistentVolume
,由.metadata.name
字段指示。 - 创建一个大小为5G的卷,由
.spec.capacity.storage
字段指示。 - 该卷可进行读写,由``.spec.accessModes`字段指示
- ReadWriteOnce:可以被一个node读写。缩写为RWO。
- ReadOnlyMany:可以被多个node读取。缩写为ROX。
- ReadWriteMany:可以摆多个node读写。缩写为RWX。
- 使用的存储类为
nas
,csi插件由阿里提供,可参考阿里官方文档。
PersistentVolumeClaim
先略吧–后续存储卷开个单章来讲。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
annotations:
pv.kubernetes.io/bind-completed: 'yes'
pv.kubernetes.io/bound-by-controller: 'yes'
finalizers:
- kubernetes.io/pvc-protection
name: nginx-pvc
namespace: mldong-test
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
selector:
matchLabels:
alicloud-pvname: nginx-pv
storageClassName: nas
volumeMode: Filesystem
volumeName: nginx-pv
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: mldong-test
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry-vpc.cn-zhangjiakou.aliyuncs.com/mldong/java/nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: port
protocol: TCP
volumeMounts:
- name: nginx-pvc
mountPath: "/usr/share/nginx/html"
- name: nginx-cm
mountPath: "/etc/nginx/conf.d"
volumes:
- name: nginx-pvc
persistentVolumeClaim:
claimName: nginx-pvc
- name: nginx-cm
configMap:
name: nginx-cm
在该例中:
- 将在命名空间
mldong-test
,由.metadata.namespace
字段指示。 - 创建名为
nginx
的Deployment
,由.metadata.name
字段指示。 -
Deployment
创建3个复制的Pods
,由replicas
字段指示。 -
selector
字段定义Deployment
如何查找要管理的Pods
。 在这种情况下,只需选择在 Pod 模板(app: nginx
)中定义的标签。但是,更复杂的选择规则是可能的,只要Pod
模板本身满足规则。 -
template
字段包含以下子字段: -
Pod
标记为app: nginx
,使用labels
字段。 -
Pod
模板规范或.template.spec
字段指示Pods
运行一个容器,nginx
,运行nginx
私有镜像仓库版本latest
的镜像 。 - 创建一个容器并使用
name
字段将其命名为nginx
。 - 镜像拉取策略为
IfNotPresent
,由字段.template.spec.containers.imagePullPolicy
指示-
IfNotPresent
:如果不存在则拉取 -
Always
:总是拉取pull -
Never
:只使用本地镜像,从不摘取
-
- 创建容器对外暴露的端口为
80
,由字段``.template.spec.containers.ports[].containerPort`指示 - 创建容器挂载了两个目录
/usr/share/nginx/html
和/etc/nginx/conf.d
,由.template.spec.containers.volumeMounts[]
指示,其中name
对应的是.template.spec.volumes
中的name
,而volumes
的定义会有多种方式,如configMap
、persistentVolumeClaim
等。
当前,除了上述定义,可能还会用到其他的,比如
- 环境变量
.template.spec.containers.env
- 启动命令
.template.spec.containers.command
- 服务存活监测
.template.spec.containers.livenessProbe
- 资源定义限制
.template.spec.containers.resources
- 等等
Service
服务访问方式
ClusterIP方式
用于为集群内Pod访问时,提供的固定访问地址,默认是自动分配地址,可使用ClusterIP关键字指定固定IP.
- 将在命名空间
mldong-test
,由.metadata.namespace
字段指示。 - 创建名为
nginx
的Service
,由.metadata.name
字段指示 - 类型为
ClusterIP
的服务,由.spec.type
字段指示 - 对应着容器的端口为80,由
.spec.ports[].targetPort
字段指示 - 指定标签选择器选择的标签范围为
app:nginx
,由.spec.selector
指示,对应的Deployment.template.metadata.labels
- 使用该方式指定的服务,可以用过http://nodeIP:nodePort的方式访问
- 其中
- 可通过命令获取nodeport
kubectl get svc -n mldong-test
- 可通过命令获取nodeport
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: mldong-test
spec:
type: ClusterIP
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
NodePort方式
用于为集群外部访问Service后面Pod提供访问接入端口
这种类型的service工作流程为:
Client----->NodeIP:NodePort----->ClusterIP:ServicePort----->PodIP:ContainerPort
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
namespace: mldong-test
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
# nodePort: 32180 # 这里不指定就会随机(30000-32767)
selector:
app: nginx
在该例中:
- 将在命名空间
mldong-test
,由.metadata.namespace
字段指示。 - 创建名为
nginx-nodeport
的Service
,由.metadata.name
字段指示 - 类型为
NodePort
的服务,由.spec.type
字段指示 - 对应着容器的端口为80,由
.spec.ports[].targetPort
字段指示 - 指定标签选择器选择的标签范围为
app:nginx
,由.spec.selector
指示,对应的Deployment.template.metadata.labels
- 使用该方式指定的服务,可以用过http://nodeIP:nodePort的方式访问
- 其中
- 可通过命令获取节点ip
kubectl get nodes
- 可通过命令获取nodeport
kubectl get svc -n mldong-test
- 可通过命令获取节点ip
Ingress
Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。
Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管
internet
|
[ Ingress ]
--|-----|--
[ Services ]
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
name: nginx-ingress
namespace: mldong-test
spec:
rules:
- host: a.mldong.com
http:
paths:
- backend:
serviceName: nginx
servicePort: 80
path: /
- host: b.mldong.com
http:
paths:
- backend:
serviceName: nginx
servicePort: 80
path: /
在该例中:
- 将在命名空间
mldong-test
,由.metadata.namespace
字段指示。 - 创建名为
nginx-ingress
的Ingress
,由.metadata.name
字段指示
每个 HTTP 规则都包含以下信息:
- 可选主机。在此示例中,未指定主机,因此该规则适用于通过指定 IP 地址的所有入站 HTTP 通信。如果提供了主机(例如 a.mldong.com和b.mldong.com),则规则适用于该主机。
- 路径列表(例如,
/
),每个路径都有一个由serviceName
和servicePort
定义的关联后端。在负载均衡器将流量定向到引用的服务之前,主机和路径都必须匹配传入请求的内容。-
serviceName
对应的.Service.metadata.name -
servicePort
对应的.Service.spec.ports[].port
-
查看命令
kubectl get ingress -n mldong-test
结果中的ADDRESS即为域名解析的IP(阿里云这个值是空的,其为负载均衡器绑定的ip),如果在内网内,可以通过配置/etc/hosts,添加如下记录
IP a.mldong.com
IP b.mldong.com
即可通过如下方式访问服务
curl a.mldong.com
curl b.mldong.com
小结
唉,纯写文,我果然不是很擅长,后面再慢慢练吧。