k8s详解基本对象
参考yaml代码如下
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-demo
namespace: netcore
labels:
name: k8s-demo
spec:
replicas: 2
selector:
matchLabels:
name: k8s-demo
template:
metadata:
labels:
name: k8s-demo
spec:
containers:
- name: k8s-demo
image: aidasi/k8sdemoapi:v1
ports:
- containerPort: 80
imagePullPolicy: Always
---
kind: Service
apiVersion: v1
metadata:
name: k8s-demo
namespace: netcore
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
selector:
name: k8s-demo
Lable & Selector
特点
- 自定义标签方便分组与筛选
Service 关联 Pod
【注意】此时的Pod为template->metadata->labels
MatchLabels 关联 Containers
当然还可以这样进行筛选
selector:
matchLabels:
component: redis
matchExpressions:
- {key: tier, operator: In, values: [cache]}
- {key: environment, operator: NotIn, values: [dev]}
Kind Job
Deployment
Replica Set
Daemon Set
matchLabels 是由 {key,value} 对组成的映射。matchLabels 映射中的单个 {key,value } 等同于 matchExpressions 的元素,其 key字段为 “key”,operator 为 “In”,而 values 数组仅包含 “value”。matchExpressions 是 pod 选择器要求的列表。有效的运算符包括 In,NotIn,Exists 和 DoesNotExist。在 In 和 NotIn 的情况下,设置的值必须是非空的。来自 matchLabels 和 matchExpressions 的所有要求都是合在一起 – 它们必须都满足才能匹配。
Deployment.metadata.labels 关联 MatchLabels
Pod
特点
- 解耦控制器和服务,管理器只需要监控Pod即可
- 无状态
- 高可用,当出现一些删除pod的操作时,会自动创建新的pod
livenessProbe Pod探针
在yaml文件中的代码如下代码
livenessProbe:
httpGet:
path: /healthz
port: 80
timeoutSeconds: 5
完整代码如下
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-demo
namespace: netcore
labels:
name: k8s-demo
spec:
replicas: 2
selector:
matchLabels:
name: k8s-demo
template:
metadata:
labels:
name: k8s-demo
spec:
containers:
- name: k8s-demo
image: aidasi/k8sdemoapi:v1
ports:
- containerPort: 80
imagePullPolicy: Always
livenessProbe:
httpGet:
path: /healthz
port: 80
timeoutSeconds: 5
---
kind: Service
apiVersion: v1
metadata:
name: k8s-demo
namespace: netcore
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
selector:
name: k8s-demo
部署的时候,当没有相关接口做探针时
通过Kubernetes Dashboard来查看
结果也是不可以被访问的
readinessProbe Pod探针
在yaml文件中的代码如下代码
readinessProbe:
httpGet:
path: /healthz
port: 80
timeoutSeconds: 5
完整代码如下
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-demo
namespace: netcore
labels:
name: k8s-demo
spec:
replicas: 2
selector:
matchLabels:
name: k8s-demo
template:
metadata:
labels:
name: k8s-demo
spec:
containers:
- name: k8s-demo
image: aidasi/k8sdemoapi:v1
ports:
- containerPort: 80
imagePullPolicy: Always
livenessProbe:
httpGet:
path: /WeatherForecast/1
port: 80
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /healthz
port: 80
timeoutSeconds: 5
---
kind: Service
apiVersion: v1
metadata:
name: k8s-demo
namespace: netcore
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
selector:
name: k8s-demo
查看结果
我这边仍然不可访问
但据教程说是可以继续被请求的
当对代码进行一定的修改
这个时候是都可以访问的时候
livenessProbe:
httpGet:
path: /WeatherForecast/1
port: 80
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /WeatherForecast/1
port: 80
timeoutSeconds: 5
通过kubectl apply -f deploy.yaml
结果如下:
探针大致就这些!
RestartPolicy 重启策略
PodSpec 中有一个 restartPolicy 字段,可能的值为
Always
、OnFailure
和Never
。默认为Always
。 restartPolicy 适用于 Pod 中的所有容器。restartPolicy 仅指通过同一节点上的 kubelet 重新启动容器。
失败的容器由 kubelet 以五分钟为上限的指数退避延迟(10秒,20秒,40秒…)重新启动,并在成功执行十分钟后重置。如 Pod 文档 中所述,一旦绑定到一个节点,Pod 将永远不会重新绑定到另一个节点。
imagePullPolicy 拉取镜像策略
支持三种imagePullPolicy
- Always: 不管镜像是否存在都会进行一次拉取 (使用时修改yaml:
image: aidasi/k8sdemoapi:latest
)- Never: 不管镜像是否存在都不会进行拉取
- IfNotPresent: 只有镜像不存在时,才会进行镜像拉取 (default)
Resources 资源限制
在containers中添加如下yaml
resources:
requests:
cpu: "300m"
memory: "56Mi"
limits:
cpu: "500m"
memory: "128Mi"
Kubernetes通过cgroups限制容器的CPU和内存等计算资源,包括requests(请求,调度器保证调度到资源充足的Node上)和limits(上限)等:
- spec.containers[].resources.limits.cpu:CPU上限,可以短暂超过,容器也不会被停止
- spec.containers[].resources.limits.memory:内存上限,不可以超过;如果超过,容器可能会被停止或调度到其他资源充足的机器上
- spec.containers[].resources.requests.cpu:CPU请求,可以超过
- spec.containers[].resources.requests.memory:内存请求,可以超过;但如果超过,容器可能会在Node内存不足时清理
初始容器 Container (Init Container)
Init Container在所有容器运行之前执行(run-to-completion),常用来初始化配置。
在spec下添加如下操作
initContainers:
- name: install
image: busybox
command:
- wget
- "-O"
- "/work-dir/index.html"
- http://kubernetes.io
volumeMounts:
- name: workdir
mountPath: "/work-dir"
容器生命周期钩子
容器生命周期钩子(Container Lifecycle Hooks)监听容器生命周期的特定事件,并在事件发生时执行已注册的回调函数。支持两种钩子。
postStart: 容器启动后执行,注意由于是异步执行,它无法保证一定在ENTRYPOINT之后运行。如果失败,容器会被杀死,并根据RestartPolicy决定是否重启
preStop:容器停止前执行,常用于资源清理。如果失败,容器同样也会被杀死而钩子的回调函数支持两种方式:
exec:在容器内执行命令
httpGet:向指定URL发起GET请求
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: nginx
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
preStop:
exec:
command: ["/usr/sbin/nginx","-s","quit"]
指定Node
通过nodeSelector,一个Pod可以指定它所想要运行的Node节点。
首先给Node加上标签:
kubectl label nodes <YourNodeName> nodetypeis=hmy
接着,指定该Pod只想运行在带有nodetypeis=hmy标签的Node上:
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
nodetypeis: hmy
使用Capabilities
默认情况下,容器都是以非特权容器的方式运行。比如,不能在容器中创建虚拟网卡、配置虚拟网络。
Kubernetes提供了修改Capabilities的机制,可以按需要给给容器增加或删除。比如下面的配置给容器增加了CAP_NET_ADMIN并删除了CAP_KILL。
apiVersion: v1
kind: Pod
metadata:
name: hello-world
spec:
containers:
- name: friendly-container
image: "alpine:3.4"
command: ["/bin/echo", "hello", "world"]
securityContext:
capabilities:
add:
- NET_ADMIN
drop:
- KILL
限制网络带宽
Ingress
可以通过给Pod增加kubernetes.io/ingress-bandwidth和kubernetes.io/egress-bandwidth这两个annotation来限制Pod的网络带宽
apiVersion: v1
kind: Pod
metadata:
name: qos
annotations:
kubernetes.io/ingress-bandwidth: 3M
kubernetes.io/egress-bandwidth: 4M
spec:
containers:
- name: iperf3
image: networkstatic/iperf3
command:
- iperf3
- -s
Service
Service版本发展史
- 初代Service客户端通过kubectl-proxy作代理访问,算法基于轮询的方式
- 二代Service客户端通过集群ip进行访问,算法是通过负载均衡的方式进行分发请求
- 三代Service与二代相通,只是请求访问的算法方式增加了
特点
- 解耦控制器和服务,管理器只需要监控Pod即可
- 无状态
- 高可用,当出现一些删除pod的操作时,会自动创建新的pod
Namespace
特点
- 有些对象和namespace相关,而有些则不受namespace管辖
- 可以借助于 resource quote 来控制 namespace 的资源
namespace 相关常规操作
查询所有namespace
kubectl get namespace
或
kubectl get ns
创建namespace
kubectl create namespace myspace
删除namespace
注意:把namespace删除也就意味着删除下面的所有资源
kubectl delete namespace myspace
通过 quote 对 namespace 的请求与限制
创建一个名为myspace的namespace
kubectl create namespace myspace
创建一个基本的compute-resources.yaml 限制yaml
cat <<EOF > compute-resources.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
spec:
hard:
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
requests.nvidia.com/gpu: 4
EOF
名称 | 定义 |
---|---|
requests.cpu | 需要的cpu个数 |
requests.memory | 需要的内存大小 |
limits.cpu | 限制cpu的个数 |
limits.memory | 限制memory的内存大小 |
requests.nvidia.com/gpu | 请求的GPU总数限制为4 |
限制到namespace myspace中去
kubectl create -f ./compute-resources.yaml --namespace=myspace
创建一个高级的object-counts.yaml 限制yaml
cat <<EOF > object-counts.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-counts
spec:
hard:
configmaps: "10"
persistentvolumeclaims: "4"
pods: "4"
replicationcontrollers: "20"
secrets: "10"
services: "10"
services.loadbalancers: "2"
EOF
名称 | 定义 |
---|---|
configmaps | 命名空间中可以存在的配置映射总数。 |
persistentvolumeclaims | 命名空间中可以存在的持久卷声明的总数。 |
pods | 命名空间中可以存在的处于非终端状态的Pod总数。如果.status.phase in (Failed, Succeeded)为true,则Pod处于终端状态。 |
replicationcontrollers | 命名空间中可以存在的复制控制器的总数。 |
secrets | 命名空间中可以存在的秘密总数。 |
services | 命名空间中可以存在的服务总数。 |
services.loadbalancers | 命名空间中可以存在的负载均衡器类型的服务总数。 |
限制到namespace myspace中去
kubectl create -f ./compute-resources.yaml --namespace=myspace
查看限制
kubectl get quota --namespace=myspace
查看指定命名空间详细配置
kubectl describe quota compute-resources --namespace=myspace
更多请参考
https://kubernetes.io/docs/concepts/policy/resource-quotas/
Volume
特点
- 对资源进行存储并管理
emptyDir
一个 emptyDir 第一次创建是在一个 pod 被指定到具体 node 的时候,并且会一直存在在 pod 的生命周期当中,正如它的名字一样,它初始化是一个空的目录,pod 中的容器都可以读写这个目录,这个目录可以被挂在到各个容器相同或者不相同的的路径下。当一个 pod 因为任何原因被移除的时候,这些数据会被永久删除。
如下图所示:
hostPath
挂载到本机(可进行长期存储)
secret
可以以键值对的方式存储密码与数据
persistentVolumeClaim
可以实现一些云存储或分布式存储
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739