1.Docker入门
1.1 Docker为什么火
1.2 Docker是什么
1.3 为什么要使用Docker
1.4 Docker与虚拟化区别
1.5 Docker Engine
1.6 Docker 体系结构
1.7 Docker 应用场景
场景一、节省项目环境部署时间
场景二、环境一致性
场景三、持续集成
场景四、微服务
总结:开箱即用、快速部署、可移植强、环境隔离。
2.Docker安装
2.1 安装Docker
curl -o /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install docker-ce -y
systemctl start docker
systemctl enable docker
2.1.1 调整镜像源从国内获取
[root@container ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://q2gr04ke.mirror.aliyuncs.com"]
}
2.1.2 调整docker数据存储位置
[root@container ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://q2gr04ke.mirror.aliyuncs.com"],
"graph": "/data/docker"
}
2.2 如何快速运行一个容器
3.Docker镜像
3.1 什么是镜像?
镜像是一推程序和文件的集合。封装了业务需要运行的代码、环境、配置文件等 ( 只读的实例 )
3.2 镜像能干什么?
镜像可以启动容器,容器需要依赖镜像才可以启动。
3.3 如何使用镜像运行容器
docker run hello-world
3.4 镜像的基本操作。搜索、下载、查看、导入、导出、删除、上传
- 搜索镜像
[root@container ~]# docker search centos | nginx
- 下载镜像
[root@container ~]# docker pull centos:7
- 查看镜像列表
[root@container ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos 7 5e35e350aded 4 months ago 203MB hello-world latest fce289e99eb9 14 months ago 1.84kB [root@container ~]# [root@container ~]# [root@container ~]# [root@container ~]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE centos 7 5e35e350aded 4 months ago 203MB hello-world latest fce289e99eb9 14 months ago 1.84kB
- 删除镜像
[root@container ~]# docker image rmi fce289e99eb9 [root@container ~]# docker image rmi -f fce289e99eb9
- 备份镜像
[root@container ~]# docker save centos:7 > /opt/centos.tar.gz
- 恢复镜像
[root@container ~]# docker load < /opt/centos.tar.gz
4.Docker容器
4.1 什么是容器
容器是镜像运行的一个实例,当启动搞一个容器就好像虚拟机程序启动了一台VM一样。
4.2 容器能运行什么
4.3 启动第一个容器
[root@container ~]# docker run -it centos:7 /bin/bash
4.4 容器运行的参数含义
docker run
表示要启动一个容器
-i
:表示 启动一个可交互的容器。并且持续打开标准输入
-t
:表示使用终端关联到容器的标准输入输出上
IMAGE
:表示我们需要运行的镜像
COMMAND
:运行该镜像需要执行的命
4.5 如何运行一个自启动的容器
[root@container ~]# docker run -it centos:7 echo "hello docker"
hello docker
[root@container ~]# docker run --name=mycentos centos:7 echo "hello world"
hello world
[root@container ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d937259c16fd centos:7 "echo 'hello world'" 7 seconds ago Exited (0) 7 seconds ago mycentos
[root@container ~]# docker run -itd centos:7 /bin/bash
运行一个测试的容器
[root@container ~]# docker run --rm centos:7 echo "hello rm"
启动|停止|restart
[root@container ~]# docker start 7bff740a839e
[root@container ~]# docker stop 7bff740a839e
[root@container ~]# docker restart 7bff740a839e
查看状态
[root@container ~]# docker info
Client:
Debug Mode: false
Server:
Containers: 8
Running: 1
Paused: 0
Stopped: 7
Images: 2
[root@container ~]# docker ps
[root@container ~]# docker ps -a #查看所有的容器
4.6 如何进入一个容器
[root@container ~]# docker exec -it d2e317b867f4 /bin/bash
清理容器
[root@container ~]# docker rm $(docker ps -a -q)
4.7 容器暴露
1.容器服务没有对外暴露?
需要通过该容器所在的宿主机去访问?
2.容器服务对外暴露?
-p 8888:80
-p hostip:hostport:containerPort
-p hostip::containerPort #随机端口的方式
-P #随机
[root@container ~]# docker run -d -p 8888:80 nginx:latest
[root@container ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9ef625ae989f nginx:latest "nginx -g 'daemon of…" 28 seconds ago Up 27 seconds 0.0.0.0:8888->80/tcp hardcore_hertz
4.8 容器的整个生命周期
以centos容器为例:
1.Docker会去获取centos的镜像,检查本地是否存在,如果存在则使用,如果不存在则上默认的远程仓库拉取该进行。
2.Docker通过Centos镜像创建一个新的容器,并且在镜像的文件 系统之上添加一层 ”可读写“ 的层来运行应用程序。
3.Docker会通过网桥设备,为容器划分一个IP地址,并挂载至于容器中。
4.Docker会执行启动的命令,比如/bin/bash 表示启动一个和本地主机可交互的进程。
5.执行完毕后容器就自动退出。让我们的进程一直处于RUNNING状态。
5.Docker数据管理
5.1 数据持久化介绍
1.什么是data volume
volumes
bind mounting
5.2 数据持久化-Data Volume
[root@container ~]# docker pull mysql:5.7
[root@container ~]# docker volume ls
[root@container ~]# docker volume inspect 2e1a36612354ead1d104c384e74b3b9b37ae5dc61ee7246296d9f8cdb0f56d6f
别名:
[root@container ~]# docker run -d --name mysql2 -v mysql2_data:/var/lib/mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=yes mysql:5.7
[root@container ~]# docker volume ls
数据持久化了,mysql2容器故障了,我重新启动一个mysql3 是否还能继续使用mysql2的数据呢?
docker rm -f mysql2
docker run -d --name mysql3 -v mysql2_data:/var/lib/mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=yes mysql:5.7
docker exec -it mysql3 /bin/bash
5.3 数据持久化-Bind Mounting ( web )
docker run -d -v /html:/usr/share/nginx/html -p:8989:80 nginx
6.Docker镜像构建
6.1 如何将运行的容器打包成镜像
yum install openssh-server openssh-clients -y
sshd-keygen
/usr/sbin/sshd -D
封装为镜像:
docker commit a7432ced3e68 centos7_sshd:v1
docker run -d -p:2222:22 centos7_sshd:v1 /usr/sbin/sshd -D
6.2 如何实现自动化构建镜像
dockerfile 一系列的命令和参数组成的YML文件。 这么命令可以给予Docker镜像创建一个新的Docker镜像。
6.3 Dockerfile介绍
6.4 Dockerfile语法
FROM
:基础镜像
RUN
:执行Bash命令
ADD
:将文件或者目录复制到镜像中 ( 压缩包,会自动解压 )
COPY
:将文件或者目录复制到镜像中
WORKDIR
:切换目录,类似于cd命令
EXPOSE
:对外暴露的端口是什么
ENV
:环境变量(设定环境变量)
ENTRYPOINT
:容器启动后执行的命令(必须执行)
CMD
:设定容器默认启动的命令 /usr/sbin/sshd -D
6.5 dockerfile构建—>remote服务
[root@container ssh]# cat Dockerfile
FROM centos:7
RUN yum install openssh-server openssh-clients -y && \
sshd-keygen && \
echo "123" | passwd --stdin root
EXPOSE 22
CMD ["/usr/sbin/sshd","-D"]
6.5 dockerfile构建—>web服务 httpd
[root@container ssh_http]# cat init.sh
#!/usr/bin/bash
if [ -n $root_pass ];then
echo $root_pass | passwd --stdin root
fi
/usr/sbin/httpd
/usr/sbin/sshd -D
[root@container ssh_http]# cat Dockerfile
FROM centos:7
RUN yum install openssh-server openssh-clients httpd -y && \
sshd-keygen && \
echo 123 | passwd --stdin root
ADD init.sh /init.sh
EXPOSE 22 80
CMD ["/bin/bash","/init.sh"]
6.6 dockerfile构建—>kodcloud服务
yum install httpd php -y
wget http://static.kodcloud.com/update/download/kodexplorer4.40.zip
chmod -R 777 /var/www/html/
init.sh
/usr/sbin/httpd
tail -f /dev/null
6.7 dockerfile构建—>运维工具 (搞清楚ENTRYPOINT与CMD之间的关系与区别)
CMD
: 容器启动时执行的命令(容易被覆盖)
[root@container cmd]# cat Dockerfile
FROM centos:7
CMD ["echo","hello cmd"]
[root@container cmd]# docker build -t centos7_cmd .
[root@container entrypoint]# cat Dockerfile
FROM centos:7
ENTRYPOINT ["echo","hello entrypoint"]
CMD与Entrpoint结合使用
[root@container cmd_entrypoint]# cat Dockerfile
FROM centos:7
ENTRYPOINT ["tail"]
CMD ["-f","/etc/passwd"]
ENTRYPOINT
CMD
都是表示 容器启动时要执行的指令,ENTRYPOINT
不能被替换 CMD
可以被替换
当出现ENTRYPOINT
和CMD
ENTRYPOINT
必须执行,CMD
就最为了ENTRYPOINT
参数被传递
7.Docker私有仓库
7.1 什么是私有仓库
仓库用来存储我们的镜像的。 对内不对外。
7.2 为什么要有私有仓库
1.速度慢
2.A -> 仓库 <- B
7.3 私有仓库种类
registry
harbor
7.2 搭建私有仓库registry
[root@container cmd_entrypoint]# docker pull registry
# docker run -d -p 5000:5000 \
--restart=always \
--name registry \
-v /opt/myregistry:/var/lib/registry \
registry
"insecure-registries": ["10.0.0.200:5000"]
1.启动带basic认证的registry
[root@docker01 ~]# yum install httpd-tools -y
[root@docker01 ~]# mkdir /opt/registry-var/auth/ -p
[root@docker01 ~]# htpasswd -Bbn oldxu 123456 > /opt/registry-var/auth/htpasswd
[root@docker01 ~]# docker run -d -p 5000:5000 \
-v /opt/registry-var/auth/:/auth/ \
-v /opt/myregistry:/var/lib/registry \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" registry
7.3 如何将本地镜像存放私有仓库
7.4 如何获取私有仓库的docker镜像
7.5 企业级私有仓库harbor
wget https://github.com/goharbor/harbor/releases/download/v1.10.1/harbor-offline-installer-v1.10.1.tgz
[root@container ~]# yum install docker-compose -y
[root@container harbor]# docker rm -f $(docker ps -a -q)
1.解析域名
2.打标签
docker tag registry:latest s.xuliangwei.com/library/registry:latest
3.登陆harbor
docker login s.ct99.cn
admin
Harbor12346
4.推送
docker push s.ct99.cn/library/registry:latest
7.5.1 harbor配置https
7.5.2 harbor同步其他仓库镜像
7.6 实战a主机推送镜像至仓库,b主机拉取镜像启动为容器
8.Docker网络
8.1 docker容器互联是什么?--link
A容器–>连接B容器。
[root@container ~]# docker run -it --rm --name myredis alpine:latest /bin/sh
[root@container ~]# docker run -it --rm --name python-web --link myredis alpine:latest /bin/sh
8.2 docker容器互联项目实践( python、php )
1.准备app.py
[root@docker-node1 flask-redis]# cat app.py
from flask import Flask
from redis import Redis
import os
import socket
app = Flask(__name__)
redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)
@app.route('/')
def hello():
redis.incr('hits')
return 'Hello Container World! website access %s count! and my hostname is %s.\n' % (redis.get('hits'),socket.gethostname())
if __name__ == "__main__":
app.run(host="0.0.0.0", port=80, debug=True)
2.准备Dockerfile
[root@docker-node1 flask-redis]# cat Dockerfile
FROM python:2.7
RUN pip install flask redis
ADD app.py /
EXPOSE 80
CMD [ "python", "/app.py" ]
3.启动redis容器
[root@container python-web]# docker run -itd --name myredis redis:latest
4.启动python程序,为REDIS_HOST
传递变量,将redis容器名称传递过去。
[root@container python-web]# docker run -itd --name python-web -p8899:80 -e "REDIS_HOST=myredis" --link myredis python-web:v1
8.3 docker网络模式 ( bridge、host、container、none )
bridge:
[root@container ~]# docker network create -d bridge mynet
[root@container ~]# docker run -it --name net01 --network mynet alpine:latest /bin/sh
ping测试网络是否畅通,
host:
docker run -itd --network=host nginx:latest
docker run -itd --network=host redis:latest
container:
容器1 容器2 127.0.0.1
[root@container ~]# docker run -d -p80:80 -p6379:6379 --name db redis:latest
[root@container ~]# docker run -d --name python-web --network=container:db python-web:v1
none:
[root@container ~]# docker run -it --network=none alpine:latest /bin/sh
9.Docker单机编排
9.1 Compose基本介绍
[root@docker-node1 ~]# docker pull wordpress
[root@docker-node1 ~]# docker pull mysql:5.7
[root@docker-node1 ~]# docker run -d --name mysql \
-v mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_DATABASE=wordpress \
mysql:5.7
[root@docker-node1 ~]# docker run -d --link mysql \
-e WORDPRESS_DB_HOST=mysql:3306 \
-p 8080:80 \
wordpress
容器编排工具,他可以通过YAML语法描述一组有关联的应用容器。 docker-compose up -d
9.2 Compose三大概念 project(services、volumes、networks)
services示例
version: '3'
services:
db: #定义容器名称
image: postgres:9.4 #定义容器所需镜像
ports: #定义容器对外暴露的端口
- 5423:5423
environment: #定义环境变量
POSTGRES_PASSWORD: 123456
volumes: #定义容器持久化哪个目录下的数据
- "pg-data:/var/lib/postgresql/data"
networks:
- pg-net #定义容器使用哪个network
docker run --name db -p:5423:5423 -e "POSTGRES_PASSWORD=123456" -v "pg-data:/var/lib/postgresql/data" --net=pg-net postgres:9.4
version: '3'
services:
db:
image: postgres:9.4
ports:
- 5423:5423
environment:
POSTGRES_PASSWORD: 123456
volumes:
- pg-data:/var/lib/postgresql/data
#由于容器需要使用pg-data数据卷持久化,所以需要使用volumes创建该卷
volumes:
pg-data:
version: '3'
services:
db:
image: postgres:9.4
ports:
- 5423:5423
environment:
POSTGRES_PASSWORD: 123456
volumes:
- pg-data:/var/lib/postgresql/data
networks:
- pg-net
volumes:
pg-data:
#容器需要依赖该网卡名称,所以需要创建,并且指定类型
networks:
pg-net:
driver: bridge
9.3 Compose编排博客系统
version: '3'
services:
wordpress:
image: wordpress
ports:
- 9999:80
links:
- mysql
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_PASSWORD: root
networks:
- my-wordpress
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: wordpress
volumes:
- mysql-data:/var/lib/mysql
networks:
- my-wordpress
volumes:
mysql-data:
networks:
my-wordpress:
driver: bridge
9.4 Compose编排Python
[root@docker-node1 flask-redis]# cat docker-compose.yml
version: "3"
services:
redis:
image: redis
web:
build:
context: .
dockerfile: Dockerfile
ports:
- 8888:80
links:
- redis
environment:
REDIS_HOST: redis
[root@docker-node1 flask-redis]# docker-compose up -d
python-web + redis
python-web
python-web
9.5 Compose实现水平扩展
[root@docker-node1 flask-redis]# cat docker-compose.yml
version: "3"
services:
redis:
image: redis
web:
build:
context: .
dockerfile: Dockerfile
# ports:
# - 8888:80
links:
- redis
environment:
REDIS_HOST: redis
docker-compose up --scale web=3 -d
9.6 Compose实现负载均衡
version: "3"
services:
redis:
image: redis
web:
build:
context: .
dockerfile: Dockerfile
# ports:
# - 8888:80
links:
- redis
environment:
REDIS_HOST: redis
#新增lb负载均衡
lb:
image: dockercloud/haproxy
links:
- web
ports:
- 8080:80
- 1936:1936 #haproxy管理页面
volumes:
- /var/run/docker.sock:/var/run/docker.sock
9.7 Compose编排投票系统 (python、node、java、db、redis)
10.Docker图形化与监控
10.1 docker图形工具 Portainer
docker pull docker.io/portainer/portainer
docker run -d -p 9000:9000 \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
--name prtainer-pro \
docker.io/portainer/portainer
10.2 docker监控工具 cAdvisor
docker pull google/cadvisor
docker run \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:rw \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--volume=/dev/disk/:/dev/disk:ro \
--publish=8787:8080 \
--detach=true \
--name=cadvisor \
google/cadvisor:latest