1. 安装配置
1.1 安装
sudo apt remove docker docker-engine docker.io
sudo apt install docker.io
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
apt-cache madison docker-ce
sudo apt install docker-ce=<VERSION>
sudo usermod -aG docker $USER
sudo systemctl restart docker
https://download.docker.com/linux/static/stable
1.2 启动配置
mkdir -p /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
],
"insecure-registries" : [ "192.168.80.250:5000" ]
}
EOF
1.3 支持代理
mkdir -p /etc/systemd/system/docker.service.d
cat > /etc/systemd/system/docker.service.d/http-proxy.conf <<EOF
[Service]
Environment="ALL_PROXY=socks5://192.168.31.20:1080/"
Environment="NO_PROXY=localhost,127.0.0.1,docker.io,hub.elihe.io,pvjhx571.mirror.aliyuncs.com"
EOF
systemctl daemon-reload && systemctl restart docker
1.4 远程访问
vi /etc/docker/daemon.json
{
"hosts": ["tcp://0.0.0.0:2357", "unix:///var/run/docker.sock"]
}
docker -H 192.168.31.41 network show
2. 镜像管理
2.1 基本操作
docker images
docker search nginx
docker pull nginx
docker rmi nginx
docker tag nginx nginx:v0.1
docker push nginx:v0.1
docker history nginx:v0.1
docker image prune
docker image prune -a
2.2 容器和镜像
-
export/import:容器文件化
-
save/load: 镜像文件化
-
commit: 容器镜像化
docker save -o nginx.tar nginx
docker load -i nginx.tar
docker run --name nginx-server -p 8080:80 -d nginx
root@02d9c2b750f6:/
docker export -o nginx-server.tar nginx-server
docker import nginx-server.tar nginx:v0.2
docker commit -p nginx-server nginx:v0.3
使用场景:
save & load
: 适合 docker-compose.yml
编排的组合镜像,进行离线的迁移export & import
: 适合在基础镜像启动的容器中,安装了其他软件或服务后,将该容器导出,形成一个新的镜像。
文件的区别:
save
: 是一个 docker 分层文件系统, 因为它由一层层文件系统叠加起来,存在很多重复的文件,所以较大export
: 是一个 Linux 系统文件目录
2.3 构建镜像
2.3.1 Dockerfile 指令
-
FROM: 指定基础镜像
- 服务类镜像:
nginx
、redis
、mongo
、mysql
、httpd
、php
、tomcat
- 语言类镜像:
node
、openjdk
、python
、ruby
、golang
- 操作系统镜像:
ubuntu
、debian
、centos
、fedora
、alpine
- 空白镜像:
scratch
适用于静态编译的程序,不需要操作系统支撑。
-
MAINTAINER:
-
COPY: 复制文件
-
ADD: 支持添加URL,自动解压文件等
-
WORKDIR: 指定默认目录工作
-
RUN: 构建镜像时执行, 用于安装应用和软件包,创建用户等操作
-
ENTRYPOINT: 运行容器的入口命令, 但支持额外参数
-
CMD: 运行容器的启动命令。如果没有定义 ENTRYPOINT, CMD 将作为它的 ENTRYPOINT;如果定义了 ENTRYPOINT 的话,CMD 只为 ENTRYPOINT 提供参数;CMD 可由 docker run 后的命令覆盖,同时覆盖参数
-
ENV: 设置环境变量
-
VOLUME: 定义匿名卷
-
EXPOSE: 曝露端口
-
USER:指定当前用户
-
HEALTHCHECK
2.3.2 scratch镜像
golang程序:静态编译
mkdir -p scratch && cd $_
cat > hello.go <<EOF
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
EOF
cat > Dockerfile <<EOF
FROM golang as builder
WORKDIR /go/src/app
COPY hello.go .
RUN go build -ldflags="-w -s" hello.go
FROM scratch
COPY --from=builder /go/src/app/hello /
CMD ["/hello"]
EOF
docker build -t hello .
docker run --rm hello
2.3.3 示例:构建Nginx镜像
$ mkdir -p nginx && cd $_
$ vi index.html
<h1>hello world!</h1>
$ vi entrypoint.sh
cat > /etc/nginx/conf.d/default.conf <<EOF
server {
listen ${IP:-0.0.0.0}:${PORT:-80};
server_name $HOSTNAME;
location / {
root ${WEB_ROOT:-/usr/share/nginx/html};
index index.html index.htm;
}
}
EOF
exec "$@"
$ vi Dockerfile
FROM nginx:1.19.2-alpine
LABEL maintainer="eli.he@live.cn"
ENV WEB_ROOT="/data/www/html/"
WORKDIR $WEB_ROOT
ADD index.html ./
ADD entrypoint.sh /bin/
RUN chmod +x /bin/entrypoint.sh
EXPOSE 80/tcp
HEALTHCHECK --start-period=3s CMD curl -o - -q http://${IP:-0.0.0.0}:${PORT:-80}
CMD ["/usr/sbin/nginx", "-g", "daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]
$ docker build -t web:1.0 .
$ docker run -p 8080:80 -d web:1.0
2.3.4 易错点
-
错误的文件系统操作
在 Shell 中,连续两行是同一个进程执行环境,因此前一个命令修改的内存状态,会直接影响后一个命令;而在 Dockerfile 中,这两行 RUN 命令的执行环境根本不同,是两个完全不同的容器。
RUN cd /app
RUN echo "hello" > world.txt # 文件并不在/app目录下
-
docker中的进程,必须以前台方式启动
对于容器而言,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义,从而退出,其它辅助进程不是它需要关心的东西。
CMD echo $HOME
CMD ["sh", "-c", "echo $HOME"] # 实际执行命令
# 错误的示范
CMD service nginx start
CMD ["sh", "-c", "service nginx start"] # 实际执行命令
# 正确的nginx启动命令, 必须以前台形式运行
CMD ["nginx", "-g", "daemon off"]
-
支持额外参数
CMD ["curl", "-s", "https://cip.cc"] # 不主持额外参数
ENTRYPOINT ["curl", "-s", "https://cip.cc"] # 支持额外参数,docker run --rm myip -i 获取HTTP请求头,但这里报错,无法将该参数传入
2.4 特殊镜像
2.4.1 虚悬镜像
仓库名、标签均为 的镜像 (docker pull/build 时,原有的镜像名被占用,会导致此种情况)
$ docker images -f dangling=true
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 06ebe39c8aee 11 minutes ago 22.1MB
<none> <none> 62c8bc68a9ed 33 minutes ago 942MB
$ docker image prune
2.4.2 中间层镜像
为了加速镜像构建、重复利用资源,Docker 会利用 中间层镜像
$ docker images -a
3. 容器管理
3.1 基本操作
docker create --name myweb -p 8080:80 nginx
docker start myweb
docker stop myweb
docker pause myweb
docker unpause myweb
docker ps
docker kill myweb
docker rm myweb
docker run --name test -it busybox /bin/sh
docker attach test
docker run --name myweb -p 8080:80 -d nginx
docker exec -it myweb /bin/sh
docker logs -tf --tail=10 myweb
docker inspect myweb
docker port myweb
docker top myweb
docker stats myweb
docker cp myweb:/usr/share/nginx/html/50x.html .
docker cp index.html myweb:/usr/share/nginx/html/
3.2 资源限制
docker run --cpu-shares=512
docker run --cpuset-cpus=0,2,4
docker run --memory 300M
3.3 访问宿主机
docker run --rm -it --cap-add SYS_ADMIN --device /dev/fuse sshfs
docker run -it --device=/dev/ttyUSB0 ubuntu /bin/sh
docker run -it --privileged -v /dev/bus/usb:/dev/bus/usb ubuntu /bin/sh
3.4 容器诊断
docker commit 05dd6f84ddf9 user/debug
docker run -it --rm user/debug /bin/sh
docker run --rm --entrypoint="" grafana/grafana:latest /bin/sh -c 'cat /etc/passwd | grep grafana'
3.5 容器自动启动
docker run --restart=always
docker update --restart=always 07fb7442f813
--restart
参数值:
- no: 不自动重启,默认值
- on-failure: 容器错误退出,即退出码不为0时,重启容器
- always:容器停止,自动重启。如果手动停止,需要重启dockerd进程或者重启容器本身才生效。主要用于宿主机重启后,自动启动容器
- unless-stopped:同always,但当手动停止,即使重启dockerd进程,也无法自动启动容器
4. 资源清理
docker kill $(docker ps -aq)
docker rm $(docker ps -aq)
docker rm -v $(docker ps -aq -f status=exited)
docker rm -v $(docker ps -aq -f status=dead)
docker rmi $(docker images -q)
docker volume rm $(docker volume ls -q)
docker volume rm $(docker volume ls -qf dangling=true)
docker system df
docker system df -v
docker system prune
docker system prune -a
docker system prune -f
docker images -f dangling=true
5. 常用镜像
docker pull mysql:5.7
docker run --name mysql-server -p 3306:3306 -v /data/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
docker pull redis:6.0.10
docker run --name reids-server -p 6379:6379 -d redis:6.0.10
docker pull elasticsearch:7.16.3
docker run --name es -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -d elasticsearch:7.16.3
6. 使用技巧
6.1 输出控制
$ docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Ports}}"
CONTAINER ID NAMES PORTS
6c30d12fadaf nexus3 0.0.0.0:8081->8081/tcp, :::8081->8081/tcp
名称 | 含义 |
---|
.ID | 容器ID |
.Image | 镜像ID |
.Command | 执行的命令 |
.CreatedAt | 容器创建时间 |
.RunningFor | 运行时长 |
.Ports | 暴露的端口 |
.Status | 容器状态 |
.Names | 容器名称 |
.Label | 分配给容器的所有标签 |
.Mounts | 容器挂载的卷 |
.Networks | 容器所用的网络名称 |
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)