【笔记】Kubernetes学习笔记
前言
Kubernetes(常简称为K8s)是用于自动部署、扩展和管理“容器化(containerized)应用程序”的开源系统。该系统由Google设计并捐赠给Cloud Native Computing Foundation(今属Linux基金会)来使用。(维基百科)
开源项目
集群部署
集群方案
单机(两台虚拟机):一个主控节点+工作节点,一个工作节点
每台至少CUP2核,内存2G
环境搭建
下载easzup脚本
上传
easzup
脚本,并添加执行权限
1 | chmod +x easzup |
- 通过脚本,下载离线安装文件
/etc/ansible
,并安装配置docker
1 | ./easzup -D |
- 通过脚本,使用临时容器
1 | ./easzup -S |
- 进入容器
1 | docker exec -it kubeasz sh |
- 在容器内制定配置命令,改为离线安装
1 | cd /etc/ansible |
- 安装python,pip,ansible
1 | yum install python -y |
- 加载容器
1 | docker load -i images.gz |
配置主控
- 生成ssh密钥对,向工作节点复制ssh公钥
1 | ssh-keygen -t ed25519 -N '' -f ~/.ssh/id_ed25519 |
- 配置hosts
1 | cd /etc/ansible |
- 在hosts文件中配置
集群节点
、主控节点
、工作节点
- 集群节点会参加选举,所以通常配置奇数个
1 | [etcd] |
- 检查所有主机状态,有
ping
有pong
即为成功
1 | ansible all -m ping |
一键安装k8s集群
- 在主控节点执行一键安装命令
1 | cd /etc/ansible |
验证环境
查看集群状态
cs
:Cluster集群
1 | kubectl get cs |
查看节点服务器
no
:Node节点
1 | kubectl get no |
对控制器的操作
- 控制器可以自动控制容器的部署和销毁
由控制器自动创建一个容器
--image=<img>
:指定镜像--port=<port>
:指定对外暴露的端口--generator=run/v1
:指定api版本<rc_name>
:控制器名
1 | kubectl run --image=<img> --port=<port> --generator=run/v1 <rc_name> |
ReplicationController
- RC可以自动化维护多个pod,只需指定pod副本的数量,就可以轻松实现自动扩容缩容
- 当一个pod宕机,RC可以自动关闭pod,并启动一个新的pod替代它
- 标签的完整匹配
apiVersion: v1
:api版本kind:
:定义配置文件类型(核心配置)
ReplicationController
:用于创建RC控制器的配置文件
metadata.name
:定义名称spec.replicas
:容器副本的数量spec.selector
:根据选择器来选择RC管理的容器
<key>
:标签键<value>
:标签值
spec.template
:定义容器的模版spec.template.metadata.labels
:创建容器时为容器贴标签
<key>
:标签键<value>
:标签值
spec.containers
:对容器的配置
1 | apiVersion: v1 |
ReplicaSet
- 标签选择可以使用运算符
- 是ReplcationController的新版控制器
创建配置文件
matchLabels
apiVersion: v1
:api版本kind:
:定义配置文件类型(核心配置)
ReplicationController
:用于创建RS控制器的配置文件
spec.selector.matchLabels
:使用label选择器,对标签进行完整匹配
<key>
:标签键<value>
:标签值
1 | apiVersion: apps/v1 |
matchExpressions
apiVersion: v1
:api版本kind:
:定义配置文件类型(核心配置)
ReplicationController
:用于创建RS控制器的配置文件
spec.selector.matchLabels
:表达式匹配选择器spec.selector.matchLabels.key
:指定标签键spec.selector.matchLabels.operator
:运算符
In
:label与其中一个值匹配NotIn
:label与任何一个值都不匹配Exists
:包含指定labet名称,值任意DoesNotExeists
:不包含指定label名称,值任意
spec.selector.matchLabels.values
:指定标签值,label值列表
1 | apiVersion: apps/v1 |
DaemonSet
- 在每个节点上运行一个 pod,包括主控服务器
- 主要用途:资源监控,kube-proxy等
- DaemonSet不指定pod数量,它会在每个节点上部署一个pod
不含节点选择器
1 | apiVersion: apps/v1 |
包含节点选择器
spec.template.spec.nodeSelector
:节点选择器
1 | apiVersion: apps/v1 |
Job
- Job 用来运行单个任务,任务结束后pod不再重启
单个运行运行单次
spec.template.spec.restartPolicy
:重启策略
OnFailure
:任务失败时
1 | apiVersion: batch/v1 |
单个运行运行多次
sepc.completions
:指定任务执行总次数
1 | apiVersion: batch/v1 |
并行运行运行共多少次
spec.parallelism
:并行运行任务数量
1 | apiVersion: batch/v1 |
Cronjob
spec.schedule
:定义cron的定时任务格式每个单位数用空格隔开,每组单位数用逗号隔开,如果该单位数每个单位都执行用
*
表示第一个单位
:分钟第二个单位
:小时第二个单位
:月中的天第二个单位
:月第二个单位
:周中的天
1 | apiVersion: batch/v1beta1 # api版本 |
通过配置文件创建控制器
<yml>
:配置文件
1 | kubectl create -f <yml> |
查看控制器
<para_1>
:操作的对象
rc
:对RC控制器的操作rs
:对RS控制器的操作ds
:对DS控制器的操作job
:对Job控制器的操作cj
:对CJ控制器的操作ns
:对Namespace操作po
:对容器的操作all
:对控制器、命名空间、容器同时操作
1 | kubectl get <para_1> |
修改控制器配置
- 如果模版中标签数量有变动,只会在创建新容器时使用新的模版
1 | kubectl edit <para_1> <name> |
删除
--cascade
:不级联删除容器
<para_2>
:过滤方式
<name>
:指定操作的对象名-l <key>=<value>
:指定标签--all
:没有任何过滤
1 | kubectl delete <para_1> <para_2> |
对容器的操作
- k8s以pod为单位来部署容器
- pod为docker容器的封装对象
- 一个pod可以封装多个docker容器
创建配置文件
- 创建并编辑
.yml
配置文件
apiVersion: v1
:api版本kind:
:定义配置文件类型(核心配置)
Pod
:用于创建容器的配置文件Namespace
:用于创建命名空间的配置文件
metadata.name
:定义名称。如果是Pod类型,会自动在末尾生成随机字符串用于区分spec.containers
:对容器的配置spec.containers.image
:docker镜像名(核心配置)spec.containers.imagePullPolicy
:是否联网下载镜像
Never
:不联网下载镜像
spec.containers.name
:定义镜像名spec.containers.ports.containerPort
:容器暴露的端口(可选)
1 | apiVersion: v1 |
通过配置文件创建容器
<yml>
:指定配置文件-n <namespace>
:指定部署的命名空间
1 | kubectl create -f <yml> |
包含节点选择器
- 部署到指定服务器
- 修改pod配置文件
spec.nodeSelector
:节点选择器
1 | apiVersion: v1 |
查看容器
po
:pod容器-o wide
:查看更多信息-n <namespace>
:查看指定命名空间的容器--show-labels
:展示标签
1 | kubectl get po |
查看容器描述
1 | kubectl describe po <name> |
查看日志
- 查看当前容器
--previous
:查看上一个容器
1 | kubectl logs <name> |
进入容器内部
1 | kubectl exec -it <name> bash |
删除容器
1 | kubectl delete po <name> |
删除多个容器
1 | kubectl delete po <name_1> <name_2> |
按标签删除
1 | kubectl delete po -l <key>=<value> |
删除当前命名空间的所有pod
- 删除后控制器会自动重建新的pod
1 | kubectl delete po --all |
对服务的操作
- 服务控制容器的访问
- 提供一个不变的访问地址,可以向所有容器转发调用,类似于SpringCloudZuul
创建服务
rc <rc_name>
:指定控制器类型及控制器名<svc_name>
:Service名
1 | kubectl expose rc <rc_name> --type=NodePort --name <svc_name> |
创建配置文件
- 创建并编辑yml配置文件
spec.ports.port
:服务向外暴露的端口spec.ports.targetPort
:容器的端口
1 | apiVersion: v1 |
通过配置文件创建服务
<yml>
:配置文件
1 | kubectl create -f <yml> |
通过服务扩容和缩容
- 通过服务调整容器的数量
<num>
:根据指定的数量自动调整,如果为0,自动销毁所有容器
1 | kubectl scale rc <rc_name> --replicas=<num> |
查看服务
svc
:Service服务
1 | kubectl get svc |
查看服务详细信息
1 | kubectl describe svc <name> |
手动创建Endpoints对象
Endpoint是在Service和pod之间的一种资源
一个Endpoint资源,包含一组pod的地址列表
创建于Service同名的Endpoints即可建立关联
subsets.addresses
:包含的地址列表
ip: <ip>
:访问地址
subsets.ports.port
:目标服务的端口
1 | apiVersion: v1 |
对外暴露
NodePort
- 每个节点都开放一个端口
部署一个新的服务
创建配置文件
- 创建并编辑yml配置文件
spec.type
:对外暴露类型
NodePort
:在每个节电上开放访问端口
spec.ports.nodePort
:外部访问端口
1 | apiVersion: v1 |
LoadBalance
- NodePort的一种扩展,负载均衡器需要云基础设施来提供
Ingress
- 一种特殊的方式
对命名空间的操作
创建配置文件
- 创建并编辑
.yml
配置文件
1 | apiVersion: v1 |
通过配置文件创建命名空间
1 | kubectl create -f <yml> |
查看命名空间
- 不同命名空间可以出现同名pod
ns
:Namespace命名空间
1 | kubectl get ns |
删除命名空间
- 删除命名空间及其包含的所有pod
1 | kubectl delete ns <namespace> |
删除所有对象
- 删除容器、控制器、服务,不包括pv和pvc
- 这个操作会删除一个系统Service kubernetes,它被删除后会立即被自动重建
1 | kubectl delete all --all |
对标签的操作
- 为每个pod贴不同的标签,service根据不同的标签掌管不同的pod
新建容器时,为新容器贴标签
- 编辑配置
metadate.labels
:标签设置,键值对形式,每个标签占一行
<key>
:标签键<value>
:标签值
1 | metadata: |
查看标签
- 列出所有的pod,并显示pod的标签
1 | kubectl get po --show-labels |
查看指定标签
- 列出所有的pod,并显示指定的标签
1 | kubectl get po -L <key_1>,<key_2> |
添加标签
po <pod>
:对容器的操作no <ip>
:对节点的操作
1 | kubectl label po <pod> <key>=<value> |
添加多个标签
1 | kubectl label po <pod> <key_1>=<value_1> <key_2>=<value_2> |
删除标签
<key>-
:根据标签键删除标签
1 | kubectl label po <pod> <key>- |
修改标签
<pod>
:指定pod名--overwrite
:修改标签,防止误修改,确认修改而不是添加po
:为容器贴标签no
:为服务器贴标签
1 | kubectl label po <pod> <key>=<value> --overwrite |
根据标签查询容器
-l
:查询标签
- 根据标签为
<key>
的pod,查看pod的详细信息,并展示和 的标签信息
1 | kubectl get po -l <key> -L <key_1>,<key_2> |
- 根据标签为
<key>=<value>
的pod,查看pod的详细信息,并展示和 的标签信息
1 | kubectl get po -l <key>=<value> -L <key_1>,<key_2> |
- 根据标签为
<key_1>=<value_1>
并且<key_2>=<value_2>
的pod,查看pod的详细信息,并展示和 的标签信息
1 | kubectl get po -l <key_1>=<value_1>,<key_2>=<value_2> -L <key_1>,<key_2> |
- 根据标签不为
<key>
的pod,查看pod的详细信息,并展示和 的标签信息
1 | kubectl get po -l '!<key>' -L <key_1>,<key_2> |
- 根据标签不为
<key>=<value>
的pod,查看pod的详细信息,并展示和 的标签信息
1 | kubectl get po -l '<key>!=<value>' -L <key_1>,<key_2> |
- 根据标签键
<key>
包含<value_1>
和<value_2>
的pod,查看pod的详细信息,并展示和 的标签信息
1 | kubectl get po -l '<key> in (<value_1>,<value_2>)' -L <key_1>,<key_2> |
- 根据标签键
<key>
不包含<value_1>
和<value_2>
的pod,查看pod的详细信息,并展示和 的标签信息
1 | kubectl get po -l '<key> notin (<value_1>,<value_2>)' -L <key_1>,<key_2> |
存活探针
- 在部署文件中,我们添加探针,来探测容器的健康状态.
- 探针默认每10秒探测一次,连续三次探测失败后重启容器
存活探针的类型
HTTP GET
- 返回2xx或3xx响应码则认为探测成功
TCP
- 与指定端口建立TCP连接,连接成功则为探测成功
Exec
- 在容器内执行指定的任意命令,并检查命令的退出码,退出码为0则为探测成功
修改配置文件
- 修改pod配置文件
spec.containers.livenessProbe
:存活探针配置spec.containers.livenessProbe.httpGet
:存活探针类型为HttpGetspec.containers.livenessProbe.httpGet.path
:探测路径spec.containers.livenessProbe.httpGet.port
:探测端口spec.containers.livenessProbe.initialDelaySeconds
:第一次探测的延迟时间
1 | spec: |
探针的描述
1 | kubectl describe po <name> |
Liveness
:存货探针的参数
http-get
:探测类型http://:8080/
:探测路径delay
:第一次探测间隔timeout
:超时时间period
:探测间隔success
:探测成功次数failure
:探测失败次数
数据卷
emptyDir
spec.containers.volumeMounts
:容器中数据卷的配置
spec.containers.volumeMounts.name
:指定容器使用的数据卷名spec.containers.volumeMounts.mountPath
:容器中的挂载路径spec.containers.volumeMounts.readOnly
:是否为只读
spec.volums
:数据卷的配置
spec.volums.name
:定义数据卷名spec.volums.emptyDir
:定义数据卷类型为emptyDir类型
emptyDir
:简单的空目录hostPath
:工作节点中的磁盘路径gitRepo
:从git克隆的本地仓库nfs
:nfs共享文件系统
1 | apiVersion: v1 |
nfs
准备一个目录
准备一个目录作为共享目录
编辑
exports
配置文件
1 | vim /etc/exports |
- 修改
exports
配置文件
/etc/nfs_data
:指定共享的目录192.168.64.0/24
:配置共享的网络,0.0.0.0
表示不限制网段rw
读写权限async
:异步写入no_root_squash
:访问时不降级root身份的权限
1 | /etc/nfs_data 192.168.64.0/24(rw,async,no_root_squash) |
- 在客户端挂载nfs目录
192.168.64.191:/etc/nfs_data
:远端nfs路径/etc/web_dir
:客户端路径
1 | mount -t nfs 192.168.64.191:/etc/nfs_data /etc/web_dir |
持久卷
持久数据卷
apec.capacity.storage
:定义持久卷大小apec.accessModes
:持久卷的权限
ReadWriteOnce
:只允许被一个客户端挂载为读写模式ReadOnlyMany
:可以被多个客户端挂载为只读模式
apec.persistentVolumeReclaimPolicy
:持久卷声明被释放时的配置
Retain
:持久卷声明被释放时,保留持久卷
apec.nfs
:配置nfs数据卷
apec.nfs.path
:远端数据卷的目录路径apec.nfs.path
:远端数据卷的访问路径
1 | apiVersion: v1 |
持久卷声明
- 根据配置自动匹配持久卷
spec.resources.requests.store
:申请存储空间大小spec.accessModes
:读写权限
1 | apiVersion: v1 |
挂载持久数据卷声明
spec.volumes.name
:定义持久卷名spec.volumes.persistentVolumeClaim.claimName
:引用持久卷声明名称
1 | apiVersion: v1 |
查看持久卷
1 | kubectl get pv |
查看持久卷声明
1 | kubectl get pvc |
删除持久卷
1 | kubectl delete pv --all |
删除持久卷声明
1 | kubectl delete pvc --all |
覆盖docker启动命令和启动参数
spec.containers.command
:覆盖ENTRYPOINT启动命令spec.containers.args
:覆盖CMD启动参数
1 | apiVersion: v1 |
设置环境变量
直接设置环境变量
spec.containers.env
:设置环境变量
spec.containers.env.name
:环境变量名spec.containers.env.value
:环境变量值
1 | apiVersion: v1 |
引用Map中的值作为环境变量
创建一个ConfigMap
data
:Map中的键值对
1 | apiVersion: v1 |
使用ConfigMap作为环境变量
spec.containers.env.valueFrom.configMapKeyRef
:通过ConfigMap设置环境变量
spec.containers.env.valueFrom.configMapKeyRef.name
:指定ConfigMap的名称spec.containers.env.valueFrom.configMapKeyRef.key
:指定对应名称ConfigMap中的键名,使用该键值对作为环境变量
1 | apiVersion: v1 |
通过目录及文件的方式生成ConfigMap
创建一个目录,目录名即为ConfigMap名
在目录下创建文件,每个文件的文件名,即为ConfigMap中的键
每个文件中包含的文本内容,即为对应文件名的键所对应的值
通过这个目录生成ConfigMap
<name>
:目录名
1 | kubectl create configmap fortune-config --from-file=<name> |
查看ConfigMap
1 | kubectl get cm <name> -o yaml |
Deployment
Deployment 是一种更高级的资源,用于部署或升级应用
创建Deployment时,ReplicaSet资源会随之创建,实际Pod是由ReplicaSet创建和管理,而不是由Deployment直接管理
Deployment可以在应用滚动升级过程中,,引入另一个RepliaSet,,并协调两个ReplicaSet
配置文件与RS相似,因为Deploy会自动启动RS做滚动升级操作
1 | apiVersion: apps/v1 |
查看Deploy
1 | kubectl get deploy |
为Deploy打补丁
- 修改Deploy属性
添加间隔时间
1 | kubectl patch deploy <name> -p '{"spec": {"minReadySeconds": 10}}' |
查看滚动升级的状态
1 | kubectl rollout status deploy <name> |
回滚上一个版本
1 | kubectl rollout undo deploy <name> |
改变滚动升级速率
spec.strategy.rollingUpdate.maxSurge
:允许超出容器的数量,可以为百分比或数值,默认值为25%spec.strategy.rollingUpdate.maxUnavailable
:允许不可用容器的数量,可以为百分比或数值,默认值为25%
1 | apiVersion: apps/v1 |
暂停滚动升级
1 | kubectl rollout pause deploy <name> |
继续滚动升级
1 | kubectl rollout resume deploy <name> |
就绪探针
- 通过就绪探针判定是否就绪,未就绪会阻塞,阻塞10分钟,升级不再执行
spec.minReadySeconds
:判定就绪的时间(单位:秒)
spec.template.spec.containers.readinessProbe
:配置就绪探针
spec.template.spec.containers.readinessProbe.periodSeconds
:间隔时间spec.template.spec.containers.readinessProbe.httpGet.path
:探测路径spec.template.spec.containers.readinessProbe.httpGet.port
:探测端口
1 | apiVersion: apps/v1 |
仪表盘
查看仪表盘容器
1 | kubectl get pod -n kube-system | grep dashboard |
查看仪表盘服务
1 | kubectl get svc -n kube-system | grep dashboard |
查看仪表盘访问地址
1 | kubectl cluster-info | grep dashboard |
- 首次访问未认证,需要通过CA生成证书,并在浏览器安装证书
生成证书
- 进入ssl目录
1 | cd /etc/kubernetes/ssl |
- 在当前目录下生成证书
1 | openssl pkcs12 -export -in admin.pem -inkey admin-key.pem -out kube-admin.p12 |
设置密码,如果不需要密码直接回车
下载证书
导入证书
在Chrome浏览器设置搜索
证书
->安全
->管理证书
->个人
->导入
->选择p12后缀
->导入导入成功后重启Chrome浏览器
登陆仪表盘
- 通过Token登陆
在服务器生成令牌
令牌过期会失效
生成令牌
1 | kubectl apply -f /etc/ansible/manifests/dashboard/admin-user-sa-rbac.yaml |
- 获取令牌
1 | kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}') |
- 通过得到的令牌进行登陆