前言
Kubernetes(简称K8s)是由Google开源的一个用于自动化部署、扩展和管理容器化应用程序的系统。自2014年发布以来,Kubernetes已经迅速成长为容器编排领域的标准,并在全球范围内得到了广泛的采用和认可。
Kubernetes作为现代容器编排的核心技术,其强大的功能和广泛的应用场景,使其在市场上占据了重要地位。对于希望在云计算和DevOps领域发展的专业人士来说,掌握Kubernetes无疑是提升职业竞争力的关键一步。特别是对于采用微服务架构的企业,如我们公司,Kubernetes的熟练使用更是至关重要。在未来,随着企业对云原生应用需求的不断增长,Kubernetes的应用前景将更加广阔。
一、K8S是什么?
Kubernetes,通常简称为K8s,是一个开源的平台,用于自动化部署、扩展和管理容器化应用程序。Kubernetes最初由Google开发,现在由云原生计算基金会(CNCF)维护。其主要目标是提供一个便捷、高效、可扩展的平台来管理容器化应用的生命周期。
二、k8s核心概念
-
容器:
容器是轻量级、独立的可执行包,包含运行应用所需的软件、库和配置文件。常用的容器引擎包括Docker和containerd。 -
Pod:
Pod是Kubernetes中最小的可部署单元,通常包含一个或多个容器,这些容器共享存储、网络和命名空间。 -
节点(Node):
节点是Kubernetes集群中的工作机器,可以是虚拟机或物理机,每个节点运行着一个容器运行时(如Docker)和Kubelet(负责与Kubernetes主节点通信)。 -
主节点(Master Node):
主节点管理Kubernetes集群,负责调度、管理和监控所有节点。主节点运行的主要组件包括API Server、Controller Manager和Scheduler。 -
部署(Deployment):
Deployment是用于描述应用的声明式定义,包括应用的副本数量、更新策略等。Deployment可以自动处理应用的滚动更新和回滚。 -
服务(Service):
Service定义了一组Pod的逻辑集合,并提供一个稳定的接口来访问这些Pod。Service通过标签选择器将请求路由到相应的Pod。 -
ConfigMap 和 Secret:
ConfigMap和Secret分别用于管理配置数据和敏感数据,如密码、密钥等。
三、Kubernetes的优势和劣势
Kubernetes (K8s) 虽然是一个流行的开源容器编排平台,我们也需要知道优劣方可进行技术的选型。
优势
- 自动化容器编排
Kubernetes可以自动化容器的部署、调度和管理,确保应用程序以高效和可靠的方式运行。
- 可扩展性
支持水平扩展和缩减,可以根据负载需求动态调整容器的数量,从而优化资源使用。
自我修复
Kubernetes可以自动检测和重启失败的容器,替换被杀死的容器,并仅在应用程序成功运行时才进行操作,从而提高应用的可靠性。
- 滚动更新和回滚
支持滚动更新和回滚,可以在不中断服务的情况下更新应用程序,同时确保在更新失败时能够快速回滚到稳定版本。
- 服务发现和负载均衡
内置服务发现和负载均衡,简化了服务间通信和负载分配。
- 存储编排
支持挂载本地存储、云存储和网络存储,提供持久化存储解决方案。
- 多租户隔离
通过命名空间和资源配额,可以在同一个集群中实现多租户隔离,确保资源使用的安全性和独立性。
- 广泛的生态系统
Kubernetes有一个庞大且活跃的社区,拥有丰富的插件和扩展,可以与各种云提供商和工具集成。
劣势
- 复杂性
Kubernetes的学习曲线较陡,配置和管理复杂,初学者需要投入大量时间来掌握其概念和操作。
资源消耗
运行Kubernetes本身需要消耗一定的资源,尤其是在小规模部署中,Kubernetes的开销可能显得较大。
- 管理开销
尽管Kubernetes自动化了很多任务,但其管理和维护仍需要专门的知识和技能,可能需要专职人员来管理集群。
- 调试困难
容器化应用程序的调试和监控比传统应用程序更具挑战性,尤其是在分布式系统中,故障排查可能变得更加复杂。
- 安全性挑战
Kubernetes的安全配置需要仔细考虑和实施,不当的配置可能导致安全漏洞。多租户环境中的安全隔离和权限管理需要特别注意。
版本兼容性
不同版本的Kubernetes及其组件可能存在兼容性问题,升级和维护需要小心处理,以避免破坏现有工作负载。
四、本地部署实践
使用 Docker Desktop构建 K8s
下载部分省略,我们在这里只需要开启即可。
- 检验是否安装 ,输出如下信息则表示Kubernetes已经启用并运行
➜ ~ kubectl cluster-info
Kubernetes control plane is running at https://127.0.0.1:6443
CoreDNS is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
- 检查 docker 启动的容器
也可以在命令行通过 docker ps
查看,目前来看一切正常。
验测k8s编排任务
目标:创建一个简单的Kubernetes部署和服务,用于运行一个Nginx容器
- 实操演示部署过程
# 创建测试目录
➜ k8s mkdir k8s-demo
cd k8s-demo
# 创建Nginx Deployment配置文件 nginx-deployment.yaml
➜ k8s-demo vim nginx-deployment.yaml
# 创建Nginx Service配置文件 nginx-service.yaml
➜ k8s-demo vim nginx-service.yaml
# 运行以下命令来创建部署和服务
➜ k8s-demo
kubectl apply -f nginx-deployment.yaml
kubectl apply -f nginx-service.yaml
deployment.apps/nginx-deployment created
service/nginx-service created
# 验证部署和服务
➜ k8s-demo kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 61s
# 查看服务状态
➜ k8s-demo kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13d
nginx-service LoadBalancer 10.110.142.82 localhost 80:30452/TCP 5m2s
# 访问 nginx 服务,结果符合预期
➜ k8s-demo curl localhost
- 配置文件解读
- 部署文件:nginx-deployment.yaml
目的
- 部署和管理Pod:定义Nginx应用的部署方式,包括Pod的数量、副本管理和滚动更新策略。
- 自我修复:确保在Pod故障时自动重新启动新的Pod。
- 一致性:保证在任何时候都运行指定数量的Pod副本。
主要功能
- 定义Pod模板:指定Pod的容器、镜像、端口等详细信息。
- 管理副本数:通过replicas字段定义所需的Pod副本数量。
- 滚动更新:支持无停机时间的滚动更新策略。
apiVersion: apps/v1 # API版本,apps/v1是当前Deployment的版本
kind: Deployment # 资源类型是Deployment
metadata:
name: nginx-deployment # Deployment的名称是nginx-deployment
labels:
app: nginx # 定义了标签,用于标识资源
spec:
replicas: 3 # 期望运行的Pod副本数量,这里是3个
selector:
matchLabels:
app: nginx # 标签选择器,选择带有app: nginx标签的Pod
template:
metadata:
labels:
app: nginx # Pod的标签,这里是app: nginx
spec:
containers: # 容器定义
- name: nginx # 容器名称是nginx
image: nginx:1.17.1 # 使用的Docker镜像是nginx版本1.17.1
ports:
- containerPort: 80 # 容器暴露的端口是80
该文件对应的管理界面中是如下Deployments部分:
-
nginx-service.yaml 文件
目的
- 暴露服务:将Nginx应用暴露为一个网络服务,使得外部用户或其他服务可以访问。
- 负载均衡:通过Service实现负载均衡,将请求分发到各个Pod实例。
- 服务发现:提供集群内部的服务发现功能,使得其他Pod可以通过Service名称访问Nginx应用。
主要功能
- 选择器:匹配带有特定标签的Pod,通常是由Deployment创建的Pod。
- 端口映射:定义外部访问端口和Pod内部端口之间的映射关系。
- 服务类型:定义Service的类型,如ClusterIP、NodePort、LoadBalancer等,以决定如何暴露服务。
apiVersion: v1 # API版本,表示这个Service资源使用的是v1版本的API
kind: Service # 资源类型,这里定义的是一个Service
metadata:
name: nginx-service # Service的名称,命名为nginx-service
spec:
selector:
app: nginx # 选择器,匹配具有app=nginx标签的Pod
ports:
- protocol: TCP # 使用的协议,这里是TCP
port: 80 # Service暴露的端口,外部访问时使用的端口
targetPort: 80 # 目标端口,容器内部应用监听的端口
type: LoadBalancer # Service的类型,这里使用的是LoadBalancer类型,用于负载均衡和外部访问
命名为nginx-service 对应的管理界面中是如下部分:
k8s管理页面使用
1、查看是否有无授权账户,如下表示还没有,需要创建一个新的服务账户并授予它足够的权限来访问Kubernetes Dashboard
➜ ~ kubectl -n kubernetes-dashboard get secret
NAME TYPE DATA AGE
kubernetes-dashboard-certs Opaque 0 13d
kubernetes-dashboard-csrf Opaque 1 13d
kubernetes-dashboard-key-holder Opaque 2 13d
2、手动创建账户
➜ k8s-demo kubectl -n kubernetes-dashboard get serviceaccount
NAME SECRETS AGE
admin-user 0 106s
default 0 13d
kubernetes-dashboard 0 13d
➜ k8s-demo kubectl get clusterrolebinding admin-user
NAME ROLE AGE
admin-user ClusterRole/cluster-admin 116s
➜ k8s-demo kubectl -n kubernetes-dashboard get secrets
NAME TYPE DATA AGE
kubernetes-dashboard-certs Opaque 0 13d
kubernetes-dashboard-csrf Opaque 1 13d
kubernetes-dashboard-key-holder Opaque 2 13d
服务账户在创建后没有关联到任何secrets,这可能是由于Kubernetes版本或配置的问题。在某些情况下,Kubernetes可能不会自动为服务账户创建token secret。在这种情况下,我们可以手动创建一个token secret并将其与服务账户关联。关键 2 步骤如下:
# 创建 创建一个Token Secret 文件名:admin-user-token-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: admin-user-token
namespace: kubernetes-dashboard
annotations:
kubernetes.io/service-account.name: admin-user
type: kubernetes.io/service-account-token
# 应用配置
kubectl apply -f admin-user-token-secret.yaml
# 获取 token
kubectl -n kubernetes-dashboard describe secret admin-user-token
如下所示:
最终我们查看 token :
➜ k8s-demo kubectl -n kubernetes-dashboard get secret
NAME TYPE DATA AGE
admin-user-token kubernetes.io/service-account-token 3 112s
kubernetes-dashboard-certs Opaque 0 13d
kubernetes-dashboard-csrf Opaque 1 13d
kubernetes-dashboard-key-holder Opaque 2 13d
➜ k8s-demo kubectl -n kubernetes-dashboard describe secret admin-user-token
Name: admin-user-token
Namespace: kubernetes-dashboard
Labels: <none>
Annotations: kubernetes.io/service-account.name: admin-user
kubernetes.io/service-account.uid: bc920e99-256e-47e7-a4c6-d42a7953199a
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1107 bytes
namespace: 20 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6Iklqc1BVbXlsSUlBWDFVd1V4TEJTNkJvMXdXWmJ2N1hKa3RmMjMzNjRjakEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJiYzkyMGU5OS0yNTZlLTQ3ZTctYTRjNi1kNDJhNzk1MzE5OWEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6YWRtaW4tdXNlciJ9.YszFyi-lLQspy5lKpbcLs_GDdV9vlXrwf14ZIutFZIe3Qv3JYSgSxplTxYL6uVS8HNWEEUiS-U6IyKT5pLvYoOR3U-o5bwbqmv_Rp_iQId9NTZNWC7Zv3h6L_NOaftYwHtGXK-M7MZT-47NVZHMGQe9dMCzFujIBSkYeg5iCPCoCclE-ic2LfD2OsUhlzQ2Ut-_FINcONWb87RpjM-TBb86xJzrZ2DvSZgsWdMeee7MB1rn0iAzkLHq8BiDt_i_xiVenOkc7Yc30o1-5bEVaJ9TdybfuAnuON1iJaLrSpSyzgwfLrGYm-M2AO39HHQmYF9dvRilFvGGJDnaVLRblDA
3、启动 web 管理界面
- 启动代理
➜ k8s-demo kubectl proxy
Starting to serve on 127.0.0.1:8001
-
访问 Dashboad
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/ -
输入如上 TOKEN
查看 service,其中就有我们测试的 Nginx, 可以直接访问 localhost:80 如下所示:
参考
官网:https://kubernetes.io/docs/home/
总结
本文详细介绍了Kubernetes (k8s) 的基本概念、安装与部署流程,并通过一个实际示例演示了如何进行Kubernetes编排部署。文章深入讲解了配置文件的作用,并最终通过web管理界面与配置文件相结合,帮助读者更好地理解和应用Kubernetes。