docker 学习

  • 一个物理机可以通过VMware虚拟化安装多个操作系统

    每个操作系统可以运行单独的app,一台物理机可以部署多个app

  • 每个app独立运行在一个VM里

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# 添加仓库,更新阿里云的源
# 基础仓库
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
额外仓库
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

# 清理yum缓存
yum clean all

# 将软件包信息提前在本地索引缓存,生成新缓存
yum makecache

# 清空现有规则
iptables -F
iptables -X
iptables -Z

# 查看SElinux状态是否为disable
getenforce

# 安装常用的工具
yum install -y bash-completion vim lrzsz wget expect net-tools nc nmap tree dos2unix htop iftop iotop unzip telnet sl psmisc nethogs glances bc ntpdate openldap-devel

# 禁止防火墙开机自启
systemctl disable firewalld

# 关掉防火墙
systemctl stop firewalld

# docker运行平台必须是centOS7平台,内核版本不低于3.10
查看uname -r

# 开启linux内核的流量转发
cat <<EOF > /etc/sysctl.d/docker.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0
net.ipv4.ip_forward = 1
EOF

# 加载修改内核的参数,配置文件
modprobe br_netfilter
sysctl -p /etc/sysctl.d/docker.conf

# 利用yum快速安装docker
# 提前配置好yum仓库
# 1. 阿里云自带仓库
# 2. 阿里云提供的专属repo仓库
# 下载阿里源repo文件
curl -o /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

yum clean all && yum makecache

# yum 安装
yum install docker-ce-20.10.6 -y
## 查看源中可用版本
yum list docker-ce --showduplicates | sort -r
## 如果需要安装旧版本
## yum install -y docker-ce-18.09.9

# 如果要卸载
yum remove -y docker-xx

镜像加速器

使用docker首要操作就是获取镜像文件,默认下载是从Docker Hub下载,网速慢,国内很多云服务商都提供了加速器服务,阿里云加速器,Daocloud加速器,灵雀云加速器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 首先创建一个docker文件夹和配置文件
mkdir -p /etc/docker
touch /etc/docker/daemon.json
vim /etc/docker/daemon.json

# 粘贴以下内容
{
"registry-mirrors":[
"https://8xpk5wnt.mirror.aliyuncs.com"
]
}

# 启动docker
systemctl daemon-reload
systemctl enable docker
systemctl restart docker

# 查看docker镜像
docker images
# 查看docker版本
docker version

启动第一个docker容器

1
2
3
4
5
6
7
8
# 1. 获取镜像
docker pull image_name
# 2. 运行镜像,生成容器,你想要的容器,就运行在容器中
docker run param image_name/id
# 3. 停止容器
docker stop id
# 4. 启动容器
docker start id

docker的生命周期

学习docker的核心要素

  • 诞生——使用——销毁
  • Dockerfile 通过docker build. 生成一个images,dockerfile是构建镜像的脚本。
  • 通过docker push送到docker hub(公开仓库)上
  • 通过docker pull拉到机器本地
  • docker save导出镜像
  • docker load导入镜像(传递镜像)
  • docker run镜像
  • docker stop、docker start、docker restart 容器id
  • docker commit 容器id,生成一个安装了软件的镜像
Docker Life Cycle

docker 镜像的原理

获取redis镜像时,下载了多行信息,最终得到了完整的镜像文件

1
2
3
4
5
6
7
8
9
10
11
[root@jueye docker]# docker pull redis
Using default tag: latest
latest: Pulling from library/redis
a2abf6c4d29d: Already exists
c7a4e4382001: Pull complete
4044b9ba67c9: Pull complete
c8388a79482f: Pull complete
413c8bb60be2: Pull complete
1abfd3011519: Pull complete
Digest: sha256:db485f2e245b5b3329fdc7eff4eb00f913e09d8feb9ca720788059fdc2ed8339
Status: Downloaded newer image for redis:latestdocker.io/library/redis:latest

一直以来使用的vmware虚拟机,安装的系统是一个完整的系统文件

  • linux内核,作用是提供操作系统基本功能,与硬件交互
  • centos7发行版,作用是提供软件功能,例如yum安装包管理

linux内核+centos发行版,组成了一个系统

docker绕过发行版使用系统,技术手段就是docker images

1
2
3
4
[root@jueye docker]# cat /etc/redhat-release
CentOS Linux release 7.8.2003 (Core)
[root@jueye docker]# uname -r
3.10.0-1127.el7.x86_64

使用docker切换不同的发行版,内核使用的都是宿主机的内核

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 利用docker获取不同的发行版镜像
[root@jueye docker]# docker pull centos:7.5.1804

[root@jueye docker]# docker pull ubuntu

# 确认当前宿主机的发行版
[root@jueye docker]# cat /etc/redhat-release
CentOS Linux release 7.8.2003 (Core)

# 运行容器且进入容器内
# 参数解释 -i 交互式命令操作 -t 开启一个终端 bash 进入容器后执行的命令
[root@jueye docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 2 years ago 141MB
redis latest 7614ae9453d1 2 years ago 113MB
ubuntu latest ba6acccedd29 2 years ago 72.8MB
centos 7.5.1804 cf49811e3cdb 5 years ago 200MB
[root@jueye docker]# docker run -it cf49811e3cdb bash
[root@f9148c20e12c /]#

# 查看容器内的发行版本
[root@f9148c20e12c home]# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)

# 运行ubuntu系统
[root@jueye docker]# docker run -it ubuntu bash
root@5221c6ac5f55:/# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.3 LTS"

# 运行SUSE
[root@jueye docker]# docker run -it opensuse bash
ce16015d4dd6:/ # cat /etc/SuSE-release
openSUSE 42.3 (x86_64)
VERSION = 42.3
CODENAME = Malachite
# /etc/SuSE-release is deprecated and will be removed in the future, use /etc/os-release instead
  • 一个完整的系统是由一个linux内核加发行版组成了一个可以使用的完整的系统
  • 利用docker容器可以方便获取不同的发行版镜像,然后基于该镜像,运行各种容器使用

理解什么是docker镜像

docker images搜索地址 https://hub.docker.com/

  1. docker解决了环境的兼容问题,在容器中运行linux发行版,以及各种软件
  2. 环境干净,安装的所有内容都在容器里,不想要了直接删除容器,不影响宿主机
  3. 比如想把mysql容器内的数据,配置,全部迁移到服务器上,只需要提交该容器,生成镜像,再把镜像放到服务器上,docker run就能运行
  4. 一个 完整的docker镜像可以创建出docker容器并运行,我们获取的是发行版,镜像文件不包含内核。

Image System

Add Image

1
2
3
4
5
6
7
8
9
10
11
12
13
# 进入到正在运行的容器内
[root@jueye docker]# docker exec -it 50a7346bec6b bash
# 查看软件基础镜像的发行版本
root@50a7346bec6b:/# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

docker 为什么分层镜像

  • 镜像分层资源共享,多个镜像来自同一个base镜像,docker host只需要存储一个base镜像
  • 内存只需要加载一份host,即可为多个容器服务
  • 修改只限制在单个容器内,其他容器不受影响
Writable Layer

顶层为可写的容器层

下面是只读的镜像层

Copy-on-Write

获取镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
docker search 镜像名:tag tag就是具体的标签版本

docker search centos

# 查看本地镜像文件有哪些
docker images
docker image ls

# 下载docker镜像
docker pull centos # 默认下载centos:latest
docker pull centos:7.8.2003

# 查看docker镜像的存储路径
[root@jueye docker]# docker info

[root@jueye docker]# docker info | grep Root
Docker Root Dir: /var/lib/docker

# 存放docker镜像的目录
# json文件,该文件作用是记录镜像和容器的配置关系
[root@jueye docker]# ls /var/lib/docker/image/overlay2/imagedb/content/sha256/ -l
总用量 28
-rw------- 1 root root 7656 3月 26 17:03 605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85
-rw------- 1 root root 7700 3月 27 10:02 7614ae9453d1d87e740a2056257a6de7135c84037c367e1fffa92ae922784631
-rw------- 1 root root 1462 3月 27 14:21 ba6acccedd2923aee4c2acc6a23780b14ed4b8a5fa4e14e252a23b846df9b6c1
-rw------- 1 root root 2205 3月 27 14:25 cf49811e3cdb94cbdfd645f3888d7add06a315449cf2c7ca7b81c312f1e46c63
-rw------- 1 root root 1866 3月 27 14:57 d9e50bf288963ff3a78d1decfcd1deda5acd15a0e3094c9e4b317cf8299bd465

# 使用不同的镜像生成容器
# -it 开启一个交互式的终端,--rm 容器退出时删除容器
[root@jueye docker]# docker run -it --rm centos bash
[root@cce87e7d1088 /]# cat /etc/redhat-release
CentOS Linux release 8.4.2105

# 找某个类型docker images
[root@jueye docker]# docker images centos
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 5d0da3dc9764 2 years ago 231MB
centos 7.8.2003 afb6fca791e0 3 years ago 203MB

# 只列出镜像的id
[root@jueye docker]# docker images -q
605c77e624dd
7614ae9453d1
ba6acccedd29
5d0da3dc9764
afb6fca791e0
d9e50bf28896

# 格式化显示镜像
# docker模板语言
[root@jueye docker]# docker images --format "{{.ID}}--{{.Repository}}"
605c77e624dd--nginx
7614ae9453d1--redis
ba6acccedd29--ubuntu
5d0da3dc9764--centos
afb6fca791e0--centos
d9e50bf28896--opensuse

# 以表格形式表示,美化
[root@jueye docker]# docker images --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}"
IMAGE ID REPOSITORY TAG
605c77e624dd nginx latest
7614ae9453d1 redis latest
ba6acccedd29 ubuntu latest
5d0da3dc9764 centos latest
afb6fca791e0 centos 7.8.2003
d9e50bf28896 opensuse latest

# 查找镜像
[root@jueye docker]# docker search centos

删除镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# docker pull hello-world
[root@jueye docker]# docker rmi hello-world:latest
Untagged: hello-world:latest
Untagged: hello-world@sha256:2498fce14358aa50ead0cc6c19990fc6ff866ce72aeb5546e1d59caac3d0d60f
Deleted: sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412
Deleted: sha256:e07ee1baac5fae6a26f30cabfe54a36d3402f96afda318fe0a96cec4ca393359

# 也可以只输入首三位字母
[root@jueye docker]# docker rmi feb

# 批量删除镜像(反引号,慎用)
# -a 列出所有容器包括停止运行的,-q列出容器数字ID而不是全部信息
[root@jueye docker]# docker rmi `docker images -aq`
# 批量删除容器
docker rm `docker ps -aq`

管理镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# 提交镜像
docker commit

# 导出镜像的命令
docker image save centos:7.8.2003 > /opt/centos7.8.2003.tgz

# 导入镜像的命令
docker image load -i /opt/centos7.8.2003.tgz

# 查看docker信息
docker info

# 查看镜像的详细信息,jason
docker image inspect 镜像id

# docker run 等于创建+启动
# docker run 镜像名,如果镜像不在本地,则会在线下载该镜像
# 注意:容器内的进程必须处于前台运行状态,否则容器就会直接退出
# 如果容器内什么也没做,也会挂掉,容器内必须有一个容器前台运行

# 运行容器且进入容器内,并在容器内执行某个命令
[root@jueye docker]# docker run -it ubuntu bash
root@58bff6aab067:/# cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.3 LTS (Focal Fossa)"

# 开启一个容器,并让他运行某个程序
[root@jueye docker]# docker run centos ping baidu.com
PING baidu.com (39.156.66.10) 56(84) bytes of data.
64 bytes from 39.156.66.10 (39.156.66.10): icmp_seq=1 ttl=127 time=27.9 ms

# -d参数,可以让容器在后台运行
# --rm参数,容器挂掉后自动删除
# --name参数,给容器起名
[root@jueye docker]# docker run -d --rm --name test centos:7.8.2003 ping baidu.com
b6d1bf78c5d3bd296e878bb92ecae3297a2dbf50fd3d1e70ae581d14fa283a97

# 查看容器日志
# -f更新日志
[root@jueye docker]# docker logs 7d8 | tail -5
[root@jueye docker]# docker logs -f 7d8

# 进入正在运行的容器内
[root@jueye docker]# docker exec -it 7d8 bash
[root@7d89cce28ce5 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 03:04 ? 00:00:00 ping baidu.com

# 查看容器的详细信息
[root@jueye docker]# docker container inspect 7d8

# 容器端口映射
# 后台运行nginx容器,起个名字,端口映射宿主机的85端口,访问到容器内的80端口
[root@jueye docker]# docker run -d --name test_nginx -p 85:80 nginx
3aeafcac21330851109ff5675439558446059e8e1df4069fc6218c75b4666660
# 随机端口映射
[root@jueye docker]# docker run -d --name test_nginx_random -P nginx

提交容器

1
2
3
[root@jueye docker]# docker commit 容器id 新的镜像名
[root@jueye docker]# docker commit c68b3ca32fe5 jueye/centos-vim-7.8.2003
sha256:e240a15cbd4862dd3ad7294cdfe035dc3c93a75e8f59d61ac5b11f75d3dcd5d2

镜像是多层存储,每一层在前一层的基础上进行修改;

容器也是多层存储,以镜像为基础层,在其基础上加一层作为容器运行时的存储层

创建镜像的两个方法

  • 手动修改容器内容,然后docker commit提交容器为新的镜像
  • 通过dockerfile中定义一系列命令和参数构成的脚本,然后这些命令应用于基础镜像,依次添加层,最终生成一个新的镜像

dockerfile主要组成部分

  1. 基础镜像信息 FROM centos:6.8
  2. 制作镜像操作指令 RUN yum Install openssh-server -y
  3. 容器启动时执行指令 CMD [“/bin/bash”]

dockerfile 学习

需求:

让你安装一个mysql,且启动

  1. 开启虚拟机VMware
  2. 运行某个虚拟机,centos7
  3. centos7安装mysql yum install mysql-server
  4. 通过脚本,或者命令,启动mysql即可

部署缓慢,且修改了宿主机的环境,删除较为麻烦,占用宿主机的一个端口

基于容器运行mysql

  1. 开始VMware
  2. 运行虚拟机centos7(宿主机)
  3. 安装docker容器软件
  4. 获取mysql镜像即可,docker pull mysql:tag获得的基础镜像是别人定制好的
  5. 直接运行该镜像,通过端口映射,运行mysql,docker run mysql:5.6 容器能够运行,必须在容器内有一个进程在前台运行,该容器内,有mysql在前台运行
  6. 访问宿主机的一个映射端口,访问到容器内的mysql

想自定义镜像,就要自己写dockerfile


dockerfile 指令

FROM 这个镜像的母体是谁?基础镜像

MAINTAINER 告诉别人,谁负责维护它?指定维护者信息,可以没有

RUN 你想让它干啥 在命令前面加上RUN

ADD 给它点创业资金 添加宿主机的文件到容器内,COPY文件,会自动解压

COPY 作用和 ADD 是一样的,都是拷贝宿主机的文件到容器内,但是 ADD 还能顺带解压

WORKDIR 我是cd,换了个妆 设置当前工作目录

VOLUME 给它一个存放数据的地方 设置卷,挂载主机目录

EXPOSE 它要打开的门户是啥 指定对外的端口

CMD 运行 指定容器启动后要干的事


dockerfile 实践

需求:通过dockerfile,构建nginx镜像,且运行容器后,生成的页面是 “HELLO WORLD!”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1. 创建Dockerfile,注意文件名必须是这个
[root@jueye learn_docker]# pwd
/learn_docker
[root@jueye learn_docker]# cat Dockerfile
FROM nginx
[root@jueye learn_docker]# cat Dockerfile
FROM nginx
RUN echo '<meta charset=utf-8>HELLO WORLD!' > /usr/share/nginx/html/index.html
# 2. 构建dockerfile
[root@jueye learn_docker]# docker build .
[root@jueye learn_docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 2edb4024387b 4 minutes ago 141MB
[root@jueye learn_docker]# docker tag 2edb4024387b my_nginx
# 运行该镜像
docker run -d -p 80:80 my-nginx

COPY

1
2
3
4
5
# COPY指令从宿主机复制文件/目录到新的一层镜像内,如
copy hello-world.py /home/
# 支持多个文件,以及通配符形式复制,语法要满足Golang的filepath.Match
copy hello* /tmp/cc?.txt. /home/
# COPY指令能够保留源文件的元数据,如权限,访问时间等,这点很重要

ADD

特性和COPY基本一致,不过多了些功能

  1. 源文件是一个URL,此时docker引擎会下载该链接,放入目标路径,且权限自动设为600
  2. 源文件是一个URL,且是一个压缩包,不会自动解压,也得单独用RUN指令解压
  3. 源文件是一个压缩文件,且是gzip,bzip2,xz,tar情况,ADD指令会自动解压缩该文件到目标路径

CMD

1
2
3
4
5
6
7
8
9
10
11
# CMD 用法,注意双引号
CMD ["参数1", "参数2"]
# 在指定entrypoint指令后,用CMD指定具体的参数
# docker不是虚拟机,容器就是一个进程,在程序启动的时候需要指定些运行参数
# centos镜像默认的CMD是/bin/bash,直接docker run -it centos会进入bash解释器。
# 也可以启动容器的时候,指定参数。docker run -it centos cat /etc/os-release
# CMD运行shell命令,也会被转化为shell形式
# 例如
CMD echo $PATH
# 会被转化为
CMD ["sh", "-c", "echo $PATH"]

容器内运行程序

docker不是虚拟机的概念,虚拟机里的程序运行,基本都是在后台,利用systemctl运行,但容器内没有后台进程的概念,必须在前台运行。容器就是为了主进程而存在的,主进程如何退出了,容器就失去了意义,自动退出

1
2
3
4
5
6
7
CMD systemctl start nginx
# 这样写是错的,容器会立即退出
# 因为systemctl start nginx是希望以守护进程形式启动nginx,CMD命令会转化为
CMD ["sh", "-c", "systemctl start nginx"]
# 这样的命令主进程是sh解释器,执行完毕后立即结束,容器退出
# 正确的做法应该是
CMD ["nginx", "-g", "daemon off;"]

把宿主机安装,启动nginx的理念放入到dockerfile

  1. RUN yum install nginx
  2. RUN 配置文件修改 sed
  3. RUN systemctl start nginx ❌ 容器内的程序必须是前台运行,否则启动不了
  4. 正确的应该是CMD ["nginx", "-g", "daemon off;"]

ENTRYPOINT

作用和 CMD 一样,都是在指定容器启动程序以及参数

当制定了 ENTRYPOINT 之后,CMD 指令的语义就有了变化

CMD 的内容当作参数传递给 ENTRYPOINT 指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1. 准备一个dockerfile
FROM centos:7.8.2003
RUN rpm --rebuilddb && yum install epel-release -y
RUN rpm --rebuilddb && yum install curl -y
CMD ["curl", "-s", "http://ipinfo.io/ip"]
# 2. 构建镜像
docker build .
# 3. 查看结果
docker tag 9d6fecfd8b8c centos_curl
# 5. 运行镜像,生成容器
[root@jueye learn_docker]# docker run centos_curl
117.147.106.3[root@jueye learn_docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 6. 修改dockerfile,将CMD替换为ENTRYPOINT
# 传递CMD指令当作了ENTRYPOINT参数,容器内执行的指令能附加上docker run后面的参数
[root@jueye learn_docker]# docker run centos_curl_new -I

ARG 和 ENV 指令

设置环境变量

1
2
3
4
5
6
7
# dockerfile 脚本,shell 脚本
ENV NAME="JUEYE"
ENV AGE='18'
ENV MYSQL_VERSION=5.6
# 后续所有操作,通过$NAME就可以直接获取变量值
# ARG和ENV一样设置环境变量,区别在于ENV无论在构建镜像还是容器运行时都能用
# ARG只是用于构建镜像需要设置的变量,容器运行时就消失了

VOLUME

容器在运行时,应该保证在存储层不写入任何数据,运行在容器内产生的数据,推荐挂载写入到宿主机上进行维护

1
2
3
4
5
6
7
8
9
10
VOLUME /data # 将容器内的/data文件夹,在容器运行时,该目录自动挂在为匿名卷,任何向该目录写入数据的操作都不会被容器记录,保证容器存储层无状态理念
# Dockerfile1
FROM centos
MAINTAINER Jueye
VOLUME ["/data1", "/data2"]
# 该容器运行时,这两个目录自动和宿主机的目录做好映射关系
docker build .
docker run f2aa80379f53
# 查看生成的容器信息,Mount信息为宿主机挂载点
docker inspect
  1. 容器数据挂载的方式,通过dockerfile,指定VOLUME目录
  2. 通过 docker run -v 参数,直接设置需要映射挂载的目录

EXPOSE

指定容器运行时对外提供的端口服务

  • 帮助使用该镜像的人,快速理解该容器的一个端口业务

  • docker port # 容器
    docker run -p # 宿主机端口:容器端口
    docker run -P # 作用是随即宿主机端口:容器内端口```
    
    

WORKDIR

用于在dockerfile中, 目录切换更改工作目录

1
WORKDIR /opt

USER

用于改变环境, 用于切换用户

1
2
USER root
USER Jueye

构建一个网站镜像

  1. nginx, 修改首页内容的html网站就跑起来了, web server, 提供web服务, 提供代理转发, 提供网关, 限流等… apache
  2. web framework, web框架, 一般由开发通过某个开发语言基于某个web框架, 自己去开发一个web站点, python, django框架
  1. 用python语言,基于flask web框架,开发一个自己的网站,写了一个后端的网站代码

  2. 开发dockerfile,部署该代码,生成镜像

  3. 其他人基于该镜像,docker run就可以在电脑跑起来你的网站

比如安装一个etcd,nacos,都是比较复复杂的软件

需要依赖go语言环境,java语言环境,在自己的机器安装好对应的开发环境,以及对应的版本和依赖。

tomcat,jdk环境

当你有了docker

docker pull tomcat # 这些主流的镜像都可以找到,并且该镜像中就已经打包好了java环境

docker pull nacos # 打包好了各种依赖环境

docker run tomcat xxxx # 可以直接访问tomcat了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 1. 在宿主机上准备一个目录 ,准备好dockerfile,你的代码 
# 写一个flask的python代码
# 创建代码文件
[root@jueye learn_docker]# cat Jueye_flask.py
#coding:utf-8
from flask import Flask
app=Flask(__name__)
@app.route('/')
def hello():
return "hello docker, I'm Jueye."
if __name__=='__main__':
app.run(host='0.0.0.0', port=8080)

# 2. 编写dockerfile
touch Dockerfile
vim Dockerfile
FROM centos:7.8.2003
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo;
RUN curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo;
RUN yum makecache fast;
RUN yum install python3-devel python3-pip -y
RUN pip3 install flask
COPY Jueye._flask.py /opt
WORKDIR /opt
EXPOSE 8080
CMD ["python3", "Jueye_flask.py"]
# 4. 构建镜像
docker build -t 'jueye/my_flask_web' .
# 5. 运行镜像生成容器
docker run -d --name myflask_web1 -p 90:8080 jueye/my_flask_web
# 6. 访问宿主机,看容器内的flask网站
http://192.168.72.128:90/
# 7. 该如何修改网站内容,这个程序跑在容器里了

如何修改该网站的内容

  1. 修改宿主机的代码以及dockerfile,重新构建
  2. 可以进入到已经运行的容器内修改代码,重启容器即可
1
2
3
4
5
6
7
# 进入容器
docker exec -it id bash
# 修改文件
vi Jueye_flask.py
# 退出容器,重启容器
exit
docker restart id

docker 容器管理总结

1
2
3
# 运行镜像,进入容器内
docker run --name my_nginx -d --restart=always -p 7070:80 nginx
# --restart=always 检查容器是否还存活,如果死了就重启

docker run 启动容器的时候,docker 后台操作流程

  • 检查本地是否有该镜像,没有就下载
  • 利用镜像创建且启动一个容器
  • 分配容器文件系统,在只读的镜像层挂载读写层
  • 宿主机的网桥接口会分配一个虚拟接口到容器中
  • 容器获得地址池里的ip地址
  • 执行用户指定的程序
  • 若程序里没有进程在运行,容器执行完毕后立即终止

docker start 可以启动一个处于 stop 状态的容器

docker logs -f 查看容器内是否写入日志,-f 表示刷新日志

docker ps 查看在运行的容器,等同于 docker container ls

docker ps -a 查看挂掉以及活着的容器

docker start id 启动容器

docker stop id 停止容器

docker exec -it id bash 进入容器内

docker rm id 删除容器

docker rm `docker ps -aq` 删除所有容器

docker rm -f id 强制杀死容器

docker top 查看容器内进程信息,PID

docker stats id 查看容器内资源信息,CPU

docker inspect id 查看容器的具体信息

docker inspect --format '{{.NetworkSettings.IPAddress}}' id 拿到容器IP