Docker
一.docker概括
1.docker三个重要的概念
容器(Container):容器是镜像运行完成以后得到的正在运行的运行环境
镜像(image):是封装好的运行环境,它是死的~
仓库(repository):镜像可以上传到仓库里,仓库里可以搜索镜像.
2.什么是容器?
容器就是在隔离的环境中运行的一个进程,如果进程停止,容器就会退出。隔离的环境拥有自己的文件系统,IP地址,主机名等
3.容器有什么好的?为什么这么多人用?
kvm:需要硬件的支持,需要模拟硬件,需要走开启启动流程,不过能运行在不同的操作系统。
容器:共用宿主机内核,轻量级,损耗少,启动快,性能高,只能运行在linux系统上。
二.安装docker
ps:官方的一种简单装docker方式,一条命令即可,安装的为最新版,安装时间比较慢5分钟左右
curl -fsSL https://get.docker.com | bash -s docker --version 20.10.6 --mirror Aliyun
1.下载清华镜像源
cd /etc/yum.repos.d/
wget http://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo
2.替换默认下载源
sed -i "s@https://download.docker.com/@https://mirrors.tuna.tsinghua.edu.cn/docker-ce/@g" /etc/yum.repos.d/docker-ce.repo
3.下载docker-ce(社区稳定版)
yum repolist
yum install docker-ce -y
4.开启服务并且开机自启
systemctl start docker
systemctl enable docker
三.docker的使用
1.配置docker镜像加速
vi /etc/docker/daemon.json
{
"registry-mirrors": ["http://hub-mirror.c.163.com","https://registry.docker-cn.com","https://pee6w651.mirror.aliyuncs.com"]
}
2.docker基础命令
PS: 开启一个守护进程的容器-it -d ,只要进入容器加-it,不进入容器无脑加-d
1.docker镜像管理命令
PS:docker容器内的第一个进程必须一直处于前台运行的状态(夯住),否则这个容器就会处于退出状态!
搜索镜像
docker search nginx
获取镜像
docker pull
查看镜像列表
docker images
删除镜像
docker rmi centos:latest
导出镜像
docker sava nginx:latest -o docker-nginx.tar.gz
导入镜像
docker load -i docker-nginx.tar.gz
2.docker容器管理命令
生成容器
docker run -d -it -p 80:80 -p 81:81 -v /zhang/a.txt:/opt/ --name nginx01 nginx:latest
-d:放在后台运行,不然中断会夯住
-it:分配交互式终端
-p:映射端口 宿主机:容器
-v:数据卷管理,挂载目录
--name:给容器命名
进入进程
docker exec -it nginx /bin/bash
启动/关闭容器
docker start/stop nginx
杀死容器
docker kill nginx
查看容器列表
docker ps(-a -l -q)
-a:显示所有容器
-l:显示最近一个容器
-q:显示所有容器的id
删除容器
docker rm -f 容器id/容器名
删除所有容器
docker rm -f `docker ps -a -q`
四.docker容器的网络访问(端口映射)
docker会自动添加一条iptables规则来实现端口映射
#访问宿主机的80端口映射到容器的80端口
docker run -d -it -p 80:80 --name nginx01 nginx:latest
#访问诉着急的指定ip的80端口映射到容器的80端口
docker run -d -it -p 10.0.0.11:80:80 --name nginx01 nginx:latest
#访问宿主机指定ip的任意端口都映射到容器的80端口
docker run -d -it -p 10.0.0.11::80 --name nginx01 nginx:latest
五.docker的数据卷管理
总结:如果第一次数据卷是空,会将容器中的数据复制到数据卷中。如果卷里有数据,会把卷中的数据挂载到容器中。
#方式一
docker run -d -it -v zhang:/etc/nginx/conf.d/ --name nginx01 nginx:latest
#方式二,与nginx01挂载相同的卷且是挂载相同的位置
docker run -d -it --volumes-from ngixn01 ngixn:latest
#方式三 与不同环境的容器挂载相同的--volumes-from,会在容器apline中自动补全不存在的路径目录
docker run -d -it --volumes-from ngixn01 alpine
六.dockerfile自动构建docker镜像
命令
docker build /opt/dockerfile/nginx/ --network=host -t Centos7nginx:v1
1.dockerfile类似ansible剧本。
2.dockerfile主要组成部分:
基础镜像信息:FROM centos:6.9
制作镜像操作指令:RUN yum install openssh-server -y
容器启动时执行初始命令:CMD [“/bin/bash”]
dockerfile常用指令
FROM 这个镜像的妈妈是谁?(指定基础镜像)
MAINTAINER 告诉别人,谁负责养它?(指定维护者信息,可以没有)
LABLE 描述,标签
RUN 你想让它干啥(在命令前面加上RUN即可)
ADD 给它点创业资金(会自动解压tar) 制作
docker基础的系统镜像 WORKDIR 我是cd,今天刚化了妆(设置当前工作目录)
VOLUME 给它一个存放行李的地方(设置卷,挂载主机目录)
EXPOSE 它要打开的门是啥(指定对外的端口)(-P 随机端口) CMD 奔跑吧,兄弟!(指定容器启动后的要干的事情)(容易被替换)
dockerfile其他指令:
COPY 复制文件(不会解压)rootfs.tar.gz ENV 环境变量(密码,其他信息)
ENTRYPOINT 容器启动后执行的命令(无法被替换,启容器的时候指定 的命令,会被当成参数)
七. 镜像的分层结构
实际上,Docker Hub中99%的镜像都是通过在base镜像中安装和配置需要的软件构建出来的,比如我们现在构建一个新的镜像,Dockerfile如下:
①:新镜像不再是从scratch开始,而是直接在 Debian base 镜像上构建。
②:安装 emacs 编辑器。
③:安装 apache2。
④:容器启动时运行 bash。
这时可能就有人会问了:如果多个容器共享一份基础镜像,当某个容器修改了基础镜像的内容,比如 /etc 下的文件,这时其他容器的 /etc 是否也会被修改?
答案是不会!
修改会被限制在单个容器内。
这就是我们接下来要学习的容器 Copy-on-Write 特性。
可写的容器层
当容器启动时,一个新的可写层被加载到镜像的顶部。
这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
- 添加文件
在容器中创建文件时,新文件被添加到容器层中。 - 读取文件
在容器中读取某个文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,打开并读入内存。 - 修改文件
在容器中修改已存在的文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之。 - 删除文件
在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件。找到后,会在容器层中记录下此删除操作。
只有当需要修改时才复制一份数据,这种特性被称作 Copy-on-Write。可见,容器层保存的是镜像变化的部分,不会对镜像本身进行任何修改。
docker镜像的优化
1:尽可能选择体积小linux发行版,alpine
2:尽可能合并RUN指令,清理无用的文件(yum缓存,源码包)
3:修改dockerfile,把变化的内容尽可能放在dockerfifile结尾
4: 使用.dockerignore,减少不必要的文件ADD . /html
八.容器间的互联(–link是单方向的)
# 创建一个nginx容器
docker run -d -p 80:80 nginx
# 创建容器,做link,并进入容器中
docker run -it --link quirky_brown:web01 centos-ssh /bin/bash
# 在容器中访问nginx容器可以ping通
docker exec nginx ping web01
启动zabbix容器
1、启动一个mysql的容器
docker run --name mysql-server -t \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix_pwd" \
-e MYSQL_ROOT_PASSWORD="root_pwd" \
-d mysql:5.7 \
--character-set-server=utf8 --collation-server=utf8_bin
2、启动java-gateway容器监控java服务
docker run --name zabbix-java-gateway -t \
-d zabbix/zabbix-java-gateway:latest
3、启动zabbix-mysql容器使用link连接mysql与java-gateway。
docker run --name zabbix-server-mysql -t \
-e DB_SERVER_HOST="mysql-server" \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix_pwd" \
-e MYSQL_ROOT_PASSWORD="root_pwd" \
-e ZBX_JAVAGATEWAY="zabbix-java-gateway" \
--link mysql-server:mysql \
--link zabbix-java-gateway:zabbix-java-gateway \
-p 10051:10051 \
-d zabbix/zabbix-server-mysql:latest
4、启动zabbix web显示,使用link连接zabbix-mysql与mysql。
docker run --name zabbix-web-nginx-mysql -t \
-e DB_SERVER_HOST="mysql-server" \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix_pwd" \
-e MYSQL_ROOT_PASSWORD="root_pwd" \
--link mysql-server:mysql \
--link zabbix-server-mysql:zabbix-server \
-p 80:80 \
-d zabbix/zabbix-web-nginx-mysql:latest
九.docker仓库(registry)
1.创建一个普通仓库
1.创建仓库
docker run -d -p 5000:5000 --restart=always --name registry -v /opt/myregistry:/var/lib/registry registry
2.修改配置文件,使之支持http
[root@docker01 ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"insecure-registries": ["10.0.0.110:5000"]
}
#重启
[root@docker01 ~]# systemctl restart docker.service
3.修改镜像标签
[root@docker01 ~]# docker tag alpine:latest 10.0.0.110:5000/alpine:v1.0
4.上传镜像到仓库
[root@docker01 ~]# docker push 10.0.0.110:5000/alpine:v1.0
2.创建basic认证的仓库
1.安装加密工具
[root@docker01 ~]# yum install httpd-tools -y
2.设置认证密码
[root@docker01 ~]# mkdir /opt/registry/auth/ -p
[root@docker01 ~]# htpasswd -Bbn zhangxianwei 123456 > /opt/registry/auth/htpasswd
3.在启动时传入认证参数
[root@docker01 ~]# docker run -d -p 5000:5000 -v /opt/myregistry:/var/lib/registry -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e "REGISTRY_AUTH_HTPASSWD_PATH=/opt/registry/auth/htpasswd" registry
4.使用用户测试
#登录用户
[root@docker01 ~]# docker login 10.0.0.110:5000
Username: zhangxianwei
Password: 123456
Login Succeeded
#修改镜像标签
[root@docker01 ~]# docker tag alpine:v1 10.0.0.110:5000/zhangxianwei/alpine:v1
#推送镜像到仓库
[root@docker01 ~]# docker push 10.0.0.110:5000/zhangxianwei/alpine:v1
3.删除私人仓库镜像
1.进入docker registry的容器中
docker exec -it registry /bin/sh
2.删除repo
rm -rf /var/lib/registry/docker/registry/v2/repositories/alpine
3.清除blob
registry garbage-collect /etc/docker/registry/config.yml
十.docker-compose编排工具
用docker run 容器的时候需要配置很多内容比如端口映射,磁盘挂载,环境变量等,全部在命令中格式麻烦也不好保存,并且如果多个容器之前需要关联也特别麻烦,所以有了Docker三剑客之一的Docker-compose出面来解决这个问题.
1.安装docker-compose
# 下载pip软件
yum install -y python2-pip
# 下载 docker-compose
pip install docker-compose
2.创建文件目录
[root@docker01 ~]# mkdir /opt/my_wordpress/
[root@docker01 ~]# cd /opt/my_wordpress/
3.编写编排文件
[root@docker01 my_wordpress]# vim docker-compose.yml
version: '3' #必须指定版本
services:
db: #容器名称
image: mysql:5.7
volumes:
- /data/db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- /data/web_data:/var/www/html
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
4.运行docker-compose
[root@oldboy zabbix]# docker-compose up
十一.容器的资源限制cgroup
cpu:–cpus 1
docker run -d -it --cpus 1 --name bbox1 alpine:v1
mem: --memory 200M
swap: --memory-swap 100M
十二.重启docker服务,容器全部退出的解决办法
1.在启动时指定自动重启
docker run --restart=always
2.修改/etc/docker/daemon.json配置文件
#加上 “live-restore”: true
[root@docker02 ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"graph": "/opt/mydocker", # 修改数据的存放目录到/opt/mydocker/,原/var/lib/docker/
"insecure-registries": ["10.0.0.100:5000"],
"live-restore": true
}
重启生效,只对在此之后启动的容器生效
[root@docker01 ~]# systemctl restart docker.service
十三.Harbor企业级仓库
harbor为企业级私有Registry服务器,可结合kubernetes作为其后端仓库。harbor镜像仓库为VMware产品,harbor仓库较其他仓库软件的优点有:审计管控、权限分配等。为企业私库的首选。
Harbor安装
1.安装环境:harbor 1.6.2 需要的运行环境:docker 17.03.0-ce+ and docker-compose 1.10.0+ .
Centos: CentOS 7.3
Docker: 18.03.1-ce
Docker-composer: 1.23.2
Harbor: harbor-offline-installer-v1.6.2.tgz
2.下载Harbor离线包
https://github.com/vmware/harbor/releases
安装有两种方式,一种是off-line ,一种是on-line,即离线和在线安装,离线安装需要下载的安装包较大,在线安装下载的安装包很小,这里推荐离线安装,一次下载完
[root@localhost harbor]# wget https://storage.googleapis.com/harbor-releases/release-1.9.0/harbor-offline-installer-v1.6.2.tgz
解压
[root@localhost harbor]# tar xvf harbor-offline-installer-v1.6.2.tgz
3.配置
在harbor的解压目录里,有下列文件,其中 harbor.cfg是配置文件,install.sh是安装文件
drwxr-xr-x. 3 root root 23 Dec 9 22:41 common
-rw-r--r--. 1 root root 813 Nov 20 13:59 docker-compose.chartmuseum.yml
-rw-r--r--. 1 root root 863 Nov 20 13:59 docker-compose.clair.yml
-rw-r--r--. 1 root root 1258 Nov 20 13:59 docker-compose.notary.yml
-rw-r--r--. 1 root root 3675 Nov 20 13:59 docker-compose.yml
drwxr-xr-x. 3 root root 136 Nov 20 13:59 ha
-rw-r--r--. 1 root root 7913 Nov 20 13:59 harbor.cfg
-rwxr-xr-x. 1 root root 6162 Nov 20 13:59 install.sh
-rw-r--r--. 1 root root 10768 Nov 20 13:59 LICENSE
-rw-r--r--. 1 root root 482 Nov 20 13:59 NOTICE
-rw-r--r--. 1 root root 1535603 Nov 20 13:59 open_source_license
-rwxr-xr-x. 1 root root 39132 Nov 20 13:59 prepare
修改配置,使用IP地址访问harbor,暴露的端口是5000
# 监听地址,不能设置为127.0.0.1或者localhost,这里设置的是docker host的ip地址
hostname = 192.168.88.30:5000
# 登录密码,默认密码:Harbor12345
harbor_admin_password = 123456
再修改docker-compose.yml,映射容器中的80端口到host的5000端口
proxy:
image: goharbor/nginx-photon:v1.6.2
container_name: nginx
restart: always
volumes:
- ./common/config/nginx:/etc/nginx:z
networks:
- harbor
ports:
#需要改这里
- 5000:80
- 443:443
- 4443:4443
4.安装
运行安装目录里面的 install.sh。耐心等待,如果是在线安装版本,需要下载一些docker镜像,如果已经 docker – 镜像加速器 配置了加速器,那是相当快的。
[root@localhost harbor]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
goharbor/redis-photon v1.6.2 473bfdd9d245 2 weeks ago 210MB
goharbor/registry-photon v2.6.2-v1.6.2 62c30cdb384a 2 weeks ago 196MB
goharbor/nginx-photon v1.6.2 c0602500e829 2 weeks ago 132MB
goharbor/harbor-log v1.6.2 781ee4ceb5d3 2 weeks ago 197MB
goharbor/harbor-jobservice v1.6.2 3419a2276f96 2 weeks ago 192MB
goharbor/harbor-ui v1.6.2 66268686bb96 2 weeks ago 215MB
goharbor/harbor-adminserver v1.6.2 4024440925a4 2 weeks ago 181MB
goharbor/harbor-db v1.6.2 0ed4186be0d1 2 weeks ago 219MB
查看启动了的容器
[root@localhost harbor]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
18c82d20d070 goharbor/harbor-jobservice:v1.6.2 "/harbor/start.sh" 2 minutes ago Up About a minute harbor-jobservice
1a807ff9307d goharbor/nginx-photon:v1.6.2 "nginx -g 'daemon of…" 2 minutes ago Up About a minute (health: starting) 0.0.0.0:443->443/tcp, 0.0.0.0:4443->4443/tcp, 0.0.0.0:5000->80/tcp nginx
83428db239b3 goharbor/harbor-ui:v1.6.2 "/harbor/start.sh" 2 minutes ago Up 23 seconds (health: starting) harbor-ui
d785d1e0b4fb goharbor/redis-photon:v1.6.2 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 6379/tcp redis
126657d6e33c goharbor/harbor-adminserver:v1.6.2 "/harbor/start.sh" 2 minutes ago Restarting (1) 3 seconds ago harbor-adminserver
1ac23c837879 goharbor/registry-photon:v2.6.2-v1.6.2 "/entrypoint.sh /etc…" 2 minutes ago Up 2 minutes (healthy) 5000/tcp registry
d080851c8190 goharbor/harbor-db:v1.6.2 "/entrypoint.sh post…" 2 minutes ago Up 2 minutes (healthy) 5432/tcp harbor-db
b47254ceba04 goharbor/harbor-log:v1.6.2 "/bin/sh -c /usr/loc…" 2 minutes ago Up 2 minutes (healthy) 127.0.0.1:1514->10514/tcp harbor-log
十二.五种网络
1.None :不为容器配置任何网络功能,没有网络 --net=none
root@docker01 ~]# docker run -it --network none busybox:latest /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2.Container :与另一个运行中的容器共享Network Namespace,–net=container:containerID.
此模式和host模式很类似,只是此模式创建容器共享的是其他容器的IP和端口而不是物理机,此模式容器自身是不会配置网络和端口,创建此模式容器进去后,你会发现里边的IP是你所指定的那个容器IP并且端口也是共享的,而且其它还是互相隔离的,如进程等。
[root@docker01 ~]# docker run -it --network container:mywordpress_db_1 busybox:latest /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
105: eth0@if106: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
3.Host :与主机共享Network Namespace,–net=host
此模式创建的容器没有自己独立的网络命名空间,是和物理机共享一个Network Namespace,并且共享物理机的所有端口与IP,并且这个模式认为是不安全的。
[root@docker01 ~]# docker run -it --network host busybox:latest /bin/sh
4.Bridge: Docker设计的NAT网络模型**(默认类型)**
none网络
故名思议,none 网络就是什么都没有的网络。挂在这个网络下的容器除了 lo,没有其他任何网卡。容器创建时,可以通过 --network=none
指定使用 none 网络。
在这里插入图片描述
5.user-defined模式网络:
1.macvlan:Macvlan网络允许您为容器分配MAC地址,使其显示为网 络上的物理设备。Docker守护程序通过其MAC地址将流量路由到容器。macvlan 在处理期望直接连接到物理网络的传统应用程序时,使用驱动程序有时是最佳选择,而不是通过Docker主机的网络堆叠进行路由
2.overlay模式网络 使用–net=overlay,覆盖网络将多个Docker守护程序连接在一起,并使群集服务能够相互通信。还可以使用覆盖网络来促进群集服务和独立容器之间的通信,或者在不同Docker守护程序上的两个独立容器之间进行通信
十三.docker容器跨网络通讯
1.跨主机通讯之macvlan
1.1 创建macvlan网络类型
docker network create --driver macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.254 -o parnet=eth0 macvlan_1
检查创建成功
docker network ls
1.2 在host1中创建容器bbox1并连接到macvlan_1
docker run -it -d --name bbox1 --ip=10.0.0.10 --network macvlan_1 busybox
中…(img-YKc9g6Ty-1576333458864)]
5.user-defined模式网络:
1.macvlan:Macvlan网络允许您为容器分配MAC地址,使其显示为网 络上的物理设备。Docker守护程序通过其MAC地址将流量路由到容器。macvlan 在处理期望直接连接到物理网络的传统应用程序时,使用驱动程序有时是最佳选择,而不是通过Docker主机的网络堆叠进行路由
2.overlay模式网络 使用–net=overlay,覆盖网络将多个Docker守护程序连接在一起,并使群集服务能够相互通信。还可以使用覆盖网络来促进群集服务和独立容器之间的通信,或者在不同Docker守护程序上的两个独立容器之间进行通信