三大核心要素:镜像(Image)、容器(Container)、仓库(Registry)
(先整体看下流程,再逐个演示)
打包了业务代码及运行环境的包,是静态的文件,不能直接对外提供服务。
镜像的运行时,可以对外提供服务。本质上讲是利用 namespace 和 cgroup 等技术在宿主机中创建的独立的虚拟空间。
公有仓库,Docker Hub,阿里,网易...
私有仓库,企业内部搭建
镜像访问地址形式 registry.devops.com/demo/hello:latest,若没有前面的 url 地址,则默认寻找 Docker Hub 中的镜像,若没有 tag 标签,则使用 latest 作为标签
公有的仓库中,一般存在这么几类镜像
启动容器
后台启动
$ docker run --name nginx -d nginx:alpine
查看 run 流程
查看容器进程
等同于在虚拟机中开辟了一块隔离的独立的虚拟空间
启动容器的同时进入容器,-ti 与/bin/sh 或者/bin/bash 配套使用,意思未分配一个 tty 终端
$ docker run --name nginx -ti nginx:alpine /bin/sh
(注意:退出容器后,该容器会变成退出状态,因为容器内部的 1 号进程退出)
实际上,在运行容器的时候,镜像地址后面跟的命令等于是覆盖了原有的容器的 CMD 命令,因此,执行的这些命令在容器内部就是 1 号进程,若该进程不存在了,那么容器就会处于退出的状态,比如,宿主机中执行
$ docker run -d --name test_echo nginx:alpine echo 1
,容器会立马退出$ docker run -d --name test_ping nginx:alpine ping www.baidu.com
,容器不会退出,但是因为没有加-d 参数,因此一直在前台运行,若 ctrl+C 终止,则容器退出,因为 1 号进程被终止了$ docker run --name nginx -d -p 8080:80 nginx:alpine
$ docker run --cpuset-cpus="0-3" --cpu-shares=512 --memory=500m nginx:alpine
$ docker run --name nginx -d -v /opt:/opt -v /var/log:/var/log nginx:alpine
$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=123456 -d -v /opt/mysql/:/var/lib/mysql mysql:5.7
$ docker volume ls
$ docker volume create my-vol
$ docker run --name nginx -d -v my-vol:/opt/my-vol nginx:alpine
$ docker exec -ti nginx touch /opt/my-vol/a.txt
$ docker run --name nginx2 -d -v my-vol:/opt/hh nginx:alpine
$ docker exec -ti nginx2 ls /opt/hh/
a.txt
$ docker exec -ti <container_id_or_name> /bin/sh
$ docker exec -ti <container_id_or_name> hostname
$ echo '123'>/tmp/test.txt
$ docker cp /tmp/test.txt nginx:/tmp
$ docker exec -ti nginx cat /tmp/test.txt
123
容器拷贝到主机
$ docker cp nginx:/tmp/test.txt ./
查看全部日志
$ docker logs nginx
实时查看最新日志
$ docker logs -f nginx
从最新的 100 条开始查看
$ docker logs --tail=100 -f nginx
$ docker stop nginx
启动退出容器
$ docker start nginx
删除退出容器
$ docker rm nginx
删除运行中的容器
$ docker rm -f nginx
查看容器详细信息,包括容器 IP 地址等
$ docker inspect nginx
查看镜像的明细信息
$ docker inspect nginx:alpine
Dockerfile 是一堆指令,在 docker build 的时候,按照该指令进行操作,最终生成我们期望的镜像
格式:
FROM <image>
FROM <image>:<tag>
示例:
FROM mysql:5.7
注意:
tag是可选的,如果不使用tag时,会使用latest版本的基础镜像
格式:
MAINTAINER <name>
示例:
MAINTAINER cuijianzhe
MAINTAINER 598941324@qq.com
MAINTAINER Jianzhe Cui <598941324@qq.com>
格式:
COPY <src>... <dest>
示例:
ADD hom* /mydir/ # 添加所有以"hom"开头的文件
ADD test relativeDir/ # 添加 "test" 到 `WORKDIR`/relativeDir/
ADD test /absoluteDir/ # 添加 "test" 到 /absoluteDir/
格式:
WORKDIR /path/to/workdir
示例:
WORKDIR /a (这时工作目录为/a)
注意:
通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行
格式:
RUN <command>
示例:
RUN yum install nginx
RUN pip install django
RUN mkdir test && rm -rf /var/lib/unusedfiles
注意:
RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache
格式:
CMD ["executable","param1","param2"] (执行可执行文件,优先)
CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
CMD command param1 param2 (执行shell内部命令)
示例:
CMD ["/usr/bin/wc","--help"]
CMD ping www.baidu.com
注意:
CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
格式:
ENTRYPOINT ["executable", "param1", "param2"] (可执行文件, 优先)
ENTRYPOINT command param1 param2 (shell内部命令)
示例:
ENTRYPOINT ["/usr/bin/wc","--help"]
注意:
ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT。Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令
格式:
ENV <key> <value>
ENV <key>=<value>
示例:
ENV myName John
ENV myCat=fluffy
格式:
EXPOSE <port> [<port>...]
示例:
EXPOSE 80 443
EXPOSE 8080
EXPOSE 11211/tcp 11211/udp
注意:
EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口
git clone https://gitee.com/agagin/python-demo.git
[root@k8s-master python-demo]# cat Dockerfile
# This my first django Dockerfile
# Version 1.0
# Base images 基础镜像
FROM centos:centos7.5.1804
#MAINTAINER 维护者信息
LABEL maintainer="598941324@qq.com"
#ENV 设置环境变量
ENV LANG en_US.UTF-8
ENV LC_ALL en_US.UTF-8
#RUN 执行以下命令
RUN curl -so /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
RUN yum install -y python36 python3-devel gcc pcre-devel zlib-devel make net-tools
#工作目录
WORKDIR /opt/myblog
#拷贝文件至工作目录
COPY . .
#安装nginx
RUN tar -zxf nginx-1.13.7.tar.gz -C /opt && cd /opt/nginx-1.13.7 && ./configure --prefix=/usr/local/nginx \
&& make && make install && ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx
RUN cp myblog.conf /usr/local/nginx/conf/myblog.conf
#安装依赖的插件
RUN pip3 install -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com -r requirements.txt
RUN chmod +x run.sh && rm -rf ~/.cache/pip
#EXPOSE 映射端口
EXPOSE 8002
#容器启动时执行命令
CMD ["./run.sh"]
[root@k8s-master python-demo]# cat Dockerfile-base
[root@k8s-master python-demo]# cat Dockerfile-base
# Base images 基础镜像
FROM centos:centos7.5.1804
#MAINTAINER 维护者信息
LABEL maintainer="598941324@qq.com"
#ENV 设置环境变量
ENV LANG en_US.UTF-8
ENV LC_ALL en_US.UTF-8
#RUN 执行以下命令
RUN curl -so /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
RUN yum install -y python36 python3-devel gcc pcre-devel zlib-devel make net-tools
COPY nginx-1.13.7.tar.gz /opt
#安装nginx
RUN tar -zxf /opt/nginx-1.13.7.tar.gz -C /opt && cd /opt/nginx-1.13.7 && ./configure --prefix=/usr/local/nginx && make && make install && ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx
构建基础镜像
[root@k8s-master python-demo]# docker build . -t centos-python3-nginx:v1 -f Dockerfile-base
[root@k8s-master python-demo]# docker tag centos-python3-nginx:v1 10.200.51.36:5000/base/centos-python3-nginx:v1
[root@k8s-master python-demo]# docker push 10.200.51.36:5000/base/centos-python3-nginx:v1
[root@k8s-master python-demo]# cat Dockerfile-optimized
# This my first django Dockerfile
# Version 1.0
# Base images 基础镜像
FROM centos-python3-nginx:v1
#MAINTAINER 维护者信息
LABEL maintainer="598941324@qq.com"
#工作目录
WORKDIR /opt/myblog
#拷贝文件至工作目录
COPY . .
RUN cp myblog.conf /usr/local/nginx/conf/myblog.conf
#安装依赖的插件
RUN pip3 install -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com -r requirements.txt
RUN chmod +x run.sh && rm -rf ~/.cache/pip
#EXPOSE 映射端口
EXPOSE 8002
#容器启动时执行命令
CMD ["./run.sh"]
构建镜像
docker build . -t myblog -f Dockerfile-optimized
docker run -d -p 3306:3306 --name mysql -v /opt/mysql/mysql-data/:/var/lib/mysql -e MYSQL_DATABASE=myblog -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
查看数据库
$ docker exec -ti mysql bash
#/ mysql -uroot -p123456
#/ show databases;
docker run -d -p 8002:8002 --name myblog -e MYSQL_HOST=10.200.51.36 -e MYSQL_USER=root -e MYSQL_PASSWD=123456 myblog
查看应用运行状态
[root@k8s-master python-demo]# docker exec -it myblog bash
[root@3087587eb981 myblog]# ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.0 13284 1436 ? Ss 10:49 0:00 /bin/bash ./run.sh
root 10 0.0 0.0 20544 1564 ? S 10:50 0:00 nginx: master process nginx -c /usr/local/nginx/conf/myblog.conf -g daemon off;
root 11 0.6 0.0 145272 30004 ? S 10:50 0:00 uwsgi --ini ./uwsgi.ini
nobody 12 0.0 0.0 20984 1068 ? S 10:50 0:00 nginx: worker process
root 14 0.0 0.0 219004 25500 ? Sl 10:50 0:00 uwsgi --ini ./uwsgi.ini
root 15 0.0 0.0 219004 25504 ? Sl 10:50 0:00 uwsgi --ini ./uwsgi.ini
root 18 0.6 0.0 13404 2016 pts/0 Ss 10:50 0:00 bash
root 32 0.0 0.0 53312 1864 pts/0 R+ 10:50 0:00 ps -aux
$ docker exec -ti myblog bash
#/ python3 manage.py makemigrations
#/ python3 manage.py migrate
#/ python3 manage.py createsuperuser
创建超级用户
docker exec -ti myblog python3 manage.py createsuperuser
收集静态文件
docker exec -ti myblog python3 manage.py collectstatic
访问 10.200.51.36:8002/admin
[root@k8s-master ~]# mkdir mysql
[root@k8s-master ~]# cd mysql/
[root@k8s-master mysql]# vim Dockerfile
[root@k8s-master mysql]# vim my.cnf
[root@k8s-master mysql]# cat my.cnf
[mysqld]
user=root
character-set-server=utf8
lower_case_table_names=1
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
[root@k8s-master mysql]# cat Dockerfile
FROM mysql:5.7
COPY my.cnf /etc/mysql/my.cnf
## CMD或者ENTRYPOINT默认继承
[root@k8s-master python-demo]#
[root@k8s-master python-demo]# docker build . -t mysql:5.7-utf8
Sending build context to Docker daemon 2.104MB
Step 1/2 : FROM mysql:5.7
---> 413be204e9c3
Step 2/2 : COPY my.cnf /etc/mysql/my.cnf
---> 0e412c9aaf3c
Successfully built 0e412c9aaf3c
Successfully tagged mysql:5.7-utf8
[root@k8s-master python-demo]# docker tag mysql:5.7-utf8 10.200.51.36:5000/mysql:5.7-utf8
[root@k8s-master python-demo]# docker push 10.200.51.36:5000/mysql:5.7-utf8
删除旧的 MySQL 容器,使用新镜像启动,不用再次初始化
[root@k8s-master python-demo]# docker rm -f mysql
mysql
[root@k8s-master python-demo]# rm -rf /opt/mysql/mysql-data/*
[root@k8s-master python-demo]# docker run -d -p 3306:3306 --name mysql -v /opt/mysql/mysql-data/:/var/lib/mysql -e MYSQL_DATABASE=myblog -e MYSQL_ROOT_PASSWORD=123456 10.200.51.36:5000/mysql:5.7-utf8
9b3af65a50c3a88858567bd190b6388c98016a79687ee92370a85b683b3c77ea
查看 MySQL 字符集
[root@k8s-master mysql]# docker exec -it mysql bash
root@d7440060e2a6:/# mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.29 MySQL Community Server (GPL)
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show variables like '%charac%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.01 sec)
重新 migrate
$ docker exec -ti myblog bash
#/ python3 manage.py makemigrations
#/ python3 manage.py migrate
#/ python3 manage.py createsuperuser
Docker 网络详见:https://www.cjzshilong.cn/articles/2019/03/27/1553657246955.html