Dockerの基本操作


#1.          docker  
docker image ls 
#   :docker images
#        、   (tag)、  ID、    、    
#docker           ,  docker    Union FS    ,             ;
#                     ;             、  、         :
docker system df

#2.    
#      docker build           docker pull      ,                  
#           ,             ,    :
#           :
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

以上の2つのコマンドdockerは、ローカルホスト上でランダムディレクトリを自動的に生成してコンテナにマウントします.
3.実行時指定ディレクトリをコンテナにマウントする
docker run -it -v `pwd`:/data ubuntu:14.04 bash

現在のディレクトリがコンテナの/dataディレクトリにマウントされていることを指定します.この場合、ミラー自体が/datavolumeとして指定した場合、元のディレクトリ内のファイルはコンテナにコピーされません.ホストの現在のディレクトリファイルは、コンテナの/dataディレクトリにコピーされます.
4.運転時にコンテナボリュームをコンテナにマウントすることを指定
docker run -it -v test_v:/data ubuntu:14.04 bash

このとき、docker volumelstest_vという容器ボリュームがなければ、dockertest_vという容器ボリュームを自動的に作成する.
コンテナを実行する場合、ディレクトリまたはコンテナボリュームが指定されず、dockerで自動的に生成されたディレクトリをボリュームとしてコンテナにマウントすると、docker rm container -vを実行するとボリューム内のすべてのファイルが一括して削除されます.他の2つの方法のファイルは削除されません
linuxネットワークブリッジ
ネットワーク名空間の表示
ip netns list

現在のブリッジ、NICリストの表示
ip link list

ネットワーク名空間の作成
ip netns add netns_test

仮想NICのペアを追加
ip link add veth_1 type veth peer name eth_1

仮想NICの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


ネットワーク名空間の仮想NICを起動
ip netns exec netns_test ip link set dev eth_1 up

ホストの仮想NICにIpを設定する
ip addr add 10.0.0.1/24 dev veth_1

ホストの仮想NICの起動
ip link set dev veth_1 up

ネットワーク名空間の仮想NIC pingホストのNIC
ip netns exec netns_test ping 10.0.0.1

ホスト仮想NIC pingネットワーク名空間の仮想NIC
ping 10.0.0.2

ネットネームスペースの削除
ip netns delete netns_test

ネットワーク名空間仮想NICの削除
ip netns exec netns_test ip link delete eth_1

仮想NICの削除
ip link delete veth_1


ブリッジの削除
brctl delbr br_name


ブリッジからのNICの削除
brctl delif br_name eth_name1 eth_name2

デフォルトでは、dockerのすべてのコンテナの仮想NICはペアで存在し、1つのホスト(veth[xxxxx])はdocker0というブリッジにマウントされ、もう1つはコンテナのネットワーク名空間にマウントされています(eth0).したがって、ホスト上のすべてのコンテナは、イントラネットIPを介して通信することができる.
練習:dockerコンテナのネットワークを構成する
1.まず、ネットワーク構成のない2つのコンテナを起動する
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.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.2対(4枚)の仮想NICを追加
sudo ip link add veth1 type veth peer name eth1
sudo ip link add veth2 type veth peer name eth2

4.2つのNICをそれぞれ対応するコンテナのネットワーク名空間に配置する
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.仮想ブリッジを追加し、作成した仮想NICの残りの2つをブリッジ上に配置して起動
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 <
#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