因开发需求,经常需要制作自定义镜像,以centos7.5,alpine3.12为例(Ubuntu也是常用的基础镜像)

一、下载镜像

从Docker Hub下载基础镜像https://hub.docker.com

docker pull centos:centos7.5.1804
docker pull alpine:3.12
docker pull ubuntu:18.04

二、centos制作业务镜像

制作基础命令镜像

官网下载的centos7.5镜像是很多基础命令都没有的,可以先以官方镜像为基础,制作具备基础命令的基础镜像

mkdir centos-base; cd centos-base
vim Dockerfile
#Docker for centos7.5 with initial command

FROM centos:centos7.5.1804
LABEL maintainer="Email <hlroliu@163.com>"

RUN  yum install -y bash-completion vim-enhanced net-tools yum-utils tree wget curl make cmake gcc gcc-c++ htop unzip pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute iotop  && rm -rf /var/cache/yum/* && ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo Asia/Shanghai > /etc/timezone

保存退出,执行构建
docker built -t centos7.5:base .

制作centos-JDK镜像

以centos:base镜像为基础,构建JDK镜像,可根据需求,可构建不同版本的JDK镜像

mkdir centos-jdk261; cd centos-jdk261
ls
  Dockerfile  jdk-8u261-linux-x64.tar.gz  profile

cat profile #在centos7.5的/etc/profile中添加java环境变量
#在文件底部添加java环境变量

export JAVA_HOME=/usr/local/jdk1.8.0_261
export JRE_HOME=$JAVA_HOME/jre  
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib

编辑Dockerfile文件

vim Dockerfile
#Docker for centos7.5 with jdk-8u261

FROM centos7.5:base
LABEL maintainer="Email <hlroliu@163.com>"

ADD jdk-8u261-linux-x64.tar.gz /usr/local/
ADD profile /etc/profile
ENV JAVA_HOME=/usr/local/jdk1.8.0_261
ENV JRE_HOME=$JAVA_HOME/jre
ENV PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib

保存退出,执行构建
docker built -t centos7.5:jdk261 .
镜像制作好之后,即可以此为基础制作Tomcat或者需要java环境的业务镜像

制作centos-nginx镜像

以centos:base镜像为基础,制作nginx业务镜像
先下载nginx源码包: http://nginx.org/en/download.html,在容器中编译nginx,并创建nginx用户,nginx安装在 /usr/local/nginx,在配置文件中修改nginx默认目录为 /nginx

mkdir centos7.5-nginx; cd centos7.5-nginx; 
ls
 Dockerfile  mycsdn.html  nginx-1.19.7.tar.gz  nginx.conf

获取网页文件,我下载自己的CSDN主页,生产上应由开发提供
curl -o mycsdn.html
编辑Dockerfile

vim Dockerfile 
#Docker for centos7.5 with nginx1.19.7

FROM centos7.5:base
LABEL maintainer="Email <hlroliu@163.com>"

ADD nginx-1.19.7.tar.gz /usr/local/
RUN groupadd -g 1001 nginx && useradd -g nginx -u 1001 -s /sbin/nologin nginx && cd /usr/local/nginx-1.19.7 && ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-stream && make && make install && ln -sv /usr/local/nginx/sbin/nginx /usr/bin && rm -rf /usr/local/nginx-1.19.7 && rm -rf /usr/local/nginx-1.19.7.tar.gz 
ADD nginx.conf /usr/local/nginx/conf/nginx.conf
ADD mycsdn.html /nginx/index.html

RUN chown -R nginx:nginx /usr/local/nginx /nginx

EXPOSE 80 443

CMD ["nginx", "-g", "daemon off;"]

保存退出,执行构建
docker build -t centos7.5:nginx .
运行测试
docker run -d --rm -p30080:80 centos7.5:nginx
浏览器访问 192.168.1.30:30080 #(192.168.1.30为我运行centos7.5:nginx镜像的主机IP)

在k8s集群中运行centos7.5:nginx

把centos7.5:nginx镜像上传到Harbor仓库

vim mynginx.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: 192.168.1.30/hlro/centos7.5:nginx
---
apiVersion: v1
kind: Service
metadata:
  labels:       
    app: nginx-svc             #Service标签
  name: nginx-svc              #Service名称,namespace内唯一
  namespace: default            #名称空间,默认为namespace
  
spec:
  type: ClusterIP                
  ports:                        #Service端口属性
  - name: http          #端口名称
    port: 80                    #服务监听的端口
    targetPort: 80            #pod内容器端口
    protocol: TCP               
  selector:
    app: nginx
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    kubernetes.io/ingress.Class: "nginx"
spec:
  rules:
  - host: www.mycsdn.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-svc
          servicePort: 80

创建nginx应用,配置域名解析并访问

kubectl apply -f mynginx.yaml
kubectl get pod,svc,ingress
NAME                                          READY   STATUS    RESTARTS   AGE
pod/busybox                                   1/1     Running   744        31d
pod/nfs-client-provisioner-56748cf854-rrj67   1/1     Running   36         31d
pod/nginx-deploy-794fb5967b-9hrzg             1/1     Running   0          132m
pod/nginx-deploy-794fb5967b-d59b8             1/1     Running   0          132m

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   31d
service/nginx-svc    ClusterIP   10.110.16.221   <none>        80/TCP    132m

NAME                               CLASS    HOSTS            ADDRESS          PORTS   AGE
ingress.extensions/nginx-ingress   <none>   www.mycsdn.com   10.105.116.139   80      132m

Windows 主机在C:\Windows\System32\drivers\etc下的host文件中配置域名解析,即可通过浏览器访问域名 www.mycsdn.com

三、alpine制作基础镜像

官方提供的centos镜像大概为200M,alpine镜像只有几兆,采用alpine制作镜像,可以缩小镜像文件大小。
编辑Dockerfile文件

vim Dockerfile
# Docker for alpine base
FROM alpine:3.12
LABEL maintainer "hlroliu@163.com"

RUN echo "http://mirrors.ustc.edu.cn/alpine/v3.12/main" > /etc/apk/repositories && echo "http://mirrors.ustc.edu.cn/alpine/v3.12/community" >> /etc/apk/repositories && apk update && apk --no-cache add ca-certificates && apk update && apk add gcc wget net-tools zip unzip pstree libevent libevent-dev iproute2 libgcc libc-dev libcurl libc-utils pcre pcre2 pcre-dev zlib-dev libnfs make tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone

保存退出,执行构建
docker build -t alpine3.12:base .

四、alpine制作jdk镜像

官方提供的centos镜像大概为200M,alpine镜像只有几兆,采用alpine制作镜像,可以缩小镜像文件大小。
Alpine是基于MUSL libc(mini libc),需要安装glibc的库才支持Java。安装方式可参考GitHub:https://github.com/sgerrand/alpine-pkg-glibc

#profile文件取自alpine3.12镜像,可运行一个alpine容器,进入到容器中把文件复制出来
mkdir alpine-jdk261; cd alpine-jdk261
ls
Dockerfile  jdk-8u261-linux-x64.tar.gz  profile

编辑Dockerfile文件

vim Dockerfile
# Docker for alpine jdk8u261
FROM alpine:3.12
LABEL maintainer "hlroliu@163.com"

RUN echo "http://mirrors.ustc.edu.cn/alpine/v3.12/main" > /etc/apk/repositories && echo "http://mirrors.ustc.edu.cn/alpine/v3.12/community" >> /etc/apk/repositories && apk update && apk --no-cache add ca-certificates && apk update && apk add gcc wget net-tools zip unzip pstree libevent libevent-dev iproute2 libgcc libc-dev libcurl libc-utils pcre pcre2 pcre-dev zlib-dev libnfs make tzdata && wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.33-r0/glibc-2.33-r0.apk && apk add glibc-2.33-r0.apk  && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone

ADD jdk-8u261-linux-x64.tar.gz /usr/local/
ADD profile /etc/profile
ENV JAVA_HOME=/usr/local/jdk1.8.0_261
ENV JRE_HOME=$JAVA_HOME/jre
ENV PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib

CMD ["java","-version"]

保存退出,执行构建
docker build -t alpine3.12:jdk261 .

镜像制作好之后,即可以此为基础制作Tomcat或者需要java环境的业务镜像