k8s的操作指令和yaml文件
一、项目的生命周期
创建----》发布----》更新----》回滚----》删除
1.创建
kubectl create deployment nginx1 --image=nginx:1.22 --replicas=3
#基于deployment控制器创建pod,控制器的名称是nginx1,pod使用的镜像是nginx:1.22,pod的数量有3个
2.发布
kubectl expose 暴露的是service的类型,可以供内网访问的一个方式
kubectl expose deployment nginx1 --port=80 --target-port=80
service的类型*
(1)ClusterIP
当设置控制器的暴露端口时,不指定type,默认就是clusterip,service的默认类型。访问这个ip可以直接访问pod,但是外部的请求是不能直接到达的。仅限于集群内部的通信。
(2)NodePort*
需要在创建的时候指定端口类型(--type=NodePort),一旦设定为NodePort,会在每个节点上都开放一个端口,每个节点上的端口都是相同的,NodePort的端口号的范围是30000-32767。
(3)LoadBalancer
这个地址一般是云平台服务商提供的地址,仅限于公有云服务平台上设置的service。可以通过这个地址直接访问,实现负载均衡。(收费服务)
(4) ExternalName
不能提供负载均衡的服务,service映射到集群外的域名,不涉及后端的pod的负载均衡。
k8s需要Service的原因
- service一旦和控制器的标签关联之后,会自动的发现该控制器pod的变化,自动的获取pod的数量和ip地址的变化。
- service既可以关联一个控制器,也可以关联多个控制器,也可以关联pod。
- pod是不断变化的,service是不变的,所以必须要有一个中间状态。
3.更新
kubectl set #更新应用资源
kubectl set image deployment nginx1 nginx=nginx:1.15 --record
#--record 记录deployment的更新方式:滚动更新
先更新其中一部分,然后更新所有
版本更新过程
以3个pod为例
- 首先在确保正常提供服务的情况下,在三个pod实例正常运行的情况下,生成一个新的指定版本呢的pod实例
- 等到新的pod实例创建成功后,会删除第一个pod实例
- 而后再生成第二个新版本的pod实例,再删除第二个,依此类推,一直到该deployment下的所有pod资源全部升级完毕
注意:资源更新后,其原本pod实例中的数据并不会被继承。如果有需要的话,可以先对数据进行备份,等到升级完毕后,再同步数据。
4.回滚
kubectl rollout history deployment #查看更新历史
kubectl rollout undo deployment nginx --to-revision=1 #回滚到版本号1
5.删除
kubectl delete deployment nginx1 #删除控制器
kubectl delete service nginx-service #删除service
kubectl delete pod nginx1-869649574d-mspkq
基于控制器创建的pod,删除pod相当于是重启,pod的数量是不会变化的,删除控制器,才会删除pod
二、项目的发布方式
1.蓝绿发布
把应用服务器分为蓝组和绿组,要先升级蓝组,先把蓝组从负载均衡中移除出去,蓝组继续为用户提供服务。
蓝组升级完毕之后,加入到负载均衡当中,把绿组移除,再升级绿组,完成之后,再把绿组加入到负载均衡当中去。
特点
- 如果升级有问题,影响范围比较大
- 发布策略简单
- 用户无感知,平滑过渡
- 早期成本较高,现在有了负载均衡之后,成本也降低了
2.金丝雀发布
在升级的时候,先升级一小部分,然后暂停整个升级,一部分是新的,另一大部分还是旧的。 筛选出一小部分用户在新的版本上应用,观察,如果没有问题再把剩余的部分全部更新到新版本。
特点
- 一旦出现问题,影响范围很小,调整和修复也很快
- 充分评估了版本的性能,稳定,出问题的话对用户的体验影响也很小。
- 用户无感知,平滑过渡
kubectl set image deployment nginx nginx=1.18 && kubectl rollout pause deployment nginx #暂停更新
kubectl rollout resume deployment nginx #恢复更新
三、k8s管理资源的方式
1.陈述式-->命令行
kubectl get cs/pod/ns/svc
kubectl create deployment ...
kubectl expose deployment ...
kubectl set image deployment ...
kubectl rollout history deployment ...
kubectl rollout undo deployment ... --to-revision=...
kubectl delete pod/deployment/svc
kubectl logs (-f) ...
kubectl descibe deployment/pod/svc
kubectl explain pod/deploment/svc
......
2.声明式-->yaml文件
kubectl get pod test1 -o yaml > pod.yaml #生成一个参考yaml文件
pod类型
kubectl explain pod
vim first.yaml
apiVersion: v1 #定义api的接口
kind: Pod #创建资源对象的类型
#----------------------------------固定开头
metadata:
#元数据信息,包括pod的名称和标签
name: nginx-test-pod
labels:
app1: nginx1
spec:
#pod内使用的容器,包括容器的名称和镜像的版本
containers:
- name: nginx
image: nignx:1.22kubectl apply -f first.yaml #运行直接生效
kubectl delete -f first.yaml #删除了yaml就删除了对应的pod
deployment类型
kubectl explain deployment
vim deployment.yaml
apiVersion: apps/v1
kind: Deployment
#前提条件,固定开头
metadata:
#元数据信息,定义资源对象的名称,对象的命名空间,标签等信息
name: nginx-yaml
labels:
app1: nginx-yaml
namespace: abc
spec:
#定义控制器的资源参数,包括副本数、匹配的标签和容器失败时是否重启等等容器相关的属性
replicas: 3
#定义副本数
selector:
#定义标签选择器
matchLabels:
app: nginx-yaml
template:
#定义业务模板,多个副本都会按照这个模板生成统一的pod
metadata:
labels:
app: nginx-yaml
#固定格式,三个标签的值都必须保持一致
spec:
#控制器pod使用的容器参数
containers:
- name: nginx
image: nginx:1.22
#ports:
#- containerPort: 80
#当容器的默认端口是人为指定过的,定义容器对外的端口,可省略字段
#hostPort: 80
#可以直接和宿主机的度那口映射,不需要再指定service,但是只能在yaml文件当中,不能在命令行中执行。一般不用hostPort,且要把kind换成Daemonset
#Daemonset可以用hostPort
restartPolicy: Always
#pod内的容器的重启策略kubectl apply -f deployment.yaml --force #强制生效
service类型
kubectl explain service
vim service.yaml
apiVersion: v1
kind: Service
metadata:
#service的名称和标签
name: nginx-abc
namespace: abc
labels:
test1: nginx
spec:
#定义service的参数类型
type: NodePort
ports:
- port: 80
targetPort: 80
selector:
#匹配对应的资源的标签
app: nginx-yamlkubectl edit svc -n abc nginx-abc #修改nginx-abc的配置文件
多个类型的可以写在一个yaml文件当中,用---分割开来。
pod内的容器的重启策略
当pod内的容器重启失败或者运行时报错的重启策略
- always: 默认模式,一直重启(自愈机制的核心)
- Never: 都不重启
- Onfailure:只有状态是非0才会重启,是0不重启
基于控制器(deployment)创建的pod的重启策略只能是always
command和args字段
apiVersion:vl
#定义api的接口
kind: Pod
#创建资源对象的类型
metadata:
#元数据信息,pod的名称,和标签
name: nginx-test-pod
labels:
app1: nginx1
spec:
#pod内使用的容器,容器的名称,和镜像的版本
containers:
- name: centos
image: centos:7
command: ["echo"]
args: ["hello,world!"]
restartPolicy: onFailure#输出hello,world!
类似于docker的CMD和ENTRYPOINT,command和args级别比cmd和entrypoint要高,会覆盖原有容器的命令输出。args也会给command传参数。
command和agrs在一个yaml文件中,非传参的情况下,只能存在一个,表示容器的启动命令,会覆盖原容器的启动命令。
多条命令一定要加上/bin/bash和-c;多个命令之间要用分号隔开,一个命令也可以用/bin/bash和-c
写法一:
args:
- /bin/bash
- -C
- while true; do sleep 3600; done写法二:
args: ["/bin/bash","-c","touch /opt/123;echo 123 > /opt/123; cat /opt/123; sleep 3600"]#运行单个命令
command: ["/usr/bin/test","-e","/etc/passwd"]
args: ["/bin/bash","-c","test -e /etc/passwd"]