k8s概述与特性
1. 概述
- 集群化管理,使用部署更加简洁高效
- 支持容器化部署
- 应用扩展
2. 特点
- 自动装箱: 自动部署
- 自我修复: 节点异常自动重新调度与重启
- 水平扩展: 简单命令-扩展或裁剪规模 ,cpu内存等硬件扩展
- 服务发现: 负载均衡,根据规则自动转发
- 滚动更新: 可以批量更新
- 版本回退: 支持历史版本回退
- 密码与配置管理: 不用重启,热更新秘钥与配置
- 存储编排: 本地目录,网络存储,公共云存储
- 批处理: 一次性或 定时任务的批处理
2. 架构组件
master组件 主节点
- APIserver :集群统一入口,restful风格
- etcd : 持久化存储相关配置信息
- scheduler : 节点的调度,根据策略选择节点服务器
- controller-manager: 处理集群的后台任务,一个资源对应一个controller
node组件 工作节点
- kubelet :管理 当前工作服务器中的容器
- kube-proxy 提供网络代理, 负载均衡
3.搭建k8s
1. 平台规划
- 单集群 :1个master
- 多集群 :多个master + master负载均衡
2. 配置要求
测试
- master :2核+4g + 20g
- node :master*2
正式
- 比测试更高
3.kubeadm搭建
master
kubeadm init
安装 kubeadm docker kubectl
node
kubeadm join
安装 kubeadm docker kubelet
要求
禁止 swap
部署网络插件CNI
kubectl apply -f kube-flannel.yml
4.二进制部署
官方参考: kubernetes.io/zh-cn/docs/…
master部署
- 安装docker
- 使用cfssl生成根证书
- 搭建etcd
- 生成etcd证书
- 下载etcd程序
- 配置etcd conf,并导入证书
- 设置systemd服务,并启动
- etcd是一个键值数据库
- 下载k8s的server包(包含node需要的库)
- 复制 apiserver,controller-manager
- 生成k8s使用的证书
- 搭建apiserver
- 配置conf和导入证书
- 设置systemd服务,并启动
- 设置授权请求证书
- 搭建kube-controller-manager
- 配置conf和导入证书
- 设置systemd服务,并启动
- 搭建kube-scheduler
- 配置conf和导入证书
- 设置systemd服务,并启动
node部署
- 安装docker
- 复制 kubelet kube-proxy kubectl
- 配置kubelet
- 配置kubelet.conf
- 配置kubelet-config.yml
- 同步master端的ssl 信息 配置到 node
- 生成 bootstrap.kubeconfig
- 设置systemd服务,并启动
- master 上 批准kubelet证书申请并加入集群(Master操作)
- 配置kube-proxy
- kube-proxy.conf
- kube-proxy-config.yml
- kube-proxy.kubeconfig
- 设置systemd服务,并启动
配置网络集群
- node节点:下载cni-plugins-linux-amd64-v0.8.6.tgz
- master执行
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
4.yaml
资源编排清单
包含
- 控制器定义
- 被控制对象
常见字段
- apiVersion API版本
- kind 资源类型
- metadata 资源元数据
- spec 资源规格
- replicas 副本数量
- selector 标签选择器
- template Pod模板
- metadata Pod元数据
- spec Pod规格
- containers 容器配置
语法格式
- 通过缩进表示层级关系
- 不能使用Tab进行缩进,只能使用空格
- 一般开通缩进两个空格
- 字符后缩进一个空格,比如冒号,逗号等后面
- 使用---表示新的yam文件开始
- 使用#代表注释
5.Pod
1.存在的意义
- 传统docker ,一个应用,一个容器,一个进程,不同进程互相独立
- pod 可以实现多进程管理
- 亲密应用
- 两个应用之间调用
- 网络之间调用
- 两个应用高频访问
2.特性
- 最小部署单元
- 生命周期短
- 一组容器的集合
- 共享网络
- 共享资源
3.实现机制
linux隔离原理
- namespace : cpu内存隔离
- group :数据隔离
共享资源与网络
- 每个pod都会创建一个pause容器:在同一个namespace下pod都共享网络
- 共享资源:通过数据卷实现持久化共享
4.测试例子
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: write
image: centos
command: ["bash","-c","for in (1..100);do echo $i >> /data/hello;sleep 1;done"]
volumeMounts:
- name: data
mountPath: /data
- name: read
image: centos
command: ["bash","-c","tail -f /data/hello"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
emptyDir: {}
5.状态
- Pending 镜像下载中
- Running 下载完成,正在启动或重启
- Completed 启动完成
- failed 启动失败
- unknown 未知错误
6.label
通过label 让service和RS 与pod产生关联
matchLabels:
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy1
spec:
replicas: 3
selector:
matchLabels:
app: nginx1
template:
metadata:
name: newkubia
labels:
app: nginx1
spec:
containers:
- image: nginx
name: nginx
6.常用配置
拉取策略
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: nqinx
image: nqinx:1.14
imagePullPolicy: Always
- IfnotPresent:默认值,镜像在宿主机上不存在时才拉取
- Always:每次创建 Pod 都会重新拉取一次镜像
- Never Pod水远不会主动拉取这个镜像
容器检查
livenessProbe存活检查
livenessProbe 当检测失败后,将杀死容器并根据 Pod 的重启策略来决定作出对应的措施。
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec
labels:
app: liveness
spec:
containers:
- name: liveness
image: busybox
args: #创建测试探针探测的文件
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
initialDelaySeconds: 10 #延迟检测时间
periodSeconds: 5 #检测时间间隔
exec: #使用命令检查
command: #指令,类似于运行命令sh
- cat #sh 后的第一个内容,直到需要输入空格,变成下一行
- /tmp/healthy #由于不能输入空格,需要另外声明,结果为sh cat"空格"/tmp/healthy
存活检查 HTTP
containers:
- name: xxx
image: xxx
# 存活检查
livenessProbe:
httpGet:
scheme: HTTP # 协议
path: /actuator/health # 路径
port: 8080 # 端口
initialDelaySeconds: 30 # 延迟探测时间(秒) 【 在k8s第一次探测前等待秒 】
periodSeconds: 10 # 执行探测频率(秒) 【 每隔秒执行一次 】
timeoutSeconds: 1 # 超时时间
successThreshold: 1 # 健康阀值
failureThreshold: 3 # 不健康阀值
存活检查 TCP
containers:
- name: xxx
image: xxx
# 存活检查
livenessProbe:
tcpSocket: # TCP
port: 8090 # 端口
initialDelaySeconds: 50 # 延迟探测时间(秒) 【 在k8s第一次探测前等待秒 】
periodSeconds: 10 # 执行探测频率(秒) 【 每隔秒执行一次 】
timeoutSeconds: 1 # 超时时间
successThreshold: 1 # 健康阀值
failureThreshold: 3 # 不健康阀值
readinessProbe就绪检查
readinessProbe 当检测失败后,将 Pod 的 IP:Port 从对应的 EndPoint 列表中删除。
containers:
- name: xxx
image: xxx
# 就绪检查
readinessProbe:
httpGet:
scheme: HTTP # 协议
path: /actuator/health # 路径
port: 8080 # 端口
initialDelaySeconds: 30 # 延迟探测时间(秒)【 在k8s第一次探测前等待秒 】
periodSeconds: 2 # 执行探测频率(秒) 【 每隔秒执行一次 】
timeoutSeconds: 1 # 超时时间
successThreshold: 1 # 健康阀值
failureThreshold: 3 # 不健康阀值
startupProbe探针
如果三个探针同时存在,先执行startupProbe探针,其他两个探针将会被暂时禁用,直到pod满足startupProbe探针配置的条件,其他2个探针启动,如果不满足按照规则重启容器
startupProbe:
httpGet:
path: /test
prot: 80
failureThreshold: 60
initialDelay:5
periodSeconds: 5
分发node策略
nodeSelector 标签选择器
# 创建标签
kubectl label node k8snode1 env_role=prod
# 查看标签
kubectl get node --show-labels
# 设置nodeSelector
- nodeSelector
env_role: dev
资源限制
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
- requests:运行的基本条件
- limits::限制最大
nodeAffinity亲和
- required强策略 :必须匹配,不满足一直重试
- preferred软策略 :尝试满足,不确定
- 条件 In NotIn Exists Gt Lt DoesNotExists 例子
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-hello-deployment
namespace: chenqiang-ns1
labels:
app: nginx-hello
spec:
replicas: 2
selector:
matchLabels:
app: nginx-hello
template:
metadata:
labels:
app: nginx-hello
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: tester
operator: NotIn
values:
- chenqiang
containers:
- name: nginx-hello
image: docker-registry.saicstack.com/chenqiang/nginx-hello:v2.0
ports:
- containerPort: 80
imagePullSecrets:
- name: regcred
污点+容忍度
原理
- 通过在node节点设置污点
- 在yaml文件设置容忍度规则
Taints污点
nodeSelector和nodeAffinity: Pod调度到某些节点上,Pod属性,调度时候实现 Taint污点:节点不做普通分配调度 ,是节点属性
# 查看
kubectl describe nodes master | grep Taints
# 添加污点
kubectl taint nodes node1 key=value:NoSchedule
# 删除 使用减号
kubectl taint nodes node1 key1:NoSchedule-
常用属性
- NoSchedule:一定不被调度
- PreferNoSchdule:尽量不被调度
- NoExecute:不会调度,并且还会驱逐Node已有Pod
容忍度tolerations
tolerations:- key: "key1" operator: "Equal" value: "value1" effect: "NoExecute" tolerationSeconds: 3600
6.Controller
- 早期使用 Replication Controller
- 后期Replica Set
- 最新使用Deployment 集成RS功能
特性
确保预期的副本数量 有状态应用部署 无状态应用部署 确保所有node在运行同一个pod 一次性与定时任务
定义
- 就是管理容器的对象,即kubectl
- 使用kubectl才能创建pod,伸缩,滚动升级
- pod和controller 通过类型deployment + 标签label+selector建立关系
例子
spec:
repicas: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
Deployment应用场景
deployment就是 rs的一个升级,管理副本数概念
deployment等价于 docker-compse
- 管理无状态应用 :web应用 ,微服务
- 管理pod和replicaSet
- 部署,滚动升级
# 更新
# 查看kubectl get svc
# 版本滚动更新 注意下面设置的nginx2 是 svc里的
kubectl set image deployment nginx2 nginx=nginx:1.15
# 回滚
# 查看升级状态
kubectl rollout status deployment nginx
# 查看历史升版本
kubectl rollout history deployment nginx
# 回滚上个版本
kubectl rollout undo deployment nginx
# 回滚 指定版本 参数--to-revision 为history查询的版本号
kubectl rollout undo deployment nginx --to-revision=2
使用流程
kubectl create deployment nginx2 --image=nginx -o yaml --dry-run=client > test.yaml
kubectl apply -f test.yaml
kubectl expose deployment nginx2 --port=80 --type=NodePort --target-port=3499 --name=nginx2
kubectl get deployment nginx2 -o yaml > nginx.yaml
# port自动原来系统的端口
# --target-port 是service的内部端口
# 设置type=NodePort 会把80 做随机端口的映射到外部
例子
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy1
spec:
replicas: 3
selector:
matchLabels:
app: nginx1
template:
metadata:
name: newkubia
labels:
app: nginx1
spec:
containers:
- image: nginx
name: nginx
7.Service
作用
定义pod的访问规则
存在的意义
- 实现服务发现 : 防止pod失联,通过service做统筹
- 实现负载均衡
和pod的关系
- 一个service关联多个pod
- 根据label和selector建立关系
例子
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: nginx2
name: nginx2
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8000
selector:
app: nginx2
type: NodePort
status:
loadBalancer: {}
service类型
- ClusterIP 集群内使用
- NodePort 对外访问
- Loadbalancer 对外,公有云 等价于 自己部署了nginx转发 ClusterIP 内部的IP和服务
8.statefulSet
无状态与有状态区别
无状态
- pod都是一样
- 无顺序
- 不考虑指定node运行
- 随意扩展 伸缩
有状态
- 每个pod独立
- 保存pod启动的唯一性 ,生成规则: 主机名称.service名称.名称空间.svc.cluster.local
- 保持pod的有启动顺序,如mysql 主从服务
- 唯一网络标识,做持久化
部署有状态
无service
- ClusterIP:none
- 无ip
- kind:StatefulSet
9.SaemonSet
守护进程
确保每一个node 都会运行一份的指定程序,不能多分。如每台机器日志或数据采集
kind: DaemonSet
10.Job
- 一次性执行的任务
- 配合command执行
11.CronJob
- 定时执行的任务
- 配合command执行
12.Secret
加密配置
- 存储在etcd
- pod 挂载Volume
- 场景 : 凭证的使用
例子
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
user: YWRtaW4=
pass: MWYyZDFlMmU2N2Rm
env环境变量挂载
#pod-secret-env.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-secret-env
spec:
containers:
- name: myapp
image: busybox
args:
- sleep
- "86400"
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: user
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: pass
restartPolicy: Never
数据卷挂载
apiVersion: v1
kind: Pod
metadata:
name: test-projected-volume
spec:
containers:
- name: test-secret-volume
image: busybox
args:
- sleep
- "86400"
volumeMounts:
- name: mysql-cred
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: mysql-cred
projected:
sources:
- secret:
name: user
- secret:
name: pass
12.ConfigMap
非加密配置存储
例子
#redis.properties
redis.host=127.0.0.1
redis.port=63793
redis.password=123456
# 创建
kubectl create configmap redis-config --from-file=redis.properties
kubectl describe cm redis-config
13.服务端与节点重置
master
# 设置节点为 维护模式
kubectl drain k8snode2 --delete-local-data --force --ignore-daemonsets node/k8snode2
kubectl drain k8snode1 --delete-local-data --force --ignore-daemonsets node/k8snode1
# 删除节点
kubectl delete node k8snode2
# 确认是否已经删除
kubectl get nodes
# 生成永久Token(node加入的时候会用到)
kubeadm token create --ttl 0 --print-join-command
# 查看token
kubeadm token list
# 只要token
kubeadm token list | awk -F" " '{print $1}' |tail -n 1
# 查看当前的节点
kubectl get nodes
# 检查健康
kubectl get cs
# 查看启动的服务
kubectl get pods -n kube-system -o wide
# 查看某个节点的完整状态
kubectl describe node k8snode2
node
# 停掉kubelet
systemctl stop kubelet
# 删除之前的相关文件
rm -rf /etc/kubernetes/*
# 依旧有异常 设置这个信息
kubeadm reset
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
# 查看日志
journalctl -xeu kubelet
# 重新加入xxxxxxxx 通过 master获取
kubeadm join 192.168.0.13:6443 --token xxxxxxxx --discovery-token-unsafe-skip-ca-verification
14.命令描述
基础命令
create # 通过文件名或标准输入创建资源
expose # 将一个资源公开为一个新的Service
run # 在集群中运行一个特定的镜像
set # 在对象上设置特定的功能
get # 显示一个或多个资源
explain # 文档参考资料
edit # 使用默认的编辑器编辑一个资源。
delete # 通过文件名、标准输入、资源名称或标签选择器来删除资源。
部署命令
rollout # 管理资源的发布
rolling-update # 对给定的复制控制器滚动更新
scaleautoscale # 扩容或缩容Pod数量,Deployment、ReplicaSet、RC或Job创建一个自动选择扩容或缩容并设置Pod数量
集群管理命令
certificate # 修改证书资源
cluster-info # 显示集群信息
top # 显示资源(CPU/Memory/Storage)使用。需要Heapster运行
cordon# 标记节点不可调度
uncordon# 标记节点可调度
drain # 驱逐节点上的应用,准备下线维护
taint# 修改节点taint标记
高级命令
apply # 通过文件名或标准输入对资源应用配置
patch # 使用补丁修改、更新资源的字段
replace # 通过文件名或标准输入替换一个资源
convert # 不同的API版本之间转换配置文件
设置命令
label # 更新资源上的标签
annotate # 更新资源上的注释
completion # 用于实现kubect1工具自动补全
其他命令
api-versions # 打印受支持的API版本
config # 修改kubeconfig文件(用于访问AP1,比如配置认证信息)
help # 所有命令帮助
plugin # 运行一个命令行插件
version # 打印客户端和服务版本信息
官方说明
Basic Commands (Beginner):
create Create a resource from a file or from stdin.
expose Take a replication controller, service, deployment or pod and expose it as a new Kubernetes Service
run Run a particular image on the cluster
set Set specific features on objects
Basic Commands (Intermediate):
explain Documentation of resources
get Display one or many resources
edit Edit a resource on the server
delete Delete resources by filenames, stdin, resources and names, or by resources and label selector
Deploy Commands:
rollout Manage the rollout of a resource
scale Set a new size for a Deployment, ReplicaSet or Replication Controller
autoscale Auto-scale a Deployment, ReplicaSet, or ReplicationController
Cluster Management Commands:
certificate Modify certificate resources.
cluster-info Display cluster info
top Display Resource (CPU/Memory/Storage) usage.
cordon Mark node as unschedulable
uncordon Mark node as schedulable
drain Drain node in preparation for maintenance
taint Update the taints on one or more nodes
Troubleshooting and Debugging Commands:
describe Show details of a specific resource or group of resources
logs Print the logs for a container in a pod
attach Attach to a running container
exec Execute a command in a container
port-forward Forward one or more local ports to a pod
proxy Run a proxy to the Kubernetes API server
cp Copy files and directories to and from containers.
auth Inspect authorization
15.常用命令
namespace
# 查看
kubectl get ns
# 删除
kubectl delete ns/nginx-01
node
# 查看当前的节点
kubectl get nodes
# 查看节点 其他信息
kubectl get node o wide
# 查看节点 labels
kubectl get node --show-labels
# 显示node描述
kubectl describe node k8smaster
pod
# 查看 默认读取default
kubectl get pods
# 查看 所有pod
kubectl get pods -A
# 输出额外信息
kubectl get pods -o=wide
# 输出yml文件
kubectl get pods etcd-k8smaster -o=yml
# 显示pod信息
kubectl get pods nginx-f89759699-4r8sf -o yaml
# 暴露端口
kubectl expose deployment nginx --port=8076 --type=NodePort
# 删除所有 Pod
kubectl delete pod --all
# 重启 pod
kubectl get pod <POD名称> -n <NAMESPACE名称> -o yaml | kubectl replace --force -f -
deployment
# 创建
kubectl create deployment nginx --image=nginx
# 执行create 同时 输出yaml
kubectl create deployment nginx2 --image=nginx -o yaml
# 不执行create只输出yaml
kubectl create deployment nginx2 --image=nginx -o yaml --dry-run=client
# 不执行create只输出yaml 同时输出文件
kubectl create deployment nginx2 --image=nginx -o yaml --dry-run=client > ngiinx.yaml
# get 输出yaml
kubectl get deployment nginx2 -o yaml
# get 输出yaml 同时输出文件
kubectl get deployment nginx2 -o yaml > nginx.yaml
# 查看已部署
kubectl get deployments
## 弹性伸缩
kubectl scale deployment nginx2 --replicas=3
# 伸缩 pod 也可以做删除处理,设置为0即可
kubectl scale deploy/nginx-1 --replicas=0
kubectl scale deploy/nginx-1 --replicas=1
controller
# run创建
kubectl run nginx --image=nginx:latest --imagePullPolicy=IfNotPresent --replicas=3
# create创建
kubectl create -f nginx.yaml
# 查看控制器
kubectl get rc
# 删除
kubectl delete rc/nginx
# rs 复制对象 ReplicaSet
kubectl get rs
service
# 暴露端口 注意8000不是对外的端口 只是pause容器端口,最终对外是随机的
kubectl expose deployment nginx2 --port=80 --type=NodePort --target-port=8000 --name=nginx2
# 暴露端口 不执行并导出文件
kubectl expose deployment nginx2 --port=80 --type=NodePort --target-port=8000 --name=nginx2 --dry-run=client -o yaml > nginx8.yaml
# 端口映射
kubectl expose rc rc-name --type=ClusterIP --target-port=80 --port=80
# yaml方式
kubectl create -f nginx-service.yaml
# 修改网络类型
kubectl patch service istio-ingressgateway -n istio-system -p '{"spec":{"type":"NodePort"}}'
# 删除
kubectl delete svc/nginx
rollout
# 查看
kubectl get svc
# 版本滚动更新 注意下面设置的nginx2 是 svc里的
kubectl set image deployment nginx2 nginx=nginx:1.15
# 查看升级状态
kubectl rollout status deployment nginx
# 查看历史升版本
kubectl rollout history deployment nginx
# 回滚上个版本
kubectl rollout undo deployment nginx
# 回滚 指定版本 参数--to-revision 为history查询的版本号
kubectl rollout undo deployment nginx --to-revision=2
其他
# exec
kubectl exec -it redis-master-cln81 -- bash
# logs
kubectl logs <pod-name>
# 实时查看日志
kubectl logs -f <pod-name>
# 查看节点 labels
kubectl get node --show-labels
# 设置label标签
kubectl label k8snode1 env_role=prod
# 查看 endpoint 列表
kubectl get endpoints
# 删除资源
kubectl delete 资源类型 -l name=<label-name>
# describe 的详细信息
kubectl describe node k8smaster
kubectl describe pod nginx
# csr
# 获取当前证书
kubectl get csr