1. Docker简介和KVM区别
1.1 docker的三大理念
- 构建
- 运输
- 运行
ps:有点类似于java代码,一次构建到处运行
1.2 docker结构
相关说明:
image: 和虚拟机的镜像类似
container: 用镜像创建的实例
repository: 类似于yum仓库
docker client: 命令行输入的docker命令
docker server: 启动的docker进程
1.3 docker和kvm的区别
1.虚拟机需要hypervisor这个中间层来进行支持,上面跑的每一个虚拟机他们之间都是相互隔离的,都有独立的操作系统。
2.docker 需要docker engine来进行支持,每个container之间 , 用lxc技术来进行隔离。
1.4 docker改变了什么?
- 简化配置
- 代码流水线管理
- 简化环境配置
- 应用隔离
- 服务合并
- 调试能力
- 多用户环境
- 快速上线
2. docker基础知识
2.1 安装docker软件
yum -y install docker
systemctl start docker
systemctl enable docker
2.2 常规操作
搜索镜像
docker search centos
导出镜像
docker save -o centos.tar centos
导入镜像
docker load -i centos.tar
查看导入的images
[[email protected] ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/centos latest 8140d0c64310 7 weeks ago 192.5 MB
docker.io/nginx latest 3448f27c273f 7 weeks ago 109.4 MB
删除镜像
ps: 如果镜像有已创建的容器, 镜像是无法被删除的.
[[email protected] ~]# docker rmi centos
Untagged: centos:latest
Deleted: sha256:8140d0c64310d4e290bf3938757837dbb8f806acba0cb3f6a852558074345348
Deleted: sha256:b51149973e6a6c4fb1091ef34ff70002ee307e971b9982075cf226004a93c9b7
[[email protected] ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/nginx latest 3448f27c273f 7 weeks ago 109.4 MB
启动docker容器
格式: docker run 参数 容器名 执行的命令
[[email protected] ~]# docker run --rm -i -t centos hostname
7d7e0e228d24
进入到docker
[[email protected] ~]# docker run --rm -i -t centos /bin/bash
[[email protected] /]#
查看docker所有创建的容器
[[email protected] ~]# docker run -i -t centos ps -a
PID TTY TIME CMD
[[email protected] ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
53c158c4560b centos "ps -a" 6 seconds ago Exited (1) 4 seconds ago admiring_roentgen
查看正在运行的容器
ps: 只有将程序启动在前台, 在这里才能看到.
docker ps
用带标签的方式启动docker
ps: 如果有修改容器里文件内容的需求, 需要重新的创建容器,因为docker的理念是不可变基础设施.
[[email protected] ~]# docker run --name centosv1 -i -t centos /bin/bash
[[email protected] /]# exit
[[email protected] ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4ddd206ef3ce centos "/bin/bash" 8 seconds ago Exited (0) 4 seconds ago centosv1
53c158c4560b centos "ps -a" 5 minutes ago Exited (1) 5 minutes ago admiring_roentgen
用标签启动
ps: 此时这个container没有运行, 因为没有程序运行在前台.
docker start centosv1
docker stop centosv1
只运行容器,运行过后就删除
(ps:container执行过命令之后就会自动的删除掉)
[[email protected] ~]# docker run --rm -i -t centos echo hehe
hehe
[[email protected] ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4ddd206ef3ce centos "/bin/bash" 6 minutes ago Exited (0) 6 minutes ago centosv1
53c158c4560b centos "ps -a" 12 minutes ago Exited (1) 11 minutes ago admiring_roentgen
删除容器
ps: 如果容器在运行,无法被删除.
docker rm ‘容器名‘
-d
运行一个容器在后台,并打印出容器id
[[email protected] ~]# docker run -d --name nginx2 nginx
d609da66283da14b6b4f07d7adf801640270904aebd274054914c1000a0b912f
[[email protected] ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d609da66283d nginx "nginx -g ‘daemon off" 30 seconds ago Up 28 seconds 80/tcp nginx2
查看容器的日志
docker logs nginx2
2.3 进入容器
方法一: 使用attach
进入容器,退出后,容器也退出了, 生产环境里不用.
[[email protected] ~]# docker run --name centosv1 -i -t centos /bin/bash
[[email protected] /]# exit
[[email protected] ~]# docker start centosv1
centosv1
[[email protected] ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
47d5b101d62c centos "/bin/bash" 31 seconds ago Up 19 seconds centosv1
[[email protected] ~]# docker attach centosv1
[[email protected] /]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.1 11768 1872 ? Ss 16:39 0:00 /bin/bash
root 15 0.0 0.0 47440 1676 ? R+ 16:39 0:00 ps aux
[[email protected] /]# exit
[[email protected] ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[[email protected] ~]#
方法二:使用nsenter
进入容器后,ps aux 发现是单独的开了一个进程进去的.
[[email protected] ~]# yum -y install util-linux
获取到容器pid
[[email protected] ~]# docker inspect -f ‘{{.State.Pid}}‘ nginx2
5730
进入容器
[[email protected] ~]# nsenter -t 5730 -m -u -i -n -p
ps aux发现是利用nsentor进入container 是单独的开了一个进程的.
[[email protected] /]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 11768 1680 ? Ss+ 16:47 0:00 /bin/bash
root 29 0.0 0.1 15200 1992 ? S 16:53 0:00 -bash
root 42 0.0 0.0 50872 1820 ? R+ 16:53 0:00 ps aux
[[email protected] /]# logout
退出之后centosv1依然运行在后台
[[email protected] ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
47d5b101d62c centos "/bin/bash" 14 minutes ago Up 5 minutes centosv1
ps: 生产环境应该写成一个脚本,利用脚本进入
[[email protected] ~]# cat docker.sh
#!/bin/bash
# auth: [email protected]
# des: login in docker
function docker_in(){
Name=$1
[ -z "$Name" ] && echo ‘error‘ && exit
DockerPid=$(docker inspect -f ‘{{.State.Pid}}‘ $Name)
nsenter -t ${DockerPid} -m -u -i -n -p
}
docker_in $1
[[email protected] ~]# chmod +x docker.sh
[[email protected] ~]# ./docker.sh centosv1
[[email protected] /]#
方法三:
exec 运行一个命令在一个已经运行的容器里.(生产环境不用,有坑)
[[email protected] ~]# docker exec centosv1 date
Wed Jul 5 10:24:15 UTC 2017
[[email protected] ~]# docker exec -it centosv1 /bin/bash
[[email protected] /]#
3. docker网络访问
3.1 随机映射-P
-P 随机映射
[[email protected] ~]# docker run -d --name nginx-v1 -P nginx
59a85323c8afab3bb9c2e450cf96d6448b075bdf5e361d0bf141ccfe660c243e
查看映射的端口
方法一:
[[email protected] ~]# docker port nginx-v1
80/tcp -> 0.0.0.0:32770
方法二:
[[email protected] ~]# iptables -t nat -vnL|grep DNAT
0 0 DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:32770 to:172.17.0.9:80
3.2 指定端口映射
格式:
- -p hostPort:containerPort
docker run -d --name nginx-v2 -p 8088:80 nginx
- -p ip:hostPort:containerPort
docker run -d --name nginx-v3 -p 192.168.1.11:8089:80 nginx
- -p ip::containerPort
docker run -d --name nginx-v4 -p 192.168.1.11::80 nginx
- -p hostPort:containerPort:udp
docker run -d --name nginx-v5 -p 8088:80:udp nginx
ps: 可以使用-p来绑定多个端口.
docker run -d --name nginx-v6 -p 81:80 -p 83:22 nginx
4. docker数据管理
docker镜像是分层设计的,容器也可以封装成一个image
4.1 数据卷
使用数据卷可以提高性能, 类似与mount.
-v /data 随机挂载系统目录
ps: 使用此方式挂载后,你也不知道挂载的是哪个目录,不建议使用
[[email protected] ~]# docker run -d --name nginxv20 -v /data/ nginx
7e8f0744eb3fed1b402b35dba0c7ca3cdd743edbced67b47781ab0fcbcbdee23
[[email protected] ~]# ./docker.sh nginxv20
mesg: ttyname failed: No such file or directory
df -h 也看不见挂载的是系统的那个目录
[email protected]:/# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/docker-253:1-665852-39abc775a9c003ffeca984adf975e8fc43fb4727803daa6a923c1c72a1934e74 10G 148M 9.9G 2% /
tmpfs 912M 0 912M 0% /dev
tmpfs 912M 0 912M 0% /sys/fs/cgroup
/dev/mapper/cl-root 17G 2.2G 15G 13% /data
shm
查看挂载的系统目录是哪个物理目录
[[email protected] ~]# docker inspect -f {{.Mounts}} nginxv20
[{844b66331c243b7a1914eb65ec68f83da35d360e14789f216fded8527c0f8f76 /var/lib/docker/volumes/844b66331c243b7a1914eb65ec68f83da35d360e14789f216fded8527c0f8f76/_data /data local true }]
-v src:dst 挂载指定的目录
ps: 可移植性差,换个机器就不一定有你挂载的这个目录.
[[email protected] ~]# docker run -d --name nginxv100 -v /data/images:/data nginx
c9358e2ce458293cad9a5f4fae95172b5d6609b1126f607b661e30a6d87dd21b
[[email protected] ~]# ./docker.sh nginxv100
[email protected]:/# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/docker-253:1-665852-0de2894a933e80bdcabd8364266e0094272889a7a76d312b98ee2eaf4f60da7c 10G 147M 9.9G 2% /
tmpfs 912M 0 912M 0% /dev
tmpfs 912M 0 912M 0% /sys/fs/cgroup
/dev/mapper/cl-root 17G 2.2G 15G 13% /data
shm 64M 0 64M 0% /dev/shm
[email protected]:/#
[[email protected] data]# docker inspect -f {{.Mounts}} nginxv100
[{ /data/images /data true rprivate}]
4.2 数据卷容器
--volumes-from
一个容器可以访问另外一个容器的卷,适用于在多个容器中共享.
ps: 另外一个容器卷如果被使用, 是无法删除的,当使用了数据卷容器.
[[email protected] ~]# docker run -d --name nginxv101 --volumes-from nginxv100 nginx
4455e9ad2bc6947009e831b21923c06c85a32680aaafab74b7d4f71b003dcc51
[[email protected] ~]# ./docker.sh nginxv101
mesg: ttyname failed: No such file or directory
[email protected]:/# cd /data/
[email protected]:/data# ls
hehe.jpg
[[email protected] ~]# docker inspect -f {{.Mounts}} nginxv101
[{ /data/images /data true rprivate}]
[[email protected] ~]#
5. Docker镜像构建和Dockerfile
5.1 手动构建
启动一个容器,进入容器里安装所需要的软件.
docker run --name mynginx -it centos
./docker.sh mynginx
yum -y install nginx
echo ‘deamon off;‘ >>/etc/nginx/nginx.conf
提交镜像
[[email protected] ~]# docker commit -m ‘my nginx‘ 4916e87a3e1f wangfei/mynginx:v1
sha256:9a18e628ede9cb1245d1c144eb8ac389aa85c2f296d1b3366c858c094ab859ba
[[email protected] ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
wangfei/mynginx v1 9a18e628ede9 26 seconds ago 381.6 MB
docker.io/centos latest 8140d0c64310 7 weeks ago 192.5 MB
docker.io/nginx latest 3448f27c273f 8 weeks ago 109.4 MB
5.2 利用Dockerfile构建
目标: 用dockerfile构建一个nginx容器
[[email protected] ~]# mkdir -p /opt/dockerfile/nginx/
# Description: build nginx container
# Base images
# 除注释的第一行,必须是FROM
From centos
# Maintainer
MAINTAINER [email protected]
# Run commands
RUN yum -y install wget
RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
RUN yum -y install nginx
RUN echo ‘daemon off;‘>>/etc/nginx/nginx.conf
# EXPOSE
EXPOSE 80
# CMD
CMD ["nginx"]
ps: Dockerfile文件名,D必须大写.
build构建
[[email protected] ~]# docker build -t mynginx:v2 /opt/dockerfile/nginx/
[[email protected] ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mynginx v2 a03c3c8678c2 8 minutes ago 401.3 MB
wangfei/mynginx v1 9a18e628ede9 44 minutes ago 381.6 MB
docker.io/centos latest 8140d0c64310 7 weeks ago 192.5 MB
docker.io/nginx latest 3448f27c273f 8 weeks ago 109.4 MB
用构建的镜像启动一个容器
[[email protected] ~]# docker run -d --name Mynginx -p 18080:80 nginx
6. Dockerfile生产实践
docker 镜像文件是分层设计, 在编写dockerfile文件时,将dockerfile按照层次细分成多个组件, 然后将经常需要变动的放在下面.dockerfile当发生变动时,都会重新构建.
6.1 设计分层
[[email protected] ~]# mkdir -p /opt/docker/{runtime,app,system}
[[email protected] ~]# mkdir -p /opt/docker/runtime/{php,java,python}
[[email protected] ~]# mkdir -p /opt/docker/system/{centos,centos-ssh,ubuntu}
[[email protected] ~]# tree /opt/docker
/opt/docker
├── app
├── runtime 运行环境层
│ ├── java
│ ├── php
│ └── python
└── system 系统层
├── centos
├── centos-ssh
└── ubuntu
9 directories, 0 files
6.2 构建一个基础 镜像 centos环境的dockerfile文件
[[email protected] centos]# ll
total 8
-rw-r--r--. 1 root root 254 Jul 7 00:00 Dockerfile
-rw-r--r--. 1 root root 1084 Jul 7 00:00 epel.repo
[[email protected] centos]# cat Dockerfile
# Base images for centos
# Base images
FROM centos
# Maintainer
MAINTAINER [email protected]
# Copy file
COPY epel.repo /etc/yum.repos.d/
#Base Pkg
RUN yum clean all
RUN yum -y install wget mysql-devel supervisor git redis tree net-tools sudo psmisc
[[email protected] centos]# docker build -t centos:v1 .
[[email protected] centos]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos v1 011d5c16b681 16 seconds ago 404.7 MB
mynginx v2 a03c3c8678c2 4 hours ago 401.3 MB
wangfei/mynginx v1 9a18e628ede9 5 hours ago 381.6 MB
docker.io/centos latest 8140d0c64310 7 weeks ago 192.5 MB
docker.io/nginx latest 3448f27c273f 8 weeks ago 109.4 MB
6.3 生产实战1
环境说明
管理程序:supervisord
应用环境:python
需要启动的应用:python程序 ssh服务
系统环境: centos
技巧
1.先在测试环境将环境部署好,然后将其配置文件copy过来,再写dockerfile文件
2.编写dockfile文件的时候,将经常变动的操作放在下面(docker images 是分层设计的,上面一动,下面的就都得重新构建,速度很慢。)
目录分层
[[email protected] docker]# tree
.
├── app
│ └── shop-api
│ ├── app.py
│ ├── Dockerfile
│ ├── requirements.txt
│ ├── supervisord.conf
│ └── supervisord.ini
├── runtime
│ ├── java
│ ├── php
│ └── python
└── system
├── centos
│ ├── Dockerfile
│ └── epel.repo
├── centos-ssh
│ └── Dockerfile
└── ubuntu
10 directories, 8 files
构建基础镜像的dockerfile文件
[[email protected] dockeri]# cat system/centos/Dockerfile
# Base images for centos
# Base images
FROM centos
# Maintainer
MAINTAINER [email protected]
# Copy file
COPY epel.repo /etc/yum.repos.d/
#Base Pkg
RUN yum clean all
RUN yum -y install wget mysql-devel supervisor git redis tree net-tools sudo psmisc python-devel python-pip supervisor vim openssh-server openssh-clients openssh
RUN pip install --upgrade pip
[[email protected] docker]# docker build -t centos:v3 system/centos/
生产环境dockerfile文件
[[email protected] docker]# cat app/shop-api/Dockerfile
# Description: shop-api
# Base images
FROM centos:v3
# Maintainer
MAINTAINER [email protected]
# Copy file
COPY app.py /opt/
COPY requirements.txt /opt/
COPY supervisord.conf /etc/supervisord.conf
COPY supervisord.ini /etc/supervisord.d/
# Add user
RUN useradd -u 1000 -s /sbin/nologin www
# Install pip dep
RUN pip install -r /opt/requirements.txt
# clear ssh cer
RUN ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key
RUN echo "root:abc#123"|chpasswd
# Expose
EXPOSE 80 5000
# CMD
CMD ["supervisord","-c","/etc/supervisord.conf"]
app python程序
[[email protected] docker]# cat app/shop-api/app.py
from flask import Flask
app = Flask(__name__)
@app.route(‘/‘)
def hello():
return ‘Hello World!‘
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
pip 安装的软件
[[email protected] docker]# cat app/shop-api/requirements.txt
flask
supervisord 管理的程序
[[email protected] docker]# cat app/shop-api/supervisord.ini
[program:shop-api]
command=/usr/bin/python2.7 /opt/app.py
process_name=%(program_name)s
autostart=true
user=www
stdout_logfile=/tmp/api.log
stderr_logfile=/tmp/api.error
[program:sshd]
command=/usr/sbin/sshd -D
process_name=%(program_name)s
autostart=true
stderr_logfile=/tmp/ssh.error
supervisord配置文件
[[email protected] docker]# grep daemon app/shop-api/supervisord.conf
nodaemon=true ; (start in foreground if true;default false) ps: 关键配置.
进行构建生产环境镜像
[[email protected] docker]# docker build -t shopapi:v3 app/shop-api/
[[email protected] docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myshopapi v3 609cd450ae28 30 minutes ago 447.3 MB
shopapi v2 6781bc1869d6 About an hour ago 447.3 MB
shopapi v1 b757b7e691a4 About an hour ago 447 MB
centos v3 19aa069dff1a About an hour ago 441.4 MB
centos v2 316718447fdc About an hour ago 433.2 MB
centos v1 011d5c16b681 2 hours ago 404.7 MB
mynginx v2 a03c3c8678c2 6 hours ago 401.3 MB
wangfei/mynginx v1 9a18e628ede9 7 hours ago 381.6 MB
docker.io/centos latest 8140d0c64310 7 weeks ago 192.5 MB
docker.io/nginx latest 3448f27c273f 8 weeks ago 109.4 MB
运行这个容器
[[email protected] docker]# dockr run --name myshopapi01 -d -p 8088:5000 -p 8022:22 shopapi:v3
6.4 生产实战2 docker 之 tomcat
[[email protected] tomcat]# tree
.
├── apache-tomcat-7.0.64.tar.gz
├── Dockerfile
├── jdk1.8.0_60.tar.gz
├── supervisord.conf
└── supervisord.ini
0 directories, 5 files
[[email protected] tomcat]# cat Dockerfile
# build tomcat
# Base images
FROM wf/centos:base
# Maintainer
MAINTAINER [email protected]
# Create New Diretory
RUN mkdir -p /application/
# Add file
ADD apache-tomcat-7.0.64.tar.gz /application/
# Add 的用法需要注意一下, 当是压缩文件的时候,会自动解压, 如果只是单纯的复制,用copy
ADD jdk1.8.0_60.tar.gz /application/
ADD supervisord.ini /etc/supervisord.d/
ADD supervisord.conf /etc/supervisord.conf
# Build tomcat and java
# 这里有一个坑,原先我使用写到文件里的方式,然后source,发现不能生效.
ENV JAVA_HOME /application/jdk
ENV CLASSPATH $CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /application/tomcat_8080
ENV PATH $CATALINA_HOME:$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
RUN mv /application/apache-tomcat-7.0.64 /application/tomcat_8080
RUN useradd -s /sbin/nologin -M www
RUN chown -R www.www /application/tomcat_8080
RUN ln -s /application/jdk1.8.0_60 /application/jdk
# EXPOSE
EXPOSE 8080
# volume
VOLUME ["/root/ROOT","/application/tomcat_8080/webapps/ROOT/"]
# CMD
CMD ["/usr/bin/supervisord","-c","/etc/supervisord.conf"]
[[email protected] tomcat]# cat supervisord.ini
[program:tomcat]
# 这里有一个梗,根据我查到的资料,tomcat放前台启动有二种方式,另外一种是startup.sh && tailf /tomcat_homg/log/catilina.log
command=/application/tomcat_8080/bin/catalina.sh run
process_name=%(program_name)s
autostart=true
user=www
# 日志输出很重要
stdout_logfile=/tmp/tomcat.log
stderr_logfile=/tmp/tomcat.error
7. Docker 本地私有仓库
7.1 使用 Docker Registry
参考链接:
https://docs.docker.com/registry/#tldr
注意事项:
- 服务端运行registy,需要配合使用https来上传镜像(so 需要搞ssl证书),客户端默认使用https
- 可以搞个nginx代理用80代理5000
7.2 使用 vmware harbor (推荐)
参考链接:
https://github.com/vmware/harbor
安装文档:
https://github.com/vmware/harbor/blob/master/docs/installation_guide.md
问题总结:
http://blog.csdn.net/jiangshouzhuang/article/details/53267094
7.3 docker仓库图形化工具
https://github.com/vmware/admiral
原文地址:http://blog.51cto.com/damaicha/2125713