文章目录
- 拥抱K8S
- 介绍+搭建
-
- 简介
- 主要特性
- K8S组件
-
- master组件---管理
- node组件---具体工作者
- 核心概念
- 下载部署
- 二进制安装
- 资源管理
-
- 资源管理方式
-
- 命令式对象管理
- 命令式对象配置
- 声明式对象配置
- 逻辑概念
-
- namespace
- pod
- Label
- Deployment
- Service
- Pod详述
拥抱K8S 介绍+搭建 传送门
- 传统式部署:直接将应用程序部署在物理机上,很难合理性分配资源
- 虚拟化部署:每个虚拟机都是一个独立的环境,解决了应用程序之间的影,一定程度上解决了资源,但增加了操作系统的部署
- 容器化部署:类似虚拟化,但是共享了操作系统,而且可以跨云服务商、跨linux操作系统
- 某个容器出故障宕机,另外一个容器立刻启动补上
- 并发访问变大,如何做到横向扩展容器数量
简介
容器化部署、管理、扩展,想想带环境安装,虽说docker也可以实现容器化的部署,但是还是需要一个完全功能的集群部署功能,而且k8s利于应用的扩展主要特性 自动装箱:应用自动部署
自愈能力:当有容器失败的时候会对容器进行重启,有问题时,会重新部署和调度,未通过检查,会关闭该容器
水平扩展:根据简单命令和ui页面以及cpu使用情况,方便扩容和裁剪
服务发现:k8s自带发现服务功能和负载均衡
滚动更新:可根据应用变化,对容器运行应用进行批次或一次性更新,检测没有问题再更新
版本回退:历史版本记录,可以即时回退
密码配置管理:热部署,不需要重启
存储编排:支持存储本地、网络存储、公有云存储
批处理:支持一次性任务、定时任务
K8S组件
master(主控节点)和node(工作节点)
文章图片
master组件—管理
api server
:集群的统一控制访问入口,以restful方式,交给etcd进行存储scheduler
:节点调度,选择节点应用部署controller-manager
:处理集群中常规的后台任务,一个资源对应一个控制器形象理解三者关系,统一入口rest请求,scheduler选择某个节点,controller去在该节点上部署服务
etcd
:存储状态类的数据,比如master、node的节点信息。有点类型元数据库,也可以替换成mysql或者其他数据库node组件—具体工作者
kubelet
:node里面的管理者,各种状态信息,节点用来管理容器kube-proxy
:提供网络代理,外部访问容器应用程序,负载均衡,类似nginxdocker
:负责节点上容器的各种操作核心概念
Pod
:最小的部署单元,一组容器的集合,共享网络,生命周期短暂的controller
:- 确保预期pod的副本的数量
- 无状态的应用部署(一个节点挂了的容器自动在另外节点启动),有状态应用部署(需要特定条件,不考虑依赖性)
- 确保所有的node运行同一个pod(比如多个节点运行同一个服务)
- 可以创建一致性任务和定时任务
service
:定义一组pod访问规则,不同服务请求不同的pod下载部署 确保docker已安装完成
# 时间同步
yum install ntpdate -y
ntpdate time.windows.com# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld# 关闭selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config# 永久
setenforce 0# 临时# 关闭swap
swapoff -a# 临时
sed -ri 's/.*swap.*/#&/' /etc/fstab# 永久# 三台节点/etc/hosts需要配置# 将桥接的IPv4流量传递到iptables的链
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system# 生效# 配置阿里云yum源,方便安装
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF# 安装1.18.0版本
yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0# 开机自启
systemctl enable kubelet# 主节点启动 参数介绍:当前节点ip 国内镜像 k8s版本 可连接的ip网段
kubeadm init \
--apiserver-advertise-address=172.16.6.10 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.18.0 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config# 使用kubectl工具
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config# 查看是否成功
kubectl get nodes# 从节点加入主节点集群
kubeadm join 172.16.6.10:6443 --token jvdyus.xkae0oh1j7qkvluu \
--discovery-token-ca-cert-hash sha256:b738b0598deb74177613994c9299f28a3899144e0d7e61da859b26d0768db148# 如果产生报错[ERROR FileContent--proc-sys-net-ipv4-ip_forward]: /proc/sys/net/ipv4/ip_forw
sysctl -w net.ipv4.ip_forward=1# 再次查看节点信息,没有准备好,需要进行下一步
[root@lv118 sysctl.d]# kubectl get nodes
NAMESTATUSROLESAGEVERSION
lv118.dct-znv.comNotReadymaster10mv1.18.0
lv121.dct-znv.comNotReady77sv1.18.0
lv123.dct-znv.comNotReady14sv1.18.0# 部署CNI网络插件
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f kube-flannel.yml# 等待全部都是ready
kubectl get pods -n kube-system# 再次查看节点信息
[root@lv118 sysctl.d]# kubectl get nodes
NAMESTATUSROLESAGEVERSION
lv118.dct-znv.comReadymaster18mv1.18.0
lv121.dct-znv.comReady9m21sv1.18.0
lv123.dct-znv.comReady8m18sv1.18.0# 测试k8s集群
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePortkubectl get pod,svc
# 任意一个节点访问80端口对外暴露端口,这里的是32574
文章图片
二进制安装 资源管理 yaml书写介绍:https://www.bilibili.com/video/BV1Qv41167ck?p=13&share_source=copy_web
yaml转json的网站,可以通过它验证yaml是否书写正确https://www.json2yaml.com/convert-yaml-to-json
资源管理方式 kubectl是一个命令行工具
- 命令式对象管理:直接用命令去操作kubernetes资源(命令行直接写参数)
kubectl run nginx-pod --image=nginx:1.17.1 --port=80
- 命令式对象配置:通过命令配置和配置文件去操作kubernetes资源(通过配置文件)
kubectl create/patch -f nginx-pod.yaml
- 声明式对象配置:通过apply命令和配置文件去操作kubernetes资源(只有一个apply关键字,只用于创建和更新资源,也就是该命令没有的时候创建,有了就表示更新)
kubectl apply -f nginx-pod.yaml
综上,第一个比较简单,一般用于测试,不能追踪;第二个适用于开发环境,可以直接定位追踪到文件配置,但项目较大的时候,文件过多;第三个适用于开发环境,支持目录的操作(yaml文件放在一个目录内,对目录进行操作,整体创建/更新)
命令式对象管理
kubectl [command] [type] [name] [flags]# 查看所有的pod
kubectl get pod# 差看某一个pod
kubectl get pod [pod_name]# 查看某个pod所处节点
kubectl get pod [pod_name] -o wide# 查看某个pod,以yaml格式展示结果
kubectl get pod [pod_name] -o yaml# 查看资源
kubectl api-resources
资源分类 | 资源名称 | 缩写 | 资源作用 |
---|---|---|---|
集群级别资源 | nodes | no | 集群组成部分 |
namespaces | ns | 隔离Pod | |
pod资源 | pods | po | 装载容器 |
pod资源控制器 | replicationcontrollers | rc | 控制pod资源 |
replicasets | rs | 控制pod资源 | |
deployments | deploy | 控制pod资源 | |
daemonsets | ds | 控制pod资源 | |
jobs | 控制pod资源 | ||
cronjobs | cj | 控制pod资源 | |
horizontalpodautoscalers | hpa | 控制pod资源 | |
statefulsets | sts | 控制pod资源 | |
服务发现资源 | services | svc | 统一pod对外接口 |
ingress | ing | 统一pod对外接口 | |
存储资源 | volumeattachments | 存储 | |
persistentvolumes | pv | 存储 | |
persistentvolumeclaims | pvc | 存储 | |
配置资源 | configmaps | cm | 配置 |
secrets | 配置 |
# 测试使用# 创建一个dev的命名空间,ns是namespaces缩写,上表有提及
kubectl create ns dev# 查看全部namespaces
kubectl get ns# 在dev下创建一个pod
kubectl run pod --image=nginx -n dev# 查看所创建的pod
kubectl get pods -n dev# 查看创建该pod的详细信息
kubectl describe pods pod -n dev# 删除该创建的pod
kubectl delete pods pod -n dev# 删除空间dev
kubectl delete ns dev
命令式对象配置
# 创建nginxpod.yaml文件,写入如下内容
apiVersion: v1
kind: Namespace
metadata:
name: dev---apiVersion: v1
kind: Pod
metadata:
name: nginxpod
namespace: dev
spec:
containers:
- name: nginx-containers
image: nginx:latest# 创建资源
kubectl create -f nginxpod.yaml# 删除资源
kubectl delete -f nginxpod.yaml
声明式对象配置
# 利用前文提及yaml文件进行创建
kubectl apply -f nginxpod.yaml# 查看资源
kubectl get pods -n dev# 再次执行,会进行更新操作,因为已存在,如果没有变化会显示unchanged,有变动会显示configured
kubectl apply -f nginxpod.yaml
以上操作都是在主节点进行,如果需要从节点执行,需要拷贝主节点用户目录下的.kube文件到从节点用户目录下
逻辑概念 namespace 实现多套环境的资源隔离和多租户的资源隔离
- namespace用于将pod划分为逻辑上的分组,以便于实现不同组之间的资源隔离
- namespace也可对不同的租户进行管理,限制不同租户所占用的资源,例如cpu核数、内存使用
# 查看namespace,k8s启动时会有几个默认的namespace
kubectl get nsdefault#所有未指定Namespace的对象都会被分配在default命名空间
kube-node-lease#集群节点之间的心跳维护,v1.13开始引入
kube-public#此命名空间下的资源可以被所有人访问(包括未认证用户)
kube-system#所有由Kubernetes系统创建的资源都处于这个命名空间# 查看某一ns详情
kubectl get ns defaultName:default
Labels:
Annotations:
Status:Active# Active 命名空间正在使用中Terminating 正在删除命名空间
No resource quota.# ResourceQuota 针对namespace做的资源限制
No LimitRange resource. # LimitRange针对namespace中的每个组件做的资源限制# 查、创、删 命令行
[root@lv118 disk3]# kubectl create ns dev
namespace/dev created
[root@lv118 disk3]# kubectl get ns dev
NAMESTATUSAGE
devActive10s
[root@lv118 disk3]# kubectl delete ns dev
namespace "dev" deleted# 查、创、删 yaml文件
[root@lv118 disk3]# cat ns-dev.yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev[root@lv118 disk3]# kubectl create -f ns-dev.yaml
namespace/dev created
[root@lv118 disk3]# kubectl get ns dev
NAMESTATUSAGE
devActive12s
[root@lv118 disk3]# kubectl delete -f ns-dev.yaml
namespace "dev" deleted
pod pod是k8s最小单元,应用程序跑在容器内,容器存在pod内,所以一个pod可以有多个容器
# 创建并运行指定镜像的pod
kubectl run nginx --image=nginx --port=80 --namespace dev# 查看pod相关信息
kubectl get pods -n dev -o wide# 查看pod详细信息
kubectl describe pod nginx -n dev# 删除pod
kubectl delete pod nginx -n dev
# 旧版本删完还存在,是因为后台是存在一个控制器,删除立马重启,这里需要删除控制器,就可删除干净(新版本忽略)
kubectl delete deploy nginx -n dev# yaml文件形式创建
cat pod-nginx.yamlapiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev
spec:
containers:
- image: nginx:latest
name: pod
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
[root@lv118 disk3]# kubectl create -f pod-nginx.yaml
pod/nginx created
[root@lv118 disk3]# kubectl get pods -n dev
NAMEREADYSTATUSRESTARTSAGE
nginx1/1Running09s
[root@lv118 disk3]# kubectl delete -f pod-nginx.yaml
pod "nginx" deleted
Label label的作用在于给资源添加标识,和用于区分选择,和namespace不同的是这是可以互相通信的,由于在功能上不同,所以用以标签区别
- 基于等式的标签选择器,选择所有包含Label中key="name"且value="https://www.it610.com/article/slave"的对象
- 基于集合的标签选择器 name in (master,slave):选择所有label中key="name"且value="https://www.it610.com/article/master"或"slave"的对象
# 查看pod打标签
[root@lv118 disk3]# kubectl get pod -n dev --show-labels
NAMEREADYSTATUSRESTARTSAGELABELS
nginx1/1Running03m14s# 打标签
[root@lv118 disk3]# kubectl label pod nginx -n dev version=1.0
pod/nginx labeled# 再次查看
[root@lv118 disk3]# kubectl get pod -n dev --show-labels
NAMEREADYSTATUSRESTARTSAGELABELS
nginx1/1Running03m56sversion=1.0# 修改标签
[root@lv118 disk3]# kubectl label pod nginx -n dev version=2.0 --overwrite
pod/nginx labeled# 再次查看
[root@lv118 disk3]# kubectl get pod -n dev --show-labels
NAMEREADYSTATUSRESTARTSAGELABELS
nginx1/1Running05m22sversion=2.0# 再添加一个pod,记得修改yaml文件内pod名字
# 将新pod增加版本,结果最后如下
[root@lv118 disk3]# kubectl get pod -n dev --show-labels
NAMEREADYSTATUSRESTARTSAGELABELS
nginx1/1Running07m36sversion=2.0
nginx11/1Running060sversion=1.0# 查询指定范围标签的pod
[root@lv118 disk3]# kubectl get pods -l version!=1.0-n dev --show-labels
NAMEREADYSTATUSRESTARTSAGELABELS
nginx1/1Running013mversion=2.0# 删除某个标签
[root@lv118 disk3]# kubectl label pod nginx -n dev version-# pod-nginx.yaml文件配置
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev
labels:
version: "3.0"
env: "test"
spec:
containers:
- image: nginx:latest
name: pod
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
# 更新
kubectl apply -f pod-nginx.yaml
#再次查看
[root@lv118 disk3]# kubectl get pods -n dev --show-labels
NAMEREADYSTATUSRESTARTSAGELABELS
nginx1/1Running022menv=test,version=3.0
Deployment pod虽然作为k8s中最小控制单元,但k8s却很少去直接控制,一般都是通过pod控制器来完成,pod控制器用于pod的管理,当pod故障时,会尝试重启/重建pod
# 创建Deployment
kubectl create deployment nginx --image=nginx -n dev# 删除Deployment
kubectl delete deploy nginx -n dev# deploy-nginx.yaml文件配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
run: nginx
template:
metadata:
labels:
run: nginx
spec:
containers:
- image: nginx:latest
name: nginx
ports:
- containerPort: 80
protocol: TCP
# 运行文件
kubectl create -f deploy-nginx.yaml
# 查看
kubectl get deployment,pods -n dev
Service 利用pod控制器可以很轻松让挂掉的pod重新启动,但是如果我们访问的是之前旧的podip端口,这样一重启岂不是ip都变了嘛
service可以看作是一组同类pod对外访问的接口,接助service,应用可以很方便的实现服务发现和负载均衡,同类指的是标签,serviceip是不变的
# 1、集群内部访问
# 创建service
kubectl expose deploy nginx --name=svc-nginx1 --type=ClusterIP --port=80 --target-port=80 -n dev# 查看service
[root@lv118 disk3]# kubectl get svc svc-nginx1 -n dev -o wide
NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGESELECTOR
svc-nginx1ClusterIP10.96.19.19780/TCP4mrun=nginx# 访问service的ip和端口
[root@lv118 disk3]# curl 10.96.19.197:80# 2、外部访问
[root@lv118 disk3]# kubectl expose deploy nginx --name=svc-nginx2 --type=NodePort --port=80 --target-port=80 -n dev
[root@lv118 disk3]# kubectl get svc -n dev
NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGE
svc-nginx1ClusterIP10.96.19.19780/TCP6m39s
svc-nginx2NodePort10.110.163.15680:30419/TCP13s
# 本机浏览器访问,注意端口来自上文的svc端口
master服务器地址:30419# 删除service
[root@lv118 disk3]# kubectl delete svc svc-nginx2 -n dev
service "svc-nginx2" deleted
[root@lv118 disk3]# kubectl delete svc svc-nginx1 -n dev
service "svc-nginx1" deleted# svc-nginx.yaml文件
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
namespace: dev
spec:
clusterIP: 10.109.179.231 #固定svc的内网ip
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: nginx
type: ClusterIP
# 执行文件
kubectl create -f svc-nginx.yaml
# 查看
kubectl get svc -n dev
Pod详述 pod配置项
apiVersion: v1#必选,版本号,例如v1
kind: Pod#必选,资源类型,例如 Pod
metadata:#必选,元数据
name: string#必选,Pod名称
namespace: string#Pod所属的命名空间,默认为"default"
labels:#自定义标签列表
- name: string
spec:#必选,Pod中容器的详细定义
containers:#必选,Pod中容器列表
- name: string#必选,容器名称
image: string#必选,容器的镜像名称
imagePullPolicy: [ Always|Never|IfNotPresent ]#获取镜像的策略
command: [string]#容器的启动命令列表,如不指定,使用打包时使用的启动命令
args: [string]#容器的启动命令参数列表
workingDir: string#容器的工作目录
volumeMounts:#挂载到容器内部的存储卷配置
- name: string#引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
mountPath: string #存储卷在容器内mount的绝对路径,应少于512字符
readOnly: boolean #是否为只读模式
ports: #需要暴露的端口库号列表
- name: string#端口的名称
containerPort: int#容器需要监听的端口号
hostPort: int#容器所在主机需要监听的端口号,默认与Container相同
protocol: string#端口协议,支持TCP和UDP,默认TCP
env:#容器运行前需设置的环境变量列表
- name: string#环境变量名称
value: string #环境变量的值
resources: #资源限制和请求的设置
limits:#资源限制的设置
cpu: string#Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
memory: string#内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
requests: #资源请求的设置
cpu: string#Cpu请求,容器启动的初始可用数量
memory: string #内存请求,容器启动的初始可用数量
lifecycle: #生命周期钩子
postStart: #容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启
preStop: #容器终止前执行此钩子,无论结果如何,容器都会终止
livenessProbe:#对Pod内各容器健康检查的设置,当探测无响应几次后将自动重启该容器
exec:#对Pod容器内检查方式设置为exec方式
command: [string]#exec方式需要制定的命令或脚本
httpGet:#对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
path: string
port: number
host: string
scheme: string
HttpHeaders:
- name: string
value: string
tcpSocket:#对Pod内个容器健康检查方式设置为tcpSocket方式
port: number
initialDelaySeconds: 0#容器启动完成后首次探测的时间,单位为秒
timeoutSeconds: 0#对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
periodSeconds: 0#对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
successThreshold: 0
failureThreshold: 0
securityContext:
privileged: false
restartPolicy: [Always | Never | OnFailure]#Pod的重启策略
nodeName: > #设置NodeName表示将该Pod调度到指定到名称的node节点上
nodeSelector: obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上
imagePullSecrets: #Pull镜像时使用的secret名称,以key:secretkey格式指定
- name: string
hostNetwork: false#是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
volumes:#在该pod上定义共享存储卷列表
- name: string#共享存储卷名称 (volumes类型有很多种)
emptyDir: {}#类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
hostPath: string#类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
path: string#Pod所在宿主机的目录,将被用于同期中mount的目录
secret:#类型为secret的存储卷,挂载集群与定义的secret对象到容器内部
scretname: string
items:
- key: string
path: string
configMap:#类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
name: string
items:
- key: string
path: string
推荐阅读
- docker|Kubernetes介绍
- 《阿里云入门到精通实战》|阿里云ECS服务器的基本管理与磁盘扩容(五)
- 宜搭小技巧|自动计算日期时长,3个公式帮你搞定!
- C#中的HashSet介绍与用法示例
- 设计模式|Kubernetes 为什么需要 Pod(37)
- 云原生|运维从零认识云原生
- 云原生|【4月12日活动预告】SRE与智能运维峰会
- devops|应云而生,幽灵的威胁 - 云原生应用交付与运维的思考
- 云原生|如何编写 Kubernetes 的 YAML 文件()