在4-4章节已经部署好构建镜像的环境,现在可以根据生产实际需求部署web应用。具体为使用nginx做网站服务,java的tomcat解析动态页面,最后使用NAS实现动静分离。
准备文件,包括构建文件,页面文件,源码包,配置文件,加速器:
ls nginx/
# 构建nginx镜像的Dockerfile
Dockerfile
# 前端页面,有图片和html组成
frontend.tar.gz
# nginx源码包
nginx-1.22.0.tar.gz
# nginx配置文件
nginx.conf
# apt-get清华源加速器
sources.list
nginx配置,访问myapp将转发tomcat service:
vim nginx.conf
upstream tomcat {
# 服务名可以通过 kubectl get svc -A 查找
server myserver-tomcat-app1-service:80;
}
location /myapp {
# 当用户请求myapp路径,便会转发到tomcat service。
proxy_pass http://tomcat;
}
构建文件Dockerfile详解:
# 基础镜像选择ubuntu
FROM ubuntu:22.04
# 添加apt-get清华源加速器
ADD sources.list /etc/apt/sources.list
# 安装基础工具与依赖
RUN apt update && apt install -y iproute2 ntpdate tcpdump telnet traceroute nfs-kernel-server nfs-common lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev ntpdate tcpdump telnet traceroute gcc openssh-server lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev ntpdate tcpdump telnet traceroute iotop unzip zip make
# 添加源码并安装
ADD nginx-1.22.0.tar.gz /usr/local/src/
RUN cd /usr/local/src/nginx-1.22.0 && ./configure --prefix=/apps/nginx && make && make install && ln -sv /apps/nginx/sbin/nginx /usr/bin
# 创建组,用户,改权限
RUN groupadd -g 2088 nginx && useradd -g nginx -s /usr/sbin/nologin -u 2088 nginx && chown -R nginx.nginx /apps/nginx
# 添加配置文件
ADD nginx.conf /apps/nginx/conf/
# 添加前端页面
ADD frontend.tar.gz /apps/nginx/html/
# 暴露80和443端口
EXPOSE 80 443
# 在前台启动nginx
CMD ["nginx","-g","daemon off;"]
构建镜像,上传下载镜像,启动容器:
# 在Dockerfile目录启动构建命令
nerdctl build -t easzlab.io.local:5000/myhub/nginx:v1 .
# 上传镜像到私有仓库
nerdctl push --insecure-registry easzlab.io.local:5000/myhub/nginx:v1
# 下载到任一节点
nerdctl pull --insecure-registry easzlab.io.local:5000/myhub/nginx:v1
# 启动镜像,映射80和443端口
nerdctl run -d -p 80:80 -p 443:443 easzlab.io.local:5000/myhub/nginx:v1
java tomcat服务需要分层构建,从jdk基础镜像,到tomcat程序镜像,最后app业务镜像。这样符合镜像分层构建思想,提高基础镜像复用率。app版本与tomcat版本相对应便于升级回滚。
准备文件,包括构建文件,安装包,全局配置文件:
ls jdk/
# 镜像构建文件
Dockerfile
# jdk安装包
jdk-8u212-linux-x64.tar.gz
# 环境变量等全局配置文件
profile
构建jdk镜像,设置环境变量:
# JDK Base Image
# 基于官网centos7.9
FROM centos:7.9.2009
# 拷贝jdk安装包
ADD jdk-8u212-linux-x64.tar.gz /usr/local/src/
RUN ln -sv /usr/local/src/jdk1.8.0_212 /usr/local/jdk
# 添加全局配置文件
ADD profile /etc/profile
# 设置jdk目录,添加到环境变量
ENV JAVA_HOME /usr/local/jdk
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/:$JRE_HOME/lib/
ENV PATH $PATH:$JAVA_HOME/bin
构建镜像,测试容器:
# 构建jdk镜像并查看
sudo nerdctl build -t easzlab.io.local:5000/myhub/jdk-base:v8.212 .
sudo nerdctl images
# 在本机运行镜像,查看java版本
sudo nerdctl run easzlab.io.local:5000/myhub/jdk-base:v8.212 java -version
java version "1.8.0_212"
Java(TM) SE Runtime Environment (build 1.8.0_212-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.212-b10, mixed mode)
# 上传基础镜像到私有仓库,以供程序镜像使用
nerdctl push --insecure-registry easzlab.io.local:5000/myhub/jdk-base:v8.212
准备文件,包括构建文件,安装包:
ls tomcat/
# tomcat镜像构建文件
Dockerfile
# 程序安装包
apache-tomcat-8.5.43.tar.gz
构建镜像,FROM镜像来源于jdk基础镜像:
# Tomcat 8.5.43 程序镜像
# 镜像源自上一步构建好的jdk镜像
FROM easzlab.io.local:5000/myhub/jdk-base:v8.212
# 将安装包放到/apps目录
RUN mkdir /apps /data/tomcat/webapps /data/tomcat/logs -pv
ADD apache-tomcat-8.5.43.tar.gz /apps
# 添加用户,创建链接,更改权限
RUN useradd tomcat -u 2050 && ln -sv /apps/apache-tomcat-8.5.43 /apps/tomcat && chown -R tomcat.tomcat /apps /data -R
如果构建镜像时,出现如下报错,请参考文章末尾故障排错部分。
server gave HTTP response to HTTPS client
构建tomcat镜像,上传镜像:
# 构建tomcat镜像并查看
nerdctl build -t easzlab.io.local:5000/myhub/tomcat-base:v8.5.43 .
nerdctl images
# 上传程序镜像,以供业务镜像使用
nerdctl push --insecure-registry easzlab.io.local:5000/myhub/tomcat-base:v8.5.43
准备文件,包括构建文件,前端页面,内核文件,脚本启动,服务配置:
ls tomcat-app1/
# 业务构建文件
Dockerfile
# 前端页面html
app1.tar.gz
# servlet容器
catalina.sh
# 启动脚本
run_tomcat.sh
# 服务配置
server.xml
构建业务镜像,基于tomcat程序镜像:
# tomcat webapp
# 基于本地构建的程序镜像
FROM easzlab.io.local:5000/myhub/tomcat-base:v8.5.43
# 添加服务配置与前端页面
ADD server.xml /apps/tomcat/conf/server.xml
ADD app1.tar.gz /data/tomcat/webapps/myapp/
# 添加内核文件并可执行
ADD catalina.sh /apps/tomcat/bin/catalina.sh
RUN chmod +x /apps/tomcat/bin/catalina.sh
# 添加启动脚本并可执行
ADD run_tomcat.sh /apps/tomcat/bin/run_tomcat.sh
RUN chmod +x /apps/tomcat/bin/run_tomcat.sh
# 创建nginx用户并授权
RUN useradd -u 2088 nginx
RUN chown -R nginx.nginx /data/ /apps/
# 暴露web服务端口
EXPOSE 8080 8443
# 启动脚本
CMD ["/apps/tomcat/bin/run_tomcat.sh"]
开始构建,本地测试,上传镜像:
# 构建业务app镜像
nerdctl build -t easzlab.io.local:5000/myhub/tomcat-app1:v2 .
# 本地测试容器,映射两个端口
nerdctl run -d -p 8080:8080 -p 8443:8443 easzlab.io.local:5000/myhub/tomcat-app1:v2
# 通过浏览器或curl测试,最后/不能少。
curl http://192.168.100.151:8080/myapp/
tomcat app1 for linux
# 上传镜像到私有仓库
nerdctl push --insecure-registry easzlab.io.local:5000/myhub/tomcat-app1:v2
全部镜像构建完成,并且单机测试通过,最后上传到私有仓库:
sudo nerdctl images
REPOSITORY TAG IMAGE ID CREATED PLATFORM SIZE BLOB SIZE
centos 7.9.2009 c73f515d06b0 3 hours ago linux/amd64 211.5 MiB 72.6 MiB
easzlab.io.local:5000/myhub/jdk-base v8.212 dd0d25a3a2b5 2 hours ago linux/amd64 602.8 MiB 259.9 MiB
easzlab.io.local:5000/myhub/nginx v1 ce4ed5ec07db 3 hours ago linux/amd64 448.9 MiB 173.4 MiB
easzlab.io.local:5000/myhub/tomcat-app1 v1 a8334e773c41 2 hours ago linux/amd64 648.4 MiB 287.7 MiB
easzlab.io.local:5000/myhub/tomcat-app1 v2 350e7e88ee8e 37 minutes ago linux/amd64 648.4 MiB 287.7 MiB
easzlab.io.local:5000/myhub/tomcat-base v8.5.43 1e20c0b071d5 2 hours ago linux/amd64 632.9 MiB 278.4 MiB
在NFS服务器创建共享目录:
# 创建共享目录,用于保存网站图片与静态文件,属主属组选nfsnobody。
mkdir -p /data/k8sdata/myserver/images
chown nfsnobody.nfsnobody /data/k8sdata/myserver/images
mkdir -p /data/k8sdata/myserver/static
chown nfsnobody.nfsnobody /data/k8sdata/myserver/static
# 提供共享服务,可共享的IP段为物理机IP,rw可读写,all_squash远程用户连到nfs服务器都压榨成nfsnobody用户。
cat << EOF >> /etc/exports
/data/k8sdata/myserver/images 192.168.100.0/24(rw,all_squash)
/data/k8sdata/myserver/static 192.168.100.0/24(rw,all_squash)
EOF
# 重新加载,查看挂载情况
exportfs -r
exportfs -v
# nfs涉及端口较多,测试环境可关闭防火墙
systemctl disable --now firewalld
通过yaml部署java Deployment,挂载NFS共享目录:
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: myserver-tomcat-app1-deployment-label
name: myserver-tomcat-app1-deployment
namespace: myserver
spec:
replicas: 1
selector:
matchLabels:
app: myserver-tomcat-app1-selector
template:
metadata:
labels:
app: myserver-tomcat-app1-selector
spec:
containers:
- name: myserver-tomcat-app1-container
image: easzlab.io.local:5000/myhub/tomcat-app1:v2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
protocol: TCP
name: http
volumeMounts:
# Pod挂载宿主机目录,再关联到NFS共享目录
- name: myserver-images
mountPath: /usr/local/nginx/html/webapp/images
readOnly: false
- name: myserver-static
mountPath: /usr/local/nginx/html/webapp/static
readOnly: false
volumes:
# 宿主机关联到NFS服务器共享目录
- name: myserver-images
nfs:
server: 192.168.100.155
path: /data/k8sdata/myserver/images
- name: myserver-static
nfs:
server: 192.168.100.155
path: /data/k8sdata/myserver/static
---
kind: Service
apiVersion: v1
metadata:
labels:
app: myserver-tomcat-app1-service-label
name: myserver-tomcat-app1-service
namespace: myserver
spec:
type: NodePort
ports:
- name: http
# 服务端口
port: 80
protocol: TCP
# Pod端口
targetPort: 8080
# 各节点端口
nodePort: 30280
selector:
app: myserver-tomcat-app1-selector
通过yaml部署nginx Deployment,挂载NFS共享目录:
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: myserver-nginx-deployment-label
name: myserver-nginx-deployment
namespace: myserver
spec:
replicas: 1
selector:
matchLabels:
app: myserver-nginx-selector
template:
metadata:
labels:
app: myserver-nginx-selector
spec:
containers:
- name: myserver-nginx-container
image: easzlab.io.local:5000/myhub/nginx:v1
imagePullPolicy: Always
ports:
- containerPort: 80
protocol: TCP
name: http
- containerPort: 443
protocol: TCP
name: https
volumeMounts:
- name: myserver-images
mountPath: /usr/local/nginx/html/webapp/images
readOnly: false
- name: myserver-static
mountPath: /usr/local/nginx/html/webapp/static
readOnly: false
volumes:
- name: myserver-images
nfs:
server: 192.168.100.155
path: /data/k8sdata/myserver/images
- name: myserver-static
nfs:
server: 192.168.100.155
path: /data/k8sdata/myserver/static
---
kind: Service
apiVersion: v1
metadata:
labels:
app: myserver-nginx-service-label
name: myserver-nginx-service
namespace: myserver
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
nodePort: 30180
- name: https
port: 443
protocol: TCP
targetPort: 443
nodePort: 30143
selector:
app: myserver-nginx-selector
测试图片和静态文件是否挂载到NFS服务器:
# 进入nginx或tomcat容器
cd /usr/local/nginx/html/webapp/images
touch 123.jpg
# 删除容器,去到NFS服务器查看
ls /data/k8sdata/myserver/images
123.jpg
在构建tomcat程序镜像时,可能发生以下报错:
> [internal] load metadata for easzlab.io.local:5000/myhub/jdk-base:v8.212:
------
Dockerfile:3
--------------------
1 | # Tomcat 8.5.43 程序镜像
2 | # 镜像源自上一步构建好的jdk镜像
3 | >>> FROM easzlab.io.local:5000/myhub/jdk-base:v8.212
4 | # 将安装包放到/apps目录
5 | RUN mkdir /apps /data/tomcat/webapps /data/tomcat/logs -pv
--------------------
error: failed to solve: easzlab.io.local:5000/myhub/jdk-base:v8.212: failed to do request: Head "https://easzlab.io.local:5000/v2/myhub/jdk-base/manifests/v8.212": http: server gave HTTP response to HTTPS client
FATA[0000] unrecognized image format
报错原因:FROM默认使用https下载镜像,私有仓库未提供https服务。
解决方案:
① 给私有仓库签发证书,让registry提供https服务。
② 配置buildkit文件,让其支持http下载镜像。
第一签发证书相对麻烦,我们采取第二种方案,修改配置文件:
mkdir /etc/buildkit
vim /etc/buildkit/buildkitd.toml
[registry."easzlab.io.local:5000"]
http = true
systemctl restart buildkitd.service