Docker 仓库与网络
DockerHub
基础介绍
Docker-Hub是Docker的一个镜像存储仓库,类似于GitHub。
全世界各地的优秀镜像都会存放于此处,使用docker search时,获取到的镜像也都是由Docker-Hub提供。
搭建命令化仓库
在某些环境中,可能我们需要搭建一个属于自己局域网内的私有镜像存储仓库。
下面将介绍如何一步一步搭建本地私有镜像仓库,我们至少需要2台机器来进行测试,在一台机器上搭建私有仓库,另一台机器通过局域网就能上传或下载以push的镜像。
第一步,启动registry组件容器:
$ mkdir -p /opt/registry
$ docker run -d -p 5000:5000 --restart=always --name=registry -v /opt/registry:/var/lib/registry registry
# --restart=always是指docker服务重启后立即重新运行该容器,而不需要手动start
第二步,所有需要连接该本地docker仓库的节点都需要修改docker配置文件并重启docker服务:
$ vim -p /etc/docker/daemon.json
{
"registry-mirrors": ["https://uoggbpok.mirror.aliyuncs.com"],
"insecure-registries": ["192.168.0.120:5000"]
}
$ systemctl daemon-reload
$ systemctl restart docker
# 对于insecure-registries来说,配置的ip即为本地docker仓库的服务器ip地址
第三步,本地docker仓库服务器添加上传镜像需要的密码认证,增加安全系数:
$ yum install httpd-tools -y
$ mkdir -p /opt/registry-auth/
$ htpasswd -Bbn userName passWord > /opt/registry-auth/htpasswd
第四步,本地docker仓库服务器重启带有秘钥功能的registery容器:
$ docker container rm -f registry
$ docker run -d -p 5000:5000 -v /opt/registry-auth/:/auth/ -v /opt/registry:/var/lib/registry --name register-auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" registry
第五步,使用另一台机器进行上传测试,你需要先进行登录:
$ docker login 192.168.0.120:5000
Username: userName
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
第五步,制作本地镜像并push到本地仓库中,需要注意的是你必须遵守镜像的name格式才能进行push,规则如下:
$ docker tag nginx 192.168.0.120:5000/nginx:v1
$ docker push 192.168.0.120:5000/nginx:v1
# 规则 私有的registry服务器ip地址:端口/镜像名/镜像标签
第六步,删除本地镜像,重新进行pull:
$ docker image rm -f 192.168.0.120:5000/nginx:v1
$ docker pull 192.168.0.120:5000/nginx:v1
搭建图形化仓库
本地图形化的Docker registery是企业中经常用到的,搭建过程也很简单。
还是准备2台服务器,一台搭图形化的Docker registery,另一台浏览器上进行访问测试。
第一步,安装docker-compose:
$ yum install -y docker-compose
第二步,下载harbor-offline-installer-vxxx.tgz软件到并解压到/opt目录:
$ cd ~
$ wget https://storage.googleapis.com/harbor-releases/harbor-offline-installer-v1.5.1.tgz
$ tar -zxvf ./harbor-offline-installer-v1.5.1.tgz -C /opt/
第三步,修改harbor.cfg配置文件:
$ vim /opt/harbor/harbor.cfg
hostname = 192.168.0.120
harbor_admin_password = 123456
第四步,执行install.sh:
$ /opt/harbor/install.sh
第五步,在本地docker仓库的节点都需要修改docker配置文件并重启docker服务:
$ vim -p /etc/docker/daemon.json
{
"registry-mirrors": ["https://uoggbpok.mirror.aliyuncs.com"],
"insecure-registries": ["192.168.0.120:5000", "192.168.0.120"],
# 仅在本地搭建docker registry仓库的服务器添加下面这个
"live-restore": true
}
$ systemctl daemon-reload
$ systemctl restart docker
# 对于insecure-registries来说,配置的ip即为本地docker仓库的服务器ip地址,前一个是命令化仓库,后一个是图形化仓库访问地址
# "live-restore": true 是指docker服务重启后立即重新所有容器,而不需要手动start
# 现在我们有2个仓库,第2个是图形化,别搞混了
第六步,用另外一台机器打开浏览器访问192.168.0.120,应该能看见仓库页面了,用户名是admin,密码是设置的123456。
第五步,登录:
$ docker login 192.168.0.120
Username: admin
Password: 123456
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
由于我们现在有2个本地仓库,一个5000端口的命令行仓库,一个80端口的图形化仓库,所以push时要注意选择哪个。
$ docker tag nginx 192.168.0.120/project/nginx:v1
$ docker push 192.168.0.120/project/nginx:v1
$ docker pull 192.168.0.120/project/nginx:v1
# 更名规则 docker push 192.168.0.120/项目名/IMAGE:TAG
容器网络
本地网络
查看支持的本地网络类型:
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
eb9e0641bc0e bridge bridge local
bc0ec5104ef5 harbor_harbor bridge local
343fc6a20365 host host local
39edc3133901 none null local
# none :不支持网络
# bridge :默认模式,相当于NAT
# host:容器与宿主机公用Network NameSpace
# container:与其他容器公用Network NameSpace
如何在启动容器时指定网络类型?
$ docker run network=xxx
每个docker宿主机都会有一块虚拟的docker0网卡(172.17.0.1/16),在bridge模式中,docker0网卡作为所有容器中网卡的网关。
通过NAT地址转换,实现各个容器之间的互联,并且docker0网卡与真实物理网卡配合,以达到容器访问外网的目的,但是外网不能直接访问容器,必须使用容器与宿主机的端口映射。
在host模式中,各个容器都使用宿主机的NetWork NameSpace,如果容器A是MySQL,则启动服务就占用3306端口,这代表外网访问容器不需要通过容器与宿主机之间的端口映射,但是容器与容器之间不能互相通信。
如果启用该模式,宿主机与容器,容器与容器之间的ip和hostname都将相同。
在container模式中,多个容器共同抢占一个NetWork NameSpace,如果一个容器的服务停止,其他容器就会抢占该NetWork NameSpace,可以用该种模式做分布式高可用服务。
bridge容器互联
多个容器之间进行互联,首先要创建一个Docker网络:
$ docker network create -d bridge my-net
运行一个容器并连接到新建的my-net网络:
$ docker run -it --rm --name="busybox1" --network my-net busybox sh
打开新的终端,再运行一个容器并加入到my-net网络:
$ docker run -it --rm --name="busybox2" --network my-net busybox sh
这样busybox1和busybox2就互联成功啦。
跨主机网络
跨主机网络指的是不同docker服务器上的容器如何进行互联。
有以下两种模式:
- macvlan
- overlay
使用macvlan模式,会为多台主机中的容器创建一个共享通道,但是不能对外提供服务,外网也访问不进来。
且配置较为麻烦:
使用方式:
# 两台docker宿主机都在一块新网卡上执行下面命令,创建一个专属的macvlan通道
$ docker network create --driver macvlan --subnet=10.0.0.0/24 --gateway=10.0.0.254 -o parent=eth0 macvlan_1
# $ ip link set eth0 promsic on (ubuntu或其他版本需要设置)
# 第一台宿主机,手动指定ip防止两方冲突
$ docker run -it --network macvlan_1 --ip=10.0.0.1 centos:6.9 /bin/bash
# 第二台宿主机,手动指定ip防止两方冲突
$ docker run -it --network macvlan_1 --ip=10.0.0.2 centos:6.9 /bin/bash
# parent=eth0 在哪个网卡上建立
# 如果要删除macvlan,可执行 docker network rm macvlan_1
如果没有多余的网卡,可添置一个虚拟网卡:
ifconfig eth0:1 172.16.0.254/24
使用overlay模式,会为多台主机中的容器创建一个共享通道,这个共享通道是自动管理的,并且还会为容器提供对外服务。类似macvlan和bridge模式的结合体:
使用方式:
# 在任意一台docker宿主机上运行如下命令,启动管理容器
$ docker run -d -p 8500:8500 -h consul --restart=always --name consul progrium/consul -server -bootstrap
# 在两台docker宿主机上,编辑一下脚本,让双方都能连接上管理容器,用于ip地址派发
$ vim /etc/docker/daemon.json
{
"hosts":["tcp://0.0.0.0:2376","unix:///var/run/docker.sock"],
"cluster-store": "consul://10.0.0.100:8500",
"cluster-advertise": "10.0.0.100:2376"
}
# 新版docker要改这个配置
$ vim /usr/lib/systemd/system/docker.service
# 重启
$ systemctl daemon-reload
$ systemctl restart docker
# 创建overlay网络,ol1是网络名词
$ docker network create -d overlay --subnet 172.16.0.0/24 --gateway 172.16.0.254 ol1
# 启动容器测试,现在每个容器有两块网卡,一块实现容器间的通讯,一块实现容器访问外网
$ docker run -it --network ol1 busybox /bin/bash