# Docker快速入门 ## Docker安装 在Rocky8上,可以先配置对应版本的yum仓库,然后使用yum工具安装Docker 1.先安装yum-utils工具 ``` yum install -y yum-utils ``` 2.配置Docker官方的yum仓库 ``` yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo ``` 3.查看Docker版本 ``` yum list docker-ce --showduplicates | sort -r ``` 4.安装指定版本Docker ``` yum install docker-ce-20.10.9-3.el8 ``` 如果不指定版本,就安装最新版 ``` yum install docker-ce ``` 5.启动服务 ``` systemctl start docker systemctl enable docker ``` ## Docker镜像和容器 关于镜像这个词,大家并不陌生,比如系统安装盘就叫镜像,另外我们常见的Ghost技术做的GHO系统镜像和这个Docker镜像非常像。我们可以将GHO镜像安装到任何计算机上,这样就拿到了跟源系统一模一样的系统。 当然Docker镜像也有它独特之处,比如它是分层的,这个后续在拉取镜像时可以看到。 Docker镜像拉取下来后,可以直接运行,运行后的东西我们叫做容器,一个镜像可以启动很多容器。 容器就是镜像启动后的状态,在Linux系统里看就是一个进程,但容器是可以进入得,就像进入了一个虚拟机里。 1.配置加速器 编写/etc/docker/daemon.json ``` cat > /etc/docker/daemon.json < web01.tar ``` 19.将导出的文件导入为新的镜像 ``` docker import - ubuntu_test < web01.tar ``` 20.docker save和docker export的差异 ``` docker save保存的是镜像,docker export保存的是容器 docker save会保留镜像所有的历史记录,docker export不会,即没有commit历史 docker load用来载入镜像包,docker import用来载入容器包,但两者都会恢复为镜像; docker load不能对载入的镜像重命名,而docker import可以为镜像指定新名称。 ``` ## Docker的数据持久化 1.将本地目录映射到容器里 ``` mkdir -p /data/ docker run -tid -v /data/:/data ubuntu bash ## -v 用来指定挂载目录 :前面的/data/为宿主机本地目录 :后面的/data/为容器里的目录,会在容器中自动创建 ``` 可以在/data/里创建一个文件 ``` echo "hello" > /data/1.txt ``` 然后到容器里查看 ``` docker exec -it c82a5a00ae68 bash -c "cat /data/1.txt" ``` 2.数据卷 创建数据卷 ``` docker volume create testvol ##testvol为数据卷名字 ``` 列出数据卷 ``` docker volume ls ``` 查看数据卷信息 ``` docker volume inspect testvol ``` 使用数据卷 ``` docker run -itd --name Cloud01 -v testvol:/data/ ubuntu ##和前面直接映射本地目录不同,冒号左边为数据卷名字 ``` 多个容器共享一个数据卷 ``` docker run -itd --name Cloud02 -v testvol:/data/ ubuntu ``` 3.将宿主机上的文件快速传输进容器里 ``` docker cp /etc/fstab Cloud01:/tmp/test.txt docker exec -it Cloud01 cat /tmp/test.txt ``` ## Docker网络 Docker服务启动时会生成一个docker0的网卡,这个网卡是实现容器网络通信的根本。 默认容器使用的网络类型为桥接(bridge.模式,这个桥接和我们的vmware里的桥接可不是一回事。它更像是vmware的NAT模式。 每启动一个容器,都会产生一个虚拟网卡 vethxxx ``` iptables -nvL -t nat ##可以看到DOCKER相关规则,容器之所以可以联网,是靠这些规则实现的 ``` 1.host模式 ``` docker run -itd --net=host --name Cloud03 ubuntu ``` 可以进入容器内,查看hostname,查看ip地址。 这种模式,容器和宿主机共享主机名、IP。 2.container模式 该模式下,在启动容器时,需要指定目标容器ID或者name,意思是将要启动的容器使用和目标容器一样的网络,即它们的IP一样 ``` docker run -itd --net=container:/Cloud01 --name Cloud04 ubuntu ``` 可以进入容器查看Cloud01和Cloud04的网络情况 3.none模式 即不需要配置网络 ``` docker run -itd --net=none --name=Cloud05 ubuntu_test bash ``` 查看: ``` docker exec -it Cloud05 bash -c "ip add" ``` 4.bridge模式 也就是默认模式,可以--net=bridge 也可以不指定--net,默认就是bridge 5.端口映射 ``` docker run -itd -v /data/:/var/www/html/ -p 8088:80 --name Cloud06 ubuntu_test bash ``` 说明: -p后面跟 宿主机监听端口:容器监听端口 ## Dockerfile编写 什么是Dockerfile?是实现自定镜像的一种手段,通过编写Dockerfile,来编译成自己想要的镜像。 Dockerfile 格式 1.FROM 指定基于哪个基础镜像,例如: ``` FROM ubuntu:latest ``` 2.MAINTAINER 指定作者信息,例如: ``` MAINTAINER Cloud Cloud@CloudPLayer ``` 3.RUN 后面跟具体的命令,例如: ``` RUN apt update RUN apt install -y curl RUN ["apt","install","-y","curl" ] ##这种写法偏复杂 ``` 4.CMD 用来指定容器启动时用到的命令,只能有一条,格式如下: ``` CMD ["executable", "param1", "param2"] CMD command param1 param2 CMD ["param1", "param2"] CDM示例: CMD ["/bin/bash", "/usr/local/nginx/sbin/nginx", "-c", "/usr/local/nginx/conf/nginx.conf"] ``` 5.EXPOSE 指定要映射的端口,格式: ``` EXPOSE [...] EXPOSE示例: EXPOSE 22 80 8443 ##要暴露22,80,8443三个端口 ``` 说明:这个需要配合-P(大写.来工作,也就是说在启动容器时,需要加上-P,让它自动分配。如果想指定具体的端口,也可以使用-p(小写.来指定。 6.ENV 为后续的RUN指令提供一个环境变量,我们也可以定义一些自定义的变量,例如 ``` ENV MYSQL_version 5.7 ``` 7.ADD 将本地的一个文件或目录拷贝到容器的某个目录里。 其中src为Dockerfile所在目录的相对路径,它也可以是一个url。例如: ``` ADD conf/vhosts /usr/local/nginx/conf ``` 8.COPY 类似于ADD,将本地文件拷贝到容器里,不过它不支持URL,例如: ``` COPY 123.txt /data/456.txt ``` 9.ENTRYPOINT 格式类似CMD 容器启动时要执行的命令,它和CMD很像,也是只有一条生效,如果写多个只有最后一条有效。 和CMD不同是: CMD 是可以被 docker run 指令覆盖的,而ENTRYPOINT不能覆盖。 比如,容器名字为Cloud 我们在Dockerfile中指定如下CMD: ``` CMD ["/bin/echo", "test"] ``` 假如启动容器的命令是 ``` docker run Cloud ``` 则会输出 test 假如启动容器的命令是 ``` docker run -it Cloud /bin/bash ``` 则什么都不会输出 ENTRYPOINT不会被覆盖,而且会比CMD或者docker run指定的命令要靠前执行 ``` ENTRYPOINT ["echo", "test"] ``` 假如启动容器的命令是 ``` docker run -it Cloud 123 ``` 则会输出 test 123 ,这相当于要执行命令 echo test 123 10.VOLUME 创建一个可以从本地主机或其他容器挂载的挂载点。 ``` VOLUME ["/data"] ``` 11.USER指定RUN、CMD或者ENTRYPOINT运行时使用的用户 ``` USER Cloud ``` 12.WORKDIR 为后续的RUN、CMD或者ENTRYPOINT指定工作目录 ``` WORKDIR /tmp/ ``` Dockerfile示例: ``` vi Dockerfile FROM ubuntu:22.04 MAINTAINER Cloud Cloud@CloudPLayer RUN sed -i 's/https:\/\/mirrors.aliyun.com/http:\/\/mirrors.cloud.aliyuncs.com/g' /etc/apt/sources.list RUN apt clean RUN apt update RUN apt install -y libpcre2-dev net-tools gcc zlib1g-dev make ADD https://nginx.org/download/nginx-1.24.0.tar.gz . RUN tar zxvf nginx-1.24.0.tar.gz RUN mkdir -p /usr/local/nginx RUN cd nginx-1.24.0 && ./configure --prefix=/usr/local/nginx && make && make install COPY index.html /usr/local/nginx/html/index.html #COPY index2.html /usr/local/nginx/html/2.html EXPOSE 80 ENTRYPOINT /usr/local/nginx/sbin/nginx -g "daemon off;" ``` 编译成镜像 ``` docker build -t cloudplayer_nginx:1.0 . ``` 说明: -t 后面跟镜像名字:tag, 这里的. 表示使用当前目录下的Dockerfile,并且工作目录也为当前目录,如果想使用其它目录下的Dockerfile,还可以使用-f选项来指定,例如 ``` docker build -t ubuntu_nginx:1.0 -f /data/docker/nginx.dkf /tmp/ ##这里/tmp/目录为工作目录,比如COPY文件的时候,到/tmp/下面去找 ``` 使用镜像 ``` docker run -itd --name nginx -P ubuntu_nginx:1.0 ##使用-P(大写P.可以随机映射一个端口到宿主机,也可以使用-p(小p.指定具体端口 ``` ## docker-compose Docker compose可以方便我们快捷高效地管理容器的启动、停止、重启等操作,它类似于linux下的shell脚本,基于yaml语法,在该文件里我们可以描述应用的架构,比如用什么镜像、数据卷、网络模式、监听端口等信息。 我们可以在一个compose文件中定义一个多容器的应用(比如wordpress.,然后通过该compose来启动这个应用。 1.安装docker-compose [官方地址](https://github.com/docker/compose/releases) ``` curl -L https://github.com/docker/compose/releases/download/v2.12.2/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose chmod a+x /usr/local/bin/docker-compose ``` 测试并查看版本 ``` docker-compose version ``` 2.用docker-compose快速部署应用 编辑wordpress的compose yaml文件 ``` vi docker-compose.yml ##写入如下内容 services: db: # 服务1:db image: mysql:5.7 # 使用镜像 mysql:5.7版本 volumes: - db_data:/var/lib/mysql # 数据持久化 restart: always # 容器服务宕机后总是重启 environment: # 环境配置 MYSQL_ROOT_PASSWORD: somewordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: # 服务2:wordpress depends_on: # wordpress服务启动时依赖db服务,所以会自动先启动db服务 - db image: wordpress:latest # 使用镜像 wordpress:latest最新版 ports: - "8000:80" #端口映射8000:80 restart: always environment: # 环境 WORDPRESS_DB_HOST: db:3306 # wordpress连接db的3306端口 WORDPRESS_DB_USER: wordpress # wordpress的数据库用户为wordpress WORDPRESS_DB_PASSWORD: wordpress # wordpress的数据库密码是wordpress WORDPRESS_DB_NAME: wordpress # wordpress的数据库名字是wordpress volumes: db_data: {} ``` 启动 ``` docker-compose up -d ``` 查看 ``` docker-compose ps ``` 还可以停止 ``` docker-compose stop ``` ## 私有镜像仓库harbor搭建 Docker容器应用的开发和运行离不开可靠的镜像管理,虽然Docker官方也提供了公共的镜像仓库,但是从安全和效率等方面考虑,部署我们私有环境内的Registry也是非常必要的。Harbor是 由VMware公司开源的企业级的Docker Registry管理项目,它包括权限管理(RBAC)、LDAP、日志审核、管理界面、自我注册、镜像复制和中文支持等功能。 [harbor官方地址](https://goharbor.io) [github地址](https://github.com/goharbor/harbor) 0.提前准备一个ca证书 如果有自己的域名,可以到https://freessl.cn/ 申请免费的ssl证书 安装好docker-compose 1.下载harbor离线包 https://github.com/goharbor/harbor/releases 我这里下载的是2.6.2 2.将下载的包上传到linux,解压 ``` tar zxf harbor-offline-installer-v2.6.2.tgz -C /opt/ ``` 3.准备配置文件 ``` cd /opt/harbor cp harbor.yml.tmpl harbor.yml ##将模板配置文件拷贝一份为正式的配置文件 ``` 4.编辑配置文件 ``` vi harbor.yml 修改 hostname: reg.mydomain.com 为 hostname: harbor.yuankeedu.com 修改 certificate: /your/certificate/path 和 private_key: /your/private/key/path 为具体的证书地址 修改 harbor_admin_password 为合适的密码 ``` 5.安装 ``` sh install.sh ``` 6.服务的停止和启动 ``` cd /opt/harbor docker-compose ps ##查看服务 docker-compose stop ##关闭 docker-compose up -d ##启动 ``` 7.访问web界面 ![](./6.png) 8.拉取公共镜像 ``` docker pull tomcat docker tag tomcat harbor.yuankeedu.com/CloudPLayer/tomcat:latest ``` 9.把tomcat镜像推送到harbor ``` # docker login https://harbor.yuankeedu.com 输入用户名和密码 # docker push harbor.yuankeedu.com/CloudPLayer/tomcat:latest ``` 问题: x509: certificate signed by unknown authority ``` 需要在客户端机器上(也就是你执行docker login的机器上.执行 1. echo -n | openssl s_client -showcerts -connect harbor.yuankeedu.com:443 2>/dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' >> /etc/ssl/certs/ca-bundle.trust.crt 2.systemctl restart docker ```