三、vim使用手册--找到 tag:1/3 或更多

本文介绍如何在Vim编辑器中利用ctags插件及其命令(如ts、tn、tp、tfirst和tlast)快速定位并跳转到函数或变量的定义位置,提高代码阅读和编辑效率。

我们在vim中加载了ctag+taglist+winmanager后

我们在关联一个函数或者一个变量定义的时候,经常有多处地方定义了相同名字,需要定位正确的定义地方。

:ts 或 tselect 查看有相同地方的定义

:tn或tnext   查找下一个定义地方。

:tp   查找上一个地方。

:tfirst  到第一个匹配

:tlast 到最后一个匹配

## 物联网管理系统从 Docker Compose 迁移到 Kubernetes 实验指导手册(CentOS 7.9) 本实验以“物联网管理系统”为例,完成从 Docker Compose 部署到 Kubernetes 集群部署的完整实践。 所有操作均在 CentOS 7.9 虚拟机中完成,推荐使用 3 台虚拟机:1 个 master,2 个 node。 > 已提供文档参考: > > - `3、基于docker的物联网管理系统部署-具体实现方法.md`:说明 Dockerfile 与 `docker-compose.yml` 配置 > - `K8S安装部署.md`:说明 Kubernetes 集群的安装与初始化 > 本手册在此基础上,串联一个完整、可落地的实验流程。 --- ### 一、实验环境准备 #### 1. 虚拟机规划 - 操作系统:`CentOS 7.9` - 节点规划(示例,可根据实际修改 IP): - `master`:4GB 内存,2 vCPU,IP:`172.16.32.10` - `node1`:2GB 内存,2 vCPU,IP:`172.16.32.2` - `node2`:2GB 内存,2 vCPU,IP:`172.16.32.6` > 内存充足时,建议台都配置为 4GB,整体体验更流畅。 #### 2. 基本网络与主机名配置(所有节点) 1. 设置各节点主机名(在各自节点执行): ```bash hostnamectl set-hostname master # 在 master 节点 hostnamectl set-hostname node1 # 在 node1 节点 hostnamectl set-hostname node2 # 在 node2 节点 ``` 2. 配置 `/etc/hosts`(所有节点执行): ```bash vim /etc/hosts 172.16.32.2 node1 172.16.32.6 node2 172.16.32.10 master ``` 3. 确保台机器之间可以互相 `ping` 通,例如: ```bash ping master ping node1 ping node2 ``` --- ### 二、在单机上通过 Docker Compose 部署物联网系统 本阶段目标:在 **任意一台虚拟机上(建议先在 master 上)**,基于已有的 Dockerfile 和 `docker-compose.yml`,将物联网管理系统完整跑起来,并通过浏览器访问。 #### 1. 安装 Docker(仅单机部署用,可与后续 K8S 共用) 如果已经按照 `K8S安装部署.md` 安装过 Docker,可跳过此步骤。 1. 安装 Docker CE 及依赖(以 `master` 节点为例): ```bash yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum install -y docker-ce-20.10.24 docker-ce-cli-20.10.24 containerd.io ``` 2. 启动并设置开机自启: ```bash systemctl enable docker systemctl start docker ``` 3. 验证 Docker 是否可用: ```bash docker version docker info ``` 确保命令无报错。 #### 2. 准备项目目录结构与配置文件 参考 `3、基于docker的物联网管理系统部署-具体实现方法.md`,在部署节点上准备如下目录结构(示例): ```bash mkdir -p /opt/iot-project/{backend,frontend,database} cd /opt/iot-project ``` 1. 将后端 JAR 文件复制到 `backend` 目录: ```bash cp /path/to/iot-1.0.0.jar /opt/iot-project/backend/ ``` 2. 在 `backend` 目录下创建 `Dockerfile`(内容参考原文档): ```bash cd /opt/iot-project/backend vim Dockerfile ``` 填入以下内容: ```dockerfile FROM openjdk:11-jre-slim WORKDIR /app COPY iot-1.0.0.jar . EXPOSE 8080 CMD ["java", "-jar", "iot-1.0.0.jar", "--spring.profiles.active=prod"] ``` 3. 在 `database` 目录下准备 `iot.sql` 和 `Dockerfile`: ```bash cd /opt/iot-project/database cp /path/to/iot.sql . vim Dockerfile ``` 填入以下内容(可根据原文档修改密码和库名,但要统一): ```dockerfile FROM mysql:5.7 COPY iot.sql /docker-entrypoint-initdb.d/ ENV MYSQL_ROOT_PASSWORD=Qinyu456 ENV MYSQL_DATABASE=iot ENV MYSQL_USER=qinyu ENV MYSQL_PASSWORD=Qinyu456 ``` 4. 在 `frontend` 目录下准备前端构建结果与 Nginx 配置: - 前端构建(在前端工程根目录): ```bash cd /path/to/iot-frontend-project npm install npm run build ``` 构建完成后,将 `dist` 目录拷贝到 `/opt/iot-project/frontend`: ```bash mkdir -p /opt/iot-project/frontend cp -r dist /opt/iot-project/frontend/ ``` - 创建 `nginx.conf`: ```bash cd /opt/iot-project/frontend vim nginx.conf ``` 填入内容(注意把后端 IP 换成你自己的): ```nginx server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; } location /api { proxy_pass http://192.168.136.146:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location ~* \.(js|css)$ { root /usr/share/nginx/html; expires 30d; add_header Cache-Control "public, no-transform"; } } ``` - 创建 `Dockerfile`: ```bash vim Dockerfile ``` 填入: ```dockerfile FROM nginx:alpine COPY dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf RUN chmod -R 755 /usr/share/nginx/html ``` #### 3. 准备 `docker-compose.yml` 并启动服务 1. 在项目根目录创建 `docker-compose.yml`: ```bash cd /opt/iot-project vim docker-compose.yml ``` 填入(可直接参考原文档内容,根据自己 IP、密码修改): ```yaml services: backend: build: ./backend container_name: iot-backend ports: - "8080:8080" environment: - SPRING_DATASOURCE_URL=jdbc:mysql://192.168.136.146:3306/iot - SPRING_DATASOURCE_USERNAME=qinyu - SPRING_DATASOURCE_PASSWORD=Qinyu456 networks: - iot-net depends_on: database: condition: service_healthy frontend: build: ./frontend container_name: iot-frontend ports: - "80:80" networks: - iot-net depends_on: - backend database: build: ./database container_name: iot-database user: root ports: - "3306:3306" volumes: - db-data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: Qinyu456 MYSQL_DATABASE: iot MYSQL_USER: qinyu MYSQL_PASSWORD: Qinyu456 healthcheck: test: ["CMD-SHELL", "mysqladmin ping -u root -p$$MYSQL_ROOT_PASSWORD"] interval: 10s timeout: 5s retries: 10 networks: - iot-net networks: iot-net: driver: bridge volumes: db-data: ``` 2. 启动并验证: ```bash docker compose up -d --build docker compose ps ``` 3. 数据库验证: ```bash docker exec -it iot-database mysql -u root -p ``` 4. 浏览器访问验证(在宿主机其他机器浏览器中): - 地址示例:`http://<部署节点IP>/iot-manage-front/`(按前端路径配置为准) 若能正常访问并登录,即完成 Docker Compose 部署。 --- ### 、在多节点上安装 Kubernetes 集群 本阶段完全参考 `K8S安装部署.md`,这里只给出关键步骤串联,便于实验操作。 > 注意:请在 **台虚拟机(master、node1、node2)** 上都完成“准备工作”和“安装组件”等步骤。 #### 1. 关闭 SELinux、防火墙和 swap(所有节点) ```bash setenforce 0 sed -i --follow-symlinks &#39;s/SELINUX=enforcing/SELINUX=disabled/g&#39; /etc/sysconfig/selinux systemctl stop firewalld systemctl disable firewalld swapoff -a vim /etc/fstab # 注释掉 swap 相关行,重启后永久生效 ``` #### 2. 配置安装源(所有节点) ```bash cat <<EOF > kubernetes.repo [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 mv kubernetes.repo /etc/yum.repos.d/ yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo ``` #### 3. 安装 Docker、kubelet、kubeadm、kubectl(所有节点) ```bash yum install -y kubelet-1.22.4 kubectl-1.22.4 kubeadm-1.22.4 yum install -y docker-ce-20.10.24 docker-ce-cli-20.10.24 containerd.io ``` > 版本建议统一为文档中的 1.22.4 与 20.10.24,避免教程不兼容。 #### 4. 启动 Docker 与 kubelet(所有节点) ```bash systemctl enable kubelet systemctl start kubelet systemctl enable docker systemctl start docker ``` #### 5. 修改 Docker cgroupdriver(所有节点) ```bash cat <<EOF > daemon.json { "exec-opts": ["native.cgroupdriver=systemd"], "registry-mirrors" : ["https://docker.registry.cyou", "https://docker-cf.registry.cyou", "https://dockercf.jsdelivr.fyi", "https://docker.jsdelivr.fyi", "https://dockertest.jsdelivr.fyi", "https://mirror.aliyuncs.com", "https://dockerproxy.com", "https://mirror.baidubce.com", "https://docker.m.daocloud.io", "https://docker.nju.edu.cn", "https://docker.mirrors.sjtug.sjtu.edu.cn", "https://docker.mirrors.ustc.edu.cn", "https://mirror.iscas.ac.cn", "https://docker.rainbond.cc", "https://do.nark.eu.org", "https://dc.j8.work", "https://dockerproxy.com", "https://gst6rzl9.mirror.aliyuncs.com", "https://registry.docker-cn.com", "http://hub-mirror.c.163.com", "http://mirrors.ustc.edu.cn/", "https://mirrors.tuna.tsinghua.edu.cn/", "https://ud6340vz.mirror.aliyuncs.com", "http://mirrors.sohu.com/" ], "insecure-registries" : [ "registry.docker-cn.com", "docker.mirrors.ustc.edu.cn" ], "debug": true, "experimental": false } EOF mv daemon.json /etc/docker/ systemctl daemon-reload systemctl restart docker ``` #### 6. 初始化 Kubernetes 集群(仅 master 节点) ```bash kubeadm init --image-repository=registry.aliyuncs.com/google_containers ``` 初始化成功后,终端会输出类似: ```text kubeadm join 172.16.32.10:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash> ``` 请复制并保存这条 `kubeadm join` 命令,供后面 node 加入集群使用。 为当前用户配置 `kubectl` 访问权限: ```bash mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config ``` #### 7. 工作节点加入集群(在 node1、node2 节点执行) 在每个工作节点上执行 master 输出的 `kubeadm join` 命令: ```bash kubeadm join 172.16.32.10:6443 --token xxx --discovery-token-ca-cert-hash sha256:xxx ``` #### 8. 安装网络插件(在 master 节点) 任选其一安装(网络受限时可用国内镜像提前下载 yaml): ```bash kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml # kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml # kubectl apply -f http://static.corecore.cn/weave.v2.8.1.yaml ``` 等待网络插件 Pod 变为 `Running`: ```bash kubectl get pods -n kube-system ``` #### 9. 集群状态验证(在 master) ```bash kubectl get nodes ``` 若所有节点状态为 `Ready`,说明集群安装成功。此时建议为台虚拟机打快照,便于后续回滚。 --- ### 四、将物联网管理系统从 Docker Compose 迁移到 Kubernetes 本阶段目标:将已在 Docker Compose 中运行的后端、数据库、前端服务,迁移为 Kubernetes 的 Deployment + Service 模式。 迁移整体思路: 1. 利用原有 Dockerfile 构建镜像,并推送到所有节点可访问的镜像仓库(在每台节点本地构建同名镜像)。 2. 把 `docker-compose.yml` 中每个 service 的配置拆分为: - `Deployment`/`StatefulSet`:描述 Pod 副本与容器配置 - `Service`:描述集群内访问方式(ClusterIP / NodePort) 3. 使用 `kubectl apply -f` 将对应 yaml 部署到集群中。 #### 1. 准备镜像(以在 master 节点构建并本地使用为例) > 简化做法:在 **master 节点** 上使用与 Docker Compose 相同的目录与 Dockerfile 构建镜像,所有 Pod 在 master 节点拉取本地镜像即可。若需要多节点调度,可搭一个私有仓库使用公共仓库。 1. 复制之前的项目目录到 master 节点(若之前就在 master 做 Compose,则可复用): ```bash cd /opt/iot-project ``` 2. 构建镜像(注意镜像名称): ```bash docker build -t iot-backend:1.0 ./backend docker build -t iot-frontend:1.0 ./frontend docker build -t iot-database:1.0 ./database ``` 3. 确认镜像构建完成: ```bash docker images | grep iot- ``` 如果打算让 node 节点也能运行 Pod,可以选择: - 在每个节点重复构建一次; - 将镜像推送到所有节点都能访问的私有仓库 / 公共仓库。 #### 2. 编写 Kubernetes yaml 清单 在 master 节点创建一个专门目录,用于存放 k8s 部署文件: ```bash mkdir -p /opt/iot-k8s cd /opt/iot-k8s ``` ##### 2.1 数据库 Deployment + Service 创建 `iot-database-deploy.yaml`: ```bash vim iot-database-deploy.yaml ``` 写入示例内容: ```yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: iot-mysql-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi --- apiVersion: apps/v1 kind: Deployment metadata: name: iot-database spec: replicas: 1 selector: matchLabels: app: iot-database template: metadata: labels: app: iot-database spec: containers: - name: mysql image: iot-database:1.0 imagePullPolicy: IfNotPresent ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD value: "Qinyu456" - name: MYSQL_DATABASE value: "iot" - name: MYSQL_USER value: "qinyu" - name: MYSQL_PASSWORD value: "Qinyu456" volumeMounts: - mountPath: /var/lib/mysql name: mysql-data volumes: - name: mysql-data persistentVolumeClaim: claimName: iot-mysql-pvc --- apiVersion: v1 kind: Service metadata: name: iot-database-svc spec: type: ClusterIP selector: app: iot-database ports: - port: 3306 targetPort: 3306 ``` > 说明: > > - 使用 `PersistentVolumeClaim` 简化卷配置,具体 PV 配置可根据集群存储方案调整。 > - Service 名称 `iot-database-svc` 会作为集群内访问地址的一部分。 ##### 2.2 后端 Deployment + Service 创建 `iot-backend-deploy.yaml`: ```bash vim iot-backend-deploy.yaml ``` 写入示例内容: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: iot-backend spec: replicas: 1 selector: matchLabels: app: iot-backend template: metadata: labels: app: iot-backend spec: containers: - name: backend image: iot-backend:1.0 imagePullPolicy: IfNotPresent ports: - containerPort: 8080 env: - name: SPRING_DATASOURCE_URL value: "jdbc:mysql://iot-database-svc:3306/iot" - name: SPRING_DATASOURCE_USERNAME value: "qinyu" - name: SPRING_DATASOURCE_PASSWORD value: "Qinyu456" readinessProbe: httpGet: path: /actuator/health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 livenessProbe: httpGet: path: /actuator/health port: 8080 initialDelaySeconds: 60 periodSeconds: 20 --- apiVersion: v1 kind: Service metadata: name: iot-backend-svc spec: type: ClusterIP selector: app: iot-backend ports: - port: 8080 targetPort: 8080 ``` > 注意: > > - 若项目没有启用 `/actuator/health` 端点,可暂时删除 `readinessProbe` 和 `livenessProbe`,换成实际存在的健康检查路径。 > - 数据库连接地址改为 `iot-database-svc`,体现 K8S 集群内通过 Service 名访问。 ##### 2.3 前端 Deployment + Service(NodePort 暴露) 创建 `iot-frontend-deploy.yaml`: ```bash vim iot-frontend-deploy.yaml ``` 写入示例内容: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: iot-frontend spec: replicas: 1 selector: matchLabels: app: iot-frontend template: metadata: labels: app: iot-frontend spec: containers: - name: frontend image: iot-frontend:1.0 imagePullPolicy: IfNotPresent ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: iot-frontend-svc spec: type: NodePort selector: app: iot-frontend ports: - port: 80 targetPort: 80 nodePort: 30080 ``` > 说明: > > - `type: NodePort` 将前端服务暴露为集群外可访问。 > - 这里固定 `nodePort: 30080`,访问地址为:`http://任意节点IP:30080/`。 > - Nginx 内部转发后端时,`proxy_pass` 地址建议改为 `http://iot-backend-svc:8080`,即通过 Service 名访问后端。 ##### 2.4 调整前端 Nginx 配置以适配 K8S 在构建 `iot-frontend` 镜像前,建议将 `nginx.conf` 中的后端地址修改为 K8S Service 名: ```nginx location /api { proxy_pass http://iot-backend-svc:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } ``` 若已经构建完镜像,可重新修改 `nginx.conf` 并重新 `docker build -t iot-frontend:1.0 ./frontend`。 --- ### 五、在 Kubernetes 中部署并验证物联网系统 #### 1. 部署所有组件(在 master 节点) 进入存放 yaml 的目录: ```bash cd /opt/iot-k8s ``` 按顺序执行: ```bash kubectl apply -f iot-database-deploy.yaml kubectl apply -f iot-backend-deploy.yaml kubectl apply -f iot-frontend-deploy.yaml ``` #### 2. 查看资源状态 1. 查看 Pod 状态: ```bash kubectl get pods ``` 确认个 Deployment 对应的 Pod 状态均为 `Running`。 2. 查看 Service: ```bash kubectl get svc ``` 确认有如下 Service(名称以实际为准): - `iot-database-svc`(ClusterIP) - `iot-backend-svc`(ClusterIP) - `iot-frontend-svc`(NodePort,端口 30080) #### 3. 数据库初始化验证 进入数据库 Pod: ```bash kubectl exec -it $(kubectl get pod -l app=iot-database -o jsonpath=&#39;{.items[0].metadata.name}&#39;) -- mysql -u root -p ``` 输入密码 `Qinyu456` 后,执行: ```sql SHOW DATABASES; USE iot; SHOW TABLES; ``` 若能看到对应的业务表,说明 `iot.sql` 已正确执行。 #### 4. 后端访问验证(集群内部) 在 master 节点测试后端 Service 是否可访问: ```bash curl http://iot-backend-svc:8080/actuator/health ``` 访问某个实际业务接口: ```bash curl http://iot-backend-svc:8080/api/... ``` 若返回 JSON 业务数据,说明后端服务正常。 #### 5. 前端访问验证(集群外) 在浏览器中访问: ```text http://<任意节点IP>:30080/ ``` 例如:`http://172.16.32.10:30080/` 在前端页面中进行登录、设备查看等操作,观察是否能正常调用后端 API。若前端页面有报错,可在浏览器按 `F12` 打开开发者工具,查看 Network 中接口返回情况。 --- ### 六、常见问题与排错建议 1. **Pod 一直处于 ImagePullBackOff** - 检查镜像名称与 tag 是否正确,例如 `iot-backend:1.0`。 - 确认该镜像是否存在于运行 Pod 的节点上:`docker images | grep iot-`。 - 如使用私有仓库,需在集群中配置 imagePullSecrets。 2. **后端无法连接数据库** - 确认 `SPRING_DATASOURCE_URL` 是否写为 `jdbc:mysql://iot-database-svc:3306/iot`; - 使用 Pod 内部命令测试: ```bash kubectl exec -it <backend-pod-name> -- sh ping iot-database-svc ``` - 检查数据库 Service 与 Pod 状态。 3. **前端页面访问后端失败(CORS 502 等)** - 查看 Nginx 日志(进入前端 Pod): ```bash kubectl exec -it <frontend-pod-name> -- sh tail -f /var/log/nginx/error.log ``` - 确认 `nginx.conf` 中 `proxy_pass` 地址是否为 `http://iot-backend-svc:8080`。 4. **K8S 集群中 Service 无法通过名字访问** - 通常与网络插件未正确安装未处于 Running 状态有关; - 检查: ```bash kubectl get pods -n kube-system ``` - 确保 flannel / weave 等 CNI 插件状态正常。 5. **端口无法从外部访问** - 确认 Service 类型为 `NodePort` 且 `nodePort` 配置正确; - 确认宿主机防火墙已关闭放行对应端口(前文已统一关闭 firewalld)。 --- ### 七、实验总结与扩展思考 通过本实验,你应当掌握: - 如何基于 Dockerfile 与 Docker Compose 将一个多服务物联网系统部署在单机上; - 如何在多节点 CentOS 7.9 上安装并初始化一个可用的 Kubernetes 集群; - 如何将原有 `docker-compose.yml` 中的服务拆解为 Kubernetes 的 Deployment + Service; - 如何在 K8S 中通过 ClusterIP / NodePort 暴露后端与前端服务,并完成端到端访问验证。 可以进一步思考和尝试: - 将 MySQL 从 Deployment 改为 StatefulSet,并结合 StorageClass 实现更规范的持久化; - 使用 Ingress + Ingress Controller 替代 NodePort,通过域名访问前端与后端; - 使用 HPA(Horizontal Pod Autoscaler)实现后端服务的自动扩缩容; - 为关键服务添加更完善的健康检查和资源限制(requests/limits)。 完成以上内容,即完成了从 Docker Compose 向 Kubernetes 迁移物联网管理系统的完整实验。 我需要结果
最新发布
12-25
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值