目录
- 一、简介
- 1.1 容器部署时代
- 1.2 Kubernetes有哪些优点
- 二、Kubernetes 组件介绍
- 三、Kubernetes 核心概念
- 3.1 Namespace
- 3.2 Pod
- 3.3 Deployment
- 3.4 Service
- 3.5 Ingress
- 四、Kubernetes 核心概念实战
- 4.1 部署yaml文件
- 4.2 通过Pod IP访问Nginx
- 4.3 通过Service IP访问Nginx
- 4.4 修改index.html 演示Service负载均衡
- 4.5 在外部通过ServiceNodePort访问Pod
- 4.5 在外部使用Ingress Host访问Pod
- 结束
一、简介
Kubernetes(这个名字源于希腊语,意为“舵手”或“飞行员”。k8s 这个缩写是因为 k 和 s 之间有八个字符的关系)。
它是一个开源的容器编排平台,解决了许多容器化应用程序在部署、管理和扩展方面面临的复杂性和挑战。最初由 Google 开发,现在由云原生计算基金会(CNCF)维护。
1.1 容器部署时代
这张图片展示了我们服务部署的三个时代:
-
传统部署时代:早期,各个组织是在物理服务器上运行应用程序。 由于无法限制在物理服务器中运行的应用程序资源使用,因此会导致资源分配问题。 例如,如果在同一台物理服务器上运行多个应用程序, 则可能会出现一个应用程序占用大部分资源的情况,而导致其他应用程序的性能下降。 一种解决方案是将每个应用程序都运行在不同的物理服务器上, 但是当某个应用程式资源利用率不高时,剩余资源无法被分配给其他应用程式, 而且维护许多物理服务器的成本很高。
-
虚拟化部署时代:因此,虚拟化技术被引入了。虚拟化技术允许你在单个物理服务器的 CPU 上运行多台虚拟机(VM)。 虚拟化能使应用程序在不同 VM 之间被彼此隔离,且能提供一定程度的安全性, 因为一个应用程序的信息不能被另一应用程序随意访问。虚拟化技术能够更好地利用物理服务器的资源,并且因为可轻松地添加或更新应用程序, 而因此可以具有更高的可扩缩性,以及降低硬件成本等等的好处。 通过虚拟化,你可以将一组物理资源呈现为可丢弃的虚拟机集群。每个 VM 是一台完整的计算机,在虚拟化硬件之上运行所有组件,包括其自己的操作系统。
-
容器部署时代:容器类似于 VM,但是更宽松的隔离特性,使容器之间可以共享操作系统(OS)。 因此,容器比起 VM 被认为是更轻量级的。且与 VM 类似,每个容器都具有自己的文件系统、CPU、内存、进程空间等。 由于它们与基础架构分离,因此可以跨云和 OS 发行版本进行移植。
容器因具有许多优势而变得流行起来,例如:
- 敏捷应用程序的创建和部署:与使用 VM 镜像相比,提高了容器镜像创建的简便性和效率。
- 持续开发、集成和部署:通过快速简单的回滚(由于镜像不可变性), 提供可靠且频繁的容器镜像构建和部署。
- 关注开发与运维的分离:在构建、发布时创建应用程序容器镜像,而不是在部署时, 从而将应用程序与基础架构分离。
- 可观察性:不仅可以显示 OS 级别的信息和指标,还可以显示应用程序的运行状况和其他指标信号。
- 跨开发、测试和生产的环境一致性:在笔记本计算机上也可以和在云中运行一样的应用程序。
- 跨云和操作系统发行版本的可移植性:可在 Ubuntu、RHEL、CoreOS、本地、 Google Kubernetes Engine 和其他任何地方运行。
- 以应用程序为中心的管理:提高抽象级别,从在虚拟硬件上运行 OS 到使用逻辑资源在 OS 上运行应用程序。
- 松散耦合、分布式、弹性、解放的微服务:应用程序被分解成较小的独立部分, 并且可以动态部署和管理 - 而不是在一台大型单机上整体运行。
- 资源隔离:可预测的应用程序性能。
- 资源利用:高效率和高密度。
1.2 Kubernetes有哪些优点
容器是打包和运行应用程序的好方式。
在生产环境中, 你需要管理运行着应用程序的容器,并确保服务不会下线。 例如,如果一个容器发生故障,则你需要启动另一个容器。 如果此行为交由给系统处理,是不是会更容易一些?这就是 Kubernetes 要来做的事情! Kubernetes 为你提供了一个可弹性运行分布式系统的框架。 Kubernetes 会满足你的扩展要求、故障转移你的应用、提供部署模式等。
-
自动化部署:Kubernetes 允许用户通过配置文件定义容器化应用程序的部署、服务、存储等资源,可以自动化部署应用程序,避免了繁琐的手动操作。
-
自动扩展:Kubernetes 可以根据应用程序的负载自动扩展容器实例数量,从而确保应用程序的高可用性和性能。用户可以根据 CPU、内存等指标自定义自动扩展的策略。
-
自我修复:Kubernetes 可以检测到容器或节点的故障,并自动重新启动或迁移容器实例,确保应用程序的高可用性和稳定性。
-
负载均衡:Kubernetes 支持多种负载均衡策略,可以将流量均衡到多个容器实例中,从而确保应用程序的高可用性和性能。
-
服务发现和 DNS:Kubernetes 可以通过 Service 和 Endpoint 对象来管理容器化应用程序的服务发现和负载均衡,同时提供了内置的 DNS 服务,使得应用程序可以方便地互相通信。
-
配置管理:Kubernetes 可以使用 ConfigMap 和 Secret 对象来管理容器化应用程序的配置信息,可以动态更新应用程序的配置,同时确保配置的安全性。
总之,Kubernetes 解决了容器化应用程序的部署、管理、扩展、自我修复、负载均衡和配置等方面的问题,使得用户可以更加轻松地构建、部署和运行云原生应用程序。
二、Kubernetes 组件介绍
上图展示了k8s集群的架构,Kubernetes 集群由多个组件组成,每个组件都有不同的职责和功能,共同协作来实现容器编排、部署、管理等任务。下面是 Kubernetes 集群的主要组件:
-
kube-apiserver:Kubernetes API 服务器,作为 Kubernetes 集群的控制面板,负责处理所有 API 请求。
-
etcd:分布式键值存储,用于存储 Kubernetes 集群的配置数据、元数据和状态信息。
-
kube-controller-manager:控制器管理器,负责监控集群状态变化,并自动进行调整和修复。
-
kube-scheduler:调度器,负责将 Pod 调度到合适的节点上运行。
-
kubelet:节点代理,负责管理节点上的容器和镜像,以及监控和报告节点状态。
-
kube-proxy:网络代理,负责为 Pod 提供网络代理和负载均衡功能。
除了上述核心组件之外,Kubernetes 还有一些其他的组件和插件,例如:
-
Ingress Controller:负责将外部流量路由到集群内部的服务。
-
DNS 插件:为 Kubernetes 集群中的服务提供 DNS 解析功能。
-
Dashboard:Web 界面,用于监控和管理 Kubernetes 集群。
-
Helm:包管理工具,用于管理 Kubernetes 应用程序的打包、发布和升级。
三、Kubernetes 核心概念
有两种方式可以创建k8s资源:
- 可以通过执行
kubectl
命令 - 执行
yaml
资源文件
3.1 Namespace
Namespace (NS):命名空间,是 Kubernetes 中的虚拟集群,用于隔离和管理不同的资源。不同命名空间中的资源是相互独立的,同一命名空间中的资源可以直接访问。
# 查看现有的全部命名空间
kubectl get ns
# 构建命名空间
kubectl create ns test
# 删除现有命名空间, 并且会删除空间下的全部资源
kubectl delete ns test
apiVersion: v1
kind: Namespace
metadata:
name: test
通过kubectl apply
或者kubectl delete
的方式部署yaml文件
kubectl apply -f yaml文件名称
kubectl delete -f yaml文件名称
3.2 Pod
Pod:是 Kubernetes 中最小的部署单元,由一个或多个容器组成。Pod 提供容器运行时的环境,同时也提供了一些共享的资源,例如网络和存储卷。
# 查看所有运行的pod
kubectl get pods -A
# 查看指定Namespace下的Pod (默认default)
kubectl get pod -n test
# 创建Pod
kubectl run my-nginx-pod --image=nginx -n test
# 查看Pod详细信息
kubectl describe pod my-nginx-pod -n test
# 删除pod
kubectl delete pod my-nginx-pod -n test
# 查看pod输出的日志
kubectl logs -f my-nginx-pod -n test
# 进去pod容器内部
kubectl exec -it my-nginx-pod -- bash
# 查看kubernetes给Pod分配的ip信息,并且通过ip和容器的端口,可以直接访问
kubectl get pod -owide -n test
apiVersion: v1
kind: Pod
metadata:
labels:
run: nginx-pod
name: nginx-pod
namespace: test
spec:
containers:
- image: nginx:latest
name: nginx
执行kubectl apply -f nginx-pod.yaml
命令进行部署。
3.3 Deployment
Deployment:是用于管理 Pod 的控制器,用于创建、更新和删除 Pod。Deployment 确保 Pod 的副本数始终处于指定状态,同时支持滚动升级和回滚操作。
用Deployment启动的容器,如果直接删除Pod则会在被删除后自动再次创建pod,只有这个Deployment被删除才能永久删除pod。
# 基于Deployment启动容器
kubectl create deployment my-nginx-deployment --image=nginx -n test
# 指定副本数为3
kubectl create deployment my-nginx-deployment --image=nginx --replicas 3 -n test
# 查看现在的deployment
kubectl get deployment -n test
# 删除deployment
kubectl delete deployment my-nginx-deployment -n test
# 基于scale实现弹性伸缩
kubectl scale deploy/my-nginx-deployment --replicas 2 -n test
#修改yaml文件
kubectl edit deploy my-nginx-deployment -n test
#更改镜像版本 Deploy可以在部署新版本数据时,成功启动一个pod,才会下线一个老版本的Pod
kubectl set image deployment/my-nginx-deployment 容器名=镜像:版本
准备yaml文件,创建镜像为nginx,端口号为80,创建三个容器副本:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: test
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
执行kubectl apply -f nginx-deploy.yaml
命令进行部署。
3.4 Service
Service:是一组 Pod 的抽象,用于提供对这组 Pod 的访问和负载均衡。Service 可以通过集群内部 IP、DNS 名称或外部 IP(NodePort 或 LoadBalancer)提供服务。
如果不指定 service type
,则创建的Service默认为ClusterIP
,这种方式只能在Pod内部实现访问。
指定type为NodePort
类型,可以实现Pod外暴露访问。
# 通过生成service映射一个Deployment下的所有pod中的某一个端口的容器 默认为ClusterIP 类型
kubectl expose deployment nginx-deployment --port=8888 --target-port=80
# NodePort类型
kubectl expose deployment nginx-deployment --port=8888 --target-port=80 --type=NodePort
kubectl get service
kubectl get svc
#以通过Deployment名称.namespace名称.svc作为域名访问,但是只能在容器内部访问
curl nginx-service.test.svc:8888
准备yaml资源文件:创建 了service,将集群的8888端口映射到容器80端口。
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-service
name: nginx-service
namespace: test
spec:
selector:
app: nginx-deployment
ports:
- port: 8888
protocol: TCP
targetPort: 80
执行kubectl apply -f nginx-service.yaml
命令进行部署。
3.5 Ingress
Ingress:是一种 Kubernetes 中的资源,用于将外部流量路由到集群内部的服务。Ingress 可以基于 URL、域名或 HTTP 头将流量路由到不同的服务中。
准备yaml文件创建Ingress,定义一个rule:host为nginx.deploy.com
, Prefix
表示去除前缀路径,转发到/ 8888端口。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
namespace: test
spec:
ingressClassName: ingress
rules:
- host: nginx.deploy.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 8888
执行kubectl apply -f nginx-ingress.yaml
命令进行部署。
四、Kubernetes 核心概念实战
接下来通过部署nginx给大家实战演示一下k8s核心概念
4.1 部署yaml文件
准备yaml资源文件:
- 创建Namespace为test
- 创建Deployment容器镜像为nginx,端口为80,副本数为2
- 创建Service将8888端口映射到容器的80端口
- 创建Ingress将nginx.deploy.com域名映射到Service
apiVersion: v1
kind: Namespace
metadata:
name: test
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: test
labels:
app: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx-deployment
template:
metadata:
labels:
app: nginx-deployment
spec:
containers:
- name: nginx-deployment
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
namespace: test
labels:
app: nginx-service
name: nginx-service
spec:
selector:
app: nginx-deployment
ports:
- port: 8888
protocol: TCP
targetPort: 80
type: NodePort
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-deployment-ingress
namespace: test
spec:
ingressClassName: ingress
rules:
- host: nginx.deploy.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 8888
使用kubectl
命令查看创建情况:
kubectl get ns -A
kubectl get deploy -n test
kubectl get pods -n test
kubectl get svc -n test
kubectl get ingress -n test
4.2 通过Pod IP访问Nginx
通过Pod IP访问Nginx:
# 查看pod ip、节点信息
kubectl get pods -n test -o wide
curl 10.244.140.79
curl 10.244.140.80
4.3 通过Service IP访问Nginx
通过Service IP访问Nginx:
kubectl get svc -n test -o wide
curl 10.107.134.62:8888
4.4 修改index.html 演示Service负载均衡
进入nginx 容器内部修改index.html,区分不同pod演示负载均衡
kubectl get pods -n test
kubectl exec -it nginx-deployment-69cfdf5bc7-25ph9 -n test -- bash
# 进入/usr/share/nginx/html/目录
cd /usr/share/nginx/html/
echo "1111" > index.html
cat index.html
#相同方法修改第二个nginx
kubectl exec -it nginx-deployment-69cfdf5bc7-82c4l -n test -- bash
echo "2222" > index.html
再次使用Service IP访问,可以看到请求是负载均衡到达pod(不过不是轮询方式)。
kubectl get svc -n test -o wide
curl 10.107.134.62:8888
在容器内部可以使用 Service 域名的方式负载均衡访问
域名规则为:ServiceName.Namespace.svc
进入pod内部
kubectl exec -it nginx-deployment-69cfdf5bc7-25ph9 -n test -- bash
curl nginx-service.test.svc:8888
4.5 在外部通过ServiceNodePort访问Pod
因为创建的Service是NodePort
类型,可以通过k8s集群任意IP+Service对外暴露的端口
访问到pod:
4.5 在外部使用Ingress Host访问Pod
在外部使用Ingress 配置的rule访问:
配置hosts文件,将nginx.deploy.com
映射为 k8s集群地址
然后再浏览器通过Ingress域名+Service的暴露端口
进行访问
结束
本次文章内容到这里就结束了
后续博主还会继续分享k8s中ConfigMap
和Secret
两个概念
请大家多多支持