Kubernetes,也被称为 K8s 或 Kube,是谷歌推出的业界最受欢迎的容器管理/运维工具(容器编排器)。它是一套自动化容器管理/运维的开源平台,包括部署、调度和节点集群的扩展等。
Kubernetes 的详细介绍,请参考 “系统架构与设计(6)- Kubernetes(K8s)“。
Kubernetes: https://kubernetes.io/
Kubernetes GitHub: https://github.com/kubernetes
本文在已搭建的 Kubernetes 集群上部署一个 Nginx 服务,如何部署一个 Kubernetes 集群可以参考 “Docker基础知识 (19) – Kubernetes(二) | 搭建单个 Master 集群(一主一从)”。
1. 部署环境
虚拟机: Virtual Box 6.1.30(Windows 版)
操作系统: Linux CentOS 7.9 64位
Docker 版本:20.10.7
Docker Compose 版本:2.6.1
Kubernetes 版本:1.23.0
工作目录:/home/k8s
1) 主机列表
主机名 IP 角色 操作系统
k8s-master 192.168.0.10 master CentOS 7.9
k8s-node01 192.168.0.11 node CentOS 7.9
2) 部署和调度
部署的工作都是在 master (192.168.0.10) 主机上进行,K8s 会自动调度到 node 节点。
默认情况下,master 节点不参与调度,且在 master 节点上有一个污点 NoSchedule(表示K8s 将不会将 Pod 调度到具有该污点的 Node 上),即如果没有 node 节点处于工作状态时,新部署的 Pod 将一直处于 Pending 状态。
让 master 节点参与调度的步骤:
# 查看 node
$ kubectl get nodes
# 查看污点
$ kubectl describe node k8s-master | grep Taints
Taints: node-role.kubernetes.io/master:NoSchedule
# 删除污点
$ kubectl taint nodes –all node-role.kubernetes.io/master-
# 让 master 节点参与调度。如果想删除,把 = 换成 –
$ kubectl label nodes k8s-master node-role.kubernetes.io/worker=
2. 创建命名空间 (namespace)
1) 命名空间 (namespace)
Kubernetes 支持多个虚拟集群,它们底层依赖于同一个物理集群,这些虚拟集群被称为命名空间。
命名空间 (namespace) 是 k8s 集群级别的资源,可以给不同的用户、租户、环境或项目创建对应的命名空间。
命名空间适用于存在很多跨多个团队或项目的用户的场景,对于只有少数项目人员的集群则不需要使用 namespace。
在创建 pod 时可以指定 pod 到 namespace,如果没有指定 namespace,则会默认使用 default 这个 namespace。
2) 创建 namespace.yaml 文件
$ cd /home/k8s/nginx-test # 手动创建 nginx-test 目录
$ vim namespace.yaml
apiVersion: v1 kind: Namespace metadata: name: nginx-test labels: name: nginx-test
配置说明:
kind:Namespace 表示该 yaml 文件要创建命名空间;
metadata: 表示命名空间的元信息;
metadata.name: 是命名空间的名称;
metadata.labels: 是命名空间的标签;
3) 执行创建命令
$ kubectl apply -f namespace.yaml
namespace/nginx-test created
# 查看命名空间列表
$ kubectl get namespaces
NAME STATUS AGE default Active 3h5m kube-node-lease Active 3h5m kube-public Active 3h5m kube-system Active 3h5m nginx-test Active 23s
# 查看命名空间详情
$ kubectl describe namespace nginx-test
Name: nginx-test Labels: kubernetes.io/metadata.name=nginx-test name=nginx-test Annotations: <none> Status: Active No resource quota. No LimitRange resource.
3. 创建 Deployment
1) Deployment 简介
Deployment 是一个定义及管理多副本应用(即多个副本 Pod)的新一代对象,与 Replication Controller 相比,它提供了更加完善的功能,使用起来更加简单方便。
在 k8s 中 Deployment 对象管理 Pod 对象的方法,被叫作 “控制器” 模式(controller pattern),Deployment 扮演的是 Pod 的 “控制器” 角色。
Deployment 通过管理 ReplicaSet 来间接管理 Pod,即:Deployment 管理 ReplicaSet,ReplicaSet 管理 Pod。所以 Deployment 比 ReplicaSet 的功能更强大。
如果 Pod 出现故障,对应的服务也会挂掉,所以 Kubernetes 提供了一个 Deployment 的概念 ,目的是让 Kubernetes 去管理一组 Pod 的副本,也就是副本集,这样就能够保证一定数量的副本一直可用,不会因为某一个 Pod 挂掉导致整个服务挂掉。
Deployment 还负责在 Pod 定义发生变化时,对每个副本进行滚动更新(Rolling Update)。
2) 创建 nginx.conf 文件
$ cd /home/k8s/nginx-test/nginx/conf.d # 手动创建 nginx/conf.d 各级子目录
$ vim nginx.conf
server { listen 80 default_server; server_name localhost; location / { root /usr/share/nginx/html; index index.php index.html index.htm; autoindex off; } }
3) 创建 test.html 文件
$ cd /home/k8s/nginx-test/nginx/html # 手动创建 nginx/html 各级子目录
$ vim test.html
<p>K8s Nginx – HTML page</p>
4) 创建 nginx-deployment.yaml 文件
$ cd /home/k8s/nginx-test
$ vim nginx-deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment namespace: nginx-test spec: replicas: 1 selector: matchLabels: app: nginx-pod template: metadata: labels: app: nginx-pod spec: containers: - name: nginx-1-21 image: nginx:1.21 ports: - containerPort: 80 volumeMounts: - name: conf mountPath: /etc/nginx/conf.d - name: log mountPath: /var/log/nginx - name: html mountPath: /usr/share/nginx/html volumes: - name: conf hostPath: path: /home/k8s/nginx-test/nginx/conf.d type: Directory - name: log hostPath: path: /home/k8s/nginx-test/nginx/log type: Directory - name: html hostPath: path: /home/k8s/nginx-test/nginx/html type: Directory
配置说明:
kind: Deployment 表示该 yaml 文件要创建 Deployment 发布;
metadata: 表示这个 deployment 的元信息;
metadata.name: 是 deployment 的名称 nginx-deployment;
metadata.labels: 是 deployment 的标签;
metadata.namespace: 是 deployment 所在的命名空间;
spec: 表示 deployment 的详细参数配置说明;
spec.replicas: 是启动几个 pod 节点(副本);
spec.template.spec: 是 deployment 选择模块的详细说明;
spec.template.spec.containers:表示容器,此处是 nginx 的 docker 镜像,容器的端口设置 containerPort: 80, volumeMounts 表示绑定的文件和目录;
spec.template.spec.volumes:表示选择的容器挂载的宿主机的文件和目录 conf, logs 和 html;
# 执行创建命令
$ kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deployment created
# 查询 pods
$ kubectl get pods -n nginx-test -o wide
NAME READY STATUS ... AGE IP NODE nginx-deployment-56786d8495-rxr9c 1/1 Running 3m32s 10.244.0.10 k8s-master
# 集群内访问 nginx(Pod 的虚拟 IP,外部无法访问)
$ curl http://10.244.0.10/test.html
<p>K8s Nginx – HTML page</p>
5) 操作 Deployment
# 查询命名空间 nginx-test 下的 deployment
$ kubectl get deploy -n nginx-test
NAME READY UP-TO-DATE AVAILABLE AGE nginx-deployment 1/1 1 1 144m
# 查询 deployment 详情
$ kubectl describe deploy nginx-deployment -n nginx-test
Name: nginx-deployment Namespace: nginx-test CreationTimestamp: Wed, 16 Nov 2022 17:44:39 -0500 Labels: <none> Annotations: deployment.kubernetes.io/revision: 1 Selector: app=nginx-pod Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable ...
# 动态修改 deployment 的副本数量
$ kubectl scale deploy nginx-deployment –replicas=2 -n nginx-test
deployment.apps/nginx-deployment scaled
# 重启 deployment
$ kubectl rollout restart deploy nginx-deployment -n nginx-test
deployment.apps/nginx-deployment restarted
# 删除一个 deployment
$ kubectl delete deploy nginx-deployment -n nginx-test
6) 操作 ReplicaSet
# 查询命名空间 nginx-test 下的 ReplicaSet
$ kubectl get rs -n nginx-test
NAME DESIRED CURRENT READY AGE nginx-deployment-fc98c7b77 2 2 0 34m
7) 操作 Pod
# 查询命名空间 nginx-test 下的 pod
$ kubectl get pods -n nginx-test
NAME READY STATUS RESTARTS AGE nginx-deployment-6487bc588b-nnpw8 1/1 Running 0 5m10s nginx-deployment-6487bc588b-sfxh9 1/1 Running 0 5m12s
# 查询 pod 详情
$ kubectl describe pod nginx-deployment-6487bc588b-nnpw8 -n nginx-test
Name: nginx-deployment-6487bc588b-nnpw8 Namespace: nginx-test Priority: 0 Node: k8s-master/192.168.0.10 Start Time: Wed, 16 Nov 2022 20:14:42 -0500 Labels: app=nginx-pod pod-template-hash=6487bc588b ...
# 删除 pod
$ kubectl delete pod nginx-deployment-6487bc588b-nnpw8 -n nginx-test
# 强制删除 pod
$ kubectl delete pod nginx-deployment-6487bc588b-nnpw8 -n nginx-test –force –grace-period=0
4. 创建 Service
上文 Deployment 创建的一组 Pod 提供具有高可用性的 Nginx 服务。
虽然每个 Pod 都会分配一个单独的 Pod 虚拟 IP,但有如下两个问题:
(1) Pod 虚拟 IP 会随着 Pod 的重建产生变化;
(2) Pod 虚拟 IP 仅仅是集群内可见,外部无法访问;
kubernetes 设计了 Service 来解决以上问题,Service 可以看作是一组同类 Pod 对外的访问接口,基于 Service,应用可以方便地实现服务发现和负载均衡。
1) 创建 nginx-service.yaml 文件
$ cd /home/k8s/nginx-test
$ vim nginx-service.yaml
apiVersion: v1 kind: Service metadata: labels: app: nginx-pod name: nginx-service namespace: nginx-test spec: ports: - port: 9080 name: nginx-service-80 protocol: TCP targetPort: 80 nodePort: 30080 selector: app: nginx-pod type: NodePort
配置说明:
kind: Service 表示 yaml 文件创建的是一个 Service;
metadata: 表示这个 Service 的元信息;
metadata.name: 是 Service 的名称 nginx-service;
metadata.labels: 是 Service 的标签;
metadata.namespace: 是 Service 的命名空间,此处选择的是第一步创建的命名空间 nginx;
sepc: 是 Service 的详细配置说明;
sepc.type: NodePort 表示外部可以访问,ClusterIP 表示集群内访问;
sepc.selector: 表示这个 Service 是将带标签的哪些 pods 做为一个集合对外通过服务;
sepc.ports.port: 是 Service 绑定端口 9080 ;
sepc.ports.name: nginx-service-80 表示 Service 服务的名称;
sepc.ports.protocol: TCP 表示 Service 转发请求到容器的协议是 TCP,我们部署的 http 的 nginx 服务,因此选择协议为TCP;
sepc.ports.targetPort: 80 表示 Service 转发外部请求到容器的目标端口 80,即 deployment 的 pod 容器对外开放的容器端口 80;
sepc.ports.nodePort: 30080 表示 Service 对外开放的节点端口;
# 执行创建 Service 命令
$ kubectl apply -f nginx-service.yaml
# 查询服务列表
$ kubectl get services -n nginx-test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-service NodePort 10.104.204.25 <none> 9080:30080/TCP 16s
浏览器外部访问 http://192.168.0.10:30080/test.html,显示结果如下:
K8s Nginx – HTML page
2) 操作 Service
# 查询 Service 详情
$ kubectl describe service nginx-service -n nginx-test
Name: nginx-service Namespace: nginx-test Labels: app=nginx-pod Annotations: <none> Selector: app=nginx-pod Type: NodePort IP Family Policy: SingleStack IP Families: IPv4 IP: 10.104.204.25 IPs: 10.104.204.25 Port: nginx-service-80 9080/TCP TargetPort: 80/TCP NodePort: nginx-service-80 30080/TCP Endpoints: 10.244.0.12:80,10.244.0.13:80 Session Affinity: None External Traffic Policy: Cluster Events: <none>
# 删除 service 服务
$ kubectl delete services nginx-service -n nginx-test
service “nginx-service” deleted
原文地址:http://www.cnblogs.com/tkuang/p/16901140.html