Docker

190 阅读8分钟

1、Docker基本概念

1.1解决的问题

  • 应用构建:比如Java、C++程序等构建时都要打成软件包,使用docker 直接docker build 创建一个镜像。 就可以了。
  • 应用分享:将镜像上传到一个指定的地方 docker hub
  • 应用运行:统一标准的镜像 docker run

1.2容器化和虚拟化区别

虚拟化:

1、通过在物理硬件上创建虚拟机,每台虚拟机都有完整的操作系统,实现资源的抽象和隔离。

2、基础镜像GB级别

3、创建使用比较复杂

4、启动速度慢

5、分享和移植不方便

容器化:

1、容器化是将应用程序及其依赖打包在一个容器中

2、基础镜像MB级别。

3、启动速度秒级

4、隔离性强

5、移植与分享方便

2、架构

  • Docker_Host:
    • 安装docker 的主机
  • Docker Daemon:
    • 运行在Docker主机上的Docker后台进程
  • Client:
    • 操作Docke 主机的客户端
  • Registry:
    • 镜像仓库
    • Docker Hub
  • Images:
    • 镜像,带环境打包好的程序,可以直接启动运行
  • Containers:
    • 容器: 由镜像启动起来正在运行中的程序

3、安装Docker

0、切换root权限命令

su root

1、移除以前docker相关包

 sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

1.1 卸载docker

1.停止docker服务
sudo systemctl stop docker
2.卸载 Docker 程序包
  • 对于使用 yum 的系统(如 CentOS)
sudo yum remove docker-ce docker-ce-cli containerd.io docker-compose-plugin

2、配置yum源

sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

3、安装Docker

sudo yum install -y docker-ce docker-ce-cli containerd.io


#以下是在安装k8s的时候使用
yum install -y docker-ce-20.10.7 docker-ce-cli-20.10.7  containerd.io-1.4.6

4、启动

systemctl enable docker --now

配置加速

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://82m9ar63.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

5、常用命令

4、安装中间件

4.1 安装nginx

docker pull nginx #下载最新版

镜像名:版本名(标签)
docker pull nginx:1.20.1


## 下载来的镜像都在本地
docker images  #查看所有镜像

启动Nginx容器

启动nginx应用容器,并映射88端口,测试的访问

# -d:后台运行
# --restart=always: 开机自启
docker run --name=mynginx   -d  --restart=always -p  88:80   nginx

修改容器内容

修改默认的index.html 页面

进入到容器内部修改
# 进入容器内部的系统,修改容器内容 -it 以交互模式进入容器
docker exec -it 容器id  /bin/bash

# 进入到容器内部的小Linux系统下的相关目录修改HTML页面
cd /usr/share/nginx/html

# 写入内容 到html 页面
echo "<h1>welcome to atguigu<h1>" > index.html 

# 写完查看
cat index.html
挂载数据到外部修改
docker run --name=mynginx   \
-d  --restart=always \
-p  88:80 -v /data/html:/usr/share/nginx/html:ro  \
nginx
# -v 数据挂载 把主机的目录挂载到容器目录中
# ro 只读模式
# 修改页面只需要去 主机的 /data/html  //挂载数据后,不能再提交改变
#如果把nginx容器内部的配置文件挂载出来,那主机也要有相同的配置文件

# 把容器里面的文件复制到外部   
docker cp image-id:etc/nginx/nginx.conf /data/conf/nginx.conf

4.2 安装Redis


docker pull redis 

docker run -v /data/redis/redis.conf:/usr/local/etc/redis/redis.conf \
-v /data/redis/data:/data \
-d --name=myredis \
-p 6379:6379 \
redis:latest redis-server /usr/local/etc/redis/redis.conf

4.3 Redis设置账号密码访问

vi data/redis/redis.conf
# 填入以下内容
requirepass [password]

5、提交改变

将自己修改好的镜像提交

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]


docker commit -a "leifengyang"  -m "首页变化" 341d81f7504f guignginx:v1.0

6、镜像传输

6.1 物理传输

  1. 将镜像压缩成一个压缩包
/将guigunginx镜像压缩成 名为abc.tar
docker save -o abc.tar guigunginx:v1.0

2. 将压缩包传输给其他的机器

// 将abc.tar 复制到另一个主机下的 root目录下
scp abc.tar root@139.198.186.134:/root/

3. 其他的机器使用这个镜像

docker load -i abc.tar

6.2 推送远程仓库

推送镜像到远程仓库 dockerHub:应用市场

           //本地镜像    标签名   新的仓库  版本
docker tag local-images:tagname new-repo:tagname
//登录到dockerhub
docker login \ docker logout

//推送镜像到dockerhub
docker push crpi-5p5rx9rwghjk24v7.cn-heyuan.personal.cr.aliyuncs.com/cloudpod-mxf/cloud:[镜像版本号]

7、部署一个Java应用

编写Dockerfile

FROM openjdk:8-jdk-slim
LABEL maintainer="mengxiangfei"

COPY target/*.jar /app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

构建镜像

//这个 .  很重要 表示在当前目录下执行
docker build -t java-demo:v1.0 .

启动容器

docker run -d -p 8080:8080 java-demo:v1.0

docker网络配置方式

  • Host:容器不会虚拟出自己的网卡,配置住主机的IP等等,而是使用宿主机的IP和端口
  • Container: 创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口的范围。
  • None: 该模式关闭了容器的网络功能
  • Briidge: 默认为该模式,桥接,此模式会为每一个容器分配,设置IP等,并将容器连接到一个docker0的虚拟网桥,通过docker0 网桥以及iptables nat表配置与宿主机通信

1、Host模式

  • host模式: 使用–net=host指定
  • 相当于VMware中的桥接模式,与宿主机在同一个网络中,但是没有独立IP地址

#创建容器web 1,指定网络模式为 host
#因为是host模式,所有宿主机和容器共享ip和端口
 docker run -d --name web1 --net=host nginx
 
#访问宿主机的ip和80端口,则可以访问到web3的nginx服务
 firefox  http://192.168.62.120:80

2、Container模式

  • container模式: 使用–net=contatiner:NAME_or_ID 指定
  • 这个模式指定新容器和已经存在的一个容器共享一个network namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,培植自己的IP。而是和一个容器共享IP 端口等。可以在一定程度上节省资源,容器内部依然不会拥有全部端口。
  • 两个容器的网络共享,但是其他的比如所文件系统,进程列表等还是隔离的

#基于镜像centos:7 创建一个名为test1的容器
[root@jn /]# docker run -itd --name test1 centos:7 /bin/bash
914e2208d2251c7c2eacadfaa29188a33ea70bf73e64fffe25bb0a012f8b0223
#查看容器的pid号
 
[root@jn /]# docker inspect -f '{{.State.Pid}}' test1
10678
#查看该容器的命名空间编号
 
[root@jn /]# ls -l /proc/10678/ns
总用量 0
lrwxrwxrwx. 1 root root 0 10月 19 20:48 ipc -> ipc:[4026532578]
lrwxrwxrwx. 1 root root 0 10月 19 20:48 mnt -> mnt:[4026532576]
lrwxrwxrwx. 1 root root 0 10月 19 20:47 net -> net:[4026532581]
lrwxrwxrwx. 1 root root 0 10月 19 20:48 pid -> pid:[4026532579]
lrwxrwxrwx. 1 root root 0 10月 19 20:48 user -> user:[4026531837]
lrwxrwxrwx. 1 root root 0 10月 19 20:48 uts -> uts:[4026532577]
 
#创建test2容器,使用container网络模式,和test1共享network Namespace
[root@jn /]# docker run -itd --name test2 --net=container:test1 centos:7 /bin/bash
f539192aa93c5fc28f3c5b69f22ef7e333f9c1e18094f490137f157e39df2547
#查看test2容器的pid
 
[root@jn /]# docker inspect -f '{{.State.Pid}}' test2
10897
 
#查看该容器的命名空间编号
[root@jn /]# ls -l /proc/10897/ns
总用量 0
lrwxrwxrwx. 1 root root 0 10月 19 20:50 ipc -> ipc:[4026532651]
lrwxrwxrwx. 1 root root 0 10月 19 20:50 mnt -> mnt:[4026532649]
lrwxrwxrwx. 1 root root 0 10月 19 20:50 net -> net:[4026532581]
lrwxrwxrwx. 1 root root 0 10月 19 20:50 pid -> pid:[4026532652]
lrwxrwxrwx. 1 root root 0 10月 19 20:50 user -> user:[4026531837]
lrwxrwxrwx. 1 root root 0 10月 19 20:50 uts -> uts:[4026532650]
 

3、none模式

  • none模式:使用 --net=none指定
  • 这种模式下,docker容器有自己的network namespace,但并没有给容器分配任何网络配置。也就是说这个docker容器没有网卡,IP 端口 路由等等信息。
  • 这种类型没有办法联网,但是封闭的网络能够保证容器的安全性
  • 该容器将完全独立于网络,用户可以根据需要为容器添加网卡。此模式拥有所有端口。(none网络模式配置网络)

bridge模式

这个模式就是docker默认的网络模式,不屑-net参数,就是bridge模式

docker cp /cloudpods/_output/bin/notify  ea1a8b80c709:/opt/yunion/bin
docker cp /cloudpods/_output/bin/cloudid  9c797d6cb6a8:/opt/yunion/bin

docker exec -it compose-mysql-1 mysql -uyunionansible -p 9YuQL9KEZn1mppaK

docker compose up -d

 - ./data/var/lib/mysql:/var/lib/mysql

smtp mxrmlwckiaafdcjj

  ports:
     - "3306:3306"

no main manifest attribute, in app.jar(Docker run命令出错)-CSDN博客

func Demo() {
    defer func() {
       if er := recover(); er != nil {
          fmt.Println(er)
       }
    }()
    // 邮件服务器配置
    smtpHost := "smtp.exmail.qq.com"       // SMTP 服务器地址
    smtpPort := "465"                      // SMTP 端口
    username := "croco.yu@sunthycloud.com" // 发件人邮箱
    password := "Muma@123123123"           // 发件人邮箱密码
    // 邮件内容
    from := username
    to := []string{"342714700@example.com"} // 收件人邮箱
    subject := "Hello from Go"
    body := "This is a test email sent from a Go application."
    message := []byte("From: " + from + "\n" +
       "To: " + to[0] + "\n" +
       "Subject: " + subject + "\n\n" +
       body)
    // 认证
    auth := smtp.PlainAuth("", username, password, smtpHost)
    // 发送邮件
    err := smtp.SendMail(smtpHost+":"+smtpPort, auth, from, to, message)
    if err != nil {
       fmt.Println(err)
    }
    fmt.Println("Email sent successfully!")
}