Dockerfile + harbor详解

发布时间:2024年01月04日

Dockerfile+harbor私服

一 docker工作流

1. docker管理流程

在这里插入图片描述

2. 镜像仓库阿里

(1) 阿里私有仓库

公司内部管理项目涉及到的所有docker镜像,会使用私有仓库的方式,集中管理。

(2) 创建阿里Docker仓库
  1. 登录阿里云创建私有仓库

    网址:容器镜像服务 (aliyun.com)

    对仓库进行配置

    在这里插入图片描述

在这里插入图片描述

  1. 创建命名空间

    通常一个项目,包含了多个镜像,为了方便管理,将多个同属于一个项目的所有镜像放在一个命名空间中。

    命名规范:公司名_项目名

    在这里插入图片描述

  2. 创建镜像仓库

    一个仓库管理一个镜像的多个版本,一个镜像的多个版本。

    命名规范:服务名_v1.0:tag

    在这里插入图片描述

(3) 案例:nginx镜像推送
1. 拉取nginx基础镜像
	docker pull nginx:1.21
2. 启动容器
	docker run --name nginx-10 -d -p 88:80 nginx:1.21
	注意:打包容器,开启新容器,将需要打包文件使用docker cp拷贝进去。无法打包容器卷中数据。
3. 部署代码
	将代码docker cp拷贝到容器中。
4. 提交镜像
	docker commit -a "yangdd@zparkhr.com.cn" -m "第一个版本cms前端代码" nginx-10 cms_nginx:1.1
5. 登录阿里云镜像
	docker login --username=15533349688 registry.cn-zhangjiakou.aliyuncs.com
	说明:
		--username:阿里云仓库注册的手机号。
6. 给镜像打tag
	docker tag cms_nginx:1.1 registry.cn-zhangjiakou.aliyuncs.com/zxtec_cms/cms_nginx:0.1
	注意:镜像最后的名字要和阿里云仓库名一致
7. 推送镜像
	docker push registry.cn-zhangjiakou.aliyuncs.com/zxtec_cms/cms_nginx:0.1
(4) 案例:拉取部署镜像
1. 从阿里私服中拉取镜像
docker pull registry.cn-zhangjiakou.aliyuncs.com/zxtec_cms/cms_nginx:0.1
2. 启动容器
docker run --name cms-nginx -d -p 80:80 -v app_nginx_html:/usr/share/nginx/html -v app_nginx_conf:/etc/nginx/conf.d -v app_nginx_logs:/var/log/nginx registry.cn-zhangjiakou.aliyuncs.com/zxtec_cms/cms_nginx:1.0
3. 测试验证

二 DockerFile

1. 简介

(1) 场景

自定义构建镜像,如果使用docker commit,优缺点

  • ① commit打包过程,对操作者不可见,不知道内部打包了什么,做了什么,有什么问题。
  • ② 所有容器的改动,需要手工操作,不具备可复制性,不具备自动化,不具备规模性。
(2) DockerFile简介

一种脚本语言,用来描述Docker镜像构建过程,也就是一个说明书,Docker通过dockerfile构建出来一个自定义镜像。

(3) Dockerfile作用

通过使用Dockerfile,开发人员可以通过简单的文本文件定义和管理镜像的构建过程,实现自动化、可重复和可管理的镜像构建。

  • 自动化构建:

    通过编写Dockerfile,可以自动构建Docker镜像,而无需手动逐步执行构建步骤。Docker根据Dockerfile中的指令顺序执行构建步骤,从而实现自动化构建过程。
    效率高,便于管理,便于和其他平台集成。

  • 版本控制:

    Dockerfile本身是一个文本文件,通过对Dockerfile内容版本控制,也就实现了Image镜像的版本控制管理。

(4) 指令
指令作用
FROM基础镜像,从这个镜像开始制作
LABEL描述,描述镜像的信息:作者、文字描述、日期、要求数据卷路径 (没有任何docker构建的作用,仅仅给工作人员看的)
maintainer描述信息,写作者信息。作用类似label。逐渐被废弃。
RUN在构建镜像的时候,执行一些命令的。
ADD向镜像中拷贝文件
COPY向镜像中拷贝文件
VOLUME数据卷目录,指定镜像中的那个目录,作为日后数据卷挂载目录。(不写也能挂载,给工作人看的)
EXPOSE暴露开放容器端口
ENV定义环境变量
WORKDIR工作目录,就是exec进入容器,默认初始位置。
ONBUILD当构建一个被继承 Dcokerfile 这个时候就会触发运行ONBUILD命令–了解。
CMD在容器启动的时候,会执行的命令。
entrypoint在容器启动的时候,会执行的命令,例如:redis镜像,一定有redis-server ./redis.conf

2. 第一个案例

构建一个自定义的tomcat镜像,基于tomcat:8.5构建。

(1) 创建dockerfile文件

例如:dockerfile/tomcat/dockerfile-tomcat-1.0

注意:dockerfile到一定要放在一个单独的目录中。

命令:

touch dockerfile-tomcat-1.0
(2) 编写dockerfile指令
# 基础镜像
FROM tomcat:8.5

# 描述
LABEL name="yangdd@zparkhr.com.cn"
LABEL desc="这是一个dockerfile构建的tomcat镜像"
(3) 构建镜像
1. 语法
docker build -t 镜像名:tag -f dockerfile的文件名 .

2. 命令
docker build -t my-tomcat:1.0 -f dockerfile-tomcat-1.0 .
(4) 验证
查看镜像信息
docker inspect 镜像名:tag

3. 详解指令

(1) FROM

基础镜像,本次docker镜像的构建基于From镜像基础之上进行操作。

  • 语法

    FROM <image>:<tag>
    
  • 说明

    • FROM必须是Dockerfile文件的第一行指令。
    • 用于为镜像文件构建过程指定基础镜像,后续的指令都基于该基础镜像环境运行
    • 基础镜像可以是任何一个镜像文件
(2) LABEL

镜像描述信息,描述镜像的信息:作者、文字描述、日期、要求数据卷路径,(没有任何docker构建的作用,仅仅给工作人员看的)

  • 语法

    # 形式1:
    LABEL author="fanqingfuming@zparkhr.com.cn"
    LABEL desc="这是描述"
    
    # 形式2:
    LABEL name="反清复明" age="18" desc="这是一段image描述"
    
  • 说明

    • LABEL指令用来给镜像以name=value对的形式添加一些描述信息
    • 会集成基础镜像中的LABEL属性,通过docker inspect,name不能重复,如果value相同会被覆盖
(3) COPY

从主机(执行docker build)中,拷贝文件或者目录到镜像里面。主机路径?

  • 语法

    COPY <主机src> <镜像dest>
    
  • 说明

    • <src>:要复制的源文件或目录,支持通配符
    • <src>必须在build所在路径或子路径下,不能是其父目录
    • <dest>:目标路径,即镜像中文件系统的路径
    • <dest>目录结尾必须以/结尾。
  • 案例

    FROM centos:7
    LABEL name="反清复明" age="18" desc="这是一段image描述"
    COPY C.txt /opt/cpdir/
    COPY dir/* /opt/cpdir/dir/
    
(4) ADD

类似COPY,但ADD支持tar包自解压和网络路径。

  • 语法

    ADD <src> <dest>
    
  • 说明

    • <src>可以是一个文件,可以是一个目录,也可以是一个网络url路径。
    • <src>如果是一个压缩文件(tar),被被解压为一个目录,如果是通过URL下载一个文件不会被解压
    • <dest>必须以/结尾。
  • 案例

    FROM centos:7
    LABEL name="反清复明" age="18" desc="这是一段image描述"
    COPY C.txt /opt/cpdir/
    COPY dir/* /opt/cpdir/dir/
    ADD dir/* /opt/adddir/dir/
    ADD https://www.cnblogs.com/azulearncode/p/14043606.html /opt/adddir/
    ADD ./jdk-8u291-linux-x64.tar.gz /opt/adddir/dir/
    
(5) ENV

设置镜像中的环境变量,这个变量可以在镜像中直接使用,也可以给会在镜像中执行的命令使用,后续的dockerfile指令使用。

  • 语法

    • 定义环境变量
    # 一次设置一个
    ENV <key>=<value>
    
    # 一次设置多个
    ENV <key>=<value> <key1>=<value1> <key2>=<value2> .....
    
    • 使用环境变量
    $key
    ${key}
    
  • 说明

    • 可以用来定义镜像使用的环境变量
    • 也可以为后续的指令,定义shell变量。
  • 案例

    FROM centos:7
    LABEL name="反清复明" age="18" desc="这是一段image描述"
    COPY C.txt /opt/cpdir/
    COPY dir/* /opt/cpdir/dir/
    ADD dir/* /opt/adddir/dir/
    ADD https://www.cnblogs.com/azulearncode/p/14043606.html /opt/adddir/
    ADD ./jdk-8u291-linux-x64.tar.gz /opt/adddir/dir/
    ENV PATH=$PATH:/opt/adddir/dir/jdk1.8.0_291/bin
    ENV JAVA_HOME=/opt/adddir/dir/jdk1.8.0_291
    
(6) WORKDIR

指定创建容器后,终端进入容器后的默认路径,后续的RUN、CMD、ENTRYPOINT、COPY、ADD涉及到的路径,均以此目录作为当前目录。

  • 语法
    WORKDIR /opt/centos
    
  • 说明

    • 如果设置的目录不存在会自动创建,包括他的父目录
    • 如果使用相对路径,则相对workdir的路径
    • WORKDIR也可以调用ENV指定的变量
  • 案例

    FROM centos:7
    LABEL name="反清复明" age="18" desc="这是一段image描述"
    COPY C.txt /opt/cpdir/
    COPY dir/* /opt/cpdir/dir/
    ADD dir/* /opt/adddir/dir/
    ADD https://www.cnblogs.com/azulearncode/p/14043606.html /opt/adddir/
    ADD ./jdk-8u291-linux-x64.tar.gz /opt/adddir/dir/
    ENV PATH=$PATH:/opt/adddir/dir/jdk1.8.0_291/bin
    ENV JAVA_HOME=/opt/adddir/dir/jdk1.8.0_291
    WORKDIR ${JAVA_HOME}
    
(7) RUN

构建**镜像**过程中,需要执行的命令,可以用来安装依赖,初始化脚本执行等。

  • 语法

    # 语法1,shell 形式
    RUN command1 && command2
    RUN yum install -y vim && yum install -y wget
    
    # 语法2,exec 形式
    RUN ["executable","param1","[param2]"]
    RUN ["yum","install","-y","vim"]
    RUN ["yum","install","-y","wget"]
    
  • 说明

    • RUN 在下一次建构期间,会优先查找本地缓存,若不想使用缓存可以通过docker build --no-cache解除
    • RUN 指令指定的命令是否可以执行取决于 基础镜像中是否允许执行该命令。
    • shell形式,可以使用 &&\ 连接多个命令
    • 一个run就会构建一层镜像,尽量减少run个数。如果命令多,尽量使用&&连接。
    • exec形式,必须使用"“,且第一个命令必须独立是一个命令,后面可以是参数,每个参数独立放在一个”"中。
    • 与 shell 形式不同,exec 形式不会调用shell解析。例如RUN ["echo","$HOME"] ;这样的指令 $HOME并不会被解析。
  • 案例

    FROM centos:7
    LABEL name="反清复明" age="18" desc="这是一段image描述"
    COPY C.txt /opt/cpdir/
    COPY dir/* /opt/cpdir/dir/
    ADD dir/* /opt/adddir/dir/
    ADD https://www.cnblogs.com/azulearncode/p/14043606.html /opt/adddir/
    ADD ./jdk-8u291-linux-x64.tar.gz /opt/adddir/dir/
    ENV PATH=$PATH:/opt/adddir/dir/jdk1.8.0_291/bin
    ENV JAVA_HOME=/opt/adddir/dir/jdk1.8.0_291
    WORKDIR ${JAVA_HOME}
    RUN ["java","-version"]
    RUN echo "哈哈" && echo $(date)
    RUN ["/bin/sh","-c","echo $HOME"]
    
(8) EXPOSE

为镜像设置日后启动容器暴露的端口。

  • 语法

    EXPOSE <port>
    EXPOSE <port>/<protocol>
    
    EXPOSE 80
    EXPOSE 80/tcp
    EXPOSE 2379/udp
    
  • 说明

    • <port>:端口号
    • <protocol>:协议类型,默认TCP协议,tcp/udp/
    • 并不会直接暴露出去,docker run时还需要-P指定才可以,这里就是一个说明,给镜像使用者看的
  • 案例

    FROM centos:7
    LABEL name="反清复明" age="18" desc="这是一段image描述"
    COPY C.txt /opt/cpdir/
    COPY dir/* /opt/cpdir/dir/
    ADD dir/* /opt/adddir/dir/
    ADD https://www.cnblogs.com/azulearncode/p/14043606.html /opt/adddir/
    ADD ./jdk-8u291-linux-x64.tar.gz /opt/adddir/dir/
    ENV PATH=$PATH:/opt/adddir/dir/jdk1.8.0_291/bin
    ENV JAVA_HOME=/opt/adddir/dir/jdk1.8.0_291
    WORKDIR ${JAVA_HOME}
    RUN ["java","-version"]
    RUN echo "哈哈" && echo $(date)
    RUN ["/bin/sh","-c","echo $HOME"]
    EXPOSE 80/udp
    EXPOSE 6379/tcp
    
(9) VOLUME

说明数据挂载目录,希望将宿主机目录挂载到容器中,但是不声明也可以挂载,所以该指令仅仅是给镜像使用者查看使用。

  • 语法

    VOLUME ["/data","/opt/data","/var/logs"]               
    
  • 说明

    • 目录必须存在,不存在则声明失败。
    • 一般不需要在Dockerfile中写明,且在Kubernetes场景几乎没用
  • 案例

    FROM centos:7
    LABEL name="反清复明" age="18" desc="这是一段image描述"
    COPY C.txt /opt/cpdir/
    COPY dir/* /opt/cpdir/dir/
    ADD dir/* /opt/adddir/dir/
    ADD https://www.cnblogs.com/azulearncode/p/14043606.html /opt/adddir/
    ADD ./jdk-8u291-linux-x64.tar.gz /opt/adddir/dir/
    ENV PATH=$PATH:/opt/adddir/dir/jdk1.8.0_291/bin
    ENV JAVA_HOME=/opt/adddir/dir/jdk1.8.0_291
    WORKDIR ${JAVA_HOME}
    RUN ["java","-version"]
    RUN echo "哈哈" && echo $(date)
    RUN ["/bin/sh","-c","echo $HOME"]
    EXPOSE 80/udp
    EXPOSE 6379/tcp
    VOLUME ["/opt/data","/var/log"]               
    
(10) ENTRYPOINT和CMD

为容器设定,启动容器时,默认执行一次的命令,主要用于指定启动容器的前台进程,例如:redis容器启动默认执行:redis-server

  • 语法

    • ENTRYPOINT语法
    # 语法,exec形式 --推荐
    ENTRYPOINT ["命令","param1","param2"]
    
    • CMD语法
    # 语法1,exec形式--推荐
    CMD ["executable","param1","param2"]
    
    # 语法2,还是exec形式,不过仅设置参数,结合entrypoint使用。--推荐
    CMD ["param1","param2"]
    
  • 说明

    • 一个Dockerfile中可以有多个ENTRYPOINT或者CMD,但只有最后一个生效
    • CMD如果结合entrypoint使用,通常用来指定参数(ENTRYPOINT 负责命令以及不可变参数,CMD 负责可变参数),且参数可以被docker run 镜像后面的命令替换CMD的参数。
    • ENTRYPOINT主要用于服务器程序启动命令。
  • 案例

    FROM centos:7
    LABEL name="反清复明" age="18" desc="这是一段image描述"
    COPY C.txt /opt/cpdir/
    COPY dir/* /opt/cpdir/dir/
    ADD dir/* /opt/adddir/dir/
    ADD https://www.cnblogs.com/azulearncode/p/14043606.html /opt/adddir/
    # ADD ./jdk-8u291-linux-x64.tar.gz /opt/adddir/dir/
    # ENV PATH=$PATH:/opt/adddir/dir/jdk1.8.0_291/bin
    # ENV JAVA_HOME=/opt/adddir/dir/jdk1.8.0_291
    # WORKDIR ${JAVA_HOME}
    # RUN ["java","-version"]
    RUN echo "哈哈" && echo $(date)
    RUN ["/bin/sh","-c","echo $HOME"]
    EXPOSE 80/udp
    EXPOSE 6379/tcp
    VOLUME ["/opt/data","/var/log"]
    
    ENTRYPOINT [ "ping","-c","5"]
    CMD [ "www.baidu.com" ]
    
  • 测试

    替换cmd参数
    [root@localhost docker]# docker run --name c8 -d centos7:0.1 www.sohu.com
    
    

3. 案例

java程序开发了java项目,文件:app.jar,将部署jdk环境的镜像中。

启动java项目:java -jar app.jar --spring.config.location=application.properties

  • (1) 启动mysql容器

    docker run --name app-mysql -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=admins mysql:5.7
    
  • (2) 编写springboot项目dockerfile

    # 基础jdk
    FROM openjdk:8-jre
    
    # 设置workdir,路径设置为app.jar所在路径
    WORKDIR ${app_path}
    
    # 端口暴露
    EXPOSE 8080/tcp
    
    # 拷贝项目相关文件到 /opt/app/
    ENV app_path=/opt/app/
    COPY application.properties ${app_path}
    COPY app.jar ${app_path}
    
    
    
    # 容器启动,启动app.jar
    ENTRYPOINT ["java","-jar","app.jar"]
    CMD ["--spring.config.location=application.properties"]
    
    
    

    注意:1. workdir放在前面,2. entrypoint存放不变命令,cmd存放可变参数

    例如:

    • application-dev.properties:开发配置文件。
    • application-test.properties:测试配置文件
    • application.properties:上线配置文件
  • (3) 构建镜像

    docker build --no-cache -t app-server:0.1 -f dockerfile .
    
  • (4) 启动容器

    docker run ...
    

三 Harbor私服

1. 场景

? 在实际生产运维中,往往需要把镜像发布到几十、上百台或更多的节点上。这时单台Docker主机上镜像已无法满足,项目越来越多,镜像就越来越多,都放到一台Docker主机上是不行的。需要一个仓库统一管理镜像。

2. 引言

Harbor英文港口的意思,Docker镜像是一个鲸鱼拖着集装箱,寓意:用来管理停靠 Docker镜像

Habor是由VMWare公司开源的容器镜像仓库Registry(Docker-Hub)。 Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,由VMware开源。

3. 功能

(1) 基于角色访问控制

? 在企业中,通常有不同的开发团队负责不同的项目,镜像像代码一样,每个人角色不同需求也不同,因此就需要访问权限控制,根据角色分配相应的权限。

? 例如,开发人员需要对项目构建这就用到读写权限(push/pull),测试人员只需要读权限(pull),运维一般管理镜像仓库,具备权限分配能力,项目经理具有所有权限。

(2) 图形化界面

? 用户可以通过浏览器查看、检索当前Docker镜像仓库,并可进行管理项目和命名空间的操作;

(3) 镜像删除和空间回收

? Harbor支持在Web删除镜像,回收无用的镜像,释放磁盘空间。

(4) 安全审计

? 所有针对镜像仓库的操作都可以被记录追溯,用于审计管理;

(5) REST API

? 可以通过java代码实现内部功能管理。完整的API,方便与外部集成。

(6) 部署简单

? harbor安装部署简单。

4. 安装要求

(1) 硬件要求

资源最小要求推荐配置
CPU2 CPU4 CPU
Mem4 GB8 GB
Disk40 GB160 GB

(2) 软件要求

软件版本号
docker17.06.0 及以上
docker-compose1.18.0 及以上
openssl

(3) 网络端口要求

端口协议描述
443httpshttps端口,可以从配置文件中修改
4443https当notary打开时使用,否则不需要使用,可以通过配置文件修改
80httphttp端口,可以从配置文件中修改

5. 安装

(1) 安装docker

(2) 安装docker-compose

1. 安装扩展yum源
yum install -y epel-release
yum makecache fast
2. 安装docker-compose
yum install -y docker-compose

3. 验证docker-compose
[root@localhost ~]# docker-compose -v
docker-compose version 1.18.0, build 8dd22a9

(3) 离线安装解压harbor

tar zxvf harbor-offline-installer-v2.5.3.tgz -C /opt/installs/

(4) 修改配置 harbor.yml

前提:将harbor.yml.tmpl文件改为harbor.yml

(5) 初始化配置

1. 修改harbor的域名或者ip
hostname: 192.168.127.100


2. 网络连接harbor使用http协议端口
http:
  port: 99
  
3. 如果不使用https,注释掉
# https:
#   # https port for harbor, default is 443
#   port: 443
#   # The path of cert and key files for nginx
#   certificate: /your/certificate/path
#   private_key: /your/private/key/path


4. 登录harbor的超级管理员密码
harbor_admin_password: *******

(6) 安装

./install.sh

(7) 检验

查看所有harbor程序

docker-compose ps

(8) 故障处理

如果有容器的状态不是up运行状态,查看harbor日志

/var/log/harbor

(9) 访问

1. 地址
http://harbor的ip:99
2. 超级管理员登录
用户名:admin
密码:配置的密码

6. docker绑定

(1) 修改/etc/docker/daemon.json

{
  "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"],
  "insecure-registries": ["192.168.199.51:88"] /*harbor的ip:端口*/
}

(2) 重启docker引擎

systemctl daemon-reload
systemctl restart docker

(3) 使用docker-compose重启harbor所有容器

注意:必须在harbor解压文件夹下面,docker-compose.yml文件位置。执行命令。

1. 关闭
docker-compose down -v
2. 启动
docker-compose up -d

7. 项目和角色

登录harbor操作

在这里插入图片描述
在这里插入图片描述

8. push推送镜像

假设有app-server和mysql两个镜像,属于cms项目,推送镜像成品。

(1) 给镜像打上tag(harbor)

命令:`docker tag 镜像名:tag harbor的ip:端口/项目名/镜像名:tag` 

```shell
1. 给app-server:1.0打标签

2. 给mysql:5.7打标签

(2) 登录私服

命令:docker login harbor的ip:端口

[root@localhost harbor]# docker login 192.168.127.100:99
Username: admin
Password:

(3) 推送镜像

命令:docker push 带harbor前缀的镜像:tag

1. 推送app-server
[root@localhost harbor]# docker push 192.168.127.100:99/cms/app-server:1.0

2. 推送mysql
[root@localhost harbor]# docker push 192.168.127.100:99/cms/mysql:5.7-1

9. pull拉取镜像

docker pull 192.168.127.100:99/cms/mysql:5.7-1
文章来源:https://blog.csdn.net/weixin_52198548/article/details/135377231
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。