K8S学习笔记-------2.极简易懂的入门示例
- 1. 准备应用代码
- 1.1 确保 Node.js 和 npm 已安装
- 1.2. 创建项目目录并初始化项目
- 1.3. 安装 Express
- 1.4 验证安装
- 2.容器化应用
- 2.1 准备 Dockerfile
- 2.2 构建镜像
- 3.编写K8s配置文件
- 创建 Deployment
- 创建 Service
- 4.部署到K8s集群
- 应用Deployment
- 应用Service
- 5.验证应用是否正常运行
1. 准备应用代码
编写Node.js应用代码,并确保它可以在本地运行。
1.1 确保 Node.js 和 npm 已安装
在使用 npm 之前,需要先安装 Node.js。因为 npm 是随 Node.js 一起安装的。你可以通过以下命令检查它们是否已经安装以及查看版本信息:
zgq@docker01:~$ node -v
Command 'node' not found, but can be installed with:
sudo apt install nodejs
zgq@docker01:~$ npm -v
Command 'npm' not found, but can be installed with:
sudo apt install npm
我的机器没有安装npm、node ,以下执行安装操作,(先安装node)
先执行对系统的更新操作
root@docker01:/home/zgq# apt update
root@docker01:/home/zgq# apt upgrade
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following upgrades have been deferred due to phasing:libunwind8 python3-distupgrade ubuntu-release-upgrader-core
0 upgraded, 0 newly installed, 0 to remove and 3 not upgraded.
zgq@docker01:~$ sudo apt install nodejs
sudo: unable to resolve host docker01: Name or service not known
[sudo] password for zgq:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:libcares2 libnode109 node-acorn node-busboy node-cjs-module-lexer node-undici node-xtend nodejs-doc
Suggested packages:npm
The following NEW packages will be installed:libcares2 libnode109 node-acorn node-busboy node-cjs-module-lexer node-undici node-xtend nodejs nodejs-doc
0 upgraded, 9 newly installed, 0 to remove and 143 not upgraded.
Need to get 16.1 MB of archives.
After this operation, 70.4 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
再安装npm
root@docker01:/home/zgq# apt install npm
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
npm is already the newest version (9.2.0~ds1-2).
0 upgraded, 0 newly installed, 0 to remove and 3 not upgraded.
验证版本信息
zgq@docker01:~$ sudo node -v
v18.19.1
zgq@docker01:~$ sudo npm -v
9.2.0
如果显示出版本号,说明已经安装成功。
1.2. 创建项目目录并初始化项目
如果你还没有项目目录,可以创建一个新的目录,并在该目录下初始化一个新的 Node.js 项目。以下是具体操作:
# 创建一个新的项目目录
zgq@docker01:~$ mkdir my-express-app
# 进入项目目录
zgq@docker01:~$ cd my-express-app
# 初始化项目,会生成一个 package.json 文件
zgq@docker01:~/my-express-app$ npm init -y
Wrote to /home/zgq/my-express-app/package.json:
{"name": "my-express-app","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"keywords": [],"author": "","license": "ISC"
}
npm init -y 中的 -y 选项表示使用默认配置快速初始化项目,这样会自动生成一个 package.json 文件,该文件用于记录项目的元数据和依赖信息。
1.3. 安装 Express
- 在项目目录下执行 npm install express 命令:
zgq@docker01:~/my-express-app$ npm install expressadded 69 packages, and audited 70 packages in 6s14 packages are looking for fundingrun `npm fund` for detailsfound 0 vulnerabilities
- 执行该命令后,npm 会从 npm 仓库下载 Express 及其所有依赖项,并将它们安装到项目目录下的 node_modules 文件夹中。同时,package.json 文件会更新,添加 Express 作为项目的依赖项,如下所示:
zgq@docker01:~/my-express-app$ cat package.json
{"name": "my-express-app","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"keywords": [],"author": "","license": "ISC","dependencies": {"express": "^4.21.2" // 此版本号可能会根据实际安装情况有所不同,执行npm install 命令后会添加Express作为项目的依赖项}
}
1.4 验证安装
- 安装完成后,你可以创建一个简单的 Express 应用来验证是否安装成功。在项目目录下创建一个名为 app.js 的文件,内容如下:
const express = require('express');
const app = express();
const port = 3000;app.get('/', (req, res) => {res.send('Hello, World!');
});app.listen(port, () => {console.log(`Server is running on port ${port}`);
});
可以使用nano编辑,例如:
zgq@docker01:~/my-express-app$ nano app.js
- 在终端中运行以下命令启动应用:
zgq@docker01:~/my-express-app$ node app.js
Server is running on port 3000
- 打开浏览器,访问 http://localhost:3000或者http://your-server-ip:3000,如果看到页面显示 Hello, Kubernetes!,则说明 Express 安装成功并且应用正常运行。
2.容器化应用
2.1 准备 Dockerfile
在项目根目录下创建一个 Dockerfile 文件,用于定义如何构建镜像。以下是一个简单的 Node.js 应用的 Dockerfile 示例:
# 使用官方 Node.js 镜像作为基础镜像
FROM node: current-slim# 设置工作目录
WORKDIR /app# 复制 package.json 和 package-lock.json
COPY package*.json ./# 安装依赖
RUN npm install# 复制项目文件
COPY . .# 暴露端口(假设应用运行在 3000 端口)
EXPOSE 3000# 启动应用
CMD ["npm", "start"]
2.2 构建镜像
- 在包含 Dockerfile 的目录下运行以下命令:
注意:命令行最某尾的" . " : 表示 Dockerfile 和构建上下文位于当前目录。
ubuntu@ip-172-31-89-208:~/zgq-kube/App$ sudo docker build -t zhuguoqiang999/node-app:1.0 .
[+] Building 9.4s (11/11) FINISHED docker:default=> [internal] load build definition from Dockerfile 0.0s=> => transferring dockerfile: 223B 0.0s=> [internal] load metadata for docker.io/library/node:current-slim 0.5s=> [auth] library/node:pull token for registry-1.docker.io 0.0s=> [internal] load .dockerignore 0.0s=> => transferring context: 170B 0.0s=> [1/5] FROM docker.io/library/node:current-slim@sha256:278dc9616f605d5de4304fb19bf245ec1fd5569fddf2c7ea611f6e7262de98b5 3.4s=> => resolve docker.io/library/node:current-slim@sha256:278dc9616f605d5de4304fb19bf245ec1fd5569fddf2c7ea611f6e7262de98b5 0.0s=> => extracting sha256:60eeb4400e1d51b1953b4b40591ad79190856f512afd10df0dcb13d184cf49c7 0.0s=> => sha256:278dc9616f605d5de4304fb19bf245ec1fd5569fddf2c7ea611f6e7262de98b5 6.49kB / 6.49kB 0.0s=> => sha256:9673e806eca4f9b3d32a0b8259e68c766d062136e3ea8e98bcffc440010a37b1 1.93kB / 1.93kB 0.0s=> => sha256:3632793bb481bbf2c572029478b0141d66cbdc590dd32d4a708aa04605f8529d 6.54kB / 6.54kB 0.0s=> => sha256:60eeb4400e1d51b1953b4b40591ad79190856f512afd10df0dcb13d184cf49c7 3.31kB / 3.31kB 0.1s=> => sha256:ce755d7cf7f5964170ef8f511ba3de78ca52a5e4871dc9f467d05d47ae846059 49.81MB / 49.81MB 0.8s=> => sha256:dc6c34e52d5c07b4fa00771ccd49191e4f3d6685ad6ab5cb7b53370bbc18a4f0 1.71MB / 1.71MB 0.2s=> => sha256:ed279290f28c8b2682ebe25022d1df670b7c3a1499ab10bf6a00439647154c06 448B / 448B 0.2s=> => extracting sha256:ce755d7cf7f5964170ef8f511ba3de78ca52a5e4871dc9f467d05d47ae846059 2.2s=> => extracting sha256:dc6c34e52d5c07b4fa00771ccd49191e4f3d6685ad6ab5cb7b53370bbc18a4f0 0.1s=> => extracting sha256:ed279290f28c8b2682ebe25022d1df670b7c3a1499ab10bf6a00439647154c06 0.0s=> [internal] load build context 0.0s=> => transferring context: 1.13kB 0.0s=> [2/5] WORKDIR /src 0.1s=> [3/5] COPY package*.json ./ 0.0s=> [4/5] RUN npm install 4.9s=> [5/5] COPY . . 0.0s=> exporting to image 0.3s=> => exporting layers 0.3s=> => writing image sha256:02a5d7d363c3ab6e6d6b0a92cf9580d6ca1ac01b9cfb71e0ec2ac7f60086ee6c 0.0s=> => naming to docker.io/zhuguoqiang999/node-app:1.0 0.0s
- 查看生成的镜像。构建完成后,可以使用以下命令查看本地镜像:
- 运行容器。使用以下命令运行容器:
ubuntu@ip-172-31-89-208:~/zgq-kube/App$ sudo docker run -p 3000:3000 zhuguoqiang999/node-app:1.0
Server is running on port 3000
- 测试应用。
打开浏览器或使用 curl 访问 http://localhost:3000,检查应用是否正常运行。
需要重新开启另外一个终端连接服务器。
ubuntu@ip-172-31-89-208:~$ curl http://localhost:3000
Hello, Kubernetes! @Zhuguoqiang 2025.2.4 2937425@qq.
- 推送镜像到 Docker Hub
如果你想将镜像推送到 Docker Hub,可以按照以下步骤操作:
1.登录 Docker Hub:
ubuntu@ip-172-31-89-208:~$ sudo docker login
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credential-storesLogin Succeeded
2.推送镜像:
ubuntu@ip-172-31-89-208:~$ sudo docker push zhuguoqiang999/node-app:1.0
The push refers to repository [docker.io/zhuguoqiang999/node-app]
922d2f65e7aa: Pushed
289c1592db1b: Pushed
324187b0ba8b: Pushed
6cd6185f60c1: Pushed
10608948e461: Mounted from library/node
a1789e7ed79e: Mounted from library/node
dd75864d0f98: Mounted from library/node
5b7299b84b0c: Mounted from library/node
f5fe472da253: Mounted from zhuguoqiang999/qsk-book
1.0: digest: sha256:548a79a5fea6b61180156f53f7d54846ab333d87edf7fed8b8c740ada9421fa1 size: 2198
- 在Docker hub上查看镜像
注意事项:
Dockerfile 路径:确保 Dockerfile 文件位于当前目录(.),或者指定正确的路径。
镜像名称:zhuguoqiang999/node-app 中的 zhuguoqiang999 必须是你的 Docker Hub 用户名,否则推送时会失败。
标签管理:建议为镜像添加明确的标签(如 zhuguoqiang999/node-app:1.0),而不是默认的 latest。
- 示例项目结构
假设你的项目结构如下:运行 docker build -t zhuguoqiang999/node-app . 后,Docker 会基于 Dockerfile 构建镜像。
ubuntu@ip-172-31-89-208:~$ tree zgq-kube
zgq-kube
└── App├── Dockerfile├── app.js└── package.json2 directories, 3 files
3.编写K8s配置文件
创建 Deployment
将以下YAML 文件保存为 node-deployment.yaml,
# node-deployment.yaml
apiVersion: apps/v1
kind: Deployment # 表明这是 Kubernetes Deployment
metadata:name: node-deployment # Deployment 的名称
spec:replicas: 3 # 希望运行的 Pod 副本数量selector:matchLabels:app: node-app # 选择具有这些标签的 Podtemplate:metadata:labels:app: node-app # 模板中创建的 Pod 的标签spec:containers:- name: node-container # 容器的名称image: zhuguoqiang999/node-app:1.0 # 使用的 Docker 镜像版本ports:- containerPort: 3000 # 容器内部监听的端口
运行以下命令创建和查看 Deployment、POD:
# 先测试node-deployment.yaml语法
zgq@k8s-node1:~/zgq-kube$ kubectl apply --dry-run='client' -f node-deployment.yaml
deployment.apps/node-deployment configured (dry run)
# 执行创建deployment
zgq@k8s-node1:~/zgq-kube$ kubectl apply -f node-deployment.yaml
deployment.apps/node-deployment created
# 查看创建的deployment
zgq@k8s-node1:~/zgq-kube$ kubectl get deployment |grep node-deployment
node-deployment 3/3 3 3 12m
# 查看创建的pods
zgq@k8s-node1:~/zgq-kube$ kubectl get pods |grep node-deployment
node-deployment-5c574c5cdb-6pwrq 1/1 Running 0 13m
node-deployment-5c574c5cdb-7hkm8 1/1 Running 0 13m
node-deployment-5c574c5cdb-qzm9v 1/1 Running 0 13m
创建 Service
为了让外部访问 Node.js 应用,需要创建一个 Service。创建一个 node-service.yaml 文件:
# node-service.yaml
apiVersion: v1
kind: Service # 表明这是 Kubernetes Service
metadata:name: node-service # Service 的全局唯一名称
spec:type: NodePort # 类型为 NodePortports:- port: 80 # Service 提供服务的端口号targetPort: 3000 # 目标 Pod 上容器监听的端口号nodePort: 30008 # 暴露在节点上的端口号(可选,如果不指定会自动分配)selector:app: node-app # Service 对应的 Pod 拥有这里定义的标签
4.部署到K8s集群
应用Deployment
运行以下命令创建和查看 Deployment、POD:
# 先测试node-deployment.yaml语法
zgq@k8s-node1:~/zgq-kube$ kubectl apply --dry-run='client' -f node-deployment.yaml
deployment.apps/node-deployment configured (dry run)
# 执行创建deployment
zgq@k8s-node1:~/zgq-kube$ kubectl apply -f node-deployment.yaml
deployment.apps/node-deployment created
# 查看创建的deployment
zgq@k8s-node1:~/zgq-kube$ kubectl get deployment |grep node-deployment
node-deployment 3/3 3 3 12m
# 查看创建的pods
zgq@k8s-node1:~/zgq-kube$ kubectl get pods |grep node-deployment
node-deployment-5c574c5cdb-6pwrq 1/1 Running 0 13m
node-deployment-5c574c5cdb-7hkm8 1/1 Running 0 13m
node-deployment-5c574c5cdb-qzm9v 1/1 Running 0 13m
应用Service
应用 Service 配置:
zgq@k8s-node1:~/zgq-kube$ kubectl apply --dry-run='client' -f node-service.yaml
service/node-service created (dry run)
zgq@k8s-node1:~/zgq-kube$ kubectl apply -f node-service.yaml
service/node-service created
zgq@k8s-node1:~/zgq-kube$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-node LoadBalancer 10.50.57.188 <pending> 8080:30856/TCP 7d17h
kubernetes ClusterIP 10.50.0.1 <none> 443/TCP 34d
kubernetes-bootcamp NodePort 10.50.28.53 <none> 8080:30707/TCP 7d16h
mysql ClusterIP 10.50.174.42 <none> 3306/TCP 45h
myweb NodePort 10.50.154.206 <none> 80:30001/TCP 42h
node-service NodePort 10.50.72.149 <none> 80:30008/TCP 10s
svc-local NodePort 10.50.187.62 <none> 8080:31111/TCP 3d1h
获取Service的NodePort端口:
zgq@k8s-node1:~/zgq-kube$ kubectl describe svc node-service
Name: node-service
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=node-app
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.50.72.149
IPs: 10.50.72.149
Port: <unset> 80/TCP
TargetPort: 3000/TCP
NodePort: <unset> 30008/TCP
Endpoints: 10.60.36.83:3000,10.60.169.147:3000,10.60.36.82:3000
Session Affinity: None
External Traffic Policy: Cluster
Internal Traffic Policy: Cluster
Events: <none>
5.验证应用是否正常运行
使用Minikube或其他K8s集群,找到节点IP并访问:
minikube ip
然后在浏览器中访问:http://<node-ip>:<node-port>
应该看到 “Hello Kubernetes!”。