docker原意为“码头工人”,可能会用到集装箱,而docker相当于it行业的集装箱,使用go语言开发实现的。(go语言09年)
Docker是一个容器引擎。是一个管理容器的软件。(镜像->容器)(相当于 程序->进程之间的关系)
Docker 并非时一个通用的容器工具,它依赖于已存在并运行的Linux内核环境;
Docker实质上是在已运行的Linux下制造了一个隔离的文件环境,因此它执行的速率几乎等同于所部署的Linux主机;因此,Docker 必须部署在Linux内核的系统上,如果其他系统想部署Docker就必须安装一个虚拟的Linux环境。
轻量级;需要什么环境配置什么环境;
Docker是基于Go语言实现的云开源项目;
Docker的主要目标是“build,ship,and run any app,anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个web应用或数据库应用等等)及其运行环境能够做到“一次镜像,处处运行”;
解决了运行环境和配置问题的软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术。
虚拟机
虚拟机就是带环境安装的一种解决方案;它可以在一种操作系统里面运行另一种操作系统,比如windows10系统里面运行linux 系统CentOS7.应用程序对此毫无感知,因为虚拟机看上去和真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。
虚拟机缺点:1.资源占用多;2.冗余步骤多;3.启动慢
1.更快速的应用交付和部署
2.更便捷的升级和扩容缩容
3.更简单的系统运维
4.更高效的计算资源利用
应用容器运行后,生产环境运行的应用可与开发、测试环境的应用高度一致,容器会将应用程序相关的环境和状态完全封装起来,不会因为底层基础架构和操作系统的不一致性给应用带来影响,产生新的bug;当出现程序异常时,也可以通过测试环境的相同容器进行快速定位和修复;
可以理解为“精简版”的虚拟机(虚拟机---虚拟环境)。但是和传统虚拟机是有较大差别的。他们都属于虚拟化技术。
为了更充分使用物理主机的硬件资源,而产生的一种技术,可以在物理主机上使用多个操作系统,在相对独立的空间环境运行更多的应用程序或服务。
一台真实的电脑
虚拟机:虚拟机的运行需要依赖虚拟硬件,必须要安装系统才能运行软件。
虚拟硬件和虚拟系统会占用和浪费大量资源。
容器:是运行在容器引擎上,会直接共享真机的操作系统内核运行,可以节省大量的资源。
特性 | 容器 | 虚拟机 |
---|---|---|
启动 | 秒级 | 分钟级 |
硬盘使用 | 一般为 MB | 一般为 GB |
性能 | 接近原生(接近真机) | 弱于 |
系统支持量 | 单机支持上千个容器 | 一般几十个 |
1.占用资源少
2.容器几乎可以在所有平台上运行
Centos6.5+
Ubuntu 14.04+ Ubuntu 16.04+ Ubuntu 18.04+ Ubuntu 20.04+ LTS
Windows 10/Server
3.使用镜像部署很方便,也很高效;一条命令足以安装配置一个项目;
C/S 架构 (客户端/服务端) 这种架构例如 Mysql,Redis,
docker命令是客户端
docker daemon 后台程序,守护进程
containers 被docker daemon管理的容器,用于运行应用
images 镜像(本地镜像和远程镜像),用于生成可运行的容器。
Registry 注册中心(远程仓库),用于镜像的下载
公共:开源镜像(个人或公司上传的),所以普人可以免费使用
私有:公司或个人的闭源镜像
无状态的服务:nginx tomcat httpd php
有状态的服务: mysql,数据卷技术将数据保留在本地
安装社区版
阿里云镜像站Centos7镜像:
https://mirrors.aliyun.com/repo/Centos-7.repo
安装步骤:
# 安装依赖 [root@zuolaoshi ~]# yum install -y yum-utils device-mapper-persistent-data lvm2 # 下载Docker官方yum源 [root@zuolaoshi ~]# wget https://download.docker.com/linux/centos/docker-ce.repo -P /etc/yum.repos.d/ # 替换成清华源 [root@zuolaoshi ~]# sed -i 's#download.docker.com#mirrors.tuna.tsinghua.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo
1.2 从阿里云官方获取Centos7镜像
cd /etc/yum.repos.d
wget https://mirrors.aliyun.com/repo/Centos-7.repo
yum update 系统更新
运行 yum makecache 生成缓存
yum makecache
查看更换的阿里云镜像的仓库是否生效。
yum clean all
yum repolist
[root@zuolaoshi ~]# yum -y install https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/x86_64/stable/Packages/containerd.io-1.6.31-3.1.el7.x86_64.rpm [root@zuolaoshi ~]# yum -y install docker-ce
[root@zuolaoshi ~]# systemctl enable docker Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service. [root@zuolaoshi ~]# systemctl start docker
[root@zuolaoshi ~]# systemctl status docker
[root@zuolaoshi ~]# docker -v docker -v Docker version 26.0.1, build d260a54
# 1、关闭docker [root@zuolaoshi ~]# systemctl stop docker # 2、修改docker启动方式,要求加载配置文件启动 [root@zuolaoshi ~]# sed -i.bak '/^ExecStart=/c\ExecStart=\/usr\/bin\/dockerd' /usr/lib/systemd/system/docker.service # 3、设置docker配置文件,默认没有 # 设置允许监听地址和端口,以及sock文件连接 # 默认是使用sock方式连接,加tcp://0.0.0.0:2375可实现远程管理 [root@zuolaoshi ~]# vim /etc/docker/daemon.json { "hosts": ["tcp://0.0.0.0:2375","unix:///var/run/docker.sock"] } 4、重载docker服务、重启docker生效配置 [root@zuolaoshi ~]# systemctl daemon-reload [root@zuolaoshi ~]# systemctl restart docker 5、查看docker的监听地址和端口 [root@zuolaoshi ~]# netstat -ntpl |grep 2375 tcp6 0 0 :::2375 :::* LISTEN 21219/dockerd 6、客户端连接docker daemon,执行命令 [root@zuolaoshi ~]# docker -H 192.168.8.50 images
1.关防火墙,关沙盒
2.安装必要系统工具
yum install -y yum-utils device-mapper-persistent-data lvm2
3.echo $? 查看一下是否成功
4.添加阿里云docker镜像
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
5.查看是否成功了
ls /etc/yum.repos.d/查看是否有docker-ce.repo,有的话就是成功了
6.更新yum缓存
yum clean all
yum makecache
7.yum安装docker
yum -y install docker-ce
8.启动docker,并设置开机自动启动
systemctl start docker
systemctl enable docker
9.确认docker安装成功
docker version
systemctl status docker
10.下载nginx镜像
docker pull nginx
# 二进制安装方式 wget http://192.168.3.200/Software/docker-20.10.21.tgz tar -zxf docker-20.10.21.tgz cp docker/* /usr/bin/ # 编辑service文件 cat > /usr/lib/systemd/system/docker.service << EOF [Unit] Description=Docker Application Container Engine Documentation=https://docs.docker.com After=network-online.target firewalld.service Wants=network-online.target [Service] Type=notify ExecStart=/usr/bin/dockerd ExecReload=/bin/kill -s HUP $MAINPID LimitNOFILE=infinity LimitNPROC=infinity LimitCORE=infinity asksMax=infinity TimeoutStartSec=0 Delegate=yes KillMode=process Restart=on-failure StartLimitBurst=3 StartLimitInterval=60s [Install] WantedBy=multi-user.target EOF # 启动服务 systemctl daemon-reload systemctl enable docker --now # 安装docker-compose curl -L http://192.168.3.200/Software/docker-compose -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose
启动图形化界面
# 1.启动visualizer docker run -itd --name visualizer -p 8080:8080 -e HOST=192.168.8.60 -e PORT=8080 -v /var/run/docker.sock:/var/run/docker.sock dockersamples/visualizer:latest # 2. 启动portainer-ce docker run -d -p 9000:9000 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer-ce
docker search centos
docker pull centos(默认最新版)
docker images
docker inspect xxxx
保存镜像为压缩文件
用法: docker save -o 压缩文件名称 [镜像名称或者ID]
[root@zuolaoshi ~]# docker save -o centos_base.tar centos [root@zuolaoshi ~]# ls anaconda-ks.cfg centos_base.tar init.sh
删除本地镜像库中的某个镜像
用法: docker rmi [镜像名称或者ID]
[root@zuolaoshi ~]# docker rmi centos Untagged: centos:latest Untagged: centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177 Deleted: sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6 Deleted: sha256:74ddd0ec08fa43d09f32636ba91a0a3053b02cb4627c35051aff89f853606b59 [root@zuolaoshi ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE
导入由save保存出来的压缩文件镜像
用法: docker load -i 镜像压缩文件名称 [镜像名称或者ID]
[root@zuolaoshi ~]# docker load -i centos_base.tar 74ddd0ec08fa: Loading layer 238.6MB/238.6MB Loaded image: centos:latest
docker images -aq
docker rmi $(docker images -aq)
用法: docker ps [-a 显示所有容器,默认只显示运行的]
1)docker ps 显示运行的容器
[root@zuolaoshi ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2)docker ps -q:只显示容器编号
3) docker ps -n:
显示最近n个创建的容器
docker inspect 镜像名称或者id
[root@zuolaoshi ~]# docker inspect centos
docker run [options] 镜像名称
常用参数:
参数 | 功能 |
---|---|
--name | 指定容器名字 |
-i --interactive | 交互式启动 |
-t --tty /bin/bash | 分配终端,创建一个伪终端,执行命令 |
-d --detach | 后台执行,守护进程 |
-v --volume | 目录映射,容器目录挂载到宿主机目录,格式: :<容器目录> |
-p | 指定端口映射,格式:主机(宿主)端口:容器端口 |
-P | 随机端口映射,容器内部端口随机映射到主机的端口(49153起始 49153到65535) |
-e username="tom | " 设置容器中的环境变量 |
--network | 指定网络 |
--rm | 容器停止自动删除容器,自动清除挂在的卷 |
-u | 以什么用户身份创建容器 |
-h | 指定容器的 host name |
-m | 设置容器使用内存最大值 |
删除的容器必须是关闭状态;关闭容器: docker stop 容器名/镜像名
[root@zuolaoshi ~]# docker rm centos7_1 centos7_1
[root@zuolaoshi ~]# docker exec centos7_3 ls / bin dev etc home lib
docker attach [容器名称或者ID]
[root@zuolaoshi ~]# docker attach centos7_3
Docker attach在容器的当前进程上直接启动一个终端,并将该终端连接到容器的标准输入、标准输出和标准错误。这意味着我们只能在容器当前运行的进程中操作,而且如果我们退出该终端,容器也会被终止。
[root@zuolaoshi ~]# docker pause centos7_3 centos7_3
[root@zuolaoshi ~]# docker unpause centos7_3 centos7_3
docker rename 容器名称 容器新名称
[root@zuolaoshi ~]# docker rename centos7_3 centos73 [root@zuolaoshi ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 948d233eb6bf centos "/bin/bash" 6 minutes ago Up About a minute
容器导出-export命令
将一个容器导出一个镜像为压缩文件
用法: docker export -o 导出后镜像文件名 [容器名称或者ID]
[root@zuolaoshi ~]# docker export -o zuolaoshi_centos.tar centos73 [root@zuolaoshi ~]# ls anaconda-ks.cfg centos_base.tar init.sh zuolaoshi_centos.tar
将容器镜像导入到镜像库
用法: docker import 镜像文件名 镜像名:tag
[root@zuolaoshi ~]# docker import zuolaoshi_centos.tar zj_centos sha256:80eecf935fa87d49f154b00b6630a966651b1a70c4042580c568a88808069679 [root@zuolaoshi ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE zj_centos latest 80eecf935fa8 2 seconds ago 231MB centos latest 5d0da3dc9764 2 years ago 231MB
docker commit [容器名称或者ID] 导出后镜像的名字:tag
[root@zuolaoshi ~]# docker commit centos73 zj_centos_73 sha256:68421c5ca664de9f771e325cab0252b16700f2db4c5243d65706cf608b47633b
docker cp :用于容器与主机之间的数据拷贝。
# 将主机/data目录拷贝到容器96f7f14e99ab中,目录重命名为/www。 docker cp /data 96f7f14e99ab:/www # 将主机/www/html目录拷贝到容器96f7f14e99ab的/www目录下。 docker cp /var/www/html 96f7f14e99ab:/www/
1)exit 容器停止
2)ctrl+p+q 容器不停止
docker run -it redis:6.0.8
docker run -d redis:6.0.8
[root@localhost ~]# docker run -it ubuntu /bin/bash root@4ec5443e0d1b:/# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 10:47 pts/0 00:00:00 /bin/bash root 9 1 0 10:48 pts/0 00:00:00 ps -ef root@4ec5443e0d1b:/#
docker logs 容器id
{ "hosts": ["tcp://0.0.0.0:2375","unix:///var/run/docker.sock"] }
1. [root@Base ~]# docker pull mysql:latest 2. [root@Base ~]# docker images 3. mkdir -p /data/mysql/{data,conf} 4. cat > /data/mysql/conf/my.cnf << EOF [mysqld] pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock datadir = /var/lib/mysql secure-file-priv= NULL character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci EOF 5. docker run -itd --name mysql-test \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=123456 \ -v /data/mysql/data:/var/lib/mysql \ -v /data/mysql/conf:/etc/mysql/ \ --restart=always \ mysql 若安装不上,删掉 -v /data/mysql/conf:/etc/mysql/ docker run -itd --name mysql-test \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=123456 \ -v /data/mysql/data:/var/lib/mysql \ --restart=always \ 6. [root@Base ~]# docker exec -it mysql-test bash root@5fe9d68ae468:/# mysql -uroot -p Enter password:
mysql 中创建wp1库
1. mysql> create database wp1 charset utf8mb4; 2. docker run -itd --name wodpress1 \ -e WORDPRESS_DB_HOST=192.168.8.101:3306 \ -e WORDPRESS_DB_USER=root \ -e WORDPRESS_DB_PASSWORD=123456 \ -e WORDPRESS_DB_NAME=wp1 \ -p 8086:80 \ --restart=always \ wordpress
让容器联网的几种方式(4中)
容器-----宿主机
容器------容器
容器--------外网
bridge 网桥(默认的网络模式)
会默认生成一个Docker0的虚拟网卡
使用该docker0网卡可以让容器和宿主机、外网通信。
NAT(网络地址转换),容器会被 自动分配一个IP和子网掩码
IP地址范围: 172.17.0.2--172.17.255.254 65534
docker 作为 “路由器” 和 “交换机”
通过宿主机 iptables防火墙的NAT表实现与外网的联系;
宿主机-----容器 通过网桥bridge访问
容器----容器 通过网桥bridge访问
网桥docker0创建一对对等虚拟设备接口,一个叫veth,另一个叫eth0,成对匹配。
host 主机
容器和真机共用网卡及对应的端口,缺点就是同一个端口只能宿主机或者某个容器使用,其他容器不能用。
host最大的优势就是网络性能比较好
--network host
none 空
不能连接外网,没有网卡和网关,只能单机运行。
--network none
container 容器网络或联盟网络
和其他容器共享同一个网卡、IP、网关、端口范围相同的。
网络方面,其他的如文件系统、进程列表等还是隔离的。
--network container:NAMEorID(共享的网络容器名或ID)
创建网桥:
[root@zuolaoshi ~]# docker network create -d bridge --subnet 192.168.1.0/24 --gateway 192.168.1.1 mydocker0 6a410e27b66ea587142d967f7dff6f36c04ced3c27116a79831412f3743aba56
查看网桥:
[root@zuolaoshi ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 6ee1e928b710 bridge bridge local
修改docker网桥名字 1、关闭新建网桥 [root@zuolaoshi ~]# ip link set dev br-6a410e27b66e down 2、修改名字 [root@zuolaoshi ~]# ip link set dev br-6a410e27b66e name mydocker0 3、启动网桥 [root@zuolaoshi ~]# ip link set dev mydocker0 up 4、重启docker服务 [root@zuolaoshi ~]# systemctl restart docker
删除未使用的网桥-prune
[root@zuolaoshi ~]# docker network prune WARNING! This will remove all networks not used by at least one container. Are you sure you want to continue? [y/N] y Deleted Networks: docker1
删除某个网桥-rm
[root@zuolaoshi ~]# docker network rm docker100 docker100
容器断开网桥
将centos1容器的网络从docker1网桥断开 [root@zuolaoshi ~]# docker network disconnect docker1 centos1
数据的持久化。将容器的数据目录挂载到宿主机上,当我们删除容器时,可以保留数据。
1.什么是存储卷(volume)
就是将一个容器的目录和一个宿主机的目录同步起来了,就称之为volume,也就是存储卷。
当在容器中产生数据的时候,这个数据就会直接写入到了物理磁盘,就解决了性能的问题
使用存储卷,还实现了数据的持久存储
通过使用存储卷,还可以实现分布式
2.存储卷的类型
Bind mount volume:
Docker managed volume
mysql /data/mysql/data://var/lib/mysql
宿主机目录 | 容器目录 | |
---|---|---|
为空 | 为空 | 空 |
不为空 | 为空 | 宿主机内容 |
为空 | 不为空 | 容器内容 |
不为空 | 不为空 | 宿主机上的数据会覆盖容器 |
加参数: --volumes-from
[root@host1 ..]# docker run --name httpd2 --rm -it --volumes-from httpd1 busybox / # / # ls /data/ t.txt / #
用来自动构建镜像的一种脚本格式
手动构建镜像
nginx–>nginx01-> docker cp -> game ->commit -> save.tar –> load
镜像:有联合文件系统UnionFS构成的文件
分层
只读
容器 镜像+容器层构成的。
容器层时可读可写的。
当将容器导出为新的镜像时,我们修改的数据会成为新镜像的额最上层一层;
构建镜像时,是一层一层构建出来的。
BASE
每执行一次run命令,就会多一层;
1.编写dockerfile文件
2.docker build 构建成一个镜像
3.docker run 镜像
4.将docker 镜像发布到公有仓库(Docker Hub ,阿里云镜像仓库等)或私有仓库。
由于文件名都为 Dockerfile,所以可以先创建几个目录:
【网络一定要好】
mkdir Dockerwork
cd dockerwork
vim Dockerfile
vim Dockerfile # 1.指定基础镜像 FROM centos:7 # 2.设置我们自己操作,RUN执行命令 RUN yum makecache fast RUN yum install httpd -y RUN sed -i 's/#ServerName www.example.com:80/ServerName localhost:80/g' /etc/httpd/conf/httpd.conf RUN echo "Hello
" >/var/www/html/index.html RUN /usr/sbin/httpd # 3.暴露出端口 EXPOSE 80 # 4.启动时执行,用于阻塞进程,防止容器被关停。 CMD ["/usr/sbin/httpd","-D","FOREGROUND"]
# 退出并执行 # 构建镜像 docker build -f Dockerfile -t hello . # 运行容器 docker run -itd --name hello-1 -p 80:80 hello
DOCKERFILE 指令 | 说明 |
---|---|
FROM | 指定基础镜像,用于后续的指令构建。 |
MAINTAINER | 指定Dockerfile的作者/维护者。(新版已弃用,推荐使用LABEL指令) |
LABEL | 添加镜像的元数据,使用键值对的形式。 |
RUN | 在构建过程中在镜像中执行命令。 |
CMD | 指定容器创建时的默认命令。(可以被覆盖) |
ENTRYPOINT | 设置容器创建时的主要命令。(不可被覆盖) |
EXPOSE | 声明容器运行时监听的特定网络端口。 |
ENV | 在容器内部设置环境变量。 |
ADD | 将文件、目录或远程URL复制到镜像中。 |
COPY | 将文件或目录复制到镜像中。 |
VOLUME | 为容器创建挂载点或声明卷。 |
WORKDIR | 设置后续指令的工作目录。 |
USER | 指定后续指令的用户上下文。 |
ARG | 定义在构建过程中传递给构建器的变量,可使用 "docker build" 命令设置。 |
ONBUILD | 当该镜像被用作另一个构建过程的基础时,添加触发器。 |
STOPSIGNAL | 设置发送给容器以退出的系统调用信号。 |
HEALTHCHECK | 定义周期性检查容器健康状态的命令。 |
SHELL | 覆盖Docker中默认的shell,用于RUN、CMD和ENTRYPOINT指令。 |
为了更好的管理镜像
公网仓库:docker hub
私网仓库:
registry(自带的)、
harbor(图形化)
搭建步骤
拉取 registry 容器镜像
创建 registry 仓库容器
测试容器应用
至少两台,一台服务端,一台客户端
IP地址 | |
---|---|
服务端 | 192.168.8.13 |
客户端 | 192.168.8.101 |
安装registry仓库
第一台机器操作:192.168.8.13
docker pull registry #1、创建持久化存储,将容器镜像存储目录/var/lib/registry挂载到本地/opt/myregistry下: mkdir /opt/myregistry # 2、创建 registry 容器: docker run -d -p 5000:5000 -v /opt/myregistry:/var/lib/registry --restart=always registry:latest # 显示仓库中没有任何镜像 curl http://192.168.1.150:5000/v2/_catalog {"repositories":[]}
上传步骤
#1.修改标签tag,将私有仓库的域名或IP地址添加到镜像上。 docker tag registry 192.168.8.13:5000/registry-lasest:latest #2.使用docker push上传 docker push 192.168.8.13:5000/registry-lasest:latest #3.如果上传成功则可输入查看 curl http://192.168.8.13:5000/v2/_catalog
排错,方法有二,一般用第二个:
Get https://172.18.11.126:5000/v2/: http: server gave HTTP response to HTTPS client
#docker默认要求仓库是https的协议 #1.服务端nginx反向代理,配置ssl加密证书。 #2.修改客户端的配置文件,让客户端允许不安全的http网址 cat /etc/docker/daemon.json { "insecure-registries": ["http://192.168.8.14:5000"] } #忽略https
进行重启Docker
systemctl daemon-reload systemctl restart docker
进行下载
设置机器的docker仓库为registry仓库
另一台机器:192.168.8.101
#1、设置docker启动文件 [root@zuolaoshi_node1 ~]# sed -i.bak '/^ExecStart=/c\ExecStart=\/usr\/bin\/dockerd' /usr/lib/systemd/system/docker.service #2、设置docker配置文件 [root@zuolaoshi_node1 ~]# cat /etc/docker/daemon.json { "insecure-registries": ["http://182.168.8.14:5000"] }
拉取镜像
docker pull 192.168.8.14:5000/registry-lasest:latest
最后进行验证
docker images
如果显示有即为正确!
实验环境:
虚拟机1 | 192.168.8.13:8088 |
第一步:下载软件包
wget http://192.168.3.200/Software/harbor-offline-installer-v1.9.2-rc1.tgz
第二步:容器编排工具,执行./install.sh时需要。如果不安装,一会重启docker服务,相关的harbor容器会死掉,安装后就会被随着docker重启
方法一:(官网)
curl -L https://github.com/docker/compose/releases/download/v2.25.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
方法二:(局域网)
curl -L http://192.168.3.200/Software/docker-compose -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
第三步:解压
tar xf harbor-offline-installer-v1.9.2-rc1.tgz
第四步:移动
mv harbor /opt/
第五步: /opt/harbor/prepare
第六步:修改配置文件 /opt/harbor/harbor.yml
第5行:hostname: 192.168.8.101
第10行: 端口号,根据主机端口使用情况配置。
port: 80
授权地址格式 ip:port
第23行添加:
external_url: 192.168.8.101
第27行: 管理员密码[不能改,改了会报错,登录成功后,可以去图形化界面修改密码]
harbor_admin_password: Harbor12345
修改完配置文件:systemctl daemon-reload
systemctl restart docker
第七步:执行
./install.sh
第八步:登录
docker login http://192.168.8.13:8088 -u admin -p Harbor12345
vim /etc/docker/daemon.json
{ "insecure-registries": ["http://182.168.8.14:5000"] }
cd /data/
删除所有内容:rm -rf *
cd /opt/harbor/
重新执行 ./install.sh
用于生成容器的一种yaml的一种文件格式,使用docker-compose的命令运行容器。
单机容器批量管理编排工具。一条命令可以同时管理多个容器,
包括创建、删除、启动、关闭、重启、查看机器;
通过docker-compose.yml 文件来管理一组容器
我们知道使用 Dockerfile 模板文件可以让用户很方便的定义一个单独的应用容器,其实在工作中,经常会碰到需要多个容器相互配合来完成的某项任务情况,例如工作中的 web 服务容器本身,往往会在后端加上数据库容器,甚至会有负责均衡器,比如 LNMP 服务
Compose 就是来做这个事情的,它允许用户通过一个单独的 docker-compose.yml 模板文件 YAML格式 来定义一组相关联的应用容器为一个项目 project
开头先写版本:
version: 3 是docker-compose文本版本
services: 定义了应用中的每个容器(服务)。每个服务可以使用不同的镜像、环境设置和依赖关系。
db\log\web: 容器在集群中名称,只在docker-compose生效和调用。
image:镜像名,不存在时,会自动下载
container_name:容器名,容器运行时在docker ps中可以看到
restart:重启方式
always:一直重启,只要docker启动,容器就会一直启动。
no:不重启。
on-failure:仅在容器非正常退出时(退出状态码非零)重启。
unless-stopped:除非手动停止,否则总是重启。
volumes:数据卷 -v
宿主机目录:容器目录 /var/lib/docker/volumes
/data/mysql:/var/lib/mysql
data:/var/lib/mysql
/var/lib/mysql # 随机生成一个挂载目录,挂载到/var/lib/docker/volumes目录中。
:ro 只读
:rw 读写(默认可以不写)
:z 安全模式(SElinux配合使用的。)
ports:
127.0.0.1:1514:10514
80:80 0.0.0.0
80 随机指定一个端口
networks: 网络连接模式 - harbor 网桥名
depends_on: 依赖容器集群中的其他容器的别名
env_file: 单独设置环境变量的配置文件路径
networks: 用于创建新的网桥
harbor: 新建的网桥名 NAT模式(网络地址转换) external: false 是否是外部网络,内部网络(类似于局域网)
让我们通过一个简单的博客系统来演示 Docker Compose 的使用。
这个系统将包括两个服务:一个是运行 WordPress 的 web 服务,
另一个是 MySQL 数据库服务。我们将使用 Docker Compose 来定义和运行这两个服务。
一台虚拟机:192.168.8.13:5000
部署wordpress
让我们通过一个简单的博客系统来演示 Docker Compose 的使用。这个系统将包括两个服务:一个是运行 WordPress 的 web 服务,另一个是 MySQL 数据库服务。我们将使用 Docker Compose 来定义和运行这两个服务。
创建名为 docker-compose.yml
的文件,并添加一下内容;
方法一:可以随便创一个目录写:
方法二:
(如果在/opt/harbor/下创建的话,因为里面有哪个文件:需要备份这个文件)
version: '3.8' services: db: image: mysql:5.7 volumes: - /data/mysql/data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: root123 MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: depends_on: - db image: wordpress:latest ports: - "8000:80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress WORDPRESS_DB_NAME: wordpress
步骤 2: 使用 Docker Compose 启动服务
在命令行执行 docker-compose up -d
会在后台启动定义在 docker-compose.yml
文件中的所有服务。
一旦服务启动,您可以通过访问 http://localhost:8000
来设置和使用 WordPress。
步骤 3: 管理和停止服务
使用 docker-compose ps
来查看服务的状态。
docker-compose logs
可以用来查看服务的日志,这在调试问题时非常有用。
当不再需要运行服务时,可以通过 docker-compose down
命令来停止并移除所有由 docker-compose.yml
文件定义的服务和网络。请注意,这不会删除 db_data
卷,因此您的数据库数据将被保留。
# 1. 创建一个目录(里面包含需要的文件) [root@zuolaoshi]# mkdir compose-py # 2. 创建一个 Python 应用, 使用 Flask ,将数值记入 Redis [root@zuolaoshi compose-py]# vim app.py import time import redis from flask import Flask app = Flask(__name__) cache = redis.Redis(host='redis', port=6379) def get_hit_count(): retries = 5 while True: try: return cache.incr('hits') except redis.exceptions.ConnectionError as exc: if retries == 0: raise exc retries -= 1 time.sleep(0.5) @app.route('/') def hello(): count = get_hit_count() return 'Hello World! I have been seen {} times.\n'.format(count) if __name__ == "__main__": app.run(host="0.0.0.0", debug=True) # 3. 创建 requirements.txt 文件,里面是需要安装的 Python 包 [root@zuolaoshi compose-py]# vim requirements.txt flask redis # 4. 创建 Dockerfile 文件 [root@zuolaoshi compose-py]# vim Dockerfile FROM python ADD . /code WORKDIR /code RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple CMD ["python", "app.py"] # 这告诉Docker: 从 Python 开始构建镜像 将当前目录 . 添加到 /code 镜像中的路径 将工作目录设置为 /code 安装 Python 依赖项 将容器的默认命令设置为 python app.py 5. 创建 docker-compose.yml 文件 [root@zuolaoshi compose-py]# vim docker-compose.yml version: '3' services: web: build: . ports: - "5000:5000" volumes: - .:/code redis: image: "redis" # 此 Compose 文件定义了两个服务,web 和 redis # 该web服务: 使用从 Dockerfile 当前目录中构建的镜像 将容器上的公开端口 5000 转发到主机上的端口 5000 我们使用 Flask Web 服务器的默认端口 5000 该 redis 服务使用从 Docker Hub 中提取的公共 Redis 映像 # 6. 使用 Compose 构建并运行您的应用程序 [root@zuolaoshi compose-py] docker-compose up -d # 7. 测试访问,在浏览器访问 IP:5000 每刷新一次就会加一
docker-compose down 删除当前项目所有容器
docker-compose up -d 运行当前项目中所有容器
docker-compose ps
集群版的docker,容器编排技术。和k8s类似,但比k8s简单。
Docker官方提供的一个容器集群编排管理工具。(编排:按照一定顺序去排列组合机器)
管理多台主机上的容器,创建、删除、修改、查看;
管理docker网络;
管理docker节点;
当单机性能不足时,增加主机,为了方便管理分散在不同服务器上的容器,就可以用docker swarm了。
Docker swarm 是单体架构;所有功能(资源调度、网络连接、路由转发、容器管理等),docker自带的。
k8s是分布式的微服务架构的应用。所有功能由不同的软件应用提供。
k8s只是一个框架,它本身并不提供网络、容器管理、数据存储、等功能。适用于大型集群;性能更强;
k8s 1.24以后版本,官方不支持docker,但是docker内部自己制作了一个插件,叫 cli-docker;安装插件后即可使用;
swarm manager:负责整个集群的管理工作包括集群配置、服务管理等所有跟集群有关的工作。
work node:即图中的 available node,主要负责运行相应的服务来执行任务(task)。
Service 一个服务是任务的定义,管理机或工作节点上执行。它是群体系统的中心结构,是用户与群体交互的主要根源。创建服务时,你需要指定要使用的容器镜像。(由一组容器构成,这一组容器可以分布在不同的机器上)
Task 任务是在docekr容器中执行的命令,Manager节点根据指定数量的任务副本分配任务给worker节点
实验环境
IP地址 | 计算机名 | 角色 |
---|---|---|
192.168.8.150 | manage01 | swarm_manager |
192.168.8.151 | node-1 | swarm_node |
192.168.8.152 | node-2 | swarm_node |
# 0.所有节点安装 docker yum install -y yum-utils device-mapper-persistent-data lvm2 wget https://download.docker.com/linux/centos/docker-ce.repo -P /etc/yum.repos.d/ sed -i 's#download.docker.com#mirrors.tuna.tsinghua.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo yum -y install docker-ce # 1.hosts 解析 cat >> /etc/hosts << EOF 192.168.8.150 manage01 192.168.8.151 node-1 192.168.8.152 node-2 EOF # 2.关闭firewalld systemctl disable firewalld systemctl stop firewalld iptables -F # 3.关闭 selinux #设置为 disabled 后需要重启计算机生效 SELINUX=disabled
# 1.初始化集群-init [root@manage01 ~]# docker swarm init --advertise-addr 192.168.8.150 #--advertise-addr参数表示其它swarm中的worker节点使用此ip地址与manager联系 # Swarm initialized: current node (dh6qthwwctbrl0y3hx1k41icl) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-0vdbyxq80uk8sf9nlnahsnkv6w3gaf5necl992ia0g8dmc5x8c-bkenoigc7kwizoch08r3fc4wq 182.168.8.150:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
[root@node-1 ~]# docker swarm join --token SWMTKN-1-0vdbyxq80uk8sf9nlnahsnkv6w3gaf5necl992ia0g8dmc5x8c-bkenoigc7kwizoch08r3fc4wq 192.168.8.150:2377 This node joined a swarm as a worker. [root@node-2 ~]# docker swarm join --token SWMTKN-1-0vdbyxq80uk8sf9nlnahsnkv6w3gaf5necl992ia0g8dmc5x8c-bkenoigc7kwizoch08r3fc4wq 192.168.8.150:2377 This node joined a swarm as a worker.
[root@manage01 ~]# docker node ls
# 创建网络在部署服务 # 创建网络 [root@manage01 ~]# docker network create -d overlay nginx_net a52jy33asc5o0ts0rq823bf0m [root@manage01 ~]# docker network ls | grep nginx_net a52jy33asc5o nginx_net overlay swarm # 部署服务 [root@manage01 ~]# docker service create --replicas 1 --network nginx_net --name my_nginx -p 80:80 nginx # 就创建了一个具有一个副本(--replicas 1 )的nginx服务,使用镜像nginx olexfmtdf94sxyeetkchwhehg overall progress: 1 out of 1 tasks 1/1: running [==================================================>] verify: Service converged 在 manager与node 节点上使用上面这个覆盖网络创建 nginx 服务 其中,--replicas 参数指定服务由几个实例组成 注意:不需要提前在节点上下载 nginx 镜像,这个命令执行后会自动下载这个容器镜像 # 使用 docker service ls 查看正在运行服务的列表 [root@manage01 ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS olexfmtdf94s my_nginx replicated 1/1 nginx:latest *:80->80/tcp 2) 查询Swarm中服务的信息 -pretty 使命令输出格式化为可读的格式,不加 --pretty 可以输出更详细的信息: [root@manage01 ~]# docker service inspect --pretty my_nginx ID: zs7fw4ereo5w7ohd4n9ii06nt Name: my_nginx Service Mode: Replicated Replicas: 1 Placement: UpdateConfig: Parallelism: 1 On failure: pause Monitoring Period: 5s Max failure ratio: 0 Update order: stop-first RollbackConfig: Parallelism: 1 On failure: pause Monitoring Period: 5s Max failure ratio: 0 Rollback order: stop-first ContainerSpec: Image: nginx:latest@sha256:b73f527d86e3461fd652f62cf47e7b375196063bbbd503e853af5be16597cb2e Init: false Resources: Networks: nginx_net Endpoint Mode: vip Ports: PublishedPort = 80 Protocol = tcp TargetPort = 80 PublishMode = ingress # 查询到哪个节点正在运行该服务 [root@manage01 ~]# docker service ps my_nginx 在 Swarm 中动态扩展服务 (scale) 当然,如果只是通过 service 启动容器,swarm 也算不上什么新鲜东西了。Service 还提供了复制(类似 kubernetes 里的副本)功能。可以通过 docker service scale 命令来设置服务中容器的副本数,比如将上面的 my_nginx 容器动态扩展到 4 个 [root@manager01 ~]# docker service scale my_nginx=4 my_nginx scaled to 4 overall progress: 4 out of 4 tasks 1/4: running [==================================================>] 2/4: running [==================================================>] 3/4: running [==================================================>] 4/4: running [==================================================>] verify: Service converged 和创建服务一样,增加 scale 数之后,将会创建新的容器,这些新启动的容器也会经历从准备到运行的过程,过一分钟左右,服务应该就会启动完成,这时候可以再来看一下 nginx 服务中的容器 [root@manager01 ~]# docker service ps my_nginx 升级镜像/升级业务/回滚业务 docker service update --image nginx:new my_nginx 删除服务 [root@manager43 ~]# docker service rm my_nginx