应用升级以及新旧业务切换,在这个过程当中如何保证对外的服务正常是一个非常重要的问题。
把服务器分为蓝组和绿组,先停其中的一部分,先停蓝组,绿组依然对外提供服务,等蓝组更新维护完毕,上线之后,再把绿组关闭维护。可以做到业务更新和发布过程的对外服务不受影响。
过去成本很高,
负载均衡+高可用
特点:一旦出现问题,影响范围比较大
发布策略也比较简单
用户无感知,平滑过渡
缺点:需要大量的后台服务器以作为支撑。成本还是比较高的
金丝雀发布就是先整个测试服测试版本,先打上断点,版本没问题就可以取消断点进行滚动更新,删除所有旧版本,加上一个新版本
金丝雀发布:灰度发布。
Deployment控制器可以通过自定义控制的方式实现金丝雀发布。
[root@master01 ~]# kubectl create deployment nginx1 --image=nginx:1.12 --replicas=3 #创建pod [root@master01 ~]# kubectl set image deployment/nginx1 nginx=nginx:1.22 && kubectl rollout pause deployment nginx1 #创建一个测试服 [root@master01 ~]# kubectl rollout resume deployment/nginx1 #测试服没有问题,更新版本
自动化控制的要求很高。整个系统的稳定性比蓝绿发布要高。影响范围可控。
部署时间比较慢,但是节约资源。发布的策略也比较复杂。
yaml文件实现:
[root@master01 k8s-yaml]# vim nginx-deploy.yaml #aip版本的标签 aipVersion: apps/v1 kind: Deployment #定义资源的类型/角色 kind的类型:Deployment Job Ingress Service Deamonset metadata: #定义创建资源的元数据信息,资源的名称————pod的名称,命名空间,pod的标签 name: nginx1 # namepaces: #定义命名空间,不写就是默认命名空间 labels: app: nginx1 #标签名:app=nginx1 上下文要一致 spec: #顶格写属于全局配置,spec配置deployment资源需要的参数属性。副本数,匹配的标签以及容器的重启策略 replicas: 3 #定义该资源pod的数量 selector: matchLabels: #selector用来定义标签的选择器,matchLabels用来定义匹配的标签,这里需要上下文保持一致。 app: nginx1 #都是定义容器和pod的元数据 template: #定义业务模板,定义了3个副本,所有的pod的属性都会和template的设置保持一致 metadata: labels: app: nginx1 #这里也需要和上下文保持一致 spec: #定义pod内的容器 containers: - name: nginx image: nginx:1.22 #--image=nginx:1.22 # ports: # - containerPort: 8080 #如果nginx的端口是默认的就是80,ports可以不写,写了也无法改变容器内的端口。 #如果默认端口不是80,那就需要加上ports声明非默认端口。 [root@master01 k8s-yaml]# kubectl apply -f nginx-deploy.yaml #创建资源对象 [root@master01 k8s-yaml]# kubectl delete -f nginx-deploy.yaml #删除资源对象
pod和容器是分开的也是合并的。镜像定义容器。pod不能改变镜像
[root@master01 k8s-yaml]# vim nginx-service.yaml #定义api标签: apiVersion: v1 kind: Service metadata: #定义service的名称和标签 name: nginx1-svc labels: app1: nginx1 spec: #定义service的资源参数,端口映射,类型、匹配的标签名(和哪个资源对象进行匹配) type: NodePort ports: - port: 80 #service的端口 targetPort: 80 #容器内的端口 nodePort: 30000 selector: app: nginx1 [root@master01 k8s-yaml]# kubectl apply -f nginx-service.yaml
[root@master01 k8s-yaml]# vim nginx-pod.yaml apiVersion: v1 kind: Pod metadata: name: nginx-pod labels: app: nginx-pod spec: #声明容器的参数 containers: - name: nginx image: nginx:1.22 ports: - containerPort: 80 hostPort: 80 #主机端口,直接让主机端口和容器端口做映射(只能在yaml文件当中表示) [root@master01 k8s-yaml]# kubectl apply -f nginx-pod.yaml pod/nginx-pod created [root@master01 k8s-yaml]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-pod 1/1 Running 0 13s 10.244.1.42 node02nginx1-b666bdb8c-67tkt 1/1 Running 0 104m 10.244.2.40 node01 nginx1-b666bdb8c-pltdv 1/1 Running 0 104m 10.244.2.41 node01 nginx1-b666bdb8c-wzw7q 1/1 Running 0 104m 10.244.1.41 node02 [root@master01 k8s-yaml]# curl 192.168.60.130 123
Always 只要启动失败就会一直重启容器
Never 从不重启 docker的默认模式
OnFailure 只有容器异常退出时,才会重启。返回码非0时,才会对容器进行重启。
[root@master01 k8s-yaml]# vim centos-pod.yaml apiVersion: v1 kind: Pod metadata: name: centos-pod labels: app: centos-pod spec: #声明容器的参数 containers: - name: centos image: centos:7 ports: - containerPort: 80 hostPort: 80 restartPolicy: Always #主机端口,直接让主机端口和容器端口做映射(只能在yaml文件当中表示) [root@master01 k8s-yaml]# kubectl apply -f nginx-centos.yaml [root@master01 k8s-yaml]# kubectl get pod NAME READY STATUS RESTARTS AGE centos-pod 0/1 CrashLoopBackOff 1 77s
apiVersion: v1 kind: Pod metadata: name: centos-pod labels: app: centos-pod spec: #声明容器的参数 containers: - name: centos image: centos:7 ports: - containerPort: 80 hostPort: 80 restartPolicy: Never [root@master01 k8s-yaml]# kubectl apply -f nginx-pod.yaml pod/centos-pod created [root@master01 k8s-yaml]# kubectl get pod NAME READY STATUS RESTARTS AGE centos-pod 0/1 Completed 0 3s
如果是deployment,那么容器只能是Always,默认就是Always,可以不写。
基于pod的yaml文件,三种类型都可以。
command和args
在yaml文件当中command和arges只能各存在一个。
agres可以给command传参
写法一: apiVersion: v1 kind: Pod metadata: name: centos-pod labels: app: centos-pod spec: #声明容器的参数 containers: - name: centos image: centos:7 ports: - containerPort: 80 hostPort: 80 args: - /bin/bash - -c - while true; do sleep 3600; done [root@master01 k8s-yaml]# kubectl apply -f nginx-pod.yaml --force #pod的yaml会有这种重复,提示有内容没有发生变化,需要加--force强制执行。 [root@master01 k8s-yaml]# kubectl get pod NAME READY STATUS RESTARTS AGE centos-pod 1/1 Running 0 9s
写法二: apiVersion: v1 kind: Pod metadata: name: centos-pod labels: app: centos-pod spec: #声明容器的参数 containers: - name: centos image: centos:7 ports: - containerPort: 80 hostPort: 80 args: ["/bin/bash","-c","while true;do sleep 3600;done"] [root@master01 k8s-yaml]# kubectl apply -f nginx-pod.yaml --force [root@master01 k8s-yaml]# kubectl get pod NAME READY STATUS RESTARTS AGE centos-pod 1/1 Running 0 4s
args: ["/bin/bash","-c","touch /opt/123.txt;echo 123 > /opt/123.txt; sleep 3600"] #/bin/bash 多个命令必须要加/bin/bash #-c 输出命令的格式 #多个命令 /bin/bash -c 都需要 #主机端口,直接让主机端口和容器端口做映射(只能在yaml文件当中表示)
command的用法:
args: ["/bin/bash","-c","touch /opt/123.txt;echo 123 > /opt/123.txt; sleep 3600"]
args给command传参:
apiVersion: v1 kind: Pod metadata: name: centos-pod labels: app: centos-pod spec: #声明容器的参数 containers: - name: centos image: centos:7 ports: - containerPort: 80 hostPort: 80 command: ["echo"] args: ["hello word"] [root@master01 k8s-yaml]# kubectl logs -f centos-pod hello word
command和args如果不需要传参只能存在一个
不论是args还是command都会覆盖容器的标准输出(类似CMD和entrypoint)
导出模板:
#先创建一个pod [root@master01 k8s-yaml]# kubectl create deployment nginx-de --image=nginx-1.22 --replicas=3 #将pod的模板导入到/opt/k8s-yaml/目录下 [root@master01 k8s-yaml]# kubectl get deployments.apps nginx-de -o yaml > /opt/k8s-yaml/nginx-de.yaml