Kubernetes容器存活探测&应用自恢复
概述当你使用kuberentes的时候,有没有遇到过Pod在启动后一会就挂掉然后又重新启动这样的恶性循环?你有没有想过kubernetes是如何检测pod是否还存活?虽然容器已经启动,但是kubernetes如何知道容器的进程是否准备好对外提供服务了呢? 本博文主要记录实践如何配置容器的存活和就绪探针。 liveness probe(存活探针)用于判断容器是否存活,即Pod是否为running状态,如果LivenessProbe探针探测到容器不健康,则kubelet将kill掉容器,并根据容器的重启策略是否重启,如果一个容器不包含LivenessProbe探针,则Kubelet认为容器的LivenessProbe探针的返回值永远成功。 readiness probe(就绪探针)用于判断容器是否启动完成,即容器的Ready是否为True,可以接收请求,如果ReadinessProbe探测失败,则容器的Ready将为False,控制器将此Pod的Endpoint从对应的service的Endpoint列表中移除,从此不再将任何请求调度此Pod上,直到下次探测成功。 每类探针都支持三种...
理解Kubernetes中的认证&授权&准入机制
概述首先需要了解这三种机制的区别: 认证(Authenticating)是对客户端的认证,通俗点就是用户名密码验证, 授权(Authorization)是对资源的授权,k8s中的资源无非是容器,最终其实就是容器的计算,网络,存储资源,当一个请求经过认证后,需要访问某一个资源(比如创建一个pod),授权检查都会通过访问策略比较该请求上下文的属性,(比如用户,资源和Namespace),根据授权规则判定该资源(比如某namespace下的pod)是否是该客户可访问的。 准入(Admission Control)机制是一种在改变资源的持久化之前(比如某些资源的创建或删除,修改等之前)的机制。在k8s中,这三种机制如下图:k8s的整体架构也是一个微服务的架构,所有的请求都是通过一个GateWay,也就是kube-apiserver这个组件(对外提供REST服务),由图中可以看出,k8s中客户端有两类,一种是普通用户,一种是集群内的Pod,这两种客户端的认证机制略有不同,后文会详述。但无论是哪一种,都需要依次经过认证,授权,准入这三个机制。 kubernetes 中的认证机制需要注意的...
理解kubernetes中的Storage
序、为何需要存储卷容器部署过程中一般有以下三种数据: 启动时需要的初始数据,可以是配置文件 启动过程中产生的临时数据,该临时数据需要多个容器间共享 启动过程中产生的持久化数据 以上三种数据都不希望在容器重启时就消失,存储卷由此而来,它可以根据不同场景提供不同类型的存储能力。各类卷:  spec.volumes:通过此字段提供指定的存储卷 spec.containers.volumeMounts:通过此字段将存储卷挂接到容器中 一、普通存储卷的用法:容器启动时依赖数据1. ConfigMap上图也说了它是在容器启动的时候以来的数据来源 示例:12345678910111213141516171819202122232425262728293031323334353637383940# 1.创建configmap预制数据卷cat >> configmap.yaml << EOFapiVersion: v1data: guomaoqiu: hello-worl...
理解kubernetes中的有状态服务StatefulSet
概述概念StatefulSet 是为了解决有状态服务的问题(对应 Deployments 和 ReplicaSets 是为无状态服务而设计),其应用场景包括 稳定的持久化存储,即 Pod 重新调度后还是能访问到相同的持久化数据,基于 PVC 来实现 稳定的网络标志,即 Pod 重新调度后其 PodName 和 HostName 不变,基于 Headless Service(即没有 Cluster IP 的 Service)来实现 有序部署,有序扩展,即 Pod 是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依序进行(即从 0 到 N-1,在下一个 Pod 运行之前所有之前的 Pod 必须都是 Running 和 Ready 状态),基于 init containers 来实现 有序收缩,有序删除(即从 N-1 到 0) 从上面的应用场景可以发现,StatefulSet 由以下几个部分组成: 用于定义网络标志(DNS domain)的 Headless Service 用于创建 PersistentVolumes 的 volumeClaimTemplates 定义具体应...
管理Kubernetes日志
概述日志是我们在运维部署当中非常重要的一个东西,对于我个人工作经验而言,一般出现问题,第一步事情就是查看日志,其次是服务器资源查看这样去定位问题,那么在kubernets集群当中呢,我主要给其分了两种类型: kubernetes组件日志 运行于kubernetes上的容器应用日志 kubernetes组件日志我们知道在kubernetes集群是有多个组件组成,协同为我们提供一个运行容器的环境。当运行当中出现问题,也是需要查看对应组件的日志,进行问题排查、处理。那么常见的日志如下: 12345/var/log/kube-apiserver.log/var/log/kube-proxy.log/var/log/kube-controller-manager.log/var/log/kube-scheduler.log/var/log/kubelet.log 当然根据搭建集群的方式不同,我们配置的日志目录也不尽相同,所以只是列举一下;如果组件的安装方式由systemd来管理的话 我们还可以通过以下命令进行排错 123journalctl -u kubelet或systemctl s...
理解kubernetes中Pod访问方式
概述Pod的IP是在docker0网段动态分配的,当发生重启,扩容等操作时,IP地址会随之变化。当某个Pod(frontend)需要去访问其依赖的另外一组Pod(backend)时,如果backend的IP发生变化时,如何保证fronted到backend的正常通信变的非常重要。由此,引出了Service的概念。这里docker0是一个网桥,docker daemon启动container时会根据docker0的网段来划粉container的IP地址Docker网络在实际生产环境中,对Service的访问可能会有两种来源:Kubernetes集群内部的程序(Pod)和Kubernetes集群外部,为了满足上述的场景,Kubernetes service有以下三种类型: ClusterIP:提供一个集群内部的虚拟IP以供Pod访问。 NodePort:在每个Node上打开一个端口以供外部访问。 LoadBalancer:通过外部的负载均衡器来访问。 那么它是怎么实现的,通过下面的示例来理解。(创建方式可以是通过yaml文件或者是命令行方式,这里为了理解我先用命令行方式创建,如果...
Kubernetes中deployment升级回滚
在kubernetes中使用deployment管理rs时,可以利用deployment滚动升级的特性,达到服务零停止升级的目的 命令行创建一个deploymen1kubectl run nginx --image=nginx 多副本deployment1kubectl run nginx --image=nginx --replicas=2 --record 滚动升级 (可以加上–record参数可以记录命令)12345678kubectl set image deploy/nginx nginx=nginx:1.9.1# 滚动策略:kubectl edit deployment nginx strategy: rollingUpdate: maxSurge: 1 # 升级过程中可以比预设的 pod 的数量多出的个数,默认值是25% maxUnavailable: 1 # 最多有几个 pod 处于无法工作的状态,默认值是25% 滚动升级状态查看1kubectl rollout status deploy/nginx 查看升级历史123kubectl...
K8s Yaml编写小技巧
学习使用k8s的童鞋都知道我们在部署pod的时候有时候需要手动去编写一些yaml文件;比如我需要编写deployment,那除了在其他地方粘贴拷贝外有没有其他方法呢?答案是有的 1.用run命令生成,然后作为模板进行编辑。12345678910kubectl run --image=nginx my-deploy -o yaml --dry-run > my-deploy.yaml ``` ### 2.用get命令导出,然后作为模板进行编辑。``` # 注意: --export 是为了去除当前正在运行的这个deployment生成的一些状态,我们用不到就过滤掉kubectl get deployment/nginx -o=yaml --export > new.yaml``` ### 3.Pod亲和性下面字段的拼写忘记了 kubectl explain pod.spec.affinity.podAffinity 示例: --- 我想生成一个有三个副本的redis pod的yaml,然后我想把这三个pod 通过node亲和性调度到同一个node...
K8s集群中pause容器是干嘛的~
当我们在检查k8s集群状态的时候会发现有很多 pause 容器运行于服务器上面,然后每次启动一个容器,都会伴随一个pause容器的启动。那它究竟是干啥子的? Pause容器,又叫Infra容器,下面通过实验来理解它。 我们知道在搭建k8s集群的时候,kubelet的配置中有这样一个参数: [root@linux-node1 cfg]# more /usr/lib/systemd/system/kubelet.service ······ ······ --pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause-amd64:3.1 \ ······ ······ 我这里是直接将这些配置参数通过启动脚本来补充进去的。Pause容器,是可以自己来定义,官方使用的gcr.io/google_containers/pause-amd64:3.0容器的代码见Github,使用C语言编写。 Pause容器的作用我们检查nod节点的时候会发现每个node上都运行了很多的pause...
理解Kubernetes的亲和性调度
NodeName、nodeSelector、nodeAffinity、podAffinity、Taints以及Tolerations用法 1. NodeNamePod.spec.nodeName用于强制约束将Pod调度到指定的Node节点上,这里说是“调度”,但其实指定了nodeName的Pod会直接跳过Scheduler的调度逻辑,直接写入PodList列表,该匹配规则是强制匹配。例子:我的预期是将该pod运行于节点名称为 192.168.56.11 这个节点: 1.1 例如(test-nodename.yaml)apiVersion: v1 kind: Pod metadata: labels: app: with-nodename-busybox-pod name: with-nodename spec: nodeName: 192.168.56.11 #通过这里指定 containers: - command: - sleep - "3600" image: busybox imagePullPolicy: If...
kubernetes调度之NodeSelector
1 NodeNamePod.spec.nodeName用于强制约束将Pod调度到指定的Node节点上,这里说是“调度”,但其实指定了nodeName的Pod会直接跳过Scheduler的调度逻辑,直接写入PodList列表,该匹配规则是强制匹配。例子: apiVersion: apps/v1 kind: Deployment metadata: name: nginx-test labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: nodeName: 192.168.56.13 # 指定pod调度到该节点 containers: - name: nginx image: nginx:latest imagePullPolicy: IfNotPres...
Prometheus 实践
PrometheusServer端安装 prometheus / alertmanager / node_expoter 一、安装prometheus server0.获取软件包(略)、解压复制二进制文件12tar -xf ./packages/alertmanager-0.15.3.linux-amd64.tar.gzmv alertmanager-0.15.3.linux-amd64/alertmanager /usr/local/sbin/ 1.创建运行用户1adduser -M -s /sbin/nologin prometheus 2.创建用户所有者目录12345678910111213# 创建prometheus server运行的目录主要存放配置文件mdkir /usr/local/share/prometheus/prometheus_server -pchown -R prometheus:prometheus /usr/local/share/prometheus# 创建prometheus server数据存储目录mkdir /var/lib/promet...
Flask RestApi 后端开发项目说明
最近一直在做的一个项目就是打算将之前的MVC风格的后台,重构为前后端分离式,由于个人对于Flask框架熟悉程度比起Django来更熟悉一些,所以最终还是选择他作为开发框架来进行后端的开发,目前呢打算的是把基础的平台功能做出来作为一个模板,然后通过这个模板再去结合业务方面的开发。前端方面暂时未开始,目前后端开发进度: 功能 完成度 methods api 备注 用户注册 🚀%100 POST /auth/register null 用户登录 🚀%100 POST /auth/login null 用户登出 🚀%100 POST /auth/logout null 邮件确认 🚀%100 POST /auth/confirm/{confirm_token} null Token刷新 🚀%100 GET /auth/refresh_token null 用户获取 🚀%100 GET /user/ null 用户删除 🚀%100 POST /user/{email} null 用户禁用/启用 🚀%0 POST null 任务添加 🚀%0 POST null 任务获取 �...
通过Consul-Template实现动态配置服务
背景:公司的测试、预发布环境的配置修改在前期都是通过手工登录到服务器上去vim配置文件的,这样一来就会产生一定的安全或者误操作以及频繁的操作真的是有些恶心的;去年在此基础上也为运营/测试使用Flask 写了一个平台让他们自己用;但是由于一些不定因素,不能够满足这方面的需求;但是本人还是坚持以自动化的理念来操作;所以学习了解了一下自动配置的一些工具,比如Consul,当然他的原理功能网上有很多;也没有必要在这里再一次说了;主要记录一下对于这个需求的一个想法到实现的过程。”妈妈再也不担心我vim错配置啦~~~😁” 这是前期为运营人员使用Flask开发的一个平台,主要日常涉及到的操作(测试/预发布环境) 下面是针对以上一些操作规划的一个拓扑图: 这里我主要使用到了consul的k/v存储以及consul-template动态的配置系统 操作人员通过Opsplatform操作后,通过调用consul-http-api将最新的key/value put到consul-datacenter; 客户端服务器添加对应的模板文件,通过consul-template命令启动监控模板文件 当...
Kubernetes Session亲和性设置
当我们在部署了多个pod,以及一个Service后,就可以在集群内部通过ServiceIP访问pod提供的服务了; 当不设置session保持时,service向后台pod转发规则是轮询:以上我通过点击页面请求,可以就看出service将我的请求分发到了后面的三个pod; k8s会根据访问的ip来把请求转发给他以前访问过的pod,这样session就保持住了。查看创建service时的yaml文件内容,如果没有设置的话 该项是为None的
如何将pod中的container时区更改为同一时区的城市或UTC时区偏移
问题:在创建pod container后发现里面的时区是UTC,对于国内习惯还是CST时区比较易读;那如何解决这种问题嘛?暂时想到的两种办法: [root@linux-node1 ~]# kubectl exec flask-app-nginx-66b56f556c-zb84s date -n flask-app-extions-stage Mon Jul 14 07:32:52 UTC 2018 [root@linux-node1 ~]# date Mon Jul 14 15:32:52 CST 2018 直接修改镜像的时间设置,好处是应用部署时无需特殊设置,但是需要手动从新构建Docker镜像 部署应用时,单独读取主机的”/etc/localtime”,无需修改镜像,但是每个应用都要单独设置。 解决:为了快速,简单的解决此问题,先使用第二种方法;yaml文件中映射主机的”/etc/localtime”文件, 添加yaml配置: ...... ...... spec: containers: - name: nginx im...
How to Change Ingress-Nginx Nginx's Configuration?
序今天访问了一下之前搭建的那套k8s应用,当我客户端通过域名访问(ingress-nginx通过域名转发请求到后端)时,出现了504的情况;第一想到的就是当后端一直没返回时;proxy超时了; 192.168.56.1 - [192.168.56.1] - - [03/Jul/2018:09:16:54 +0000] "GET / HTTP/1.1" 504 586 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36" 412 10.002 [flask-app-extions-stage-flask-app-nginx-80] 10.2.17.5:80 0 10.003 504 497fe6db73abcd3ed749fdc646870432 # 响应10.003秒就报504😢 问题就出在这里,ingress-nginx代理用户请求到flask-app-nginx SVC...
劝君莫惜金缕衣,劝君惜取少年时。
人生短短几十年、工作、学习(专业技能知识)也许就占了我们生命中的大部分的时间、也是我们生存下来的基础。但是能不能在这基础之上找点缝隙学习、尝试一些不一样的东西呢,这个还是看个人吧~~~我个人倒是现在除了工作、学习还是需要培养一点其他的兴趣爱好,从各个方面不断丰富、完善自己。 回想起年幼时父亲用最严厉的方式逼着我练字,当时根本不懂为什么非要逼着我练习,现在回想起来我只能打心底的感激父亲让我有了这个习惯或者说是培养了我这个兴趣爱好。以至于能写出还算拿得出手的字体。 劝君莫惜金缕衣,劝君惜取少年时。 花开堪折直须折,莫待花开空折枝。