文章目录
- Kubernetes是什么
- Kubernetes能干什么
- 容器技术市场份额
- 容器化
- 服务编排
- 架构原理、交互流程
- 安装
- k8s安装
- calico安装
- dashboard令牌
- 设置自动补全
- 术语
- 名称空间
- 命令
- 资源(resource)
- 节点(node)
- namespace,pod
- deploy
- 公共操作
- 查看日志,查看描述,用于排错
- 使用scale对deploy扩缩容
- service负载均衡网络
- 滚动升级
- yaml配置⭐⭐⭐⭐⭐
- 不知道yaml怎么写了,使用查看yaml的黑科技,⭐⭐⭐⭐⭐
- yaml命令
- 格式
- 使用密钥拉取私有仓库
- command与args
- 容器的生命周期钩子
- pod模板
- 静态pod
- probe探针(健康检查机制)
- 工作负载
- deployment
- HPA自动扩缩容
- StaefulSet
- statefulset和deployment的区别(面试题)
- Job 任务
- CronJob 定时任务
Kubernetes是什么
为了生产环境的容器化大规模应用编排,必须有一个自动化的框架系统,Kubernetes是一种容器编排系统
大型云平台=kubernetes+cncf其他软件
就是一个容器管家:
安装了很多应用。 ------------------------- qq电脑管家。(自动杀垃圾,自动卸载没用东西…)
机器上有很多容器。 -------------------------- kubernete容器的管家。(容器的启动停止、故障转义、负载均衡等)
Kubernetes能干什么
- 服务发现和负载均衡(类比consul)
- 存储编排
- 自动部署和回滚
- 自动完成装箱计算
- 自动完成装箱计算
允许你指定每个容器所需的CPU和内存。Kubernetes可以做出决策管理容器资源 - 自我修复
- 密钥与配置管理
- …
容器技术市场份额
容器化
服务编排
大型云平台=kubernetes+cncf其他软件
容器管家:
安装了很多应用。 ------------------------- qq电脑管家。(自动杀垃圾,自动卸载没用东西…)
机器上有很多容器。 -------------------------- kubernete容器的管家。(容器的启动停止、故障转义、负载均衡等)
架构原理、交互流程
想让k8s部署一个tomcat?
0、开机默认所有节点的kubelet、master节点的scheduler(调度器)、controller-manager(控制管理器)一直监听master的api-server发来的事件变化(for ::)
1、程序员使用命令行工具: kubectl ; kubectl create deploy tomcat --image=tomcat8(告诉master让集群使用tomcat8镜像,部署一个tomcat应用)
2、kubectl命令行内容发给api-server,api-server保存此次创建信息到etcd
3、etcd给api-server上报事件,说刚才有人给我里面保存一个信息。(部署Tomcat[deploy])
4、controller-manager监听到api-server的事件,是 (部署Tomcat[deploy])
5、controller-manager 处理这个 (部署Tomcat[deploy])的事件。controller-manager会生成Pod的部署信息【pod信息】
6、controller-manager 把Pod的信息交给api-server,再保存到etcd
7、etcd上报事件【pod信息】给api-server。
8、scheduler专门监听 【pod信息】 ,拿到 【pod信息】的内容,计算,看哪个节点合适部署这个Pod【pod调度过后的信息(node: node-02)】,
9、scheduler把 【pod调度过后的信息(node: node-02)】交给api-server保存给etcd
10、etcd上报事件【pod调度过后的信息(node: node-02)】,给api-server
11、其他节点的kubelet专门监听 【pod调度过后的信息(node: node-02)】 事件,集群所有节点kubelet从api-server就拿到了 【pod调度过后的信息(node: node-02)】 事件
12、每个节点的kubelet判断是否属于自己的事情;node-02的kubelet发现是他的事情
13、node-02的kubelet启动这个pod。汇报给master当前启动好的所有信息
安装
k8s安装
准备至少两台机器,内网互通。其中一台大于等于2核4G,作为master节点
待补充
calico安装
将文件下载下来 https://docs.projectcalico.org/manifests/calico.yaml
然后修改相应位置,再使用kubectl apply -f xxxx.yaml
安装
dashboard令牌
dashboard可视化界面,每次进入都要令牌,使用以下命令查看
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')
设置自动补全
yum install bash-completion
echo 'source <(kubectl completion bash)' >>~/.bashrc
kubectl completion bash >/etc/bash_completion.d/kubectl
source /usr/share/bash-completion/bash_completion
术语
资源(resource)
包含Pod
,namespace
,nodes
,deployments
,replicaset
等等
deploy包含启动了多个pod,pod启动多个container,删除前面的,后面的也就没了
名称空间
特点:资源隔离、网络不隔离
名称空间未来如何隔离
1)、基于环境隔离(prod,test)
prod:部署的所有应用
test:部署的所有应用
2)、基于产品线的名称空间(商城,android,ios,backend);
3)、基于团队隔离
访问其他名称空间的东西?
1)、配置直接拿来用。不行
2)、网络访问,可以。
命令
kubectl的命令非常多,靠所有都记住是不现实的,可以通过 kubectl 命令 --help
查看命令的用法,文档真的是非常详细,有解释并且有示例
官方命令文档官方教程文档其他作者的文档
资源(resource)
- 注意并不是所有的对象都在名称空间中
显示所有的资源类型:kubectl api-resources
通过api-resources --namespaced查看是否在名称空间:
在名称空间里 kubectl api-resources --namespaced=true
不在名称空间里 kubectl api-resources --namespaced=false - 获取某种资源的列表:
kubectl get 资源类型
获取类型为Deployment的资源列表kubectl get deployments
获取类型为Pod的资源列表kubectl get pods
获取类型为Node的资源列表kubectl get nodes
节点(node)
获取类型为Node的资源列表 kubectl get nodes
namespace,pod
查看所有名称空间的 Deployment kubectl get deployments -A
或kubectl get deployments --all-namespaces
查看所有名称空间的 Pod: kubectl get pod -A
或kubectl get pod --all-namespaces
查看指定命名空间 kube-system 的 Deployment kubectl get deployments -n kube-system
查看指定名称空间 kube-system 的 pod:kubectl get pod -n kube-system
获取pod,node,deploy 等资源的格式是一样的,可以同时一句命令获得:kubectl get pod,node,deploy,namespace
启动一个pod: kubectl run nginx --image=nginx
交互进入pod:kubectl exec -it pod名 -- sh
进入pod内的特定容器:kubectl exec -it pod名 -c nginx-container(容器名) -- /bin/bash
查看pod标签:kubectl get pod --show-labels
deploy
部署一个应用:kubectl create deployment my-nginx --image=nginx
查看deploy:kubectl get deploy
查看所有名称空间下的,查看指定命名空间下的deploy,写法参照pod
公共操作
公共操作不针对特定资源,很多资源都适用
- 删除:
以删除deploy为例,其他资源一样:kubectl delete deployment.apps/2-nginx
或kubectl delete deploy my-nginx
- 查看:
以node为例:kubectl get node
- 标签
查看标签:kubectl get pod --show-labels
以pod为例,打标签:kubectl label pod -nginx-6b74b79f57-zgt5c aaa=bbb
按标签过滤资源:kubectl get deploy -l app=nginx
- yaml黑科技命令,请查看yaml部分
查看日志,查看描述,用于排错
- 查看pod日志,格式:kubectl logs Pod名称
查看名称为 my-nginx-6b74b79f57-gtrcq的P od内的容器打印的日志:kubectl logs my-nginx-6b74b79f57-gtrcq
监听pod内具体容器的日志:kubectl logs -f pod名 -c 容器名
- 查看资源的描述信息:格式:kubectl describe 资源类型 资源名称
查看名称为nginx-XXXXXX的Pod的信息kubectl describe pod nginx-XXXXXX
查看名称为nginx的Deployment的信息kubectl describe deployment my-nginx
使用scale对deploy扩缩容
kubectl scale --replicas=2 deployment.apps/my-nginx
service负载均衡网络
获取service列表:kubectl get svc
对deploy下的pod进行负载均衡:kubectl expose deploy my-nginx --port=8888 --target-port=80 --type=NodePort
使用kubectl get svc
查看
内网使用10.96.60.131:8888
访问,外网使用公网IP:30110
访问
如果此时对deploy进行扩容,新的pod仍然会自动加入到service中
滚动升级
tomcat升级:kubectl set image deployment.apps/tomcat6 tomcat=tomcat:jre8-alpine #可以携带--record参数,记录变更
查看deploy的版本历史:kubectl rollout history deployment.apps/tomcat6
或kubectl rollout history deploy tomcat6
回滚到指定版本:kubectl rollout undo deployment.apps/tomcat6 --to-revision=1
或kubectl rollout undo deploy tomcat6 --to-revision=1
yaml配置⭐⭐⭐⭐⭐
不知道yaml怎么写了,使用查看yaml的黑科技,⭐⭐⭐⭐⭐
1、kubectl get pod my-nginx666 -oyaml
集群中挑一个同类资源,获取出他的yaml。
2、kubectl run my-tomcat --image=tomcat --dry-run -oyaml
干跑一遍
3、kubectl explain pod.metadata.labels
查看具体的字段写法,可以无限链式写
如果还不知道怎么写,就去官方文档搜索
yaml命令
创建或修改yaml声明的资源:kubectl apply -f demo.yaml
销毁yaml声明的资源: kubectl delete -f demo.yaml
yaml文件修改了,对比之前不同:kubectl diff -f k8s-demo.yaml
格式
使用密钥拉取私有仓库
- pod的底层是容器,如果是私有仓库,就必须创建密钥:
这个秘钥默认在default名称空间,不能被hello名称空间共享
kubectl create secret -n hello docker-registry my-aliyun \
--docker-server=registry.cn-hangzhou.aliyuncs.com \
--docker-username=用户名 \
--docker-password=密码
- 在yaml文件中声明密钥
apiVersion: v1
kind: Pod
metadata:
name: foo
spec:
containers:
- name: foo
image: registry.cn-zhangjiakou.aliyuncs.com/atguigudocker/atguigu-javaimg:v1.0
imagePullSecrets:
- name: my-aliyun
command与args
示例:
apiVersion: v1
kind: Pod
metadata:
name: "commandtest"
namespace: default
labels:
app: "commandtest"
spec:
containers:
- name: commandtest
image: "alpine"
command: ["echo"]
args:
- "def"
容器的生命周期钩子
使用 kubectl explain pod.spec.containers.lifecycle.postStart
查看解释
有三种钩子:exec,httpGet, tcpSocket
钩子字段解释:postStart
启动后钩子,preStop
delete前钩子
以httpGet钩子为例:
apiVersion: v1
kind: Pod
metadata:
name: test-nginx
spec:
containers:
- name: test-nginx
image: nginx
lifecycle:
postStart:
httpGet:
port: 8978
path: "/bb"
host: "120.79.202.23"
scheme: HTTP
preStop:
httpGet:
port: 8978
path: "/bb"
host: "120.79.202.23"
scheme: "HTTP"
pod模板
静态pod
在/etc/kubernetes/manifests位置的yaml文件,机器启动,kubelet自己就把他启动起来
yaml文件放在哪个节点,静态pod就在哪个节点启动,并且删除后可以重启
probe探针(健康检查机制)
官方文档 示例:
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: k8s.gcr.io/busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
启动探针,存活探针,就绪探针示例:
apiVersion: v1
kind: Pod
metadata:
name: "nginx-start-probe02"
namespace: default
labels:
app: "nginx-start-probe02"
spec:
volumes:
- name: nginx-vol
hostPath:
path: /app
- name: nginx-html
hostPath:
path: /html
containers:
- name: nginx
image: "nginx"
ports:
- containerPort: 80
startupProbe:
exec:
command: ["/bin/sh","-c","cat /app/abc"] ## 返回不是0,那就是探测失败
# initialDelaySeconds: 20 ## 指定的这个秒以后才执行探测
periodSeconds: 5 ## 每隔几秒来运行这个
timeoutSeconds: 5 ##探测超时,到了超时时间探测还没返回结果说明失败
successThreshold: 1 ## 成功阈值,连续几次成才算成功
failureThreshold: 3 ## 失败阈值,连续几次失败才算真失败
volumeMounts:
- name: nginx-vol
mountPath: /app
- name: nginx-html
mountPath: /usr/share/nginx/html
livenessProbe: ## nginx容器有没有 /abc.html,就绪探针
# httpGet:
# host: 127.0.0.1
# path: /abc.html
# port: 80
# scheme: HTTP
# periodSeconds: 5 ## 每隔几秒来运行这个
# successThreshold: 1 ## 成功阈值,连续几次成才算成功
# failureThreshold: 5 ## 失败阈值,连续几次失败才算真失败
exec:
command: ["/bin/sh","-c","cat /usr/share/nginx/html/abc.html"] ## 返回不是0,那就是探测失败
# i nitialDelaySeconds: 20 ## 指定的这个秒以后才执行探测
periodSeconds: 5 ## 每隔几秒来运行这个
timeoutSeconds: 5 ##探测超时,到了超时时间探测还没返回结果说明失败
successThreshold: 1 ## 成功阈值,连续几次成才算成功
failureThreshold: 3 ## 失败阈值,连续几次失败才算真失败
readinessProbe: ##就绪检测,都是http
httpGet:
# host: 127.0.0.1 ###不行
path: /abc.html ## 给容器发请求
port: 80
scheme: HTTP ## 返回不是0,那就是探测失败
initialDelaySeconds: 2 ## 指定的这个秒以后才执行探测
periodSeconds: 5 ## 每隔几秒来运行这个
timeoutSeconds: 5 ##探测超时,到了超时时间探测还没返回结果说明失败
successThreshold: 3 ## 成功阈值,连续几次成才算成功
failureThreshold: 5 ## 失败阈值,连续几次失败才算真失败
# livenessProbe:
# exec: ["/bin/sh","-c","sleep 30;abc "] ## 返回不是0,那就是探测失败
# initialDelaySeconds: 20 ## 指定的这个秒以后才执行探测
# periodSeconds: 5 ## 每隔几秒来运行这个
# timeoutSeconds: 5 ##探测超时,到了超时时间探测还没返回结果说明失败
# successThreshold: 5 ## 成功阈值,连续几次成才算成功
# failureThreshold: 5 ## 失败阈值,连续几次失败才算真失败
配置项:
工作负载
deployment
deployment每次创建或更新,都会对应一个replica资源,作为版本记录。
各个字段含义:
# Deployment:
# 滚动更新: 10 2 - 8 4 , 2 4 0 - 10
# RS1 RS2 两个版本同时存在
minReadySeconds: 10 这个Pod10s以后才认为是read状态,影响多久后杀死旧Pod
paused <boolean>: false 当前是否停止状态,暂停更新
progressDeadlineSeconds: 600 处理的最终期限,Deployment如果超过了这个指定的处理描述就会给集群汇报错误
The maximum time in seconds for a deployment to make progress before it is
considered to be failed. The deployment controller will continue to process
failed deployments and a condition with a ProgressDeadlineExceeded reason
will be surfaced in the deployment status. Note that progress will not be
estimated during the time a deployment is paused. Defaults to 600s.
replicas <integer>: Pod 期望的数量(副本数量),是 ReplicaSet 控制器实现的
revisionHistoryLimit <integer>: 旧副本集保留的数量,可回滚的数量,默认是10
selector <Object> -required-: 指定我们Deployment要控制的所有的Pod的共通标签
strategy <Object>: 指定新Pod替换旧Pod的策略
rollingUpdate <Object>: 指定滚动更新策略
maxSurge <string>【最大增量】: 2 一次最多新建几个Pod。 百分比和数字都可以
MaxUnavailable:为0 的时候, maxSurge不能为0
maxUnavailable【最大不可用量】: 4 最大不可用的Pod数量,比如有10个Pod,部署时一定要保证6个pod可用
type <string>: Recreate/RollingUpdate(默认)
template <Object> -required-: 编写Pod
简单示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydeploy-01
namespace: default
labels:
dep: test-01
# 期望状态
spec:
selector: # 指定控制的Pod标签
matchLabels:
pod-name: ppp #这里和下面的标签一定要一样
# replicas: 1
template:
metadata:
labels:
pod-name: ppp #和上面一样
spec:
containers:
- name: nginx
image: nginx:latest
resources:
requests:
cpu: 100m
memory: 100Mi
limits:
cpu: 100m
滚动更新示例:
apiVersion: apps/v1 ###
kind: Deployment ##
metadata:
name: mydeploy-05 ### 遵循域名编写规范
namespace: default
labels:
dep: test-04
### 期望状态
spec:
strategy:
# type: Recreate ### 把以前全部杀死,直接新建
type: RollingUpdate
rollingUpdate:
maxUnavailable: 2
maxSurge: 20%
replicas: 10
selector: ### 选择器
matchLabels: ### 匹配标签
pod-name: aaa55566 ### 和模板template里面的pod的标签必须一样
####
template:
metadata: ### pod的metadata
labels:
pod-name: aaa55566
spec:
containers:
- name: nginx-01
image: nginx
HPA自动扩缩容
注意:需要先安装metrics
组件,才支持动态扩缩容
官方文档安装点我 使用kubectl apply -f 即可安装
命令:
kubectl top nodes --use-protocol-buffers
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
creationTimestamp: null
name: php-apache
spec:
maxReplicas: 10
minReplicas: 1
scaleTargetRef: ### 将要扩展的目标引用
apiVersion: apps/v1
kind: Deployment # 指定对deploy进行扩缩容
name: php-apache ## Pod limit: 100m
targetCPUUtilizationPercentage: 50 ### cpu使用超过50%就扩容,低于就缩容
StaefulSet
有状态副本集;Deployment等属于无状态的应用部署(stateless)
- StatefulSet 使用场景;对于有如下要求的应用程序,StatefulSet 非常适用:
- 稳定、唯一的网络标识(dnsname)
- StatefulSet通过与其相关的无头服务为每个pod提供DNS解析条目。假如无头服务的DNS条目为:
“(namespace).svc.cluster.local”,
那么pod的解析条目就是"(service name).$(namespace).svc.cluster.local",每个pod name也是唯一的。
- 稳定的、持久的存储;【每个Pod始终对应各自的存储路径(PersistantVolumeClaimTemplate)】
- 有序的、优雅的部署和缩放。【按顺序地增加副本、减少副本,并在减少副本时执行清理】
- 有序的、自动的滚动更新。【按顺序自动地执行滚动更新】
- 限制
- 给定 Pod 的存储必须由 PersistentVolume 驱动 基于所请求的
storage class
来提供,或者由管理员预先提供。 - 删除或者收缩 StatefulSet 并不会删除它关联的存储卷。 这样做是为了保证数据安全,它通常比自动清除 StatefulSet 所有相关的资源更有价值。
- StatefulSet 当前需要无头服务 来负责 Pod 的网络标识。你需要负责创建此服务。
- 当删除 StatefulSets 时,StatefulSet 不提供任何终止 Pod 的保证。 为了实现 StatefulSet 中的 Pod 可以有序地且体面地终止,可以在删除之前将 StatefulSet 缩放为 0。
- 在默认 Pod 管理策略(
OrderedReady
) 时使用 滚动更新,可能进入需要人工干预 才能修复的损坏状态。
如果一个应用程序不需要稳定的网络标识,或者不需要按顺序部署、删除、增加副本,就应该考虑使用 Deployment 这类无状态(stateless)的控制器
示例:
apiVersion: v1
kind: Service #定义一个负载均衡网络
metadata:
name: stateful-tomcat
labels:
app: stateful-tomcat
spec:
ports:
- port: 8123
name: web
targetPort: 8080
clusterIP: None #NodePort:任意机器+NodePort都能访问,ClusterIP:集群内能用这个ip、service域名能访问,clusterIP: None;不要分配集群ip。headless;无头服务。稳定的域名
selector:
app: stateful-tomcat
---
apiVersion: apps/v1
kind: StatefulSet #控制器。
metadata:
name: stateful-tomcat
spec:
selector:
matchLabels:
app: stateful-tomcat # has to match .spec.template.metadata.labels
serviceName: "stateful-tomcat" #这里一定注意,必须提前有个service名字叫这个的
replicas: 3 # by default is 1
template:
metadata:
labels:
app: stateful-tomcat # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: tomcat
image: tomcat:7
ports:
- containerPort: 8080
name: web
#观察效果。
删除一个,重启后名字,ip等都是一样的。保证了状态
#细节
kubectl explain StatefulSet.spec
podManagementPolicy:
OrderedReady(按序)、Parallel(并发)
serviceName -required-
设置服务名,就可以用域名访问pod了。
pod-specific-string.serviceName.default.svc.cluster.local
#测试
kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh
ping stateful-tomcat-0.stateful-tomcat
#我们在这里没有加存储卷。如果有的话 kubectl get pvc -l app=stateful-tomcat 我们就能看到即使Pod删了再拉起,卷还是同样的。
查看pod:
查看svc:
statefulset和deployment的区别(面试题)
Job 任务
注意:任务是通过pod运行的,每个pod执行完,也就是一个任务完成了。其中的pod一定要保证不是阻塞的,否则任务执行不完
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
completions: 4 ## 有几个小任务需要完成
parallelism: 3 ## 并行的任务数量,默认是1
template:
spec:
containers:
- name: pi
image: busybox ## job类型的pod,不要用阻塞的。如nginx。 Deployment才应该是阻塞式的
command: ["/bin/sh", "-c", "echo abc"]
restartPolicy: Never #Job情况下,不支持Always
#backoffLimit: 4 #任务4次都没成,认为失败
activeDeadlineSeconds: 10 ## 整个job的存活时间,超出就自动杀死
ttlSecondAfterFinished: 10 ## 运行完自己删除
CronJob 定时任务
定时周期性的执行 Job 任务
例子:
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *" #分、时、日、月、周 调度时间,如果concurrencyPolicy是Allow,每一分钟启动一次
concurrencyPolicy: Allow
# 并发策略, Allow,允许任务并发执行 "Forbid"(禁止): forbids;前个任务没执行完,要并发下一个的话,下一个会被跳过
# "Replace"(替换): 新任务,替换当前运行的任务
failedJobsHistoryLimit: 1 #记录失败数的上限,Defaults to 1.
successfulJobsHistoryLimit: 3 # 记录成功任务的上限。 Defaults to 3.
startingDeadlineSeconds: 100
# 表示如果Job因为某种原因无法按调度准时启动,在spec.startingDeadlineSeconds时间段之内,\
# CronJob仍然试图重新启动Job,如果在.spec.startingDeadlineSeconds时间之内没有启动成功,则不再试图重新启动。如果spec.startingDeadlineSeconds的值没有设置,则没有按时启动的任务不会被尝试重新启动
suspend: false #暂停定时任务,对已经执行了的任务,不会生效; Defaults to false.
jobTemplate: # 以下是Job的内容
spec:
template: # 以下是pod的内容
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
关系图