docker命令
koko
一、docker命令
1. docker image 操作命令
- sudo docker image ls (or) docker images 查看系统所有image
- sudo docker pull ubuntu:14.04 安装 ubuntu 14.04 image
- sudo docker pull bitnami/wordpress 安装bitnami的wordpress image
- docker image rm [image ID] (or) docker rmi [image ID] 删除image
2. Dockerfile 编译
- docker image build (or) docker build # 将Dockerfile 编译成 image
- docker build -t xiaopeng163/hello-world . 在当前目录编译Dockerfile
- docker history [image_ID] 查看image生成过程
3. 容器管理
- docker run xiaopeng163/hello-world docker运行image
- docker run -it ubuntu 交互式运行ubuntu container
- docker run -it [image] /bin/bash 表示进入containe的 shell中
- docker run -d [image] 后台运行
- docker run -d --name=demo laosuaidami/flask-hello-world 指定容器名字
- docker container ls 当前本地正在运行的程序
- docker container ls -a or docker ps -a 所有的容器,包括正在运行的,和已经退出的
- docker container rm [containerID] (or) docker rm [containerID] 删除容器,包括正在运行的,和已经退出的
- docker container ls -aq (or) docker container ls -a|awk{'print$1'}
- docker rm $(docker container ls -aq) 删除所有container
- docker rm $(docker container ls -f 'status=exited' -q) 删除已经结束的container
- docker container commit (or) docker commit 修改container后变成新的container
- docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
- eg:docker commit quirky_chatelet hewei/centos-vim-f
- docker exec -it [container id] [要执行的命令] 进入正在运行的container中
- docker exec -it 05554595249d /bin/bash
- docker exec -it 05554595249d python
- docker exec -it 05554595249d ip a 打印运行的容器IP地址
- docker stop/start [container id (or) container name] 停止容器
- docker inspect [container id (or) container name] 查看容器信息
- docker logs [container id (or) container name] 查看容器日志
- sudo docker logs mysql1 查看安装logs
- sudo docker volume ls 查看volume
- sudo docker volume rm [volume ID] 删除volume
- docker tag SOURCEIMAGE[:TAG] TARGETIMAGE[:TAG] docker tag image:latest
4. 查看官方命令文档
https://docs.docker.com/engine/reference/commandline/container/
5. docker hub 操作
- docker login / docker logout 登录退出docker hub
- docker push laosuaidami/hello-world:latest 将docker推送到docker hub
二、Dockerfile 语法
FROM
FROM scratch # 使用base image
FROM centos # 使用base image
FROM ubuntu:14.04
尽量使用官方的image作为base image
LABEL
LABEL maintainer="[email protected]"
LABEL version="1.0"
LABEL description="This is description"
类似代码注释
RUN
RUN yum update && yum install -y vim \
python-dev # 反斜线换行
RUN apt-get update && apt-get instll -y perl\
pwgen --no-install-recommends && rm -rf \
/var/lib/apt/lists/* # 注意清理cache
RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'
WORKDIR
WORKDIR /root
WORKDIR /test # 如果没有会自动创建test目录
WORKDIR demo
RUN pwd # 输出结果应该是 /test/demo
使用WORKDIR, 不要用 RUN cd! 尽量使用绝对目录!
ADD and COPY
ADD hello /
ADD test.tar.gz / # 添加的根目录并解压
WORKDIR /root
ADD hello test/ # root/test/hello
WORKDIR /root
COPY hello test/
大部分情况, COPY 优于 ADD
ADD 除了 COPY 还有额外功能(解压)!
添加远程文件/目录请使用curl或者wget !
ENV
ENV MYSQL_VERSION 5.6 # 设置常量
RUN apt-get install -y mysql-server="${MYSQL_VERSION}" && rm -rf /var/lib/apt/lists/* # 引用常量
尽量使用,增加可维护性
VOLUME and EXPOSE (存储和网络)
CMD and ENTRYPOINT
RUM: 执行命令并创建新的Image Layer
CMD: 设置容器启动后默认执行的命令和参数
ENTRYPOINT: 设置容器启动时执行的命令
eg:
ENTRYPOINT ["/usr/bin/stress"] 这是执行的命令
CMD ['--verbose'] 这是执行的参数 可以外部输入 也可以设置默认 参数
三、容器的资源限制
1. 限制内存 --memory=xxxM
docker run --memory=200M laosuaidami/docker-stress --vm 1 --verbose --vm-bytes 500M
2. 限制cpu占用权重 --cpu-shares=10
docker run --cpu-shares=10 --name=test1 laosuaidami/docker-stress --cpu 1
docker run --cpu-shares=5 --name=test2 laosuaidami/docker-stress --cpu 1
四、docker网络
1. Linux 创建 network namespace 并将其连通
1. docker run -d --name=test1 busybox /bin/sh -c "while true; do sleep 3600; done"
2. ip a 在shell中查看IP
3. sudo ip netns list # 查看network的namespace
4. sudo ip netns delete [namespace] 删除network namespace
5. 创建network namespace
1. sudo ip netns add test1
2. sudo ip netns add test2
6. sudo ip netns exec [namespace/ test1] ip a 查看network namespace ip
7. ip link 查看IP链接
8. sudo ip netns exec [namespace/ test1] ip link set dev lo up 启动 network namespace lo 网络链接
9. sudo ip link add veth-test1 type veth peer name veth-test2 添加一对veth link
10. 添加link到network namespace
1. sudo ip link set veth-test1 netns test1
2. sudo ip link set veth-test2 netns test2
11. 分别给test1 test2 分配IP地址
1. sudo ip netns exec test1 ip addr add 192.168.1.1/24 dev veth-test1
2. sudo ip netns exec test2 ip addr add 192.168.1.2/24 dev veth-test2
12. 启动 network namespace lo 网络链接
1. sudo ip netns exec test1 ip link set dev veth-test1 up
2. sudo ip netns exec test2 ip link set dev veth-tes2 up
13. 测试网络的连通性
1. sudo ip netns exec test1 ping 192.168.1.2
2. sudo ip netns exec test2 ping 192.168.1.1
14. 创建网络
docker network create [OPTIONS] NETWORK
eg: sudo docker network create -d overlay demo # -d, --driver string-->Driver to manage the Network (default "bridge")
2. docker network namespace & docker bridge0
1. docker network ls 查看docker网络network 信息
2. sudo docker network inspect [network id] 查看network的信息(可查看network上桥接的ip)
- sudo docker network inspect 5bb68053a8c3
3. sudo docker exec test1 ip a 查看test1容器的IP信息
4. brctl show 显示Linux网桥 sudo yum install bridge-utils
3. docker容器之间的link, 通过名字访问docker,不需要ip : --link test1
1. 先创建test1容器,在创建test2容器 并让test2链接到test1上
1. docker run -d --name=test1 busybox /bin/sh -c "while true; do sleep 3600; done"
2. docker run -d --name=test2 --link test1 busybox /bin/sh -c "while true; do sleep 3600; done"
3. 测试一下(可以用test1 代替 test1 container的ip)
1. sudo docker exec -it test2 /bin/sh 进入test2的shell
2. ping test1 测试能否ping通
3. test1:3306 即可访问MySQL数据库
2. link有方向性
4. 自己新建一个bridg
1. 新建bridg:
sudo docker network create -d bridge my-bridge
2. 创建container时指定bridge: --network my-bridge
docker run -d --name test3 --network my-bridge busybox /bin/sh -c "while true; do sleep3600; done"
3. 给已经创建的container更换bridge
docker network connect my-bridge test2 test2 会同时连接到bridge和my-bridge
4. 如果两个container同时连接到一个用户自己定义的bridge时, 这两个container默认是相互link,即可以通过container name 代替 ip进行相互访问
5. container 的端口映射
1. 创建Nginx容器
1. docker run --name web -d nginx
2. 进入容器bash
1. docker exec -it web /bin/bash
3. 停止并删除web container
1. docker stop web
2. docker rm web
5.1 container 的端口映射 -p 80:80 (容器内端口:容器外端口)
1. docker run --name web -d -p 80:80 nginx
6. host 和 none 网路模式
1. host: --network host 当前容器和主机共用ip和mac
docker run -d --name test1 --network host busybox /bin/sh -c "while true; do sleep3600; done"
2. none: --network none 当前容器没有ip和mac
docker run -d --name test1 --network none busybox /bin/sh -c "while true; do sleep3600; done"
7. 多容器的复杂部署
redis 和 服务分开部署,试验代码chapter4/flask-redis
给容器添加环境变量,-e PENG=value
1. 启动redis container
1. sudo docker run -d --name redis redis
2. 编译Docker,并启动container
1. sudo build -t laosuaidami/flask-redis .
2. sudo docker run -d --link redis --name flask-redis -e REDIS_HOST=redis laosuaidami/flask-redis
3. 进入container bash 中查看
1. docker exec -it flask-redis /bin/bash
2. 在bash中输入env 可以看到 REDIS_HOST=redis
3. 在bash中输入 curl 127.0.0.1:5000 可以访问服务
4. 重启 flask-redis ,先停止后关闭再重启
1. 重启命令加 -p 5000:5000 绑定本地端口
8. 多机通信
- 创建overlay 网络, 跨设备通信 eg: sudo docker network create -d overlay demo
五、数据持久化
1. Date Volume方法:创建MySQL container (Dockerfile: VOLUME /var/lib/mysql)
1. sudo docker run -d --name mysql1 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
2. docker volume ls / docker volume rm [volume name] / docker volume inspect 查看/删除 volume
3. volume起别名(若别名存在则使用已有数据库): -v 别名:/var/lib/mysql
1. sudo docker run -d -v mysql_test:/var/lib/mysql --name mysql1 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
2. Bind Mouting方法:docker run -v /home/aaa:/root/aaa
相当于共享文件夹 开发利器 便于调试容器内的代码,本地修改即可实现
docker run -d -v $(pwd):/usr/share/nginx/html -p 80:80 --name web laosuaidami/my-nginx
六、docker compose 主要是应用在开发场景下,方便使用,是本地开发工具,能在本机上部署
1. 部署wordpress
1. 创建MySQL容器
1. sudo docker run -d --name mysql -v mysql_data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=wordpress mysql:5.7
2. sudo docker run -d --name mysql -v mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=wordpress mysql:5.7
2. 创建WordPress容器
1. sudo docker run -d -e WORDPRESS_DB_HOST=mysql:3306 --link mysql -p 8080:80 wordpress
2. sudo docker run -d -e WORDPRESS_DB_HOST=mysql:3306 --link mysql -p 8080:80 wordpress
2. docker compose
2.1 docker compose 命令
2.1.1 安装 docker compose
1. sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
2. sudo chmod +x /usr/local/bin/docker-compose
2.1.2 docker-compose 常用命令
1. docker-compose -f docker-compose.yml up -d # 启动yml文件中container
2. docker-compose ps # container list
3. docker-compose stop # stop services
4. docker-compose down # stop services and remove
5. docker-compose start # start services
6. docker-compose images # docker-compose 中的使用的 list images
7. docker-compose exec [options] [-e KEY=VAL...] SERVICE COMMAND [ARGS...]
1. eg: docker-compose exec mysql bash
2. eg: docker-compose exec wordpress bash
8. docker-compose build
1. 可以先将Dockerfile进行编译成image,再使用 docker-compose up 来启动,当然直接使用docker-compose up 也是可以的
2. 当Dockerfile更改后也可以先docker-compose build,再docker-compose up
2.2 service
2.2.1 选用docker hub image
2.2.2 选用本地Dockerfile
2.3 Volumes
2.4 Network
2.5 水平扩展和负载均衡
1. docker-compose scale 命令 # set number of container for a service
up [options] [--scale SERVICE=NUM...] [SERVICE...]
1. docker-compose up --scale web=3 -d # 同时开启3个web container
2. HAProxy + scale 负载均衡的部署服务
1. 先执行docker-compose.yml 启动服务, 再启动多个APP,实验环境chapter6/lb-scale
1. docker-compose up -d
2. docker-compose up --scale web=3 -d # 可以通过scale增加、减少web容器的数量
七、容器编排:Swarm mode
搭建 3 nodes swarm cluster setup
1. Vagrant + Virtualbox
1. 先初始化manager的cluster,宣告地址
1. docker swarm init --advertise-addr=192.168.205.10
2. 添加worker到manage cluster
1. docker swarm join --token SWMTKN-1-5zj189y4mz8yttawc6jlq1vb86hcu4lbzzo1nts1yzu7d9teaa-7g0w1oyppjynrqki1zy1pk3xi 192.168.205.10:2377
2. Docker Machine + Virtualbox
1. docker-machine creat swarm-manager
2. docker-machine creat swarm-work1
3. docker-machine creat swarm-work2
4. 之后和Vagrant + Virtualbox的方法一样了
3. Play with docker https://labs.play-with-docker.com/
Swarm 命令
1. docker swarm init --advertise-addr=192.168.205.10 # 先初始化cluster,宣告地址,让其他节点指定此节点的存在
2. docker node ls # list nodes in the swarm
3. 创建service
docker service create [OPTIONS] IMAGE [COMMAND] [ARG...]
eg: docker service create --name demo busybox sh -c "while true; do sleep 3600; done"
4. 查看service
docker service ls
5. 查看service在那台设备上
docker service ps [service name]
eg: docker service ps demo
6. docker service scale # 横向扩展,平均分配在各节点上 ,service container被删除后,会自动重启,平均分布在各cluster上
docker service scale SERVICE=REPLICAS [SERVICE=REPLICAS...]
eg: docker service scale dome=5 平均部署到各节点上
7. 删除service
ocker service rm SERVICE [SERVICE...]
eg: docker service rm demo
1. mysql + wordpress + swarm 在swarm集群里通过service部署wordpress
1. 创建overlay network
1. docker network create -d overlay demo # 创建名为demo的overlay网络
2. 创建 MySQL service
sudo docker service create --name mysql --env MYSQL_ROOT_PASSWORD=root --env MYSQL_DATABASE=wordpress --network demo --mount type=volume,source=mysql-date,destination=/var/lib/mysql mysql:5.7
3. 创建 WordPress service
sudo docker service create --name wordpress --env WORDPRESS_DB_PASSWORD=root --env WORDPRESS_DB_HOST=mysql -p 80:80 --network demo wordpress
2. 集群服务间通信之RoutingMesh
2.1 Internal 方式
1. 创建overlay network
docker network create -d overlay demo # 创建名为demo的overlay网络
2. 创建 whoami service
1. docker service create --name whoami -p 8000:8000 --network demo -d jwilder/whoami
2. docker service create --name client -d --network demo busybox sh -c "while true; do sleep 3600; done"
3. 进入 client container shell 中:
1. ping whoami # 结果ip为 10.0.0.7
2. 通过 docker service scale whoami=3 开启多个whoami container后,ping whoami 结果仍然为 10.0.0.7
3. 在 client container 中运行 nslookup tasks.whoami 发现有3个ip 10.0.0.15~10.0.0.17,
4. 由此可见 10.0.0.7 是一个虚拟ip,他只和server name 相关
4. 通过VIP多次访问请求whoami会发现轮流出现container id ,其实内部自带负载均衡,主要需要使用虚拟ip访问才行
5. LVS--> Linux virtual Server lvs + keepalived 配置一个高可用的负载均衡
LVS--> Linux virtual Server 详见官方文档
2.2 Ingress Network 方式
试验环境和2.1一样,在各个note server shell 运行:curl 127.0.0.1:8000, 会发现返回不同container id
1. 查看转发规则运行命令:sudo iptables -nL -t nat
2. brctl show 显示Linux网桥 sudo yum install bridge-utils
3. docker network inspect docker_gwbridge # 查看'ingress-sbox'ip
4. sudo ls /var/run/docker/netns 查找'ingress-sbox'文件
5. sudo nsentre --net=/var/run/docker/netns/ingress-sbox 进入'ingress-sbox'文件
6. ip a # 查看ip
1. 查看防火墙 iptables -nL -t mangle
2. sudo yum install ipvsadm 使用命令 ipvsadm -l
3. DockerStack 部署wordpress
1. 运行yml文件, docker stack deploy [OPTIONS] STACK
eg: docker stack deploy -c=docker-compose.yml wordpress
2. 查看stack
eg: docker stack ls
3. 查看stack的具体细节
eg: docker stack ps wordpress
4. 查看stack services
eg: docker stack services wordpress
4. Docker Secrets Managment
方法一:创建secrete
1. 新建文件将密码写入其中:假如文件名叫password
2. 创建secrete: docker secret create [OPTIONS] SECRET [file|-], 注意此步完成后可以删除password文件了!!!
eg: docker secret create my-pw password
3. 查看 secrete:
eg: docker secret ls
方法二:创建secrete
1. 命令行创建 secret:
echo "root" | docker secret create my-pw2 -
2. 删除secret
docker secret rm my-pw2
使用 secrete
1. 创建docker service create 使用--secret指定secret # Specify secrets to expose to the service
eg: docker service create --name demo --secret my-pw busybox sh -c "while true; do sleep 3600; done"
2. 查看secrete,进入容器:docker exec -it demo sh
eg: cat /run/secrets/my-pw
3. mysql service 创建的时候指定secret文件
eg: docker service create --name db --secret my-pw -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/my-pw mysql:5.7
4. compose 中使用secret:
version: '3.7'
services:
web:
image: wordpress
ports:
- 8080:80
secrets:
- my-pw
environment:
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_PASSWORD_FILE: /run/secrets/my-pw
networks:
- my-network
depends_on:
- mysql
deploy:
mode: replicated
replicas: 3
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
update_config:
parallelism: 1
delay: 10s
mysql:
image: mysql:5.7
secrets:
- my-pw
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/my-pw
MYSQL_DATABASE: wordpress
volumes:
- mysql-data:/var/lib/mysql
networks:
- my-network
deploy:
mode: global
placement:
constraints:
- node.role == manager
volumes:
mysql-data:
networks:
my-network:
driver: overlay
# secrets:
# my-pw:
# file: ./password
secrets:
my-pw:
external: true
# name: my-pw2
更新service
1. 新建network: docker network create -d overlay demo
2. 创建service:docker service create --name web --publish 8080:5000 --network demo xiaopeng163/python-flask-demo:1.0
3. 增加web容器:docker service scale web=2
4. 更新image:docker service update --image xiaopeng163/python-flask-demo:2.0 web
5. 更新端口:ocker service update --publish-rm 8080:5000 --publish-add 8888:5000 web
7. compose.yml 更新, 需要更改yml文件,然后重新运行compose.yml文件,并且可以在yml中deploy字段设置更新模式
deploy:
mode: replicated
replicas: 3
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
update_config:
parallelism: 1 # 同时允许几个scale更新
delay: 10s # 每次更新延时
八、Docker Cloud 之自动 build Docker image