docker

docker 概述

1. 基础知识

1. docker 和虚拟机技术的不同

  • 传统虚拟机,虚拟出一个硬件,运行整个完整的操作系统,然后在这个系统上部署软件
  • 容器内的应用直接运行在宿主主机上,没有自己的内核,也没虚拟硬件。且容器间是相互独立的,每个容器内都有自己的文件系统,互不影响。

2. docker 的特点

  • 应用更快速的交付
  • 更便捷的升级和扩容
  • 更简单的系统运维
  • 更高效的计算资源利用

3. docker 架构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cC4OLzoI-1653055781765)(C:\Users\86134\AppData\Roaming\Typora\typora-user-images\image-20210517201203814.png)]

4. 什么是容器数据卷

  • 当我们删除容器后,容器内的数据也会跟着被删除。为了能够在容器删除后还能保留数据的需求下,应运而生了一个数据共享技术,这就是卷技术。
  • docker 容器中产生的数据同步到本地就是容器数据卷。即将容器的目录挂载到本地服务器。

2. docker 部署

  • 卸载旧版本 docker

    yum remove docker \
                      docker-client \
                      docker-client-latest \
                      docker-common \
                      docker-latest \
                      docker-latest-logrotate \
                      docker-logrotate \
                      docker-engine
    
  • 配置yum

    yum install -y yum-utils 
    yum-config-manager \
        --add-repo \
        http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    yum makecache fast
    
  • 安装docker

    yum install -y docker-ce docker-ce-cli containerd.io
    
  • 配置docker网卡

    $ yum install bridge-utils -y                 # 安装网卡工具
    $ ip link set dev docker0 down                # 将 docker0 网卡停掉
    $ brctl delbr docker0					          # 将 docker0 删掉
    $ brctl addbr docker0                       # 增加一块 docker0 网卡
    $ ip addr add 172.16.10.1/24 dev docker0          # 配置网卡 ip 地址
    $ ip link set dev docker0 up                  # 启动网卡
    $ip addr                               # 查看 ip 地址信息,有没有 docker0 网卡
    
  • 启动并检测docker

    systemctl start docker
    docker run hello-world  ## Hello from Docker 即为成功!
    
  • 配置阿里云加速器

     1. 登录阿里云,点击左上角的`三个横线`,选择`产品与服务`,选择`容器镜像服务`,`镜像工具`--->`镜像加速器`
    sudo mkdir -p /etc/docker
    sudo tee /etc/docker/daemon.json <<-'EOF'
    {
      "registry-mirrors": ["https://ujhbdxl8.mirror.aliyuncs.com"]
    }
    EOF
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    

3. docker 常用命令

  • 官方手册
    https://docs.docker.com/engine/reference/commandline/port/

  • 系统命令

    docker version			# 显示 docker 版本信息
    docker info				# 显示 docker 的系统信息,包括镜像和容器的数量
    

1. 镜像命令

1. 查看本地镜像
`docker` images		# 查看本地有多少镜像
REPOSITORY   TAG   IMAGE ID   CREATED       SIZE
# 镜像的仓库源  标签   镜像ID  镜像创建的时间 镜像大小

`docker` images --help
# Options:
  -a, --all			# 列出所有的镜像
  -q, --quiet        # 只显示镜像 ID
2. 搜索镜像
`docker` search image-name
`docker` search mysql
  NAME      DESCRIPTION   STARS     OFFICIAL     AUTOMATED
# 镜像名字   镜像的描述	  收藏数     是否官方发布  是否自动更新镜像仓库的镜像
`docker` search --help
# Options:
  -f, --filter filter   # 根据相应信息进行过滤,示例如下:
   `docker` search -f stars=3000 mysql                 # 列出收藏数大于3000的
   `docker` search -f is-automated=true mysql          # 列出是官方发布
   `docker` search -f is-official=true mysql           # 列出是自动更新镜像仓库的
   
  --format string       # 以什么形式输出,示例如下:
    `docker` search --format "{{.Name}}: {{.StarCount}}" nginx
     nginx: 14875
    `docker` search --format "table {{.Name}}\t{{.IsAutomated}}\t{{.IsOfficial}}" nginx
      NAME                               AUTOMATED   OFFICIAL
      nginx                                          [OK]
      
  --limit int           # 列出多少列(默认 25),示例如下
    `docker` search --limit 3 mysql
3. 下载镜像
`docker` pull [options] name[:tag|@digest] 
# 选项基本没什么用
# 示例如下
docker pull mysql
Using default tag: latest   # 不指定 tag 将下载最新的
latest: Pulling from library/mysql
69692152171a: Pull complete # 分层下载,docker镜像基本都是由多层组成(分层存储),每一层都可以被不同镜像共同使用
Digest:   sha256:d50098d7fcb25b # 有时候你可能并不想获取最新的镜像文件,而是使用一个固定版本的镜像文件。docker提供了一种通过摘要digest拉取镜像的方式,这种方式你可以明确的指定镜像的版本号。这样你可以获得一个固定版本的镜像文件。并且确保你每次使用的时候都是同一个镜像文件。
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest

4. 删除镜像
docker rmi image-id          # 删除指定镜像
docker rmi ${docker images -qa}  # 删除全部
5. 镜像改名
`docker` tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
7. 具名挂载和匿名挂载
  • 具名挂载

    `docer` run -v nginx01:/etc/nginx nginx002
    # 查看全部挂载
    `docker` volume ls
    
    DRIVER    VOLUME NAME
    # local     nginx001
    
    # 查看挂载目录
    `docker` inspect nginx001 | grep -A8 "Mounts"
            "Mounts": [
                {
                    "Type": "volume",
                    "Name": "nginx001",
                    "Source": # "/var/lib/docker/volumes/nginx001/_data",
                    "Destination": "/etc/nginx",
                    "Driver": "local",
                    "Mode": "z",
                    "RW": true,
    
    
  • 匿名挂载

    docker run -v /etc/nginx/ nginx:stable
    ## 没有具体的名字,不常用!
    
  • 容器之间进行数据共享

    docker run --vlumes-from mysql001 mysql:5.7 --name mysql002 # 如果 mysql001 是将 /var/lib/mysql 挂载到本机上,那么 mysql002 也的 /var/lib/mysql 目录,也会挂载到本机上,实现 mysql 之间的数据共享。
    
6. 实现两个容器间进行数据共享
  • 创建第一个容器时,部署容器和主机的共享目录

  • 创建新的容器时进行数据共享

    `docker` run --volumes-from docker01 centos
    

2. 容器命令

1. 运行(创建)、开启、关闭、进入、退出容器
  • 创建容器

    docker run [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG...]			# 不加tag,默认最新
    # 参数说明
    --name="Name"    							  # 给容器起名字
    -d               						 # 在后台运行,容器后台启动,就必须有一个前台的进程
    -it                              # 使用交互的方式运行,进入容器查看内容
    
    -p 主机端口:容器端口      # 主机端口映射到容器端口
    -p IP:主机端口:容器端口    # 主机端口映射到容器端口
    -p 容器端口            # 外面访问不到该端口
    容器端口			      # 外面访问不到该端口
    
    -e "discovery.type=single-node"         # 单机使用容器	  安装es
    -e ES_JAVA_OPTS="-Xms265m -Xmx512m"      # 设置内存使用量   安装es
    
    -e MYSQL_ROOT_PASSWORD=mysql				# 设置 MySQL 密码为 mysql
    
    -v 本机目录:容器目录:读写权限[ro rw]	   # 设置容器挂载目录,读写权限若设置了 ro 则只能在主机上进行操作了
    -v /home/mysql/conf:/etc/mysql/conf.d		# 将 MySQL 的配置文件目录挂载到本地的 /home/mysql/conf 下
    -v /home/mysql/var/date:/var/lib/mysql    # 将 MySQL 的存储目录挂载到本地的 /home/mysql/var/data 下
    
    --net mynet       # 将容器加入到 mynet 网络模式
    
    ### 示例如下:
    docker run -it centos:7 /bin/bash  # 启动容器并进入容器
    
  • 启动和停止容器

    `docker` start   容器ID      # 启动容器
    `docker` restart 容器ID      # 重启容器
    `docker` stop    容器ID      # 停止容器
    `docker` kill    容器ID      # 强制停止
    
  • 进入当前正在运行的容器

    `docker` exec -it 容器ID /bin/bash  # 打开一个新的窗口
    `docker` attch 容器ID				 # 进入运行的窗口
    
  • 退出容器

    exit  # 直接退出容器
    Ctrl + p + q # 退出容器不停止
    
  • 删除容器

    `docker` rm -f 容器id  # 删除指定容器
    
2. 列出所有运行的容器
`docker` ps       # 列出正在运行的容器
`docker` ps -a    # 列出运行过和正在运行的容器
`docker` ps -n=1  # 列出一行
`docker` ps -q	# 只显示 id
3. 查看容器相关信息
  • 查看容器的系统日志

    `docker` logs [options] 容器ID
    `docker` logs --help
    # Options:
          --details        # Show extra details provided to logs
      -f, --follow         # 和 Linux tail -f 一样
          --since string   # Show logs since timestamp
      -n, --tail string    # 打印多少行(默认全部)
      -t, --timestamps     # 显示时间戳
          --until string   # 显示日志在一个时间戳后
    
  • 查看容器中的进程信息

    `docker` top 容器id
    
  • 查看镜像的元数据

    `docker` inspect 容器ID
    
4. 从容器内拷贝文件到主机
docker cp 容器ID:/root/a.txt ./ # 从容器中拷贝 a.txt 文件到主机的当前目录下
docker cp ./a.xt 容器ID:/root/  # 拷贝当前目录下的 a.txt 到容器中的 /root 目录
5. commit 镜像
`docker` commit -m "提交的描述信息" -a "作者" 容器id 目标镜像名:[tag]
### 举例:
docker commit -m "it is a private nginx for codefun." -a "codefun" 2890096b3958 nginx:codefun

4. 项目案例部署

1. docker 部署 portainer

docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
  • 网页访问 ip:8088 即可

2. docker 部署 Nginx

  • 查找 Nginx 镜像,建议在dockerhub上,网址如下:
    https://hub.docker.com/

  • 拉取镜像,建议使用稳定版本stable

    `docker` pull nginx:stable
    
  • 创建nginx 容器

    `docker` run --name="nginx001" -p 80:80 nginx:stable
    
  • 启动容器并测试是否安装成功

    `docker` start nginx001
    curl localhost:80
    

3. centos7 安装 ssh

vim /dockerfile/centos_ssh
---------------------------------------------------
FROM centos:7
MAINTAINER This is centos:ssh
RUN  yum update -y  && yum install -y openssh-server net-tools lsof telnet passwd
RUN echo "123456" | passwd --stdin root
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN sed -i '/^session\s\+required\s\+pam_loginuid.so/s/^ /#/' /etc/pam.d/sshd
RUN mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.ssh
EXPOSE 22
CMD ["/usr/sbin/sshd","-D"]
----------------------------------------------------
docker build -f /dockerfile/centos_ssh -t codefun001/centos_ssh:v1 .

4. docker 部署 registry

  • 拉取并生成容器

    `docker` run -d -P --restart=always --name reg -v reg:/var/lib/registry registry
    
  • 编写配置文件

    cat /etc/docker/daemon.json 
    --------------------------------------------------------------------
    {
      "registry-mirrors": ["https://ujhbdxl8.mirror.aliyuncs.com"],
      "insecure-registries": ["192.168.80.141:49153"]
    }
    --------------------------------------------------------------------
    
  • 上传和下载镜像

    `docker` tag nginx:latest 192.168.80.141:49153/codefun/nginx01:v1  # 注意名字的格式
    `docker` push 192.168.80.141:49153/codefun/nginx01:v1
    `docker` pull 192.168.80.141:49153/codefun/nginx01:v1
    
  • 用户认证

    `docker` run -d -p 5000:5000 -v regauth:/auth/ -v reglib:/var/lib/registry --name reg -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e 
    "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" registry   # 添加用户认证功能
    `yum` install -y httpd-tools # 下载用户认证工具
    `htpasswd` -Bbn codefun 123 > /var/lib/docker/volumes/regauth/_data/htpasswd # 添加用户
    `docker` login 192.168.80.141:5000      # 进行登录
    `docker` push  192.168.80.141:5000/codefun/nginx01:v1  # 推送镜像
    `docker` logout
    

5. harbor 部署

安装 docker-compose :

https://github.com/docker/compose/releases/download/1.15.0/docker-compose-Linux-x86_64

(一)下载安装包,重命名为docker-compose,放入/usr/local/bin,

(二) chmod +x /usr/local/bin/docker-compose # 增加可执行权限

(三)ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose # 创建软连接,使其可以直接运行

安装 harbor:

https://github.com/vmware/harbor/releases/download/v1.1.1/harbor-online-installer-v1.1.1.tgz

(一)下载压缩包,解压并进入harbor目录,

(二)修改 harbor.cfg 文件:

hostname = 192.168.80.141   # 修改为自己的IP地址

(三)将仓库容器的5000端口映射到主机的5000端口,修改docker-compose.yml文件 :

registry:									# 注意:是 registry: 下
image: vmware/registry:photon-2.6.0
container_name: registry
restart: always
volumes:
- /data/registry:/storage:z
- ./common/config/registry/:/etc/registry/:z
 ports:
   - 5000:5000						# 这个是在 volumes 和 networks 之间添加的两行
networks:
   - harbor

(四)执行安装脚本

./install.sh

(五)检测是否成功

docker ps   # 有大量容器启动

在网页上访问 http://192.168.80.141:80 用户名为:admin,密码为:Harbor12345

在 Linux 上进行上传镜像:

`docker` login 192.168.80.141:5000
`docker` pull busybox
`docker` tag busybox:latest 192.168.80.141:5000/library/busybox:test
`docker` push 192.168.80.141:5000/library/busybox:test 

5. dockerFile[^1]

1. 整体操作流程

  1. 编写 dockerFile 文件

  2. docker build 构建成一个镜像

    `docker build` -f dockerfile_path -t image_name:tag `.`   ## 不要忘记后面有个小点
    `docker build` -f /dockerfile/centos -t centosfun:gx `.`  # 示例
    
  3. docker run 运行镜像,建立容器

  4. docker push 将镜像发布到 dockerhub

    1. ## 在 dockerhub 上注册用户
    2. ## 在主机上进行登录
        `docker` login -u codefun001
    3. ## 将镜像上传到 dockerhub
    	 `docker` push image_name:tag     # 注意:镜像名字的格式必须为 dockerhub用户名/image_name
    
  5. 将镜像发布到阿里云

    1. 找到容器镜像服务,点击实例列表,创建个人实例
    2. 点击命名空间,进行相关配置
    3. 点击创建镜像仓库,进行相关配置
    4. 根据网页提示进行操作即可

2. dockerFile 指令

FROM	image-name:tag		# 基础镜像,以那个镜像为基础创建新的镜像

FROM	centos:7			# 示例
MAINTAINER	creator-name				# 指定维护者信息

MAINTAINER	codefun						# 示例
RUN		shell-command	 		# 镜像构建时需要运行的指令

RUN		yum install -y vim		# 示例
ADD		source	dest		  # 向镜像中添加一些配置文件

ADD		/tmp/a.txt	/tmp	  # 将主机内 /tmp/a.txt 添加到容器 /tmp/ 目录下

## 注意:add 和 copy 的区别,add 会自动解压 tar、gzip、bzip2 文件,官方推荐我们使用 copy,因为解压是非常费事的。
COPY	source	dest	 	  # 将文件拷贝到镜像中

COPY	/tmp/a.txt	/tmp	  # 将主机内 /tmp/a.txt 添加到容器 /tmp/ 目录下
WORKDIR		dir-path		  # 镜像的工作目录

WORKDIR		/usr/local		  # 示例
VOLUME		["<dir_path1>", "<dir_path2>"...]  # 和主机共享的目录

VOLUME		/tmp								# 示例
EXPOSE		port_name1 port_name2		# 向外暴露那个端口,但是还未和主机建立联系 

EXPOSE		80							# 示例
CMD		shell_command	# 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代

CMD		systemctl start nginx 		# 容器启动的时候,启动 nginx

`docker run` 后面追加的命令会将 `CMD` 的命令进行覆盖。
若在 dockerfile 中写入的是`CMD ls`,则使用 `docker run xxx -l` 创建容器后,容器就会执行 `-l`命令。
ENTRYPOINT  shell_command	 # 指定这个容器启动的时候要运行的命令,可以追加命令

ENTRYPOINT  systemctl start nginx  # 容器启动的时候,启动 nginx

`ENTRYPOINT`会追加`docker run` 后面追加的命令。
若dockerfile 中写入`ENTRYPOINT ls`, 则使用 `docker run xxx -l` 创建容器后,容器就会执行 `ls -l`命令。
ONBUILD		 # 当构建一个被继承 dockerfile 时,就会运行这个命令### 语法:若指令后面跟多个参数,则需要用中括号括起来。
ENV		 key1=value1 key2=value2  # 构建的时候设置环境变量

ENV		 MYSQL_ROOT_PASSWORD=mysql  # 在创建 mysql 或者 es 的时候用到

3. dockerfile 示例

  • 构建一个普通的镜像

    cat /dockerfile/centos
    --------------------------------------------------------------------
    FROM	centos:7
    MAINTAINER	codefun
    RUN		yum install -y vim
    RUN		yum install -y net-tools
    CMD		echo "it is already installed"
    WORKDIR 	/tmp
    VOLUME		["/tmp"]	
    EXPOSE		80
    CMD		echo "it is already OK"
    --------------------------------------------------------------------
    

6. docker 网络

1. 基本原理

  • Docker 中的网络接口默认都是虚拟的接口。虚拟接口的优势之一是转发效率较高。
  • Linux 通过在内核中进行数据复制来实现虚拟接口之间的数据转发。
  • docker 容器网络就利用了这项技术。它在本地主机和容器内分别创建一个虚拟接口,并让它们彼此连通(这样的一对接口叫做 veth pair)。

2. docker 网络模式

  • host 模式

    • 与宿主机在同一个网络中,但没有独立IP地址。
    • 容器不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。
    • 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
  • container模式

    • 这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。
    • 新创建的容器会和一个指定的容器共享IP、端口。
    • 两个容器的进程可以通过lo网卡设备通信。
  • bridge模式

    • 容器使用独立network Namespace,并连接到docker0虚拟网卡(默认模式)。
    • 为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上
    • 缺点:不能用容器的主机名互相访问
  • none模式

    • 不设置网络,保护容器的数据安全。

3. 自定网络

  • docker network 命令详解

    `docker` network --help
    # Commands:
       -connect           # 使用指定的网络模式
        `docker` network connect mynet container01	   # 指定 container01 使用 mynet 网络
        
       -create        	   # 创建网络模式
        `docker` network create --driver bridge --subnet 182.168.0.0/16 --gateway 182.168.0.1 mynet  # 创建名为 mynet 的网络模式,网络范围为 182.168.0.1 ~ 182.168.254.254,网关为 182.168.0.1,连接方式为桥接。
    
       -disconnect         # 取消使用指定的网络模式
        `docker` network disconnect mynet container01	# 取消 container01 使用 mynet 网络
       
       -inspect				# 显示网络模式的详细信息
        `docker` network inspect mynet	# 显示 mynet 网络的详细信息
        
       ls             # 列出所有的网络模式
        `docker` network ls         # 列出所有的网络模式
        
       prune           # 删除所有没有用的网络模式
       
       rm             # 删除指定的网络模式
    
  • 创建自定义网络模式

    `docker` network create --driver bridge --subnet 182.168.0.0/16 --gateway 182.168.0.1 mynet
    # 返回 docker 部署,配置 docker 网卡
    
  • 创建容器并加入自定义网络模式

    `docker` run -d -P 0 --net mynet --name tomcat001 tomcat
    `docker` run -d -P 0 --net tomcat002 tomcat
    
  • 使 tomcat001 能够 ping 通 tomcat002

    `docker` network connect bridge tomcat001
    
  • 自定义网络的优点

    自定义网络和 docker 自带的网络模式中的 bridge 模式的基本原理相同,但是自定义网络修复了**容器名直接互相 ping **的缺点。

普通用户使用 docker 设置

方法一:赋予普通用户root权限

vim /etc/sudoers
---------------------------------------------
root ALL=(ALL) ALL
name1 ALL=(ALL:ALL) ALL	# 使用 sudo 时,需要 name1 密码
name2 ALL=(ALL:ALL)NOPASSWD: ALL  # 使用 sudo 时,不需要 name1 密码
----------------------------------------
## 注意:需要按 wq! 才能保存退出。
		# 不用刷新 sudoers 文件,即时生效。

方法二:添加 docker 组

  • 查看是否有 docker 组 cat /etc/group | grep docker

    • 没有就添加 groupadd docker
  • 查看/var/run/docker.sock的属性 ls /var/run/docker.sock ,正确的应该是 root docker

    • 不正确就修改:chgrp docker /var/run/docker.sock
  • 将普通用户添加至 docker 组

    gpasswd -a test docker
    id test # 查看是否添加成功
    newgrp docker # 没有成功就刷新 docker 组
    newgrp test # 最后切回原组
    
  • 将用户从 docker 组中删除

    gpasswd -d test docker
    newgrp doker
    # 此时 id test 显示已经删除了,但是该用户若正在连接,还是可以使用 docker,只需要断开连接再次重连即可。
    # 若他不重连,则直接杀死该连接
    w # 查看当前终端的使用情况
     17:19:24 up  1:17,  2 users,  load average: 0.00, 0.01, 0.05
    USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
    root     pts/0    192.168.154.1    16:03    4.00s  0.19s  0.01s w
    gongxian pts/1    192.168.154.1    17:19    7.00s  0.01s  0.01s -bash
    
     pkill -kill -t pts/1 # 杀死该连接
      pkill -9-t pts/1	#上面的不行,强制杀死
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值