1. 问题简述
怎样在K8S集群中发布一个新的项目?怎样判断一个项目是发布成功了还是失败了?怎样访问一个项目?怎样实现灰度发布?怎样实现发布过程中的并发度控制、暂停、继续、取消?怎样实现回滚?
本文中,会努力寻求这些问题的答案。
参考文档:
- Pod 的生命周期
- 管理资源
- Service
- 10 Most Common Reasons Kubernetes Deployments Fail (Part 1)
- 10 Most Common Reasons Kubernetes Deployments Fail (Part 2)
2. 准备镜像
首先准备两个镜像,分别是nginx:v1.0和nginx:v2.0。
1、启动并进入容器
1 | docker run --name nginx -d -p 80:80 voidking/nginx:latest |
有些小伙伴会有疑问,为什么不使用docker run
启动并进入容器?docker run -it voidking/nginx:latest /bin/bash
因为如果使用这种方式进入容器,修改内容后commit镜像,那么镜像无法正常启动。
docker ps -a --no-trunc
使用该命令可以看到,voidking/nginx:latest的默认启动命令为:nginx -g 'daemon off;'
而commit后的镜像,默认启动命令被修改为:/bin/bash
看到这里就知道,因为自定义的启动命令覆盖掉了原有的启动命令,所以镜像无法正常启动。为什么会覆盖呢?因为CMD指令允许用户指定容器的默认的执行命令,此命令会在容器启动且docker run没有指定其他命令时运行。当docker run指定其他命令时,则会覆盖默认的执行命令。更多内容参考Dockerfile RUN,CMD,ENTRYPOINT命令区别。
2、修改index.html
1 | cd /usr/share/nginx/html |
3、commit/push镜像
1 | docker ps -l |
3. kubectl
在使用go-client之前,我们先来学习一下使用kubectl怎样发布项目、获取状态、访问项目、更新项目。
3.1. 发布项目
以发布一个nginx项目为例。
1、准备deployment yaml文件nginx.yaml
1 | apiVersion: apps/v1 |
2、发布项目
1 | kubectl apply -f nginx.yaml |
3.2. 获取状态
1 | kubectl get deployments nginx |
根据获取到的信息,判断发布成功还是失败。
3.3. 访问项目
1、准备service yaml文件nginx-svc.yaml
1 | apiVersion: v1 |
2、查看服务IP和端口
1 | kubectl get svc nginx |
3、访问项目
1 | minikube service nginx |
执行上面的命令后,会自动打开浏览器。
或者使用curl命令访问:curl http://192.168.99.100:32329/
4、从容器内部访问项目(三种方式)
1 | kubectl get pods |
如果env命令没有显示出nginx service信息,那么可以重建pod:
1 | kubectl get pod hello-node-6747d458b6-d757m -n default -o yaml | kubectl replace --force -f - |
PS:使用kubectl进入容器的方法
1 | kubectl get pods |
3.4. 更新发布
1、修改nginx.yaml中的配置,升级镜像为voidking/nginx:2.0
1 | apiVersion: apps/v1 |
2、更新发布
1 | kubectl apply -f nginx.yaml |
3、访问项目
1 | curl http://192.168.99.100:32329/ |
4. client-go
《使用client-go操作K8S》一文中,配置好了k8s-client-go项目,可以使用这个项目对k8s集群进行一些基本操作。在此基础上,本节会实现一些更高阶的操作。
4.1. 判断发布状态
根据deployment和pod的状态,怎样判断一次发布成功还是失败?首先,要知道deployment和pod都有哪些状态。
1、通过kubectl命令获取发布数据
1 | kubectl get deployments hello-node -o json |
2、获取到的发布数据
发布成功的json数据:hello-node.json
发布失败的json数据:nginx.json
3、具体可用状态有哪些
1 | # deployment部分 |
4、判断条件组合
参考k8s-client-go/common/deployment.go文件的GetDeploymentStatus函数。
4.2. 灰度发布
常见的发布方案包括蓝绿发布、滚动发布和灰度发布(金丝雀发布),更多内容参考微服务部署:蓝绿部署、滚动部署、灰度发布、金丝雀发布。
参考Spinnaker第四节-对接k8s、基于 Spinnaker 的 K8S 灰度发布、灰度发布/蓝绿发布,使用Ingress,可以很好地实现灰度发布。但是,在没有Ingress的情况下,该怎样实现灰度发布?
最简单的方案是发布一个新的deployment,把service的流量分流到新的deployment
,测试通过后删除老的deployment,流量就全部到了新的deployment。具体实现参考k8s-client-go/common/deploy.go文件的GrayDeploy和UpdateDeploy函数。
但是,如果只允许维护一个deployment,该怎么处理?创建灰度的deployment,测试通过后删除灰度的deployment,然后正常更新原有的deployment。具体实现参考k8s-client-go/common/deploy.go文件的GrayDeploy2和UpdateDeploy2函数。
5. 后记
并发度控制、暂停、继续、取消、回滚等等功能,未完待续。。。