Docker 基础知识-入门篇

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker 基础知识-入门篇相关的知识,希望对你有一定的参考价值。

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语法格式参考链接

目标: 用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

以上是关于Docker 基础知识-入门篇的主要内容,如果未能解决你的问题,请参考以下文章

Docker入门基础篇

Docker基础入门篇

docker入门篇

Kotlin基础从入门到进阶系列讲解(基础篇)Fragment的基本使用

Kotlin基础从入门到进阶系列讲解(基础篇)Fragment的基本使用

DevOps利器之Docker入门篇