实战内容
1、基于alpine制作nginx、mysql、dns、redis镜像
2、通过k8s实现以上中间件的单pod部署
3、最后测试对应pod的可行性
Master:192.168.95.177
node1:192.168.95.178
node2:192.168.95.179
关卡一:准备基础环境 (在 Master 192.168.95.177 上操作)
首先,我们要确保你手里的 alpine.tar 镜像已经正确加载到了 Docker 里。
1. 加载镜像
在终端执行:
bash
编辑
1docker load -i alpine.tar
2. 验证加载结果
执行:
bash
编辑
1docker images | grep alpine
预期结果: 你应该能看到一行包含 alpine 的镜像信息。
注意: 请记下它的 REPOSITORY 和 TAG (比如 alpine:latest 或者 alpine:3.19)。接下来所有的 Dockerfile 里,第一行 FROM 后面都要填你实际查到的这个名字。
🟡 关卡二:制作并验证 Nginx 镜像 (重点:修改网页路径)
我们要做一个自定义的 Nginx,把网页放在 /var/www/ 下。
1. 创建文件夹并编写 Dockerfile
bash
编辑
1mkdir -p /opt/my-images/nginx && cd /opt/my-images/nginx
2# 使用 vi 或 nano 编辑器创建 Dockerfile
3vi Dockerfile
把下面的内容复制进去(注意第一行 FROM 换成你刚才查到的 alpine 镜像名):
dockerfile
(注意!这里看查询自己的alpine的版本,一定一定,查看你安装的nginx的路径在哪,里面配置文件内容,我这里的内容是自己编辑后的,因人而异)
编辑
1FROM alpine:latest #
2
3# 换源并安装 nginx
4RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
5 apk add --no-cache nginx
6
7# 修改 nginx 配置,把网页路径从默认的 html 改为 /var/www
8RUN sed -i 's|/usr/share/nginx/html|/var/www|g' /etc/nginx/nginx.conf && \
9 sed -i 's|root html;|root /var/www;|g' /etc/nginx/nginx.conf
10
11# 创建目录并写入自定义网页内容
12RUN mkdir -p /var/www && \
13 echo "<h1>Nginx on Alpine - Custom Path</h1>" > /var/www/index.html
14
15EXPOSE 80
16CMD ["nginx", "-g", "daemon off;"]
2. 构建镜像
bash
编辑
1docker build -t my-nginx:v1 .
3. 验证 Nginx 镜像 (关键步骤!)
在推送到 K8s 之前,我们先用 Docker 本地跑一下,确保路径修改成功了:
bash
编辑
1# 在后台启动一个容器,把容器的 80 端口映射到宿主机的 8080
2docker run -d --name test-nginx -p 8080:80 my-nginx:v1
等待几秒后,访问测试:
bash
编辑
1curl http://127.0.0.1:8080
预期结果: 终端打印出 <h1>Nginx on Alpine - Custom Path</h1>。
如果成功: 说明镜像制作完美!清理掉测试容器:docker rm -f test-nginx。
如果失败: 请检查 Dockerfile 里的 sed 替换命令是否写对。
🔵 关卡三:制作 MySQL、Redis、DNS 镜像
步骤和 Nginx 一样,我们快速过一遍。
1. 制作 MySQL (MariaDB) 镜像
bash
编辑
1cd /opt/my-images/
2mkdir mysql && cd mysql
3vi Dockerfile
Dockerfile 内容:
dockerfile
编辑
1FROM alpine:latest # ⚠️ 替换成你的 alpine 镜像名
2RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
3 apk add --no-cache mariadb mariadb-client && \
4 mkdir -p /var/lib/mysql /run/mysqld && \
5 chown -R mysql:mysql /var/lib/mysql /run/mysqld && \
6 mysql_install_db --user=mysql --datadir=/var/lib/mysql
7EXPOSE 3306
8CMD ["mysqld", "--user=mysql"]
构建:docker build -t my-mysql:v1 .
2. 制作 Redis 镜像
bash
编辑
1cd /opt/my-images/
2mkdir redis && cd redis
3vi Dockerfile
Dockerfile 内容:
dockerfile
编辑
1FROM alpine:latest # ⚠️ 替换成你的 alpine 镜像名
2RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
3 apk add --no-cache redis && \
4 sed -i 's/protected-mode yes/protected-mode no/' /etc/redis.conf
5EXPOSE 6379
6CMD ["redis-server", "/etc/redis.conf"]
构建:docker build -t my-redis:v1 .
3. 制作 DNS (Dnsmasq) 镜像
bash
编辑
1cd /opt/my-images/
2mkdir dns && cd dns
3vi Dockerfile
Dockerfile 内容:
dockerfile
编辑
1FROM alpine:latest # ⚠️ 替换成你的 alpine 镜像名
2RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
3 apk add --no-cache dnsmasq
4EXPOSE 53 53/udp
5CMD ["dnsmasq", "-k", "--no-daemon"]
构建:docker build -t my-dns:v1 .
4. 验证镜像是否都做好了
在 Master 上执行:
bash
编辑
1docker images | grep my-
你应该能看到 my-nginx, my-mysql, my-redis, my-dns 这四个镜像。
🟠 关卡四:将镜像分发给 Node 节点
K8s 的 Node 节点需要这些镜像才能启动 Pod。
1. 打包镜像 (在 Master 上)
bash
编辑
1docker save my-nginx:v1 my-mysql:v1 my-redis:v1 my-dns:v1 -o /root/my-middleware.tar
2. 传输给 Node1 (178) 和 Node2 (179) (在 Master 上)
bash
编辑
1scp /root/my-middleware.tar root@192.168.95.178:/root/
2scp /root/my-middleware.tar root@192.168.95.179:/root/
(如果提示输入密码,请输入你 node 节点的 root 密码)
3. 在 Node 节点上加载 (分别登录 178 和 179 执行)
bash
编辑
1# 在 Node1 (178) 上执行
2docker load -i /root/my-middleware.tar
3
4# 在 Node2 (179) 上执行
5docker load -i /root/my-middleware.tar
验证: 在两个 Node 上都运行 docker images | grep my-,确保镜像都在。
🟣 关卡五:编写 K8s YAML 并部署
现在所有准备工作都做好了,我们开始向 K8s 提交作业。
1. 编写 YAML 文件 (在 Master 上)
bash
编辑
1cd /root/
2vi middleware.yaml
将以下内容复制进去(再次提醒:检查 image 的名字是否和你 build 的一模一样):
yaml
编辑
1apiVersion: v1
2kind: Namespace
3metadata:
4 name: middleware-ns
5---
6apiVersion: v1
7kind: Pod
8metadata:
9 name: nginx-pod
10 namespace: middleware-ns
11 labels:
12 app: nginx
13spec:
14 containers:
15 - name: nginx
16 image: my-nginx:v1
17 imagePullPolicy: IfNotPresent # 告诉k8s如果本地有镜像就别去网上拉取了
18 ports:
19 - containerPort: 80
20---
21apiVersion: v1
22kind: Pod
23metadata:
24 name: mysql-pod
25 namespace: middleware-ns
26 labels:
27 app: mysql
28spec:
29 containers:
30 - name: mysql
31 image: my-mysql:v1
32 imagePullPolicy: IfNotPresent
33 ports:
34 - containerPort: 3306
35---
36apiVersion: v1
37kind: Pod
38metadata:
39 name: redis-pod
40 namespace: middleware-ns
41 labels:
42 app: redis
43spec:
44 containers:
45 - name: redis
46 image: my-redis:v1
47 imagePullPolicy: IfNotPresent
48 ports:
49 - containerPort: 6379
50---
51apiVersion: v1
52kind: Pod
53metadata:
54 name: dns-pod
55 namespace: middleware-ns
56 labels:
57 app: dns
58spec:
59 containers:
60 - name: dns
61 image: my-dns:v1
62 imagePullPolicy: IfNotPresent
63 ports:
64 - containerPort: 53
65 protocol: UDP
66 - containerPort: 53
67 protocol: TCP
2. 提交部署
bash
编辑
1kubectl apply -f middleware.yaml
3. 验证部署状态 (最重要的一步)
bash
编辑
1kubectl get pods -n middleware-ns -o wide
预期结果:
刚开始 STATUS 可能是 ContainerCreating。等待 1 分钟左右,再次执行该命令。
所有 4 个 Pod 的 STATUS 都必须变成 Running,且 READY 是 1/1。
(如果有 Pod 报错,比如 ErrImagePull 或 CrashLoopBackOff,请立刻告诉我报错信息,我们现场排查!)
🔴 关卡六:最终可行性测试
Pod 跑起来后,我们要验证它们的功能是否正常。
1. 测试 Nginx (验证自定义网页)
bash
编辑
1# 获取 nginx-pod 的 IP 地址
2NGINX_IP=$(kubectl get pod nginx-pod -n middleware-ns -o jsonpath='{.status.podIP}')
3# 访问它
4curl http://$NGINX_IP
成功标志: 返回 <h1>Nginx on Alpine - Custom Path</h1>。
2. 测试 Redis
我们进入 Redis 的 Pod 内部,用 redis-cli 敲个命令:
bash
编辑
1kubectl exec -it redis-pod -n middleware-ns -- redis-cli ping
成功标志: 返回 PONG。
3. 测试 MySQL
进入 Pod 内部,尝试登录数据库:
bash
编辑
1kubectl exec -it mysql-pod -n middleware-ns -- mysql -u root -e "SELECT 'MySQL is OK';"
成功标志: 输出表格显示 MySQL is OK。
4. 测试 DNS
进入 Pod 内部,查看进程是否活着:
bash
编辑
1kubectl exec -it dns-pod -n middleware-ns -- ps aux | grep dnsmasq
成功标志: 能看到包含 dnsmasq 的进程信息。