无数次想放弃,最后选择了坚持
监控pod日志
监控名为 foobar 的 Pod 的日志,并过滤出具有 unable-access-website 信息的行,然后将
写入到 /opt/KUTR00101/foobar
# 解析
监控pod的日志,使用kubectl logs pod-name
kubectl logs foobar | grep unable-access-website > /opt/KUTR00101/foobar
监控pod度量指标
找出具有 name=cpu-user 的 Pod,并过滤出使用 CPU 最高的 Pod,然后把它的名字写在已
经存在的/opt/KUTR00401/KUTR00401.txt 文件里(注意他没有说指定 namespace。所以需要使
用-A 指定所以 namespace)
# 解析
过滤cpu最高,使用top命令
kubectl top pod -A -l name=cpu-user
echo x >> /opt/KUTR00401/KUTR00401.txt
deployment扩缩容
扩容名字为 loadbalancer 的 deployment 的副本数为 6
# 解析
kubectl scale --replicas=6 deployment loadbancer
检查Node节点的健康状态
检查集群中有多少节点为 Ready 状态,并且去除包含 NoSchedule 污点的节点。之后将数字
写到/opt/KUSC00402/kusc00402.txt
# 解析
查看节点ready状态,只需要get直接查就行
而要查调度,就要使用describe来查
kubectl get node | grep -i Ready
kubectl describe node | grep Taint | grep NoSchedule
echo x > /opt/KUSC00402/kusc00402.txt
节点维护
将 ek8s-node-1 节点设置为不可用,然后重新调度该节点上的所有 Pod
设置不可用,就是将节点设置不可调度,使用cordon
kubectl cordon ek8s-node-1
重新调度
指定节点部署
创建一个 Pod,名字为 nginx-kusc00401,镜像地址是 nginx,调度到具有 disk=spinning 标
签 的 节 点 上
# 解析
vim pod-ns.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-kusc00401
labels:
role: nginx-kusc00401
spec:
nodeSelector:
disk: spinning
containers:
- name: nginx
image: nginx
一个pod多个容器
创建一个 Pod , 名 字 为 kucc1 ,这个 Pod 可能包含 1-4 容 器 , 该 题 为 四 个 :
nginx+redis+memcached+consul
apiVersion: v1
kind: Pod
metadata:
name: kucc1
spec:
containers:
- image: nginx
name: nginx
- image: redis
name: redis
- image: memcached
name: memcached
- image: consul
name: consul
Service
重新配置一个已经存在的 deployment front-end,在名字为 nginx 的容器里面添加一个端口
配置,名字为 http,暴露端口号为 80,然后创建一个 service,名字为 front-end-svc,暴露该
deployment 的 http 端口,并且 service 的类型为 NodePort。
# 查看已存在的deployment
kubectl get deployment
# 编辑deployment
kubectl edit deploy nginx
# 打开之后找到nginx容器
ports:
- containerPort: 80
name: http
protocol: TCP
# 暴露service
kubectl expose deploy nginx --name=front-end-svc --port=80 --target-port=http --type=NodePort
# 查看svc
kubectl get svc
curl 192.168.0.100:30214
ingress
在 ing-internal 命名空间下创建一个 ingress,名字为 pong,代理的 service hi,端口为 5678,
配置路径/hi。
验证:访问 curl -kL <INTERNAL_IP>/hi 会返回 hi
kubectl get svc -n ing-internal
1.19之前不需要关注资源,之后需要
vim set paste粘贴模式
address是不是空不影响
address=internal-ip
Sidecar
添加一个名为 busybox 且镜像为 busybox 的 sidecar 到一个已经存在的名为 legacy-app 的
Pod 上,这个 sidecar 的启动命令为/bin/sh, -c, ‘tail -n+1 -f /var/log/legacy-app.log’。
并且这个 sidecar 和原有的镜像挂载一个名为 logs 的 volume,挂载的目录为/var/log/
RBAC
创建一个名为deployment-clusterrole的 clusterrole,该clusterrole只允许创建Deployments,Daemonset,Statefulset的create操作
在名字为app-team1的namespace下创建一个名为cicd-token的serviceAccount,并且将上一步创建的clusterrole的权限绑定到该serviceAccount
# 创建clusterrole
apiVersion:rbac.authorization.k8s.io/v1
kind:ClusterRole
metadata:
name: deployment-clusterrole
rules:
-apiGroups:["apps"]
resources:["deployments","statefulsets","daemonsets"]
verbs:["create"]
# 创建serviceaccount
kubectl create sa cicd-token -n app-team1
# 绑定权限
kubecdtl creare rolebinding deployment-rolebinding --clusterrole=deployment-clusterrole --serviceaccount=app-team1:cicd-token -n app-team1
PersistentVolume
创建一个 pv,名字为 app-config,大小为 2Gi,访问权限为 ReadWriteMany。Volume 的类
型为 hostPath,路径为/srv/app-config
apiVersion: v1
kind: PersistentVolume
metadata:
name: app-config
labels:
type: local
spec:
storageClassName: manual
capacity:
storage:2Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/srv/app-config"
升级集群
如果不能执行kubectl,退出当前节点在执行
登录到某个节点,解完题不要忘了退出
sudo su - 切换root用户
集群故障排查
kubelet故障
查看kubelet的状态
systemctl status kubelet
主节点故障
netstat -lntp | grep 6443
查看api-server是怎么启动的
systemctl status kube-apiserver
没有显示证明不是二进制启动的,是kubeadm启动的
kubelet静态pod管理,kubeadm方式启动的话
manifest:配置文件
systemctl status kubelet
找到–config
找到staticPodPath
systemctl daemon-reload
systemctl restart kubelet
虚拟机出问题,以上排查没错误,查看ip地址是否匹配
sudo ifconfig ens33 192.168.1.31 netmask 255.255.255.0
然后重启kubelet即可
单题目
监控pod日志
监控名为 foobar 的 Pod 的日志,并过滤出具有 unable-access-website 信息的行,然后将
写入到 /opt/KUTR00101/foobar
监控pod度量指标
找出具有 name=cpu-user 的 Pod,并过滤出使用 CPU 最高的 Pod,然后把它的名字写在已
经存在的/opt/KUTR00401/KUTR00401.txt 文件里(注意他没有说指定 namespace。所以需要使
用-A 指定所以 namespace)
deployment扩缩容
扩容名字为 loadbalancer 的 deployment 的副本数为 6
检查node节点的健康状态
检查集群中有多少节点为 Ready 状态,并且去除包含 NoSchedule 污点的节点。之后将数字
写到/opt/KUSC00402/kusc00402.txt
节点维护
将 ek8s-node-1 节点设置为不可用,然后重新调度该节点上的所有 Pod
指定节点部署
创建一个 Pod,名字为 nginx-kusc00401,镜像地址是 nginx,调度到具有 disk=spinning 标
签 的 节 点 上
一个pod多个容器
创建一个 Pod , 名 字 为 kucc1 ,这个 Pod 可能包含 1-4 容 器 , 该 题 为 四 个 :
nginx+redis+memcached+consul
Service
重新配置一个已经存在的 deployment front-end,在名字为 nginx 的容器里面添加一个端口
配置,名字为 http,暴露端口号为 80,然后创建一个 service,名字为 front-end-svc,暴露该
deployment 的 http 端口,并且 service 的类型为 NodePort。
ports:
-containerPort: 80
name: http
protocol: TCP
kubectl expose service --name=front-end-svc --target-port=http --type=NodePort
kubectl expose deployment front-end – name=front-end-svc --port=80 --target-port=http --type=NodePort
ingress
在 ing-internal 命名空间下创建一个 ingress,名字为 pong,代理的 service hi,端口为 5678,
配置路径/hi。
验证:访问 curl -kL <INTERNAL_IP>/hi 会返回 hi
Sidecar
添加一个名为 busybox 且镜像为 busybox 的 sidecar 到一个已经存在的名为 legacy-app 的
Pod 上,这个 sidecar 的启动命令为/bin/sh, -c, ‘tail -n+1 -f /var/log/legacy-app.log’。
并且这个 sidecar 和原有的镜像挂载一个名为 logs 的 volume,挂载的目录为/var/log/
RBAC
创建一个名为deployment-clusterrole的 clusterrole,该clusterrole只允许创建Deployments,Daemonset,Statefulset的create操作
在名字为app-team1的namespace下创建一个名为cicd-token的serviceAccount,并且将上一步创建的clusterrole的权限绑定到该serviceAccount
PersistentVolume
创建一个 pv,名字为 app-config,大小为 2Gi,访问权限为 ReadWriteMany。Volume 的类
型为 hostPath,路径为/srv/app-config
kubectl练习
logs
打印pod或指定资源中容器的日志
如果pod只有一个容器,则容器名称是可选的
# 仅使用一个容器从pod nginx返回快照日志
kubectl logs nginx
# 使用多容器从pod nginx 返回快照日志
kubectl logs nginx --all-containers=true
# 从标签app=nginx定义的pod中的所有pod容器返回快照日志
kubectl logs -l app=nginx --all-containers=true
# 从pod web-1返回以前终止的ruby容器日志的快照
kubectl logs -p -c ruby web-1
# 开始从标签app=nginx定义的pod中的所有容器流式传输日志
kubectl logs -f -l app=nginx --all-containers=true
# 在pod nginx中显示最近的20行
kubectl logs --tail=20 nginx
# 显示过去一小时内写入的pod nginx中的所有日志
kubectl logs --since=1h nginx
# 显示服务证书已过期的kubelet中的日志
kubectl logs --insecure-skip-tls-verify-backend nginx
# 从名为hello的作业的第一个容器返回快照日志
kubectl logs job/hello
# 从名为nginx的部署的容器nginx-1返回快照日志
kubectl logs deployment/nginx -c nginx-1
top
显示资源使用情况
运行查看node或pod的资源情况
前置条件:需要正确配置metrics server在服务器上工作
node
# 获取所有node
kubectl top node
# 查看指定节点指标
kubectl top node node-name
pod
# 显示默认命名空间的pod指标
kubectl top pod
# 显示指定命名空间的所有pod指标
kubectl top pod --namespace=namespacename
# 显示更定pod及其容器的指标
kubectl top pod pod-name --containers
# 显示name=mylabel定义的pod的指标
kubectl top pod -l name=mylabel
scale
部署 deployment,replicaset replication controller,statefulset
如果指定了 --current-replicas或 --resource-version,则在尝试缩放之前对其进行验证,并保证在将缩放发送到服务器时条件成立
# 将replicaset缩放3
kubectl scale --replicas=3 rs/foo
# 将foo.yaml中缩放为3
kubectl scale --replicas=3 -f foo.yaml
# 如果名为Mysql的当前为2,变为3
kubectl scale --current-replicas=2 --replicas=3 deployment/mysql
# 扩展多个rc
kubectl scale --replicas=5 rc/foo rc/bar rc/baz
# 扩展statefulset为3
kubectl scale --replicas=3 statefulset/web
cordon
将节点标记为不可调度,node级别
kubectl cordon foo
drain
排空节点准备维护
expose
将资源公开为新的kubernetes服务
按名称查找deployment,service,replica set, replication controller,pod
并将该资源的选择器用作指定端口上新服务的选择器
仅当deployment,replicaset的选择器可转换为服务支持的选择器的时候
当选择器是match labels组件时,deployment,replicaset才会公开为服务
如果未通过–port指定端口,并且公开的资源具有多个端口,则新服务重用所有端口
如果未指定标签,新服务将重用其公开资源中的标签
kubectl expose deoloyment front-end --name=front-end-svc --port=80 --target-port=http --type=NodePort
–name:新创建对象的名称
–port:服务应在其上提供服务的端口,从公开的资源复制(如果未指定)
–target-port:服务应将流量定向到容器上的端口名称或编号
–type:此服务的类型为:clusertIP,NodePort,LoadBalancer,ExternalName,默认值为ClusterIP
容忍(taint)和污点(toleration)
taint和toleration
taint在一类服务器上打上污点,让不能容忍这个污点的pod不能部署在打了污点的服务器上
toleration是让pod容忍节点上配置的污点,可以让一些需要特殊配置的pod能够调用到具有污点和特殊配置的节点上
污点像锁node级别,容忍像钥匙pod级别
taint配置解析
创建一个污点
kubectl taint nodes node-name taint_key=taint_value:effect
kubectl taint nodes k8s-node01 ssd=true:prefernoschedule
NoSchedule:禁止调度到该节点,已经在该节点上的pod不受影响
NoExecute:禁止调度到该节点,如果不符合这个污点,会立马被驱逐(或在一段时间后)
PreferNoSchedule:尽量避免将pod调度到指定的节点上,如果没有更合适的节点,可以部署到该节点
将pod指派给节点
与节点标签匹配的nodeSelector
亲和性和反亲和性
nodeName字段
Pod拓扑分布约束
ingress
ingress是对集群中服务的外部访问进行管理的API对象,典型的访问方式是HTTP
ingress可以提供负载均衡,SSL终结和基于名称的虚拟托管
node:kubernetes集群中的一台工作机器,是集群的一部分
cluster:一组运行容器化应用程序的Node,用kubernetes管理
集群中的节点都不在公共网络中
edge router:边缘路由器,在集群中强制执行防火墙策略的路由器
可以由云提供商管理的网关,也可以是物理硬件
cluster Network:集群网络,一组逻辑的或物理的连结
基于kubernetes网络模型实现集群内的通信
service:kubernetes服务,使用标签选择算符selectors来选择一组pod
假定service具有只能在集群网络内路由的虚拟ip
ingress是什么
ingress提供从集群外部到集群内服务的http和https路由
流量路由由ingress资源所定义的规则来控制
将所有流量都发送到同一service
ingress可为service提供外部可访问的url,对其流量作负载均衡,终止ssl/tls
以及基于名称的虚拟托管等能力
ingress控制器负责完成ingress的工作
具体实现上通常会使用某个负载均衡器
ingress不会随意公开端口或协议,
将HTTP和HTTPS以外的服务开放到internet时,通常使用Service.Type=NodePort或Service.Type=LoadBalancer类型的service
环境准备
必须拥有一个Ingress控制器才能满足ingress的要求
仅创建ingress资源本身没有任何效果
apiVersion:networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
annotations:
nginx.ingress.kubernetes.ip/rewrite-target:/
spec:
ingressClassName: nginx-example
rules:
- http:
paths:
- path:/testpath
pathType:Prefix
backend:
service:
name:test
port:
number:80
ingress经常使用annotations来配置一些选项,具体取决于Ingress控制器
日志架构
应用日志可以了解应用内部的运行状况
日志对调试问题和监控集群活动非常有用
集群中,日志应该具有独立的存储,并且其生命周期与节点,pod或容器的生命周期相独立
集群级日志:具有独立的存储,其生命周期与node,pod或container的生命周期相独立
集群级日志架构需要一个独立的后端来存储,分析和查询日志
kubernetes并不为日志数据提供原生的存储解决方案
pod和容器日志
kubernetes从正在运行的pod中捕捉每个容器的日志
容器每秒将文本写入标准输出一次
# 一个容器的pod清单,每秒将文本写入标准输出一次
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
-name: count
image: busybox:1.28
args: [/bin/sh,-c,
'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']
系统组件日志
容器中运行的组件
kubelet和容器运行时不在容器中运行
kubelet运行你的容器(一起按pod分组)
直接参与容器运行的组件
kubernetes调度器,控制器管理器和api服务器在pod中运行(通常是静态Pod)
etcd组件在控制平面中运行,最常见的也是作为静态pod
集群中使用kube-proxy,通常作为daemonset运行
对于在pod中运行的kubernetes集群组件,日志会写入/var/log目录中的文件
绕过默认的日志机制(组件不会写入sytemd日志)
可以使用kubernetes的存储机制将持久存储映射到运行该组件的容器中
集群级日志架构
使用在每个节点上运行的节点级日志记录代理
在应用程序的pod中,包含专门记录日志的sidecar容器
将日志直接从应用程序中推送到日志记录后端
使用sidecar容器运行日志代理
sidecar容器将应用程序日志传送到自己的标准输出
sidecar运行一个日志代理,配置该日志代理以便从应用容器收集日志
使用RBAC鉴权
基于角色role的访问控制rbac是一种基于组织用户的角色来控制对计算机或网络资源的访问的方法
RBAC鉴权机制使用rbac.authorization.k8s.ioAPI组来驱动鉴权决定,运行你通过kubernetesAPI动态配置策略
启动RBAC,在启动API服务器时将–authorization-mode参数设置为一个逗号分隔的列表并确保其中包含rbac
API对象
RBAC API声明了四种kubernetes对象:role,clusterRole,rolebinding和clusterRoleBinding
role和clusterRole
RBAC的Role或ClusterRole中包含一组代表相关权限的规则
这些权限是纯粹累加的
Role总是用来在某个名字空间内设置访问权限,在创建role时,必须指定role所属的名字空间
clusterRole是一个集群作用域的资源
kubernetes对象要么是名字空间作用域的,要么是集群作用域的
clusterrole
定义对某名字空间域对象的访问权限,并将在个别名字空间内被授予访问权限
为名字空间作用域的对象设置访问权限,并被授予跨所有名字空间的访问权限
为集群作用域的资源定义访问权限
role:在名字空间内定义角色
clusterrole:定义集群范围的角色
role实例
# 在位于default名字空间的role实例,用来授予对pod的读访问权限
apiVersion:rbac.authorization.k8s.io/v1
kind:Role
metadata:
namespace:default
name:pod-reader
rules:
- apiGroups:[] # 标明core api组
resources:["pods"]
verbs:["get","watch","list"]
clusterrole实例
clusterrole同样可以用于授予role能够授予的权限
clusterrole属于集群范围
集群范围资源
非资源端点
跨名字空间访问的名字空间作用域的资源
# 为任一特定名字空间中的Secret授予读访问权限,或者跨名字空间的访问权限
apiVersion:rbac.authorization.k8s.io/v1
kind:ClusterRole
metadata:
name:secret-reader
rules:
-apiGroups:[""]
resources:["secrets"]
verbs:["get","watch","list"]
RoleBinding和ClusterRoleBinding
角色绑定是将角色中定义的权限赋予一个或者一组用户
包含若干主体的列表和对这些主体所获得的角色的引用
rolebinding在指定的名字空间中执行授权
clusterRoleBinding在集群范围执行授权
一个roleBinding可以引用同一名字空间中的任何Role
一个RoleBinding可以引用某CluseterRole并将该clusterRole绑定到RoleBinding所在的名字空间
希望将某clusterRole绑定到集群中所有名字空间,使用clusterrolebinding
rolebinding或clusterrolebinding对象的名称必须是合法的路径分段名称
roleBinding实例
RoleBinding将pod-reader,Role授予在default名字空间中的用户jane
这样jane就具有了读取default名字空间中所有pod的权限
apiVersion:rbac.authorization.k8s.io/v1
kind:RoleBinding
metadata:
name:read-pods
namespace:default
subjects:
-kind:user
name: jane
apiGroup:rbac.authorization.k8s.io
roleRef:
# rpleref指定与某role或clusterrole的绑定关系
kind:Role
name:pod-reader
apiGroup:rbac.authorization.k8s.io
纯题目
1 监控pod日志
监控名为 foobar 的 Pod 的日志,并过滤出具有 unable-access-website 信息的行,然后将
写入到 /opt/KUTR00101/foobar
2 监控pod度量指标
找出具有 name=cpu-user 的 Pod,并过滤出使用 CPU 最高的 Pod,然后把它的名字写在已
经存在的/opt/KUTR00401/KUTR00401.txt 文件里(注意他没有说指定 namespace。所以需要使
用-A 指定所以 namespace)
3 Deployment 扩缩容
扩容名字为 loadbalancer 的 deployment 的副本数为 6
4 检查节点的健康状态
检查集群中有多少节点为 Ready 状态,并且去除包含 NoSchedule 污点的节点。之后将数字
写到/opt/KUSC00402/kusc00402.txt
5 节点维护
将 ek8s-node-1 节点设置为不可用,然后重新调度该节点上的所有 Pod
6 指定节点部署
创建一个 Pod,名字为 nginx-kusc00401,镜像地址是 nginx,调度到具有 disk=spinning 标
签 的 节 点 上
7 一个pod多个容器
创建一个 Pod , 名 字 为 kucc1 ,这个 Pod 可能包含 1-4 容 器 , 该 题 为 四 个 :
nginx+redis+memcached+consul
8 service
重新配置一个已经存在的 deployment front-end,在名字为 nginx 的容器里面添加一个端口
配置,名字为 http,暴露端口号为 80,然后创建一个 service,名字为 front-end-svc,暴露该
deployment 的 http 端口,并且 service 的类型为 NodePort。
9 ingress
在 ing-internal 命名空间下创建一个 ingress,名字为 pong,代理的 service hi,端口为 5678,
配置路径/hi。
验证:访问 curl -kL <INTERNAL_IP>/hi 会返回 hi
10 sidecar
添加一个名为 busybox 且镜像为 busybox 的 sidecar 到一个已经存在的名为 legacy-app 的
Pod 上,这个 sidecar 的启动命令为/bin/sh, -c, ‘tail -n+1 -f /var/log/legacy-app.log’。
并且这个 sidecar 和原有的镜像挂载一个名为 logs 的 volume,挂载的目录为/var/log/
11 rbac
创建一个名为 deployment-clusterrole 的 clusterrole,该 clusterrole 只允许创建 Deployment、
Daemonset、Statefulset 的 create 操作
在名字为 app-team1 的 namespace 下创建一个名为 cicd-token 的 serviceAccount,并且将上一
步创建 clusterrole 的权限绑定到该 serviceAccount
12 NetworkPolicy
创建一个名字为 allow-port-from-namespace 的 NetworkPolicy,这个 NetworkPolicy 允许
internal 命名空间下的 Pod 访问该命名空间下的 9000 端口。
并且不允许不是 internal 命令空间的下的 Pod 访问
不允许访问没有监听 9000 端口的 Pod。
13 PersistentVolume
创建一个 pv,名字为 app-config,大小为 2Gi,访问权限为 ReadWriteMany。Volume 的类
型为 hostPath,路径为/srv/app-config
14 CSI & PersistentVolumeClaim
创建一个名字为 pv-volume 的 pvc,指定 storageClass 为 csi-hostpath-sc,大小为 10Mi
然后创建一个 Pod,名字为 web-server,镜像为 nginx,并且挂载该 PVC 至/usr/share/nginx/html,
挂载的权限为 ReadWriteOnce。之后通过 kubectl edit 或者 kubectl path 将 pvc 改成 70Mi,并且
记录修改记录。
15 etcd备份恢复
针对 etcd 实例 https://127.0.0.1:2379 创建一个快照,保存到/srv/data/etcd-snapshot.db。
在创建快照的过程中,如果卡住了,就键入 ctrl+c 终止,然后重试。
然后恢复一个已经存在的快照: /var/lib/backup/etcd-snapshot-previous.db
执行 etcdctl 命令的证书存放在:
ca 证书:/opt/KUIN00601/ca.crt
客户端证书:/opt/KUIN00601/etcd-client.crt
客户端密钥:/opt/KUIN00601/etcd-client.key
16 k8s升级
17 集群故障排查 – kubelet 故障
18 主节点故障
考试重构
1 监控pod日志
监控名为 foobar 的 Pod 的日志,并过滤出具有 unable-access-website 信息的行,然后将
写入到 /opt/KUTR00101/foobar
2 监控pod度量指标
找出具有 name=cpu-user 的 Pod,并过滤出使用 CPU 最高的 Pod,然后把它的名字写在已
经存在的/opt/KUTR00401/KUTR00401.txt 文件里(注意他没有说指定 namespace。所以需要使
用-A 指定所以 namespace)
3 Deployment 扩缩容
扩容名字为 loadbalancer 的 deployment 的副本数为 6
4 检查节点的健康状态 更新
检查集群中有多少节点为 Ready 状态,并且去除包含 NoSchedule 污点的节点。之后将数字
写到/opt/KUSC00402/kusc00402.txt
首先用kubectl get node将所有是ready状态的数出来
然后再用kubectl describe node xxx | grep NoSchedule将所有ready状态这个节点的找出来
然后减完写入即可
5 节点维护
将 ek8s-node-1 节点设置为不可用,然后重新调度该节点上的所有 Pod
6 指定节点部署
创建一个 Pod,名字为 nginx-kusc00401,镜像地址是 nginx,调度到具有 disk=spinning 标
签 的 节 点 上
7 一个pod多个容器
创建一个 Pod , 名 字 为 kucc1 ,这个 Pod 可能包含 1-4 容 器 , 该 题 为 四 个 :
nginx+redis+memcached+consul
8 service
重新配置一个已经存在的 deployment front-end,在名字为 nginx 的容器里面添加一个端口
配置,名字为 http,暴露端口号为 80,然后创建一个 service,名字为 front-end-svc,暴露该
deployment 的 http 端口,并且 service 的类型为 NodePort。
9 ingress 更新
在 ing-internal 命名空间下创建一个 ingress,名字为 pong,代理的 service hi,端口为 5678,
配置路径/hi。
验证:访问 curl -kL <INTERNAL_IP>/hi 会返回 hi
k8s1.19之前不需要关注ingressclass,
10 sidecar
添加一个名为 busybox 且镜像为 busybox 的 sidecar 到一个已经存在的名为 legacy-app 的
Pod 上,这个 sidecar 的启动命令为/bin/sh, -c, ‘tail -n+1 -f /var/log/legacy-app.log’。
并且这个 sidecar 和原有的镜像挂载一个名为 logs 的 volume,挂载的目录为/var/log/
11 rbac
创建一个名为 deployment-clusterrole 的 clusterrole,该 clusterrole 只允许创建 Deployment、
Daemonset、Statefulset 的 create 操作
在名字为 app-team1 的 namespace 下创建一个名为 cicd-token 的 serviceAccount,并且将上一
步创建 clusterrole 的权限绑定到该 serviceAccount
12 NetworkPolicy 更新
创建一个名字为 allow-port-from-namespace 的 NetworkPolicy,这个 NetworkPolicy 允许
internal 命名空间下的 Pod 访问该命名空间下的 9000 端口。
并且不允许不是 internal 命令空间的下的 Pod 访问
不允许访问没有监听 9000 端口的 Pod。
13 PersistentVolume
创建一个 pv,名字为 app-config,大小为 2Gi,访问权限为 ReadWriteMany。Volume 的类
型为 hostPath,路径为/srv/app-config
14 CSI & PersistentVolumeClaim
创建一个名字为 pv-volume 的 pvc,指定 storageClass 为 csi-hostpath-sc,大小为 10Mi
然后创建一个 Pod,名字为 web-server,镜像为 nginx,并且挂载该 PVC 至/usr/share/nginx/html,
挂载的权限为 ReadWriteOnce。之后通过 kubectl edit 或者 kubectl path 将 pvc 改成 70Mi,并且
记录修改记录。
15 etcd备份恢复
针对 etcd 实例 https://127.0.0.1:2379 创建一个快照,保存到/srv/data/etcd-snapshot.db。
在创建快照的过程中,如果卡住了,就键入 ctrl+c 终止,然后重试。
然后恢复一个已经存在的快照: /var/lib/backup/etcd-snapshot-previous.db
执行 etcdctl 命令的证书存放在:
ca 证书:/opt/KUIN00601/ca.crt
客户端证书:/opt/KUIN00601/etcd-client.crt
客户端密钥:/opt/KUIN00601/etcd-client.key
16 k8s升级 更新
ssh之后记得登录root用户
用完记得退出
17 集群故障排查 – kubelet 故障
ssh
sudo
systemctl status kubelet
systemctl restart kubelet
systemctl enable kubelet
18 主节点故障
考试1.0
1 监控pod日志
监控名为 foobar 的 Pod 的日志,并过滤出具有 unable-access-website 信息的行,然后将
写入到 /opt/KUTR00101/foobar
kubectl logs foobar | grep unable-access-website > /opt/KUTR00101/foobar
2 监控pod度量指标
找出具有 name=cpu-user 的 Pod,并过滤出使用 CPU 最高的 Pod,然后把它的名字写在已
经存在的/opt/KUTR00401/KUTR00401.txt 文件里(注意他没有说指定 namespace。所以需要使
用-A 指定所以 namespace)
kubectl get pod -A -l name=cpu-user
echo "x" >> /opt/KUTR00401/KUTR00401.txt
3 Deployment 扩缩容
扩容名字为 loadbalancer 的 deployment 的副本数为 6
kubectl scale deployment loadbalancer --replicas=6
4 检查节点的健康状态 更新
检查集群中有多少节点为 Ready 状态,并且去除包含 NoSchedule 污点的节点。之后将数字
写到/opt/KUSC00402/kusc00402.txt
kubectl get node | grep -w ready
kubectl describe node xxx | grep NoSchedule
echo "x" > /opt/KUSC00402/kusc00402.txt
5 节点维护
将 ek8s-node-1 节点设置为不可用,然后重新调度该节点上的所有 Pod
kubectl crodon ek8s-node-1
kubectl drain ek8s-node-1 --delete-emptydir-data --force --ignore-daemonsets
6 指定节点部署
创建一个 Pod,名字为 nginx-kusc00401,镜像地址是 nginx,调度到具有 disk=spinning 标
签 的 节 点 上
vim 6.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-kusc00401
spec:
containes:
- name: nginx
image: nginx
nodeSelector:
disk: spinning
7 一个pod多个容器
创建一个 Pod , 名 字 为 kucc1 ,这个 Pod 可能包含 1-4 容 器 , 该 题 为 四 个 :
nginx+redis+memcached+consul
apiVersion: v1
kind: Pod
metadata:
name: kucc1
spec:
containers:
- name: nginx
image: nginx
- name: redis
image: redis
- name: memcached
image: memcached
- name: consul
image: consul
8 service
重新配置一个已经存在的 deployment front-end,在名字为 nginx 的容器里面添加一个端口
配置,名字为 http,暴露端口号为 80,然后创建一个 service,名字为 front-end-svc,暴露该
deployment 的 http 端口,并且 service 的类型为 NodePort。
kubectl get deployment front-end -o yaml > 8.yaml
# 配置deployment
- name: nginx
ports:
- containerPort: 80
name: http
protocol: TCP
kubectl apply -f 8.yaml
kubectl expose deployment front-end --name=front-end-svc --port=80 --target-port=http --type=NodePort
# 验证
kubectl describe service front-end-svc
9 ingress 更新
在 ing-internal 命名空间下创建一个 ingress,名字为 pong,代理的 service hi,端口为 5678,
配置路径/hi。
验证:访问 curl -kL <INTERNAL_IP>/hi 会返回 hi
# 查看ingressclass
kubectl get ingressclass
vi 9.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: pong
namespace: ing-internal
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /hi
pathType: Prefix
backend:
service:
name: hi
port:
number: 5678
kubectl apply -f 9.yaml
kubectl get pod -n ing-internal
10 sidecar
添加一个名为 busybox 且镜像为 busybox 的 sidecar 到一个已经存在的名为 legacy-app 的
Pod 上,这个 sidecar 的启动命令为/bin/sh, -c, ‘tail -n+1 -f /var/log/legacy-app.log’。
并且这个 sidecar 和原有的镜像挂载一个名为 logs 的 volume,挂载的目录为/var/log/
kubectl get pod legacy-app -o yaml
- name: busybox
image: busybox
args: ["/bin/sh, -c, 'tail -n+1 -f /var/log/legacy-app.log"]
volumeMounts:
- mountPath: /var/log
name: logs
kubectl get po legacy-app -o yaml > csidercar.yaml
11 rbac
创建一个名为 deployment-clusterrole 的 clusterrole,该 clusterrole 只允许创建 Deployment、
Daemonset、Statefulset 的 create 操作
在名字为 app-team1 的 namespace 下创建一个名为 cicd-token 的 serviceAccount,并且将上一
步创建 clusterrole 的权限绑定到该 serviceAccount
# vi 11.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: deployment-clusterrole
rules:
- apiGroups: ["apps"]
resources: ["deployments","statefulsets","daemonsets"]
verbs: ["create"]
kubectl create -f 11.yaml
kubectl create serviceaccount cicd-token -n app-team1
kubectl create rolebinding deployment-rolebinding --clusterrole=deployment-clusterrole --serviceaccount=app-team1:cicd-token --namespace=app-team1
# 验证
kubectl describe rolebinding deployment-rolebinding -n app-team1
12 NetworkPolicy
创建一个名字为 allow-port-from-namespace 的 NetworkPolicy,这个 NetworkPolicy 允许
internal 命名空间下的 Pod 访问该命名空间下的 9000 端口。
并且不允许不是 internal 命令空间的下的 Pod 访问
不允许访问没有监听 9000 端口的 Pod。
13 PersistentVolume
创建一个 pv,名字为 app-config,大小为 2Gi,访问权限为 ReadWriteMany。Volume 的类
型为 hostPath,路径为/srv/app-config
14 CSI & PersistentVolumeClaim
创建一个名字为 pv-volume 的 pvc,指定 storageClass 为 csi-hostpath-sc,大小为 10Mi
然后创建一个 Pod,名字为 web-server,镜像为 nginx,并且挂载该 PVC 至/usr/share/nginx/html,
挂载的权限为 ReadWriteOnce。之后通过 kubectl edit 或者 kubectl path 将 pvc 改成 70Mi,并且
记录修改记录。
15 etcd备份恢复 更新
针对 etcd 实例 https://127.0.0.1:2379 创建一个快照,保存到/srv/data/etcd-snapshot.db。
在创建快照的过程中,如果卡住了,就键入 ctrl+c 终止,然后重试。
然后恢复一个已经存在的快照: /var/lib/backup/etcd-snapshot-previous.db
执行 etcdctl 命令的证书存放在:
ca 证书:/opt/KUIN00601/ca.crt
客户端证书:/opt/KUIN00601/etcd-client.crt
客户端密钥:/opt/KUIN00601/etcd-client.key
# 备份etcd
ETCDCTL_API=3
etcdctl --endpoints=https://127.0.0.1:2379 \
--cacert=/opt/KUIN00601/ca.crt --cert=/opt/KUIN00601/etcd-client.crt --key=/opt/KUIN00601/etcd-client.key \
snapshot save /srv/data/etcd-snapshot.db
# 查看etcd位置 data-dir需要记忆
ps aux | grep etcd | grep data-dir
# 停止etcd
systemctl stop etcd
# 备份
mv /var/lib/etcd /var/lib/etcd.bak
# 恢复
ETCDCTL_API=3
etcdctl --endpoints=https://127.0.0.1:2379 \
--cacert=/opt/KUIN00601/ca.crt --cert=/opt/KUIN00601/etcd-client.crt --key=/opt/KUIN00601/etcd-client.key \
snapshot restore /var/lib/backup/etcd-snapshot-previous.db --data-dir=/var/lib/etcd
# 重新启动需要记忆
systemctl restart etcd
16 k8s升级 更新
# 升级到v1.27.1
# 1. 清空节点
kubectl cordon k8s-master01
kubectl drain k8s-master01 --delete-emptydir-data --ignore-daemonsets --force
ssh
# 2. 检查版本
apt update
apt-cache madison kubeadm | grep 1.27.1
# 3. 升级kubeadm
apt-mark unhold kubeadm && \
apt-get update && apt-get install -y kubeadm='1.27.1-00' && \
apt-mark hold kubeadm
# 4. 验证升级计划
kubeadm upgrade plan
# 5. 选择要升级的目标版本,不要etcd kubeadm upgrade apply v1.27.1 -h | grep etcd 此处etcd加前面的upgrade需要记忆
kubeadm upgrade apply v1.27.1 --etcd-upgrade=false -f
# 6. 升级kubelet和kubectl
apt-mark unhold kubelet kubectl && \
apt-get update && apt-get install -y kubelet='1.27.1-00' kubectl='1.27.1-00' && \
apt-mark hold kubelet kubectl
# 7. 重启
sudo systemctl daemon-reload
sudo systemctl restart kubelet
# 8. 解除节点保护
kubectl uncordon k8s-master01
17 集群故障排查 – kubelet 故障
ssh
sudo
systemctl status kubelet
systemctl restart kubelet
systemctl enable kubelet
18 主节点故障
考试2.0
1 监控pod日志
监控名为 foobar 的 Pod 的日志,并过滤出具有 unable-access-website 信息的行,然后将
写入到 /opt/KUTR00101/foobar
kubectl logs foobar | grep unable-access-website > /opt/KUTR00101/foobar
# 检查
cat /opt/KUTR00101/foobar
2 监控pod度量指标
找出具有 name=cpu-user 的 Pod,并过滤出使用 CPU 最高的 Pod,然后把它的名字写在已
经存在的/opt/KUTR00401/KUTR00401.txt 文件里(注意他没有说指定 namespace。所以需要使
用-A 指定所以 namespace)
kubectl top pod -A -l name=cpu-user
echo "x" >> /opt/KUTR00401/KUTR00401.txt
# 检查
cat /opt/KUTR00401/KUTR00401.txt
3 Deployment 扩缩容
扩容名字为 loadbalancer 的 deployment 的副本数为 6
kubectl scale --replicas=6 deployment loadbalancer
4 检查节点的健康状态 更新
检查集群中有多少节点为 Ready 状态,并且去除包含 NoSchedule 污点的节点。之后将数字
写到/opt/KUSC00402/kusc00402.txt
kubectl get node | grep -w ready
kubectl describe node xxx | grep NoSchedule
echo "x" > /opt/KUSC00402/kusc00402.txt
# 检查
cat /opt/KUSC00402/kusc00402.txt
5 节点维护
将 ek8s-node-1 节点设置为不可用,然后重新调度该节点上的所有 Pod
kubectl cordon ek8s-node-1
kubectl drain ek8s-node-1 --delete-emptydir-data --ignore-daemonsets --force
6 指定节点部署
创建一个 Pod,名字为 nginx-kusc00401,镜像地址是 nginx,调度到具有 disk=spinning 标
签 的 节 点 上
# vi 6.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-kusc00401
spec:
containers:
- name: nginx
image: nginx
nodeSelector:
disk: spinning
# kubectl apply -f 6.yaml
# 检查
kubelet describe pod nginx-kusc00401 | grep disk
7 一个pod多个容器
创建一个 Pod , 名 字 为 kucc1 ,这个 Pod 可能包含 1-4 容 器 , 该 题 为 四 个 :
nginx+redis+memcached+consul
# vi 7.yaml
apiVersion: v1
kind: Pod
metadata:
name: kucc1
spec:
containers:
- name: nginx
image: nginx
- name: redis
image: redis
- name: memcached
image: memcached
- name: consul
image: consul
# kubectl apply -f 7.yaml
# 检查
kubectl describe pod kucc1
8 service
重新配置一个已经存在的 deployment front-end,在名字为 nginx 的容器里面添加一个端口
配置,名字为 http,暴露端口号为 80,然后创建一个 service,名字为 front-end-svc,暴露该
deployment 的 http 端口,并且 service 的类型为 NodePort。
kubectl get deploy front-end -oyaml > frontnew.yaml
vi frontnew.yaml
- name: nginx
prots:
- containerPort: 80
name: http
protocol: TCP
kubectl delete -f frontnew.yaml
kubectl apply -f frontnew.yaml
kubectl describe deploy front-end # 查看ports是否添加成功
kubectl expose deploy front-end --name=front-end-svc --port=80 --target-port=http --type=NodePort
kubectl get svc front-end-svc
kubectl describe svc front-end-svc
9 ingress 更新
在 ing-internal 命名空间下创建一个 ingress,名字为 pong,代理的 service hi,端口为 5678,
配置路径/hi。
验证:访问 curl -kL <INTERNAL_IP>/hi 会返回 hi
# 查看ingressclass 1.19之后需要
kubectl get ingressclass
# vi 9.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: pong
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /hi
pathType: Prefix
backend:
service:
name: hi
port:
number: 80
kubectl apply -f 9.yaml
kubectl get ingress # 查看是否创建成功
kubectl describe ingress pong
curl xxx/
10 sidecar
添加一个名为 busybox 且镜像为 busybox 的 sidecar 到一个已经存在的名为 legacy-app 的
Pod 上,这个 sidecar 的启动命令为/bin/sh, -c, ‘tail -n+1 -f /var/log/legacy-app.log’。
并且这个 sidecar 和原有的镜像挂载一个名为 logs 的 volume,挂载的目录为/var/log/
kubectl get pod legacy-app -oyaml > newlegacy.yaml
- name: busybox
image: busybox
args: ["/bin/sh, -c, 'tail -n+1 -f /var/log/legacy-app.log"]
volumeMounts:
- mountPath: /var/log
name: logs
volumes:
- name: logs
hostPath:
path: /var/log
kubectl delete -f newlegacy.yaml
kubectl apply -f newlegacy.yaml
kubectl logs legacy-app busybox
11 rbac
创建一个名为 deployment-clusterrole 的 clusterrole,该 clusterrole 只允许创建 Deployment、
Daemonset、Statefulset 的 create 操作
在名字为 app-team1 的 namespace 下创建一个名为 cicd-token 的 serviceAccount,并且将上一
步创建 clusterrole 的权限绑定到该 serviceAccount
vi 11.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: deployment-clusterrole
rules:
- apiGroups: ["apps"]
resources: ["deployments","statefulsets","daemonsets"]
verbs: ["create"]
kubectl apply -f 11.yaml
kubectl create serviceaccount cicd-token -n app-team1
kubectl create rolebinding deployment-binding --clusterrole=deployment-clusterrole --serviceaccount=app-team1:cicd-token --namespace=app-team1
12 NetworkPolicy
创建一个名字为 allow-port-from-namespace 的 NetworkPolicy,这个 NetworkPolicy 允许
internal 命名空间下的 Pod 访问该命名空间下的 9000 端口。
并且不允许不是 internal 命令空间的下的 Pod 访问
不允许访问没有监听 9000 端口的 Pod。
13 PersistentVolume
创建一个 pv,名字为 app-config,大小为 2Gi,访问权限为 ReadWriteMany。Volume 的类
型为 hostPath,路径为/srv/app-config
vi 13.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: app-config
spec:
accessModes:
- ReadWriteMany
capacity:
storage: 2Gi
hostPath:
path: /srv/app-config
kubectl apply -f 13.yaml
kubectl get pv app-config
14 CSI & PersistentVolumeClaim
创建一个名字为 pv-volume 的 pvc,指定 storageClass 为 csi-hostpath-sc,大小为 10Mi
然后创建一个 Pod,名字为 web-server,镜像为 nginx,并且挂载该 PVC 至/usr/share/nginx/html,
挂载的权限为 ReadWriteOnce。之后通过 kubectl edit 或者 kubectl path 将 pvc 改成 70Mi,并且
记录修改记录。
vi 14.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pv-volume
spec:
accessModes:
- ReadWriteOnce
storageClassName: csi-hostpath-sc
resources:
requests:
storage: 10Mi
kubectl patch pvc pv-volume -p '{"spec":{"resources":{"requests":{"storage": "70Mi"}}}}' --record
---
apiVersion: v1
kind: Pod
metadata:
name: web-server
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: pv-volume
volumes:
- name: pv-volume
persistentVolumeClaim:
claimName: pv-volume
kubectl get pvc pv-volume
15 etcd备份恢复 更新
针对 etcd 实例 https://127.0.0.1:2379 创建一个快照,保存到/srv/data/etcd-snapshot.db。
在创建快照的过程中,如果卡住了,就键入 ctrl+c 终止,然后重试。
然后恢复一个已经存在的快照: /var/lib/backup/etcd-snapshot-previous.db
执行 etcdctl 命令的证书存放在:
ca 证书:/opt/KUIN00601/ca.crt
客户端证书:/opt/KUIN00601/etcd-client.crt
客户端密钥:/opt/KUIN00601/etcd-client.key
# 备份
ETCDCTL_API=3
etcdctl --endpoints=https://192.168.38.129:2379 \
--cacert=/opt/KUIN00601/ca.crt --cert=/opt/KUIN00601/etcd-client.crt --key=/opt/KUIN00601/etcd-client.key \
snapshot save /srv/data/etcd-snapshot.db
# 查看etcd存在哪里
ps aux | grep etcd | grep data-dir # /var/lib/minikube/etcd
# 备份
mv /var/lib/minikube/etcd /var/lib/minikube/etcd.bak
# 停止etcd
systemctl stop etcd
# 恢复
etcdctl --endpoints=https://192.168.38.129:2379 \
--cacert=/opt/KUIN00601/ca.crt --cert=/opt/KUIN00601/etcd-client.crt --key=/opt/KUIN00601/etcd-client.key \
snapshot restore /var/lib/backup/etcd-snapshot-previous.db --data-dir=/var/lib/minikube/etcd
# 启动
systemctl restart etcd
16 k8s升级 更新
升级1.27.1
# 清空节点
kubectl cordon master01
kubectl drain master01 --delete-emptydir-data --ignore-daemonsets --force
ssh
# 确定升级到哪个版本
apt update
apt-cache madison kubeadm | grep 1.27.1
apt-mark unhold kubeadm && \
apt-get update && apt-get install -y kubeadm='1.27.1-00' && \
apt-mark hold kubeadm
# 验证升级计划
kubeadm upgrade plan
# 选择要升级到的目标版本
kubeadm upgrade apply v1.27.1 --etcd-upgrade=false -f
# 升级kubelet和kubectl
apt-mark unhold kubelet kubectl && \
apt-get update && apt-get install -y kubelet='1.27.1-00' kubectl='1.27.1-00' && \
apt-mark hold kubelet kubectl
sudo systemctl daemon-reload
sudo systemctl restart kubelet
kubectl uncordon master01
17 集群故障排查 – kubelet 故障
ssh
sudo
systemctl status kubelet
systemctl restart kubelet
systemctl enable kubelet
‘’
18 主节点故障
安装考试环境
ubuntu20.04
ubuntu虚拟机安装
k8s-master01
k8s-node01
k8s-node02
心得
考试3.0
1 监控pod日志
监控名为 foobar 的 Pod 的日志,并过滤出具有 unable-access-website 信息的行,然后将
写入到 /opt/KUTR00101/foobar
kubectl logs foobar | grep unable-access-website > /opt/KUTR00101/foobar
cat /opt/KUTR00101/foobar
2 监控pod度量指标
找出具有 name=cpu-user 的 Pod,并过滤出使用 CPU 最高的 Pod,然后把它的名字写在已
经存在的/opt/KUTR00401/KUTR00401.txt 文件里(注意他没有说指定 namespace。所以需要使
用-A 指定所以 namespace)
kubectl top po -A -l name=cpu-user
echo “x” >> /opt/KUTR00401/KUTR00401.txt
3 Deployment 扩缩容
扩容名字为 loadbalancer 的 deployment 的副本数为 6
kubectl scale --replicas=6 deployment loadbalancer
kubectl get deploy loadbalancer
4 检查节点的健康状态 更新
检查集群中有多少节点为 Ready 状态,并且去除包含 NoSchedule 污点的节点。之后将数字
写到/opt/KUSC00402/kusc00402.txt
kubectl get node
kubectl describe node xxx | grep NoScheDule
echo x > /opt/KUSC00402/kusc00402.txt
5 节点维护
将 ek8s-node-1 节点设置为不可用,然后重新调度该节点上的所有 Pod
kubectl cordon ek8s-node-1
kubectl drain ek8s-node-1 --delete-emptydir-data --ignore-daemonsets --force
6 指定节点部署
创建一个 Pod,名字为 nginx-kusc00401,镜像地址是 nginx,调度到具有 disk=spinning 标
签 的 节 点 上
apiVersion: v1
kind: Pod
metadata:
name: nginx-kusc00401
spec:
containers:
- name: nginx
image: nginx
nodeSelector:
disk: spinning
7 一个pod多个容器
创建一个 Pod , 名 字 为 kucc1 ,这个 Pod 可能包含 1-4 容 器 , 该 题 为 四 个 :
nginx+redis+memcached+consul
apiVersion: v1
kind: Pod
metadata:
name: kucc1
spec:
containers:
- name: nginx
image: nginx - name: redis
image: redis - name: memcached
image: memcached - name: consul
image: consul
8 service
重新配置一个已经存在的 deployment front-end,在名字为 nginx 的容器里面添加一个端口
配置,名字为 http,暴露端口号为 80,然后创建一个 service,名字为 front-end-svc,暴露该
deployment 的 http 端口,并且 service 的类型为 NodePort。
kubectl edit deploy front-end
name: http
protocol: TCP
containerPort: 80
kubectl expose deploy front-end --name=front-end-svc --port=80 --target-port=http --type=NodePort
kubectl get svc
kubectl describe svc front-end-svc
9 ingress 更新
在 ing-internal 命名空间下创建一个 ingress,名字为 pong,代理的 service hi,端口为 5678,
配置路径/hi。
验证:访问 curl -kL <INTERNAL_IP>/hi 会返回 hi
kubectl get ingressclasses
vi 9.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
namespace: ing-internal
spec:
ingressClassName: nginx-example
rules:
- http:
paths:- path: /hi
pathType: Prefix
backend:
service:
name: hi
port:
number: 5678
kubectl apply -f 9.yaml
- path: /hi
10 sidecar
添加一个名为 busybox 且镜像为 busybox 的 sidecar 到一个已经存在的名为 legacy-app 的
Pod 上,这个 sidecar 的启动命令为/bin/sh, -c, ‘tail -n+1 -f /var/log/legacy-app.log’。
并且这个 sidecar 和原有的镜像挂载一个名为 logs 的 volume,挂载的目录为/var/log/
kubectl get pod legacy-app -o yaml > sider.yaml
- name: busybox
image: busybox
args: [“/bin/sh, -c, ‘tail -n+1 -f /var/log/legacy-app.log’”]
volumeMounts:- mountPath: /var/log/
name: logs
volume:
name: logs
emptyDir : {}
kubectl delete -f sider.yaml
kubectl apply -f sider.yaml
- mountPath: /var/log/
11 rbac
创建一个名为 deployment-clusterrole 的 clusterrole,该 clusterrole 只允许创建 Deployment、
Daemonset、Statefulset 的 create 操作
在名字为 app-team1 的 namespace 下创建一个名为 cicd-token 的 serviceAccount,并且将上一
步创建 clusterrole 的权限绑定到该 serviceAccount
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: deployment-clusterrole
rules:
- apiGroups: [“apps”]
resources: [“deployments”,“daemonsets”,“statefulsets”]
verbs: [“create”]
kubectl create serviceaccount cicd-token -n app-team1
kubectl create rolebinding deploymentrolebinding --clusterrole=deployment-clusterrole
–serviceaccount=app-team1:cicd-token -n app-team1
12 NetworkPolicy
创建一个名字为 allow-port-from-namespace 的 NetworkPolicy,这个 NetworkPolicy 允许
internal 命名空间下的 Pod 访问该命名空间下的 9000 端口。
并且不允许不是 internal 命令空间的下的 Pod 访问
不允许访问没有监听 9000 端口的 Pod。
13 PersistentVolume
创建一个 pv,名字为 app-config,大小为 2Gi,访问权限为 ReadWriteMany。Volume 的类
型为 hostPath,路径为/srv/app-config
apiVersion: v1
kind: PersistentVolume
metadata:
name: app-config
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteMany
hostPath:
path: /srv/app-config
14 CSI & PersistentVolumeClaim
创建一个名字为 pv-volume 的 pvc,指定 storageClass 为 csi-hostpath-sc,大小为 10Mi
然后创建一个 Pod,名字为 web-server,镜像为 nginx,并且挂载该 PVC 至/usr/share/nginx/html,
挂载的权限为 ReadWriteOnce。之后通过 kubectl edit 或者 kubectl path 将 pvc 改成 70Mi,并且
记录修改记录。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pv-volume
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Mi
storageClassName: csi-hostpath-sc
apiVersion: v1
kind: Pod
metadata:
name: web-server
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- mountPath: “/usr/share/nginx/html”
name: pv-volume
volumes:
- name: pv-volume
persistentVolumeClaim:
claimName: pv-volume
15 etcd备份恢复 更新
针对 etcd 实例 https://127.0.0.1:2379 创建一个快照,保存到/srv/data/etcd-snapshot.db。
在创建快照的过程中,如果卡住了,就键入 ctrl+c 终止,然后重试。
然后恢复一个已经存在的快照: /var/lib/backup/etcd-snapshot-previous.db
执行 etcdctl 命令的证书存放在:
ca 证书:/opt/KUIN00601/ca.crt
客户端证书:/opt/KUIN00601/etcd-client.crt
客户端密钥:/opt/KUIN00601/etcd-client.key
export ETCDCTL_API=3
etcdctl --endpoints=https://127.0.0.1:2379
–cacert=/opt/KUIN00601/ca.crt --cert=/opt/KUIN00601/etcd-client.crt --key=/opt/KUIN00601/etcd-client.key
snapshot save /srv/data/etcd-snapshot.db
找到etcd位置 ps aux | grep etcd | etcd-dir
systemctl stop etcd
mv /var/lib/etcd /var/lib/etcd.bak
export ETCDCTL_API=3
etcdctl --endpoints=https://127.0.0.1:2379
–cacert=/opt/KUIN00601/ca.crt --cert=/opt/KUIN00601/etcd-client.crt --key=/opt/KUIN00601/etcd-client.key
snapshot restore /var/lib/backup/etcd-snapshot-previous.db --data-dir= /var/lib/etcd
16 k8s升级 更新
清空节点
kubectl cordon ek8s-node-1
kubectl drain ek8s-node-1 --delete-emptydir-data --ignore-daemonsets --force
确定升级到哪个版本 1.27.2
apt update
apt-cache madison kubeadm | grep 1.27.2
apt-mark unhold kubeadm &&
apt-get update && apt-get install -y kubeadm=‘1.27.2-’ &&
apt-mark hold kubeadm
kubeadm version
kubeadm upgrade plan
kubeadm upgrade apply v1.27.2 --etcd-upgrade=false
apt-mark unhold kubelet kubectl &&
apt-get update && apt-get install -y kubelet='1.27.2-’ kubectl=‘1.27.2-*’ &&
apt-mark hold kubelet kubectl
sudo systemctl daemon-reload
sudo systemctl restart kubelet
kubectl uncordon ek8s-node-1
17 集群故障排查 – kubelet 故障
ssh
sudo -i
systemctl status kubelet
systemctl start kubelet
systemctl enable kubelet