第5章 常用资源类型
1.工作负载类型
RC ReplicationController #副本控制器 不用
RS ReplicaSet #RC的升级版 不用
DP Deployment #自动创建和管理RS
DS DaemonSet #每个节点只运行一个POD
2.服务发现及负载均衡
Service
Ingress
3.配置与存储资源
ConfigMap 存储配置文件
Secret 存储用户字典
4.集群级别资源
Namespace
Node
Role
ClusterRole
RoleBinding
ClusterRoleBinding
第6章 资源配置清单
1.创建资源的方法
在Docker时代,我们可以使⽤docker run或者docker-compose来管理容器。但是在k8s⾥,我们使⽤json格 式或者YAML格式的资源清单来描述应⽤。 但是相对来说,yaml格式更容器理解和阅读,所以我们都是使⽤yaml格式来声明
apiserver仅能接受json格式的资源定义 yaml格式提供的清单,apiserver可以自动将其转换为json格式再提交
2.资源清单介绍
查看资源清单所需字段
kubectl explain pod
kubectl explain pod.spec
kubectl explain pod.spec.volumes
资源清单字段介绍
apiVersion: v1 #属于k8s哪一个API版本或组
kind: Pod #资源类型
metadata: #元数据,嵌套字段
spec: #定义容器的规范,创建的容器应该有哪些特性
status: #只读的,由系统控制,显示当前容器的状态
3.使用资源配置清单创建POD
3.1首先使用命令行创建一个pod
kubectl create deployment nginx --image=nginx:alpine
kubectl get pod -o wide
3.2 将刚才创建的pod配置到处成yaml格式
kubectl get pod -o yaml > nginx-pod.yaml
3.3 精简资源清单,删掉不需要的配置
cat nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
json格式写法:
{
apiVersion: "v1",
kind: "Pod",
metadata:
{
name: "nginx",
labels:
{
app: "nginx"
}
}
spec:
{
containers:
{
name: "nginx",
image: "nginx:alpine",
imagePullPolicy: "IfNotPresent"
}
}
}
3.5 删除命令行创建的资源
kubectl delete deployments.apps nginx
3.6 应用资源配置清单
kubectl create -f nginx-pod.yaml
3.7 查看pod信息
kubectl get pod -o wide
3.8 查看pod详细信息
kubectl describe pod nginx
4.POD资源清单总结
声明式管理 我想运行一个Nginx k8s帮你干活
apiVersion: v1 #api版本
kind: Pod #资源类型
metadata: #元数据
name: nginx #pod显示名称,不可重复
labels: #pod标签
app: nginx
spec: #容器定义
containers: #容器的特性
- name: nginx #容器名称
image: nginx:alpine #容器的镜像名称
imagePullPolicy: IfNotPresent #容器的拉取策略
ports: #容器端口
- name: http
containerPort: 80 #容器暴露的端口
第7章 Node节点标签设置
1.查看node的标签
kubectl get node --show-labels
2.给node打标签
kubectl label nodes node1 CPU=Xeon
kubectl label nodes node2 disktype=ssd
3.编辑POD资源配置清单,使用node标签选择器
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.0
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
nodeSelector: #指定标签选择
#CPU: Xeon #给节点打的标签,注意:要跟打的标签名一致
disktype: SSD
4.删除容器重新创建
kubectl delete pod nginx
kubectl create -f nginx-pod.yaml
5.查看结果
kubectl get pod -o wide
6.删除节点标签
kubectl label nodes node1 CPU-
kubectl label nodes node2 disktype-
第8章 Pod容器打标签及使用
1.标签说明
一个标签可以给多个POD使用
一个POD也可以拥有多个标签
2.查看POD标签
kubectl get pod --show-labels
3.添加标签方法
3.1 方法1:直接编辑资源配置清单:
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx # 打标签
release: beta
3.2 方法2:命令行打标签
kubectl label pods nginx release=beta
kubectl label pods nginx job=linux
kubectl get pod --show-labels
4.删除标签
kubectl label pod nginx job-
kubectl get pod --show-labels
5.POD标签实验
5.1 生成2个不同标签的POD
kubectl create deployment nginx --image=nginx:1.14.0
kubectl get pod --show-labels
kubectl label pods nginx-xxxxxxxx release=stable
kubectl get pod --show-labels
5.2 根据标签查看
kubectl get pods -l release=beta --show-labels
kubectl get pods -l release=stable --show-labels
5.3 根据标签删除
kubectl delete pod -l app=nginx
第9章 重新认识pod
1.Pod的原理
1.1 共享⽹络空间
POD内的容器使⽤container模式共享根容器的⽹络
容器看到的⽹络设备信息和根容器完全相同
POD内的多个容器可以直接使⽤localhost通信
POD内的多个容器不能绑定相同的端⼝
POD的⽣命周期和根容器⼀样,如果根容器推出,POD就退出了
可以在node节点使⽤docker inspect查看容器的详细信息,会发现有⽹络模式为container
[root@node2 ~]# docker inspect 6d636151f567|grep "NetworkMode""NetworkMode": "container:1613f2dee9e410805679c6073ee7c1a9160c3fd24b7135f7e5ed17ffc6502ee2",
1.2 共享⽂件系统
默认情况下⼀个POD内的容器⽂件系统是互相隔离的
如果想让⼀个POD的容器共享⽂件,那么只需要定义⼀个Volume,然后两个容器分别挂在这个Volume就可以共享了
举个例⼦:
cat > nginx_vo_hostPath.yaml << 'EOF'
apiVersion: v1
kind: Pod
metadata:
name: nginx-volume
spec:
nodeName: node2
volumes:
- name: nginxlog
emptyDir: {}
#hostPath:
# path: /var/log/nginx/
containers:
- name: nginx
image: nginx:alpine
volumeMounts:
- name: nginxlog
mountPath: /var/log/nginx/
- name: tail-log
image: busybox
args: [/bin/sh, -c, 'tail -f /var/log/nginx/access.log']
volumeMounts:
- name: nginxlog
mountPath: /var/log/nginx/
EOF
2.Pod的⽣命周期
init container:
初始化容器是指在主容器启动之前,先启动⼀个容器来做⼀些准备⼯作,⽐如两个容器做了共享volum,然后可以先启动⼀个容器来对⽬录进⾏更改⽤户授权。
⽐如主容器需要连接数据库,可以先使⽤初始化容器测试可否正常连接数据库,如果可以正常连接再启动主容器。
hook:
PostStart:在容器启动创建后⽴刻执⾏,但是时间不能太⻓,否则容器将不会是running状态
PreStop:在容器停⽌被删除前执⾏,主要⽤于优雅的关闭应⽤程序。
liveness probe:
存活性探针,⽤于确定容器内的应⽤是否还活着
readiness probe:
就绪性探针,⽤于确定容器是否已经准备就绪可以⼲活了,⽐如扩容⼀个Pod,只有等这个Pod⾥⾯的应⽤完全启动了,才会将流量进⼊。
3.POD运⾏状态
Pending(挂起):
Pod 已被Kubernetes 系统接受,但有⼀个或者多个容器尚未创建亦未运⾏。此阶段包括等待 Pod 被调度的时间和通过⽹络下载镜像的时间
Running(运⾏中):
Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。⾄少有⼀个容器仍在运⾏,或者正处于启动或重启状态。
Succeeded(成功):
Pod 中的所有容器都已成功终⽌,并且不会再重启
Failed(失败):
Pod 中的所有容器都已终⽌,并且⾄少有⼀个容器是因为失败终⽌。也就是说,容器以⾮ 0 状态退出或者被系统终⽌
Unknown(未知):
因为某些原因⽆法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。
4.Pod对容器的封装和应⽤
涉及到数据类的问题,要解决数据的完整性,访问以及数据写入的唯一性
那么在⼯作中我们究竟如何决策⼀个POD是跑⼀个容器还是多个容器呢? 在实际⼯作中我们除了完成任务以外还需要考虑以后扩容的问题,就拿wordpress举例,有以下两种⽅案:
第⼀种:全部放⼀个pod⾥
第⼆种:Wordpress和MySQL分开
那么如何扩容呢?如果第⼀种⽅案⼤家会发现没有办法很好的扩容,因为数据库和wordpress已经绑定成⼀个整体 了,扩容wordpress就得扩容mysql。⽽第⼆种⽅案就要灵活的多
总结:
多个容器之间是否⾮常紧密的关系,⽐如nginx和php就⾮常紧密,但是php和mysql不紧密
这些容器是否必须是⼀个整体
这些容器放在⼀起是否影响扩容
5.初始化容器
cat > nginx_init.yaml << 'EOF'
apiVersion: v1
kind: Pod
metadata:
name: nginx-init
spec:
nodeName: node2
volumes:
- name: nginx-index
emptyDir: {}
initContainers:
- name: init
image: busybox
args: [/bin/sh, -c, 'echo k8s >> /usr/share/nginx/html/index.html']
volumeMounts:
- name: nginx-index
mountPath: /usr/share/nginx/html
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: nginx-index
mountPath: /usr/share/nginx/html
EOF
6.Pod hook 钩子
postStart:
apiVersion: v1
kind: Pod
metadata:
name: nginx-postStart
spec:
nodeName: node2
containers:
- name: nginx
image: nginx:alpine
lifecycle:
postStart:
exec:
command: [/bin/sh, -c, 'echo k8s >> /usr/share/nginx/html/index.html']
ports:
- containerPort: 80
preStop:
apiVersion: v1
kind: Pod
metadata:
name: nginx-life
spec:
nodeName: node2
volumes:
- name: nginxlog
hostPath:
path: /var/log/nginx/
containers:
- name: nginx
image: nginx:alpine
lifecycle:
postStart:
exec:
command: [/bin/sh, -c, 'echo k8s > /usr/share/nginx/html/index.html']
preStop:
exec:
command: [/bin/sh, -c, 'echo bye > /var/log/nginx/stop.log']
ports:
- containerPort: 80
volumeMounts:
- name: nginxlog
mountPath: /var/log/nginx/
7.Pod 健康检查
7.1 存活探针
存活探针简单来说就是⽤来检测容器的应⽤程序是否还正常⼯作,如果应⽤程序不正常,即使容器还活着也没有意义了,所以这时候就可以使⽤存活探针来探测,如果应⽤程序不正常,就重启POD
存活探针语法:
apiVersion: v1
kind: Pod
metadata:
name: liveness-pod
spec:
nodeName: node2
volumes:
- name: nginx-html
hostPath:
path: /usr/share/nginx/html/
containers:
- name: liveness
image: nginx
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
exec:
command: [/bin/sh, -c, 'echo k8s > /usr/share/nginx/html/index.html']
livenessProbe:
exec:
command:
- cat
- /usr/share/nginx/html/index.html
initialDelaySeconds: 3
periodSeconds: 1
volumeMounts:
- name: nginx-html
mountPath: /usr/share/nginx/html/
配置解释:
livenessProbe: #存活探针
exec: #执⾏命令
command: #具体的命令结果0的状态被视为存活,⾮零是不健康的
- cat
- /usr/share/nginx/html/index.html
initialDelaySeconds: 3 #第⼀次执⾏探针的时候等待5秒
periodSeconds: 1 #每隔5秒执⾏⼀次存活探针,默认为10秒,最⼩值为1秒
通过命令可以查看Pod的详细状态
kubectl describe pod liveness-pod
kubectl get pod -w
除了我们⾃⼰写的命令以外,也⽀持基于http请求:
apiVersion: v1
kind: Pod
metadata:
name: liveness-pod
spec:
nodeName: node2
volumes:
- name: nginx-html
hostPath:
path: /usr/share/nginx/html/
containers:
- name: liveness
image: nginx
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
exec:
command: [/bin/sh, -c, 'echo k8s > /usr/share/nginx/html/index.html']
livenessProbe:
httpGet:
path: /index.html
port: 80
initialDelaySeconds: 3
periodSeconds: 1
volumeMounts:
- name: nginx-html
mountPath: /usr/share/nginx/html/
参数解释:
livenessProbe:
httpGet: #基于http请求探测
path: /index.html #请求地址,如果这个地址返回的状态码在200-400之间正常
port: 80 #请求的端⼝
initialDelaySeconds: 3 #第⼀次启动探测在容器启动后3秒开始
periodSeconds: 1 #容器启动后每隔3秒检查⼀次
7.2 就绪探针
有时候我们Pod本身已经起来了,但是pod的容器还没有完全准备好对外提供服务,那么这时候流量进来就会造成请求失败的情况出现,针对这种情况k8s有⼀种探针叫就绪探针,他的作⽤就是让k8s知道你的Pod内应⽤是否准备好为请求提供服务。只有就绪探针ok了才会把流量转发到pod上
配置语法:就绪探针的配置语法和存活探针基本⼀样
apiVersion: v1
kind: Pod
metadata:
name: liveness-pod
spec:
containers:
- name: liveness-pod
image: nginx
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo ok > /usr/share/nginx/html/health.html"]
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 5
timeoutSeconds: 3
periodSeconds: 3
successThreshold: 3
failureThreshold: 3
livenessProbe:
httpGet:
path: /health.html
port: 80
initialDelaySeconds: 3
periodSeconds: 3
参数解释:
initialDelaySeconds: 第⼀次执⾏探针需要在容器启动后等待的时候时间
periodSeconds: 容器启动后每隔多少秒执⾏⼀次存活探针
timeoutSeconds: 探针超时时间,默认1秒,最⼩1秒
successThreshold: 探针失败后最少连续探测成功多少次才被认定成功,默认1次,如果是liveness必须为1
failureThreshold: 探针成功后被视为失败的探测的最⼩连续失败次数。默认3次。最⼩值为1
8.Pod资源限制
在学习Docker的时候我们知道容器可以使⽤Linux系统的CGroup技术限制内存和CPU的使⽤率,那么POD⾥应该 如何限制容器的CPU和内存资源呢?
资源配置清单:
apiVersion: v1
kind: Pod
metadata:
name: resource-demo
spec:
containers:
- name: resource-demo
image: nginx
ports:
- containerPort: 80
resources:
requests:
memory: 50Mi
cpu: 1500m
limits:
memory: 100Mi
cpu: 1700m
参数解释:
requests :节点所需的最⼩计算资源量,k8s调度的时候的依据值
limits :限制允许的最⼤计算资源量,真正的资源限制参数
数值的转换:
1 CPU = 1000m
0.5 CPU = 500m
1 Mib = 1024 Kib
1 MB = 1000 KB
查看验证:
docker inspect 容器ID|grep CgroupParent
cd /sys/fs/cgroup/cpu/kubepods.slice/kubepods-burstable.slice/kubepods-burstablepodxxxx.slice
cat cpu.cfs_quota_us