相信大家在前面的安装过程中,我们的k8s已经完成了一个超级具体的安装【是不是还是有点难度】,今天我们就在前面已经安装好的基础上来对我们K8s做一个基本操作的学习。
一、K8s介绍
Kubernetes(通常称为K8s,K8s是将8个字母“ubernete”替换为“8”的缩写)是一个以容器为中心的基础架构,可以实现在物理集群或虚拟机集群上调度和运行容器,提供容器自动部署、扩展和管理的开源平台。满足了应用程序在生产环境中的一些通用需求:应用实例副本、水平自动扩展、命名与发现、负载均衡、滚动升级、资源监控等。
Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化工作负载和服务,有助于声明式配置和自动化。它拥有庞大且快速发展的生态系统。
然后再来看看我们所需要了解到的专业术语
pod
pod可以理解为容器的外壳,它为容器做了一层抽象的封装,pod里面运行容器,pod的特点是可以将多个容器加入到同一个网络名称空间中。同一个pod可以共享储存卷。一个pod上无论是有一个容器还是有多个容器,一旦将此pod调度到某个node上运行时,这一个pod内的所有容器只能运行在同一个node上。
node
node是kubernetes集群中的工作节点,就是负责工作的。【我们在工作节点上join操作的那个】
node可以是任何形式的计算设备,能装k8s的集群代理程序,它都可以作为整个k8s集群一个成员。
当大量的pod运行在一个集群中时,怎么批量进行管理呢?想只控制一部分的pod时又该如何?如何挑选和检测这些pod?有人会想到通过名称来识别容器,但是pod是随时删除和创建的,名称也会随着pod的删除和创建而发生改变。这样我们就给一类的pod进行分组,就是在创建pod时为其附上app的key的一个键值对,这样我们进行批量操作时可以通过检查pod中是否存在app的key,来实现对多个pod的控制,这样就会有一个新的问题了,怎么实现对多个标签的管理呢?这里我们就可以通过标签选择器组件来实现。标签选择器就是一种根据标签来过滤符合条件的资源对象的机制。
etcd 保存整个集群的状态;
apiserver 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
controller manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
scheduler 负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
kubelet 负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
Container runtime 负责镜像管理以及Pod和容器的真正运行(CRI);
kube-proxy 负责为Service提供cluster内部的服务发现和负载均衡
核心组件
组件名称 | 作用 |
etcd | 保存整个集群的状态 |
apiserver | 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制 |
controller manager | 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等 |
scheduler | 负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上 |
kubelet | 负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理 |
Container runtime | 负责镜像管理以及Pod和容器的真正运行(CRI) |
kube-proxy | 负责为Service提供cluster内部的服务发现和负载均衡 |
接下来就开始今天的学习吧
二、容器编排
首先去检查我们所有组件的状态,这里要保证我们所有状态为1才可以进行操作
kubectl get pod --all-namespaces -o wide
2.1 部署应用
查看可用节点《确保位于可用状态》
kubectl get nodes
创建带有部署名称和应用程序镜像位置的部署
kubectl create deployment kubernetes-bootcamp --image=gcr.lank8s.cn/google-samples/kubernetes-bootcamp:v1 --replicas=1 创建一个名为kubernetes-bootcamp 的 deployment,运行 kubernetes-bootcamp 镜像 kubectl create deployment:创建部署 --image :指定镜像
查看刚刚的创建的部署
kubectl get deployments
去查看pods
kubectl get pods
在Kubernetes内部运行的Pod是在一个私人隔离网络上运行的,默认情况下,同一Kubernetes集群内的其他pod和服务都可以看到pod。我们可以通过
窗口A:kubectl proxy 窗口B:curl http://localhost:8001/version
来建立主机和Kubernetes集群之间的连接
2.2 了解应用
在上诉的实验中,我们创建了一个 Deployment ,k8s会添加一个Pod来对我们的应用进行管理。Deployment 具体的作用包括创建一个Pod副本集、控制Pod副本的版本、自动修复故障、提供回滚机制、调整 Pod 副本数量
同一个Pod下
共享存储
网络
容器信息
同一个pod下,可能会有多个容器,比如会有我们的jar和我们jar需要访问的数据库,在同一个节点处进行,彼此共享IP地址和主机。在Kubernetes中,不同的Pod被分配了不同的IP地址。这是因为每个Pod都被视为一个独立的实例,并且具有自己的网络标识符。当Kubernetes集群中的一个Pod创建时,它被分配了一个随机的IP地址,并且能够在整个Kubernetes集群范围内被唯一访问。每个Pod都会和他的工作节点绑定,直到终止, 如果工作节点发生故障,则会在集群中的其他可用工作节点上调度相同的 Pod。一个工作节点上存在多个pod。
当我们使用故障排查时可以通过如下命令执行
命令 | 作用 |
kubectl get | 列出资源 |
kubectl describe | 显示有关资源的详细信息 |
kubectl logs | 打印 pod 和其中容器的日志 |
kubectl exec | 在 pod 中的容器上执行命令 |
2.3 公开暴露应用
Kubernetes Pod 是转瞬即逝的。 Pod 实际上拥有 生命周期,当我们的Node挂掉之后,pod也会消亡,这个时候ReplicaSet 会自动地通过创建新的 Pod 驱动集群回到目标状态,但是我们在上面已经知道每一个pod的ip地址都不一样,当我们pod丢失或重新创建,需要一种方法自动去调整我们IP地址的变更。Service 匹配一组 Pod 是使用 标签(Label)和选择器(Selector)。
type | 作用 |
ClusterIP (默认) | 在集群的内部 IP 上公开 Service 。这种类型使得 Service 只能从集群内访问 |
NodePort | 使用 NAT 在集群中每个选定 Node 的相同端口上公开 Service 。使用: 从集群外部访问 Service。是 ClusterIP 的超集 |
LoadBalancer | 在当前云中创建一个外部负载均衡器(如果支持的话),并为 Service 分配一个固定的外部IP。是 NodePort 的超集 |
ExternalName | 通过返回带有该名称的 CNAME 记录,使用任意名称(由 spec 中的externalName指定)公开 Service。不使用代理。这种类型需要kube-dns的v1.7或更高版本 |
创建服务
kubectl get services kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080 kubectl get services #将 Deployment 对象 kubernetes-bootcamp 对应的 Pod 所提供的服务暴露出去,以便可以在 Kubernetes 集群外部访问该服务。 #将服务类型设置为 NodePort,这意味着服务将会绑定到每个节点的 IP 地址和随机端口上。这样,在集群外部可以使用任意一个节点的地址和端口来访问该服务。 #将服务的端口设置为 8080,这意味着在集群外部访问该服务时,需要使用 NodeIP:8080 的格式来指定访问的地址和端口。
访问
curl <node ip>:<port>
使用标签进行查看
kubectl describe deployment
kubectl get pods -l app=kubernetes-bootcamp kubectl get services -l app=kubernetes-bootcamp
添加标签
export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}') #执行该命令后,可以使用 echo $POD_NAME 命令查看环境变量值,得到 Pod 的名称。这样,在后续操作中就可以直接使用 POD_NAME #环境变量来指定操作的 Pod,而不需要手动输入 Pod 的名称。 kubectl label pods $POD_NAME version=v1 #给指定pod添加标签 kubectl get pods -l version=v1
删除服务
kubectl get services kubectl delete service -l app=kubernetes-bootcamp kubectl get services curl 172.20.10.4:30064 #可以看到已经连不上了 kubectl exec -ti $POD_NAME -- curl localhost:8080#我们只是关闭了外部端口,但是我们本机还是可以访问的
2.4 扩缩应用
在之前我们创建了一个 Deployment,然后通过 Service让其可以开放访问。Deployment 仅为跑这个应用程序创建了一个 Pod。当我们流量增加时,需要进行扩容来保证我们容器应用满足客户的需求。
扩展 Deployment 将创建新的 Pods,并将资源调度请求分配到有可用资源的节点上,收缩 会将 Pods 数量减少至所需的状态。Kubernetes 还支持 Pods 的自动缩放。将 Pods 数量收缩到0也是可以的,但这会终止 Deployment 上所有已经部署的 Pods,扩缩是通过改变 Deployment 中的副本数量来实现的,一旦有了多个应用实例,就可以没有宕机地滚动更新。
Deployment 扩张
kubectl get deployments kubectl get rs #当前 Kubernetes 集群中所有 ReplicaSet(缩写为 RS)的列表。ReplicaSet 是 Kubernetes 中的一种控制器,用于确保在任何时间都有一个指定数量的 Pod 副本在运行。 kubectl scale deployments/kubernetes-bootcamp --replicas=4 #更改副本数量 kubectl get deployments kubectl get pods -o wide kubectl describe deployments/kubernetes-bootcamp
打开端口
kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080 kubectl describe services/kubernetes-bootcamp
export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}') kubectl get nodes -o wide curl 172.20.10.4:$NODE_PORT
Deployment 收缩
kubectl scale deployments/kubernetes-bootcamp --replicas=2 kubectl get deployments kubectl get pods -o wide
2.4 滚动更新
用户希望应用程序始终可用,而开发人员则需要每天多次部署它们的新版本。在 Kubernetes 中,这些是通过滚动更新(Rolling Updates)完成的。 滚动更新 允许通过使用新的实例逐步更新 Pod 实例,零停机进行 Deployment 更新。新的 Pod 将在具有可用资源的节点上进行调度
滚动更新允许以下操作:
将应用程序从一个环境提升到另一个环境(通过容器镜像更新)
回滚到以前的版本
持续集成和持续交付应用程序,无需停机
kubectl get deployments kubectl get pods kubectl describe pods #建立一个v2版本的 kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2 #之前的是curl 172.20.10.4:30064注意区分,而且版本是V1 curl 172.20.10.4:30417
更新
kubectl rollout status deployments/kubernetes-bootcamp kubectl describe pods | grep image
版本回退
kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=gcr.lank8s.cn/google-samples/kubernetes-bootcamp:v10 kubectl get deployments kubectl get pods kubectl describe pods
kubectl rollout undo deployments/kubernetes-bootcamp kubectl get pods kubectl describe pods | grep images
三、Kubernetes 对象
apiVersion
创建该对象所使用的 Kubernetes API 的版本
kind
想要创建的对象的类别
metadata
帮助唯一标识对象的一些数据
spec
你所期望的该对象的状态
Pod
最小的可部署单元,代表一个或多个主进程运行的容器实例
Service
为一组 Pod 提供稳定的网络访问端点,可以根据选择器匹配到特定的 Pod
Deployment
管理 ReplicaSet 的更新,使其从旧版本无缝地滚动升级到新版本,确保应用程序的高可用性和零停机时间
ReplicaSet
确保总有指定数量的 Pod 实例在运行中,如果遇到故障则自动替换
Secret
存储敏感数据(如密码、证书)的对象,与 ConfigMap 类似也可以在 Pod 中使用环境变量或卷的形式挂载到容器中
Namespace
虚拟集群的一种抽象,用于将资源隔离和分组,让不同的团队可以共享同一个 Kubernetes 环境