Docker的基本操作

#1.列出当前系统中所有的docker镜像
docker image ls 
#旧版本:docker images
#该命令会列出仓库、镜像名(tag)、镜像ID、创建时间、镜像大小
#docker的镜像是多层存储结构的,由于docker使用的是Union FS文件系统,相同的层文件只需要存储一份;
#因此镜像的总大小可能比列出来的总和要小的多;可以用使用以下命令查看镜像、容器、数据卷所占用的空间:
docker system df

#2.虚悬镜像
#如果我们使用docker build 构建同名镜像或者使用docker pull拉取同名镜像,本地的同名镜像的仓库和镜像名就会变成<none>;
#此时的镜像称为虚悬镜像,此类镜像已经没有存在的必要,可以删除:
#专门显示此类镜像的命令:
docker image ls -f dangling=true

#删除此类镜像的命令:
docker image purne

#3.中间层镜像
#由于docker是多层结构,在使用一段时间后,系统中会出现很多中间层依赖镜像,默认的docker image ls只显示顶层镜像;如果希望
#查看所有镜像,可以使用以下命令:(可能会看到很多无标签的镜像,此类镜像为其他镜像的依赖镜像,不能删除)
docker image ls -a
docker image ls -a -q (只显示镜像Id)


#4.更多查看指令
#4.1查看指定仓库镜像
docker image ls ubuntu

#4.2 查看指定镜像
docker image ls ubuntu:14.04

#4.3查看自从某个时间之后的镜像
docker image ls -f since=ubuntu:14.04

#4.4按指定格式显示镜像(格式按照go的模板参数格式)
docker image ls --format "{{.ID}}: {{.Repository}}"


#5.删除镜像(只能删除没有容器的镜像;如果使用该镜像运行了容器,则需先删除依赖的容器再删除该镜像)
docker image rm [镜像id] [镜像名]
#对应老版本的docker rmi
#由于镜像是分层存储的,删除过程会一层一层删除;并且docker多个标签可以对应一个镜像,当删除一个标签时,还有其他标签指向
#该镜像时,docker image rm 只会执行untagged指令,不会执行deleted指令,只有当没有标签对应该镜像时;才会真正删除该镜像

#删除所有镜像
docker image rm $(docker image ls -q)

Docker Volume操作

1.创建单独的volume

docker volume create --name test_v 

2.通过运行时+ -v参数来指定volume

docker run -it -v /data ubuntu:14.04 bash

以上两个命令docker会在本地主机上自动生成一个随机目录挂载到容器内

3.运行时指定目录挂载到容器

docker run -it -v `pwd`:/data ubuntu:14.04 bash

指定当前目录挂载到容器的/data目录上,此时如果镜像本身指定了/data作为volume,则原来的目录内的文件不会拷贝到容器中;主机的当前目录文件会拷贝到容器的/data目录;

4.运行时指定容器卷挂载到容器

docker run -it -v test_v:/data ubuntu:14.04 bash

此时如果docker volumels中如果没有test_v这个容器卷,则docker会自动创建名为test_v的容器卷;

如果运行容器时,没有指定目录或者容器卷,而使用docker自动生成的目录作为卷挂载到容器中的,
执行docker rm container -v会把卷中的所有文件一并删除;其他两种方式的文件不会删除

linux网络桥接

查看网络名字空间

ip netns list

查看当前的网桥、网卡列表

ip link list

创建网络名字空间

ip netns add netns_test

添加一对虚拟网卡

ip link add veth_1 type veth peer name eth_1

将其中一块虚拟网卡添加进网络名字空间netns_test

ip link set eth_1 netns netns_test

给网络名字空间的网卡配置ip

ip netns exec netns_test ip addr add 10.0.0.2/24 dev eth_1

启动网络名字空间里面的虚拟网卡

ip netns exec netns_test ip link set dev eth_1 up

给主机的虚拟网卡配置Ip

ip addr add 10.0.0.1/24 dev veth_1

启动主机的虚拟网卡

ip link set dev veth_1 up

网络名字空间的虚拟网卡ping主机的网卡

ip netns exec netns_test ping 10.0.0.1

主机虚拟网卡ping网络名字空间的虚拟网卡

ping 10.0.0.2

删除网络名字空间

ip netns delete netns_test

删除网络名字空间虚拟网卡

ip netns exec netns_test ip link delete eth_1

删除虚拟网卡

ip link delete veth_1

删除网桥

brctl delbr br_name

从网桥上的移除网卡

brctl delif br_name eth_name1 eth_name2

默认情况下,docker中所有容器的虚拟网卡都是成对存在的,一个存在主机(veth[xxxxx]),挂载在docker0这个网桥上,另一个挂载在容器的网络名字空间里面(eth0);所以,主机上的所有容器都可以通过内网IP进行通信。

练习:配置docker容器的网络

1.首先,启动两没有网络配置的容器

docker run --rm -it --net=none --name docker1 ubuntu:14.04 bash
docker run --rm -it --net=none --name docker2 ubuntu:14.04 bash

2.查询两docker容器的进程id,并对各自的网络名字空间设置软链接

docker inspect --format '{{ .State.Pid}}' docker1
6225 
docker inspect --format '{{ .State.Pid}}' docker2
6385

sudo ln -s /proc/6225/ns/net /var/run/netns/netns_docker_1
sudo ln -s /proc/6385/ns/net /var/run/netns/netns_docker_1

3.添加两对(4块)虚拟网卡

sudo ip link add veth1 type veth peer name eth1
sudo ip link add veth2 type veth peer name eth2

4.将两块网卡分别设置进相应容器的网络名字空间

sudo ip link set eth1 netns netns_docker_1
sudo ip link set eth2 netns netns_docker_2

5.分别给网络名字空间里面的网卡设置ip,并启动网卡

sudo ip netns exec netns_docker_1 ip addr add 10.0.0.2/24 dev eth1
sudo ip netns exec netns_docker_2 ip addr add 10.0.0.3/24 dev eth2
sudo ip netns exec netns_docker_1 ip link set dev eth1 up
sudo ip netns exec netns_docker_2 ip link set dev eth2 up

6.添加虚拟网桥,并将刚才创建的虚拟网卡中的剩余两块配置在网桥上,并启动

sudo brctl addbr br0
brctl addif br0 veth1 veth2
sudo ifconfig br0 up
sudo ifconfig veth1 up
sudo ifconfig veth2 up

7.在两容器中通信


tools.py

#!/bin/env  python
#-*- encoding:utf-8 -*-

import os
import json
import hashlib
import urlparse
import functools
import requests


#1.获取镜像tag列表
TAG_LIST_URL = "http://127.0.0.1:5000/v2/ubuntu/tags/list"
#2.获取镜像的manifest
MANIFEST_INFO_URL = "http://127.0.0.1:5000/v2/ubuntu/manifests/16.04"
#3.获取服务中的仓库列表
REPOSITORIES_LIST_URL = "http://127.0.0.1:5000/v2/_catalog"

headers = {
    'Accept': 'application/vnd.docker.distribution.manifest.list.v2+json, application/vnd.docker.distribution.manifest.v1+prettyjws, application/json, application/vnd.docker.distribution.manifest.v2+json'
}


DOMAIN = "http://127.0.0.1:5000/v2/"
DOCKERPATH = "/var/lib/docker"
DOCKERPATH = "/data/docker"
DOCKERDRIVER = "overlay2"

def read_json(fn, key, default=None):
    """get data from json file"""
    if not os.path.exists(fn):
        return default
    with open(fn) as fd:
        data = fd.read()
        try:
            return json.loads(data).get(key, default)
        except:
            pass
    return default

def read_data(fn):
    """read data from normal file"""
    if not os.path.exists(fn):
        return ""
    with open(fn) as fd:
        return fd.read().strip()
    return ""

def get_manifest_info(image, tag):
    """request image manifest, which contains config and layers info"""
    url = urlparse.urljoin(DOMAIN, image+"/manifests/"+tag)
    rep = requests.get(url, headers=headers)
    headdigest = rep.headers['docker-content-digest'].split(":")[1]
    contdigest = hashlib.sha256(rep.text).hexdigest()
    if headdigest == contdigest:
        print(rep.text)
        return rep.text
    return ""

def echo_image_info(imageid):
    path = os.path.join(DOCKERPATH, "image", DOCKERDRIVER,
                        "imagedb/content/sha256", imageid)
    if not os.path.exists(path):
        print("Image[%s] metadata:%s not exists "%(imageid, path))
        return
    diffids = read_json(path, "rootfs", {}).get("diff_ids", [])
    laymeta = diffid_to_layermetadata(diffids)
    laymeta = map(lambda x:
                  DOCKERPATH+"/image/"+DOCKERDRIVER+"/layerdb/sha256/"+x,
                  laymeta)
    layers = map(laymeta_to_layer, laymeta)
    imageinfo = {
        "image_metadata": path,
        "diff_ids": diffids,
        "layers_metapath": laymeta,
        "layers_path": layers,
    }
    print(json.dumps(imageinfo, indent=4))

def laymeta_to_layer(laypath):
    layer = read_data(laypath+"/cache-id")
    return DOCKERPATH+"/"+DOCKERDRIVER+"/"+layer if layer else ""

def diffid_to_layermetadata(diffids):
    """通过diffid计算各层layer的目录名,layer元数据的存放位置"""
    if not diffids: return diffids
    digest = []
    digest.append(diffids[0].split(":")[1])
    def calc_chainid(sli, x, y):
        chainid = hashlib.sha256(x + " " + y).hexdigest()
        sli.append(chainid)
        return "sha256:"+chainid
    reduce(functools.partial(calc_chainid, digest), diffids)
    return digest

def calc_chainid(diffids):
    """chainid的计算方法"""
    difflen = len(diffids)
    if difflen == 1:
        return diffids[0]
    elif difflen == 2:
        return "sha256:"+hashlib.sha256(diffids[0] + " " +
                                        diffids[1]).hesdigest()
    return calc_chainid([calc_chainid(diffids[:difflen-1]), diffids[difflen-1]])

def main():
    data = get_manifest_info("ubuntu", "16.04")
    imageid = json.loads(data).get("config", {}).get("digest", "").split(":")[1]
    print("Image:[ubuntu:16.04] ID:[%s]"%imageid)
    echo_image_info(imageid)


if __name__ == "__main__":
    main()

centos_docker_install.sh

#!/bin/bash
#Centos7 安装docker

#1.删除旧版本
sudo yum remove -y docker-ce docker docker-common docker-selinux docker-engine

#2.安装依赖包
sudo yum install -y yum-utils device-mapper-persistent-data lvm

#3.替换国内源
sudo yum-config-manager --add-repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
#阿里源
#sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#官方源
#sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

#4.安装docker-ce软件包
sudo yum makecache fast
sudo yum install -y docker-ce

#5.默认情况下, docker 命令会使用 Unix socket 与 Docker 引擎通讯。而只有 root 用户和docker 组的用户才可以访问 
#Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 root 用户。因此,更好地做法是将需要使
#用 docker 的用户加入 docker用户组
sudo groupadd docker
sudo usermod -aG docker $USER

#6.开启开机启动(新版本)
sudo mkdir /etc/docker && sudo cp ./daemon.json /etc/docker/ -f
sudo systemctl enable docker
sudo systemctl start docker


#默认配置下,如果在 CentOS 使用 Docker CE 看到下面的这些警告信息:
#	WARNING: bridge-nf-call-iptables is disabled
#	WARNING: bridge-nf-call-ip6tables is disabled
#请添加内核配置参数以启用这些功能。
#$ sudo tee -a /etc/sysctl.conf <<-EOF
#net.bridge.bridge-nf-call-ip6tables = 1
#net.bridge.bridge-nf-call-iptables = 1
#net.ipv4.ip_forward = 1
#EOF
#然后重新加载 sysctl.conf 即可
#$ sudo sysctl -p

#7.配置镜像加速器
#vi /etc/docker/daemon.json
#添加以下内容
#{
#	"registry-mirrors": [
#		"https://registry.docker-cn.com"
#	]
#}
#重启服务
#sudo systemctl daemon-reload
#sudo systemctl restart docker

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值