https://www.bilibili.com/video/BV1LQ4y127n4?p=43&spm_id_from=pageDriver
https://www.bilibili.com/video/BV1LQ4y127n4?p=44&spm_id_from=pageDriver
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine \
docker-ce
yum install -y yum-utils
# 或者
yum install -y yum-utils \
device-mapper-persistent-data \
lvm2 --skip-broken
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 更新 yum 软件源缓存
yum makecache fast
yum install -y docker-ce
# 关闭防火墙
systemctl stop firewalld
# 禁止开机去懂
systemctl disable firewalld
# 启动docker
systemctl enable docker
systemctl start docker
systemctl stop docker
systemctl restart docker
# 查看版本
docker -v
live-restore": true可以去掉
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://kfwkfulq.mirror.aliyuncs.com",
"https://2lqq34jg.mirror.aliyuncs.com",
"https://pee6w651.mirror.aliyuncs.com",
"https://registry.docker-cn.com",
"http://hub-mirror.c.163.com",
"https://registry.docker-cn.com"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
docker run hello-world
参考:https://www.cnblogs.com/lwhzj/p/16551039.html
镜像相关命令
docker save --help
docker save -o nginx.tar nginx:latest
docker rmi nginx:latest
docker load -i nginx.tar
访问:官网查看使用命令
# 运行一个容器
docker run --name nginx -p 80:80 -d nginx
# 查看容器是否运行成功
docker ps
# 查看日志
docker logs nginx
命令解读
docker logs nginx
docker logs -f nginx
docker logs -t -f -tail=100 edevp-app
说明:
docker exec -it nginx bash
docker exec -it nginx /bin/bash
# SpringBoot工程
docker exec -it java-app /bin/sh
先通过官方文档查看nginx的容器目录
Hosting some simple static content
Alternatively, a simple Dockerfile can be used to generate a new image that includes the necessary content (which is a much cleaner solution than the bind mount above):
FROM nginx
COPY static-html-directory /usr/share/nginx/html
先通过exec进入容器,然后进入nginx的html对应目录
# 进入html目录
cd /usr/share/nginx/html
# 查看内容
cat index.html
修改内容把"Welcome to nginx"替换为"欢迎您"
方法一:vi
vi index.html
方法二:sed
sed -i 's#Welcome to nginx#欢迎您#g' index.html
sed -i 's###g' index.html
exit
docker stop nginx
docker start nginx
# 查看在运行的
docker ps
# 查看所有,包含停止的
docker ps -a
docker rm nginx
# 强制删除
docker rm -f nginx
docker exec -it redis redis-cli
–link可以通过容器名互相通信,容器间共享环境变量。
–link主要用来解决两个容器通过ip地址连接时容器ip地址会变的问题.
1.当新建一个容器时,如果没有显示指定其使用的网络,那么默认会使用bridge网络
2.当一个容器link到另一个容器时,该容器可以通过IP或容器名称访问被link的容器(此时类似于加入相同网络join net),而被link容器可以通过IP访问该容器,但是无法通过容器名称访问
3.当被link的容器被删除时,创建link的容器也无法正常使用
4.如果两个容器被加入到我们手动创建的网络时,那么该网络内的容器相互直接可以通过IP和名称同时访问。
例如:
–link参数连接到了rmqnamesrv容器,并使用了别名namesrv,因此后面再rmqconsole容器中,可以使用namesrv:9876访问rmqnamesrv
docker run -d \
--name rmqconsole \
--net=mynet \
-p 8180:8080 \
--link rmqnamesrv:namesrv \
-v /etc/localtime:/etc/localtime \
-v /etc/timezone:/etc/timezone \
-e "JAVA_OPTS=-Drocketmq.namesrv.addr=namesrv:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false" \
-t styletang/rocketmq-console-ng
-v /etc/localtime:/etc/localtime \
-v /etc/timezone:/etc/timezone \
示例
docker run -e VAR1=value1 --env VAR2=value2 ubuntu
docker run --env VAR1=value1 --env VAR2=value2 ubuntu
You can also use variables that you’ve exported to your local environment:
export VAR1=value1
export VAR2=value2
$ docker run --env VAR1 --env VAR2 ubuntu env | grep VAR
VAR1=value1
VAR2=value2
使用文件作为环境变量,.env 文件如下:
# This is a comment
VAR1=value1
VAR2=value2
USER # which takes the value from the local environment
运行示例:
docker run --env-file .env ubuntu
docker inspect <CONTAINER-NAME> OR <CONTAINER-ID>
如下映射
config:192.168.1.191
registry:192.168.1.191
rabbitmq:192.168.1.191
docker run -d -p 8989:8989 -p 8080:8080 -e HOST_IP=192.168.1.191 -e CONFIG_SERVICE_PASSWORD=${CONFIG_SERVICE_PASSWORD} --add-host config:192.168.1.191 -e CONFIG_PORT=8888 --add-host registry:192.168.1.191 -e REGISTRY_PORT=8761 --add-host rabbitmq:192.168.1.191 -e RABBITMQ_PORT=5672 --name=monitoring monitoring
# 创建容器时指定
docker run --restart-always
# 已经启动的容器 docker update --restart=always 容器名
docker update --restart=always kafka-ui
容器和数据耦合的问题
数据卷是一个虚拟目录,指向宿主机文件系统中的某个目录
数据卷的作用:
将容器与数据分离,解耦合,方便操作容器内数据,保证数据安全
docker volume [COMMAND]
docker volume命令是数据卷操作,根据命令后跟随的command来确定下一步的操作:
需求:创建一个数据卷,并查看数据卷在宿主机的目录位置
docker volume create html
docker volume ls
DRIVER VOLUME NAME
local de0fd3925a75374dc53808ef97fff74d2a9b2baaf6294244a28a7cc724bdf176
local f820bf9079ac57b3c8f289d693beeaf4f504be7895cdf6bf361f007a1eaea133
local html
docker volume inspect html
#可以看到,我们创建的html这个数据卷关联的宿主机目录为/var/lib/docker/volumes/html/_data目录。
[
{
"CreatedAt": "2022-04-05T14:14:53+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/html/_data",
"Name": "html",
"Options": {},
"Scope": "local"
}
]
# 删除未使用的数据卷
docker volume prune
# 删除指定数据卷
docker volume rm html
我们在创建容器时,可以通过 -v 参数来挂载一个数据卷到某个容器内目录,命令格式如下:
docker run \
--name mn \
-v html:/root/html \
-p 8080:80
nginx \
这里的-v就是挂载数据卷的命令:
① 创建容器并挂载数据卷到容器内的HTML目录
docker run --name mn -v html:/usr/share/nginx/html -p 80:80 -d nginx
② 进入html数据卷所在位置,并修改HTML内容
# 查看html数据卷的位置
docker volume inspect html
# 进入该目录
cd /var/lib/docker/volumes/html/_data
# 修改文件
vi index.html
容器不仅仅可以挂载数据卷,也可以直接挂载到宿主机目录上。关联关系如下:
带数据卷模式:宿主机目录 --> 数据卷 —> 容器内目录
直接挂载模式:宿主机目录 —> 容器内目录
语法:
目录挂载与数据卷挂载的语法是类似的:
-v [宿主机目录]:[容器内目录]
-v [宿主机文件]:[容器内文件]
实现思路如下:
1)在将课前资料中的mysql.tar文件上传到虚拟机,通过load命令加载为镜像
2)创建目录/tmp/mysql/data
3)创建目录/tmp/mysql/conf,将课前资料提供的hmy.cnf文件上传到/tmp/mysql/conf
4)去DockerHub查阅资料,创建并运行MySQL容器,要求:
① 挂载/tmp/mysql/data到mysql容器内数据存储目录
② 挂载/tmp/mysql/conf/hmy.cnf到mysql容器的配置文件
③ 设置MySQL密码
#创建容器
docker run \
#容器名称自定义为mysql
--name mysql \
#mysql root密码设置为:654321
-e MYSQL_ROOT_PASSWORD=654321 \
#端口映射
-p 3307:3306
#宿主机的/tmp/mysql/conf/hmy.cnf文件挂载到容器的/etc/mysql/conf.d/hmy.cnf文件
-v /tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf \
#宿主机的/tmp/mysql/data目录挂载到容器的/var/lib/mysql目录
-v /tmp/mysql/data:/var/lib/mysql \
#后台运行mysql镜像(版本号5.7.25)
-d mysql:5.7.25
镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成。
我们以MySQL为例,来看看镜像的组成结构:
![在这里插入图片描述](https://img-blog.csdnimg.cn/7f31bc0a35e14e88824660f499b2763a.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQmx1ZWV5ZWRib3k1MjE=,size_20,color_FFFFFF,t_70,g_se,x_16
简单来说,镜像就是在系统函数库、运行环境基础上,添加应用程序文件、配置文件、依赖文件等组合,然后编写好启动脚本打包在一起形成的文件。
我们要构建镜像,其实就是实现上述打包的过程。
构建自定义的镜像时,并不需要一个个文件去拷贝,打包。
我们只需要告诉Docker,我们的镜像的组成,需要哪些BaseImage、需要拷贝什么文件、需要安装什么依赖、启动脚本是什么,将来Docker会帮助我们构建镜像。
而描述上述信息的文件就是Dockerfile文件。
Dockerfile就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层Layer。
更新详细语法说明,请参考官网文档: https://docs.docker.com/engine/reference/builder
也可以参考:Dockerfile文件详解
需求:基于Ubuntu镜像构建一个新镜像,运行一个java项目
Dockerfile其中的内容如下:
# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录
ENV JAVA_DIR=/usr/local
# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
# 安装JDK
RUN cd $JAVA_DIR \
&& tar -xf ./jdk8.tar.gz \
&& mv ./jdk1.8.0_144 ./java8
# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin
# 暴露端口
EXPOSE 8090
# 入口,java项目的启动命令
ENTRYPOINT java -jar /tmp/app.jar
docker build -t javaweb:1.0 .
最后访问 http://192.168.150.101:8090/hello/count,其中的ip改成你的虚拟机ip
虽然我们可以基于Ubuntu基础镜像,添加任意自己需要的安装包,构建镜像,但是却比较麻烦。所以大多数情况下,我们都可以在一些安装了部分软件的基础镜像上做改造。
例如,构建java项目的镜像,可以在已经准备了JDK的基础镜像基础上构建。
需求:基于java:8-alpine镜像,将一个Java项目构建为镜像
实现思路如下:
① 新建一个空的目录,然后在目录中新建一个文件,命名为Dockerfile
② 拷贝课前资料提供的docker-demo.jar到这个目录中
③ 编写Dockerfile文件:
a )基于java:8-alpine作为基础镜像
b )将app.jar拷贝到镜像中
c )暴露端口
d )编写入口ENTRYPOINT
内容如下:
FROM java:8-alpine
COPY ./app.jar /tmp/app.jar
EXPOSE 8090
ENTRYPOINT java -jar /tmp/app.jar
# 可以指定yml文件
# ENTRYPOINT java -Dfile.encoding=utf-8 -jar /tmp/app.jar --spring.profiles.active=prod
④ 使用docker build命令构建镜像
如果不写tag则默认latest
docker build -t edevp-user:0.0.1 .
# 查看
docker images
⑤ 使用docker run创建容器并运行
docker run -d -P --name edevp-user edevp-user:0.0.1
⑥ 通过Docker run命令定义Spring Profile
可以将spring profile作为环境变量传递给docker run命令,使用 -e 标记。
例如 -e “SPRING_PROFILES_ACTIVE=dev”会将dev profile传递给Docker容器
docker run -d -p 8080:8080 -e "SPRING_PROFILES_ACTIVE=dev" --name edevp-user edevp-user:0.0.1
小结:
Dockerfile的本质是一个文件,通过指令描述镜像的构建过程
Dockerfile的第一行必须是FROM,从一个基础镜像来构建
基础镜像可以是基本操作系统,如Ubuntu。也可以是其他人制作好的镜像,例如:java:8-alpine
mkdir edevp-gateway
cd edevp-gateway
touch Dockerfile
# 拷贝之前的文件
# 上传app.jar
tar -cf edevp-gateway.tar *
官方文档
Docker-Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。 Docker-Compose将所管理的容器分为三层,分别是工程(project),服务(service)以及容器(container)。Docker-Compose运行目录下的所有文件(docker-compose.yml,extends文件或环境变量文件等)组成一个工程,若无特殊指定工程名即为当前目录名。一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像,参数,依赖。一个服务当中可包括多个容器实例,Docker-Compose并没有解决负载均衡的问题,因此需要借助其它工具实现服务发现及负载均衡。 Docker-Compose的工程配置文件默认为docker-compose.yml,可通过环境变量COMPOSE_FILE或-f参数自定义配置文件,其定义了多个有依赖关系的服务及每个服务运行的容器。 使用一个Dockerfile模板文件,可以让用户很方便的定义一个单独的应用容器。在工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个Web项目,除了Web服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。 Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。 Docker-Compose项目由Python编写,调用Docker服务提供的API来对容器进行管理。因此,只要所操作的平台支持Docker API,就可以在其上利用Compose来进行编排管理。
sudo curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
# 给docker-compose添加可执行权限
sudo chmod +x /usr/local/bin/docker-compose
curl -L https://get.daocloud.io/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
ubuntu安装
# 查看linux内核
uname -a
# 安装
apt-get install python-pip
# python3
apt-get install python3-pip
apt-get -y install docker-compose
红帽系Linux使用以下命令安装
yum -y install python-pip
yum -y install docker-compose
centos7.9安装
yum install epel-release
yum install python3-pip
pip3 install --upgrade pip
pip3 install docker-compose
这里会报错:ModuleNotFoundError: No module named 'setuptools_rust'
解决方法:pip3 install -U pip setuptools
docker-compose --version
# 查看安装的版本
docker-compose -v
# docker-compose version 1.25.0, build unknown
按照上文讲解,我们已经成功地安装完Docker Compose。但是,我们输入docker-compose 命令,按下TAB键,发现此时Compose并没有给我们该命令的提示,那么如何让命令给我们提示呢?我们需要安装Compose命令补全工具。Compose命令补全在Bash和Zsh下的安装方式不同,由于笔者是使用CentOS 7进行讲解的,而CentOS 7默认使用Bash,故而本文只讲解命令补全在Bash下的安装,其他Shell以及其他系统上的安装,请查看Docker的官方文档:https://docs.docker.com/compose/completion/
curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version --short)/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose
如果命令失败,则修改hosts
echo "199.232.68.133 raw.githubusercontent.com" >> /etc/hosts
再次尝试,发现可以正常列出docker的子命令,示例如下:
[root@docker ~]# docker (docker + 空格 + 连续按2次Tab键)
attach container engine history inspect logs port restart search stats top volume
build context events image kill network ps rm secret stop trust wait
builder cp exec images load node pull rmi service swarm unpause
commit create export import login pause push run stack system update
config diff help info logout plugin rename save start tag version
apt-get remove docker-compose
# 前台启动
docker-compose up
# 后台启动
docker-compose up -d
# -f 指定使用的 Compose 模板文件,默认为 docker-compose.yml,可以多次指定,指定多个 yml
docker-compose -f docker-compose.yml up -d
docker-compose logs
查看服务容器的输出日志。默认情况下,docker-compose
将对不同的服务输出使用不同的颜色来区分。可以通过--no-color
来关闭颜色。
# 输出日志,不同的服务输出使用不同的颜色来区分
docker-compose logs
# 跟踪日志输出
docker-compose logs -f
# 关闭颜色
docker-compose logs --no-color
docker-compose ps
列出工程中所有服务的容器。
# 列出工程中所有服务的容器
docker-compose ps
# 列出工程中指定服务的容器
docker-compose ps nginx
docker-compose run
在指定服务容器上执行一个命令。
# 在工程中指定服务的容器上执行 echo "helloworld"
docker-compose run nginx echo "helloworld"
docker-compose exec
进入服务容器。
# 进入工程中指定服务的容器
docker-compose exec nginx bash
# 当一个服务拥有多个容器时,可通过 --index 参数进入到该服务下的任何容器
docker-compose exec --index=1 nginx bash
docker-compose pause
docker-compose pause暂停服务容器
# 暂停工程中所有服务的容器
docker-compose pause
# 暂停工程中指定服务的容器
docker-compose pause nginx
docker-compose unpause
恢复服务容器。
# 在工程中指定服务的容器上执行 echo "helloworld"
docker-compose run nginx echo "helloworld"
docker-compose start
启动服务容器。
# 启动工程中所有服务的容器
docker-compose start
# 启动工程中指定服务的容器
docker-compose start nginx
docker-compose stop
停止服务容器。
# 在工程中指定服务的容器上执行 echo "helloworld"
docker-compose run nginx echo "helloworld"
docker-compose kill
docker-compose kill通过发送SIGKILL信号停止指定服务的容器。
# 通过发送 SIGKILL 信号停止工程中指定服务的容器
docker-compose kill nginx
docker-compose rm
删除服务(停止状态)容器。
# 删除所有(停止状态)服务的容器
docker-compose rm
# 先停止所有服务的容器,再删除所有服务的容器
docker-compose rm -s
# 不询问是否删除,直接删除
docker-compose rm -f
# 删除服务容器挂载的数据卷
docker-compose rm -v
# 删除工程中指定服务的容器
docker-compose rm -sv nginx
停止并删除所有服务的容器、网络、镜像、数据卷
# 停止并删除工程中所有服务的容器、网络
docker-compose stop
# 停止并删除工程中所有服务的容器、网络、镜像
docker-compose down --rmi all
# 停止并删除工程中所有服务的容器、网络、数据卷
docker-compose down -v
docker-compose images
打印服务容器所对应的镜像。
# 打印所有服务的容器所对应的镜像
docker-compose images
# 打印指定服务的容器所对应的镜像
docker-compose images nginx
docker-compose port
打印指定服务容器的某个端口所映射的宿主机端口。
docker-compose port nginx 80
docker-compose top
显示正在运行的进程。
# 显示工程中所有服务的容器正在运行的进程
docker-compose top
# 显示工程中指定服务的容器正在运行的进程
docker-compose top nginx
## 指定时区
environment:
TZ: Asia/Shanghai
```yaml
apollo-db:
image: mysql:5.7
container_name: apollo-db
environment:
TZ: Asia/Shanghai
# 五、DockerCompose部署微服务
## 1、新建文件夹
```bash
mkdir cloud-demo
cd cloud-demo
mkdir edevp-gateway edevp-order edevp-user
FROM java:8-alpine
COPY ./app.jar /tmp/app.jar
ENTRYPOINT java -jar /tmp/app.jar
spring:
application:
name: @artifactId@
profiles:
active: @profiles.active@
cloud:
nacos:
discovery: #服务注册与发现
server-addr: ${NACOS_HOST:nacos}:${NACOS_PORT:8848} #nacos地址
username: dev
password: 123456
namespace: edevp-demo #指定命名空间 可以删掉namespace不写默认public
#配置文件组成 : 通俗点 服务名称-指定环境.后缀名称 name-active.file-extension
config: #动态配置
server-addr: ${spring.cloud.nacos.discovery.server-addr} #nacos地址
username: dev
password: 123456
file-extension: yml #配置文件类型 非常重要后缀一定要一致 xxx.yml
namespace: edevp-demo #指定命名空间 可以删掉namespace不写默认public
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
可以在各自微服务的pom.xml中指定打包之后的名字
<build>
<finalName>appfinalName>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
docker network create mynet
# 或者指定网段
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
# 查看
docker network ls
# 查看自定义网络
docker network inspect mynet
方法一:命令方式
docker network connect mynet nacos
# 如果容器已创建好但是之前没有指定自己的网络,则使用下面命令修改:
docker network connect --alias mysql mynet mysql
docker network connect --alias nacos mynet nacos
docker network connect --alias redis mynet redis
方法二:portainer.io
点击某个容器进入编辑页面加入
在cloud-demo目录下新建
version: '3.2'
#networks:
# mynet:
# driver: bridge
services:
edevp-user:
# image: registry.cn-shanghai.aliyuncs.com/demo-store/demo_online:demo-usercenter-v1.0
container_name: edevp-user
build: ./edevp-user
environment:
TZ: Asia/Shanghai
# ports:
# - 8204:8204
networks:
- mynet
edevp-order:
# image: registry.cn-shanghai.aliyuncs.com/demo-store/demo_online:demo-usercenter-v1.0
container_name: edevp-order
build: ./edevp-order
environment:
TZ: Asia/Shanghai
networks:
- mynet
edevp-gateway:
container_name: edevp-gateway
build: ./edevp-gateway
environment:
TZ: Asia/Shanghai
ports:
- 8888:8888
networks:
- mynet
networks:
mynet:
external: true
注意指定自定义网络mynet,并且由于使用外部网络,所以需要设置external:true
# 在cloud-demo目录下执行
docker-compose up -d
curl http://127.0.0.1:8888/orders/1?authorization=admin
docker镜像仓库(repository)是集中存放镜像的地方。方便与后续的镜像拉取与上传,便于对镜像的集中管理。镜像仓库一般可分为Docker Hub公共中央仓库和个人或者公司使用的私有仓库,私有仓库如果是个人使用则可以直接使用docker自带的registry私有仓库,如果是企业级使用则可以搭建Harbor镜像私有仓库。
镜像仓库有公有和私有两种
公有仓库:例如官方DockerHub,国内有网易云镜像仓库,阿里云镜像仓库,DaoCloud镜像服务等
私有仓库:DockerRegistry(个人)、harbor(企业)
官网https://hub.docker.com/_/registry
docker run -d -p 5000:5000 --restart always -v registry-data:/var/lib/registry --name registry registry:2
mkdir /usr/local/docker/registry
cd /usr/local/docker/registry
touch docker-compose.yml
不指定网路
version: '3.0'
services:
registry:
image: registry
volumes:
- ./registry-data:/var/lib/registry
ui:
image: joxit/docker-registry-ui:static
ports:
- 8080:80
environment:
- REGISTRY_TITLE=图形化私有仓库
- REGISTRY_URL=http://registry:5000
depends_on:
- registry
#可以指定网络mynet,也可以去掉
version: '3.0'
services:
registry:
image: registry
volumes:
- ./registry-data:/var/lib/registry
networks:
- mynet
ui:
image: joxit/docker-registry-ui:static
ports:
- 8080:80
environment:
- REGISTRY_TITLE=图形化私有仓库
- REGISTRY_URL=http://registry:5000
depends_on:
- registry
networks:
- mynet
networks:
mynet:
external: true
依赖depends_on表示ui服务启动依赖于registry
我们私服采用的是http协议,默认不被Docker新人,所有需要做一个配置:
由于我们使用了ui图形工具,所以端口5000改为8080
# 打开要修改的文件
vim /etc/docker/daemon.json
# 加上下面这一句,这里的“your-server-ip”请换为你的服务器的外网IP地址:
{
"insecure-registries" : [ "your-server-ip:5000" ]
}
# 由于我们使用了ui图形工具,所以端口是8080
# 效果如下:
{
"registry-mirrors": [
"https://kfwkfulq.mirror.aliyuncs.com",
"https://2lqq34jg.mirror.aliyuncs.com",
"https://pee6w651.mirror.aliyuncs.com",
"https://registry.docker-cn.com",
"http://hub-mirror.c.163.com",
"https://registry.docker-cn.com"
],
"insecure-registries": ["http://192.168.0.44:8080"]
}
# 重新加载
systemctl daemon-reload
# 重启docker
systemctl restart docker
# cd /usr/local/docker/registry
docker-compose up -d
docker start registry_registry_1
docker start registry_ui_1
注意端口,如果安装了图形界面8080,则5000改为8080
# 重新tag本地镜像,
docker tag your-image-name:tagname your-server-ip:5000/your-image-name:tagname
# 示例表示把edevp-user:latest重命名为192.168.0.44:5000/edevp-user:0.0.1
docker tag edevp-user:latest 192.168.0.44:5000/edevp-user:0.0.1
# 示例nginx
docker tag nginx:latest 192.168.0.44:8080/nginx:1.0
# 推送
# 最后,开始正式上传镜像到服务端镜像仓库
docker push your-registry-server-ip:8080/your-image-name:tagname
# 示例
docker push 192.168.0.44:8080/edevp-user:0.0.1# 示例
docker push 192.168.0.44:8080/nginx:1.0
docker pull 192.168.0.44:8080/nginx:1.0
harbor意为港湾, 很贴合它的作用
github地址: https://github.com/goharbor/harbor
记得以前是在vmware下, 现在地址转到goharbor下了
官方的定义是企业级私有Registry服务器, 实际内部也是依靠docker registry
那么它与registry相比, 一定提供了很多企业级的特性, 例如:
环境准备
在安装harbor之前, 需要docker环境, 除此还需要docker-compose, 不说了
参考安装教程https://www.cnblogs.com/chinda/p/12776675.html
在github release中查看需要安装的版本, 这里我用当前最新的v1.7.5
文档中有两种安装方式: offline和online, 也就是在线和离线
下载地址:
# 1、在线安装包
$ wget https://github.com/vmware/harbor/releases/download/v2.4.2/harbor-online-installer-v2.4.2.tgz
tar xvf harbor-online-installer-v2.4.2.tgz
# 2、离线安装包
$ wget https://github.com/vmware/harbor/releases/download/v2.4.2/harbor-offline-installer-v2.4.2.tgz
$ tar xvf harbor-offline-installer-v2.4.2.tgz
解压之后的结构
root@sony-HP-Notebook:/usr/local/docker/harbor/harbor# tree
.
├── common.sh
├── harbor.v2.4.2.tar.gz
├── harbor.yml.tmpl
├── install.sh
├── LICENSE
└── prepare
0 directories, 6 files
# 备份一份配置文件
cp harbor.yml.tmpl harbor.yml
vim harbor.yml
修改如下几个位置
# 注释中也说了, 不要设置成localhost和127.0.0.1阿
hostname = hub.edevp.cn
https:
port: 443
certificate: /usr/local/docker/harbor/cert/hub.edevp.cn.crt
private_key: /usr/local/docker/harbor/cert/hub.edevp.cn.key
# 修改admin默认的登录密码
harbor_admin_password = 123456
vim /etc/hosts
# 加入如下
192.168.0.44 hub.edevp.cn
cd /usr/local/docker/harbor/cert
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=chinda/OU=chinda/CN=hub.edevp.cn" \
-key ca.key \
-out ca.crt
证书通常包含一个.crt文件和一个.key文件。
openssl genrsa -out hub.edevp.cn.key 4096
openssl req -sha512 -new \
-subj "/C=CN/ST=Beijing/L=Beijing/O=chinda/OU=chinda/CN=hub.edevp.cn" \
-key hub.edevp.cn.key \
-out hub.edevp.cn.csr
cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1=hub.edevp.cn
DNS.2=edevp
DNS.3=hub
EOF
将chinda.com`CRS和CRT文件名中的替换为Harbor主机名。
openssl x509 -req -sha512 -days 3650 \
-extfile v3.ext \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in hub.edevp.cn.csr \
-out hub.edevp.cn.crt
生成ca.crt,hub.edevp.cn.crt和hub.edevp.cn.key文件后,必须将它们提供给Harbor和Docker和重新配置使用它们的Harbor。首先创建存放他们的文件夹。
# 我们本身就在当前文件夹
# cp chinda.com.crt /data/cert/
# cp chinda.com.key /data/cert/
# chmod a+x /data/cert/
chmod a+x *
Docker守护程序将.crt文件解释为CA证书,并将.cert文件解释为客户端证书。
openssl x509 -inform PEM -in hub.edevp.cn.crt -out hub.edevp.cn.cert
mkdir /etc/docker/certs.d/hub.edevp.cn
cp hub.edevp.cn.cert /etc/docker/certs.d/hub.edevp.cn/
cp hub.edevp.cn.key /etc/docker/certs.d/hub.edevp.cn/
cp ca.crt /etc/docker/certs.d/hub.edevp.cn/
systemctl restart docker
cd /usr/local/harbor/harbor
./install.sh
https://192.168.0.44/harbor/projects
或者
https://hub.edevp.cn/harbor/projects
admin/123456
docker login https://hub.edevp.cn
# 查看执行状态。注意,要在项目下执行此命令,不然会抛出异常
docker-compose ps
# 停止/移除存在的实例
docker-compose down -v
# 重启harbor
docker-compose up -d
# 在项目中标记镜像:
docker tag SOURCE_IMAGE[:TAG] chinda.com/library/IMAGE[:TAG]
# 示例
docker tag nginx:latest hub.edevp.cn/library/nginx:1.0
# 推送镜像到当前项目:
docker push chinda.com/library/IMAGE[:TAG]
docker push hub.edevp.cn/library/nginx:1.0
[root@harbor harbor]# docker login https://chinda.com
Authenticating with existing credentials...
Login did not succeed, error: Error response from daemon: login attempt to https://chinda.com/v2/ failed with status: 401 Unauthorized
Username (admin): admin
Password:
Error response from daemon: login attempt to https://chinda.com/v2/ failed with status: 401 Unauthorized
解决方案
docker-compose down -v
docker-compose up -d