资源对象文件:kubenetes通过RC/RS管理POD,在RC中定义了如何启动POD,如何运行,启动几副本等功能,如果我们创建的文件在其中使用Yaml的语法格式描述了上面的信息,这个文件就是我们的资源对象文件.
资源对象文件的作用:可以创建,删除,管理资源对象
资源对象从哪里来:
资源对象文件一般由用户根据需求编写,我可以查询一个资源对象文件,包括json,yaml,wide
kubectl get 资源对象 资源名 -o 格式
一般的话,我们创建资源对象会选择deployment和service
[root@kubemaseter ~]# kubectl get pod test1-67b44cc6bf-rcmz2 -o yaml #查看pod对应的资源文件,但是我们一般是不直接使用
apiVersion: v1 #当前格式的版本
kind: Pod #当前创建资源的类型,当前类型是pod
metadata: #当前资源的元数据
creationTimestamp: 2020-06-11T06:39:24Z
generateName: test1-67b44cc6bf-
labels:
pod-template-hash: "2360077269"
run: test1
name: test1-67b44cc6bf-rcmz2 #当前资源的名字是元数据必须的项
namespace: default
ownerReferences:
- apiVersion: extensions/v1beta1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
name: test1-67b44cc6bf
uid: 4a1ca997-abae-11ea-9033-525400eb2966
resourceVersion: "1164287"
selfLink: /api/v1/namespaces/default/pods/test1-67b44cc6bf-rcmz2
uid: 4a20a194-abae-11ea-9033-525400eb2966
spec: #是当前pod的规格说明
containers:
- image: 192.168.1.100:5000/myos:latest
imagePullPolicy: Always
name: test1
resources: {}
stdin: true
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
tty: true
dnsPolicy: ClusterFirst
nodeName: kubenode2
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
status:
conditions:
- lastProbeTime: null
lastTransitionTime: 2020-06-11T06:39:24Z
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: 2020-06-11T06:41:44Z
status: "True"
type: Ready
- lastProbeTime: null
lastTransitionTime: 2020-06-11T06:39:24Z
status: "True"
type: PodScheduled
containerStatuses:
- containerID: docker://d79fc56955097465f2f38fba01f34c2978ec55be0cce666328e1cddb02594b32
image: 192.168.1.100:5000/myos:latest
imageID: docker-pullable://192.168.1.100:5000/myos@sha256:aa7b94907abef0d27fb0f50a1e803c1d20bb4338f8d4c5ab269bafc2ccff2dd5
lastState:
terminated:
containerID: docker://46c755a4c96a603783b7775684377e0410480b60dc978f59a1a8a55242a66261
exitCode: 0
finishedAt: 2020-06-11T06:41:39Z
reason: Completed
startedAt: 2020-06-11T06:39:31Z
name: test1
ready: true
restartCount: 1
state:
running:
startedAt: 2020-06-11T06:41:43Z
hostIP: 192.168.1.22
phase: Running
podIP: 10.254.45.3
qosClass: BestEffort
startTime: 2020-06-11T06:39:24Z
[root@kubemaseter ~]# kubectl get service apche -o yaml #服务对应的资源文件
apiVersion: v1
kind: Service
metadata:
creationTimestamp: 2020-06-11T06:29:33Z
labels:
run: my-apache
name: apche
namespace: default
resourceVersion: "1163182"
selfLink: /api/v1/namespaces/default/services/apche
uid: ea2d7f22-abac-11ea-9033-525400eb2966
spec:
clusterIP: 10.254.18.254
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: my-apache
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
编辑资源文件控制容器副本
[root@kubemaseter ~]# kubectl get deployment my-apache
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
my-apache 2 2 2 2 7h
[root@kubemaseter ~]# kubectl edit deployment my-apache
deployment.extensions "my-apache" edited
[root@kubemaseter ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-apache-7c49dcfd54-4lfxw 0/1 ContainerCreating 0 7s
my-apache-7c49dcfd54-cl8bd 1/1 Running 0 7h
my-apache-7c49dcfd54-xlxb7 1/1 Running 0 7h
如何使用资源文件
使用资源文件管理对象
kubectl (apply|create|delete ) -f 资源文件
create 创建资源对象, apply升级更新资源对象
delete 删除资源对象
Deployment 的资源对象的编写
---
apiVersion: extensions/v1beta1 #当前格式的版本
kind: Deployment #当前创建资源的类型,当前类型是Deployment
metadata: #当前资源的云数据
name: zhyapache #当前资源的名字,是元数据必须的项
spec: #是当前Deployment的规格说明
replicas: 1 #指当前创建的副本数量,默认值1
template: #定义的pod的模板
metadata: #当前pod的元数据
labels: #至少一个labels标签,可以任意创建一个key:value
app: zhyapache #标签名
spec: #当前pod的规格说明
containers: #容器
- name: zhyapache #是容器的名称,容器的名称是必须填写的
image: 192.168.1.100:5000/myos:httpd #镜像地址
stdin: true #交互式输入相当于 -i 参数
tty: true #打开终端相当于 -t 参数
service的资源对象编写
---
apiVersion: v1 #当前格式的版本
kind: Service #创建资源的类型
metadata: #当前资源的元数据
name: apche #资源名称
spec: #规格说明
ports: #端口
- port: 80 #服务端口
protocol: TCP #协议
targetPort: 80 #容器端口
selector: #标签选择器
run: my-apache #后端服务资源
type: ClusterIP #资源类型
举例1: 创建一个Deployment资源文件,是的它可以自动创建对应的pod
[root@kubemaseter ~]# vim httpd.yaml
---
apiVersion: extensions/v1beta1 #当前格式的版本
kind: Deployment #当前创建资源的类型,当前类型是Deployment
metadata: #当前资源的云数据
name: zhyapache #当前资源的名字,是元数据必须的项
spec: #是当前Deployment的规格说明
replicas: 1 #指当前创建的副本数量,默认值1
template: #定义的pod的模板
metadata: #当前pod的元数据
labels: #至少一个labels标签,可以任意创建一个key:value
app: zhyapache #标签名
spec: #当前pod的规格说明
containers: #容器
- name: zhyapache #是容器的名称,容器的名称是必须填写的
image: 192.168.1.100:5000/myos:httpd #镜像地址
stdin: true #交互式输入相当于 -i 参数
tty: true #打开终端相当于 -t 参数
[root@kubemaseter ~]# kubectl create -f httpd.yaml # 创建资源对象
deployment.extensions "zhyapache" created
[root@kubemaseter ~]# kubectl get pod #查看yaml创建的yaml文件
NAME READY STATUS RESTARTS AGE
my-apache-7c49dcfd54-4lfxw 1/1 Running 0 11h
my-apache-7c49dcfd54-cl8bd 1/1 Running 0 19h
my-apache-7c49dcfd54-xlxb7 1/1 Running 0 19h
test-69bf8fdc5-7c7f6 1/1 Running 1 19h
test1-67b44cc6bf-rcmz2 1/1 Running 1 19h
zhyapache-5799dbdf6b-zx2n4 1/1 Running 0 8s
[root@kubemaseter ~]# kubectl delete -f httpd.yaml #资源的回收,资源回收之后,对应的pod将会被回收掉
deployment.extensions "zhyapache" deleted
[root@kubemaseter ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
举例2:
编写资源文件:要求创建一个有2个服务的apche服务的pod,各这个web服务配置一个service来访问
刚刚入门,建议不要自己修改,在工作中也不要自己全部写,可以通过之前创建的Deployment或者service,通过看对应的yaml文件,通过这些yaml在去编写对应的资源文件
[root@kubemaseter ~]# kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
my-apache 3 3 3 3 19h
[root@kubemaseter ~]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
apche ClusterIP 10.254.18.254
[root@kubemaseter ~]# kubectl get deployment my-apache -o yaml >z1.yaml
[root@kubemaseter ~]# kubectl get service apche -o yaml > z2.yaml
[root@kubemaseter ~]# kubectl delete service apche
service "apche" deleted
[root@kubemaseter ~]# kubectl delete deployment my-apache
deployment.extensions "my-apache" deleted
[root@kubemaseter ~]# vim z1.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-apache
spec:
replicas: 3
template:
metadata:
labels:
run: my-apache
spec:
containers:
- image: 192.168.1.100:5000/myos:httpd
name: my-apache
[root@kubemaseter ~]# kubectl create -f z1.yaml
deployment.extensions "my-apache" created
[root@kubemaseter ~]# kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
my-apache 3 3 3 0 9s
[root@kubemaseter ~]# kubectl get replicaset
NAME DESIRED CURRENT READY AGE
my-apache-7c49dcfd54 3 3 3 21s
[root@kubemaseter ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-apache-7c49dcfd54-4mqff 1/1 Running 0 28s
my-apache-7c49dcfd54-kzn4x 1/1 Running 0 28s
my-apache-7c49dcfd54-mrh6s 1/1 Running 0 28s
[root@kubemaseter ~]# vim z2.yaml
apiVersion: v1
kind: Service
metadata:
name: apche
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: my-apache
type: ClusterIP
[root@kubemaseter ~]# kubectl create -f z2.yaml
service "apche" created
[root@kubemaseter ~]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
apche ClusterIP 10.254.94.26
在工作中,也可以将同一个服务,写在一个yaml文件中,比如我们可以把以上的Deployment和service合并成一个
[root@kubemaseter ~]# cat z12.yaml
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-apache
spec:
replicas: 3
template:
metadata:
labels:
app: my-apache
spec:
containers:
- image: 192.168.1.100:5000/myos:httpd
name: my-apache
---
apiVersion: v1
kind: Service
metadata:
name: apche
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: my-apache
type: ClusterIP
CondigMap是在pod中映射(文件或者目录)的一种方式,容许将配置文件与镜像文件分离,以使容器化的应用程序具有课移植性
在日常工作中经常要修改各种参数文件和参数,数据库的地址,用户名密码等,这些操作在容器内非常麻烦,pod在重启或者迁移时候又会恢复到初始的状态,使用ConfigMap就可以解决这样的问题
ConfigMap定义使用
举例:获取httpd.conf,并做出相应的修改
创建Configmap
kubectl create configmap 名称 --from-file=文件路径
举例需求:更改Apache的监听端口为8080
1,获取httpd.conf
[root@kubemaseter ~]# cat z1.yaml
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-apache
spec:
replicas: 1
template:
metadata:
labels:
app: my-apache
spec:
containers:
- image: 192.168.1.100:5000/myos:httpd
name: my-apache
[root@kubemaseter ~]# kubectl create -f z1.yaml
deployment.extensions "my-apache" created
[root@kubemaseter ~]# kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
my-apache 1 1 1 1 7s
[root@kubemaseter ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
my-apache-96d87dcb-2r77v 1/1 Running 0 9m 10.254.95.5 kubenode1
默认访问的是my-apache-96d87dcb-2r77v的80端口
[root@kubemaseter ~]# curl http://10.254.95.5:80
需要实现的是在外部改为配置文件可以作用与内部的容器,
[root@kubemaseter ~]# curl http://10.254.95.5:8080
curl: (7) Failed connect to 10.254.95.5:8080; 拒绝连接
将容器中的配置文件拷贝到容器外的的目录下,更改文件
[root@kubemaseter ~]# kubectl cp my-apache-96d87dcb-2r77v:/etc/httpd/conf/httpd.conf ./httpd.conf
tar: Removing leading `/' from member names
[root@kubemaseter ~]# ls
httpd.conf
[root@kubemaseter ~]# vim httpd.conf
42 Listen 8080
[root@kubemaseter ~]# kubectl create configmap my-httpd --from-file=./httpd.conf
configmap "my-httpd" created
[root@kubemaseter ~]# kubectl get configmap
NAME DATA AGE
my-httpd 1 6s
nginx.conf 1 15d
如果使用资源文件生成映射文件的方式,如果不是很清楚,可以参考一下用命令生成的Configmap在对于资源文件进行相应的更改.
映射目录
创建http应用中使用Configmap映射配置文件,Configmap映射文件到文件或者目录,主要这个时候,及时只是改动了目录里面一个文件,也需要全面拷贝出来,因为在做映射中会全部覆盖掉,如果目标目录存在就覆盖,不存在就创建出来.
映射目录
volumeMounts:
- mountPath: /etc/httpd/conf/httpd.conf #映射目录
name: config #引用的Configmap
volumes:
- name: config
configMap:
name: zhyapache
映射单一文件
映射单一文件需要使用subpath关键字(红色为一对名称)
volumeMounts:
- mountPath: /etc/httpd/conf/httpd.conf #映射完全路径
name: config #引用的Configmap
subPath: httpd.conf #目标文件名
volumes:
- name: config
configMap:
name: zhyapache #这个名称为kubectl get configmap 中的
[root@kubemaseter ~]# # kubectl get configmap -o yaml
[root@kubemaseter ~]# vim z1.yaml
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-apache
spec:
replicas: 1
template:
metadata:
labels:
app: my-apache
spec:
containers:
- image: 192.168.1.100:5000/myos:httpd
name: my-apache
volumeMounts:
- mountPath: /etc/httpd/conf/httpd.conf
name: config
subPath: httpd.conf
volumes:
- name: config
configMap:
name: my-httpd
[root@kubemaseter ~]# kubectl create -f z1.yaml
deployment.extensions "my-apache" created
[root@kubemaseter ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
my-apache-5ff6dd54f9-hc7lp 1/1 Running 0 10m 10.254.95.5 kubenode1
[root@kubemaseter ~]# curl http://10.254.95.5
curl: (7) Failed connect to 10.254.95.5:80; 拒绝连接
[root@kubemaseter ~]# curl http://10.254.95.5:8080
为什么需要卷?
容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题.首先,但容器崩溃时,kubelet会重启,但是容器中的文件将会丢失,容器以干净的状态(镜像最初的状态)重新启动.其次,在Pod中同时运行多个容器时,这些容器之间通常需要共享文件.kubenetes中的Volume抽象就很好的解决了这些问题.
k8s目前支持的卷如下:
emptyDir
emptyDir是最基础的Volume类型,用于存储临时数据的简单空目录.如果Pod设置了emptyDIr类型Volume,Pod被分配到Node上时候,会创建emptyDir,只要Pod运行在Node上,emptyDir都会存在(容器挂掉不会导致emptyDir丢失数据),但是如果Pod从Node上被删除或者Pod发生迁移,emptyDir也会被删除,并且永久丢失.emptyDir可以实现同一个pod中数据的共享.
emptyDir案例
创建emptyDir目录
volumeMounts:
- mountPath: /var/data #目标路径
name: empty-data #引用卷映射定义
volumes:
- name: empty-data #卷名称
emptyDir:{} #卷类型
NFS共享存储
在生成环境中经常需要多个pod或者多个APP中共享数据,而这些应用又在不同的机器的不同Pod里面,网络文件系统经常用来解决这一问题.Kubenetes中通过简单的配置就可以挂载NFS到Pod中,而NFS中的数据是可以永久保存的,同时NFS支持并发写操作.
当然cephfs,glusterfs,rbd等都能很好的解决这个问题.
NFS共享举例
步骤一:搭建一台所有节点都可以mount的nfs服务器
[root@nfs ~]# ifconfig eth0
eth0: flags=4163
inet 192.168.1.101 netmask 255.255.255.0 broadcast 192.168.1.255
[root@nfs ~]# yum -y install nfs-utils
[root@nfs ~]# yum -y install nfs-utils
[root@nfs ~]# mkdir -m 777 /var/webroot/
[root@nfs ~]# cat /etc/exports
/var/webroot *(rw)
[root@nfs ~]# systemctl start nfs
[root@nfs ~]# systemctl enable nfs
其他的node节点都需要安装如下
[root@node1 ~]# yum install -y nfs-utils
[root@node1~]# showmount -e 192.168.1.101
Export list for 192.168.1.101:
/var/webroot *
PV/PVC配置
pV/PVC是什么?
PersistentVolume持久卷,简称PV.是资源的提供者,根据集群的基础设施变化而变化,由k8s集群管理员配置
Persistent VolumeClaim (持久卷声明,简称PVC)是资源的使用者,根据业务服务的需求变化来配置
PV/PVC的引入使K8s集群具备了存储的逻辑抽象能力
[root@kubemaseter ~]# cat pv.yaml
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs
labels:
app: web-nfs
spec:
capacity:
storage: 20Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: /var/webroot
server: 192.168.1.101
[root@kubemaseter ~]# kubectl get pv
No resources found.
[root@kubemaseter ~]# kubectl create -f pv.yaml #生成资源文件
persistentvolume "pv-nfs" created
[root@kubemaseter ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs 20Gi RWX Retain Available 3s
[root@kubemaseter ~]# cat pvc.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-nfs
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 20Gi
selector:
matchLabels:
app: web-nfs
[root@kubemaseter ~]# kubectl create -f pvc.yaml
persistentvolumeclaim "pvc-nfs" created
[root@kubemaseter ~]# kubectl get pvc #可以看到pv和pvc已经绑定在一起了
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-nfs Bound pv-nfs 20Gi RWX 23s
[root@kubemaseter ~]# cat t6.yaml
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-apache
spec:
replicas: 1
template:
metadata:
labels:
app: my-apache
spec:
containers:
- image: 192.168.1.100:5000/myos:httpd
name: my-apache
volumeMounts:
- mountPath: /etc/httpd/conf/httpd.conf
name: config
subPath: httpd.conf
- mountPath: /var/www/html
name: site-data
volumes:
- name: config
configMap:
name: my-httpd
- name: site-data
persistentVolumeClaim:
claimName: pvc-nfs
[root@kubemaseter ~]# kubectl create -f t6.yaml
deployment.extensions "my-apache" created
[root@kubemaseter ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
my-apache-75644bd6d9-59p28 1/1 Running 0 2m 10.254.95.5 kubenode1
验证容器的目录是否挂载到了nfs上的方法,在nfs上写对应的文件,在使用容器的ip访问,如果可以正常访问到nfs的文件则证明成功
[root@nfs ~]# cd /var/webroot/
[root@nfs webroot]# ls
index.html
[root@nfs webroot]# cat index.html
hello world
hello world
hello world
[root@kubemaseter ~]# curl http://10.254.95.5:8080