kubernetes的使用
kubectl命令行管理工具
参考命令:前端
kubectl经常使用的命令行管理命令
- 部署应用
kubectl create deployment web --image=nginx:1.14 kubectl get deploy,pods
- 暴露应用
kubectl expose deployment web --port=80 --type=NodePort --targer-port=80 --name=web kubectl get service
- 应用升级
kubectl set image deployment/web nginx=nginx:1.16 kubectl rollout status deployment/web
- 应用回滚
kubectl rollout undo deployment/web #回滚到上一个版本 kubectl rollout history deploy/web #查看版本(版本号递增,最新的也就是版本号最大的) kubectl rollout undo deploy/web --to-revision=1 #指定版本回滚
- 扩缩容
kubectl scale deployment web --replicas=4 #扩容至4个pod kubectl scale deployment web --replicas=1 #缩容至1个pod
资源编排
kubeadm init工做:
一、[preflight] 检查环境是否知足条件
二、[kubelet-start] 启动kubelet
三、[certs] /etc/kubernetes/pki 生成apiserver和etcd两套证书
四、[kubeconfig] 链接apiserver的配置文件
五、[control-plane] 静态Pod /etc/kubernetes/manifests
六、[etcd] 静态pod启动etcd
七、[upload-config] 将kubeadm配置存放到kube-system configmap
八、[kubelet] 将kkubelet配置存放到kube-system configmap
九、[mark-control-plane] node-role.kubernetes.io/master='' 说明master节点不调度pod
十、[bootstrap-token] 为kubelet自动颁发证书机制
十一、安装插件 CoreDNS kube-proxy
java
k8s组成回顾
- master
- apiserver: 为api对象验证并配置数据,包括pods,services,APIserver提供Restful操做和到集群共享状态的前端,全部其它组件经过apiserver进行交互
- kube-scheduler: 具备丰富的资源策略,可以感知拓扑变化,支持特定负载的功能组件,它对集群的可用性,性能表现以及容量都影响巨大,scheduler须要考虑独立的和集体的资源需求,服务质量需求,硬件、软件,策略限制,亲和与反亲和规范,数据位置吗内部负载接口,截止时间等等,若有特定的负载需求能够经过apiserver暴露出来
- kube-controllermanager:做为集群内部的控制中心,负责集群内部的Node,Pod副本,服务端点,命名空间,服务帐号,资源配额的管理,当某个Node意外宕机时,controller-manager会及时发现并执行自动修复,确保集群始终处于预期的工做状态
- Node
- kube-proxy: 维护node节点上的网络规则,实现用户访问请求的转发,其实就是转发给service,须要管理员指定service和NodePort的对应关系
- kubelet: kubelet 是运行在每一个节点上的主要的“节点代理”,它按照 PodSpec 中的描述工做。 PodSpec 是用来描述一个 pod 的 YAML 或者 JSON 对象。kubelet 经过各类机制(主要经过 apiserver )获取一组 PodSpec 并保证在这些 PodSpec 中描述的容器健康运行。kubelet 无论理不是由 Kubernetes 建立的容器。
- Etcd: 存储全部集群数据
yaml文件格式说明
- 声明式API: 资源清单
- 定义资源控制器,以便维护资源建立的对象
- 资源比较多,文档查找方法
# dry-run获取 kubectl create deployment nginx --image=nginx:1.14 -o yaml --dry-run=client > my-deploy.yml # 命令行导出 kubectl get deploy/web -o yaml --export > my-deploy.yml # 忘记字段 kubectl explain pod.spec
深刻理解POD资源对象
kubectl的命令可分为三类
- 陈述式命令: 用到的run,expose,delete和get等命令,他们直接操做于k8s系统上的活动对象,简单易用;但不支持代码服用,修改以及日志审计等功能,这些功能的实现要经过依赖于资源配置文件中,这些文件称为资源清单
- 陈述式对象配置
- 声明式对象配置: apply完成增和改的操做 [推荐使用]
POD基本概念
- k8s最小部署单元
- pod是名称空间级别的资源(namespace)
- 能够是一组容器的组合
- 一个POD中的容器共享网络名称空间
- Pod是短暂的
建立pod的方式
- 直接命令行建立
- 使用pod控制器建立,例如(deployment,daemonset,statefulset)
- service也能建立
pod存在的意义
- pod为亲密性应用而存在
- 亲密性应用场景
- 两个应用之间发生文件交互
- 应用之间须要经过127.0.0.1或者socket通讯
- 两个应用之间须要发生频繁的调用
pod实现机制与设计模式
- 共享网络
- 共享存储
$ vim demo1.yml apiVersion: v1 kind: Pod metadata: name: my-pod namespace: prod spec: containers: - name: write image: centos:7 command: ["bash","-c","for i in {1..100};do echo $i >> /data/hello;sleep 1;done"] volumeMounts: - name: data mountPath: /data - name: read image: centos:7 command: ["bash","-c","tail -f /data/hello"] volumeMounts: - name: data mountPath: /data volumes: - name: data emptyDir: {} $ kubectl create ns prod $ kubectl apply -f demo1.yml $ kubectl get pod -n prod $ kubectl exec -it my-pod -n prod bash
镜像拉取策略
- imagePullPolicy
- ifNotPresent
- Always
- Never
$ vim demo2.yml apiVersion: v1 kind: Pod metadata: name: foo namespace: prod spec: containers: - name: foo image: janedoe/awesomeapp:v1 imagePullPolicy: IfNotPresent $ kubectl apply -f demo2.yml $ kubectl describe pod foo -n prod $ kubectl get pod foo -n prod
资源限制
官方文档:https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/node
Pod和Container的资源请求和限制:
• spec.containers[].resources.limits.cpu
• spec.containers[].resources.limits.memory
• spec.containers[].resources.requests.cpu
• spec.containers[].resources.requests.memory
mysql
- 资源限制类型
- limits: 最大值
- requests: 最小值
$ vim demo3.yml apiVersion: v1 kind: Pod metadata: name: frontend spec: containers: - name: db image: mysql env: - name: MYSQL_ROOT_PASSWORD value: "password" resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" - name: wp image: wordpress resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" $ kubectl apply -f demo3.yml
重启策略
- restartPolicy:
- Always: 默认策略,当容器退出后老是重启容器
- OnFailure
- Never
kubectl explain pod.spec.restartPolicy $ vim demo4.yml apiVersion: v1 kind: Pod metadata: name: demo namespace: prod spec: containers: - name: demo1 image: janedoe/awesomeapp:v1 restartPolicy: Always $ kubectl get pod -n prod -w #查看重启状态
健康检查(probe)
- 有两种健康检查方式
- livenessProbe: 存活检测
- readinessProbe: 就绪检测
- probe支持如下三种检查方法
- httpGet
- exec
- tcpSocket
$ vim pod_healthy.yml apiVersion: v1 kind: Pod metadata: labels: test: liveness name: healthy-check namespace: prod spec: containers: - name: liveness image: busybox args: - /bin/sh - -c - touch /tmp/healthy;sleep 30;rm -fr /tmp/healthy;sleep 60 livenessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 5 periodSeconds: 5
资源调度
- pod建立流程
没有涉及到控制器,因此就没有涉及到kube-controller-managernginx
调度策略-影响Pod调度的重要属性
schedulerName: default-secheduler
nodeName: "k8s-node1"
nodeSelector: {}
affinity: {}
tolerations: {}
web
$ vim pod_sheduler.yml apiVersion: v1 kind: Pod metadata: name: web namespace: prod spec: containers: - name: java-demo image: lizhenliang/java-demo imagePullPolicy: IfNotPresent livenessProbe: initialDelaySeconds: 30 periodSeconds: 20 tcpSocket: port: 8080 resources: {} restartPolicy: Always schedulerName: default-secheduler nodeName: "k8s-node1" nodeSelector: {} affinity: {} tolerations: {} $ kubectl apply -f pod_sheduler.yml $ kubectl get pod -n prod -o wide #能够发现pod被调度到k8s-node1
资源限制对Pod调度的影响
- 根据request的值查找有足够资源的node来调度此pod
$ vim pod_schedule_resource.yml apiVersion: v1 kind: Pod metadata: name: mysql namespace: prod spec: containers: - name: mysql image: mysql env: - name: MYSQL_ROOT_PASSWORD value: "123456" resources: requests: cpu: "250m" memory: "64Mi" limits: cpu: "500m" memory: "128Mi" $ kubectl apply -f pod_schedule_resource.yml
nodeSelector & nodeAffinity
- nodeSelector:用于将Pod调度到指定Label的Node上
# 给节点打标签 $ kubectl label nodes k8s-node2 disktype=ssd # 让pod调度到ssd节点 $ vim pod_ssd.yml apiVersion: v1 kind: Pod metadata: name: pod-example namespace: prod spec: nodeSelector: disktype: ssd containers: - name: nginx image: nginx:1.14-alpine $ kubectl apply -f pod_ssd.yml $ kubectl get pod -n prod -o wide #pod被调度到k8s-node2
-
nodeAffinity:节点亲和相似于nodeSelector,能够根据节点上的标签来约束Pod能够调度到哪些节点。sql
- 相比nodeSelector:
- 匹配有更多的逻辑组合,不仅是字符串的彻底相等
- 调度分为软策略和硬策略,而不是硬性要求
- 硬(required):必须知足
- 软(preferred):尝试知足,但不保证
- 操做符:In、NotIn、Exists、DoesNotExist、Gt、Lt
$ vim pod_affinity.yml apiVersion: v1 kind: Pod metadata: name: node-affinity namespace: prod spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: gpu operator: In values: - nvida-telsla preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: group operator: In values: - ai containers: - name: web image: nginx:1.14-alpine $ kubectl apply -f pod_affinity.yml
taint(污点)
Taints:避免Pod调度到特定Node上bootstrap
- 应用场景:
- 专用节点
- 配备了特殊硬件的节点
- 基于Taint的驱逐
# 节点污点的设置 $ kubectl taint node k8s-master item-names=aard:NoSchedule
kubectl taint node [node] key=value:effectvim
其中effect可取值:centos
• NoSchedule :必定不能被调度。
• PreferNoSchedule:尽可能不要调度。
• NoExecute:不只不会调度,还会驱逐Node上已有的Pod。
# 查看node污点 $ kubectl describe node k8s-master #去掉污点 $kubectl taint node k8s-master item-name:NoSchedule-
污点容忍
# 首先选一个节点设置污点 $ kubectl taint node k8s-node2 DiskType=nossd:NoSchedule $ vim pod_tolerate.yml apiVersion: v1 kind: Pod metadata: name: tolerate namespace: prod spec: containers: - name: pod-taint image: busybox:latest tolerations: - key: "DiskType" operator: "Equal" value: "nossd" effect: "NoSchedule" schedulerName: default-secheduler nodeName: "k8s-node2" $ kubectl apply -f pod_tolerate.yml $ kubectl get pod -n prod -o wide #发现会被调度到k8s-node2
故障排查
kubectl describe TYPE/NAME kubectl logs TYPE/NAME [-c CONTAINER] kubectl exec POD [-c CONTAINER] -- COMMAND [args...]