Docker入门实战教程-动力哥

Docker引擎的安装

安装Docker需要的依赖gcc gcc-c++

yum -y install gcc
yum -y install gcc-c++

因为我之前已经安装了,所以现在提示"Nothing to do"

[root@localhost ~]# yum -y install gcc
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
Package gcc-4.8.5-44.el7.x86_64 already installed and latest version
Nothing to do

[root@localhost ~]# yum -y install gcc-c++
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
Package gcc-c++-4.8.5-44.el7.x86_64 already installed and latest version
Nothing to do

非root用户需要使用sudo提权

sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装Docker

sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

查看docker版本

docker version
[root@localhost ~]# docker version
Client: Docker Engine - Community
 Version:           26.0.0
 API version:       1.45
 Go version:        go1.21.8
 Git commit:        2ae903e
 Built:             Wed Mar 20 15:21:09 2024
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          26.0.0
  API version:      1.45 (minimum version 1.24)
  Go version:       go1.21.8
  Git commit:       8b79278
  Built:            Wed Mar 20 15:20:06 2024
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.28
  GitCommit:        ae07eda36dd25f8a1b98dfbf587313b99c0190bb
 runc:
  Version:          1.1.12
  GitCommit:        v1.1.12-0-g51d5e94
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

运行hello-world

docker run hello-world
[root@localhost ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c1ec31eb5944: Pull complete 
Digest: sha256:53641cd209a4fecfc68e21a99871ce8c6920b2e7502df0a20671c6fccc73a7c6
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

Docker比vm虚拟机快

为什么Docker会比vm虚拟机快

1.docker有着比虚拟机更少的抽象层
  由于docker不需要Hypervisor(虚拟机)实现硬件资源虚拟化,
  运行在docker容器上的程序直接使用的都是实际物理机的硬件资源,因此在cpu、内存利用率上docker将会在效率上有明显优势。
  
2.docker利用的是宿主机的内核,而不是需要加载操作系统os内核
  当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。

Docker常用命令

在这里插入图片描述

Docker启动管理命令

systemctl start docker
systemctl stop docker
systemctl status docker
systemctl restart docker
systemctl enable docker
docker info
docker --help
docker command(具体命令) --help

镜像命令

docker images

docker images  #列出本地主机上的镜像
[root@localhost ~]# docker images
REPOSITORY(表示镜像的仓库源)    TAG(镜像的标签版本号)       IMAGE ID(镜像ID)       CREATED(镜像创建时间)         SIZE(镜像大小)
hello-world                  latest                    d2c94e258dcb           11 months ago               13.3kB

docker search

docker search 镜像名称

docker search redis
[root@localhost ~]# docker search redis
NAME                                DESCRIPTION                                     STARS     OFFICIAL
redis                               Redis is an open source key-value store that…   12764     [OK]
redislabs/redisearch                Redis With the RedisSearch module pre-loaded…   63        
redislabs/redisinsight              RedisInsight - The GUI for Redis                101       
redis/redis-stack-server            redis-stack-server installs a Redis server w…   72        
redis/redis-stack                   redis-stack installs a Redis server with add…   103       
redislabs/rebloom                   A probablistic datatypes module for Redis       27        
redislabs/redis                     Clustered in-memory database engine compatib…   40 
......

name        镜像名称
DESCRIPTION 镜像说明
STATRS      点赞数量
OFFICIAL    是否官方认证

docker search --limit 5 redis #搜索前五名

docker pull

下载镜像

docker pull 镜像名字[:TAG]  #没有TAG就是最新版

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

docker system df

查看镜像/容器/数据卷所占的空间
在这里插入图片描述

docker rmi

删除镜像

docker rmi -f 镜像ID                  #删除单个
docker rmi -f 镜像名1:TAG 镜像名2:TAG  #删除多个
docker rmi -f$(docker images -qa)    #删除全部

在这里插入图片描述

docker rm

删除下图中NAMES为redis的容器
在这里插入图片描述

 docker rm redis

在这里插入图片描述

容器命令

[root@localhost ~]# docker run --help

Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Create and run a new container from an image
Aliases:
  docker container run, docker run

Options:
  -i, --interactive                      Keep STDIN open even if not attached
  -t, --tty                              Allocate a pseudo-TTY
  -d, --detach                           Run container in background and print container ID

redis前台交互式启动

前台启动很容易被意外终止,窗口一关就没了

docker run -it redis:6.0.8

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

redis后台守护进程启动

docker run -d redis:6.0.8

在这里插入图片描述
查看容器内运行的进程
在这里插入图片描述

Nginx容器运行

在这里插入图片描述
保存拉取好的nginx镜像
在这里插入图片描述
删除nginx镜像,通过上一步保存好的nginx.tar包再将nginx加载回来
在这里插入图片描述
在这里插入图片描述
创建nginx容器

docker run -d --name nginx -p 80:80 nginx
[root@localhost ~]# docker run -d --name nginx -p 80:80 nginx
c37c23e22fcb0001e16f0da7e4d23f7787673f1e222e788826ea843c55d26437

在这里插入图片描述

[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED              STATUS              PORTS                               NAMES
c37c23e22fcb   nginx     "/docker-entrypoint.…"   About a minute ago   Up About a minute   0.0.0.0:80->80/tcp, :::80->80/tcp   nginx

停掉nginx容器

docker stop nginx

在这里插入图片描述
在这里插入图片描述
启动nginx容器

docker start nginx

在这里插入图片描述
在这里插入图片描述
查看nginx日志

docker logs nginx

docker logs -f nginx    #持续刷新日志

进入nginx容器内部

docker exec -it nginx bash

在这里插入图片描述

ubuntu交互式运行

当我们直接使用docker run(不加任何参数)运行某个容器,使用ps命令查看容器状态时,STATUS显示的是‘Exited’,表示已经退出了。当我们希望有交互式的命令输入时,需要使用到‘-it’参数
在这里插入图片描述

docker run -it --name myubuntu2 ubuntu /bin/bash

交互式时,容器的状态是’Up’
在这里插入图片描述

tomcat交互式运行

docker run --name mytomcat2 -it tomcat:8.5.49

当运行完以上命令后,以下为截取的部分tomcat启动运行日志,可以看到tomcat启动成功了。

[root@localhost ~]# docker run --name mytomcat2 -it tomcat:8.5.49
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/local/openjdk-8
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
.......
ProtocolHandler ["http-nio-8080"]
11-Apr-2024 07:33:02.042 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
11-Apr-2024 07:33:02.058 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 571 ms

查看容器状态时,可以看到COMMAND为“catalina.sh run”, 此命令可以参考tomcat的Dockerfile
在这里插入图片描述
在这里插入图片描述

既然tomcat都启动成功了,那tomcat就可以访问了吗,此时我们访问下这个主机的8080端口试一下,
在这里插入图片描述
哦NO,汤姆小猫并没有出来,此时你需要对外暴露访问端口。

对外暴露访问端口

专用术语称之为端口映射,将宿主机的8080端口映射为8081,也就是对外我们访问8081端口就等于访问宿主机的8080端口。

docker run --name mytomcat3 -it -p 8081:8080 tomcat:8.5.49
  -p, --publish list    Publish a container's port(s) to the host
  # -p参数用于指定发布端口
[root@localhost ~]# docker run --name mytomcat3 -it -p 8081:8080 tomcat:8.5.49
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/local/openjdk-8
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
11-Apr-2024 07:45:24.267 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name:   Apache Tomcat/8.5.49
11-Apr-2024 07:45:24.269 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Nov 17 2019 18:45:30 UTC
11-Apr-2024 07:45:24.269 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 8.5.49.0
11-Apr-2024 07:45:24.269 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux
11-Apr-2024 07:45:24.269 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version:            3.10.0-1160.el7.x86_64
11-Apr-2024 07:45:24.270 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture:          amd64
11-Apr-2024 07:45:24.270 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home:             /usr/local/openjdk-8/jre
11-Apr-2024 07:45:24.270 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version:           1.8.0_232-b09
11-Apr-2024 07:45:24.270 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor:            Oracle Corporation
11-Apr-2024 07:45:24.270 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:         /usr/local/tomcat
11-Apr-2024 07:45:24.270 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:         /usr/local/tomcat
......

11-Apr-2024 07:45:24.990 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/manager] has finished in [16] ms
11-Apr-2024 07:45:24.998 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
11-Apr-2024 07:45:25.009 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
11-Apr-2024 07:45:25.013 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 594 ms

在这里插入图片描述

此时我们访问8081端口:
在这里插入图片描述
噢耶,Tomcat小猫咪出来了。

Dockerfile

Dockerfile 是用于构建 Docker 镜像的脚本文件,由一系列指令构成。通过 docker build命令构建镜像时,Dockerfile 中的指令会由上而下依次执行,每条指令都将会构建出一个镜像,这就是镜像的分层。因此指令越多,层次就越多,创建的镜像就越多,效率就越低。所以在定义 Dockerfile 时,能用一个指令完成的动作就不要分为两条。

对于 Dockerfile 的指令,需要注意以下几点:
 指令是大小写不敏感的,但惯例是写为全大写。
 指令后至少会携带一个参数。
 "#"号开头的为注释行
FROM:指定基础镜像
 【语法】FROM <image>[:<tag>]
 【解析】用于指定基础镜像,且必须是第一条指令;若省略了tag,则默认为 latest。
LABEL:指定镜像元数据
 【语法】LABEL <key>=<value> <key>=<value> „„
 【解析】LABEL 指令中可以以键值对的方式包含任意镜像的元数据信息,用于替代MAINTAINER 指令。
      通过 docker inspect 可查看到 LABEL 与 MAINTAINER 的内容。
ENV:设置环境变量
 【语法1】ENV <key> <value>
 【解析】用于指定环境变量,这些环境变量,后续可以被 RUN 指令使用,容器运行起来之后,也可以在容器中获取这些环境变量。

 【语法2】ENV <key1>=<value1> <key2>=<value2> ...
 【解析】可以设置多个变量,每个变量为一对<key>=<value>指定。
COPY:复制文本
 【说明】功能与 ADD 指令相同,只不过 src 不能是 URL。若 src 为压缩文件,复制到容器后不会自动解压。
ADD:复制和解包文件
 【语法 1】ADD <src> <dest>
 【语法 2】ADD ["<src>", "<dest>"] # 路径中存在空格时使用双引号引起来
 【解析】该指令将复制当前宿主机中指定文件 src 到容器中的指定目录 dest 中。src 可以是宿主机中的绝对路径,也可以时相对路径。
        但相对路径是相对于 docker build 命令所指定的路径的。src 指定的文件可以是一个压缩文件,压缩文件复制到容器后会自动解为  目录; 
        src 也可以是一个 URL,此时的 ADD 指令相当于 wget 命令;
        src 最好不要是目录,其会将该目录中所有内容复制到容器的指定目录中。
        dest 是一个绝对路径,其最后面的路径必须要加上斜杠,否则系统会将最后的目录名称当做是文件名的。
WORKDIR:指定工作目录
 【语法】WORKDIR path
 【解析】容器打开后默认进入的目录,一般在后续的 RUN、CMD、ENTRYPOINT、ADD 等指令中会引用该目录。
       可以设置多个 WORKDIR 指令。后续 WORKDIR 指令若用的是相对路径,
       则会基于之前 WORKDIR 指令指定的路径。
       在使用 docker run 运行容器时,可以通过-w 参数覆盖构建时所设置的工作目录。
RUN:执行shell命令
 【语法1】RUN <command>
 【解析】这里的<command>就是 shell 命令。docker build 执行过程中,会使用 shell 运行指定的 command。
 
 【语法2】RUN ["EXECUTABLE","PARAM1","PARAM2", ...]
 【解析】在 docker build 执行过程中,会调用第一个参数"EXECUTABLE"指定的应用程序运行,
       并使用后面第二、三等参数作为应用程序的运行参数。
CMD: 容器启动命令
 【语法1】CMD ["EXECUTABLE","PARAM1","PARAM2", ...]
 【解析】在容器启动后,即在执行完 docker run 后会立即调用执行"EXECUTABLE"指定的可执行文件,并使用后面第二、第三...等参数作为应用程序的运行参数。
 
 【语法 2】CMD command param1 param2, ...
 【解析】这里的 command 就是 shell 命令。在容器启动后会立即运行指定的 shell 命令。
 
 【语法 3】CMD ["PARAM1","PARAM2", ...]
 【解析】提供给 ENTERYPOINT 的默认参数。

run和cmd的区别:run是构建镜像时的命令,而cmd测试启动容器时的命令
在这里插入图片描述

ENTRYPOINT:入口点,功能类似于CMD,配置容器启动后执行的命令以及参数
 【语法1】ENTRYPOINT ["EXECUTABLE","PARAM1","PARAM2", ...]
 【解析】在容器启动过程中,即在执行 docker run 时,会调用执行"EXECUTABLE"指定的应用程序,并使用后面第二、第三...等参数作为应用程序的运行参数。
 
 【语法2】ENTRYPOINT command param1 param2, ...
 【解析】这里的 command 就是 shell 命令。在容器启动过程中,即在执行 docker run 时,会运行指定的 shell 命令。
EXPOSE: 暴露端口
 【语法】EXPOSE <port> [<port>...]
 【解析】指定容器准备对外暴露的端口号,但该端口号并不会真正的对外暴露。若要真正暴露,则需要在执行 docker run 命令时使用-p(小 p)来指定说要真正暴露出的端口号。
ONBUILD:子镜像引用父镜像的指令
 【语法】ONBUILD [INSTRUCTION] 
 【解析】该指令用于指定当前镜像的子镜像进行构建时要执行的指令。
VOLUME
 【语法】VOLUME ["dir1", "dir2", ...]
 【解析】在容器创建可以挂载的数据卷。

Docker网络模型

为了实现同一个宿主机以及跨宿主机的容器之间网络互联,Docker网络支持5种网络模式

1.none
2.bride
3.host
4.container
5.network-name

查看Docker默认的网络模式有三个

 docker network ls

在这里插入图片描述

网络模式指定

默认新建的容器使用Bridge模式,创建容器时,docker run命令使用以下选项指定网络模式格式

docker run --network <mode>
docker run --net=<mode>

<mode>: 可以是以下值
bridge
container:<容器名或容器ID>
host
none
docker run --network #再按两下Tab键
bridge      container:  host        ipvlan      macvlan     none        null        overlay 

在这里插入图片描述

bridge网络模式

bridge网络模式概念
  1.bridge模式是docker默认的网络模式,即不指定任何模式就是bridge模式,也是使用比较多的模式;
  2.此模式创建的容器会为每一个容器分配自己的网络ip等信息,并将容器连接到一个虚拟网桥与外界通信;
  3.可以和外部网络之间进行通信,通过SNAT访问外网,使用DNAT可以让容器被外部主机访问,所以此模式也称为NAT模式。
bridge网络模式特点
  1.网络资源隔离:不同宿主机的容器无法直接通信,各自使用独立网络;
  2.无需手动配置:容器默认自动获取172.17.0.0/16的ip地址,此地址可以修改;
  3.可访问外网:利用宿主机的物理网卡,SNAT连接外网;
  4.外部主机无法直接访问容器:可以通过配置DNAT接受外网的访问;
  5.性能较低:因为需要通过NAT网络转换,所以会带来更多的损耗;
  6.端口管理繁琐:每个容器必须手动指定唯一的端口,容易产生端口冲突。

查看bridge模式信息

root@docker:~# docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "700fc2656609bcbb19b0565c759eed7368e3d29d1f9b02f78a0701a653312431",
        "Created": "2024-05-28T01:33:04.396608546Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "c0f5460d0bb5d3ea015707c612f1a903083e0b1da7fd9093d33f282cb4215899": {
                "Name": "wordpress",
                "EndpointID": "38ed58998c8c76f70c10059967cbc4be891799f36a254b5355c62fd026e27e22",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

Host模式

Host模式概念
  1.如果指定host模式启动容器,那么新创建的容器不会创建自己的虚拟网卡,而是直接使用宿主机的网卡和IP地址,
  2.因此在容器里面查看到的IP信息就是宿主机的信息,
  3.访问容器的时候直接使用宿主机IP+容器端口即可,
  4.不过容器内除网络以外的其他资源,如:文件系统,系统进程等仍然和宿主机保持隔离。
Host模式特点
  1.使用参数-network host指定
  2.共享宿主机网络
  3.网络性能无损耗
  4.网络故障排除相对简单
  5.个容器网络无隔离
  6.网络字段无法分别统计
  7.端口管理困难,容易产生端口冲突
  8.不支持端口映射

发布自己的应用

发布一个Java的hello world

@RestController()
public class HelloWorld {

    @GetMapping("/hello")
     public String hello(){
        System.out.println("++++++++++Java: Hello Dockerfile+++++++++++++");
         return "Java: hello world Dockerfile";
     }
}

编写完成后,打包成jar包(HelloDocker.jar)上传到linux上的某个目录下
在这里插入图片描述
编写Dockerfile

FROM openjdk:8u102
LABEL auth="leilei" email="2369005098@qq.com" version="1.0"
COPY HelloDocker.jar HelloJava.jar
ENTRYPOINT ["java","-jar","HelloJava.jar"]
EXPOSE 8080

构建镜像
在这里插入图片描述

运行镜像,对外暴露9003端口

[root@localhost java]# docker run --name hello -dp 9003:8080 hello-jave:1.1
6b0d0439511e085faa34ef24515406602b89cc3e7e260570f9c8f4b9d25dbdf4

在这里插入图片描述
进入到容器里面查看
在这里插入图片描述
查看容器日志
在这里插入图片描述
浏览器访问我暴露出的9003端口
在这里插入图片描述
ok,java的hello world的小应用程序就以docker容器的方式运行成功了。

Mysql和Redis的Docker安装

Mysql

可以参考docker-hub的官方安装命令docker-hub-mysql
在这里插入图片描述

docker run --name mysql -dp 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7

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

Mysql生成安装

为了保证数据的安全性,在生产环境下安装的 mysql 容器,在启动时都会使用数据卷来持久化数据。

docker run --name mysql \
-e MYSQL_ROOT_PASSWORD=root \
-v /root/mysql/data:/var/lib/mysql \
-v /root/mysql/log:/var/log/mysql \
-v /root/mysql/conf:/etc/mysql/conf.d \
-dp 3306:3306 \
mysql:5.7

在这里插入图片描述

MySQL集群安装

安装master容器

第一步:启动master容器,指定数据卷路径

docker run --name mysql_master \
-e MYSQL_ROOT_PASSWORD=root \
-v /root/mysql_master/data:/var/lib/mysql \
-v /root/mysql_master/log:/var/log/mysql \
-v /root/mysql_master/conf:/etc/mysql/conf.d \
-dp 3316:3306 \
mysql:5.7

第二步: 新建 my.cnf

[client]
default_character_set=utf8

[mysql]
default_character_set=utf8

[mysqld]
character_set_server=utf8

server_id=01
binlog-ignore-db=mysql
log-bin=master-log-bin
binlog_cache_size=1M
binlog_format=mixed
expire_logs_days=7
slave_skip_errors=1062

第三部:创建用户

mysql> create user 'slave'@'%' identified by '123456';
Query OK, 0 rows affected (0.00 sec)

第四步:给用户赋予权限

mysql> grant replication slave,replication client on *.* to 'slave'@'%';
Query OK, 0 rows affected (0.01 sec)

第五步:查看该用户权限

mysql> show grants for 'slave'@'%';
+-------------------------------------------------------------------+
| Grants for slave@%                                                |
+-------------------------------------------------------------------+
| GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%' |
+-------------------------------------------------------------------+
1 row in set (0.00 sec)

安装slave容器

第一步:启动slave容器,指定数据卷路径

docker run --name mysql_slave \
-e MYSQL_ROOT_PASSWORD=root \
-v /root/mysql_slave/data:/var/lib/mysql \
-v /root/mysql_slave/log:/var/log/mysql \
-v /root/mysql_slave/conf:/etc/mysql/conf.d \
-dp 3326:3306 \
mysql:5.7

第二步:新建my.cnf

[client]
default_character_set=utf8

[mysql]
default_character_set=utf8

[mysqld]
character_set_server=utf8

server_id=02
binlog-ignore-db=mysql
log-bin=slave-log-bin
binlog_cache_size=1M
binlog_format=mixed
expire_logs_days=7
slave_skip_errors=1062
relay_log=relay-log-bin
log_slave_updates=1
read_only=1

第三部:进入容器连接mysql

[root@localhost conf]# docker exec -it mysql_slave /bin/bash
bash-4.2# mysql -uroot -p 
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.44-log MySQL Community Server (GPL)

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

配置主从复制

1.查看master状态

mysql> show master status;
+-----------------------+----------+--------------+------------------+-------------------+
| File                  | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-----------------------+----------+--------------+------------------+-------------------+
| master-log-bin.000001 |      617 |              | mysql            |                   |
+-----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

2.slave 指定 master
在 slave 中通过运行 change master to 命令来指定其要连接的 master 相关信息。

mysql> change master to master_host='10.0.0.226',master_user='slave',master_password='123456',master_port=3316,master_log_file='master-log-bin.000001',master_log_pos=617,master_connect_retry=30,master_retry_count=3;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 10.0.0.226
                  Master_User: slave
                  Master_Port: 3316
                Connect_Retry: 30
              Master_Log_File: master-log-bin.000001
          Read_Master_Log_Pos: 617
               Relay_Log_File: relay-log-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: master-log-bin.000001
             Slave_IO_Running: No
            Slave_SQL_Running: No
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 617
              Relay_Log_Space: 154
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 0
                  Master_UUID: 
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: 
           Master_Retry_Count: 3
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
1 row in set (0.00 sec)
ERROR: 
No query specified

3.开启slave

start slave;

在这里插入图片描述
此时master和slave已经完成了主从复制,在master上新建一个数据库和数据表已经即时同步到slave上了。

再次验证主从是否读写分离,master可以读写数据,slave只能读数据。
验证slave节点上能否插入数据
在这里插入图片描述
查看master上是否有slave插入的数据。master上自然不会有Tony这条数据。
在这里插入图片描述
问题所在
slave上可以写数据,因为我们在配置文件中设置的是slave用户的只读权限,而slave节点上我们用的是root用户登录的。此时我们可以设置super用户为只读权限则slave节点就不能插入数据了。

mysql> set global super_read_only=1;
Query OK, 0 rows affected (0.00 sec)

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

Redis

单机安装Redis

docker run --name myredis \
-v /root/redis/redis.conf:/etc/redis/redis.conf \
-v /root/redis/data:/data \
-dp 6379:6379 \
redis:7.0 \
redis-server /etc/redis/redis.conf

在这里插入图片描述
在这里插入图片描述
进入redis容器
在这里插入图片描述

Redis一主两从集群搭建

现要搭建一个“一主两从”的 Redis 集群。这三个容器的端口号都保持默认,但对外暴露出的端口号分别为 6381、6382、6383。其中,6381 的为 master,另外两个为 slave。

1.复制三份 redis.conf
在两个slave的redis.conf上加上两个如下配置

slave-announce-ip ip地址
slave-announce-port 端口号

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

2.启动master容器

docker run --name myredis-1 \
-v /root/redis/redis1.conf:/etc/redis/redis.conf \
-v /root/redis/data/6381:/data \
-dp 6381:6379 \
redis:7.0 \
redis-server /etc/redis/redis.conf

在这里插入图片描述

启动slave容器
myredis-2

docker run --name myredis-2 \
-v /root/redis/redis2.conf:/etc/redis/redis.conf \
-v /root/redis/data/6382:/data \
-dp 6382:6379 \
redis:7.0 \
redis-server /etc/redis/redis.conf --slaveof 10.0.0.227 6381

在这里插入图片描述
myredis-3

docker run --name myredis-3 \
-v /root/redis/redis3.conf:/etc/redis/redis.conf \
-v /root/redis/data/6383:/data \
-dp 6383:6379 \
redis:7.0 \
redis-server /etc/redis/redis.conf --slaveof 10.0.0.227 6381

在这里插入图片描述
查看主从关系
master节点上
在这里插入图片描述
slave节点上
在这里插入图片描述
验证主从是否同步,在master上set一个值之后,两个slave节点可以直接get到
在这里插入图片描述

Redis 高可用集群搭建

主从集群存在的问题是,其容灾方式只能采用冷处理方案,无法在生产中使用。所以这里要搭建一个“一主两从三哨兵”的高可用集群,以达到热处理的容灾方案。

对于“一主两从”集群,仍使用前面的即可。下面直接搭建三个 Sentinel 节点的集群。
这三个容器的端口号都保持默认,但对外暴露出的端口号分别为 26381、26382、26383。

1.复制三份 sentinel.conf
复制 sentinel.conf 文件并重命名为 sentinel1.conf。
仅修改两处:

1.指定其要监视的 master 及<quorum>2.指定当前 sentinel 对外宣布的 IP 与端口号。其中 IP 为 docker 宿主机的 IP,端口号为其对外暴露的端口号。

2.启动 sentinel
2.1启动mysentinel-1

docker run --name mysentinel-1 \
-v /root/redis/sentinel1.conf:/etc/redis/sentinel.conf \
-dp 26381:26379 \
redis:7.0 \
redis-sentinel /etc/redis/sentinel.conf

在这里插入图片描述
2.2启动mysentinel-2

docker run --name mysentinel-2 \
-v /root/redis/sentinel2.conf:/etc/redis/sentinel.conf \
-dp 26382:26379 \
redis:7.0 \
redis-sentinel /etc/redis/sentinel.conf

在这里插入图片描述

2.3启动mysentinel-3

docker run --name mysentinel-3 \
-v /root/redis/sentinel3.conf:/etc/redis/sentinel.conf \
-dp 26383:26379 \
redis:7.0 \
redis-sentinel /etc/redis/sentinel.conf

在这里插入图片描述
关系查看
在这里插入图片描述
以上命令的查看结果说明 sentinel 对 master 的监视成功,说明高可用集群搭建成功。连
接任何一个 sentinel 容器节点查看到的信息与上面的都是相同的。
在这里插入图片描述

故障转移测试

为了验证高可用性,现将充当 master 的容器 myredis-1 停掉。

此时,再查看另外两个 redis 容器的状态数据,发现 myredis-2 成为了 myredis-3 的 slave,
在这里插入图片描述
myredis-3 成为了新的 master

在这里插入图片描述
此时再次启动myredis-1时,发现它成了myredis-3的slave节点
在这里插入图片描述
在这里插入图片描述

Docker compose

安装Docker compose

curl -SL https://github.com/docker/compose/releases/download/v2.26.1/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose

在这里插入图片描述
赋予docker-compose执行权限
在这里插入图片描述

chmod +x /usr/local/bin/docker-compose

手工启动项目的步骤

现有java项目ssrm,windows本地运行结果如下
在这里插入图片描述
将项目在windows下使用到的mysql和redis全部转换成linux下的服务,10.0.0.227为我虚拟机的ip,此台机器上安装了mysql3306和redis6379
在这里插入图片描述
1.构建镜像
将项目打包成ssrm.jar,编写Dockerfile将其构建成finance:1.0镜像.
在这里插入图片描述

在这里插入图片描述
2.运行镜像
因为本java项目需要mysql和redis环境,所以我们最先运行了mysql和redis容器,此时我们先后手动启动了三个容器。我对外暴露9000的访问端口。
在这里插入图片描述
3.访问项目
在这里插入图片描述
项目已经基于容器的方式运行成功了。redis中也是有数据写入的。
在这里插入图片描述
访问日志也是正常的
在这里插入图片描述

手工启动项目的弊端

手工启动项目不仅繁琐易错,而且还存在一个致命问题:当前应用访问的 mysql 与 redis只能是运行在当前 Docker 宿主机之上的,否则将无法访问到它们。因为在应用的配置文件中已经将 mysql 与 redis 的 IP 进行了硬编码。而使用 Docker Compose 可以解决所有问题

Compose 编排启动项目

1.定义 compose.yml

services:
  app:
    build: ./
    container_name: myapp
    ports:
      - 9001:8080
    volumes:
      - ./logs:/var/applogs
    depends_on:
      - mysql
      - redis

  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
    ports:
      - 3306:3306
    volumes:
      - /root/mysql/log:/var/log/mysql
      - /root/mysql/data:/var/log/mysql
      - /root/mysql/conf:/etc/mysql/conf.d

  redis:
    image: redis:7.0
    ports:
      - 6379:6379
    volumes:
      - /root/redis/redis.conf:/etc/redis/redis.conf
      - /root/redis/data:/data
    command: redis-server /etc/redis/redis.conf

修改application.yml配置文件
将 mysql 与 redis 的主机名修改为它们相应服务的名称。
在这里插入图片描述
之后重新打包上传
在这里插入图片描述

2.启动所有容器

docker-compose up -d

在这里插入图片描述
访问应用
Docker compose已经成功将项目运行起来了。
在这里插入图片描述
在这里插入图片描述
错误排查,可能会遇到端口占用的情况
在这里插入图片描述

指定各组件名称

compose2.yml

services:
  app:
    build: ./
    image: finance:3.0
    container_name: myapp
    ports:
      - 9001:8080
    volumes:
      - ./logs:/var/applogs
    networks:
      - ab
    depends_on:
      - leimysql
      - leiredis

  leimysql:
    image: mysql:5.7
    container_name: lmysql
    environment:
      MYSQL_ROOT_PASSWORD: root
    ports:
      - 3306:3306
    volumes:
      - /root/mysql/log:/var/log/mysql
      - /root/mysql/data:/var/log/mysql
      - /root/mysql/conf:/etc/mysql/conf.d
    networks:
      - ab

  leiredis:
    image: redis:7.0
    container_name: lredis
    ports:
      - 6379:6379
    volumes:
      - /root/redis/redis.conf:/etc/redis/redis.conf
      - /root/redis/data:/data
    networks:
      - ab
    command: redis-server /etc/redis/redis.conf

networks:
  ab:

因为指定了的各个组件的别名redis别名为leiredis,mysql别名为leimysql,所以java程序需要修改相应的服务名后重新打包
在这里插入图片描述

docker-compose -f compose2.yml up -d

在这里插入图片描述
指定自定义的服务名后,程序访问仍然是正常的
在这里插入图片描述

Docker网络

docker network inspect finance_ab
[root@localhost finance]# docker network inspect finance_ab
[
    {
        "Name": "finance_ab",
        "Id": "468e5c3d0b3bc73ff5060c5db8929a0ee2f5fef8a51051d682d92e073de6eb5e",
        "Created": "2024-05-08T11:51:34.792743101+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.19.0.0/16",
                    "Gateway": "172.19.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "29d4052b7322b7a3e3eb06702566ff06376656a0c884fc9ec6b5fc8c7644fb0b": {
                "Name": "lmysql",
                "EndpointID": "f25454ba1da32168c709c7853d582a5cd6b5b1c9afd6894d375c1ded5c2581ab",
                "MacAddress": "02:42:ac:13:00:03",
                "IPv4Address": "172.19.0.3/16",
                "IPv6Address": ""
            },
            "4732bdaaa453065cee1eade619381f5baff9e63d8ce75d8abde5cf15c70596d2": {
                "Name": "lredis",
                "EndpointID": "c4da3f083e4e4f980b8ac96375cd29559c4fe52363ef6d936481a89f0d839332",
                "MacAddress": "02:42:ac:13:00:02",
                "IPv4Address": "172.19.0.2/16",
                "IPv6Address": ""
            },
            "60f6dead3dbca7a7e30eeb72d9b06c20d3f1bc6aaabf73d33d87bd2418f45ba0": {
                "Name": "myapp",
                "EndpointID": "05459a3e0349be81c79232a770683e27fbaedcf26fae046ed674116e6ea8967e",
                "MacAddress": "02:42:ac:13:00:04",
                "IPv4Address": "172.19.0.4/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "ab",
            "com.docker.compose.project": "finance",
            "com.docker.compose.version": "2.26.1"
        }
    }
]

Docker管理监控平台

DockerUI

docker run -d -p 7000:9000 -v /var/run/docker.sock:/var/run/docker.sock uifd/ui-for-docker

在这里插入图片描述
访问管理页面
在这里插入图片描述

Portainer

Portainer安装文档

Portainer可以管理集群,

docker volume create portainer_data

在这里插入图片描述

docker run -d -p 8000:8000 -p 9443:9443 -p 7100:9000 \
--name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:latest

在这里插入图片描述
访问portainer管理页面:ip+端口号(10.0.0.227:7100)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Harbor镜像中心

安装Harbor

 wget https://github.com/goharbor/harbor/releases/download/v2.7.1/harbor-offline-installer-v2.7.1.tgz

访问Harbor镜像管理中心,配置文件里默认80端口
在这里插入图片描述
在这里插入图片描述

Harbor的高可用

Harbor高可用实现方案
   1.两台Harbor主机,一台nginx主机,
   2.两台Harbor主机相互同步,nginx主机做负载均衡,使用户无感知切换两台Harbor主机。

Harbor安装脚本来自马哥教育王晓春老师
此脚本我在Ubuntu20.04上执行成功了,在RockyLinx8.5中执行失败

#!/bin/bash
#
#********************************************************************
#Author:            wangxiaochun
#Date:              2020-02-04
#FileName:          install_harbor.sh
#URL:               http://www.wangxiaochun.com
#Description:       The test script
#Copyright (C):     2020 All rights reserved
#********************************************************************

DOCKER_VERSION="20.10.10"
UBUNTU_DOCKER_VERSION="5:${DOCKER_VERSION}~3-0~`lsb_release -si`-`lsb_release -cs`"
DOCKER_COMPOSE_VERSION=2.6.1
#DOCKER_COMPOSE_VERSION=1.29.2
DOCKER_COMPOSE_FILE=docker-compose-Linux-x86_64
HARBOR_VERSION=2.5.2
HARBOR_BASE=/apps
HARBOR_NAME=harbor.magedu.org
#HARBOR_NAME=`hostname -I|awk '{print $1}'`
HARBOR_IP=`hostname -I|awk '{print $1}'`
HARBOR_ADMIN_PASSWORD=123456

COLOR_SUCCESS="echo -e \\033[1;32m"
COLOR_FAILURE="echo -e \\033[1;31m"
END="\033[m"

. /etc/os-release

color () {
    RES_COL=60
    MOVE_TO_COL="echo -en \\033[${RES_COL}G"
    SETCOLOR_SUCCESS="echo -en \\033[1;32m"
    SETCOLOR_FAILURE="echo -en \\033[1;31m"
    SETCOLOR_WARNING="echo -en \\033[1;33m"
    SETCOLOR_NORMAL="echo -en \E[0m"
    echo -n "$1" && $MOVE_TO_COL
    echo -n "["
    if [ $2 = "success" -o $2 = "0" ] ;then
        ${SETCOLOR_SUCCESS}
        echo -n $"  OK  "    
    elif [ $2 = "failure" -o $2 = "1"  ] ;then 
        ${SETCOLOR_FAILURE}
        echo -n $"FAILED"
    else
        ${SETCOLOR_WARNING}
        echo -n $"WARNING"
    fi
    ${SETCOLOR_NORMAL}
    echo -n "]"
    echo 
}


install_docker(){
    if [ $ID = "centos" -o $ID = "rocky" ];then
        if [ $VERSION_ID = "7" ];then
            cat >  /etc/yum.repos.d/docker.repo  <<EOF
[docker]
name=docker
gpgcheck=0
#baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/x86_64/stable/
EOF
        else     
            cat >  /etc/yum.repos.d/docker.repo  <<EOF
[docker]
name=docker
gpgcheck=0
#baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/8/x86_64/stable/
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/8/x86_64/stable/
EOF
        fi
	    yum clean all 
        ${COLOR_FAILURE} "Docker有以下版本"${END}
        yum list docker-ce --showduplicates
        ${COLOR_FAILURE}"5秒后即将安装: docker-"${DOCKER_VERSION}" 版本....."${END}
        ${COLOR_FAILURE}"如果想安装其它Docker版本,请按ctrl+c键退出,修改版本再执行"${END}
        sleep 5
        yum -y install docker-ce-$DOCKER_VERSION docker-ce-cli-$DOCKER_VERSION  \
            || { color "Base,Extras的yum源失败,请检查yum源配置" 1;exit; }
    else
	    dpkg -s docker-ce &> /dev/null && $COLOR"Docker已安装,退出" 1 && exit
        apt update || { color "更新包索引失败" 1 ; exit 1; }  
        apt  -y install apt-transport-https ca-certificates curl software-properties-common || \
            { color "安装相关包失败" 1 ; exit 2;  }  
        curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
        add-apt-repository "deb [arch=amd64] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
        apt update
        ${COLOR_FAILURE} "Docker有以下版本"${END}
        apt-cache madison docker-ce
        ${COLOR_FAILURE}"5秒后即将安装: docker-"${UBUNTU_DOCKER_VERSION}" 版本....."${END}
        ${COLOR_FAILURE}"如果想安装其它Docker版本,请按ctrl+c键退出,修改版本再执行"${END}
        sleep 5
        apt -y  install docker-ce=${UBUNTU_DOCKER_VERSION} docker-ce-cli=${UBUNTU_DOCKER_VERSION}
    fi
    if [ $? -eq 0 ];then
        color "安装软件包成功"  0
    else
        color "安装软件包失败,请检查网络配置" 1
        exit
    fi
        
    mkdir -p /etc/docker
    tee /etc/docker/daemon.json <<-'EOF'
{
	  "registry-mirrors": ["https://si7y70hh.mirror.aliyuncs.com"],
	  "insecure-registries":["harbor.magedu.org:80"]
}
EOF
    systemctl daemon-reload
    systemctl enable docker
    systemctl restart docker
    docker version && color "Docker 安装成功" 0 ||  color "Docker 安装失败" 1
	echo 'alias rmi="docker images -qa|xargs docker rmi -f"' >> ~/.bashrc
	echo 'alias rmc="docker ps -qa|xargs docker rm -f"' >> ~/.bashrc
}



install_docker_compose(){
    if [ $ID = "centos" -o $ID = "rocky" ];then
        ${COLOR_SUCCESS}"开始安装 Docker compose....."${END}
        sleep 1
        if [ ! -e  ${DOCKER_COMPOSE_FILE} ];then
            #curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/${DOCKER_COMPOSE_FILE} -o /usr/bin/docker-compose
            curl -L https://get.daocloud.io/docker/compose/releases/download/v${DOCKER_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m) -o /usr/bin/docker-compose
        else
            mv ${DOCKER_COMPOSE_FILE} /usr/bin/docker-compose
        fi
        chmod +x /usr/bin/docker-compose
    else 
        apt -y install docker-compose
    fi
    if docker-compose --version ;then
        ${COLOR_SUCCESS}"Docker Compose 安装完成"${END} 
    else
        ${COLOR_FAILURE}"Docker compose 安装失败"${END}
        exit
    fi
}

install_harbor(){
    ${COLOR_SUCCESS}"开始安装 Harbor....."${END}
    sleep 1
    if  [ ! -e  harbor-offline-installer-v${HARBOR_VERSION}.tgz ] ;then
        wget https://github.com/goharbor/harbor/releases/download/v${HARBOR_VERSION}/harbor-offline-installer-v${HARBOR_VERSION}.tgz || ${COLOR_FAILURE} "下载失败!" ${END}
    fi
    [ -d ${HARBOR_BASE} ] ||  mkdir ${HARBOR_BASE}
    tar xvf harbor-offline-installer-v${HARBOR_VERSION}.tgz  -C ${HARBOR_BASE}
    cd ${HARBOR_BASE}/harbor
    cp harbor.yml.tmpl harbor.yml
    sed -ri "/^hostname/s/reg.mydomain.com/${HARBOR_NAME}/" harbor.yml
    sed -ri "/^https/s/(https:)/#\1/" harbor.yml
    sed -ri "s/(port: 443)/#\1/" harbor.yml
    sed -ri "/certificate:/s/(.*)/#\1/" harbor.yml
    sed -ri "/private_key:/s/(.*)/#\1/" harbor.yml
    sed -ri "s/Harbor12345/${HARBOR_ADMIN_PASSWORD}/" harbor.yml
    sed -i 's#^data_volume: /data#data_volume: /data/harbor#' harbor.yml
    #mkdir -p /data/harbor
    ${HARBOR_BASE}/harbor/install.sh && ${COLOR_SUCCESS}"Harbor 安装完成"${END} ||  ${COLOR_FAILURE}"Harbor 安装失败"${END}
    cat > /lib/systemd/system/harbor.service <<EOF
[Unit]
Description=Harbor
After=docker.service systemd-networkd.service systemd-resolved.service
Requires=docker.service
Documentation=http://github.com/vmware/harbor

[Service]
Type=simple
Restart=on-failure
RestartSec=5
ExecStart=/usr/bin/docker-compose -f  ${HARBOR_BASE}/harbor/docker-compose.yml up
ExecStop=/usr/bin/docker-compose -f ${HARBOR_BASE}/harbor/docker-compose.yml down

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload 
systemctl enable  harbor &>/dev/null ||  ${COLOR}"Harbor已配置为开机自动启动"${END}
    if [ $?  -eq 0 ];then  
        echo 
        color "Harbor安装完成!" 0
        echo "-------------------------------------------------------------------"
        echo -e "请访问链接: \E[32;1mhttp://${HARBOR_IP}/\E[0m" 
		echo -e "用户和密码: \E[32;1madmin/${HARBOR_ADMIN_PASSWORD}\E[0m" 
    else
        color "Harbor安装失败!" 1
        exit
    fi 
}

docker info  &> /dev/null  && ${COLOR_FAILURE}"Docker已安装"${END} || install_docker

docker-compose --version &> /dev/null && ${COLOR_FAILURE}"Docker Compose已安装"${END} || install_docker_compose

install_harbor

两台主机之间怎么拷贝文件
在这里插入图片描述
root用户可以直接执行普通lei用户下的文件
在这里插入图片描述
脚本执行完了,docker,docker-compose,harbor都安装好了
在这里插入图片描述

  • 21
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值