您的位置:首页 > 运维架构 > Docker

Docker学习笔记 第一记

2017-07-06 15:38 246 查看
*注:部分内容来自于网络摘取

懒得排版,凑合看吧

基于

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 镜像(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 []:28154232@qq.com


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 创建个自己的镜像。。。未完
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息