# 镜像的构建历史
docker history 镜像id
# 一个镜像可以起多个标签,多个标签类似于硬链接,必须把所有相同镜像的标签删除,
# 这个镜像才算完全删除,只删除其中一个,相当于只删了标记,因为镜像层是共用的。
docker tag alpine:3.9 alpine:latest
# docker container diff容器相对于镜像发生变化的文件
docker run -d -it centos:7
docker cp 1.txt 容器id:/root
docker container diff 容器id
# export和import是一对导出镜像/导入镜像,他们和save和load的区别是(一般不使用)
# export导出的镜像只有一层,import导入的镜像是无名镜像
docker run -d kod:v2
docker export 容器id >docker_test.tar.gz
docker import docker_test.tar.gz
# 查看镜像和容器的id
docker image inspect 镜像id
docker container inspect 容器id
# 将容器进行挂起
docker container pause 容器id
# 将容器取消挂起
docker container unpause 容器id
# 单纯看一下容器的端口映射,比较鸡肋,直接用docker ps查看即可(一般不用)
docker container port 容器id
# 清理停止状态的容器
docker container prune
# 清理没有标签的镜像
docker image prune
# 容器的监控,监控每个容器占用了多少资源
docker container stats # 实时动态展示
docker container stats --no-stream # 只显示一次
# 可以修改容器的属性,资源的限制
docker container update --help
## 只要docker已启动,这个容器就会启动
docker container update --restart always 容器id
## 更新资源的限制
[root@docker01 ~]# docker container update --memory 50MiB --memory-swap 50MiB zabbix_zabbix-server_1
zabbix_zabbix-server_1
## 内存限制成功
[root@docker01 ~]# docker container stats --no-stream | grep zabbix_zabbix-server_1
f52e728c1856 zabbix_zabbix-server_1 0.25% 21.93MiB / 50MiB 43.87% 38MB / 19.5MB 0B / 0B 30
## 也可以启动容器的时候指定容器的资源
docker run -d --memory 10M kod:v3
docker container stats --no-stream
# 查看容器内的进程信息
docker container top 7ea8724b7da6
# 容器停止后,返回容器内初始命令停止的$?的值
docker container wait 容器id
# 网络有关
docker network
# 数据卷有关
docker volume ls
docker volume prune # 清理卷,删除操作要谨慎
docker system df # 查看镜像和容器和卷和构建缓存的信息
docker system prune # 清理停止的容器、没有使用网络的容器、没有名字的镜像、没有使用的缓存
docker system info # 查看docker的信息
Runtimes: runc # 如果容器的运行环境都是runc,容器镜像就可以通用
docker system event # 查看事件,启动容器的会产生事件
实验环境:
10.0.0.11 docker01
安装私有仓库,充当服务端
10.0.0.12 docker02
充当客户端,上传下载镜像
# 1. 上传下载后的镜像,如果没有就会从官网仓库下载,启动私有仓库
[root@docker01 ~]# docker load -i registry.tar.gz
[root@docker01 ~]# docker run -d -p 5000:5000 --restart=always --name registry -v /opt/myregistry:/var/lib/registry registry
# 2. 在客户端进行配置镜像加速和添加信任私有仓库,并重启docker生效
[root@docker02 ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"insecure-registries": ["10.0.0.11:5000"]
}
[root@docker01 ~]# systemctl restart docker
# 3. 镜像地址
## 镜像的名字决定了是官方镜像还是第三方仓库的镜像
nginx:1.15 官方仓库的官方镜像
nginx/nginx:1.15 官方仓库的用户镜像
daocloud.io/nginx/nginx:1.15 私有仓库的镜像
# 4. 上传镜像的步骤
(1) docker tag 打标签
(2) docker push 推镜像
# 5. 实战演练: 上传镜像和下载镜像
## 上传镜像,私有仓库也是分层存储的,如果上传的镜像在仓库中已经有镜像层了,那么只上传了标签
[root@docker02 ~]# docker tag alpine:3.9 10.0.0.11:5000/alpine:3.9
[root@docker02 ~]# docker image push 10.0.0.11:5000/alpine:3.9
## 下载镜像,下载镜像也是有分层
[root@docker02 ~]# docker image pull 10.0.0.11:5000/alpine:3.9
docker-registry仓库管理操作
# 1. 查看仓库里有哪些镜像
http://10.0.0.11:5000/v2/_catalog
# 2. 查看某个镜像有哪些版本
http://10.0.0.11:5000/v2/alpine/tags/list
# 3. 在仓库中删除镜像
## (1) 进入docker registry的容器中
[root@docker01 ~]# docker exec -it registry /bin/sh
ls /var/lib/registry/docker/registry/v2/
blobs # 镜像的层信息
repositories # 仓库的信息,存的各种镜像的名字
## (2) 删除repo
rm -fr /var/lib/registry/docker/registry/v2/repositories/alpine
## (3) 清楚掉blob
registry garbage-collect /etc/docker/registry/config.yml
# 4. 带认证的registry
yum install httpd-tools -y
mkdir /opt/registry-var/auth/ -p
htpasswd -Bbn admin 123456 >> /opt/registry-var/auth/htpasswd
docker run -d -p 5000:5000 -v /opt/registry-var/auth/:/auth/ -v /opt/myregistry:/var/lib/registry -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry
# 提示: 上传下载镜像都需要登陆
docker login 10.0.0.11:5000
admin/123456
# 登出私有仓库
docker logout 10.0.0.11:5000
小提示:
docker-registry优点:功能简单,占用资源比较少,推荐个人使用
docker-registry缺点:功能比较少,web界面操作不方便,不像docker hub一样在页面可以直接进行镜像的管理,所以生产一般用企业级的仓库harbor
# (1) 登录docker hub,输入账号和密码
[root@docker01 ~]# docker login
# (2) 在alpine镜像打tag,然后push镜像到docker hub中个人的仓库
[root@docker01 ~]# docker tag alpine:v1 d15926990/alpine:v1
[root@docker01 ~]# docker push d15926990/alpine:3.9
小提示: docker pull的时候默认是拉取的是最新的镜像latest,所以上传镜像的时候打一个v1版,在打一个latest版本,方便别人下载
实验环境:
10.0.0.12 docker01
安装harbor,充当harbor服务端
10.0.0.11 docker02
充当客户端,上传下载镜像
harbor是在docker-registry的基础上进行的二次开发
# (1) 配置yum源
[root@docker02 ~]# curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
[root@docker02 ~]# curl -o /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
# (2) 配置信任的仓库,并重启docker
[root@docker01 ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"insecure-registries": ["10.0.0.12"]
}
[root@docker01 ~]# systemctl restart docker
# (3) 安装docker-compose,安装harbor依赖docker-compose,可以在gitlhub上看相应的版本的安装步骤
[root@docker02 ~]# yum install docker-compose -y
[root@docker02 ~]# docker-compose -v
小提示: (了解即可,这样安装会有报错)
# epel源里面的docker-compose不是最新的,如果像安装最新的docker-compose,用pip去安装
yum install python-pip -y
# pip默认使用的是国外的源
pip install docker-compose
# 使用国内的源https://mirrors.tuna.tsinghua.edu.cn/help/pypi/
pip install docker-compose -i https://pypi.tuna.tsinghua.edu.cn/simple
# (4) 上传下载的harbor,并且进行解压,下载地址: https://github.com/goharbor/harbor/releases/download/v1.10.0/harbor-offline-installer-v1.10.0.tgz
[root@docker02 ~] mkdir harbor
[root@docker02 ~] cd harbor
[root@docker02 harbor]# tar xf harbor-offline-installer-v2.1.0.tgz
[root@docker02 harbor]# cd harbor
[root@docker02 harbor]# cp harbor.yml.tmpl harbor.yml
# (5) 修改配置文件
[root@docker02 harbor]# vim harbor.yml
hostname: 10.0.0.12
## 取消https的配置
harbor_admin_password: 123456
# (6) 执行安装脚本, 注意: 每次改完harbor.yml后,都要执行以下install.sh
[root@docker02 harbor]# ./install.sh
[root@docker02 harbor]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e391d207c6c8 goharbor/harbor-jobservice:v2.1.0 "/harbor/entrypoint.…" 37 seconds ago Up 34 seconds (healthy) harbor-jobservice
c6c75effa454 goharbor/nginx-photon:v2.1.0 "nginx -g 'daemon of…" 37 seconds ago Up 34 seconds (healthy) 0.0.0.0:80->8080/tcp, :::80->8080/tcp nginx
7f92a6011fe1 goharbor/harbor-core:v2.1.0 "/harbor/entrypoint.…" 37 seconds ago Up 36 seconds (healthy) harbor-core
2c002af31254 goharbor/harbor-registryctl:v2.1.0 "/home/harbor/start.…" 40 seconds ago Up 37 seconds (healthy) registryctl
aa586c1e5eeb goharbor/registry-photon:v2.1.0 "/home/harbor/entryp…" 40 seconds ago Up 36 seconds (healthy) registry
a91f8df80b77 goharbor/redis-photon:v2.1.0 "redis-server /etc/r…" 40 seconds ago Up 37 seconds (healthy) redis
3a8ae1794ca2 goharbor/harbor-portal:v2.1.0 "nginx -g 'daemon of…" 40 seconds ago Up 36 seconds (healthy) harbor-portal
2dc692066706 goharbor/harbor-db:v2.1.0 "/docker-entrypoint.…" 40 seconds ago Up 38 seconds (healthy) harbor-db
929feea38c1f goharbor/harbor-log:v2.1.0 "/bin/sh -c /usr/loc…" 42 seconds ago Up 39 seconds (healthy) 127.0.0.1:1514->10514/tcp harbor-log
# (7) 访问harbor,并且push镜像到harbor仓库中
## 浏览器访问harbor
http://10.0.0.12
## docker登录到harbor服务器,注意:docker login 默认登录的是docker hub仓库
## 登录10.0.0.12的harbor服务,如果有服务器是域名docker login dk.harbor.com,需要重新进行密码认证
[root@docker01 ~]# docker login 10.0.0.12
[root@docker01 ~]# docker tag alpine:3.9 10.0.0.12/library/alpine:3.9
[root@docker01 ~]# docker push 10.0.0.12/library/alpine:3.9
# (1) 修改harbor.yml,在阿里云或者腾讯云申请下来的证书配置到对应的路径中
[root@docker02 harbor]# vim harbor.yml
## 配置域名
hostname: dk.harbor.com
## 配置证书
https:
port: 443
certificate: /opt/certs/nginx/xxx.crt
private_key: /opt/certs/nginx/xxx.key
# (2) 重新执行安装脚本
## 因为harbor已经安装完成,没必要重新导入镜像,所以可以注释导入镜像,加快脚本执行
[root@docker02 harbor]# vim install.sh
## docker load -i ./harbor*.tar.gz
[root@docker02 harbor]# ./install.sh
# (3) liunx和windows都要配置host劫持
## linux配置host劫持,用于docker pull镜像,域名解析
[root@docker01 ~]# vim /etc/hosts
10.0.0.12 dk.harbor.com
## windows的hosts劫持,用于域名访问harbor网站
C:\Windows\System32\drivers\etc/hosts
10.0.0.12 dk.harbor.com
把一个项目的所有镜像都归类为一组,比如创建zabbix项目仓库
# (1) 查找相关zabbix的项目
[root@docker01 ~]# docker images | grep zabbix
zabbix/zabbix-server-mysql latest e36e7fa7e11a 6 years ago 106MB
zabbix/zabbix-web-nginx-mysql latest 386dc9afc1c4 6 years ago 174MB
zabbix/zabbix-java-gateway latest 4257519fd740 6 years ago 148MB
# (2) 将zabbix的项目打tag,上传到zabbix项目仓库
[root@docker01 ~]# docker tag zabbix/zabbix-server-mysql:latest 10.0.0.12/zabbix/zabbix-server-mysql:latest
[root@docker01 ~]# docker push 10.0.0.12/zabbix/zabbix-server-mysql:latest
linux后台操作
# harbor上用户创建好了之后,在linux后台要把之前docker login 10.0.0.12的账号密码删掉,重新认证
# cat /root/.docker/config.json, auth:"xxx" 这个密码是base64加密的
[root@docker01 ~]# rm -f /root/.docker/config.json
# 使用zabbix用户进行登录,在进行docker pull,docker push
[root@docker01 ~]# docker login 10.0.0.12
仓库管理:可以做主从同步,可以把别的仓库上的镜像,都拉取过来
删除镜像后,还需要垃圾清理
(1) brige 默认类型,NAT模式(172.17网段)
[root@docker01 ~]# docker run -d alpine:3.9
[root@docker01 ~]# docker run -d --network brige alpine:3.9
(2) host host类型,使用宿主机网络,网络性能最高
[root@docker01 ~]# docker run -d --network host alpine:3.9
(3) container 容器类型。使用其他容器共用网络,k8s中使用(跟其他容器共用网络,不属于一个单独的类型)
# 新启动的容器使用的网络要跟容器088f18113eeb一样,报错hosts解析,主机名,ip地址等都相同,但是一个容器占用3000端口,另一个就不能使用3000端口了
[root@docker01 ~]# docker run -d --network container:088f18113eeb alpine:3.9
# 启动一个监听端口为 3000 的服务器,用来测试端口占用问题
nc -l -p 3000
(4) none 没有网络,上不了外网
[root@docker01 ~]# docker run -d --network none alpine:3.9
brige网络默认使用的是172.17网段,如果想要使用其他网段,可以自定义一个网络
# (1) 创建自定义网络,-d就是DRIVER
[root@docker01 ~]# docker network create -d bridge --subnet 172.19.0.0/16 --gateway 172.19.0.1 dk_network
# (2) 查看所有的网络,dk_network网络的详细信息
## 查看所有的网络
[root@docker01 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
88e9df90483a bridge bridge local
d9a0dfe597ea dk_network bridge local
89ca93183afb host host local
ff7f6a319b68 none null local
## 查看dk_network网络的详细信息
[root@docker01 ~]# docker network inspect dk_network
# (3) 启动一个容器,使用刚创建的网络dk_network
[root@docker01 ~]# docker run -it --network dk_network alpine:3.9
# (4) 启动容器,使用刚创建的网络dk_network,自定义网络可以指定ip地址
[root@docker01 ~]# docker run -it --network dk_network --ip 172.19.0.100 alpine:3.9
macvlan类似与虚拟机的桥接网络
# (1) 在两台虚拟机上创建网络
[root@docker01 ~]# docker network create -d macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.254 -o parent=eth0 macvlan_dk
[root@docker02 ~]# docker network create -d macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.254 -o parent=eth0 macvlan_dk
# (2) 启动容器,使用macvlan_dk网络,并进行测试
## macvlan要手动管理ip地址,手动指定ip地址,否则容易ip地址冲突,虚拟机有检测ip地址冲突的机制,容器是没有的
[root@docker01 ~]# docker run -it --network macvlan_dk --ip 10.0.0.105 alpine:3.9
[root@docker02 ~]# docker run -it --network macvlan_dk --ip 10.0.0.106 alpine:3.9
/ # ping 10.0.0.105
PING 10.0.0.105 (10.0.0.105): 56 data bytes
64 bytes from 10.0.0.105: seq=0 ttl=64 time=1.414 ms
64 bytes from 10.0.0.105: seq=1 ttl=64 time=1.009 ms
--gateway 10.0.0.254
这个网关的ip地址与下图保持一致
docker03上: consul存储ip地址的分配
docker run --restart=always -d -p 8500 :8500 -h consul --name consul progrium/consul -server -bootstrap
docker01、 02 上:
vim /etc/docker/daemon.json
{
"cluster-store": "consul://10.0.0.13:8500",
"cluster-advertise": "10.0.0.11:2376"
}
vim /usr/lib/systemd/system/docker.service
systemctl daemon-reload
systemctl restart docker
2)创建overlay网络
docker network create -d overlay --subnet 172 .20.2.0/24 --gateway 172.20.2.254 ol1
3)启动容器测试
docker run -it --network ol1 --name test01 alpine:3.9 /bin/sh
每个容器有两块网卡,eth0实现容器间的通讯,eth1实现容器访问外网