公司内部管理项目涉及到的所有docker镜像,会使用私有仓库的方式,集中管理。
登录阿里云创建私有仓库
对仓库进行配置
创建命名空间
通常一个项目,包含了多个镜像,为了方便管理,将多个同属于一个项目的所有镜像放在一个命名空间中。
命名规范:公司名_项目名
创建镜像仓库
一个仓库管理一个镜像的多个版本,一个镜像的多个版本。
命名规范:服务名_v1.0:tag
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
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. 测试验证
自定义构建镜像,如果使用docker commit,优缺点
- ① commit打包过程,对操作者不可见,不知道内部打包了什么,做了什么,有什么问题。
- ② 所有容器的改动,需要手工操作,不具备可复制性,不具备自动化,不具备规模性。
一种脚本语言,用来描述Docker镜像构建过程,也就是一个说明书,Docker通过dockerfile构建出来一个自定义镜像。
通过使用Dockerfile,开发人员可以通过简单的文本文件定义和管理镜像的构建过程,实现自动化、可重复和可管理的镜像构建。
自动化构建:
通过编写Dockerfile,可以自动构建Docker镜像,而无需手动逐步执行构建步骤。Docker根据Dockerfile中的指令顺序执行构建步骤,从而实现自动化构建过程。
效率高,便于管理,便于和其他平台集成。
版本控制:
Dockerfile本身是一个文本文件,通过对Dockerfile内容版本控制,也就实现了Image镜像的版本控制管理。
指令 | 作用 |
---|---|
FROM | 基础镜像,从这个镜像开始制作 |
LABEL | 描述,描述镜像的信息:作者、文字描述、日期、要求数据卷路径 (没有任何docker构建的作用,仅仅给工作人员看的 ) |
maintainer | 描述信息,写作者信息。作用类似label。逐渐被废弃。 |
RUN | 在构建镜像的时候,执行一些命令的。 |
ADD | 向镜像中拷贝文件 |
COPY | 向镜像中拷贝文件 |
VOLUME | 数据卷目录,指定镜像中的那个目录,作为日后数据卷挂载目录。(不写也能挂载,给工作人看的 ) |
EXPOSE | 暴露开放容器端口 |
ENV | 定义环境变量 |
WORKDIR | 工作目录,就是exec进入容器,默认初始位置。 |
ONBUILD | 当构建一个被继承 Dcokerfile 这个时候就会触发运行ONBUILD命令–了解。 |
CMD | 在容器启动的时候,会执行的命令。 |
entrypoint | 在容器启动的时候,会执行的命令,例如:redis镜像,一定有redis-server ./redis.conf |
构建一个自定义的tomcat镜像,基于tomcat:8.5构建。
例如:dockerfile/tomcat/dockerfile-tomcat-1.0
注意:dockerfile到一定要放在一个单独的目录中。
命令:
touch dockerfile-tomcat-1.0
# 基础镜像
FROM tomcat:8.5
# 描述
LABEL name="yangdd@zparkhr.com.cn"
LABEL desc="这是一个dockerfile构建的tomcat镜像"
1. 语法
docker build -t 镜像名:tag -f dockerfile的文件名 .
2. 命令
docker build -t my-tomcat:1.0 -f dockerfile-tomcat-1.0 .
查看镜像信息
docker inspect 镜像名:tag
基础镜像,本次docker镜像的构建基于From镜像基础之上进行操作。
语法
FROM <image>:<tag>
说明
FROM
必须是Dockerfile文件的第一行指令。镜像描述信息,描述镜像的信息:作者、文字描述、日期、要求数据卷路径,(没有任何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相同会被覆盖从主机(执行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/
类似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/
设置镜像中的环境变量,这个变量可以在镜像中直接使用,也可以给会在镜像中执行的命令使用,后续的dockerfile指令使用。
语法
# 一次设置一个
ENV <key>=<value>
# 一次设置多个
ENV <key>=<value> <key1>=<value1> <key2>=<value2> .....
$key
${key}
说明
案例
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
指定创建容器后,终端进入容器后的默认路径,后续的RUN、CMD、ENTRYPOINT、COPY、ADD涉及到的路径,均以此目录作为当前目录。
WORKDIR /opt/centos
说明
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}
构建**
镜像
**过程中,需要执行的命令,可以用来安装依赖,初始化脚本执行等。
语法
# 语法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
指令指定的命令是否可以执行取决于 基础镜像中是否允许执行该命令。&&
或 \
连接多个命令exec
形式,必须使用"“,且第一个命令必须独立是一个命令,后面可以是参数,每个参数独立放在一个”"中。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"]
为镜像设置日后启动容器暴露的端口。
语法
EXPOSE <port>
EXPOSE <port>/<protocol>
EXPOSE 80
EXPOSE 80/tcp
EXPOSE 2379/udp
说明
<port>
:端口号<protocol>
:协议类型,默认TCP协议,tcp/udp/给镜像使用者看的
。案例
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 ["/data","/opt/data","/var/logs"]
说明
案例
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"]
为容器设定,启动容器时,默认执行一次的命令,主要用于指定启动容器的前台进程,例如:redis容器启动默认执行:
redis-server
语法
# 语法,exec形式 --推荐
ENTRYPOINT ["命令","param1","param2"]
# 语法1,exec形式--推荐
CMD ["executable","param1","param2"]
# 语法2,还是exec形式,不过仅设置参数,结合entrypoint使用。--推荐
CMD ["param1","param2"]
说明
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
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存放可变参数
例如:
(3) 构建镜像
docker build --no-cache -t app-server:0.1 -f dockerfile .
(4) 启动容器
docker run ...
? 在实际生产运维中,往往需要把镜像发布到几十、上百台或更多的节点上。这时单台Docker主机上镜像已无法满足,项目越来越多,镜像就越来越多,都放到一台Docker主机上是不行的。需要一个仓库统一管理镜像。
Harbor英文港口的意思,Docker镜像是一个鲸鱼拖着集装箱,寓意:用来管理停靠 Docker镜像
Habor是由VMWare公司开源的容器镜像仓库Registry(Docker-Hub)。 Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,由VMware开源。
? 在企业中,通常有不同的开发团队负责不同的项目,镜像像代码一样,每个人角色不同需求也不同,因此就需要访问权限控制,根据角色分配相应的权限。
? 例如,开发人员需要对项目构建这就用到读写权限(push/pull),测试人员只需要读权限(pull),运维一般管理镜像仓库,具备权限分配能力,项目经理具有所有权限。
? 用户可以通过浏览器查看、检索当前Docker镜像仓库,并可进行管理项目和命名空间的操作;
? Harbor支持在Web删除镜像,回收无用的镜像,释放磁盘空间。
? 所有针对镜像仓库的操作都可以被记录追溯,用于审计管理;
? 可以通过java代码实现内部功能管理。完整的API,方便与外部集成。
? harbor安装部署简单。
(1) 硬件要求
资源 | 最小要求 | 推荐配置 |
---|---|---|
CPU | 2 CPU | 4 CPU |
Mem | 4 GB | 8 GB |
Disk | 40 GB | 160 GB |
(2) 软件要求
软件 | 版本号 |
---|---|
docker | 17.06.0 及以上 |
docker-compose | 1.18.0 及以上 |
openssl |
(3) 网络端口要求
端口 | 协议 | 描述 |
---|---|---|
443 | https | https端口,可以从配置文件中修改 |
4443 | https | 当notary打开时使用,否则不需要使用,可以通过配置文件修改 |
80 | http | http端口,可以从配置文件中修改 |
(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
密码:配置的密码
(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
登录harbor操作
假设有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
docker pull 192.168.127.100:99/cms/mysql:5.7-1