Docker笔记1

什么是docker:
咱们可以通过这篇文章了解一下:
https://cloud.tencent.com/developer/article/1005172
Docker 容器本质上是宿主机上的一个进程。Docker 通过 namespace 实现了资源隔离,通过 cgroups 实现了资源的限制,通过写时复制机制(copy-on-write)实现了高效的文件操作。

从Docker底层技术来看,Docker原生态是不能直接在Windows平台上运行的,只支持linux系统,原因是Docker依赖linux kernel三项最基本的技术,namespaces充当隔离的第一级,是对Docker容器进行隔离,让容器拥有独立的hostname,ip,pid,同时确保一个容器中运行一个进程而且不能看到或影响容器外的其它进程;Cgroups是容器对使用的宿主机资源进行核算并限制的关键功能。

比如CPU,内存,磁盘等,union FS主要是对镜像也就是image这一块作支持,采用copy-on-write技术,让大家可以共用某一层,对于某些差异层的话就可以在差异的内存存储,Libcontainer是一个库,是对上面这三项技术做一个封装。

Docker engine 用来控制容器container的运行,以及镜像文件的拉取。

安装docker的过程可以参考官网,注意要用centos7:
https://docs.docker.com/install/#desktop
我这边是通过vagrant新建了一个centos7的环境,命令记录如下:

sudo systemctl start docker
sudo service docker.restart
sudo docker image ls

更多命令可以直接通过输入docker命令来查看。

docker-machine需要VirtualBox的支持,docker-machine通常会包含在docker安装包中,其独立的安装可以参照官网:
https://docs.docker.com/machine/install-machine/#install-machine-directly

docker-machine create demo1 #创建一台linux虚机
docker-machine ls
docker-machine ssh demo1 #进入虚机
docker-machine stop demo1

docker run的相关参数:

Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]    
  
  -d, --detach=false         指定容器运行于前台还是后台,默认为false     
  -i, --interactive=false   打开STDIN,用于控制台交互    
  -t, --tty=false            分配tty设备,该可以支持终端登录,默认为false    
  -u, --user=""              指定容器的用户    
  -a, --attach=[]            登录容器(必须是以docker run -d启动的容器)  
  -w, --workdir=""           指定容器的工作目录   
  -c, --cpu-shares=0        设置容器CPU权重,在CPU共享场景使用    
  -e, --env=[]               指定环境变量,容器中可以使用该环境变量    
  -m, --memory=""            指定容器的内存上限    
  -P, --publish-all=false    指定容器暴露的端口    
  -p, --publish=[]           指定容器暴露的端口   
  -h, --hostname=""          指定容器的主机名    
  -v, --volume=[]            给容器挂载存储卷,挂载到容器的某个目录    
  --volumes-from=[]          给容器挂载其他容器上的卷,挂载到容器的某个目录  
  --cap-add=[]               添加权限,权限清单详见:http://linux.die.net/man/7/capabilities    
  --cap-drop=[]              删除权限,权限清单详见:http://linux.die.net/man/7/capabilities    
  --cidfile=""               运行容器后,在指定文件中写入容器PID值,一种典型的监控系统用法    
  --cpuset=""                设置容器可以使用哪些CPU,此参数可以用来容器独占CPU    
  --device=[]                添加主机设备给容器,相当于设备直通    
  --dns=[]                   指定容器的dns服务器    
  --dns-search=[]            指定容器的dns搜索域名,写入到容器的/etc/resolv.conf文件    
  --entrypoint=""            覆盖image的入口点    
  --env-file=[]              指定环境变量文件,文件格式为每行一个环境变量    
  --expose=[]                指定容器暴露的端口,即修改镜像的暴露端口    
  --link=[]                  指定容器间的关联,使用其他容器的IP、env等信息    
  --lxc-conf=[]              指定容器的配置文件,只有在指定--exec-driver=lxc时使用    
  --name=""                  指定容器名字,后续可以通过名字进行容器管理,links特性需要使用名字    
  --net="bridge"             容器网络设置:  
                                bridge 使用docker daemon指定的网桥       
                                host    //容器使用主机的网络    
                                container:NAME_or_ID  >//使用其他容器的网路,共享IP和PORT等网络资源    
                                none 容器使用自己的网络(类似--net=bridge),但是不进行配置   
  --privileged=false         指定容器是否为特权容器,特权容器拥有所有的capabilities    
  --restart="no"             指定容器停止后的重启策略:  
                                no:容器退出时不重启    
                                on-failure:容器故障退出(返回值非零)时重启   
                                always:容器退出时总是重启    
  --rm=false                 指定容器停止后自动删除容器(不支持以docker run -d启动的容器)    
  --sig-proxy=true           设置由代理接受并处理信号,但是SIGCHLD、SIGSTOP和SIGKILL不能被代理 

docker search centos # 搜索镜像
docker pull alpine# 获取镜像
docker images # 查看本地镜像
docker rm ID # 删除容器
docker rmi ID #删除镜像
docker ps # 查看容器
docker ps -a
docker ps -l # 查看最后一个容器的信息
docker commit 容器名 镜像名 # 把退出状态的容器commit成新的images
docker run -it 镜像名 # 通过镜像启动容器
docker run -d 镜像名 # 通过镜像后台启动容器
docker start CONTAINER_NAME
docker stop CONTAINER_NAME
docker container ls -f “status=exited” -q # 列出所有状态是退出的容器,-q可以只列出来id

docker rm $(docker container ls -aq) #删除所有容器  
docker rmi $(docker image |grep "none") # 删除中间状态镜像  
docker rmi $(docker image ls -q) # 删除所有镜像  
docker rmi $(docker image ls |grep "fangfu123/ubuntu-stress"|awk '{print $3}') # 有条件的删除指定镜像  
docker rm $(docker ps -a |grep "Exited"|awk '{print $1}') # 有条件的删除指定容器  
docker exec test1 ip a # 返回容器test1执行'ip a'命令结果  
docker run -d --name test2 -e hostname=host busybox /bin/sh -c "while true; do sleep 3600; done"  # -e是定义环境变量   
docker inspect 容器ID # 显示容器详细信息  
docker logs 容器ID # 容器运行日志
  
docker history ImageID  

启动容器时用-P(大写)参数,表示让容器随机对应一个宿主机的端口,注意是随机端口:
docker run -d -P --name mynginx nginx

启动容器时用-p(小写)参数,可以指定端口号进行映射:
docker run -d -p 90:80 --name mynginx1 nginx

如果你是通过run + bash的格式进入容器,可以通过ctrl + p + q #退出命令行。

在生产环境中,通常用如下这个命令:
docker exe -it CONTAINER_NAME bash # 用exec进入容器后,用exit退出,不会停止容器运行
将容器挂载到宿主的随机目录上:
docker run -it --name test1 -h centos-01 -v /data centos

将容器挂载到宿主的指定目录上:
docker run -it --name test2 -h centos-02 -v /opt/centos-02:/data centos

创建镜像:
docker commit -m “centos with git” -a “fangfutest” ee2fbabbbcde fangfu123/my-centos:v1
-m参数是添加注释,-a参数是作者,这两个是可选参数。
后面跟的是容器id,以及要生成镜像的名称。

我们可以通过docker images 查看镜像是否创建成功。

centos7/centos6是主版本,centos6.7/centos6.8就是次版本。对于centos镜像的滚动构建,官方有以下的声明:

The CentOS Project offers regularly updated images for all active releases. These images will be updated monthly or as needed for emergency fixes. These rolling updates are tagged with the major version number only. For example: docker pull centos:6 or docker pull centos:7

我们可以用 docker pull centos:6 下载主镜像
然后通过主镜像构建容器,再通过容器构建image
相关命令如下:
docker登录:
docker login
上传命令格式:
docker push /:
如:docker push fangfu123/django:v1

基础镜像建议使用Alpine linux

docker build -t fangfu123/centos-vim-new .

RUN
执行命令并创建新的Image Layer

CMD
容器启动时默认执行的命令和参数
如果docker run指定了其他命令,CMD命令会被忽略
如果定义了多个CMD,只有最后一个会执行

ENTRYPOINT
让容器以应用程序或者服务的形式运行
不会被忽略,一定会执行
最佳实践:可以写一个shell脚本作为entrypoint
命令相关如下:
FROM alpine
ENV name Docker
CMD echo “hello, we have n a m e " C M D [ " / b i n / s h " , " − c " , " name" CMD ["/bin/sh", "-c", " name"CMD["/bin/sh","c","name change world”] #注意要用双引号
ENTRYPOINT echo “hello, we have n a m e " E N T R Y P O I N T [ " / b i n / s h " , " − c " , " name" ENTRYPOINT ["/bin/sh", "-c", " name"ENTRYPOINT["/bin/sh","c","name change world”]

简单的dockerfile演示:

FROM python:2.7
LABEL maintainer="fangfu123<[email protected]>"
RUN pip install flask
COPY app.py /app/
WORKDIR /app
EXPOSE 5000
CMD ["python", "app.py"]

关于网络名称空间的相关命令:
netns可以让一台机器上模拟多个网络设备,是网络虚拟化的重要组成,将不同类型的网络应用隔离
ip link
ip netns
ip netns add test1
ip netns add test2
ip netns exec test1 ip a
ip netns exec test1 ip link
ip link add veth-test1 type veth peer name veth-test2
ip link set veth-test1 netns test1
ip link set veth-test2 netns test2
ip netns exec test1 ip addr add 172.15.10.1/24 dev veth-test1
ip netns exec test2 ip addr add 172.15.10.1/24 dev veth-test2
ip netns exec test1 ip link set dev veth-test1 up
ip netns exec test2 ip link set dev veth-test2 up
ip netns exec test1 ip link

docker network ls
bridge
host # 跟主机的network共享一套
none # 孤立的,无网络的
docker network inspect networkID
yum install bridge-utils
brctl show

docker run -d --name test2 --link test1 busybox /bin/sh -c “while true; do sleep 3600; done”

自定义bridge可以方便快速的对bridge接入容器自动两端link
docker network create -d bridge my-bridge
docker network inspect my-bridge
docker network connect my-bridge test1
docker network connect my-bridge test2

端口映射:
docker run --name web -d -p 80:80 nginx

数据持久化:

docker run -d -v mysql:/var/lib/mysql --name mysql1 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql # 空密码为true
docker run -d -v mysql:/var/lib/mysql -p 3306:3306 --name mysql1 -e MYSQL_ROOT_PASSWORD=root mysql
docker volume ls
docker volume rm volumeID
注意-v参数,重新定义volume的别名为mysql,对应container里的/var/lib/mysql这个路径做映射,这个路径不是固定路径,具体的值需要参照你自己的Dockerfile

docker run -d -v $(pwd):/root -p 80:80 --name nginx nginx # 当前目录映射到容器的root目录下,会自动同步

我们可以添加–restart=always参数,让container自动启动

从宿主机拷贝文件到容器:
docker cp file.txt mycontainer:/opt/test/
从容器拷贝文件到宿主机:
docker cp mycontainer:/opt/test/file.txt .

pycharm链接docker:
pycharm有两个地方需要设置:
1、File – Settings – Project Interpreter ,在右边的 Project Interpreter 点配置–add
弹出add Project Interpreter,选择docker – new – 选择docker machine 点确定
最后选择image name
2、Run – Edit configurations – 0.0.0.0
关于pycharm链接docker的一些做法可以参考:
https://blog.csdn.net/liyachong138/article/details/64443707
不过这种方法在调试python程序的过程中,会奇慢无比。

你可能感兴趣的:(Docker)