Docker学习笔记 第一记

*注:部分内容来自于网络摘取
懒得排版,凑合看吧
基于
Linux centos 7
Docker version 1.12.6*

什么是docker

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

docker的特性

    交互式Shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上,例如运行一个一次性交互shell   
    文件系统隔离:每个进程容器运行在完全独立的根文件系统里   
    写时复制:采用写时复制方式创建根文件系统,这让部署变得极其快捷,并且节省内存和硬盘空间   
    资源隔离:可以使用cgroup为每个进程容器分配不同的系统资源   
    网络隔离:每个进程容器运行在自己的网络命名空间里,拥有自己的虚拟接口和IP地址   
    日志记录:Docker将会收集和记录每个进程容器的标准流(stdout/stderr/stdin),用于实时检索或批量检索   
    变更管理:容器文件系统的变更可以提交到新的映像中,并可重复使用以创建更多的容器。无需使用模板或手动配置

docker的原理

docker是一个容器引擎,容器就要求对进程空间、用户空间、网络空间、硬盘空间等等做一些隔离,docker的底层是使用LXC实现的,LXC则使用Linux Namespace技术对各种技术做隔离。

Linux Namespace是Linux提供的一种内核级别环境隔离的方法, 隔离的资源包括:Mount、UTS、IPC、PID、Network、User。

docker的基本构成

Docker学习笔记 第一记_第1张图片

**Docker 镜像(Images): 镜像是用于创建 Docker 容器的模板。是一个只读模板,用来运行Docker容器。
Docker 容器(Container) :容器是独立运行的一个或一组应用。负责应用程序的运行,包括操作系统、用户添加的文件以及元数据。
DockerFile:是文件指令集,用来说明如何自动创建Docker镜像。**
Docker 客户端(Client) 客户端通过命令行或者其他工具使用 Docker API (https://docs.docker.com/reference/api/docker_remote_api) 与 Docker 的守护进程通信。
Docker 主机(Host)
一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。
Docker 仓库(Registry)
Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。
Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。
Docker Machine
Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。

Docker 的安装

安装就不多说了,傻瓜式安装步骤如下:

1、 安装环境 : centOS 7 64位
2、 运行 uname -r 查看当前系统内核
3、 可选运行 yum update 进行 yum的更新
4、 安装docker 运行 yum install docker
5、 安装完毕后,运行 docker info 查看docker信息,在启动后执行
6、 运行 docker –version 查看docker版本
7、 运行 service docker start 启动服务
8、 运行 chkconfig docker on 设置开机启动

运行Docker

安装完毕了,那开始运行喽
先看看这三个操作docker服务的命令吧

service docker start #启动docker服务
service docker stop # 停止docker服务
service docker restart # 重新启动docker 服务

好了,服务起来了?
接下来,看看docker 的版本信息吧
运行 docker –version

[root@bogon myevn]# docker info
Containers: 4
 Running: 0
 Paused: 0
 Stopped: 4
Images: 13
Server Version: 1.12.6
Storage Driver: devicemapper
 Pool Name: docker-8:3-136136012-pool
 Pool Blocksize: 65.54 kB
 Base Device Size: 10.74 GB
 Backing Filesystem: xfs
 Data file: /dev/loop0
 Metadata file: /dev/loop1
 Data Space Used: 891.9 MB
 Data Space Total: 107.4 GB
 Data Space Available: 45.46 GB
 Metadata Space Used: 1.675 MB
 Metadata Space Total: 2.147 GB
 Metadata Space Available: 2.146 GB
 Thin Pool Minimum Free Space: 10.74 GB
 Udev Sync Supported: true
 Deferred Removal Enabled: false
 Deferred Deletion Enabled: false
 Deferred Deleted Device Count: 0
 Data loop file: /var/lib/docker/devicemapper/devicemapper/data
 WARNING: Usage of loopback devices is strongly discouraged for production use. Use `--storage-opt dm.thinpooldev` to specify a custom block storage device.
 Metadata loop file: /var/lib/docker/devicemapper/devicemapper/metadata
 Library Version: 1.02.135-RHEL7 (2016-11-16)
Logging Driver: journald
Cgroup Driver: systemd
Plugins:
 Volume: local
 Network: overlay bridge null host
Swarm: inactive
Runtimes: docker-runc runc
Default Runtime: docker-runc
Security Options: seccomp selinux
Kernel Version: 3.10.0-514.21.2.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
Number of Docker Hooks: 2
CPUs: 2
Total Memory: 2.765 GiB
Name: bogon
ID: G276:IK5Z:5U2N:4DCW:ISYK:DVQE:XQM7:NTEA:4BAX:UACX:YV5P:V2YM
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Insecure Registries:
 127.0.0.0/8
Registries: docker.io (secure)

运行docker --version 或者 docker -v 返回如下:

Docker version 1.12.6, build 1398f24/1.12.6

好,一切正常,按照以往惯例 运行 docker -help


Commands:
    attach    Attach to a running container
    build     Build an image from a Dockerfile
    commit    Create a new image from a container's changes
    cp        Copy files/folders between a container and the local filesystem
    create    Create a new container
    diff      Inspect changes on a container's filesystem
    events    Get real time events from the server
    exec      Run a command in a running container
    export    Export a container's filesystem as a tar archive
    history   Show the history of an image
    images    List images
    import    Import the contents from a tarball to create a filesystem image
    info      Display system-wide information
    inspect   Return low-level information on a container, image or task
    kill      Kill one or more running containers
    load      Load an image from a tar archive or STDIN
    login     Log in to a Docker registry.
    logout    Log out from a Docker registry.
    logs      Fetch the logs of a container
    network   Manage Docker networks
    node      Manage Docker Swarm nodes
    pause     Pause all processes within one or more containers
    port      List port mappings or a specific mapping for the container
    ps        List containers
    pull      Pull an image or a repository from a registry
    push      Push an image or a repository to a registry
    rename    Rename a container
    restart   Restart a container
    rm        Remove one or more containers
    rmi       Remove one or more images
    run       Run a command in a new container
    save      Save one or more images to a tar archive (streamed to STDOUT by default)
    search    Search the Docker Hub for images
    service   Manage Docker services
    start     Start one or more stopped containers
    stats     Display a live stream of container(s) resource usage statistics
    stop      Stop one or more running containers
    swarm     Manage Docker Swarm
    tag       Tag an image into a repository
    top       Display the running processes of a container
    unpause   Unpause all processes within one or more containers
    update    Update configuration of one or more containers
    version   Show the Docker version information
    volume    Manage Docker volumes
    wait      Block until a container stops, then print its exit code

出现一堆命令,不过在深入之前,只有几个关键命令要用到,其他暂且不管。

images   #查看镜像
pull      #拉取一个镜像
push      #提交一个镜像
rm        #删除一个容器
rmi       #删除一个镜像
run       #运行一个容器
stop      #停止一个容器

详细的参数 网上有很多资料,查下就明白啦。

获取一个docker镜像

运行 docker pull busybox

Using default tag: latest
Trying to pull repository docker.io/library/busybox ...
latest: Pulling from docker.io/library/busybox
Digest: sha256:be3c11fdba7cfe299214e46edc642e09514dbb9bbefcd0d3836c05a1e0cd0642

已经从官方镜像库里成功拉取了一个busybox的简单小镜像
busybox是一个最小的Linux系统,它提供了该系统的主要功能,不包含一些与GNU相关的功能和选项。
下一步我们将运行一个“Hello World”的例子,我们暂且叫它“Hello Docker”吧。

docker run busybox /bin/echo Hello Docker

现在,让我们以后台进程的方式运行hello docker:

sample_job=$(docker run -d busybox /bin/sh -c "while true; do echo Docker; sleep 1; done")

sample_job命令会隔一秒打印一次Docker,使用docker logs可以查看输出的结果。如果没有给这个job起名字,那这个job就会被分配一个id,以后使用命令例如docker logs查看日志就会变得比较麻烦。
运行
docker logs $sample_job #可以查看日志的输出

也可以使用以下命令来停止:

docker stop $sample_job

使用以下命令可以重新启动该容器:

docker restart $sample_job

如果要完全移除容器,需要先将该容器停止,然后才能移除。像这样:

docker stop $sample_job #停止
docker rm $sample_job

将容器的状态保存为镜像,使用以下命令:

docker commit $sample_job job1

注意,镜像名称只能取字符[a-z]和数字[0-9]。
现在,你就可以使用以下命令查看所有镜像的列表:

docker images

在我们之前的Docker教程中,我们学习过镜像是存储在Docker registry。在registry中的镜像可以使用以下命令查找到:

docker search (image-name)

查看镜像的历史版本可以执行以下命令:

docker history (image_name)

最后,使用以下命令将镜像推送到registry:

docker push (image_name)

非常重要的一点是,你必须要知道存储库不是根存储库,它应该使用此格式(user)/(repo_name)。

好了,大神翻译的docker 文档贴完了,基本就是这个步骤,就可以玩转了

docker私有库搭建

从 Docker v1.12 开始,docker 就不支持从 HTTP 仓库下载镜像,建立私有仓库必须走 HTTPs 加密协议,坑好多,来走起。

我在本地机器上安装了两个虚拟机 一个是248一个是249 都是centos 7 64

首先呢,得有docker环境,嗯。
再来呢,更改两台机器上的 hosts文件了,以便签名和push 镜像方便。
编辑 /etc/hosts , 添加 registry 域名 mydockerregistry.com

172.20.81.248 mydockerregistry.com

在来就是创建证书了:
运行

mkdir -p certs  #在当前目录创建一个certs 文件夹
mkdir -p certs && openssl req \
   -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
   -x509 -days 365 -out certs/domain.crt
#在certs文件目录里生成 两个签名文件,一个叫 domain.key  一个叫domain.crt

按步骤输入相应内容

Generating a 4096 bit RSA private key
..................................................................................................................++
.......................++
writing new private key to 'certs/domain.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:beijing
Locality Name (eg, city) [Default City]:beijing
Organization Name (eg, company) [Default Company Ltd]:zthd
Organizational Unit Name (eg, section) []:it
Common Name (eg, your name or your server's hostname) []:mydockerregistry.com #这里要写域名哦
Email Address []:[email protected]

ok大功告成

接下来呢,是让docker 客户端信任你的证书

mkdir /etc/docker/certs.d/myregistrydomain.com:5000/ -p
cp certs/domain.crt /etc/docker/certs.d/myregistrydomain.com:5000/ca.crt
service docker restart

这些命令就不用解释了吧
嗯接下来 下来 registry

mkdir data
docker run -d -p 5000:5000 --restart=always --privileged=true --name registry \
  -v `pwd`/certs:/certs \
  -v `pwd`/data:/var/lib/registry \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
  registry:2

这里解释下 /data:/var/lib/registry,格式:(宿主机目录:容器目录)
宿主机的/data目录与容器的/var/lib/registry共享

在这里,如果不添加–privileged=true, 可以正常启动,但是当上传镜像是,会给出500错误

错误如下:

received unexpected HTTP status: 500 Internal Server Error

靠,真是坑,那查看下日志吧,/var/log/message的log会发现这样一段日志 :

Jun 30 02:01:00 bogon journal: 172.20.81.248 - - [30/Jun/2017:09:01:00 +0000] "HEAD /v2/busybox/blobs/sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 HTTP/1.1" 404 157 "" "docker/1.12.6 go/go1.7.4 kernel/3.10.0-514.21.2.el7.x86_64 os/linux arch/amd64 UpstreamClient(Docker-Client/1.12.6 \\(linux\\))"
Jun 30 02:01:00 bogon dbus[558]: [system] Activating service name='org.fedoraproject.Setroubleshootd' (using servicehelper)
Jun 30 02:01:00 bogon dbus-daemon: dbus[558]: [system] Activating service name='org.fedoraproject.Setroubleshootd' (using servicehelper)
Jun 30 02:01:00 bogon journal: time="2017-06-30T09:01:00Z" level=error msg="response completed with error" err.code=unknown err.detail="filesystem: mkdir /var/lib/registry/docker/registry/v2/repositories/busybox/_uploads/28e24cbe-b921-4f86-9096-2260346d2e44: permission denied" err.message="unknown error" go.version=go1.7.3 http.request.host="mydockerregistry.com:5000" http.request.id=6e7029aa-8b4d-4f2d-86c5-75f22ad34b14 http.request.method=POST http.request.remoteaddr="172.20.81.248:38532" http.request.uri="/v2/busybox/blobs/uploads/" http.request.useragent="docker/1.12.6 go/go1.7.4 kernel/3.10.0-514.21.2.el7.x86_64 os/linux arch/amd64 UpstreamClient(Docker-Client/1.12.6 \\(linux\\))" http.response.contenttype="application/json; charset=utf-8" http.response.duration="890.217µs" http.response.status=500 http.response.written=243 instance.id=9b8b0eab-1c6e-4c80-ac7e-fe39137ae88d vars.name=busybox version=v2.6.1
Jun 30 02:01:00 bogon dockerd-current: time="2017-06-30T02:01:00.816251847-07:00" level=error msg="Attempting next endpoint for push after error: received unexpected HTTP status: 500 Internal Server Error"
Jun 30 01:52:21 bogon journal: 172.20.81.248 - - [30/Jun/2017:08:52:21 +0000] "HEAD /v2/busybox/blobs/sha256:27144aa8f1b9e066514d7f765909367584e552915d0d4bc2f5b7438ba7d1033a HTTP/1.1" 404 157 "" "docker/1.12.6 go/go1.7.4 kernel/3.10.0-514.21.2.el7.x86_64 os/linux arch/amd64 UpstreamClient(Docker-Client/1.12.6 \\(linux\\))"
Jun 30 01:52:21 bogon journal: time="2017-06-30T08:52:21Z" level=error msg="response completed with error" err.code=unknown err.detail="filesystem: mkdir /var/lib/registry/docker: permission denied" err.message="unknown error" go.version=go1.7.3 http.request.host="mydockerregistry.com:5000" http.request.id=683956ea-e9b6-4ec7-b4c4-290f5b2f7ff7 http.request.method=POST http.request.remoteaddr="172.20.81.248:38488" http.request.uri="/v2/busybox/blobs/uploads/" http.request.useragent="docker/1.12.6 go/go1.7.4 kernel/3.10.0-514.21.2.el7.x86_64 os/linux arch/amd64 UpstreamClient(Docker-Client/1.12.6 \\(linux\\))" http.response.contenttype="application/json; charset=utf-8" http.response.duration=3.299945ms http.response.status=500 http.response.written=164 instance.id=9b8b0eab-1c6e-4c80-ac7e-fe39137ae88d vars.name=busybox version=v2.6.1

说是没有权限 巴拉巴拉巴拉 (╯—﹏—)╯(┷━━━┷
知道错误那就好办啦
在启动时候 加上 –privileged=true 就ok了。。。┻━┻ ヘ╰( •̀ε•́ ╰)

解释下:

在Cent OS 7中运行,发现挂载的本地目录在容器中没有执行权限,原因是CentOS7中的安全模块selinux把权限禁掉了,至少有以下三种方式解决挂载的目录没有权限的问题:
1,在运行容器的时候,给容器加特权:--privileged=true
2,临时关闭selinux:

su -c "setenforce 0"  

注意:之后要记得重新开启selinux,命令:
su -c "setenforce 1"
3,添加selinux规则,将要挂载的目录添加到白名单:

chcon -Rt svirt_sandbox_file_t /home/docs  


跑偏了。。。

继续 ٩(๑`н´๑)۶

docker tag hello-world mydockerregistry.com:5000/hello-world # 标记本地镜像,将其归入某一仓库。
docker push mydockerregistry.com:5000/hello-world
docker pull mydockerregistry.com:5000/hello-world

如果没错的话,大功告成了就,来检查下 本地镜像吧。

浏览器 输入 https://172.20.81.248:5000/v2/
返回一个文件让你下载 打开是一个 {}
https://172.20.81.248:5000/v2/_catalog
返回 {“repositories”:[“hello-world”]}

\(@ ̄∇ ̄@)/ 这里就算成功了吧
下一步 通过 dockerfile 创建个自己的镜像。。。未完

你可能感兴趣的:(docker,docker-私有仓库)